cpp.py.svn-base
上传用户:market2
上传日期:2018-11-18
资源大小:18786k
文件大小:19k
源码类别:

外挂编程

开发平台:

Windows_Unix

  1. #
  2. # Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
  3. #
  4. # Permission is hereby granted, free of charge, to any person obtaining
  5. # a copy of this software and associated documentation files (the
  6. # "Software"), to deal in the Software without restriction, including
  7. # without limitation the rights to use, copy, modify, merge, publish,
  8. # distribute, sublicense, and/or sell copies of the Software, and to
  9. # permit persons to whom the Software is furnished to do so, subject to
  10. # the following conditions:
  11. #
  12. # The above copyright notice and this permission notice shall be included
  13. # in all copies or substantial portions of the Software.
  14. #
  15. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
  16. # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  17. # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  18. # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  19. # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  20. # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  21. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22. #
  23. __revision__ = "src/engine/SCons/cpp.py 3057 2008/06/09 22:21:00 knight"
  24. __doc__ = """
  25. SCons C Pre-Processor module
  26. """
  27. import SCons.compat
  28. import os
  29. import re
  30. import string
  31. #
  32. # First "subsystem" of regular expressions that we set up:
  33. #
  34. # Stuff to turn the C preprocessor directives in a file's contents into
  35. # a list of tuples that we can process easily.
  36. #
  37. # A table of regular expressions that fetch the arguments from the rest of
  38. # a C preprocessor line.  Different directives have different arguments
  39. # that we want to fetch, using the regular expressions to which the lists
  40. # of preprocessor directives map.
  41. cpp_lines_dict = {
  42.     # Fetch the rest of a #if/#elif/#ifdef/#ifndef as one argument,
  43.     # separated from the keyword by white space.
  44.     ('if', 'elif', 'ifdef', 'ifndef',)
  45.                         : 's+(.+)',
  46.     # Fetch the rest of a #import/#include/#include_next line as one
  47.     # argument, with white space optional.
  48.     ('import', 'include', 'include_next',)
  49.                         : 's*(.+)',
  50.     # We don't care what comes after a #else or #endif line.
  51.     ('else', 'endif',)  : '',
  52.     # Fetch three arguments from a #define line:
  53.     #   1) The #defined keyword.
  54.     #   2) The optional parentheses and arguments (if it's a function-like
  55.     #      macro, '' if it's not).
  56.     #   3) The expansion value.
  57.     ('define',)         : 's+([_A-Za-z][_A-Za-z0-9_]+)(([^)]*))?s*(.*)',
  58.     # Fetch the #undefed keyword from a #undef line.
  59.     ('undef',)          : 's+([_A-Za-z][A-Za-z0-9_]+)',
  60. }
  61. # Create a table that maps each individual C preprocessor directive to
  62. # the corresponding compiled regular expression that fetches the arguments
  63. # we care about.
  64. Table = {}
  65. for op_list, expr in cpp_lines_dict.items():
  66.     e = re.compile(expr)
  67.     for op in op_list:
  68.         Table[op] = e
  69. del e
  70. del op
  71. del op_list
  72. # Create a list of the expressions we'll use to match all of the
  73. # preprocessor directives.  These are the same as the directives
  74. # themselves *except* that we must use a negative lookahead assertion
  75. # when matching "if" so it doesn't match the "if" in "ifdef."
  76. override = {
  77.     'if'                        : 'if(?!def)',
  78. }
  79. l = map(lambda x, o=override: o.get(x, x), Table.keys())
  80. # Turn the list of expressions into one big honkin' regular expression
  81. # that will match all the preprocessor lines at once.  This will return
  82. # a list of tuples, one for each preprocessor line.  The preprocessor
  83. # directive will be the first element in each tuple, and the rest of
  84. # the line will be the second element.
  85. e = '^s*#s*(' + string.join(l, '|') + ')(.*)$'
  86. # And last but not least, compile the expression.
  87. CPP_Expression = re.compile(e, re.M)
  88. #
  89. # Second "subsystem" of regular expressions that we set up:
  90. #
  91. # Stuff to translate a C preprocessor expression (as found on a #if or
  92. # #elif line) into an equivalent Python expression that we can eval().
  93. #
  94. # A dictionary that maps the C representation of Boolean operators
  95. # to their Python equivalents.
  96. CPP_to_Python_Ops_Dict = {
  97.     '!'         : ' not ',
  98.     '!='        : ' != ',
  99.     '&&'        : ' and ',
  100.     '||'        : ' or ',
  101.     '?'         : ' and ',
  102.     ':'         : ' or ',
  103.     'r'        : '',
  104. }
  105. CPP_to_Python_Ops_Sub = lambda m, d=CPP_to_Python_Ops_Dict: d[m.group(0)]
  106. # We have to sort the keys by length so that longer expressions
  107. # come *before* shorter expressions--in particular, "!=" must
  108. # come before "!" in the alternation.  Without this, the Python
  109. # re module, as late as version 2.2.2, empirically matches the
  110. # "!" in "!=" first, instead of finding the longest match.
  111. # What's up with that?
  112. l = CPP_to_Python_Ops_Dict.keys()
  113. l.sort(lambda a, b: cmp(len(b), len(a)))
  114. # Turn the list of keys into one regular expression that will allow us
  115. # to substitute all of the operators at once.
  116. expr = string.join(map(re.escape, l), '|')
  117. # ...and compile the expression.
  118. CPP_to_Python_Ops_Expression = re.compile(expr)
  119. # A separate list of expressions to be evaluated and substituted
  120. # sequentially, not all at once.
  121. CPP_to_Python_Eval_List = [
  122.     ['defineds+(w+)',         '__dict__.has_key("\1")'],
  123.     ['defineds*((w+))',     '__dict__.has_key("\1")'],
  124.     ['/*.**/',                ''],
  125.     ['/*.*',                   ''],
  126.     ['//.*',                    ''],
  127.     ['(0x[0-9A-Fa-f]*)[UL]+',   '\1L'],
  128. ]
  129. # Replace the string representations of the regular expressions in the
  130. # list with compiled versions.
  131. for l in CPP_to_Python_Eval_List:
  132.     l[0] = re.compile(l[0])
  133. # Wrap up all of the above into a handy function.
  134. def CPP_to_Python(s):
  135.     """
  136.     Converts a C pre-processor expression into an equivalent
  137.     Python expression that can be evaluated.
  138.     """
  139.     s = CPP_to_Python_Ops_Expression.sub(CPP_to_Python_Ops_Sub, s)
  140.     for expr, repl in CPP_to_Python_Eval_List:
  141.         s = expr.sub(repl, s)
  142.     return s
  143. del expr
  144. del l
  145. del override
  146. class FunctionEvaluator:
  147.     """
  148.     Handles delayed evaluation of a #define function call.
  149.     """
  150.     def __init__(self, name, args, expansion):
  151.         """
  152.         Squirrels away the arguments and expansion value of a #define
  153.         macro function for later evaluation when we must actually expand
  154.         a value that uses it.
  155.         """
  156.         self.name = name
  157.         self.args = function_arg_separator.split(args)
  158.         try:
  159.             expansion = string.split(expansion, '##')
  160.         except (AttributeError, TypeError):
  161.             # Python 1.5 throws TypeError if "expansion" isn't a string,
  162.             # later versions throw AttributeError.
  163.             pass
  164.         self.expansion = expansion
  165.     def __call__(self, *values):
  166.         """
  167.         Evaluates the expansion of a #define macro function called
  168.         with the specified values.
  169.         """
  170.         if len(self.args) != len(values):
  171.             raise ValueError, "Incorrect number of arguments to `%s'" % self.name
  172.         # Create a dictionary that maps the macro arguments to the
  173.         # corresponding values in this "call."  We'll use this when we
  174.         # eval() the expansion so that arguments will get expanded to
  175.         # the right values.
  176.         locals = {}
  177.         for k, v in zip(self.args, values):
  178.             locals[k] = v
  179.         parts = []
  180.         for s in self.expansion:
  181.             if not s in self.args:
  182.                 s = repr(s)
  183.             parts.append(s)
  184.         statement = string.join(parts, ' + ')
  185.         return eval(statement, globals(), locals)
  186. # Find line continuations.
  187. line_continuations = re.compile('\\r?n')
  188. # Search for a "function call" macro on an expansion.  Returns the
  189. # two-tuple of the "function" name itself, and a string containing the
  190. # arguments within the call parentheses.
  191. function_name = re.compile('(S+)(([^)]*))')
  192. # Split a string containing comma-separated function call arguments into
  193. # the separate arguments.
  194. function_arg_separator = re.compile(',s*')
  195. class PreProcessor:
  196.     """
  197.     The main workhorse class for handling C pre-processing.
  198.     """
  199.     def __init__(self, current=os.curdir, cpppath=(), dict={}, all=0):
  200.         global Table
  201.         cpppath = tuple(cpppath)
  202.         self.searchpath = {
  203.             '"' :       (current,) + cpppath,
  204.             '<' :       cpppath + (current,),
  205.         }
  206.         # Initialize our C preprocessor namespace for tracking the
  207.         # values of #defined keywords.  We use this namespace to look
  208.         # for keywords on #ifdef/#ifndef lines, and to eval() the
  209.         # expressions on #if/#elif lines (after massaging them from C to
  210.         # Python).
  211.         self.cpp_namespace = dict.copy()
  212.         self.cpp_namespace['__dict__'] = self.cpp_namespace
  213.         if all:
  214.            self.do_include = self.all_include
  215.         # For efficiency, a dispatch table maps each C preprocessor
  216.         # directive (#if, #define, etc.) to the method that should be
  217.         # called when we see it.  We accomodate state changes (#if,
  218.         # #ifdef, #ifndef) by pushing the current dispatch table on a
  219.         # stack and changing what method gets called for each relevant
  220.         # directive we might see next at this level (#else, #elif).
  221.         # #endif will simply pop the stack.
  222.         d = {
  223.             'scons_current_file'    : self.scons_current_file
  224.         }
  225.         for op in Table.keys():
  226.             d[op] = getattr(self, 'do_' + op)
  227.         self.default_table = d
  228.     # Controlling methods.
  229.     def tupleize(self, contents):
  230.         """
  231.         Turns the contents of a file into a list of easily-processed
  232.         tuples describing the CPP lines in the file.
  233.         The first element of each tuple is the line's preprocessor
  234.         directive (#if, #include, #define, etc., minus the initial '#').
  235.         The remaining elements are specific to the type of directive, as
  236.         pulled apart by the regular expression.
  237.         """
  238.         global CPP_Expression, Table
  239.         contents = line_continuations.sub('', contents)
  240.         cpp_tuples = CPP_Expression.findall(contents)
  241.         return  map(lambda m, t=Table:
  242.                            (m[0],) + t[m[0]].match(m[1]).groups(),
  243.                     cpp_tuples)
  244.     def __call__(self, file):
  245.         """
  246.         Pre-processes a file.
  247.         This is the main public entry point.
  248.         """
  249.         self.current_file = file
  250.         return self.process_contents(self.read_file(file), file)
  251.     def process_contents(self, contents, fname=None):
  252.         """
  253.         Pre-processes a file contents.
  254.         This is the main internal entry point.
  255.         """
  256.         self.stack = []
  257.         self.dispatch_table = self.default_table.copy()
  258.         self.current_file = fname
  259.         self.tuples = self.tupleize(contents)
  260.         self.initialize_result(fname)
  261.         while self.tuples:
  262.             t = self.tuples.pop(0)
  263.             # Uncomment to see the list of tuples being processed (e.g.,
  264.             # to validate the CPP lines are being translated correctly).
  265.             #print t
  266.             self.dispatch_table[t[0]](t)
  267.         return self.finalize_result(fname)
  268.     # Dispatch table stack manipulation methods.
  269.     def save(self):
  270.         """
  271.         Pushes the current dispatch table on the stack and re-initializes
  272.         the current dispatch table to the default.
  273.         """
  274.         self.stack.append(self.dispatch_table)
  275.         self.dispatch_table = self.default_table.copy()
  276.     def restore(self):
  277.         """
  278.         Pops the previous dispatch table off the stack and makes it the
  279.         current one.
  280.         """
  281.         try: self.dispatch_table = self.stack.pop()
  282.         except IndexError: pass
  283.     # Utility methods.
  284.     def do_nothing(self, t):
  285.         """
  286.         Null method for when we explicitly want the action for a
  287.         specific preprocessor directive to do nothing.
  288.         """
  289.         pass
  290.     def scons_current_file(self, t):
  291.         self.current_file = t[1]
  292.     def eval_expression(self, t):
  293.         """
  294.         Evaluates a C preprocessor expression.
  295.         This is done by converting it to a Python equivalent and
  296.         eval()ing it in the C preprocessor namespace we use to
  297.         track #define values.
  298.         """
  299.         t = CPP_to_Python(string.join(t[1:]))
  300.         try: return eval(t, self.cpp_namespace)
  301.         except (NameError, TypeError): return 0
  302.     def initialize_result(self, fname):
  303.         self.result = [fname]
  304.     def finalize_result(self, fname):
  305.         return self.result[1:]
  306.     def find_include_file(self, t):
  307.         """
  308.         Finds the #include file for a given preprocessor tuple.
  309.         """
  310.         fname = t[2]
  311.         for d in self.searchpath[t[1]]:
  312.             if d == os.curdir:
  313.                 f = fname
  314.             else:
  315.                 f = os.path.join(d, fname)
  316.             if os.path.isfile(f):
  317.                 return f
  318.         return None
  319.     def read_file(self, file):
  320.         return open(file).read()
  321.     # Start and stop processing include lines.
  322.     def start_handling_includes(self, t=None):
  323.         """
  324.         Causes the PreProcessor object to start processing #import,
  325.         #include and #include_next lines.
  326.         This method will be called when a #if, #ifdef, #ifndef or #elif
  327.         evaluates True, or when we reach the #else in a #if, #ifdef,
  328.         #ifndef or #elif block where a condition already evaluated
  329.         False.
  330.         """
  331.         d = self.dispatch_table
  332.         d['import'] = self.do_import
  333.         d['include'] =  self.do_include
  334.         d['include_next'] =  self.do_include
  335.     def stop_handling_includes(self, t=None):
  336.         """
  337.         Causes the PreProcessor object to stop processing #import,
  338.         #include and #include_next lines.
  339.         This method will be called when a #if, #ifdef, #ifndef or #elif
  340.         evaluates False, or when we reach the #else in a #if, #ifdef,
  341.         #ifndef or #elif block where a condition already evaluated True.
  342.         """
  343.         d = self.dispatch_table
  344.         d['import'] = self.do_nothing
  345.         d['include'] =  self.do_nothing
  346.         d['include_next'] =  self.do_nothing
  347.     # Default methods for handling all of the preprocessor directives.
  348.     # (Note that what actually gets called for a given directive at any
  349.     # point in time is really controlled by the dispatch_table.)
  350.     def _do_if_else_condition(self, condition):
  351.         """
  352.         Common logic for evaluating the conditions on #if, #ifdef and
  353.         #ifndef lines.
  354.         """
  355.         self.save()
  356.         d = self.dispatch_table
  357.         if condition:
  358.             self.start_handling_includes()
  359.             d['elif'] = self.stop_handling_includes
  360.             d['else'] = self.stop_handling_includes
  361.         else:
  362.             self.stop_handling_includes()
  363.             d['elif'] = self.do_elif
  364.             d['else'] = self.start_handling_includes
  365.     def do_ifdef(self, t):
  366.         """
  367.         Default handling of a #ifdef line.
  368.         """
  369.         self._do_if_else_condition(self.cpp_namespace.has_key(t[1]))
  370.     def do_ifndef(self, t):
  371.         """
  372.         Default handling of a #ifndef line.
  373.         """
  374.         self._do_if_else_condition(not self.cpp_namespace.has_key(t[1]))
  375.     def do_if(self, t):
  376.         """
  377.         Default handling of a #if line.
  378.         """
  379.         self._do_if_else_condition(self.eval_expression(t))
  380.     def do_elif(self, t):
  381.         """
  382.         Default handling of a #elif line.
  383.         """
  384.         d = self.dispatch_table
  385.         if self.eval_expression(t):
  386.             self.start_handling_includes()
  387.             d['elif'] = self.stop_handling_includes
  388.             d['else'] = self.stop_handling_includes
  389.     def do_else(self, t):
  390.         """
  391.         Default handling of a #else line.
  392.         """
  393.         pass
  394.     def do_endif(self, t):
  395.         """
  396.         Default handling of a #endif line.
  397.         """
  398.         self.restore()
  399.     def do_define(self, t):
  400.         """
  401.         Default handling of a #define line.
  402.         """
  403.         _, name, args, expansion = t
  404.         try:
  405.             expansion = int(expansion)
  406.         except (TypeError, ValueError):
  407.             pass
  408.         if args:
  409.             evaluator = FunctionEvaluator(name, args[1:-1], expansion)
  410.             self.cpp_namespace[name] = evaluator
  411.         else:
  412.             self.cpp_namespace[name] = expansion
  413.     def do_undef(self, t):
  414.         """
  415.         Default handling of a #undef line.
  416.         """
  417.         try: del self.cpp_namespace[t[1]]
  418.         except KeyError: pass
  419.     def do_import(self, t):
  420.         """
  421.         Default handling of a #import line.
  422.         """
  423.         # XXX finish this -- maybe borrow/share logic from do_include()...?
  424.         pass
  425.     def do_include(self, t):
  426.         """
  427.         Default handling of a #include line.
  428.         """
  429.         t = self.resolve_include(t)
  430.         include_file = self.find_include_file(t)
  431.         if include_file:
  432.             #print "include_file =", include_file
  433.             self.result.append(include_file)
  434.             contents = self.read_file(include_file)
  435.             new_tuples = [('scons_current_file', include_file)] + 
  436.                          self.tupleize(contents) + 
  437.                          [('scons_current_file', self.current_file)]
  438.             self.tuples[:] = new_tuples + self.tuples
  439.     # Date: Tue, 22 Nov 2005 20:26:09 -0500
  440.     # From: Stefan Seefeld <seefeld@sympatico.ca>
  441.     #
  442.     # By the way, #include_next is not the same as #include. The difference
  443.     # being that #include_next starts its search in the path following the
  444.     # path that let to the including file. In other words, if your system
  445.     # include paths are ['/foo', '/bar'], and you are looking at a header
  446.     # '/foo/baz.h', it might issue an '#include_next <baz.h>' which would
  447.     # correctly resolve to '/bar/baz.h' (if that exists), but *not* see
  448.     # '/foo/baz.h' again. See http://www.delorie.com/gnu/docs/gcc/cpp_11.html
  449.     # for more reasoning.
  450.     #
  451.     # I have no idea in what context 'import' might be used.
  452.     # XXX is #include_next really the same as #include ?
  453.     do_include_next = do_include
  454.     # Utility methods for handling resolution of include files.
  455.     def resolve_include(self, t):
  456.         """Resolve a tuple-ized #include line.
  457.         This handles recursive expansion of values without "" or <>
  458.         surrounding the name until an initial " or < is found, to handle
  459.                 #include FILE
  460.         where FILE is a #define somewhere else.
  461.         """
  462.         s = t[1]
  463.         while not s[0] in '<"':
  464.             #print "s =", s
  465.             try:
  466.                 s = self.cpp_namespace[s]
  467.             except KeyError:
  468.                 m = function_name.search(s)
  469.                 s = self.cpp_namespace[m.group(1)]
  470.                 if callable(s):
  471.                     args = function_arg_separator.split(m.group(2))
  472.                     s = apply(s, args)
  473.             if not s:
  474.                 return None
  475.         return (t[0], s[0], s[1:-1])
  476.     def all_include(self, t):
  477.         """
  478.         """
  479.         self.result.append(self.resolve_include(t))
  480. class DumbPreProcessor(PreProcessor):
  481.     """A preprocessor that ignores all #if/#elif/#else/#endif directives
  482.     and just reports back *all* of the #include files (like the classic
  483.     SCons scanner did).
  484.     This is functionally equivalent to using a regular expression to
  485.     find all of the #include lines, only slower.  It exists mainly as
  486.     an example of how the main PreProcessor class can be sub-classed
  487.     to tailor its behavior.
  488.     """
  489.     def __init__(self, *args, **kw):
  490.         apply(PreProcessor.__init__, (self,)+args, kw)
  491.         d = self.default_table
  492.         for func in ['if', 'elif', 'else', 'endif', 'ifdef', 'ifndef']:
  493.             d[func] = d[func] = self.do_nothing
  494. del __revision__