c_dumbpreproc.py 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. #!/usr/bin/env python
  2. # encoding: utf-8
  3. # Thomas Nagy, 2006-2010 (ita)
  4. """
  5. Dumb C/C++ preprocessor for finding dependencies
  6. It will look at all include files it can find after removing the comments, so the following
  7. will always add the dependency on both "a.h" and "b.h"::
  8. #include "a.h"
  9. #ifdef B
  10. #include "b.h"
  11. #endif
  12. int main() {
  13. return 0;
  14. }
  15. To use::
  16. def configure(conf):
  17. conf.load('compiler_c')
  18. conf.load('c_dumbpreproc')
  19. """
  20. import re
  21. from waflib.Tools import c_preproc
  22. re_inc = re.compile(
  23. '^[ \t]*(#|%:)[ \t]*(include)[ \t]*[<"](.*)[>"]\r*$',
  24. re.IGNORECASE | re.MULTILINE)
  25. def lines_includes(node):
  26. code = node.read()
  27. if c_preproc.use_trigraphs:
  28. for (a, b) in c_preproc.trig_def:
  29. code = code.split(a).join(b)
  30. code = c_preproc.re_nl.sub('', code)
  31. code = c_preproc.re_cpp.sub(c_preproc.repl, code)
  32. return [(m.group(2), m.group(3)) for m in re.finditer(re_inc, code)]
  33. parser = c_preproc.c_parser
  34. class dumb_parser(parser):
  35. def addlines(self, node):
  36. if node in self.nodes[:-1]:
  37. return
  38. self.currentnode_stack.append(node.parent)
  39. # Avoid reading the same files again
  40. try:
  41. lines = self.parse_cache[node]
  42. except KeyError:
  43. lines = self.parse_cache[node] = lines_includes(node)
  44. self.lines = lines + [(c_preproc.POPFILE, '')] + self.lines
  45. def start(self, node, env):
  46. try:
  47. self.parse_cache = node.ctx.parse_cache
  48. except AttributeError:
  49. self.parse_cache = node.ctx.parse_cache = {}
  50. self.addlines(node)
  51. while self.lines:
  52. (x, y) = self.lines.pop(0)
  53. if x == c_preproc.POPFILE:
  54. self.currentnode_stack.pop()
  55. continue
  56. self.tryfind(y)
  57. c_preproc.c_parser = dumb_parser