1 # ex:ts=4:sw=4:sts=4:et
2 # -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
4 BitBake Smart Dictionary Implementation
6 Functions for interacting with the data structure used by the
9 Copyright (C) 2003, 2004 Chris Larson
10 Copyright (C) 2004, 2005 Seb Frankengul
11 Copyright (C) 2005, 2006 Holger Hans Peter Freyther
12 Copyright (C) 2005 Uli Luckas
13 Copyright (C) 2005 ROAD GmbH
15 This program is free software; you can redistribute it and/or modify it under
16 the terms of the GNU General Public License as published by the Free Software
17 Foundation; either version 2 of the License, or (at your option) any later
20 This program is distributed in the hope that it will be useful, but WITHOUT
21 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
22 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
24 You should have received a copy of the GNU General Public License along with
25 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
26 Place, Suite 330, Boston, MA 02111-1307 USA.
28 Based on functions from the base bb module, Copyright 2003 Holger Schurig
31 import copy, os, re, sys, time, types
32 from bb import note, debug, error, fatal, utils, methodpool
36 import cPickle as pickle
39 print "NOTE: Importing cPickle failed. Falling back to a very slow implementation."
41 __setvar_keyword__ = ["_append","_prepend"]
42 __setvar_regexp__ = re.compile('(?P<base>.*?)(?P<keyword>_append|_prepend)(_(?P<add>.*))?')
43 __expand_var_regexp__ = re.compile(r"\${[^{}]+}")
44 __expand_python_regexp__ = re.compile(r"\${@.+?}")
51 # cookie monster tribute
52 self._special_values = {}
53 self._seen_overrides = {}
55 def expand(self,s, varname):
57 key = match.group()[2:-1]
60 raise Exception("variable %s references itself!" % varname)
61 var = self.getVar(key, 1)
67 def python_sub(match):
69 code = match.group()[3:-1]
72 if type(s) == types.IntType: s = str(s)
75 if type(s) is not types.StringType: # sanity check
78 while s.find('$') != -1:
81 s = __expand_var_regexp__.sub(var_sub, s)
82 s = __expand_python_regexp__.sub(python_sub, s)
84 if type(s) is not types.StringType: # sanity check
85 error('expansion of %s returned non-string %s' % (olds, s))
86 except KeyboardInterrupt:
89 note("%s:%s while evaluating:\n%s" % (sys.exc_info()[0], sys.exc_info()[1], s))
93 def initVar(self, var):
94 if not var in self.dict:
97 def _findVar(self,var):
100 while (_dest and var not in _dest):
101 if not "_data" in _dest:
104 _dest = _dest["_data"]
106 if _dest and var in _dest:
110 def _makeShadowCopy(self, var):
114 local_var = self._findVar(var)
117 self.dict[var] = copy.copy(local_var)
121 def setVar(self,var,value):
122 match = __setvar_regexp__.match(var)
123 if match and match.group("keyword") in __setvar_keyword__:
124 base = match.group('base')
125 keyword = match.group("keyword")
126 override = match.group('add')
127 l = self.getVarFlag(base, keyword) or []
128 l.append([value, override])
129 self.setVarFlag(base, keyword, l)
131 # pay the cookie monster
133 self._special_values[keyword].add( base )
135 self._special_values[keyword] = Set()
136 self._special_values[keyword].add( base )
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 )
144 if not var in self.dict:
145 self._makeShadowCopy(var)
146 if self.getVarFlag(var, 'matchesenv'):
147 self.delVarFlag(var, 'matchesenv')
148 self.setVarFlag(var, 'export', 1)
150 # more cookies for the cookie monster
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 )
158 self.dict[var]["content"] = value
160 def getVar(self,var,exp):
161 value = self.getVarFlag(var,"content")
164 return self.expand(value,var)
167 def delVar(self,var):
170 def setVarFlag(self,var,flag,flagvalue):
171 if not var in self.dict:
172 self._makeShadowCopy(var)
173 self.dict[var][flag] = flagvalue
175 def getVarFlag(self,var,flag):
176 local_var = self._findVar(var)
178 if flag in local_var:
179 return copy.copy(local_var[flag])
182 def delVarFlag(self,var,flag):
183 local_var = self._findVar(var)
186 if not var in self.dict:
187 self._makeShadowCopy(var)
189 if var in self.dict and flag in self.dict[var]:
190 del self.dict[var][flag]
192 def setVarFlags(self,var,flags):
193 if not var in self.dict:
194 self._makeShadowCopy(var)
196 for i in flags.keys():
199 self.dict[var][i] = flags[i]
201 def getVarFlags(self,var):
202 local_var = self._findVar(var)
206 for i in self.dict[var].keys():
209 flags[i] = self.dict[var][i]
216 def delVarFlags(self,var):
217 if not var in self.dict:
218 self._makeShadowCopy(var)
223 # try to save the content
224 if "content" in self.dict[var]:
225 content = self.dict[var]["content"]
227 self.dict[var]["content"] = content
232 def createCopy(self):
234 Create a copy of self by setting _data to self
236 # we really want this to be a DataSmart...
238 data.dict["_data"] = self.dict
239 data._seen_overrides = copy.copy(self._seen_overrides)
240 data._special_values = copy.copy(self._special_values)
248 _keys(d["_data"],mykey)
254 _keys(self.dict,keytab)
257 def __getitem__(self,item):
262 elif "_data" in start:
263 start = start["_data"]
268 def __setitem__(self,var,data):
269 self._makeShadowCopy(var)
270 self.dict[var] = data
273 class DataSmartPackage(DataSmart):
275 Persistent Data Storage
277 def linkDataSet(self):
278 if not self.parent == None:
279 # assume parent is a DataSmartInstance
280 self.dict["_data"] = self.parent.dict
283 def __init__(self,cache,name,clean,parent):
285 Construct a persistent data instance
287 #Initialize the dictionary
288 DataSmart.__init__(self)
291 self.bbfile = os.path.abspath( name )