bitbake-1.4/bin/bitbake:
[vuplus_bitbake] / lib / bb / data_smart.py
1 # ex:ts=4:sw=4:sts=4:et
2 # -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
3 """
4 BitBake Smart Dictionary Implementation
5
6 Functions for interacting with the data structure used by the
7 BitBake build tools.
8
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
14
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
18 version.
19
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.
23
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. 
27
28 Based on functions from the base bb module, Copyright 2003 Holger Schurig
29 """
30
31 import copy, os, re, sys, time, types
32 from bb   import note, debug, error, fatal, utils, methodpool
33 from sets import Set
34
35 try:
36     import cPickle as pickle
37 except ImportError:
38     import pickle
39     print "NOTE: Importing cPickle failed. Falling back to a very slow implementation."
40
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"\${@.+?}")
45
46
47 class DataSmart:
48     def __init__(self):
49         self.dict = {}
50
51         # cookie monster tribute
52         self._special_values = {}
53         self._seen_overrides = {}
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         while s.find('$') != -1:
79             olds = s
80             try:
81                 s = __expand_var_regexp__.sub(var_sub, s)
82                 s = __expand_python_regexp__.sub(python_sub, s)
83                 if s == olds: break
84                 if type(s) is not types.StringType: # sanity check
85                     error('expansion of %s returned non-string %s' % (olds, s))
86             except KeyboardInterrupt:
87                 raise
88             except:
89                 note("%s:%s while evaluating:\n%s" % (sys.exc_info()[0], sys.exc_info()[1], s))
90                 raise
91         return s
92
93     def initVar(self, var):
94         if not var in self.dict:
95             self.dict[var] = {}
96
97     def _findVar(self,var):
98         _dest = self.dict
99
100         while (_dest and var not in _dest):
101             if not "_data" in _dest:
102                 _dest = None
103                 break
104             _dest = _dest["_data"]
105
106         if _dest and var in _dest:
107             return _dest[var]
108         return None
109
110     def _makeShadowCopy(self, var):
111         if var in self.dict:
112             return
113
114         local_var = self._findVar(var)
115
116         if local_var:
117             self.dict[var] = copy.copy(local_var)
118         else:
119             self.initVar(var)
120
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)
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 )
142             return
143
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)
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
157         # setting var
158         self.dict[var]["content"] = value
159
160     def getVar(self,var,exp):
161         value = self.getVarFlag(var,"content")
162
163         if exp and value:
164             return self.expand(value,var)
165         return value
166
167     def delVar(self,var):
168         self.dict[var] = {}
169
170     def setVarFlag(self,var,flag,flagvalue):
171         if not var in self.dict:
172             self._makeShadowCopy(var)
173         self.dict[var][flag] = flagvalue
174
175     def getVarFlag(self,var,flag):
176         local_var = self._findVar(var)
177         if local_var:
178             if flag in local_var:
179                 return copy.copy(local_var[flag])
180         return None
181
182     def delVarFlag(self,var,flag):
183         local_var = self._findVar(var)
184         if not local_var:
185             return
186         if not var in self.dict:
187             self._makeShadowCopy(var)
188
189         if var in self.dict and flag in self.dict[var]:
190             del self.dict[var][flag]
191
192     def setVarFlags(self,var,flags):
193         if not var in self.dict:
194             self._makeShadowCopy(var)
195
196         for i in flags.keys():
197             if i == "content":
198                 continue
199             self.dict[var][i] = flags[i]
200
201     def getVarFlags(self,var):
202         local_var = self._findVar(var)
203         flags = {}
204
205         if local_var:
206             for i in self.dict[var].keys():
207                 if i == "content":
208                     continue
209                 flags[i] = self.dict[var][i]
210
211         if len(flags) == 0:
212             return None
213         return flags
214
215
216     def delVarFlags(self,var):
217         if not var in self.dict:
218             self._makeShadowCopy(var)
219
220         if var in self.dict:
221             content = None
222
223             # try to save the content
224             if "content" in self.dict[var]:
225                 content  = self.dict[var]["content"]
226                 self.dict[var]            = {}
227                 self.dict[var]["content"] = content
228             else:
229                 del self.dict[var]
230
231
232     def createCopy(self):
233         """
234         Create a copy of self by setting _data to self
235         """
236         # we really want this to be a DataSmart...
237         data = DataSmart()
238         data.dict["_data"] = self.dict
239         data._seen_overrides = copy.deepcopy(self._seen_overrides)
240         data._special_values = copy.deepcopy(self._special_values)
241
242         return data
243
244     # Dictionary Methods
245     def keys(self):
246         def _keys(d, mykey):
247             if "_data" in d:
248                 _keys(d["_data"],mykey)
249
250             for key in d.keys():
251                 if key != "_data":
252                     mykey[key] = None
253         keytab = {}
254         _keys(self.dict,keytab)
255         return keytab.keys()
256
257     def __getitem__(self,item):
258         start = self.dict
259         while start:
260             if item in start:
261                 return start[item]
262             elif "_data" in start:
263                 start = start["_data"]
264             else:
265                 start = None
266         return None
267
268     def __setitem__(self,var,data):
269         self._makeShadowCopy(var)
270         self.dict[var] = data
271
272