summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kconfiglib.py40
-rw-r--r--tests/Kpreprocess6
-rw-r--r--testsuite.py17
3 files changed, 40 insertions, 23 deletions
diff --git a/kconfiglib.py b/kconfiglib.py
index 3908985..6c42ca2 100644
--- a/kconfiglib.py
+++ b/kconfiglib.py
@@ -2649,14 +2649,12 @@ class Kconfig(object):
# Returns the expanded 's' (including the part before the macro) and
# the index of the first character after the expanded macro in 's'.
- start = i
+ res = s[:i]
i += 2 # Skip over "$("
- # Start of current macro argument
- arg_start = i
-
- # Arguments of this macro call
- new_args = []
+ arg_start = i # Start of current macro argument
+ new_args = [] # Arguments of this macro call
+ nesting = 0 # Current parentheses nesting level
while 1:
match = _macro_special_search(s, i)
@@ -2664,32 +2662,42 @@ class Kconfig(object):
self._parse_error("missing end parenthesis in macro expansion")
- if match.group() == ")":
+ if match.group() == "(":
+ nesting += 1
+ i = match.end()
+
+ elif match.group() == ")":
+ if nesting:
+ nesting -= 1
+ i = match.end()
+ continue
+
# Found the end of the macro
new_args.append(s[arg_start:match.start()])
- prefix = s[:start]
-
# $(1) is replaced by the first argument to the function, etc.,
# provided at least that many arguments were passed
try:
# Does the macro look like an integer, with a corresponding
# argument? If so, expand it to the value of the argument.
- prefix += args[int(new_args[0])]
+ res += args[int(new_args[0])]
except (ValueError, IndexError):
# Regular variables are just functions without arguments,
# and also go through the function value path
- prefix += self._fn_val(new_args)
+ res += self._fn_val(new_args)
- return (prefix + s[match.end():],
- len(prefix))
+ return (res + s[match.end():], len(res))
elif match.group() == ",":
+ i = match.end()
+ if nesting:
+ continue
+
# Found the end of a macro argument
new_args.append(s[arg_start:match.start()])
- arg_start = i = match.end()
+ arg_start = i
else: # match.group() == "$("
# A nested macro call within the macro
@@ -7015,8 +7023,8 @@ _assignment_lhs_fragment_match = _re_match("[A-Za-z0-9_-]*")
# variable assignment
_assignment_rhs_match = _re_match(r"\s*(=|:=|\+=)\s*(.*)")
-# Special characters/strings while expanding a macro (')', ',', and '$(')
-_macro_special_search = _re_search(r"\)|,|\$\(")
+# Special characters/strings while expanding a macro ('(', ')', ',', and '$(')
+_macro_special_search = _re_search(r"\(|\)|,|\$\(")
# Special characters/strings while expanding a string (quotes, '\', and '$(')
_string_special_search = _re_search(r'"|\'|\\|\$\(')
diff --git a/tests/Kpreprocess b/tests/Kpreprocess
index e30b389..f9aca10 100644
--- a/tests/Kpreprocess
+++ b/tests/Kpreprocess
@@ -51,7 +51,7 @@ surround-rev-quote = $(0) $(rev-quote,$(1),$(2)) $(0)
surround-rev-quote-unused-arg = $(surround-rev-quote,$(1),$(2)) $(3)
# No value is passed for $(3), so it expands to nothing
fn-indir = surround-rev-quote
-messy-fn-res = $($(fn-indir)-unused-arg, a b , c d )
+messy-fn-res = $($(fn-indir)-unused-arg, a b (,) , c d )
# Special characters in function call
comma = ,
@@ -121,6 +121,10 @@ shell-res = $(shell,false && echo foo bar || echo baz qaz)
# Warns about output on stderr, expands to nothing
shell-stderr-res := $(shell,echo message on stderr >&2)
+# Nested parens in macro call. Should give a single argument. Test it with
+# $(shell) to get a free argument number check.
+parens-res = pre-$(shell,echo '(a,b,(c,d),e)')-post
+
# Expands to the current location
location-res := $(filename):$(lineno)
diff --git a/testsuite.py b/testsuite.py
index 93e85d6..a29f815 100644
--- a/testsuite.py
+++ b/testsuite.py
@@ -2478,8 +2478,8 @@ config J
verify_variable("immediate", "foofoo", "foofoo", False)
verify_variable("messy-fn-res",
- "$($(fn-indir)-unused-arg, a b , c d )",
- 'surround-rev-quote " c d " " a b " surround-rev-quote ',
+ "$($(fn-indir)-unused-arg, a b (,) , c d )",
+ 'surround-rev-quote " c d " " a b (,) " surround-rev-quote ',
True)
verify_variable("special-chars-fn-res",
@@ -2516,7 +2516,7 @@ config PRINT_ME_TOO
verify_repr(
"messy-fn-res",
- "<variable messy-fn-res, recursive, value '$($(fn-indir)-unused-arg, a b , c d )'>")
+ "<variable messy-fn-res, recursive, value '$($(fn-indir)-unused-arg, a b (,) , c d )'>")
def verify_recursive(name):
try:
@@ -2546,9 +2546,14 @@ config PRINT_ME_TOO
verify_variable("shell-stderr-res", "", "", False)
+ verify_variable("parens-res",
+ "pre-$(shell,echo '(a,b,(c,d),e)')-post",
+ "pre-(a,b,(c,d),e)-post",
+ True)
+
verify_variable("location-res",
- "Kconfiglib/tests/Kpreprocess:125",
- "Kconfiglib/tests/Kpreprocess:125",
+ "Kconfiglib/tests/Kpreprocess:129",
+ "Kconfiglib/tests/Kpreprocess:129",
False)
verify_variable("warning-res", "", "", False)
@@ -2568,7 +2573,7 @@ config PRINT_ME_TOO
# Check that the expected warnings were generated
verify_equal(c.warnings, [
"Kconfiglib/tests/Kpreprocess:122: warning: 'echo message on stderr >&2' wrote to stderr: message on stderr",
- "Kconfiglib/tests/Kpreprocess:130: warning: a warning"
+ "Kconfiglib/tests/Kpreprocess:134: warning: a warning"
])