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