bitbake/data_smart.py: Allow the data expand function to keep track of references (including those from python code)

Signed-off-by: Richard Purdie <rpurdie@linux.intel.com>
This commit is contained in:
Richard Purdie 2010-08-25 14:26:37 +01:00
parent e6566322bd
commit f7627e4f67
1 changed files with 48 additions and 23 deletions

View File

@ -39,6 +39,39 @@ __setvar_regexp__ = re.compile('(?P<base>.*?)(?P<keyword>_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 "<expansion>", "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 "<expansion>", "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
if varname:
self.expand_cache[varname] = s
varparse.value = s
return s
if varname:
self.expand_cache[varname] = varparse
return varparse
def expand(self, s, varname):
return self.expandWithRefs(s, varname).value
def finalize(self):
"""Performs final steps upon the datastore, including application of overrides"""