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.py158
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
9Copyright (C) 2003, 2004 Chris Larson 9Copyright (C) 2003, 2004 Chris Larson
10Copyright (C) 2004, 2005 Seb Frankengul 10Copyright (C) 2004, 2005 Seb Frankengul
11Copyright (C) 2005 Holger Hans Peter Freyther 11Copyright (C) 2005, 2006 Holger Hans Peter Freyther
12Copyright (C) 2005 Uli Luckas 12Copyright (C) 2005 Uli Luckas
13Copyright (C) 2005 ROAD GmbH 13Copyright (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
31import copy, os, re, sys, time, types 31import copy, os, re, sys, time, types
32from bb import note, debug, fatal, utils 32from bb import note, debug, error, fatal, utils, methodpool
33from sets import Set
33 34
34try: 35try:
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
272class 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