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