zenilib  0.5.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
chktrcmp.py
Go to the documentation of this file.
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