SCons.Scanner.C

Package SCons :: Package Scanner :: Module C |
[hide private]
[frames] | no frames]

# Source Code for Module SCons.Scanner.C

      1  """SCons.Scanner.C
      2
      3  This module implements the depenency scanner for C/C++ code.
      4
      5  """
      6
      7  #
      8  # Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
      9  #
     10  # Permission is hereby granted, free of charge, to any person obtaining
     11  # a copy of this software and associated documentation files (the
     12  # "Software"), to deal in the Software without restriction, including
     13  # without limitation the rights to use, copy, modify, merge, publish,
     14  # distribute, sublicense, and/or sell copies of the Software, and to
     15  # permit persons to whom the Software is furnished to do so, subject to
     16  # the following conditions:
     17  #
     18  # The above copyright notice and this permission notice shall be included
     19  # in all copies or substantial portions of the Software.
     20  #
     21  # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
     22  # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
     23  # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     24  # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
     25  # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
     26  # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
     27  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     28  #
     29
     30  __revision__ = "src/engine/SCons/Scanner/C.py 2725 2008/03/31 12:52:02 knight"
     31
     32  import SCons.Node.FS
     33  import SCons.Scanner
     34  import SCons.Util
     35
     36  import SCons.cpp
     37
     38 -class SConsCPPScanner(SCons.cpp.PreProcessor):
     39      """
     40      SCons-specific subclass of the cpp.py module's processing.
     41
     42      We subclass this so that: 1) we can deal with files represented
     43      by Nodes, not strings; 2) we can keep track of the files that are
     44      missing.
     45      """
     46 -    def __init__(self, *args, **kw):
     47          apply(SCons.cpp.PreProcessor.__init__, (self,)+args, kw)
     48          self.missing = []
     49 -    def initialize_result(self, fname):
     50          self.result = SCons.Util.UniqueList([fname])
     51 -    def finalize_result(self, fname):
     52          return self.result[1:]
     53 -    def find_include_file(self, t):
     54          keyword, quote, fname = t
     55          result = SCons.Node.FS.find_file(fname, self.searchpath[quote])
     56          if not result:
     57              self.missing.append((fname, self.current_file))
     58          return result
     59 -    def read_file(self, file):
     60          try:
     61              fp = open(str(file.rfile()))
     62          except EnvironmentError, e:
     63              self.missing.append((file, self.current_file))
     64              return ''
     65          else:
     66              return fp.read()
     67
     68 -def dictify_CPPDEFINES(env):
     69      cppdefines = env.get('CPPDEFINES', {})
     70      if cppdefines is None:
     71          return {}
     72      if SCons.Util.is_Sequence(cppdefines):
     73          result = {}
     74          for c in cppdefines:
     75              if SCons.Util.is_Sequence(c):
     76                  result[c[0]] = c[1]
     77              else:
     78                  result[c] = None
     79          return result
     80      if not SCons.Util.is_Dict(cppdefines):
     81          return {cppdefines : None}
     82      return cppdefines
     83
     84 -class SConsCPPScannerWrapper:
     85      """
     86      The SCons wrapper around a cpp.py scanner.
     87
     88      This is the actual glue between the calling conventions of generic
     89      SCons scanners, and the (subclass of) cpp.py class that knows how
     90      to look for #include lines with reasonably real C-preprocessor-like
     91      evaluation of #if/#ifdef/#else/#elif lines.
     92      """
     93 -    def __init__(self, name, variable):
     94          self.name = name
     95          self.path = SCons.Scanner.FindPathDirs(variable)
     96 -    def __call__(self, node, env, path = ()):
     97          cpp = SConsCPPScanner(current = node.get_dir(),
     98                                cpppath = path,
     99                                dict = dictify_CPPDEFINES(env))
    100          result = cpp(node)
    101          for included, includer in cpp.missing:
    102              fmt = "No dependency generated for file: %s (included from: %s) -- file not found"
    103              SCons.Warnings.warn(SCons.Warnings.DependencyWarning,
    104                                  fmt % (included, includer))
    105          return result
    106
    107 -    def recurse_nodes(self, nodes):
    108          return nodes
    109 -    def select(self, node):
    110          return self
    111
    112 -def CScanner():
    113      """Return a prototype Scanner instance for scanning source files
    114      that use the C pre-processor"""
    115
    116      # Here's how we would (or might) use the CPP scanner code above that
    117      # knows how to evaluate #if/#ifdef/#else/#elif lines when searching
    118      # for #includes.  This is commented out for now until we add the
    119      # right configurability to let users pick between the scanners.
    120      #return SConsCPPScannerWrapper("CScanner", "CPPPATH")
    121
    122      cs = SCons.Scanner.ClassicCPP("CScanner",
    123                                    "$CPPSUFFIXES",
    124                                    "CPPPATH",
    125                                    '^[ \t]*#[ \t]*(?:include|import)[ \t]*(<|")([^>"]+)(>|")')
    126      return cs
    127