[Mesa-dev] [PATCH 1/2] scons: add ParseSourcesMak method
Chia-I Wu
olvaffe at gmail.com
Thu Aug 18 02:48:14 PDT 2011
From: Chia-I Wu <olv at 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
More information about the mesa-dev
mailing list