From fb0f6ed5eada02ca13fef60bcde8b216f39eb7f8 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Sun, 5 Aug 2012 01:33:11 +0200 Subject: [PATCH] Issue 1186 --- waflib/Tools/c_preproc.py | 4 +-- waflib/Tools/winres.py | 65 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 66 insertions(+), 3 deletions(-) diff --git a/waflib/Tools/c_preproc.py b/waflib/Tools/c_preproc.py index 63b902c4..945644e3 100644 --- a/waflib/Tools/c_preproc.py +++ b/waflib/Tools/c_preproc.py @@ -26,8 +26,8 @@ A dumb preprocessor is also available in the tool *c_dumbpreproc* """ # TODO: more varargs, pragma once -import re, sys, os, string, traceback -from waflib import Logs, Build, Utils, Errors +import re, string, traceback +from waflib import Logs, Utils, Errors from waflib.Logs import debug, error class PreprocError(Errors.WafError): diff --git a/waflib/Tools/winres.py b/waflib/Tools/winres.py index f54c090a..ddddd949 100644 --- a/waflib/Tools/winres.py +++ b/waflib/Tools/winres.py @@ -4,8 +4,10 @@ "Process *.rc* files for C/C++: X{.rc -> [.res|.rc.o]}" -from waflib import Task +import re, traceback +from waflib import Task, Logs, Utils from waflib.TaskGen import extension +from waflib.Tools import c_preproc @extension('.rc') def rc_file(self, node): @@ -21,6 +23,56 @@ def rc_file(self, node): except AttributeError: self.compiled_tasks = [rctask] +re_lines = re.compile( + '(?:^[ \t]*(#|%:)[ \t]*(ifdef|ifndef|if|else|elif|endif|include|import|define|undef|pragma)[ \t]*(.*?)\s*$)|'\ + '(?:^\w+[ \t]*(ICON|BITMAP|CURSOR|HTML|FONT|MESSAGETABLE|TYPELIB|REGISTRY|D3DFX)[ \t]*(.*?)\s*$)', + re.IGNORECASE | re.MULTILINE) + +class rc_parser(c_preproc.c_parser): + def filter_comments(self, filepath): + code = Utils.readf(filepath) + if c_preproc.use_trigraphs: + for (a, b) in c_preproc.trig_def: code = code.split(a).join(b) + code = c_preproc.re_nl.sub('', code) + code = c_preproc.re_cpp.sub(c_preproc.repl, code) + ret = [] + for m in re.finditer(re_lines, code): + if m.group(2): + ret.append((m.group(2), m.group(3))) + else: + ret.append(('include', m.group(5))) + return ret + + def addlines(self, node): + self.currentnode_stack.append(node.parent) + filepath = node.abspath() + + self.count_files += 1 + if self.count_files > c_preproc.recursion_limit: + raise c_preproc.PreprocError("recursion limit exceeded") + pc = self.parse_cache + Logs.debug('preproc: reading file %r', filepath) + try: + lns = pc[filepath] + except KeyError: + pass + else: + self.lines.extend(lns) + return + + try: + lines = self.filter_comments(filepath) + lines.append((c_preproc.POPFILE, '')) + lines.reverse() + pc[filepath] = lines + self.lines.extend(lines) + except IOError: + raise c_preproc.PreprocError("could not read the file %s" % filepath) + except Exception: + if Logs.verbose > 0: + Logs.error("parsing %s failed" % filepath) + traceback.print_exc() + class winrc(Task.Task): """ Task for compiling resource files @@ -28,6 +80,17 @@ class winrc(Task.Task): run_str = '${WINRC} ${WINRCFLAGS} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${WINRC_TGT_F} ${TGT} ${WINRC_SRC_F} ${SRC}' color = 'BLUE' + def scan(self): + tmp = rc_parser(self.generator.includes_nodes) + tmp.start(self.inputs[0], self.env) + nodes = tmp.nodes + names = tmp.names + + if Logs.verbose: + Logs.debug('deps: deps for %s: %r; unresolved %r' % (str(self), nodes, names)) + + return (nodes, names) + def configure(conf): """ Detect the programs RC or windres, depending on the C/C++ compiler in use