From f7627e4f677c628bf25ccbf4973ac3e4cd986dee Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Wed, 25 Aug 2010 14:26:37 +0100 Subject: bitbake/data_smart.py: Allow the data expand function to keep track of references (including those from python code) Signed-off-by: Richard Purdie --- bitbake/lib/bb/data_smart.py | 69 ++++++++++++++++++++++++++++++-------------- 1 file changed, 47 insertions(+), 22 deletions(-) diff --git a/bitbake/lib/bb/data_smart.py b/bitbake/lib/bb/data_smart.py index 01a333024..1ed04d50c 100644 --- a/bitbake/lib/bb/data_smart.py +++ b/bitbake/lib/bb/data_smart.py @@ -39,6 +39,39 @@ __setvar_regexp__ = re.compile('(?P.*?)(?P_append|_prepend)(_(?P< __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.funcrefs = 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 "", "eval") + + parser = bb.rptest.PythonParser() + parser.parse_python(code) + self.references |= parser.references + self.funcrefs |= parser.execs + + value = utils.better_eval(codeobj, {"d": self.d}) + return str(value) + class DataSmart: def __init__(self, special = COWDictBase.copy(), seen = COWDictBase.copy() ): @@ -50,35 +83,21 @@ class DataSmart: 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 "", "eval") - value = utils.better_eval(codeobj, {"d": 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 KeyboardInterrupt: @@ -87,10 +106,16 @@ class DataSmart: bb.msg.note(1, bb.msg.domain.Data, "%s:%s while evaluating:\n%s" % (sys.exc_info()[0], sys.exc_info()[1], s)) raise + varparse.value = s + if varname: - self.expand_cache[varname] = s + self.expand_cache[varname] = varparse + + return varparse - return s + def expand(self, s, varname): + return self.expandWithRefs(s, varname).value + def finalize(self): """Performs final steps upon the datastore, including application of overrides""" -- cgit v1.2.3