Add a script to check the undefined and unused trace macros.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
diff --git a/ChangeLog b/ChangeLog
index 53d474d..be8815c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2009-07-12 suzuki toshiya <mpsuzuki@hiroshima-u.ac.jp>
+
+ Add a script to check the undefined and unused trace macros.
+
+ * src/tools/chktrcmp.py: A script to check trace_XXXX macros
+ that are used in C source but undefined in fttrace.h, or
+ defined in fttrace.h but unused in C sources. See
+ http://lists.gnu.org/archive/html/freetype-devel/2009-07/msg00013.html.
+ * docs/DEBUG: Mention on chktrcmp.py.
+ * docs/release: Ditto.
+
2009-07-09 Werner Lemberg <wl@gnu.org>
[ftraster] Make it compile again with -D_STANDALONE_.
diff --git a/docs/DEBUG b/docs/DEBUG
index 1fccc21..3d6acd3 100644
--- a/docs/DEBUG
+++ b/docs/DEBUG
@@ -92,7 +92,10 @@ its code:
The value of the FT_COMPONENT macro is an enumeration named
trace_XXXX where XXXX is one of the component names defined in the
- internal file `freetype/internal/fttrace.h'.
+ internal file `freetype/internal/fttrace.h'. If you modify FreeType
+ source and insert new trace_XXXX macro, you must register it in
+ fttrace.h. If you insert or remove many trace macros, you can check
+ the undefined or the unused trace macro by src/tools/chktrcmp.py.
Each such component is assigned a `debug level', ranging from 0
to 7, through the use of the FT2_DEBUG environment variable
@@ -186,7 +189,7 @@ behaviour of FreeType at runtime.
------------------------------------------------------------------------
-Copyright 2002, 2003, 2004, 2005 by
+Copyright 2002, 2003, 2004, 2005, 2009 by
David Turner, Robert Wilhelm, and Werner Lemberg.
This file is part of the FreeType project, and may only be used,
diff --git a/docs/release b/docs/release
index e93f430..c6a535b 100644
--- a/docs/release
+++ b/docs/release
@@ -33,6 +33,8 @@ How to prepare a new release
. Test C++ compilation for ft2demos too.
+. Run src/tools/chktrcmp.py and check no undefined trace_XXXX macros.
+
. Tag the CVS (freetype2, ft2demos).
TODO: Tag the home page CVS on savannah.nongnu.org.
@@ -153,7 +155,7 @@ How to prepare a new release
----------------------------------------------------------------------
-Copyright 2003, 2005, 2006, 2007 by
+Copyright 2003, 2005, 2006, 2007, 2009 by
David Turner, Robert Wilhelm, and Werner Lemberg.
This file is part of the FreeType project, and may only be used,
diff --git a/src/tools/chktrcmp.py b/src/tools/chktrcmp.py
new file mode 100755
index 0000000..d0f342e
--- /dev/null
+++ b/src/tools/chktrcmp.py
@@ -0,0 +1,114 @@
+#!/usr/bin/env python
+#
+# Check trace components in FreeType 2 source.
+# Author: suzuki toshiya, 2009
+#
+# This code is explicitly into the public domain.
+
+
+import sys
+import os
+import re
+
+SRC_FILE_LIST = []
+USED_COMPONENT = {}
+KNOWN_COMPONENT = {}
+
+SRC_FILE_DIRS = [ "src" ]
+TRACE_DEF_FILES = [ "include/freetype/internal/fttrace.h" ]
+
+
+# --------------------------------------------------------------
+# Parse command line options
+#
+
+for i in range( 1, len( sys.argv ) ):
+ if sys.argv[i].startswith( "--help" ):
+ print "Usage: %s [option]" % sys.argv[0]
+ print "Search used-but-defined and defined-but-not-used trace_XXX macros"
+ print ""
+ print " --help:"
+ print " Show this help"
+ print ""
+ print " --src-dirs=dir1:dir2:..."
+ print " Specify the directories of C source files to be checked"
+ print " Default is %s" % ":".join( SRC_FILE_DIRS )
+ print ""
+ print " --def-files=file1:file2:..."
+ print " Specify the header files including FT_TRACE_DEF()"
+ print " Default is %s" % ":".join( TRACE_DEF_FILES )
+ print ""
+ exit(0)
+ if sys.argv[i].startswith( "--src-dirs=" ):
+ SRC_FILE_DIRS = sys.argv[i].replace( "--src-dirs=", "", 1 ).split( ":" )
+ elif sys.argv[i].startswith( "--def-files=" ):
+ TRACE_DEF_FILES = sys.argv[i].replace( "--def-files=", "", 1 ).split( ":" )
+
+
+# --------------------------------------------------------------
+# Scan C source and header files using trace macros.
+#
+
+c_pathname_pat = re.compile( '^.*\.[ch]$', re.IGNORECASE )
+trace_use_pat = re.compile( '^[ \t]*#define[ \t]+FT_COMPONENT[ \t]+trace_' )
+
+for d in SRC_FILE_DIRS:
+ for ( p, dlst, flst ) in os.walk( d ):
+ for f in flst:
+ if c_pathname_pat.match( f ) != None:
+ src_pathname = os.path.join( p, f )
+
+ line_num = 0
+ for src_line in open( src_pathname, 'r' ):
+ line_num = line_num + 1
+ src_line = src_line.strip()
+ if trace_use_pat.match( src_line ) != None:
+ component_name = trace_use_pat.sub( '', src_line )
+ if component_name in USED_COMPONENT:
+ USED_COMPONENT[component_name].append( "%s:%d" % ( src_pathname, line_num ) )
+ else:
+ USED_COMPONENT[component_name] = [ "%s:%d" % ( src_pathname, line_num ) ]
+
+
+# --------------------------------------------------------------
+# Scan header file(s) defining trace macros.
+#
+
+trace_def_pat_opn = re.compile( '^.*FT_TRACE_DEF[ \t]*\([ \t]*' )
+trace_def_pat_cls = re.compile( '[ \t\)].*$' )
+
+for f in TRACE_DEF_FILES:
+ line_num = 0
+ for hdr_line in open( f, 'r' ):
+ line_num = line_num + 1
+ hdr_line = hdr_line.strip()
+ if trace_def_pat_opn.match( hdr_line ) != None:
+ component_name = trace_def_pat_opn.sub( '', hdr_line )
+ component_name = trace_def_pat_cls.sub( '', component_name )
+ if component_name in KNOWN_COMPONENT:
+ print "trace component %s is defined twice, see %s and fttrace.h:%d" % \
+ ( component_name, KNOWN_COMPONENT[component_name], line_num )
+ else:
+ KNOWN_COMPONENT[component_name] = "%s:%d" % \
+ ( os.path.basename( f ), line_num )
+
+
+# --------------------------------------------------------------
+# Compare the used and defined trace macros.
+#
+
+print "# Trace component used in the implementations but not defined in fttrace.h."
+cmpnt = USED_COMPONENT.keys()
+cmpnt.sort()
+for c in cmpnt:
+ if c not in KNOWN_COMPONENT:
+ print "Trace component %s (used in %s) is not defined." % ( c, ", ".join( USED_COMPONENT[c] ) )
+
+print "# Trace component is defined but not used in the implementations."
+cmpnt = KNOWN_COMPONENT.keys()
+cmpnt.sort()
+for c in cmpnt:
+ if c not in USED_COMPONENT:
+ if c != "any":
+ print "Trace component %s (defined in %s) is not used." % ( c, KNOWN_COMPONENT[c] )
+