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 def expand(self,s, varname):
55 key = match.group()[2:-1]
58 raise Exception("variable %s references itself!" % varname)
59 var = self.getVar(key, 1)
65 def python_sub(match):
67 code = match.group()[3:-1]
70 if type(s) == types.IntType: s = str(s)
73 if type(s) is not types.StringType: # sanity check
76 while s.find('$') != -1:
79 s = __expand_var_regexp__.sub(var_sub, s)
80 s = __expand_python_regexp__.sub(python_sub, s)
82 if type(s) is not types.StringType: # sanity check
83 bb.msg.error(bb.msg.domain.Data, 'expansion of %s returned non-string %s' % (olds, s))
84 except KeyboardInterrupt:
87 bb.msg.note(1, bb.msg.domain.Data, "%s:%s while evaluating:\n%s" % (sys.exc_info()[0], sys.exc_info()[1], s))
91 def initVar(self, var):
92 if not var in self.dict:
95 def _findVar(self,var):
98 while (_dest and var not in _dest):
99 if not "_data" in _dest:
102 _dest = _dest["_data"]
104 if _dest and var in _dest:
108 def _makeShadowCopy(self, var):
112 local_var = self._findVar(var)
115 self.dict[var] = copy.copy(local_var)
119 def setVar(self,var,value):
120 match = __setvar_regexp__.match(var)
121 if match and match.group("keyword") in __setvar_keyword__:
122 base = match.group('base')
123 keyword = match.group("keyword")
124 override = match.group('add')
125 l = self.getVarFlag(base, keyword) or []
126 l.append([value, override])
127 self.setVarFlag(base, keyword, l)
129 # todo make sure keyword is not __doc__ or __module__
130 # pay the cookie monster
132 self._special_values[keyword].add( base )
134 self._special_values[keyword] = Set()
135 self._special_values[keyword].add( base )
139 if not var in self.dict:
140 self._makeShadowCopy(var)
141 if self.getVarFlag(var, 'matchesenv'):
142 self.delVarFlag(var, 'matchesenv')
143 self.setVarFlag(var, 'export', 1)
145 # more cookies for the cookie monster
147 override = var[var.rfind('_')+1:]
148 if not self._seen_overrides.has_key(override):
149 self._seen_overrides[override] = Set()
150 self._seen_overrides[override].add( var )
153 self.dict[var]["content"] = value
155 def getVar(self,var,exp):
156 value = self.getVarFlag(var,"content")
159 return self.expand(value,var)
162 def delVar(self,var):
165 def setVarFlag(self,var,flag,flagvalue):
166 if not var in self.dict:
167 self._makeShadowCopy(var)
168 self.dict[var][flag] = flagvalue
170 def getVarFlag(self,var,flag):
171 local_var = self._findVar(var)
173 if flag in local_var:
174 return copy.copy(local_var[flag])
177 def delVarFlag(self,var,flag):
178 local_var = self._findVar(var)
181 if not var in self.dict:
182 self._makeShadowCopy(var)
184 if var in self.dict and flag in self.dict[var]:
185 del self.dict[var][flag]
187 def setVarFlags(self,var,flags):
188 if not var in self.dict:
189 self._makeShadowCopy(var)
191 for i in flags.keys():
194 self.dict[var][i] = flags[i]
196 def getVarFlags(self,var):
197 local_var = self._findVar(var)
201 for i in self.dict[var].keys():
204 flags[i] = self.dict[var][i]
211 def delVarFlags(self,var):
212 if not var in self.dict:
213 self._makeShadowCopy(var)
218 # try to save the content
219 if "content" in self.dict[var]:
220 content = self.dict[var]["content"]
222 self.dict[var]["content"] = content
227 def createCopy(self):
229 Create a copy of self by setting _data to self
231 # we really want this to be a DataSmart...
232 data = DataSmart(seen=self._seen_overrides.copy(), special=self._special_values.copy())
233 data.dict["_data"] = self.dict
241 _keys(d["_data"],mykey)
247 _keys(self.dict,keytab)
250 def __getitem__(self,item):
251 #print "Warning deprecated"
252 return self.getVar(item, False)
254 def __setitem__(self,var,data):
255 #print "Warning deprecated"
256 self.setVar(var,data)