3 # Check trace components in FreeType 2 source.
4 # Author: suzuki toshiya, 2009
6 # This code is explicitly into the public domain.
17 SRC_FILE_DIRS
= [ "src" ]
18 TRACE_DEF_FILES
= [ "include/freetype/internal/fttrace.h" ]
21 # --------------------------------------------------------------
22 # Parse command line options
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"
31 print " Show this help"
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
)
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
)
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( ":" )
48 # --------------------------------------------------------------
49 # Scan C source and header files using trace macros.
52 c_pathname_pat
= re
.compile( '^.*\.[ch]$', re
.IGNORECASE
)
53 trace_use_pat
= re
.compile( '^[ \t]*#define[ \t]+FT_COMPONENT[ \t]+trace_' )
55 for d
in SRC_FILE_DIRS
:
56 for ( p
, dlst
, flst
) in os
.walk( d
):
58 if c_pathname_pat
.match( f
) != None:
59 src_pathname
= os
.path
.join( p
, f
)
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
) )
70 USED_COMPONENT
[component_name
] = [ "%s:%d" % ( src_pathname
, line_num
) ]
73 # --------------------------------------------------------------
74 # Scan header file(s) defining trace macros.
77 trace_def_pat_opn
= re
.compile( '^.*FT_TRACE_DEF[ \t]*\([ \t]*' )
78 trace_def_pat_cls
= re
.compile( '[ \t\)].*$' )
80 for f
in TRACE_DEF_FILES
:
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
)
92 KNOWN_COMPONENT
[component_name
] = "%s:%d" % \
93 ( os
.path
.basename( f
), line_num
)
96 # --------------------------------------------------------------
97 # Compare the used and defined trace macros.
100 print "# Trace component used in the implementations but not defined in fttrace.h."
101 cmpnt
= USED_COMPONENT
.keys()
104 if c
not in KNOWN_COMPONENT
:
105 print "Trace component %s (used in %s) is not defined." % ( c
, ", ".join( USED_COMPONENT
[c
] ) )
107 print "# Trace component is defined but not used in the implementations."
108 cmpnt
= KNOWN_COMPONENT
.keys()
111 if c
not in USED_COMPONENT
:
113 print "Trace component %s (defined in %s) is not used." % ( c
, KNOWN_COMPONENT
[c
] )