summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/bb/data_smart.py
diff options
context:
space:
mode:
Diffstat (limited to 'bitbake/lib/bb/data_smart.py')
-rw-r--r--bitbake/lib/bb/data_smart.py117
1 files changed, 64 insertions, 53 deletions
diff --git a/bitbake/lib/bb/data_smart.py b/bitbake/lib/bb/data_smart.py
index 0128a5bb17..8e7dd98384 100644
--- a/bitbake/lib/bb/data_smart.py
+++ b/bitbake/lib/bb/data_smart.py
@@ -31,7 +31,7 @@ logger = logging.getLogger("BitBake.Data")
31 31
32__setvar_keyword__ = [":append", ":prepend", ":remove"] 32__setvar_keyword__ = [":append", ":prepend", ":remove"]
33__setvar_regexp__ = re.compile(r'(?P<base>.*?)(?P<keyword>:append|:prepend|:remove)(:(?P<add>[^A-Z]*))?$') 33__setvar_regexp__ = re.compile(r'(?P<base>.*?)(?P<keyword>:append|:prepend|:remove)(:(?P<add>[^A-Z]*))?$')
34__expand_var_regexp__ = re.compile(r"\${[a-zA-Z0-9\-_+./~:]+?}") 34__expand_var_regexp__ = re.compile(r"\${[a-zA-Z0-9\-_+./~:]+}")
35__expand_python_regexp__ = re.compile(r"\${@(?:{.*?}|.)+?}") 35__expand_python_regexp__ = re.compile(r"\${@(?:{.*?}|.)+?}")
36__whitespace_split__ = re.compile(r'(\s)') 36__whitespace_split__ = re.compile(r'(\s)')
37__override_regexp__ = re.compile(r'[a-z0-9]+') 37__override_regexp__ = re.compile(r'[a-z0-9]+')
@@ -106,52 +106,52 @@ class VariableParse:
106 self.contains = {} 106 self.contains = {}
107 107
108 def var_sub(self, match): 108 def var_sub(self, match):
109 key = match.group()[2:-1] 109 key = match.group()[2:-1]
110 if self.varname and key: 110 if self.varname and key:
111 if self.varname == key: 111 if self.varname == key:
112 raise Exception("variable %s references itself!" % self.varname) 112 raise Exception("variable %s references itself!" % self.varname)
113 var = self.d.getVarFlag(key, "_content") 113 var = self.d.getVarFlag(key, "_content")
114 self.references.add(key) 114 self.references.add(key)
115 if var is not None: 115 if var is not None:
116 return var 116 return var
117 else: 117 else:
118 return match.group() 118 return match.group()
119 119
120 def python_sub(self, match): 120 def python_sub(self, match):
121 if isinstance(match, str): 121 if isinstance(match, str):
122 code = match 122 code = match
123 else: 123 else:
124 code = match.group()[3:-1] 124 code = match.group()[3:-1]
125 125
126 # Do not run code that contains one or more unexpanded variables 126 # Do not run code that contains one or more unexpanded variables
127 # instead return the code with the characters we removed put back 127 # instead return the code with the characters we removed put back
128 if __expand_var_regexp__.findall(code): 128 if __expand_var_regexp__.findall(code):
129 return "${@" + code + "}" 129 return "${@" + code + "}"
130 130
131 if self.varname: 131 if self.varname:
132 varname = 'Var <%s>' % self.varname 132 varname = 'Var <%s>' % self.varname
133 else: 133 else:
134 varname = '<expansion>' 134 varname = '<expansion>'
135 codeobj = compile(code.strip(), varname, "eval") 135 codeobj = compile(code.strip(), varname, "eval")
136 136
137 parser = bb.codeparser.PythonParser(self.varname, logger) 137 parser = bb.codeparser.PythonParser(self.varname, logger)
138 parser.parse_python(code) 138 parser.parse_python(code)
139 if self.varname: 139 if self.varname:
140 vardeps = self.d.getVarFlag(self.varname, "vardeps") 140 vardeps = self.d.getVarFlag(self.varname, "vardeps")
141 if vardeps is None: 141 if vardeps is None:
142 parser.log.flush()
143 else:
144 parser.log.flush() 142 parser.log.flush()
145 self.references |= parser.references 143 else:
146 self.execs |= parser.execs 144 parser.log.flush()
145 self.references |= parser.references
146 self.execs |= parser.execs
147 147
148 for k in parser.contains: 148 for k in parser.contains:
149 if k not in self.contains: 149 if k not in self.contains:
150 self.contains[k] = parser.contains[k].copy() 150 self.contains[k] = parser.contains[k].copy()
151 else: 151 else:
152 self.contains[k].update(parser.contains[k]) 152 self.contains[k].update(parser.contains[k])
153 value = utils.better_eval(codeobj, DataContext(self.d), {'d' : self.d}) 153 value = utils.better_eval(codeobj, DataContext(self.d), {'d' : self.d})
154 return str(value) 154 return str(value)
155 155
156class DataContext(dict): 156class DataContext(dict):
157 excluded = set([i for i in dir(builtins) if not i.startswith('_')] + ['oe']) 157 excluded = set([i for i in dir(builtins) if not i.startswith('_')] + ['oe'])
@@ -272,12 +272,9 @@ class VariableHistory(object):
272 return 272 return
273 if 'op' not in loginfo or not loginfo['op']: 273 if 'op' not in loginfo or not loginfo['op']:
274 loginfo['op'] = 'set' 274 loginfo['op'] = 'set'
275 if 'detail' in loginfo:
276 loginfo['detail'] = str(loginfo['detail'])
277 if 'variable' not in loginfo or 'file' not in loginfo: 275 if 'variable' not in loginfo or 'file' not in loginfo:
278 raise ValueError("record() missing variable or file.") 276 raise ValueError("record() missing variable or file.")
279 var = loginfo['variable'] 277 var = loginfo['variable']
280
281 if var not in self.variables: 278 if var not in self.variables:
282 self.variables[var] = [] 279 self.variables[var] = []
283 if not isinstance(self.variables[var], list): 280 if not isinstance(self.variables[var], list):
@@ -336,7 +333,8 @@ class VariableHistory(object):
336 flag = '[%s] ' % (event['flag']) 333 flag = '[%s] ' % (event['flag'])
337 else: 334 else:
338 flag = '' 335 flag = ''
339 o.write("# %s %s:%s%s\n# %s\"%s\"\n" % (event['op'], event['file'], event['line'], display_func, flag, re.sub('\n', '\n# ', event['detail']))) 336 o.write("# %s %s:%s%s\n# %s\"%s\"\n" % \
337 (event['op'], event['file'], event['line'], display_func, flag, re.sub('\n', '\n# ', str(event['detail']))))
340 if len(history) > 1: 338 if len(history) > 1:
341 o.write("# pre-expansion value:\n") 339 o.write("# pre-expansion value:\n")
342 o.write('# "%s"\n' % (commentVal)) 340 o.write('# "%s"\n' % (commentVal))
@@ -390,7 +388,7 @@ class VariableHistory(object):
390 if isset and event['op'] == 'set?': 388 if isset and event['op'] == 'set?':
391 continue 389 continue
392 isset = True 390 isset = True
393 items = d.expand(event['detail']).split() 391 items = d.expand(str(event['detail'])).split()
394 for item in items: 392 for item in items:
395 # This is a little crude but is belt-and-braces to avoid us 393 # This is a little crude but is belt-and-braces to avoid us
396 # having to handle every possible operation type specifically 394 # having to handle every possible operation type specifically
@@ -582,12 +580,10 @@ class DataSmart(MutableMapping):
582 else: 580 else:
583 loginfo['op'] = keyword 581 loginfo['op'] = keyword
584 self.varhistory.record(**loginfo) 582 self.varhistory.record(**loginfo)
585 # todo make sure keyword is not __doc__ or __module__
586 # pay the cookie monster 583 # pay the cookie monster
587 584
588 # more cookies for the cookie monster 585 # more cookies for the cookie monster
589 if ':' in var: 586 self._setvar_update_overrides(base, **loginfo)
590 self._setvar_update_overrides(base, **loginfo)
591 587
592 if base in self.overridevars: 588 if base in self.overridevars:
593 self._setvar_update_overridevars(var, value) 589 self._setvar_update_overridevars(var, value)
@@ -640,6 +636,7 @@ class DataSmart(MutableMapping):
640 nextnew.update(vardata.contains.keys()) 636 nextnew.update(vardata.contains.keys())
641 new = nextnew 637 new = nextnew
642 self.overrides = None 638 self.overrides = None
639 self.expand_cache = {}
643 640
644 def _setvar_update_overrides(self, var, **loginfo): 641 def _setvar_update_overrides(self, var, **loginfo):
645 # aka pay the cookie monster 642 # aka pay the cookie monster
@@ -829,6 +826,8 @@ class DataSmart(MutableMapping):
829 value = copy.copy(local_var[flag]) 826 value = copy.copy(local_var[flag])
830 elif flag == "_content" and "_defaultval" in local_var and not noweakdefault: 827 elif flag == "_content" and "_defaultval" in local_var and not noweakdefault:
831 value = copy.copy(local_var["_defaultval"]) 828 value = copy.copy(local_var["_defaultval"])
829 elif "_defaultval_flag_"+flag in local_var and not noweakdefault:
830 value = copy.copy(local_var["_defaultval_flag_"+flag])
832 831
833 832
834 if flag == "_content" and local_var is not None and ":append" in local_var and not parsing: 833 if flag == "_content" and local_var is not None and ":append" in local_var and not parsing:
@@ -920,6 +919,8 @@ class DataSmart(MutableMapping):
920 self.varhistory.record(**loginfo) 919 self.varhistory.record(**loginfo)
921 920
922 del self.dict[var][flag] 921 del self.dict[var][flag]
922 if ("_defaultval_flag_" + flag) in self.dict[var]:
923 del self.dict[var]["_defaultval_flag_" + flag]
923 924
924 def appendVarFlag(self, var, flag, value, **loginfo): 925 def appendVarFlag(self, var, flag, value, **loginfo):
925 loginfo['op'] = 'append' 926 loginfo['op'] = 'append'
@@ -954,17 +955,22 @@ class DataSmart(MutableMapping):
954 flags = {} 955 flags = {}
955 956
956 if local_var: 957 if local_var:
957 for i in local_var: 958 for i, val in local_var.items():
958 if i.startswith(("_", ":")) and not internalflags: 959 if i.startswith("_defaultval_flag_") and not internalflags:
960 i = i[len("_defaultval_flag_"):]
961 if i not in local_var:
962 flags[i] = val
963 elif i.startswith(("_", ":")) and not internalflags:
959 continue 964 continue
960 flags[i] = local_var[i] 965 else:
966 flags[i] = val
967
961 if expand and i in expand: 968 if expand and i in expand:
962 flags[i] = self.expand(flags[i], var + "[" + i + "]") 969 flags[i] = self.expand(flags[i], var + "[" + i + "]")
963 if len(flags) == 0: 970 if len(flags) == 0:
964 return None 971 return None
965 return flags 972 return flags
966 973
967
968 def delVarFlags(self, var, **loginfo): 974 def delVarFlags(self, var, **loginfo):
969 self.expand_cache = {} 975 self.expand_cache = {}
970 if not var in self.dict: 976 if not var in self.dict:
@@ -1114,5 +1120,10 @@ class DataSmart(MutableMapping):
1114 value = d.getVar(i, False) or "" 1120 value = d.getVar(i, False) or ""
1115 data.update({i:value}) 1121 data.update({i:value})
1116 1122
1123 moddeps = bb.codeparser.modulecode_deps
1124 for dep in sorted(moddeps):
1125 # Ignore visitor code, sort sets
1126 data.update({'moddep[%s]' % dep : [sorted(moddeps[dep][0]), sorted(moddeps[dep][1]), sorted(moddeps[dep][2]), sorted(moddeps[dep][3]), moddeps[dep][4]]})
1127
1117 data_str = str([(k, data[k]) for k in sorted(data.keys())]) 1128 data_str = str([(k, data[k]) for k in sorted(data.keys())])
1118 return hashlib.sha256(data_str.encode("utf-8")).hexdigest() 1129 return hashlib.sha256(data_str.encode("utf-8")).hexdigest()