diff options
Diffstat (limited to 'bitbake/lib/bb/data_smart.py')
-rw-r--r-- | bitbake/lib/bb/data_smart.py | 158 |
1 files changed, 36 insertions, 122 deletions
diff --git a/bitbake/lib/bb/data_smart.py b/bitbake/lib/bb/data_smart.py index 52f391dec1..fbd4167fe4 100644 --- a/bitbake/lib/bb/data_smart.py +++ b/bitbake/lib/bb/data_smart.py | |||
@@ -8,7 +8,7 @@ BitBake build tools. | |||
8 | 8 | ||
9 | Copyright (C) 2003, 2004 Chris Larson | 9 | Copyright (C) 2003, 2004 Chris Larson |
10 | Copyright (C) 2004, 2005 Seb Frankengul | 10 | Copyright (C) 2004, 2005 Seb Frankengul |
11 | Copyright (C) 2005 Holger Hans Peter Freyther | 11 | Copyright (C) 2005, 2006 Holger Hans Peter Freyther |
12 | Copyright (C) 2005 Uli Luckas | 12 | Copyright (C) 2005 Uli Luckas |
13 | Copyright (C) 2005 ROAD GmbH | 13 | Copyright (C) 2005 ROAD GmbH |
14 | 14 | ||
@@ -29,7 +29,8 @@ Based on functions from the base bb module, Copyright 2003 Holger Schurig | |||
29 | """ | 29 | """ |
30 | 30 | ||
31 | import copy, os, re, sys, time, types | 31 | import copy, os, re, sys, time, types |
32 | from bb import note, debug, fatal, utils | 32 | from bb import note, debug, error, fatal, utils, methodpool |
33 | from sets import Set | ||
33 | 34 | ||
34 | try: | 35 | try: |
35 | import cPickle as pickle | 36 | import cPickle as pickle |
@@ -37,9 +38,8 @@ except ImportError: | |||
37 | import pickle | 38 | import pickle |
38 | print "NOTE: Importing cPickle failed. Falling back to a very slow implementation." | 39 | print "NOTE: Importing cPickle failed. Falling back to a very slow implementation." |
39 | 40 | ||
40 | 41 | __setvar_keyword__ = ["_append","_prepend"] | |
41 | __setvar_keyword__ = ["_append","_prepend","_delete"] | 42 | __setvar_regexp__ = re.compile('(?P<base>.*?)(?P<keyword>_append|_prepend)(_(?P<add>.*))?') |
42 | __setvar_regexp__ = re.compile('(?P<base>.*?)(?P<keyword>_append|_prepend|_delete)(_(?P<add>.*))?') | ||
43 | __expand_var_regexp__ = re.compile(r"\${[^{}]+}") | 43 | __expand_var_regexp__ = re.compile(r"\${[^{}]+}") |
44 | __expand_python_regexp__ = re.compile(r"\${@.+?}") | 44 | __expand_python_regexp__ = re.compile(r"\${@.+?}") |
45 | 45 | ||
@@ -48,6 +48,10 @@ class DataSmart: | |||
48 | def __init__(self): | 48 | def __init__(self): |
49 | self.dict = {} | 49 | self.dict = {} |
50 | 50 | ||
51 | # cookie monster tribute | ||
52 | self._special_values = {} | ||
53 | self._seen_overrides = {} | ||
54 | |||
51 | def expand(self,s, varname): | 55 | def expand(self,s, varname): |
52 | def var_sub(match): | 56 | def var_sub(match): |
53 | key = match.group()[2:-1] | 57 | key = match.group()[2:-1] |
@@ -78,8 +82,7 @@ class DataSmart: | |||
78 | s = __expand_python_regexp__.sub(python_sub, s) | 82 | s = __expand_python_regexp__.sub(python_sub, s) |
79 | if s == olds: break | 83 | if s == olds: break |
80 | if type(s) is not types.StringType: # sanity check | 84 | if type(s) is not types.StringType: # sanity check |
81 | import bb | 85 | error('expansion of %s returned non-string %s' % (olds, s)) |
82 | bb.error('expansion of %s returned non-string %s' % (olds, s)) | ||
83 | except KeyboardInterrupt: | 86 | except KeyboardInterrupt: |
84 | raise | 87 | raise |
85 | except: | 88 | except: |
@@ -91,18 +94,6 @@ class DataSmart: | |||
91 | if not var in self.dict: | 94 | if not var in self.dict: |
92 | self.dict[var] = {} | 95 | self.dict[var] = {} |
93 | 96 | ||
94 | def pickle_prep(self, cfg): | ||
95 | if "_data" in self.dict: | ||
96 | if self.dict["_data"] == cfg: | ||
97 | self.dict["_data"] = "cfg"; | ||
98 | else: # this is an unknown array for the moment | ||
99 | pass | ||
100 | |||
101 | def unpickle_prep(self, cfg): | ||
102 | if "_data" in self.dict: | ||
103 | if self.dict["_data"] == "cfg": | ||
104 | self.dict["_data"] = cfg; | ||
105 | |||
106 | def _findVar(self,var): | 97 | def _findVar(self,var): |
107 | _dest = self.dict | 98 | _dest = self.dict |
108 | 99 | ||
@@ -116,14 +107,6 @@ class DataSmart: | |||
116 | return _dest[var] | 107 | return _dest[var] |
117 | return None | 108 | return None |
118 | 109 | ||
119 | def _copyVar(self,var,name): | ||
120 | local_var = self._findVar(var) | ||
121 | if local_var: | ||
122 | self.dict[name] = copy.copy(local_var) | ||
123 | else: | ||
124 | debug(1,"Warning, _copyVar %s to %s, %s does not exists" % (var,name,var)) | ||
125 | |||
126 | |||
127 | def _makeShadowCopy(self, var): | 110 | def _makeShadowCopy(self, var): |
128 | if var in self.dict: | 111 | if var in self.dict: |
129 | return | 112 | return |
@@ -142,11 +125,20 @@ class DataSmart: | |||
142 | keyword = match.group("keyword") | 125 | keyword = match.group("keyword") |
143 | override = match.group('add') | 126 | override = match.group('add') |
144 | l = self.getVarFlag(base, keyword) or [] | 127 | l = self.getVarFlag(base, keyword) or [] |
145 | if override == 'delete': | ||
146 | if l.count([value, None]): | ||
147 | del l[l.index([value, None])] | ||
148 | l.append([value, override]) | 128 | l.append([value, override]) |
149 | self.setVarFlag(base, match.group("keyword"), l) | 129 | self.setVarFlag(base, keyword, l) |
130 | |||
131 | # pay the cookie monster | ||
132 | try: | ||
133 | self._special_values[keyword].add( base ) | ||
134 | except: | ||
135 | self._special_values[keyword] = Set() | ||
136 | self._special_values[keyword].add( base ) | ||
137 | |||
138 | # SRC_URI_append_simpad is both a flag and a override | ||
139 | #if not override in self._seen_overrides: | ||
140 | # self._seen_overrides[override] = Set() | ||
141 | #self._seen_overrides[override].add( base ) | ||
150 | return | 142 | return |
151 | 143 | ||
152 | if not var in self.dict: | 144 | if not var in self.dict: |
@@ -155,6 +147,13 @@ class DataSmart: | |||
155 | self.delVarFlag(var, 'matchesenv') | 147 | self.delVarFlag(var, 'matchesenv') |
156 | self.setVarFlag(var, 'export', 1) | 148 | self.setVarFlag(var, 'export', 1) |
157 | 149 | ||
150 | # more cookies for the cookie monster | ||
151 | if '_' in var: | ||
152 | override = var[var.rfind('_')+1:] | ||
153 | if not override in self._seen_overrides: | ||
154 | self._seen_overrides[override] = Set() | ||
155 | self._seen_overrides[override].add( var ) | ||
156 | |||
158 | # setting var | 157 | # setting var |
159 | self.dict[var]["content"] = value | 158 | self.dict[var]["content"] = value |
160 | 159 | ||
@@ -237,6 +236,8 @@ class DataSmart: | |||
237 | # we really want this to be a DataSmart... | 236 | # we really want this to be a DataSmart... |
238 | data = DataSmart() | 237 | data = DataSmart() |
239 | data.dict["_data"] = self.dict | 238 | data.dict["_data"] = self.dict |
239 | data._seen_overrides = copy.deepcopy(self._seen_overrides) | ||
240 | data._special_values = copy.deepcopy(self._special_values) | ||
240 | 241 | ||
241 | return data | 242 | return data |
242 | 243 | ||
@@ -254,98 +255,11 @@ class DataSmart: | |||
254 | return keytab.keys() | 255 | return keytab.keys() |
255 | 256 | ||
256 | def __getitem__(self,item): | 257 | def __getitem__(self,item): |
257 | start = self.dict | 258 | #print "Warning deprecated" |
258 | while start: | 259 | return self.getVar(item, False) |
259 | if item in start: | ||
260 | return start[item] | ||
261 | elif "_data" in start: | ||
262 | start = start["_data"] | ||
263 | else: | ||
264 | start = None | ||
265 | return None | ||
266 | 260 | ||
267 | def __setitem__(self,var,data): | 261 | def __setitem__(self,var,data): |
268 | self._makeShadowCopy(var) | 262 | #print "Warning deprecated" |
269 | self.dict[var] = data | 263 | self.setVar(var,data) |
270 | |||
271 | |||
272 | class DataSmartPackage(DataSmart): | ||
273 | """ | ||
274 | Persistent Data Storage | ||
275 | """ | ||
276 | def sanitize_filename(bbfile): | ||
277 | return bbfile.replace( '/', '_' ) | ||
278 | sanitize_filename = staticmethod(sanitize_filename) | ||
279 | 264 | ||
280 | def unpickle(self): | ||
281 | """ | ||
282 | Restore the dict from memory | ||
283 | """ | ||
284 | cache_bbfile = self.sanitize_filename(self.bbfile) | ||
285 | p = pickle.Unpickler( file("%s/%s"%(self.cache,cache_bbfile),"rb")) | ||
286 | self.dict = p.load() | ||
287 | self.unpickle_prep() | ||
288 | funcstr = self.getVar('__functions__', 0) | ||
289 | if funcstr: | ||
290 | comp = utils.better_compile(funcstr, "<pickled>", self.bbfile) | ||
291 | utils.better_exec(comp, __builtins__, funcstr, self.bbfile) | ||
292 | |||
293 | def linkDataSet(self): | ||
294 | if not self.parent == None: | ||
295 | # assume parent is a DataSmartInstance | ||
296 | self.dict["_data"] = self.parent.dict | ||
297 | |||
298 | |||
299 | def __init__(self,cache,name,clean,parent): | ||
300 | """ | ||
301 | Construct a persistent data instance | ||
302 | """ | ||
303 | #Initialize the dictionary | ||
304 | DataSmart.__init__(self) | ||
305 | |||
306 | self.cache = cache | ||
307 | self.bbfile = os.path.abspath( name ) | ||
308 | self.parent = parent | ||
309 | |||
310 | # Either unpickle the data or do copy on write | ||
311 | if clean: | ||
312 | self.linkDataSet() | ||
313 | else: | ||
314 | self.unpickle() | ||
315 | |||
316 | def commit(self, mtime): | ||
317 | """ | ||
318 | Save the package to a permanent storage | ||
319 | """ | ||
320 | self.pickle_prep() | ||
321 | |||
322 | cache_bbfile = self.sanitize_filename(self.bbfile) | ||
323 | p = pickle.Pickler(file("%s/%s" %(self.cache,cache_bbfile), "wb" ), -1 ) | ||
324 | p.dump( self.dict ) | ||
325 | |||
326 | self.unpickle_prep() | ||
327 | 265 | ||
328 | def mtime(cache,bbfile): | ||
329 | cache_bbfile = DataSmartPackage.sanitize_filename(bbfile) | ||
330 | try: | ||
331 | return os.stat( "%s/%s" % (cache,cache_bbfile) )[8] | ||
332 | except OSError: | ||
333 | return 0 | ||
334 | mtime = staticmethod(mtime) | ||
335 | |||
336 | def pickle_prep(self): | ||
337 | """ | ||
338 | If self.dict contains a _data key and it is a configuration | ||
339 | we will remember we had a configuration instance attached | ||
340 | """ | ||
341 | if "_data" in self.dict: | ||
342 | if self.dict["_data"] == self.parent: | ||
343 | dest["_data"] = "cfg" | ||
344 | |||
345 | def unpickle_prep(self): | ||
346 | """ | ||
347 | If we had a configuration instance attached, we will reattach it | ||
348 | """ | ||
349 | if "_data" in self.dict: | ||
350 | if self.dict["_data"] == "cfg": | ||
351 | self.dict["_data"] = self.parent | ||