misc/libfreetype/src/tools/chktrcmp.py
changeset 9372 915436ff64ab
parent 9371 f3840de881bd
child 9373 b769a8e38cbd
equal deleted inserted replaced
9371:f3840de881bd 9372:915436ff64ab
     1 #!/usr/bin/env python
       
     2 #
       
     3 # Check trace components in FreeType 2 source.
       
     4 # Author: suzuki toshiya, 2009
       
     5 #
       
     6 # This code is explicitly into the public domain.
       
     7 
       
     8 
       
     9 import sys
       
    10 import os
       
    11 import re
       
    12 
       
    13 SRC_FILE_LIST   = []
       
    14 USED_COMPONENT  = {}
       
    15 KNOWN_COMPONENT = {}
       
    16 
       
    17 SRC_FILE_DIRS   = [ "src" ]
       
    18 TRACE_DEF_FILES = [ "include/freetype/internal/fttrace.h" ]
       
    19 
       
    20 
       
    21 # --------------------------------------------------------------
       
    22 # Parse command line options
       
    23 #
       
    24 
       
    25 for i in range( 1, len( sys.argv ) ):
       
    26   if sys.argv[i].startswith( "--help" ):
       
    27     print "Usage: %s [option]" % sys.argv[0]
       
    28     print "Search used-but-defined and defined-but-not-used trace_XXX macros"
       
    29     print ""
       
    30     print "  --help:"
       
    31     print "        Show this help"
       
    32     print ""
       
    33     print "  --src-dirs=dir1:dir2:..."
       
    34     print "        Specify the directories of C source files to be checked"
       
    35     print "        Default is %s" % ":".join( SRC_FILE_DIRS )
       
    36     print ""
       
    37     print "  --def-files=file1:file2:..."
       
    38     print "        Specify the header files including FT_TRACE_DEF()"
       
    39     print "        Default is %s" % ":".join( TRACE_DEF_FILES )
       
    40     print ""
       
    41     exit(0)
       
    42   if sys.argv[i].startswith( "--src-dirs=" ):
       
    43     SRC_FILE_DIRS = sys.argv[i].replace( "--src-dirs=", "", 1 ).split( ":" )
       
    44   elif sys.argv[i].startswith( "--def-files=" ):
       
    45     TRACE_DEF_FILES = sys.argv[i].replace( "--def-files=", "", 1 ).split( ":" )
       
    46 
       
    47 
       
    48 # --------------------------------------------------------------
       
    49 # Scan C source and header files using trace macros.
       
    50 #
       
    51 
       
    52 c_pathname_pat = re.compile( '^.*\.[ch]$', re.IGNORECASE )
       
    53 trace_use_pat  = re.compile( '^[ \t]*#define[ \t]+FT_COMPONENT[ \t]+trace_' )
       
    54 
       
    55 for d in SRC_FILE_DIRS:
       
    56   for ( p, dlst, flst ) in os.walk( d ):
       
    57     for f in flst:
       
    58       if c_pathname_pat.match( f ) != None:
       
    59         src_pathname = os.path.join( p, f )
       
    60 
       
    61         line_num = 0
       
    62         for src_line in open( src_pathname, 'r' ):
       
    63           line_num = line_num + 1
       
    64           src_line = src_line.strip()
       
    65           if trace_use_pat.match( src_line ) != None:
       
    66             component_name = trace_use_pat.sub( '', src_line )
       
    67             if component_name in USED_COMPONENT:
       
    68               USED_COMPONENT[component_name].append( "%s:%d" % ( src_pathname, line_num ) )
       
    69             else:
       
    70               USED_COMPONENT[component_name] = [ "%s:%d" % ( src_pathname, line_num ) ]
       
    71 
       
    72 
       
    73 # --------------------------------------------------------------
       
    74 # Scan header file(s) defining trace macros.
       
    75 #
       
    76 
       
    77 trace_def_pat_opn = re.compile( '^.*FT_TRACE_DEF[ \t]*\([ \t]*' )
       
    78 trace_def_pat_cls = re.compile( '[ \t\)].*$' )
       
    79 
       
    80 for f in TRACE_DEF_FILES:
       
    81   line_num = 0
       
    82   for hdr_line in open( f, 'r' ):
       
    83     line_num = line_num + 1
       
    84     hdr_line = hdr_line.strip()
       
    85     if trace_def_pat_opn.match( hdr_line ) != None:
       
    86       component_name = trace_def_pat_opn.sub( '', hdr_line )
       
    87       component_name = trace_def_pat_cls.sub( '', component_name )
       
    88       if component_name in KNOWN_COMPONENT:
       
    89         print "trace component %s is defined twice, see %s and fttrace.h:%d" % \
       
    90           ( component_name, KNOWN_COMPONENT[component_name], line_num )
       
    91       else:
       
    92         KNOWN_COMPONENT[component_name] = "%s:%d" % \
       
    93           ( os.path.basename( f ), line_num )
       
    94 
       
    95 
       
    96 # --------------------------------------------------------------
       
    97 # Compare the used and defined trace macros.
       
    98 #
       
    99 
       
   100 print "# Trace component used in the implementations but not defined in fttrace.h."
       
   101 cmpnt = USED_COMPONENT.keys()
       
   102 cmpnt.sort()
       
   103 for c in cmpnt:
       
   104   if c not in KNOWN_COMPONENT:
       
   105     print "Trace component %s (used in %s) is not defined." % ( c, ", ".join( USED_COMPONENT[c] ) )
       
   106 
       
   107 print "# Trace component is defined but not used in the implementations."
       
   108 cmpnt = KNOWN_COMPONENT.keys()
       
   109 cmpnt.sort()
       
   110 for c in cmpnt:
       
   111   if c not in USED_COMPONENT:
       
   112     if c != "any":
       
   113       print "Trace component %s (defined in %s) is not used." % ( c, KNOWN_COMPONENT[c] )
       
   114