diff options
| -rw-r--r-- | bitbake/lib/bb/data_smart.py | 69 |
1 files changed, 47 insertions, 22 deletions
diff --git a/bitbake/lib/bb/data_smart.py b/bitbake/lib/bb/data_smart.py index 01a3330245..1ed04d50c3 100644 --- a/bitbake/lib/bb/data_smart.py +++ b/bitbake/lib/bb/data_smart.py | |||
| @@ -39,6 +39,39 @@ __setvar_regexp__ = re.compile('(?P<base>.*?)(?P<keyword>_append|_prepend)(_(?P< | |||
| 39 | __expand_var_regexp__ = re.compile(r"\${[^{}]+}") | 39 | __expand_var_regexp__ = re.compile(r"\${[^{}]+}") |
| 40 | __expand_python_regexp__ = re.compile(r"\${@.+?}") | 40 | __expand_python_regexp__ = re.compile(r"\${@.+?}") |
| 41 | 41 | ||
| 42 | class VariableParse: | ||
| 43 | def __init__(self, varname, d, val = None): | ||
| 44 | self.varname = varname | ||
| 45 | self.d = d | ||
| 46 | self.value = val | ||
| 47 | |||
| 48 | self.references = set() | ||
| 49 | self.funcrefs = set() | ||
| 50 | |||
| 51 | def var_sub(self, match): | ||
| 52 | key = match.group()[2:-1] | ||
| 53 | if self.varname and key: | ||
| 54 | if self.varname == key: | ||
| 55 | raise Exception("variable %s references itself!" % self.varname) | ||
| 56 | var = self.d.getVar(key, 1) | ||
| 57 | if var is not None: | ||
| 58 | self.references.add(key) | ||
| 59 | return var | ||
| 60 | else: | ||
| 61 | return match.group() | ||
| 62 | |||
| 63 | def python_sub(self, match): | ||
| 64 | code = match.group()[3:-1] | ||
| 65 | codeobj = compile(code.strip(), self.varname or "<expansion>", "eval") | ||
| 66 | |||
| 67 | parser = bb.rptest.PythonParser() | ||
| 68 | parser.parse_python(code) | ||
| 69 | self.references |= parser.references | ||
| 70 | self.funcrefs |= parser.execs | ||
| 71 | |||
| 72 | value = utils.better_eval(codeobj, {"d": self.d}) | ||
| 73 | return str(value) | ||
| 74 | |||
| 42 | 75 | ||
| 43 | class DataSmart: | 76 | class DataSmart: |
| 44 | def __init__(self, special = COWDictBase.copy(), seen = COWDictBase.copy() ): | 77 | def __init__(self, special = COWDictBase.copy(), seen = COWDictBase.copy() ): |
| @@ -50,35 +83,21 @@ class DataSmart: | |||
| 50 | 83 | ||
| 51 | self.expand_cache = {} | 84 | self.expand_cache = {} |
| 52 | 85 | ||
| 53 | def expand(self, s, varname): | 86 | def expandWithRefs(self, s, varname): |
| 54 | def var_sub(match): | ||
| 55 | key = match.group()[2:-1] | ||
| 56 | if varname and key: | ||
| 57 | if varname == key: | ||
| 58 | raise Exception("variable %s references itself!" % varname) | ||
| 59 | var = self.getVar(key, 1) | ||
| 60 | if var is not None: | ||
| 61 | return var | ||
| 62 | else: | ||
| 63 | return match.group() | ||
| 64 | |||
| 65 | def python_sub(match): | ||
| 66 | code = match.group()[3:-1] | ||
| 67 | codeobj = compile(code.strip(), varname or "<expansion>", "eval") | ||
| 68 | value = utils.better_eval(codeobj, {"d": self}) | ||
| 69 | return str(value) | ||
| 70 | 87 | ||
| 71 | if not isinstance(s, basestring): # sanity check | 88 | if not isinstance(s, basestring): # sanity check |
| 72 | return s | 89 | return VariableParse(varname, self, s) |
| 73 | 90 | ||
| 74 | if varname and varname in self.expand_cache: | 91 | if varname and varname in self.expand_cache: |
| 75 | return self.expand_cache[varname] | 92 | return self.expand_cache[varname] |
| 76 | 93 | ||
| 94 | varparse = VariableParse(varname, self) | ||
| 95 | |||
| 77 | while s.find('${') != -1: | 96 | while s.find('${') != -1: |
| 78 | olds = s | 97 | olds = s |
| 79 | try: | 98 | try: |
| 80 | s = __expand_var_regexp__.sub(var_sub, s) | 99 | s = __expand_var_regexp__.sub(varparse.var_sub, s) |
| 81 | s = __expand_python_regexp__.sub(python_sub, s) | 100 | s = __expand_python_regexp__.sub(varparse.python_sub, s) |
| 82 | if s == olds: | 101 | if s == olds: |
| 83 | break | 102 | break |
| 84 | except KeyboardInterrupt: | 103 | except KeyboardInterrupt: |
| @@ -87,10 +106,16 @@ class DataSmart: | |||
| 87 | bb.msg.note(1, bb.msg.domain.Data, "%s:%s while evaluating:\n%s" % (sys.exc_info()[0], sys.exc_info()[1], s)) | 106 | bb.msg.note(1, bb.msg.domain.Data, "%s:%s while evaluating:\n%s" % (sys.exc_info()[0], sys.exc_info()[1], s)) |
| 88 | raise | 107 | raise |
| 89 | 108 | ||
| 109 | varparse.value = s | ||
| 110 | |||
| 90 | if varname: | 111 | if varname: |
| 91 | self.expand_cache[varname] = s | 112 | self.expand_cache[varname] = varparse |
| 113 | |||
| 114 | return varparse | ||
| 92 | 115 | ||
| 93 | return s | 116 | def expand(self, s, varname): |
| 117 | return self.expandWithRefs(s, varname).value | ||
| 118 | |||
| 94 | 119 | ||
| 95 | def finalize(self): | 120 | def finalize(self): |
| 96 | """Performs final steps upon the datastore, including application of overrides""" | 121 | """Performs final steps upon the datastore, including application of overrides""" |
