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
33 from bb import utils, methodpool
34 from COW import COWDictBase
36 from new import classobj
39 __setvar_keyword__ = ["_append","_prepend"]
40 __setvar_regexp__ = re.compile('(?P<base>.*?)(?P<keyword>_append|_prepend)(_(?P<add>.*))?')
41 __expand_var_regexp__ = re.compile(r"\${[^{}]+}")
42 __expand_python_regexp__ = re.compile(r"\${@.+?}")
46 def __init__(self, special = COWDictBase.copy(), seen = COWDictBase.copy() ):
49 # cookie monster tribute
50 self._special_values = special
51 self._seen_overrides = seen
53 self.expand_cache = {}
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 if varname and varname in self.expand_cache:
79 return self.expand_cache[varname]
81 while s.find('$') != -1:
84 s = __expand_var_regexp__.sub(var_sub, s)
85 s = __expand_python_regexp__.sub(python_sub, s)
87 if type(s) is not types.StringType: # sanity check
88 bb.msg.error(bb.msg.domain.Data, 'expansion of %s returned non-string %s' % (olds, s))
89 except KeyboardInterrupt:
92 bb.msg.note(1, bb.msg.domain.Data, "%s:%s while evaluating:\n%s" % (sys.exc_info()[0], sys.exc_info()[1], s))
96 self.expand_cache[varname] = s
100 def initVar(self, var):
101 self.expand_cache = {}
102 if not var in self.dict:
105 def _findVar(self,var):
108 while (_dest and var not in _dest):
109 if not "_data" in _dest:
112 _dest = _dest["_data"]
114 if _dest and var in _dest:
118 def _makeShadowCopy(self, var):
122 local_var = self._findVar(var)
125 self.dict[var] = copy.copy(local_var)
129 def setVar(self,var,value):
130 self.expand_cache = {}
131 match = __setvar_regexp__.match(var)
132 if match and match.group("keyword") in __setvar_keyword__:
133 base = match.group('base')
134 keyword = match.group("keyword")
135 override = match.group('add')
136 l = self.getVarFlag(base, keyword) or []
137 l.append([value, override])
138 self.setVarFlag(base, keyword, l)
140 # todo make sure keyword is not __doc__ or __module__
141 # pay the cookie monster
143 self._special_values[keyword].add( base )
145 self._special_values[keyword] = Set()
146 self._special_values[keyword].add( base )
150 if not var in self.dict:
151 self._makeShadowCopy(var)
152 if self.getVarFlag(var, 'matchesenv'):
153 self.delVarFlag(var, 'matchesenv')
154 self.setVarFlag(var, 'export', 1)
156 # more cookies for the cookie monster
158 override = var[var.rfind('_')+1:]
159 if not self._seen_overrides.has_key(override):
160 self._seen_overrides[override] = Set()
161 self._seen_overrides[override].add( var )
164 self.dict[var]["content"] = value
166 def getVar(self,var,exp):
167 value = self.getVarFlag(var,"content")
170 return self.expand(value,var)
173 def delVar(self,var):
174 self.expand_cache = {}
177 def setVarFlag(self,var,flag,flagvalue):
178 if not var in self.dict:
179 self._makeShadowCopy(var)
180 self.dict[var][flag] = flagvalue
182 def getVarFlag(self,var,flag):
183 local_var = self._findVar(var)
185 if flag in local_var:
186 return copy.copy(local_var[flag])
189 def delVarFlag(self,var,flag):
190 local_var = self._findVar(var)
193 if not var in self.dict:
194 self._makeShadowCopy(var)
196 if var in self.dict and flag in self.dict[var]:
197 del self.dict[var][flag]
199 def setVarFlags(self,var,flags):
200 if not var in self.dict:
201 self._makeShadowCopy(var)
203 for i in flags.keys():
206 self.dict[var][i] = flags[i]
208 def getVarFlags(self,var):
209 local_var = self._findVar(var)
213 for i in self.dict[var].keys():
216 flags[i] = self.dict[var][i]
223 def delVarFlags(self,var):
224 if not var in self.dict:
225 self._makeShadowCopy(var)
230 # try to save the content
231 if "content" in self.dict[var]:
232 content = self.dict[var]["content"]
234 self.dict[var]["content"] = content
239 def createCopy(self):
241 Create a copy of self by setting _data to self
243 # we really want this to be a DataSmart...
244 data = DataSmart(seen=self._seen_overrides.copy(), special=self._special_values.copy())
245 data.dict["_data"] = self.dict
253 _keys(d["_data"],mykey)
259 _keys(self.dict,keytab)
262 def __getitem__(self,item):
263 #print "Warning deprecated"
264 return self.getVar(item, False)
266 def __setitem__(self,var,data):
267 #print "Warning deprecated"
268 self.setVar(var,data)