summaryrefslogtreecommitdiffstats
path: root/bitbake-dev/lib/bb/data.py
diff options
context:
space:
mode:
Diffstat (limited to 'bitbake-dev/lib/bb/data.py')
-rw-r--r--bitbake-dev/lib/bb/data.py562
1 files changed, 0 insertions, 562 deletions
diff --git a/bitbake-dev/lib/bb/data.py b/bitbake-dev/lib/bb/data.py
deleted file mode 100644
index d3058b9a1d..0000000000
--- a/bitbake-dev/lib/bb/data.py
+++ /dev/null
@@ -1,562 +0,0 @@
1# ex:ts=4:sw=4:sts=4:et
2# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
3"""
4BitBake 'Data' implementations
5
6Functions for interacting with the data structure used by the
7BitBake build tools.
8
9The expandData and update_data are the most expensive
10operations. At night the cookie monster came by and
11suggested 'give me cookies on setting the variables and
12things will work out'. Taking this suggestion into account
13applying the skills from the not yet passed 'Entwurf und
14Analyse von Algorithmen' lecture and the cookie
15monster seems to be right. We will track setVar more carefully
16to have faster update_data and expandKeys operations.
17
18This is a treade-off between speed and memory again but
19the speed is more critical here.
20"""
21
22# Copyright (C) 2003, 2004 Chris Larson
23# Copyright (C) 2005 Holger Hans Peter Freyther
24#
25# This program is free software; you can redistribute it and/or modify
26# it under the terms of the GNU General Public License version 2 as
27# published by the Free Software Foundation.
28#
29# This program is distributed in the hope that it will be useful,
30# but WITHOUT ANY WARRANTY; without even the implied warranty of
31# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32# GNU General Public License for more details.
33#
34# You should have received a copy of the GNU General Public License along
35# with this program; if not, write to the Free Software Foundation, Inc.,
36# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
37#
38#Based on functions from the base bb module, Copyright 2003 Holger Schurig
39
40import sys, os, re, types
41if sys.argv[0][-5:] == "pydoc":
42 path = os.path.dirname(os.path.dirname(sys.argv[1]))
43else:
44 path = os.path.dirname(os.path.dirname(sys.argv[0]))
45sys.path.insert(0,path)
46
47from bb import data_smart
48import bb
49
50_dict_type = data_smart.DataSmart
51
52def init():
53 return _dict_type()
54
55def init_db(parent = None):
56 if parent:
57 return parent.createCopy()
58 else:
59 return _dict_type()
60
61def createCopy(source):
62 """Link the source set to the destination
63 If one does not find the value in the destination set,
64 search will go on to the source set to get the value.
65 Value from source are copy-on-write. i.e. any try to
66 modify one of them will end up putting the modified value
67 in the destination set.
68 """
69 return source.createCopy()
70
71def initVar(var, d):
72 """Non-destructive var init for data structure"""
73 d.initVar(var)
74
75
76def setVar(var, value, d):
77 """Set a variable to a given value
78
79 Example:
80 >>> d = init()
81 >>> setVar('TEST', 'testcontents', d)
82 >>> print getVar('TEST', d)
83 testcontents
84 """
85 d.setVar(var,value)
86
87
88def getVar(var, d, exp = 0):
89 """Gets the value of a variable
90
91 Example:
92 >>> d = init()
93 >>> setVar('TEST', 'testcontents', d)
94 >>> print getVar('TEST', d)
95 testcontents
96 """
97 return d.getVar(var,exp)
98
99
100def renameVar(key, newkey, d):
101 """Renames a variable from key to newkey
102
103 Example:
104 >>> d = init()
105 >>> setVar('TEST', 'testcontents', d)
106 >>> renameVar('TEST', 'TEST2', d)
107 >>> print getVar('TEST2', d)
108 testcontents
109 """
110 d.renameVar(key, newkey)
111
112def delVar(var, d):
113 """Removes a variable from the data set
114
115 Example:
116 >>> d = init()
117 >>> setVar('TEST', 'testcontents', d)
118 >>> print getVar('TEST', d)
119 testcontents
120 >>> delVar('TEST', d)
121 >>> print getVar('TEST', d)
122 None
123 """
124 d.delVar(var)
125
126def setVarFlag(var, flag, flagvalue, d):
127 """Set a flag for a given variable to a given value
128
129 Example:
130 >>> d = init()
131 >>> setVarFlag('TEST', 'python', 1, d)
132 >>> print getVarFlag('TEST', 'python', d)
133 1
134 """
135 d.setVarFlag(var,flag,flagvalue)
136
137def getVarFlag(var, flag, d):
138 """Gets given flag from given var
139
140 Example:
141 >>> d = init()
142 >>> setVarFlag('TEST', 'python', 1, d)
143 >>> print getVarFlag('TEST', 'python', d)
144 1
145 """
146 return d.getVarFlag(var,flag)
147
148def delVarFlag(var, flag, d):
149 """Removes a given flag from the variable's flags
150
151 Example:
152 >>> d = init()
153 >>> setVarFlag('TEST', 'testflag', 1, d)
154 >>> print getVarFlag('TEST', 'testflag', d)
155 1
156 >>> delVarFlag('TEST', 'testflag', d)
157 >>> print getVarFlag('TEST', 'testflag', d)
158 None
159
160 """
161 d.delVarFlag(var,flag)
162
163def setVarFlags(var, flags, d):
164 """Set the flags for a given variable
165
166 Note:
167 setVarFlags will not clear previous
168 flags. Think of this method as
169 addVarFlags
170
171 Example:
172 >>> d = init()
173 >>> myflags = {}
174 >>> myflags['test'] = 'blah'
175 >>> setVarFlags('TEST', myflags, d)
176 >>> print getVarFlag('TEST', 'test', d)
177 blah
178 """
179 d.setVarFlags(var,flags)
180
181def getVarFlags(var, d):
182 """Gets a variable's flags
183
184 Example:
185 >>> d = init()
186 >>> setVarFlag('TEST', 'test', 'blah', d)
187 >>> print getVarFlags('TEST', d)['test']
188 blah
189 """
190 return d.getVarFlags(var)
191
192def delVarFlags(var, d):
193 """Removes a variable's flags
194
195 Example:
196 >>> data = init()
197 >>> setVarFlag('TEST', 'testflag', 1, data)
198 >>> print getVarFlag('TEST', 'testflag', data)
199 1
200 >>> delVarFlags('TEST', data)
201 >>> print getVarFlags('TEST', data)
202 None
203
204 """
205 d.delVarFlags(var)
206
207def keys(d):
208 """Return a list of keys in d
209
210 Example:
211 >>> d = init()
212 >>> setVar('TEST', 1, d)
213 >>> setVar('MOO' , 2, d)
214 >>> setVarFlag('TEST', 'test', 1, d)
215 >>> keys(d)
216 ['TEST', 'MOO']
217 """
218 return d.keys()
219
220def getData(d):
221 """Returns the data object used"""
222 return d
223
224def setData(newData, d):
225 """Sets the data object to the supplied value"""
226 d = newData
227
228
229##
230## Cookie Monsters' query functions
231##
232def _get_override_vars(d, override):
233 """
234 Internal!!!
235
236 Get the Names of Variables that have a specific
237 override. This function returns a iterable
238 Set or an empty list
239 """
240 return []
241
242def _get_var_flags_triple(d):
243 """
244 Internal!!!
245
246 """
247 return []
248
249__expand_var_regexp__ = re.compile(r"\${[^{}]+}")
250__expand_python_regexp__ = re.compile(r"\${@.+?}")
251
252def expand(s, d, varname = None):
253 """Variable expansion using the data store.
254
255 Example:
256 Standard expansion:
257 >>> d = init()
258 >>> setVar('A', 'sshd', d)
259 >>> print expand('/usr/bin/${A}', d)
260 /usr/bin/sshd
261
262 Python expansion:
263 >>> d = init()
264 >>> print expand('result: ${@37 * 72}', d)
265 result: 2664
266
267 Shell expansion:
268 >>> d = init()
269 >>> print expand('${TARGET_MOO}', d)
270 ${TARGET_MOO}
271 >>> setVar('TARGET_MOO', 'yupp', d)
272 >>> print expand('${TARGET_MOO}',d)
273 yupp
274 >>> setVar('SRC_URI', 'http://somebug.${TARGET_MOO}', d)
275 >>> delVar('TARGET_MOO', d)
276 >>> print expand('${SRC_URI}', d)
277 http://somebug.${TARGET_MOO}
278 """
279 return d.expand(s, varname)
280
281def expandKeys(alterdata, readdata = None):
282 if readdata == None:
283 readdata = alterdata
284
285 todolist = {}
286 for key in keys(alterdata):
287 if not '${' in key:
288 continue
289
290 ekey = expand(key, readdata)
291 if key == ekey:
292 continue
293 todolist[key] = ekey
294
295 # These two for loops are split for performance to maximise the
296 # usefulness of the expand cache
297
298 for key in todolist:
299 ekey = todolist[key]
300 renameVar(key, ekey, alterdata)
301
302def expandData(alterdata, readdata = None):
303 """For each variable in alterdata, expand it, and update the var contents.
304 Replacements use data from readdata.
305
306 Example:
307 >>> a=init()
308 >>> b=init()
309 >>> setVar("dlmsg", "dl_dir is ${DL_DIR}", a)
310 >>> setVar("DL_DIR", "/path/to/whatever", b)
311 >>> expandData(a, b)
312 >>> print getVar("dlmsg", a)
313 dl_dir is /path/to/whatever
314 """
315 if readdata == None:
316 readdata = alterdata
317
318 for key in keys(alterdata):
319 val = getVar(key, alterdata)
320 if type(val) is not types.StringType:
321 continue
322 expanded = expand(val, readdata)
323# print "key is %s, val is %s, expanded is %s" % (key, val, expanded)
324 if val != expanded:
325 setVar(key, expanded, alterdata)
326
327def inheritFromOS(d):
328 """Inherit variables from the environment."""
329 for s in os.environ.keys():
330 try:
331 setVar(s, os.environ[s], d)
332 setVarFlag(s, "export", True, d)
333 except TypeError:
334 pass
335
336def emit_var(var, o=sys.__stdout__, d = init(), all=False):
337 """Emit a variable to be sourced by a shell."""
338 if getVarFlag(var, "python", d):
339 return 0
340
341 export = getVarFlag(var, "export", d)
342 unexport = getVarFlag(var, "unexport", d)
343 func = getVarFlag(var, "func", d)
344 if not all and not export and not unexport and not func:
345 return 0
346
347 try:
348 if all:
349 oval = getVar(var, d, 0)
350 val = getVar(var, d, 1)
351 except KeyboardInterrupt:
352 raise
353 except:
354 excname = str(sys.exc_info()[0])
355 if excname == "bb.build.FuncFailed":
356 raise
357 o.write('# expansion of %s threw %s\n' % (var, excname))
358 return 0
359
360 if all:
361 o.write('# %s=%s\n' % (var, oval))
362
363 if type(val) is not types.StringType:
364 return 0
365
366 if (var.find("-") != -1 or var.find(".") != -1 or var.find('{') != -1 or var.find('}') != -1 or var.find('+') != -1) and not all:
367 return 0
368
369 varExpanded = expand(var, d)
370
371 if unexport:
372 o.write('unset %s\n' % varExpanded)
373 return 1
374
375 val.rstrip()
376 if not val:
377 return 0
378
379 if func:
380 # NOTE: should probably check for unbalanced {} within the var
381 o.write("%s() {\n%s\n}\n" % (varExpanded, val))
382 return 1
383
384 if export:
385 o.write('export ')
386
387 # if we're going to output this within doublequotes,
388 # to a shell, we need to escape the quotes in the var
389 alter = re.sub('"', '\\"', val.strip())
390 o.write('%s="%s"\n' % (varExpanded, alter))
391 return 1
392
393
394def emit_env(o=sys.__stdout__, d = init(), all=False):
395 """Emits all items in the data store in a format such that it can be sourced by a shell."""
396
397 env = keys(d)
398
399 for e in env:
400 if getVarFlag(e, "func", d):
401 continue
402 emit_var(e, o, d, all) and o.write('\n')
403
404 for e in env:
405 if not getVarFlag(e, "func", d):
406 continue
407 emit_var(e, o, d) and o.write('\n')
408
409def update_data(d):
410 """Modifies the environment vars according to local overrides and commands.
411 Examples:
412 Appending to a variable:
413 >>> d = init()
414 >>> setVar('TEST', 'this is a', d)
415 >>> setVar('TEST_append', ' test', d)
416 >>> setVar('TEST_append', ' of the emergency broadcast system.', d)
417 >>> update_data(d)
418 >>> print getVar('TEST', d)
419 this is a test of the emergency broadcast system.
420
421 Prepending to a variable:
422 >>> setVar('TEST', 'virtual/libc', d)
423 >>> setVar('TEST_prepend', 'virtual/tmake ', d)
424 >>> setVar('TEST_prepend', 'virtual/patcher ', d)
425 >>> update_data(d)
426 >>> print getVar('TEST', d)
427 virtual/patcher virtual/tmake virtual/libc
428
429 Overrides:
430 >>> setVar('TEST_arm', 'target', d)
431 >>> setVar('TEST_ramses', 'machine', d)
432 >>> setVar('TEST_local', 'local', d)
433 >>> setVar('OVERRIDES', 'arm', d)
434
435 >>> setVar('TEST', 'original', d)
436 >>> update_data(d)
437 >>> print getVar('TEST', d)
438 target
439
440 >>> setVar('OVERRIDES', 'arm:ramses:local', d)
441 >>> setVar('TEST', 'original', d)
442 >>> update_data(d)
443 >>> print getVar('TEST', d)
444 local
445
446 CopyMonster:
447 >>> e = d.createCopy()
448 >>> setVar('TEST_foo', 'foo', e)
449 >>> update_data(e)
450 >>> print getVar('TEST', e)
451 local
452
453 >>> setVar('OVERRIDES', 'arm:ramses:local:foo', e)
454 >>> update_data(e)
455 >>> print getVar('TEST', e)
456 foo
457
458 >>> f = d.createCopy()
459 >>> setVar('TEST_moo', 'something', f)
460 >>> setVar('OVERRIDES', 'moo:arm:ramses:local:foo', e)
461 >>> update_data(e)
462 >>> print getVar('TEST', e)
463 foo
464
465
466 >>> h = init()
467 >>> setVar('SRC_URI', 'file://append.foo;patch=1 ', h)
468 >>> g = h.createCopy()
469 >>> setVar('SRC_URI_append_arm', 'file://other.foo;patch=1', g)
470 >>> setVar('OVERRIDES', 'arm:moo', g)
471 >>> update_data(g)
472 >>> print getVar('SRC_URI', g)
473 file://append.foo;patch=1 file://other.foo;patch=1
474
475 """
476 bb.msg.debug(2, bb.msg.domain.Data, "update_data()")
477
478 # now ask the cookie monster for help
479 #print "Cookie Monster"
480 #print "Append/Prepend %s" % d._special_values
481 #print "Overrides %s" % d._seen_overrides
482
483 overrides = (getVar('OVERRIDES', d, 1) or "").split(':') or []
484
485 #
486 # Well let us see what breaks here. We used to iterate
487 # over each variable and apply the override and then
488 # do the line expanding.
489 # If we have bad luck - which we will have - the keys
490 # where in some order that is so important for this
491 # method which we don't have anymore.
492 # Anyway we will fix that and write test cases this
493 # time.
494
495 #
496 # First we apply all overrides
497 # Then we will handle _append and _prepend
498 #
499
500 for o in overrides:
501 # calculate '_'+override
502 l = len(o)+1
503
504 # see if one should even try
505 if not d._seen_overrides.has_key(o):
506 continue
507
508 vars = d._seen_overrides[o]
509 for var in vars:
510 name = var[:-l]
511 try:
512 d[name] = d[var]
513 except:
514 bb.msg.note(1, bb.msg.domain.Data, "Untracked delVar")
515
516 # now on to the appends and prepends
517 if d._special_values.has_key('_append'):
518 appends = d._special_values['_append'] or []
519 for append in appends:
520 for (a, o) in getVarFlag(append, '_append', d) or []:
521 # maybe the OVERRIDE was not yet added so keep the append
522 if (o and o in overrides) or not o:
523 delVarFlag(append, '_append', d)
524 if o and not o in overrides:
525 continue
526
527 sval = getVar(append,d) or ""
528 sval+=a
529 setVar(append, sval, d)
530
531
532 if d._special_values.has_key('_prepend'):
533 prepends = d._special_values['_prepend'] or []
534
535 for prepend in prepends:
536 for (a, o) in getVarFlag(prepend, '_prepend', d) or []:
537 # maybe the OVERRIDE was not yet added so keep the prepend
538 if (o and o in overrides) or not o:
539 delVarFlag(prepend, '_prepend', d)
540 if o and not o in overrides:
541 continue
542
543 sval = a + (getVar(prepend,d) or "")
544 setVar(prepend, sval, d)
545
546
547def inherits_class(klass, d):
548 val = getVar('__inherit_cache', d) or []
549 if os.path.join('classes', '%s.bbclass' % klass) in val:
550 return True
551 return False
552
553def _test():
554 """Start a doctest run on this module"""
555 import doctest
556 import bb
557 from bb import data
558 bb.msg.set_debug_level(0)
559 doctest.testmod(data)
560
561if __name__ == "__main__":
562 _test()