Skip to content

Commit

Permalink
kconfiglib: Fix preprocessor issue for nested parentheses
Browse files Browse the repository at this point in the history
Prompted by an upstream bug report. Nothing in Zephyr triggers this at
the moment, but might as well fix it.

Update Kconfiglib to upstream revision 7d05084b7e, to get this commit
in:

    Fix handling of parentheses in macro argument values

    As an oversight, there was no check for nested parentheses in macro
    arguments, making the preprocessor think the call ended after
    'void)' in

        def_bool $(success,echo 'void foo(void) { asm inline (""); }' \
                   | $(CC) -x c - -c -o /dev/null)

    This broke the latest linux-next kernels (with a Kconfig error),
    starting with commit eb111869301e1 ("compiler-types.h: add
    asm_inline definition").

    I remember seeing this when going through the C code, but somehow
    forgot to put it in. Fix it, and clean up _expand_macro() a bit at
    the same time.

Signed-off-by: Ulf Magnusson <[email protected]>
  • Loading branch information
ulfalizer authored and carlescufi committed Sep 27, 2019
1 parent 45dba1e commit a7c4307
Showing 1 changed file with 27 additions and 20 deletions.
47 changes: 27 additions & 20 deletions scripts/kconfig/kconfiglib.py
Original file line number Diff line number Diff line change
Expand Up @@ -554,7 +554,7 @@ def my_other_fn(kconf, name, arg_1, arg_2, ...):
from os.path import dirname, exists, expandvars, islink, join, realpath


VERSION = (12, 14, 0)
VERSION = (12, 14, 1)


# File layout:
Expand Down Expand Up @@ -2603,10 +2603,9 @@ def _expand_name_iter(self, s, i):
while 1:
match = _name_special_search(s, i)

if match.group() == "$(":
s, i = self._expand_macro(s, match.start(), ())
else:
if match.group() != "$(":
return (s, match.start())
s, i = self._expand_macro(s, match.start(), ())

def _expand_str(self, s, i):
# Expands a quoted string starting at index 'i' in 's'. Handles both
Expand Down Expand Up @@ -2649,47 +2648,55 @@ def _expand_macro(self, s, i, args):
# 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)
if not match:
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
Expand Down Expand Up @@ -7015,8 +7022,8 @@ def _re_search(regex):
# 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'"|\'|\\|\$\(')
Expand Down

0 comments on commit a7c4307

Please sign in to comment.