]> code.ossystems Code Review - openembedded-core.git/commitdiff
Implement ??= operator
authorChris Larson <chris_larson@mentor.com>
Thu, 25 Feb 2010 16:42:28 +0000 (09:42 -0700)
committerRichard Purdie <rpurdie@linux.intel.com>
Mon, 22 Mar 2010 15:02:59 +0000 (15:02 +0000)
??= is a lazy, conditional assignment.  Whereas a ?= immediately assigns to
the variable if the variable has not yet been set, ??= does not apply the
default assignment until the end of the parse.  As a result, the final ??= for
a given variable is used, as opposed to the first as in ?=.

Note that the initial implementation relies upon finalise() to apply the
defaults, so a "bitbake -e" without specifying a recipe will not show the
defaults as set by ??=.  Moving application of the default into getVar adds
too large a performance hit.  We may want to revisit this later.

(Bitbake rev: 74f50fbca194c9c72bd2a540f4b9de458cb08e2d)

Signed-off-by: Chris Larson <chris_larson@mentor.com>
Signed-off-by: Richard Purdie <rpurdie@linux.intel.com>
bitbake/doc/manual/usermanual.xml
bitbake/lib/bb/parse/ast.py
bitbake/lib/bb/parse/parse_py/ConfHandler.py

index c3403449fe10797060e820b3ecabd914a0f3bd80..450ac77d7abe30a1e8b5b60b7146157d59bbb1e6 100644 (file)
@@ -91,7 +91,13 @@ share common metadata between many packages.</para></listitem>
             <section>
                 <title>Setting a default value (?=)</title>
                 <para><screen><varname>A</varname> ?= "aval"</screen></para>
-                <para>If <varname>A</varname> is set before the above is called, it will retain it's previous value. If <varname>A</varname> is unset prior to the above call, <varname>A</varname> will be set to <literal>aval</literal>.</para>
+                <para>If <varname>A</varname> is set before the above is called, it will retain it's previous value. If <varname>A</varname> is unset prior to the above call, <varname>A</varname> will be set to <literal>aval</literal>.  Note that this assignment is immediate, so if there are multiple ?= assignments to a single variable, the first of those will be used.</para>
+            </section>
+            <section>
+                <title>Setting a default value (??=)</title>
+                <para><screen><varname>A</varname> ??= "somevalue"</screen></para>
+                <para><screen><varname>A</varname> ??= "someothervalue"</screen></para>
+                <para>If <varname>A</varname> is set before the above, it will retain that value.  If <varname>A</varname> is unset prior to the above, <varname>A</varname> will be set to <literal>someothervalue</literal>.  This is a lazy version of ??=, in that the assignment does not occur until the end of the parsing process, so that the last, rather than the first, ??= assignment to a given variable will be used.</para>
             </section>
             <section>
                 <title>Immediate variable expansion (:=)</title>
index e0b795fa68363b207719af17ee9db4ae50b53850..70a69b8d1405cd1bfa003a4c5f3bdd8346dc0278 100644 (file)
@@ -99,9 +99,15 @@ class DataNode(AstNode):
             val = "%s%s" % (groupd["value"], (self.getFunc(key, data) or ""))
         else:
             val = groupd["value"]
+
         if 'flag' in groupd and groupd['flag'] != None:
             bb.msg.debug(3, bb.msg.domain.Parsing, "setVarFlag(%s, %s, %s, data)" % (key, groupd['flag'], val))
             bb.data.setVarFlag(key, groupd['flag'], val, data)
+        elif groupd["lazyques"]:
+            assigned = bb.data.getVar("__lazy_assigned", data) or []
+            assigned.append(key)
+            bb.data.setVar("__lazy_assigned", assigned, data)
+            bb.data.setVarFlag(key, "defaultval", val, data)
         else:
             bb.data.setVar(key, val, data)
 
@@ -286,6 +292,11 @@ def handleInherit(statements, m):
     statements.append(InheritNode(m.group(1)))
 
 def finalise(fn, d):
+    for lazykey in bb.data.getVar("__lazy_assigned", d) or ():
+        if bb.data.getVar(lazykey, d) is None:
+            val = bb.data.getVarFlag(lazykey, "defaultval", d)
+            bb.data.setVar(lazykey, val, d)
+
     bb.data.expandKeys(d)
     bb.data.update_data(d)
     anonqueue = bb.data.getVar("__anonqueue", d, 1) or []
index a1eaf317ac1fc0237bfd75250b340d3eec825ef7..f4f85de245efe2e6f3d34aba9b9194c069d87b7d 100644 (file)
@@ -28,7 +28,7 @@ import re, bb.data, os, sys
 from bb.parse import ParseError, resolve_file, ast
 
 #__config_regexp__  = re.compile( r"(?P<exp>export\s*)?(?P<var>[a-zA-Z0-9\-_+.${}]+)\s*(?P<colon>:)?(?P<ques>\?)?=\s*(?P<apo>['\"]?)(?P<value>.*)(?P=apo)$")
-__config_regexp__  = re.compile( r"(?P<exp>export\s*)?(?P<var>[a-zA-Z0-9\-_+.${}/]+)(\[(?P<flag>[a-zA-Z0-9\-_+.]+)\])?\s*((?P<colon>:=)|(?P<ques>\?=)|(?P<append>\+=)|(?P<prepend>=\+)|(?P<predot>=\.)|(?P<postdot>\.=)|=)\s*(?P<apo>['\"]?)(?P<value>.*)(?P=apo)$")
+__config_regexp__  = re.compile( r"(?P<exp>export\s*)?(?P<var>[a-zA-Z0-9\-_+.${}/]+)(\[(?P<flag>[a-zA-Z0-9\-_+.]+)\])?\s*((?P<colon>:=)|(?P<lazyques>\?\?=)|(?P<ques>\?=)|(?P<append>\+=)|(?P<prepend>=\+)|(?P<predot>=\.)|(?P<postdot>\.=)|=)\s*(?P<apo>['\"]?)(?P<value>.*)(?P=apo)$")
 __include_regexp__ = re.compile( r"include\s+(.+)" )
 __require_regexp__ = re.compile( r"require\s+(.+)" )
 __export_regexp__ = re.compile( r"export\s+(.+)" )