You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

592 lines
19 KiB

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