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