summaryrefslogtreecommitdiffstats
path: root/bitbake-dev/lib/bb/data_smart.py
diff options
context:
space:
mode:
authorRichard Purdie <richard@openedhand.com>2008-09-30 15:08:33 +0000
committerRichard Purdie <richard@openedhand.com>2008-09-30 15:08:33 +0000
commitc30eddb243e7e65f67f656e62848a033cf6f2e5c (patch)
tree110dd95788b76f55d31cb8d30aac2de8400b6f4a /bitbake-dev/lib/bb/data_smart.py
parent5ef0510474004eeb2ae8a99b64e2febb1920e077 (diff)
downloadpoky-c30eddb243e7e65f67f656e62848a033cf6f2e5c.tar.gz
Add bitbake-dev to allow ease of testing and development of bitbake trunk
git-svn-id: https://svn.o-hand.com/repos/poky/trunk@5337 311d38ba-8fff-0310-9ca6-ca027cbcb966
Diffstat (limited to 'bitbake-dev/lib/bb/data_smart.py')
-rw-r--r--bitbake-dev/lib/bb/data_smart.py292
1 files changed, 292 insertions, 0 deletions
diff --git a/bitbake-dev/lib/bb/data_smart.py b/bitbake-dev/lib/bb/data_smart.py
new file mode 100644
index 0000000000..b3a51b0edf
--- /dev/null
+++ b/bitbake-dev/lib/bb/data_smart.py
@@ -0,0 +1,292 @@
1# ex:ts=4:sw=4:sts=4:et
2# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
3"""
4BitBake Smart Dictionary Implementation
5
6Functions for interacting with the data structure used by the
7BitBake build tools.
8
9"""
10
11# Copyright (C) 2003, 2004 Chris Larson
12# Copyright (C) 2004, 2005 Seb Frankengul
13# Copyright (C) 2005, 2006 Holger Hans Peter Freyther
14# Copyright (C) 2005 Uli Luckas
15# Copyright (C) 2005 ROAD GmbH
16#
17# This program is free software; you can redistribute it and/or modify
18# it under the terms of the GNU General Public License version 2 as
19# published by the Free Software Foundation.
20#
21# This program is distributed in the hope that it will be useful,
22# but WITHOUT ANY WARRANTY; without even the implied warranty of
23# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24# GNU General Public License for more details.
25#
26# You should have received a copy of the GNU General Public License along
27# with this program; if not, write to the Free Software Foundation, Inc.,
28# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
29# Based on functions from the base bb module, Copyright 2003 Holger Schurig
30
31import copy, os, re, sys, time, types
32import bb
33from bb import utils, methodpool
34from COW import COWDictBase
35from sets import Set
36from new import classobj
37
38
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"\${@.+?}")
43
44
45class DataSmart:
46 def __init__(self, special = COWDictBase.copy(), seen = COWDictBase.copy() ):
47 self.dict = {}
48
49 # cookie monster tribute
50 self._special_values = special
51 self._seen_overrides = seen
52
53 self.expand_cache = {}
54
55 def expand(self,s, varname):
56 def var_sub(match):
57 key = match.group()[2:-1]
58 if varname and key:
59 if varname == key:
60 raise Exception("variable %s references itself!" % varname)
61 var = self.getVar(key, 1)
62 if var is not None:
63 return var
64 else:
65 return match.group()
66
67 def python_sub(match):
68 import bb
69 code = match.group()[3:-1]
70 locals()['d'] = self
71 s = eval(code)
72 if type(s) == types.IntType: s = str(s)
73 return s
74
75 if type(s) is not types.StringType: # sanity check
76 return s
77
78 if varname and varname in self.expand_cache:
79 return self.expand_cache[varname]
80
81 while s.find('${') != -1:
82 olds = s
83 try:
84 s = __expand_var_regexp__.sub(var_sub, s)
85 s = __expand_python_regexp__.sub(python_sub, s)
86 if s == olds: break
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:
90 raise
91 except:
92 bb.msg.note(1, bb.msg.domain.Data, "%s:%s while evaluating:\n%s" % (sys.exc_info()[0], sys.exc_info()[1], s))
93 raise
94
95 if varname:
96 self.expand_cache[varname] = s
97
98 return s
99
100 def initVar(self, var):
101 self.expand_cache = {}
102 if not var in self.dict:
103 self.dict[var] = {}
104
105 def _findVar(self,var):
106 _dest = self.dict
107
108 while (_dest and var not in _dest):
109 if not "_data" in _dest:
110 _dest = None
111 break
112 _dest = _dest["_data"]
113
114 if _dest and var in _dest:
115 return _dest[var]
116 return None
117
118 def _makeShadowCopy(self, var):
119 if var in self.dict:
120 return
121
122 local_var = self._findVar(var)
123
124 if local_var:
125 self.dict[var] = copy.copy(local_var)
126 else:
127 self.initVar(var)
128
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)
139
140 # todo make sure keyword is not __doc__ or __module__
141 # pay the cookie monster
142 try:
143 self._special_values[keyword].add( base )
144 except:
145 self._special_values[keyword] = Set()
146 self._special_values[keyword].add( base )
147
148 return
149
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)
155
156 # more cookies for the cookie monster
157 if '_' in var:
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 )
162
163 # setting var
164 self.dict[var]["content"] = value
165
166 def getVar(self,var,exp):
167 value = self.getVarFlag(var,"content")
168
169 if exp and value:
170 return self.expand(value,var)
171 return value
172
173 def renameVar(self, key, newkey):
174 """
175 Rename the variable key to newkey
176 """
177 val = self.getVar(key, 0)
178 if val is None:
179 return
180
181 self.setVar(newkey, val)
182
183 for i in ('_append', '_prepend'):
184 dest = self.getVarFlag(newkey, i) or []
185 src = self.getVarFlag(key, i) or []
186 dest.extend(src)
187 self.setVarFlag(newkey, i, dest)
188
189 if self._special_values.has_key(i) and key in self._special_values[i]:
190 self._special_values[i].remove(key)
191 self._special_values[i].add(newkey)
192
193 self.delVar(key)
194
195 def delVar(self,var):
196 self.expand_cache = {}
197 self.dict[var] = {}
198
199 def setVarFlag(self,var,flag,flagvalue):
200 if not var in self.dict:
201 self._makeShadowCopy(var)
202 self.dict[var][flag] = flagvalue
203
204 def getVarFlag(self,var,flag):
205 local_var = self._findVar(var)
206 if local_var:
207 if flag in local_var:
208 return copy.copy(local_var[flag])
209 return None
210
211 def delVarFlag(self,var,flag):
212 local_var = self._findVar(var)
213 if not local_var:
214 return
215 if not var in self.dict:
216 self._makeShadowCopy(var)
217
218 if var in self.dict and flag in self.dict[var]:
219 del self.dict[var][flag]
220
221 def setVarFlags(self,var,flags):
222 if not var in self.dict:
223 self._makeShadowCopy(var)
224
225 for i in flags.keys():
226 if i == "content":
227 continue
228 self.dict[var][i] = flags[i]
229
230 def getVarFlags(self,var):
231 local_var = self._findVar(var)
232 flags = {}
233
234 if local_var:
235 for i in local_var.keys():
236 if i == "content":
237 continue
238 flags[i] = local_var[i]
239
240 if len(flags) == 0:
241 return None
242 return flags
243
244
245 def delVarFlags(self,var):
246 if not var in self.dict:
247 self._makeShadowCopy(var)
248
249 if var in self.dict:
250 content = None
251
252 # try to save the content
253 if "content" in self.dict[var]:
254 content = self.dict[var]["content"]
255 self.dict[var] = {}
256 self.dict[var]["content"] = content
257 else:
258 del self.dict[var]
259
260
261 def createCopy(self):
262 """
263 Create a copy of self by setting _data to self
264 """
265 # we really want this to be a DataSmart...
266 data = DataSmart(seen=self._seen_overrides.copy(), special=self._special_values.copy())
267 data.dict["_data"] = self.dict
268
269 return data
270
271 # Dictionary Methods
272 def keys(self):
273 def _keys(d, mykey):
274 if "_data" in d:
275 _keys(d["_data"],mykey)
276
277 for key in d.keys():
278 if key != "_data":
279 mykey[key] = None
280 keytab = {}
281 _keys(self.dict,keytab)
282 return keytab.keys()
283
284 def __getitem__(self,item):
285 #print "Warning deprecated"
286 return self.getVar(item, False)
287
288 def __setitem__(self,var,data):
289 #print "Warning deprecated"
290 self.setVar(var,data)
291
292