diff options
| -rw-r--r-- | kconfiglib.py | 58 | ||||
| -rwxr-xr-x | menuconfig.py | 35 |
2 files changed, 66 insertions, 27 deletions
diff --git a/kconfiglib.py b/kconfiglib.py index 30b7507..f61b793 100644 --- a/kconfiglib.py +++ b/kconfiglib.py @@ -700,6 +700,14 @@ class Kconfig(object): enabled will get added to Kconfig.warnings. See the various Kconfig.enable/disable_*_warnings() functions. + missing_syms: + A list with (name, value) tuples for all assignments to undefined symbols + within the most recently loaded .config file(s). 'name' is the symbol + name without the 'CONFIG_' prefix. 'value' is a string that gives the + right-hand side of the assignment verbatim. + + See Kconfig.load_config() as well. + srctree: The value of the $srctree environment variable when the configuration was loaded, or the empty string if $srctree wasn't set. This gives nice @@ -747,6 +755,7 @@ class Kconfig(object): "m", "mainmenu_text", "menus", + "missing_syms", "modules", "n", "named_choices", @@ -863,6 +872,8 @@ class Kconfig(object): self.const_syms = {} self.defined_syms = [] + self.missing_syms = [] + self.named_choices = {} self.choices = [] @@ -1032,10 +1043,15 @@ class Kconfig(object): "# CONFIG_FOO is not set" within a .config file sets the user value of FOO to n. The C tools work the same way. - The Symbol.user_value attribute can be inspected afterwards to see what - value the symbol was assigned in the .config file (if any). The user - value might differ from Symbol.str/tri_value if there are unsatisfied - dependencies. + For each symbol, the Symbol.user_value attribute holds the value the + symbol was assigned in the .config file (if any). The user value might + differ from Symbol.str/tri_value if there are unsatisfied dependencies. + + Calling this function also updates the Kconfig.missing_syms attribute + with a list of all assignments to undefined symbols within the + configuration file. Kconfig.missing_syms is cleared if 'replace' is + True, and appended to otherwise. See the documentation for + Kconfig.missing_syms as well. Raises (possibly a subclass of) IOError on IO errors ('errno', 'strerror', and 'filename' are available). Note that IOError can be @@ -1115,6 +1131,8 @@ class Kconfig(object): def _load_config(self, filename, replace): with self._open_config(filename) as f: if replace: + self.missing_syms = [] + # If we're replacing the configuration, keep track of which # symbols and choices got set so that we can unset the rest # later. This avoids invalidating everything and is faster. @@ -1140,14 +1158,12 @@ class Kconfig(object): if match: name, val = match.groups() if name not in syms: - self._warn_undef_assign_load(name, val, filename, - linenr) + self._undef_assign(name, val, filename, linenr) continue sym = syms[name] if not sym.nodes: - self._warn_undef_assign_load(name, val, filename, - linenr) + self._undef_assign(name, val, filename, linenr) continue if sym.orig_type in _BOOL_TRISTATE: @@ -1209,8 +1225,7 @@ class Kconfig(object): name = match.group(1) if name not in syms: - self._warn_undef_assign_load(name, "n", filename, - linenr) + self._undef_assign(name, "n", filename, linenr) continue sym = syms[name] @@ -1251,6 +1266,16 @@ class Kconfig(object): if not choice._was_set: choice.unset_value() + def _undef_assign(self, name, val, filename, linenr): + # Called for assignments to undefined symbols during .config loading + + self.missing_syms.append((name, val)) + + if self._warn_for_undef_assign: + self._warn( + "attempt to assign the value '{}' to the undefined symbol {}" + .format(val, name), filename, linenr) + def write_autoconf(self, filename, header="/* Generated by Kconfiglib (https://github.com/ulfalizer/Kconfiglib) */\n"): r""" @@ -3617,19 +3642,6 @@ class Kconfig(object): if self._warn_to_stderr: sys.stderr.write(msg + "\n") - def _warn_undef_assign(self, msg, filename, linenr): - # See the class documentation - - if self._warn_for_undef_assign: - self._warn(msg, filename, linenr) - - def _warn_undef_assign_load(self, name, val, filename, linenr): - # Special version for load_config() - - self._warn_undef_assign( - 'attempt to assign the value "{}" to the undefined symbol {}' - .format(val, name), filename, linenr) - def _warn_override(self, msg, filename, linenr): # See the class documentation diff --git a/menuconfig.py b/menuconfig.py index 4f3bef8..53221dc 100755 --- a/menuconfig.py +++ b/menuconfig.py @@ -192,7 +192,7 @@ import sys import textwrap from kconfiglib import Symbol, Choice, MENU, COMMENT, MenuNode, \ - BOOL, STRING, INT, HEX, UNKNOWN, \ + BOOL, TRISTATE, STRING, INT, HEX, UNKNOWN, \ AND, OR, \ expr_str, expr_value, split_expr, \ standard_sc_expr_str, \ @@ -631,8 +631,8 @@ def menuconfig(kconf): _kconf = kconf - # Always prompt for save if the configuration file doesn't exist - _conf_changed = not kconf.load_config() + # Load existing configuration and set _conf_changed True if it is outdated + _conf_changed = _load_config() # Any visible items in the top menu? _show_all = False @@ -678,6 +678,33 @@ def menuconfig(kconf): # curses has been de-initialized. print(curses.wrapper(_menuconfig)) +def _load_config(): + # Loads any existing .config file. See the Kconfig.load_config() docstring. + # + # Returns True if .config is missing or outdated. We always prompt for + # saving the configuration in that case. + + if not _kconf.load_config() or _kconf.missing_syms: + # Either no .config, or assignments to undefined symbols in the + # existing .config (which would get removed when saving) + return True + + for sym in _kconf.unique_defined_syms: + if sym.user_value is None: + if sym.config_string: + # Unwritten symbol + return True + elif sym.type in (BOOL, TRISTATE): + if sym.tri_value != sym.user_value: + # Written bool/tristate symbol, new value + return True + elif sym.str_value != sym.user_value: + # Written string/int/hex symbol, new value + return True + + # No need to prompt for save + return False + # Global variables used below: # # _stdscr: @@ -811,7 +838,7 @@ def _menuconfig(stdscr): continue if _load_dialog(): - _conf_changed = False + _conf_changed = True elif c in ("s", "S"): if _save_dialog(_kconf.write_config, standard_config_filename(), |
