From: Chia-I Wu <o...@lunarg.com> ParseSourcesMak() parses sources.mak in the source directory and returns the files defined by the specified variables. It can be used like
sources = env.ParseSourcesMak(['C_SOURCES']) --- scons/custom.py | 19 ++++++++++ scons/sources_mak.py | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 115 insertions(+), 0 deletions(-) create mode 100644 scons/sources_mak.py diff --git a/scons/custom.py b/scons/custom.py index df7ac93..2ddd0a2 100644 --- a/scons/custom.py +++ b/scons/custom.py @@ -42,6 +42,7 @@ import SCons.Scanner import fixes +import sources_mak def quietCommandLines(env): # Quiet command lines @@ -229,6 +230,23 @@ def createPkgConfigMethods(env): env.AddMethod(pkg_use_modules, 'PkgUseModules') +def parse_sources_mak(env, names): + parser = sources_mak.SourcesMakParser() + src = env.File('sources.mak').srcnode() + variables = parser.parse(src.abspath) + + all_files = [] + for name in names: + val = variables[name] + files = [env.File(f) for f in val.split(' ') if f] + all_files.extend(files) + + return all_files + +def createParseSourcesMakMethod(env): + env.AddMethod(parse_sources_mak, 'ParseSourcesMak') + + def generate(env): """Common environment generation code""" @@ -240,6 +258,7 @@ def generate(env): createConvenienceLibBuilder(env) createCodeGenerateMethod(env) createPkgConfigMethods(env) + createParseSourcesMakMethod(env) # for debugging #print env.Dump() diff --git a/scons/sources_mak.py b/scons/sources_mak.py new file mode 100644 index 0000000..ae4b47e --- /dev/null +++ b/scons/sources_mak.py @@ -0,0 +1,96 @@ +"""sources.mak Parser + +The syntax of sources.mak is a very small subset of GNU Make. +""" + +class SourcesMakParser(object): + def __init__(self): + self._reset() + + def _reset(self): + self.variables = {} + self.line_cont = '' + + def _next_dereference(self, val, cur): + deref_pos = val.find('$', cur) + if deref_pos < 0: + return (-1, -1) + elif val[deref_pos + 1] != '(': + raise RuntimeError('non-variable dereference') + + deref_end = val.find(')', deref_pos + 2) + if deref_end < 0: + raise RuntimeError('unterminated variable dereference') + + return (deref_pos, deref_end + 1) + + def _expand_value(self, val): + expanded = '' + cur = 0 + while True: + deref_pos, deref_end = self._next_dereference(val, cur) + if deref_pos < 0: + expanded += val[cur:] + break + + deref = val[(deref_pos + 2):(deref_end - 1)] + expanded += val[cur:deref_pos] + self.variables[deref] + cur = deref_end + + return expanded + + def _parse_definition(self, line): + op_pos = line.find('=') + op_end = op_pos + 1 + if op_pos < 0: + raise RuntimeError('not a definition %s') + + if op_pos > 0 and line[op_pos - 1] in [':', '+']: + op_pos -= 1 + else: + raise RuntimeError('only := and += are supported') + + # set op, name, and val + op = line[op_pos:op_end] + name = line[:op_pos].strip() + val = self._expand_value(line[op_end:].lstrip()) + + if op == ':=': + self.variables[name] = val + elif op == '+=': + self.variables[name] += ' ' + val + + def _parse_line(self, line): + # more lines to come + if line and line[-1] == '\\': + line = line[:-1].strip() + ' ' + self.line_cont += line + return + + # combine with previous lines + if self.line_cont: + line = self.line_cont + line.lstrip() + self.line_cont = '' + + if line: + begins_with_tab = (line[0] == '\t') + + line = line.lstrip() + if line[0] != '#': + if begins_with_tab: + raise RuntimeError('recipe line not supported') + else: + self._parse_definition(line) + + def parse(self, filename): + """Parse a source list file.""" + fp = open(filename) + lines = fp.read().splitlines() + fp.close() + + self._reset() + + for line in lines: + self._parse_line(line) + + return self.variables -- 1.7.5.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev