diff options
| author | Ulf Magnusson <ulfalizer@gmail.com> | 2018-12-23 20:40:48 +0100 |
|---|---|---|
| committer | Ulf Magnusson <ulfalizer@gmail.com> | 2018-12-24 19:47:35 +0100 |
| commit | 3a3559fd094567bac218e9478f1b7e48656d6f85 (patch) | |
| tree | 690dcdc763bff1a84f4d2ef1fd6477c0d2cf25f5 | |
| parent | e629c33d31e223ca1284aa77efce4628bbf50e21 (diff) | |
menuconfig: Prompt for save if a different .config would be saved
Previously, menuconfig.py only prompted for saving the configuration if
.config didn't exist or the user changed symbol values within the
interface.
Also make it prompt for save if Kconfig symbols have been added,
removed, or have had their defaults changed, provided it would make the
saved .config differ from the loaded one.
This usually won't matter for correctness, because loading an outdated
configuration performs an implicit olddefconfig, but it's less
confusing.
Also add a Kconfig.missing_syms attribute that records all assignments
to undefined symbols in the most recently loaded .config file. This is
needed to implement the check for whether the saved .config would be
different.
As an unrelated change, always prompt for saving if a .config has been
loaded from within the menuconfig interface. The intention is probably
often to save the configuration somewhere else, even if it isn't
modified.
| -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(), |
