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 |
|