3 OpenEmbedded 'Data' implementations
5 Functions for interacting with the data structure used by the
6 OpenEmbedded (http://openembedded.org) build infrastructure.
8 Copyright: (c) 2003 Chris Larson
10 Based on functions from the base oe module, Copyright 2003 Holger Schurig
13 import sys, os, re, time, types
14 if sys.argv[0][-5:] == "pydoc":
15 path = os.path.dirname(os.path.dirname(sys.argv[1]))
17 path = os.path.dirname(os.path.dirname(sys.argv[0]))
20 from oe import note, debug
27 def initVar(var, d = _data):
28 """Non-destructive var init for data structure"""
32 if not "flags" in d[var]:
35 __setvar_regexp__ = {}
36 __setvar_regexp__["_append"] = re.compile('(?P<base>.*?)%s(_(?P<add>.*))?' % "_append")
37 __setvar_regexp__["_prepend"] = re.compile('(?P<base>.*?)%s(_(?P<add>.*))?' % "_prepend")
38 __setvar_regexp__["_delete"] = re.compile('(?P<base>.*?)%s(_(?P<add>.*))?' % "_delete")
40 def setVar(var, value, d = _data):
41 """Set a variable to a given value
44 >>> setVar('TEST', 'testcontents')
45 >>> print getVar('TEST')
48 for v in ["_append", "_prepend", "_delete"]:
49 match = __setvar_regexp__[v].match(var)
51 base = match.group('base')
52 override = match.group('add')
53 l = getVarFlag(base, v, d) or []
54 if override == 'delete':
55 if l.count([value, None]):
56 del l[l.index([value, None])]
57 l.append([value, override])
58 setVarFlag(base, v, l, d)
63 if getVarFlag(var, 'matchesenv', d):
64 delVarFlag(var, 'matchesenv', d)
65 setVarFlag(var, 'export', 1, d)
66 d[var]["content"] = value
68 def getVar(var, d = _data, exp = 0):
69 """Gets the value of a variable
72 >>> setVar('TEST', 'testcontents')
73 >>> print getVar('TEST')
76 if not var in d or not "content" in d[var]:
79 return expand(d[var]["content"], d)
80 return d[var]["content"]
82 def delVar(var, d = _data):
83 """Removes a variable from the data set
86 >>> setVar('TEST', 'testcontents')
87 >>> print getVar('TEST')
90 >>> print getVar('TEST')
96 def setVarFlag(var, flag, flagvalue, d = _data):
97 """Set a flag for a given variable to a given value
100 >>> setVarFlag('TEST', 'python', 1)
101 >>> print getVarFlag('TEST', 'python')
104 # print "d[%s][\"flags\"][%s] = %s" % (var, flag, flagvalue)
107 d[var]["flags"][flag] = flagvalue
109 def getVarFlag(var, flag, d = _data):
110 """Gets given flag from given var
113 >>> setVarFlag('TEST', 'python', 1)
114 >>> print getVarFlag('TEST', 'python')
117 if var in d and "flags" in d[var] and flag in d[var]["flags"]:
118 return d[var]["flags"][flag]
121 def delVarFlag(var, flag, d = _data):
122 """Removes a given flag from the variable's flags
125 >>> setVarFlag('TEST', 'testflag', 1)
126 >>> print getVarFlag('TEST', 'testflag')
128 >>> delVarFlag('TEST', 'testflag')
129 >>> print getVarFlag('TEST', 'testflag')
133 if var in d and "flags" in d[var] and flag in d[var]["flags"]:
134 del d[var]["flags"][flag]
136 def setVarFlags(var, flags, d = _data):
137 """Set the flags for a given variable
141 >>> myflags['test'] = 'blah'
142 >>> setVarFlags('TEST', myflags)
143 >>> print getVarFlag('TEST', 'test')
148 d[var]["flags"] = flags
150 def getVarFlags(var, d = _data):
151 """Gets a variable's flags
154 >>> setVarFlag('TEST', 'test', 'blah')
155 >>> print getVarFlags('TEST')['test']
158 if var in d and "flags" in d[var]:
159 return d[var]["flags"]
162 def delVarFlags(var, d = _data):
163 """Removes a variable's flags
166 >>> setVarFlag('TEST', 'testflag', 1)
167 >>> print getVarFlag('TEST', 'testflag')
169 >>> delVarFlags('TEST')
170 >>> print getVarFlags('TEST')
174 if var in d and "flags" in d[var]:
177 def getData(d = _data):
178 """Returns the data object used"""
181 def setData(newData, d = _data):
182 """Sets the data object to the supplied value"""
185 __expand_var_regexp__ = re.compile(r"\${[^{}]+}")
186 __expand_python_regexp__ = re.compile(r"\${@.+?}")
188 def expand(s, d = _data):
189 """Variable expansion using the data store.
193 >>> setVar('A', 'sshd')
194 >>> print expand('/usr/bin/${A}')
198 >>> print expand('result: ${@37 * 72}')
202 key = match.group()[2:-1]
203 #print "got key:", key
204 var = getVar(key, d, 1)
210 def python_sub(match):
211 code = match.group()[3:-1]
215 if type(s) == types.IntType: s = str(s)
218 if type(s) is not types.StringType: # sanity check
221 while s.find('$') != -1:
223 s = __expand_var_regexp__.sub(var_sub, s)
224 s = __expand_python_regexp__.sub(python_sub, s)
226 debug(1, "expanded string too long")
231 def expandKeys(alterdata = _data, readdata = None):
235 for key in alterdata.keys():
236 ekey = expand(key, readdata)
239 val = getVar(key, alterdata)
242 setVar(ekey, val, alterdata)
244 def expandData(alterdata = _data, readdata = None):
245 """For each variable in alterdata, expand it, and update the var contents.
246 Replacements use data from readdata.
251 >>> setVar("dlmsg", "dl_dir is ${DL_DIR}", a)
252 >>> setVar("DL_DIR", "/path/to/whatever", b)
254 >>> print getVar("dlmsg", a)
255 dl_dir is /path/to/whatever
260 for key in alterdata.keys():
261 val = getVar(key, alterdata)
262 if type(val) is not types.StringType:
264 expanded = expand(val, readdata)
265 # print "key is %s, val is %s, expanded is %s" % (key, val, expanded)
267 setVar(key, expanded, alterdata)
271 def inheritFromOS(d = _data):
272 """Inherit variables from the environment."""
273 # fakeroot needs to be able to set these
274 non_inherit_vars = [ "LD_LIBRARY_PATH", "LD_PRELOAD" ]
275 for s in os.environ.keys():
276 if not s in non_inherit_vars:
278 setVar(s, os.environ[s], d)
279 setVarFlag(s, 'matchesenv', '1', d)
285 def emit_var(var, o=sys.__stdout__, d = _data):
286 """Emit a variable to be sourced by a shell."""
287 if getVarFlag(var, "python", d):
290 val = getVar(var, d, 1)
291 if type(val) is not types.StringType:
292 debug(2, "Warning, %s variable is not a string, not emitting" % var)
295 if getVarFlag(var, 'matchesenv', d):
298 if var.find("-") != -1 or var.find(".") != -1 or var.find('{') != -1 or var.find('}') != -1 or var.find('+') != -1:
299 debug(2, "Warning, %s variable name contains an invalid char, not emitting to shell" % var)
302 if getVarFlag(var, "func", d):
303 # NOTE: should probably check for unbalanced {} within the var
304 o.write("%s() {\n%s\n}\n" % (var, val))
306 if not getVarFlag(var, "export", d):
310 # if we're going to output this within doublequotes,
311 # to a shell, we need to escape the quotes in the var
312 alter = re.sub('"', '\\"', val.strip())
313 o.write('%s="%s"\n' % (var, alter))
317 def emit_env(o=sys.__stdout__, d = _data):
318 """Emits all items in the data store in a format such that it can be sourced by a shell."""
324 if getVarFlag(e, "func", d):
326 emit_var(e, o, d) and o.write('\n')
329 if not getVarFlag(e, "func", d):
331 emit_var(e, o, d) and o.write('\n')
333 def update_data(d = _data):
334 """Modifies the environment vars according to local overrides and commands.
336 Appending to a variable:
337 >>> setVar('TEST', 'this is a')
338 >>> setVar('TEST_append', ' test')
339 >>> setVar('TEST_append', ' of the emergency broadcast system.')
341 >>> print getVar('TEST')
342 this is a test of the emergency broadcast system.
344 Prepending to a variable:
345 >>> setVar('TEST', 'virtual/libc')
346 >>> setVar('TEST_prepend', 'virtual/tmake ')
347 >>> setVar('TEST_prepend', 'virtual/patcher ')
349 >>> print getVar('TEST')
350 virtual/patcher virtual/tmake virtual/libc
353 >>> setVar('TEST_arm', 'target')
354 >>> setVar('TEST_ramses', 'machine')
355 >>> setVar('TEST_local', 'local')
356 >>> setVar('OVERRIDES', 'arm')
358 >>> setVar('TEST', 'original')
360 >>> print getVar('TEST')
363 >>> setVar('OVERRIDES', 'arm:ramses:local')
364 >>> setVar('TEST', 'original')
366 >>> print getVar('TEST')
370 debug(2, "update_data()")
372 # can't do delete env[...] while iterating over the dictionary, so remember them
374 overrides = string.split(getVar('OVERRIDES', d, 1) or "", ":") or []
376 def applyOverrides(var, d = _data):
378 debug(1, "OVERRIDES not defined, nothing to do")
382 if var.endswith("_" + o):
389 sval = getVar(s, d) or ""
391 # Handle line appends:
392 for (a, o) in getVarFlag(s, '_append', d) or []:
393 delVarFlag(s, '_append', d)
395 if not o in overrides:
400 # Handle line prepends
401 for (a, o) in getVarFlag(s, '_prepend', d) or []:
402 delVarFlag(s, '_prepend', d)
404 if not o in overrides:
409 # Handle line deletions
411 nameval = getVar(name, d)
416 pattern = string.replace(nameval,"\n","").strip()
417 for line in string.split(sval,"\n"):
418 if line.find(pattern) == -1:
419 new = new + '\n' + line
423 # delete all environment vars no longer needed
428 """Start a doctest run on this module"""
431 doctest.testmod(data)
433 if __name__ == "__main__":