diff options
author | Richard Purdie <rpurdie@linux.intel.com> | 2010-08-25 14:26:37 +0100 |
---|---|---|
committer | Richard Purdie <rpurdie@linux.intel.com> | 2010-08-31 12:06:18 +0100 |
commit | f7627e4f677c628bf25ccbf4973ac3e4cd986dee (patch) | |
tree | ee351f3c97d4f6cc15d623fea775ee243aa0ff77 | |
parent | e6566322bd2856e14fbabd78a6307f6575ba3d8c (diff) | |
download | poky-f7627e4f677c628bf25ccbf4973ac3e4cd986dee.tar.gz |
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>
-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""" |