diff options
| author | Ulf Magnusson <ulfalizer@gmail.com> | 2018-08-23 00:22:10 +0200 |
|---|---|---|
| committer | Ulf Magnusson <ulfalizer@gmail.com> | 2018-08-23 00:51:52 +0200 |
| commit | 4ebc2aa72f41a9c5739ee8a8ad89bdfa0a489a2d (patch) | |
| tree | fa166e004d86c058b91a653d6478a9a812d9fcee | |
| parent | 7dae98803a6fc5d08041d1387e2e0d83fc0eb0ed (diff) | |
Flag extra tokens after 'if'/'depends on'/'visible if' expressions
Extra trailing tokens after 'if <expr>', 'depends on <expr>', and
'visible if <expr>' now trigger syntax errors instead of being ignored.
Oversight.
This indirectly makes Kconfig.eval_expr() detect extra trailing tokens
as well.
| -rw-r--r-- | kconfiglib.py | 33 | ||||
| -rw-r--r-- | testsuite.py | 7 |
2 files changed, 27 insertions, 13 deletions
diff --git a/kconfiglib.py b/kconfiglib.py index 8abec53..76853ea 100644 --- a/kconfiglib.py +++ b/kconfiglib.py @@ -1394,11 +1394,11 @@ class Kconfig(object): # Don't include the "if " from below to avoid giving confusing error # messages self._line = s - # Remove the _T_IF token + # [1:] removes the _T_IF token self._tokens = self._tokenize("if " + s)[1:] self._tokens_i = -1 - return expr_value(self._parse_expr(True)) # transform_m + return expr_value(self._expect_expr_and_eol()) # transform_m def unset_values(self): """ @@ -1849,9 +1849,9 @@ class Kconfig(object): def _peek_token(self): return self._tokens[self._tokens_i + 1] - # The functions below are just _next_token() with extra syntax checking. - # Inlining _next_token() and _peek_token() into them saves a few % of - # parsing time. + # The functions below are just _next_token() and _parse_expr() with extra + # syntax checking. Inlining _next_token() and _peek_token() into them saves + # a few % of parsing time. # # See the 'Intro to expressions' section for what a constant symbol is. @@ -1906,6 +1906,14 @@ class Kconfig(object): return token + def _expect_expr_and_eol(self): + expr = self._parse_expr(True) + + if self._peek_token() is not None: + self._parse_error("extra tokens at end of line") + + return expr + def _check_token(self, token): # If the next token is 'token', removes it and returns True @@ -2276,7 +2284,7 @@ class Kconfig(object): node.filename = self._filename node.linenr = self._linenr - node.dep = self._parse_expr(True) + node.dep = self._expect_expr_and_eol() self._parse_block(_T_ENDIF, node, node) node.list = node.next @@ -2376,10 +2384,8 @@ class Kconfig(object): # Parses an optional 'if <expr>' construct and returns the parsed # <expr>, or self.y if the next token is not _T_IF - expr = self._parse_expr(True) if self._check_token(_T_IF) else self.y - if self._peek_token() is not None: - self._parse_error("extra tokens at end of line") - return expr + return self._expect_expr_and_eol() if self._check_token(_T_IF) \ + else self.y def _parse_properties(self, node): # Parses and adds properties to the MenuNode 'node' (type, 'prompt', @@ -2415,7 +2421,8 @@ class Kconfig(object): if not self._check_token(_T_ON): self._parse_error('expected "on" after "depends"') - node.dep = self._make_and(node.dep, self._parse_expr(True)) + node.dep = self._make_and(node.dep, + self._expect_expr_and_eol()) elif t0 == _T_HELP: self._parse_help(node) @@ -2521,8 +2528,8 @@ class Kconfig(object): if not self._check_token(_T_IF): self._parse_error('expected "if" after "visible"') - node.visibility = \ - self._make_and(node.visibility, self._parse_expr(True)) + node.visibility = self._make_and(node.visibility, + self._expect_expr_and_eol()) elif t0 == _T_OPTIONAL: if not isinstance(node.item, Choice): diff --git a/testsuite.py b/testsuite.py index 1e3d89a..5c90f33 100644 --- a/testsuite.py +++ b/testsuite.py @@ -473,8 +473,15 @@ def run_selftests(): verify_eval_bad(")") verify_eval_bad("=") verify_eval_bad("(X") + verify_eval_bad("X)") + verify_eval_bad("X X") + verify_eval_bad("!X X") + verify_eval_bad("X !X") + verify_eval_bad("(X) X") verify_eval_bad("X &&") verify_eval_bad("&& X") + verify_eval_bad("X && && X") + verify_eval_bad("X && !&&") verify_eval_bad("X ||") verify_eval_bad("|| X") |
