diff options
| author | Ulf Magnusson <ulfalizer@gmail.com> | 2018-01-28 10:02:20 +0100 |
|---|---|---|
| committer | Ulf Magnusson <ulfalizer@gmail.com> | 2018-01-28 10:56:57 +0100 |
| commit | 9c309400fca07f15d8f4b116c12fa58f97d8043a (patch) | |
| tree | d7537af3e0da66e7e9335f563b8dcdb69c601388 /kconfiglib.py | |
| parent | 13c563637ebb87e2442adf6b12ab4931adb18268 (diff) | |
Add some post-parsing warnings
These are easiest to check after parsing, since a symbol/choice can be
defined in multiple locations:
- Warn if a symbol or choice defined without a type. Also warn for
choice value symbols defined without a type, even if they
automatically get their type from the choice. This feature isn't
well-known and probably not used deliberately.
- Warn if a choice is defined without a prompt
- Warn of a choice default symbol is not contained in the choice
Also move _name_and_loc_str() from the symbol class to the global scope
and generalize it to be able to handle choices.
Diffstat (limited to 'kconfiglib.py')
| -rw-r--r-- | kconfiglib.py | 72 |
1 files changed, 52 insertions, 20 deletions
diff --git a/kconfiglib.py b/kconfiglib.py index 164cf62..e68e58f 100644 --- a/kconfiglib.py +++ b/kconfiglib.py @@ -701,7 +701,7 @@ class Kconfig(object): self._warn("'{}' is not a valid value for the {} " "symbol {}. Assignment ignored." .format(val, TYPE_TO_STR[sym.orig_type], - sym._name_and_loc_str())) + _name_and_loc_str(sym))) continue # We represent tristate values as 0, 1, 2 @@ -726,7 +726,7 @@ class Kconfig(object): if not string_match: self._warn("Malformed string literal in " "assignment to {}. Assignment ignored." - .format(sym._name_and_loc_str()), + .format(_name_and_loc_str(sym)), filename, linenr) continue @@ -761,7 +761,7 @@ class Kconfig(object): display_user_val = sym.user_value warn_msg = '{} set more than once. Old value: "{}", new value: "{}".'.format( - sym._name_and_loc_str(), display_user_val, display_val + _name_and_loc_str(sym), display_user_val, display_val ) if display_user_val == display_val: @@ -2708,7 +2708,7 @@ class Symbol(object): "Assignment ignored." \ .format(TRI_TO_STR[value] if value in (0, 1, 2) else "'{}'".format(value), - self._name_and_loc_str(), + _name_and_loc_str(self), TYPE_TO_STR[self.orig_type]) if self.orig_type in (BOOL, TRISTATE) and value in ("n", "m", "y"): @@ -2721,7 +2721,7 @@ class Symbol(object): if self.env_var is not None: self.kconfig._warn("ignored attempt to assign user value to " "{}, which gets its value from the environment" - .format(self._name_and_loc_str())) + .format(_name_and_loc_str(self))) return False if self.choice and value == 2: @@ -2976,7 +2976,7 @@ class Symbol(object): return if self.kconfig._warn_no_prompt: - self.kconfig._warn(self._name_and_loc_str() + " has no prompt, " + self.kconfig._warn(_name_and_loc_str(self) + " has no prompt, " "meaning user values have no effect on it") def _warn_select_unsatisfied_deps(self): @@ -2987,7 +2987,7 @@ class Symbol(object): """ warn_msg = "{} has unsatisfied direct dependencies ({}), but is " \ "currently being selected by the following symbols:" \ - .format(self._name_and_loc_str(), + .format(_name_and_loc_str(self), expr_str(self.direct_dep)) # Returns a warning string if 'select' is actually selecting us, and @@ -3009,7 +3009,7 @@ class Symbol(object): msg = "\n{}, with value {}, direct dependencies {} " \ "(value: {})" \ - .format(selecting_sym._name_and_loc_str(), + .format(_name_and_loc_str(selecting_sym), selecting_sym.str_value, expr_str(selecting_sym.direct_dep), TRI_TO_STR[expr_value(selecting_sym.direct_dep)]) @@ -3040,18 +3040,6 @@ class Symbol(object): self.kconfig._warn(warn_msg) - def _name_and_loc_str(self): - """ - Helper for giving the symbol name and location(s) in e.g. warnings - """ - if not self.nodes: - return self.name + " (undefined)" - - return "{} (defined at {})".format( - self.name, - ", ".join("{}:{}".format(node.filename, node.linenr) - for node in self.nodes)) - class Choice(object): """ Represents a choice statement: @@ -3999,6 +3987,22 @@ def _sym_choice_str(sc): return "\n".join(lines) + "\n" +def _name_and_loc_str(sc): + """ + Helper for giving the symbol/choice name and location(s) in e.g. + warnings + """ + name = sc.name or "<choice>" + + if not sc.nodes: + return name + " (undefined)" + + return "{} (defined at {})".format( + name, + ", ".join("{}:{}".format(node.filename, node.linenr) + for node in sc.nodes)) + + # Menu manipulation def _expr_depends_on(expr, sym): @@ -4147,6 +4151,8 @@ def _finalize_tree(node): node.next = cur.next cur.next = None + _check_sanity(node.item) + if node.list: # We have a node with child nodes where the child nodes are now @@ -4158,6 +4164,32 @@ def _finalize_tree(node): # Empty choices (node.list None) are possible, so this needs to go outside if isinstance(node.item, Choice): _finalize_choice(node) + _check_sanity(node.item) + +def _check_sanity(sc): + """ + Prints warnings for bad things that are easiest to check after parsing + + sc: Symbol or Choice + """ + if sc.type == UNKNOWN: + sc.kconfig._warn("{} defined without a type" + .format(_name_and_loc_str(sc))) + + if isinstance(sc, Choice): + for node in sc.nodes: + if node.prompt: + break + else: + sc.kconfig._warn("{} defined without a prompt" + .format(_name_and_loc_str(sc))) + + for sym, _ in sc.defaults: + if sym.choice is not sc: + sc.kconfig._warn("the default selection {} of {} is not " + "contained in the choice" + .format(_name_and_loc_str(sym), + _name_and_loc_str(sc))) # # Public global constants |
