summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kconfiglib.py58
-rwxr-xr-xmenuconfig.py35
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(),