summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/bb/parse
diff options
context:
space:
mode:
Diffstat (limited to 'bitbake/lib/bb/parse')
-rw-r--r--bitbake/lib/bb/parse/__init__.py49
-rw-r--r--bitbake/lib/bb/parse/ast.py154
-rw-r--r--bitbake/lib/bb/parse/parse_py/BBHandler.py61
-rw-r--r--bitbake/lib/bb/parse/parse_py/ConfHandler.py24
4 files changed, 232 insertions, 56 deletions
diff --git a/bitbake/lib/bb/parse/__init__.py b/bitbake/lib/bb/parse/__init__.py
index a4358f1374..d428d8a4b4 100644
--- a/bitbake/lib/bb/parse/__init__.py
+++ b/bitbake/lib/bb/parse/__init__.py
@@ -49,20 +49,23 @@ class SkipPackage(SkipRecipe):
49__mtime_cache = {} 49__mtime_cache = {}
50def cached_mtime(f): 50def cached_mtime(f):
51 if f not in __mtime_cache: 51 if f not in __mtime_cache:
52 __mtime_cache[f] = os.stat(f)[stat.ST_MTIME] 52 res = os.stat(f)
53 __mtime_cache[f] = (res.st_mtime_ns, res.st_size, res.st_ino)
53 return __mtime_cache[f] 54 return __mtime_cache[f]
54 55
55def cached_mtime_noerror(f): 56def cached_mtime_noerror(f):
56 if f not in __mtime_cache: 57 if f not in __mtime_cache:
57 try: 58 try:
58 __mtime_cache[f] = os.stat(f)[stat.ST_MTIME] 59 res = os.stat(f)
60 __mtime_cache[f] = (res.st_mtime_ns, res.st_size, res.st_ino)
59 except OSError: 61 except OSError:
60 return 0 62 return 0
61 return __mtime_cache[f] 63 return __mtime_cache[f]
62 64
63def check_mtime(f, mtime): 65def check_mtime(f, mtime):
64 try: 66 try:
65 current_mtime = os.stat(f)[stat.ST_MTIME] 67 res = os.stat(f)
68 current_mtime = (res.st_mtime_ns, res.st_size, res.st_ino)
66 __mtime_cache[f] = current_mtime 69 __mtime_cache[f] = current_mtime
67 except OSError: 70 except OSError:
68 current_mtime = 0 71 current_mtime = 0
@@ -70,7 +73,8 @@ def check_mtime(f, mtime):
70 73
71def update_mtime(f): 74def update_mtime(f):
72 try: 75 try:
73 __mtime_cache[f] = os.stat(f)[stat.ST_MTIME] 76 res = os.stat(f)
77 __mtime_cache[f] = (res.st_mtime_ns, res.st_size, res.st_ino)
74 except OSError: 78 except OSError:
75 if f in __mtime_cache: 79 if f in __mtime_cache:
76 del __mtime_cache[f] 80 del __mtime_cache[f]
@@ -172,4 +176,41 @@ def get_file_depends(d):
172 dep_files.append(os.path.abspath(fn)) 176 dep_files.append(os.path.abspath(fn))
173 return " ".join(dep_files) 177 return " ".join(dep_files)
174 178
179def vardeps(*varnames):
180 """
181 Function decorator that can be used to instruct the bitbake dependency
182 parsing to add a dependency on the specified variables names
183
184 Example:
185
186 @bb.parse.vardeps("FOO", "BAR")
187 def my_function():
188 ...
189
190 """
191 def inner(f):
192 if not hasattr(f, "bb_vardeps"):
193 f.bb_vardeps = set()
194 f.bb_vardeps |= set(varnames)
195 return f
196 return inner
197
198def vardepsexclude(*varnames):
199 """
200 Function decorator that can be used to instruct the bitbake dependency
201 parsing to ignore dependencies on the specified variable names in the code
202
203 Example:
204
205 @bb.parse.vardepsexclude("FOO", "BAR")
206 def my_function():
207 ...
208 """
209 def inner(f):
210 if not hasattr(f, "bb_vardepsexclude"):
211 f.bb_vardepsexclude = set()
212 f.bb_vardepsexclude |= set(varnames)
213 return f
214 return inner
215
175from bb.parse.parse_py import __version__, ConfHandler, BBHandler 216from bb.parse.parse_py import __version__, ConfHandler, BBHandler
diff --git a/bitbake/lib/bb/parse/ast.py b/bitbake/lib/bb/parse/ast.py
index 7581d003fd..49a0788038 100644
--- a/bitbake/lib/bb/parse/ast.py
+++ b/bitbake/lib/bb/parse/ast.py
@@ -43,6 +43,21 @@ class IncludeNode(AstNode):
43 else: 43 else:
44 bb.parse.ConfHandler.include(self.filename, s, self.lineno, data, False) 44 bb.parse.ConfHandler.include(self.filename, s, self.lineno, data, False)
45 45
46class IncludeAllNode(AstNode):
47 def __init__(self, filename, lineno, what_file):
48 AstNode.__init__(self, filename, lineno)
49 self.what_file = what_file
50
51 def eval(self, data):
52 """
53 Include the file and evaluate the statements
54 """
55 s = data.expand(self.what_file)
56 logger.debug2("CONF %s:%s: including %s", self.filename, self.lineno, s)
57
58 for path in data.getVar("BBPATH").split(":"):
59 bb.parse.ConfHandler.include(self.filename, os.path.join(path, s), self.lineno, data, False)
60
46class ExportNode(AstNode): 61class ExportNode(AstNode):
47 def __init__(self, filename, lineno, var): 62 def __init__(self, filename, lineno, var):
48 AstNode.__init__(self, filename, lineno) 63 AstNode.__init__(self, filename, lineno)
@@ -137,7 +152,10 @@ class DataNode(AstNode):
137 152
138 flag = None 153 flag = None
139 if 'flag' in groupd and groupd['flag'] is not None: 154 if 'flag' in groupd and groupd['flag'] is not None:
140 flag = groupd['flag'] 155 if groupd["lazyques"]:
156 flag = "_defaultval_flag_"+groupd['flag']
157 else:
158 flag = groupd['flag']
141 elif groupd["lazyques"]: 159 elif groupd["lazyques"]:
142 flag = "_defaultval" 160 flag = "_defaultval"
143 161
@@ -240,14 +258,16 @@ class ExportFuncsNode(AstNode):
240 data.setVar(func, sentinel + " " + calledfunc + "\n", parsing=True) 258 data.setVar(func, sentinel + " " + calledfunc + "\n", parsing=True)
241 259
242class AddTaskNode(AstNode): 260class AddTaskNode(AstNode):
243 def __init__(self, filename, lineno, func, before, after): 261 def __init__(self, filename, lineno, tasks, before, after):
244 AstNode.__init__(self, filename, lineno) 262 AstNode.__init__(self, filename, lineno)
245 self.func = func 263 self.tasks = tasks
246 self.before = before 264 self.before = before
247 self.after = after 265 self.after = after
248 266
249 def eval(self, data): 267 def eval(self, data):
250 bb.build.addtask(self.func, self.before, self.after, data) 268 tasks = self.tasks.split()
269 for task in tasks:
270 bb.build.addtask(task, self.before, self.after, data)
251 271
252class DelTaskNode(AstNode): 272class DelTaskNode(AstNode):
253 def __init__(self, filename, lineno, tasks): 273 def __init__(self, filename, lineno, tasks):
@@ -320,13 +340,62 @@ class InheritDeferredNode(AstNode):
320 self.inherit = (classes, filename, lineno) 340 self.inherit = (classes, filename, lineno)
321 341
322 def eval(self, data): 342 def eval(self, data):
323 inherits = data.getVar('__BBDEFINHERITS', False) or [] 343 bb.parse.BBHandler.inherit_defer(*self.inherit, data)
324 inherits.append(self.inherit) 344
325 data.setVar('__BBDEFINHERITS', inherits) 345class AddFragmentsNode(AstNode):
346 def __init__(self, filename, lineno, fragments_path_prefix, fragments_variable, flagged_variables_list_variable, builtin_fragments_variable):
347 AstNode.__init__(self, filename, lineno)
348 self.fragments_path_prefix = fragments_path_prefix
349 self.fragments_variable = fragments_variable
350 self.flagged_variables_list_variable = flagged_variables_list_variable
351 self.builtin_fragments_variable = builtin_fragments_variable
352
353 def eval(self, data):
354 # No need to use mark_dependency since we would only match a fragment
355 # from a specific layer and there can only be a single layer with a
356 # given namespace.
357 def find_fragment(layers, layerid, full_fragment_name):
358 for layerpath in layers.split():
359 candidate_fragment_path = os.path.join(layerpath, full_fragment_name)
360 if os.path.exists(candidate_fragment_path) and bb.utils.get_file_layer(candidate_fragment_path, data) == layerid:
361 return candidate_fragment_path
362 return None
363
364 def check_and_set_builtin_fragment(fragment, data, builtin_fragments):
365 prefix, value = fragment.split('/', 1)
366 if prefix in builtin_fragments.keys():
367 data.setVar(builtin_fragments[prefix], value)
368 return True
369 return False
370
371 fragments = data.getVar(self.fragments_variable)
372 layers = data.getVar('BBLAYERS')
373 flagged_variables = data.getVar(self.flagged_variables_list_variable).split()
374 builtin_fragments = {f[0]:f[1] for f in [f.split(':') for f in data.getVar(self.builtin_fragments_variable).split()] }
375
376 if not fragments:
377 return
378 for f in fragments.split():
379 if check_and_set_builtin_fragment(f, data, builtin_fragments):
380 continue
381 layerid, fragment_name = f.split('/', 1)
382 full_fragment_name = data.expand("{}/{}.conf".format(self.fragments_path_prefix, fragment_name))
383 fragment_path = find_fragment(layers, layerid, full_fragment_name)
384 if fragment_path:
385 bb.parse.ConfHandler.include(self.filename, fragment_path, self.lineno, data, "include fragment")
386 for flagged_var in flagged_variables:
387 val = data.getVar(flagged_var)
388 data.setVarFlag(flagged_var, f, val)
389 data.setVar(flagged_var, None)
390 else:
391 bb.error("Could not find fragment {} in enabled layers: {}".format(f, layers))
326 392
327def handleInclude(statements, filename, lineno, m, force): 393def handleInclude(statements, filename, lineno, m, force):
328 statements.append(IncludeNode(filename, lineno, m.group(1), force)) 394 statements.append(IncludeNode(filename, lineno, m.group(1), force))
329 395
396def handleIncludeAll(statements, filename, lineno, m):
397 statements.append(IncludeAllNode(filename, lineno, m.group(1)))
398
330def handleExport(statements, filename, lineno, m): 399def handleExport(statements, filename, lineno, m):
331 statements.append(ExportNode(filename, lineno, m.group(1))) 400 statements.append(ExportNode(filename, lineno, m.group(1)))
332 401
@@ -348,21 +417,11 @@ def handlePythonMethod(statements, filename, lineno, funcname, modulename, body)
348def handleExportFuncs(statements, filename, lineno, m, classname): 417def handleExportFuncs(statements, filename, lineno, m, classname):
349 statements.append(ExportFuncsNode(filename, lineno, m.group(1), classname)) 418 statements.append(ExportFuncsNode(filename, lineno, m.group(1), classname))
350 419
351def handleAddTask(statements, filename, lineno, m): 420def handleAddTask(statements, filename, lineno, tasks, before, after):
352 func = m.group("func") 421 statements.append(AddTaskNode(filename, lineno, tasks, before, after))
353 before = m.group("before")
354 after = m.group("after")
355 if func is None:
356 return
357
358 statements.append(AddTaskNode(filename, lineno, func, before, after))
359 422
360def handleDelTask(statements, filename, lineno, m): 423def handleDelTask(statements, filename, lineno, tasks):
361 func = m.group(1) 424 statements.append(DelTaskNode(filename, lineno, tasks))
362 if func is None:
363 return
364
365 statements.append(DelTaskNode(filename, lineno, func))
366 425
367def handleBBHandlers(statements, filename, lineno, m): 426def handleBBHandlers(statements, filename, lineno, m):
368 statements.append(BBHandlerNode(filename, lineno, m.group(1))) 427 statements.append(BBHandlerNode(filename, lineno, m.group(1)))
@@ -378,12 +437,43 @@ def handleInheritDeferred(statements, filename, lineno, m):
378 classes = m.group(1) 437 classes = m.group(1)
379 statements.append(InheritDeferredNode(filename, lineno, classes)) 438 statements.append(InheritDeferredNode(filename, lineno, classes))
380 439
440def handleAddFragments(statements, filename, lineno, m):
441 fragments_path_prefix = m.group(1)
442 fragments_variable = m.group(2)
443 flagged_variables_list_variable = m.group(3)
444 builtin_fragments_variable = m.group(4)
445 statements.append(AddFragmentsNode(filename, lineno, fragments_path_prefix, fragments_variable, flagged_variables_list_variable, builtin_fragments_variable))
446
381def runAnonFuncs(d): 447def runAnonFuncs(d):
382 code = [] 448 code = []
383 for funcname in d.getVar("__BBANONFUNCS", False) or []: 449 for funcname in d.getVar("__BBANONFUNCS", False) or []:
384 code.append("%s(d)" % funcname) 450 code.append("%s(d)" % funcname)
385 bb.utils.better_exec("\n".join(code), {"d": d}) 451 bb.utils.better_exec("\n".join(code), {"d": d})
386 452
453# Handle recipe level PREFERRED_PROVIDERs
454def handleVirtRecipeProviders(tasklist, d):
455 depends = (d.getVar("DEPENDS") or "").split()
456 virtprovs = (d.getVar("BB_RECIPE_VIRTUAL_PROVIDERS") or "").split()
457 newdeps = []
458 for dep in depends:
459 if dep in virtprovs:
460 newdep = d.getVar("PREFERRED_PROVIDER_" + dep)
461 if not newdep:
462 bb.fatal("Error, recipe virtual provider PREFERRED_PROVIDER_%s not set" % dep)
463 newdeps.append(newdep)
464 else:
465 newdeps.append(dep)
466 d.setVar("DEPENDS", " ".join(newdeps))
467 for task in tasklist:
468 taskdeps = (d.getVarFlag(task, "depends") or "").split()
469 remapped = []
470 for entry in taskdeps:
471 r, t = entry.split(":")
472 if r in virtprovs:
473 r = d.getVar("PREFERRED_PROVIDER_" + r)
474 remapped.append("%s:%s" % (r, t))
475 d.setVarFlag(task, "depends", " ".join(remapped))
476
387def finalize(fn, d, variant = None): 477def finalize(fn, d, variant = None):
388 saved_handlers = bb.event.get_handlers().copy() 478 saved_handlers = bb.event.get_handlers().copy()
389 try: 479 try:
@@ -391,6 +481,17 @@ def finalize(fn, d, variant = None):
391 if d.getVar("_FAILPARSINGERRORHANDLED", False) == True: 481 if d.getVar("_FAILPARSINGERRORHANDLED", False) == True:
392 raise bb.BBHandledException() 482 raise bb.BBHandledException()
393 483
484 inherits = [x[0] for x in (d.getVar('__BBDEFINHERITS', False) or [('',)])]
485 bb.event.fire(bb.event.RecipePreDeferredInherits(fn, inherits), d)
486
487 while True:
488 inherits = d.getVar('__BBDEFINHERITS', False) or []
489 if not inherits:
490 break
491 inherit, filename, lineno = inherits.pop(0)
492 d.setVar('__BBDEFINHERITS', inherits)
493 bb.parse.BBHandler.inherit(inherit, filename, lineno, d, deferred=True)
494
394 for var in d.getVar('__BBHANDLERS', False) or []: 495 for var in d.getVar('__BBHANDLERS', False) or []:
395 # try to add the handler 496 # try to add the handler
396 handlerfn = d.getVarFlag(var, "filename", False) 497 handlerfn = d.getVarFlag(var, "filename", False)
@@ -409,6 +510,7 @@ def finalize(fn, d, variant = None):
409 510
410 tasklist = d.getVar('__BBTASKS', False) or [] 511 tasklist = d.getVar('__BBTASKS', False) or []
411 bb.event.fire(bb.event.RecipeTaskPreProcess(fn, list(tasklist)), d) 512 bb.event.fire(bb.event.RecipeTaskPreProcess(fn, list(tasklist)), d)
513 handleVirtRecipeProviders(tasklist, d)
412 bb.build.add_tasks(tasklist, d) 514 bb.build.add_tasks(tasklist, d)
413 515
414 bb.parse.siggen.finalise(fn, d, variant) 516 bb.parse.siggen.finalise(fn, d, variant)
@@ -444,14 +546,6 @@ def multi_finalize(fn, d):
444 logger.debug("Appending .bbappend file %s to %s", append, fn) 546 logger.debug("Appending .bbappend file %s to %s", append, fn)
445 bb.parse.BBHandler.handle(append, d, True) 547 bb.parse.BBHandler.handle(append, d, True)
446 548
447 while True:
448 inherits = d.getVar('__BBDEFINHERITS', False) or []
449 if not inherits:
450 break
451 inherit, filename, lineno = inherits.pop(0)
452 d.setVar('__BBDEFINHERITS', inherits)
453 bb.parse.BBHandler.inherit(inherit, filename, lineno, d, deferred=True)
454
455 onlyfinalise = d.getVar("__ONLYFINALISE", False) 549 onlyfinalise = d.getVar("__ONLYFINALISE", False)
456 550
457 safe_d = d 551 safe_d = d
@@ -487,7 +581,7 @@ def multi_finalize(fn, d):
487 d.setVar("BBEXTENDVARIANT", variantmap[name]) 581 d.setVar("BBEXTENDVARIANT", variantmap[name])
488 else: 582 else:
489 d.setVar("PN", "%s-%s" % (pn, name)) 583 d.setVar("PN", "%s-%s" % (pn, name))
490 bb.parse.BBHandler.inherit(extendedmap[name], fn, 0, d) 584 bb.parse.BBHandler.inherit_defer(extendedmap[name], fn, 0, d)
491 585
492 safe_d.setVar("BBCLASSEXTEND", extended) 586 safe_d.setVar("BBCLASSEXTEND", extended)
493 _create_variants(datastores, extendedmap.keys(), extendfunc, onlyfinalise) 587 _create_variants(datastores, extendedmap.keys(), extendfunc, onlyfinalise)
diff --git a/bitbake/lib/bb/parse/parse_py/BBHandler.py b/bitbake/lib/bb/parse/parse_py/BBHandler.py
index cd1c998f8f..008fec2308 100644
--- a/bitbake/lib/bb/parse/parse_py/BBHandler.py
+++ b/bitbake/lib/bb/parse/parse_py/BBHandler.py
@@ -23,8 +23,8 @@ __func_start_regexp__ = re.compile(r"(((?P<py>python(?=(\s|\()))|(?P<fr>faker
23__inherit_regexp__ = re.compile(r"inherit\s+(.+)" ) 23__inherit_regexp__ = re.compile(r"inherit\s+(.+)" )
24__inherit_def_regexp__ = re.compile(r"inherit_defer\s+(.+)" ) 24__inherit_def_regexp__ = re.compile(r"inherit_defer\s+(.+)" )
25__export_func_regexp__ = re.compile(r"EXPORT_FUNCTIONS\s+(.+)" ) 25__export_func_regexp__ = re.compile(r"EXPORT_FUNCTIONS\s+(.+)" )
26__addtask_regexp__ = re.compile(r"addtask\s+(?P<func>\w+)\s*((before\s*(?P<before>((.*(?=after))|(.*))))|(after\s*(?P<after>((.*(?=before))|(.*)))))*") 26__addtask_regexp__ = re.compile(r"addtask\s+([^#\n]+)(?P<comment>#.*|.*?)")
27__deltask_regexp__ = re.compile(r"deltask\s+(.+)") 27__deltask_regexp__ = re.compile(r"deltask\s+([^#\n]+)(?P<comment>#.*|.*?)")
28__addhandler_regexp__ = re.compile(r"addhandler\s+(.+)" ) 28__addhandler_regexp__ = re.compile(r"addhandler\s+(.+)" )
29__def_regexp__ = re.compile(r"def\s+(\w+).*:" ) 29__def_regexp__ = re.compile(r"def\s+(\w+).*:" )
30__python_func_regexp__ = re.compile(r"(\s+.*)|(^$)|(^#)" ) 30__python_func_regexp__ = re.compile(r"(\s+.*)|(^$)|(^#)" )
@@ -34,6 +34,7 @@ __infunc__ = []
34__inpython__ = False 34__inpython__ = False
35__body__ = [] 35__body__ = []
36__classname__ = "" 36__classname__ = ""
37__residue__ = []
37 38
38cached_statements = {} 39cached_statements = {}
39 40
@@ -41,12 +42,22 @@ def supports(fn, d):
41 """Return True if fn has a supported extension""" 42 """Return True if fn has a supported extension"""
42 return os.path.splitext(fn)[-1] in [".bb", ".bbclass", ".inc"] 43 return os.path.splitext(fn)[-1] in [".bb", ".bbclass", ".inc"]
43 44
45def inherit_defer(expression, fn, lineno, d):
46 inherit = (expression, fn, lineno)
47 inherits = d.getVar('__BBDEFINHERITS', False) or []
48 inherits.append(inherit)
49 d.setVar('__BBDEFINHERITS', inherits)
50
44def inherit(files, fn, lineno, d, deferred=False): 51def inherit(files, fn, lineno, d, deferred=False):
45 __inherit_cache = d.getVar('__inherit_cache', False) or [] 52 __inherit_cache = d.getVar('__inherit_cache', False) or []
46 #if "${" in files and not deferred: 53 #if "${" in files and not deferred:
47 # bb.warn("%s:%s has non deferred conditional inherit" % (fn, lineno)) 54 # bb.warn("%s:%s has non deferred conditional inherit" % (fn, lineno))
48 files = d.expand(files).split() 55 files = d.expand(files).split()
49 for file in files: 56 for file in files:
57 defer = (d.getVar("BB_DEFER_BBCLASSES") or "").split()
58 if not deferred and file in defer:
59 inherit_defer(file, fn, lineno, d)
60 continue
50 classtype = d.getVar("__bbclasstype", False) 61 classtype = d.getVar("__bbclasstype", False)
51 origfile = file 62 origfile = file
52 for t in ["classes-" + classtype, "classes"]: 63 for t in ["classes-" + classtype, "classes"]:
@@ -80,7 +91,7 @@ def inherit(files, fn, lineno, d, deferred=False):
80 __inherit_cache = d.getVar('__inherit_cache', False) or [] 91 __inherit_cache = d.getVar('__inherit_cache', False) or []
81 92
82def get_statements(filename, absolute_filename, base_name): 93def get_statements(filename, absolute_filename, base_name):
83 global cached_statements 94 global cached_statements, __residue__, __body__
84 95
85 try: 96 try:
86 return cached_statements[absolute_filename] 97 return cached_statements[absolute_filename]
@@ -100,6 +111,11 @@ def get_statements(filename, absolute_filename, base_name):
100 # add a blank line to close out any python definition 111 # add a blank line to close out any python definition
101 feeder(lineno, "", filename, base_name, statements, eof=True) 112 feeder(lineno, "", filename, base_name, statements, eof=True)
102 113
114 if __residue__:
115 raise ParseError("Unparsed lines %s: %s" % (filename, str(__residue__)), filename, lineno)
116 if __body__:
117 raise ParseError("Unparsed lines from unclosed function %s: %s" % (filename, str(__body__)), filename, lineno)
118
103 if filename.endswith(".bbclass") or filename.endswith(".inc"): 119 if filename.endswith(".bbclass") or filename.endswith(".inc"):
104 cached_statements[absolute_filename] = statements 120 cached_statements[absolute_filename] = statements
105 return statements 121 return statements
@@ -233,29 +249,38 @@ def feeder(lineno, s, fn, root, statements, eof=False):
233 249
234 m = __addtask_regexp__.match(s) 250 m = __addtask_regexp__.match(s)
235 if m: 251 if m:
236 if len(m.group().split()) == 2: 252 after = ""
237 # Check and warn for "addtask task1 task2" 253 before = ""
238 m2 = re.match(r"addtask\s+(?P<func>\w+)(?P<ignores>.*)", s) 254
239 if m2 and m2.group('ignores'): 255 # This code splits on 'before' and 'after' instead of on whitespace so we can defer
240 logger.warning('addtask ignored: "%s"' % m2.group('ignores')) 256 # evaluation to as late as possible.
241 257 tasks = m.group(1).split(" before ")[0].split(" after ")[0]
242 # Check and warn for "addtask task1 before task2 before task3", the
243 # similar to "after"
244 taskexpression = s.split()
245 for word in ('before', 'after'):
246 if taskexpression.count(word) > 1:
247 logger.warning("addtask contained multiple '%s' keywords, only one is supported" % word)
248 258
249 # Check and warn for having task with exprssion as part of task name 259 for exp in m.group(1).split(" before "):
260 exp2 = exp.split(" after ")
261 if len(exp2) > 1:
262 after = after + " ".join(exp2[1:])
263
264 for exp in m.group(1).split(" after "):
265 exp2 = exp.split(" before ")
266 if len(exp2) > 1:
267 before = before + " ".join(exp2[1:])
268
269 # Check and warn for having task with a keyword as part of task name
270 taskexpression = s.split()
250 for te in taskexpression: 271 for te in taskexpression:
251 if any( ( "%s_" % keyword ) in te for keyword in bb.data_smart.__setvar_keyword__ ): 272 if any( ( "%s_" % keyword ) in te for keyword in bb.data_smart.__setvar_keyword__ ):
252 raise ParseError("Task name '%s' contains a keyword which is not recommended/supported.\nPlease rename the task not to include the keyword.\n%s" % (te, ("\n".join(map(str, bb.data_smart.__setvar_keyword__)))), fn) 273 raise ParseError("Task name '%s' contains a keyword which is not recommended/supported.\nPlease rename the task not to include the keyword.\n%s" % (te, ("\n".join(map(str, bb.data_smart.__setvar_keyword__)))), fn)
253 ast.handleAddTask(statements, fn, lineno, m) 274
275 if tasks is not None:
276 ast.handleAddTask(statements, fn, lineno, tasks, before, after)
254 return 277 return
255 278
256 m = __deltask_regexp__.match(s) 279 m = __deltask_regexp__.match(s)
257 if m: 280 if m:
258 ast.handleDelTask(statements, fn, lineno, m) 281 task = m.group(1)
282 if task is not None:
283 ast.handleDelTask(statements, fn, lineno, task)
259 return 284 return
260 285
261 m = __addhandler_regexp__.match(s) 286 m = __addhandler_regexp__.match(s)
diff --git a/bitbake/lib/bb/parse/parse_py/ConfHandler.py b/bitbake/lib/bb/parse/parse_py/ConfHandler.py
index 7826dee7d3..9ddbae123d 100644
--- a/bitbake/lib/bb/parse/parse_py/ConfHandler.py
+++ b/bitbake/lib/bb/parse/parse_py/ConfHandler.py
@@ -20,10 +20,10 @@ from bb.parse import ParseError, resolve_file, ast, logger, handle
20__config_regexp__ = re.compile( r""" 20__config_regexp__ = re.compile( r"""
21 ^ 21 ^
22 (?P<exp>export\s+)? 22 (?P<exp>export\s+)?
23 (?P<var>[a-zA-Z0-9\-_+.${}/~:]+?) 23 (?P<var>[a-zA-Z0-9\-_+.${}/~:]*?)
24 (\[(?P<flag>[a-zA-Z0-9\-_+.][a-zA-Z0-9\-_+.@]*)\])? 24 (\[(?P<flag>[a-zA-Z0-9\-_+.][a-zA-Z0-9\-_+.@/]*)\])?
25 25
26 \s* ( 26 (?P<whitespace>\s*) (
27 (?P<colon>:=) | 27 (?P<colon>:=) |
28 (?P<lazyques>\?\?=) | 28 (?P<lazyques>\?\?=) |
29 (?P<ques>\?=) | 29 (?P<ques>\?=) |
@@ -32,7 +32,7 @@ __config_regexp__ = re.compile( r"""
32 (?P<predot>=\.) | 32 (?P<predot>=\.) |
33 (?P<postdot>\.=) | 33 (?P<postdot>\.=) |
34 = 34 =
35 ) \s* 35 ) (?P<whitespace2>\s*)
36 36
37 (?!'[^']*'[^']*'$) 37 (?!'[^']*'[^']*'$)
38 (?!\"[^\"]*\"[^\"]*\"$) 38 (?!\"[^\"]*\"[^\"]*\"$)
@@ -43,10 +43,12 @@ __config_regexp__ = re.compile( r"""
43 """, re.X) 43 """, re.X)
44__include_regexp__ = re.compile( r"include\s+(.+)" ) 44__include_regexp__ = re.compile( r"include\s+(.+)" )
45__require_regexp__ = re.compile( r"require\s+(.+)" ) 45__require_regexp__ = re.compile( r"require\s+(.+)" )
46__includeall_regexp__ = re.compile( r"include_all\s+(.+)" )
46__export_regexp__ = re.compile( r"export\s+([a-zA-Z0-9\-_+.${}/~]+)$" ) 47__export_regexp__ = re.compile( r"export\s+([a-zA-Z0-9\-_+.${}/~]+)$" )
47__unset_regexp__ = re.compile( r"unset\s+([a-zA-Z0-9\-_+.${}/~]+)$" ) 48__unset_regexp__ = re.compile( r"unset\s+([a-zA-Z0-9\-_+.${}/~]+)$" )
48__unset_flag_regexp__ = re.compile( r"unset\s+([a-zA-Z0-9\-_+.${}/~]+)\[([a-zA-Z0-9\-_+.][a-zA-Z0-9\-_+.@]+)\]$" ) 49__unset_flag_regexp__ = re.compile( r"unset\s+([a-zA-Z0-9\-_+.${}/~]+)\[([a-zA-Z0-9\-_+.][a-zA-Z0-9\-_+.@]+)\]$" )
49__addpylib_regexp__ = re.compile(r"addpylib\s+(.+)\s+(.+)" ) 50__addpylib_regexp__ = re.compile(r"addpylib\s+(.+)\s+(.+)" )
51__addfragments_regexp__ = re.compile(r"addfragments\s+(.+)\s+(.+)\s+(.+)\s+(.+)" )
50 52
51def init(data): 53def init(data):
52 return 54 return
@@ -164,6 +166,10 @@ def feeder(lineno, s, fn, statements, baseconfig=False, conffile=True):
164 m = __config_regexp__.match(s) 166 m = __config_regexp__.match(s)
165 if m: 167 if m:
166 groupd = m.groupdict() 168 groupd = m.groupdict()
169 if groupd['var'] == "":
170 raise ParseError("Empty variable name in assignment: '%s'" % s, fn, lineno);
171 if not groupd['whitespace'] or not groupd['whitespace2']:
172 logger.warning("%s:%s has a lack of whitespace around the assignment: '%s'" % (fn, lineno, s))
167 ast.handleData(statements, fn, lineno, groupd) 173 ast.handleData(statements, fn, lineno, groupd)
168 return 174 return
169 175
@@ -177,6 +183,11 @@ def feeder(lineno, s, fn, statements, baseconfig=False, conffile=True):
177 ast.handleInclude(statements, fn, lineno, m, True) 183 ast.handleInclude(statements, fn, lineno, m, True)
178 return 184 return
179 185
186 m = __includeall_regexp__.match(s)
187 if m:
188 ast.handleIncludeAll(statements, fn, lineno, m)
189 return
190
180 m = __export_regexp__.match(s) 191 m = __export_regexp__.match(s)
181 if m: 192 if m:
182 ast.handleExport(statements, fn, lineno, m) 193 ast.handleExport(statements, fn, lineno, m)
@@ -197,6 +208,11 @@ def feeder(lineno, s, fn, statements, baseconfig=False, conffile=True):
197 ast.handlePyLib(statements, fn, lineno, m) 208 ast.handlePyLib(statements, fn, lineno, m)
198 return 209 return
199 210
211 m = __addfragments_regexp__.match(s)
212 if m:
213 ast.handleAddFragments(statements, fn, lineno, m)
214 return
215
200 raise ParseError("unparsed line: '%s'" % s, fn, lineno); 216 raise ParseError("unparsed line: '%s'" % s, fn, lineno);
201 217
202# Add us to the handlers list 218# Add us to the handlers list