diff options
author | Richard Purdie <rpurdie@linux.intel.com> | 2010-08-25 14:26:37 +0100 |
---|---|---|
committer | Chris Larson <chris_larson@mentor.com> | 2010-12-29 23:51:07 -0700 |
commit | dab657bf8a841cb872c7418d41fdecb21f36780d (patch) | |
tree | e930af4519872737dc10ccd89bb11e2419419952 /lib/bb/data_smart.py | |
parent | 4318da793a1b5008d7c122e5dac414d5c652a57d (diff) | |
download | openembedded-core-contrib-dab657bf8a841cb872c7418d41fdecb21f36780d.tar.gz |
data_smart: track variable references
Signed-off-by: Richard Purdie <rpurdie@linux.intel.com>
Diffstat (limited to 'lib/bb/data_smart.py')
-rw-r--r-- | lib/bb/data_smart.py | 72 |
1 files changed, 49 insertions, 23 deletions
diff --git a/lib/bb/data_smart.py b/lib/bb/data_smart.py index 9b89c5f5a4..83e6f70cd7 100644 --- a/lib/bb/data_smart.py +++ b/lib/bb/data_smart.py @@ -31,7 +31,7 @@ BitBake build tools. import copy, re from collections import MutableMapping import logging -import bb +import bb, bb.codeparser from bb import utils from bb.COW import COWDictBase @@ -43,6 +43,40 @@ __expand_var_regexp__ = re.compile(r"\${[^{}]+}") __expand_python_regexp__ = re.compile(r"\${@.+?}") +class VariableParse: + def __init__(self, varname, d, val = None): + self.varname = varname + self.d = d + self.value = val + + self.references = set() + self.execs = set() + + def var_sub(self, match): + key = match.group()[2:-1] + if self.varname and key: + if self.varname == key: + raise Exception("variable %s references itself!" % self.varname) + var = self.d.getVar(key, 1) + if var is not None: + self.references.add(key) + return var + else: + return match.group() + + def python_sub(self, match): + code = match.group()[3:-1] + codeobj = compile(code.strip(), self.varname or "<expansion>", "eval") + + parser = bb.codeparser.PythonParser() + parser.parse_python(code) + self.references |= parser.references + self.execs |= parser.execs + + value = utils.better_eval(codeobj, DataContext(self.d)) + return str(value) + + class DataContext(dict): def __init__(self, metadata, **kwargs): self.metadata = metadata @@ -66,45 +100,37 @@ class DataSmart(MutableMapping): self.expand_cache = {} - def expand(self, s, varname): - def var_sub(match): - key = match.group()[2:-1] - if varname and key: - if varname == key: - raise Exception("variable %s references itself!" % varname) - var = self.getVar(key, 1) - if var is not None: - return var - else: - return match.group() - - def python_sub(match): - code = match.group()[3:-1] - codeobj = compile(code.strip(), varname or "<expansion>", "eval") - value = utils.better_eval(codeobj, DataContext(self)) - return str(value) + def expandWithRefs(self, s, varname): if not isinstance(s, basestring): # sanity check - return s + return VariableParse(varname, self, s) if varname and varname in self.expand_cache: return self.expand_cache[varname] + varparse = VariableParse(varname, self) + while s.find('${') != -1: olds = s try: - s = __expand_var_regexp__.sub(var_sub, s) - s = __expand_python_regexp__.sub(python_sub, s) + s = __expand_var_regexp__.sub(varparse.var_sub, s) + s = __expand_python_regexp__.sub(varparse.python_sub, s) if s == olds: break except Exception: logger.exception("Error evaluating '%s'", s) raise + varparse.value = s + if varname: - self.expand_cache[varname] = s + self.expand_cache[varname] = varparse + + return varparse + + def expand(self, s, varname): + return self.expandWithRefs(s, varname).value - return s def finalize(self): """Performs final steps upon the datastore, including application of overrides""" |