summaryrefslogtreecommitdiff
path: root/kconfiglib.py
diff options
context:
space:
mode:
Diffstat (limited to 'kconfiglib.py')
-rw-r--r--kconfiglib.py95
1 files changed, 95 insertions, 0 deletions
diff --git a/kconfiglib.py b/kconfiglib.py
index 1a07da3..85a0054 100644
--- a/kconfiglib.py
+++ b/kconfiglib.py
@@ -961,6 +961,62 @@ class Kconfig(object):
else:
return
+ def write_min_config(self, filename,
+ header="# Generated by Kconfiglib (https://github.com/ulfalizer/Kconfiglib)\n"):
+ """
+ Writes out a "minimal" configuration file, omitting symbols whose value
+ matches their default value. The format matches the one produced by
+ 'make savedefconfig'.
+
+ The resulting configuration file is incomplete, but a complete
+ configuration can be derived from it by loading it. Minimal
+ configuration files can serve as a more manageable configuration format
+ compared to a "full" .config file, especially when configurations files
+ are merged or edited by hand.
+
+ filename:
+ Self-explanatory.
+
+ header (default: "# Generated by Kconfiglib (https://github.com/ulfalizer/Kconfiglib)\n"):
+ Text that will be inserted verbatim at the beginning of the file. You
+ would usually want each line to start with '#' to make it a comment,
+ and include a final terminating newline.
+ """
+ with open(filename, "w") as f:
+ f.write(header)
+
+ # Avoid duplicates -- see write_config()
+ for sym in self.defined_syms:
+ sym._written = False
+
+ for sym in self.defined_syms:
+ if not sym._written:
+ sym._written = True
+
+ # Skip symbols that cannot be changed. Only check
+ # non-choice symbols, as selects don't affect choice
+ # symbols.
+ if not sym.choice and \
+ sym.visibility <= expr_value(sym.rev_dep):
+ continue
+
+ # Skip symbols whose value matches their default
+ if sym.str_value == sym._str_default():
+ continue
+
+ # Skip symbols that would be selected by default in a
+ # choice, unless the choice is optional or the symbol type
+ # isn't bool (it might be possible to set the choice mode
+ # to n or the symbol to m in those cases).
+ if sym.choice and \
+ not sym.choice.is_optional and \
+ sym.choice._get_selection_from_defaults() is sym and \
+ sym.orig_type == BOOL and \
+ sym.tri_value == 2:
+ continue
+
+ f.write(sym.config_string)
+
def sync_deps(self, path):
"""
Creates or updates a directory structure that can be used to avoid
@@ -3233,6 +3289,41 @@ class Symbol(object):
self.kconfig._warn(_name_and_loc_str(self) + " has no prompt, "
"meaning user values have no effect on it")
+ def _str_default(self):
+ # write_min_config() helper function. Returns the value the symbol
+ # would get from defaults if it didn't have a user value. Uses exactly
+ # the same algorithm as the C implementation (though a bit cleaned up),
+ # for compatibility.
+
+ if self.orig_type in (BOOL, TRISTATE):
+ val = 0
+
+ # Defaults, selects, and implies do not affect choice symbols
+ if not self.choice:
+ for default, cond in self.defaults:
+ cond_val = expr_value(cond)
+ if cond_val:
+ val = min(expr_value(default), cond_val)
+ break
+
+ val = max(expr_value(self.rev_dep),
+ expr_value(self.weak_rev_dep),
+ val)
+
+ # Transpose mod to yes if type is bool (possibly due to modules
+ # being disabled)
+ if val == 1 and self.type == BOOL:
+ val = 2
+
+ return TRI_TO_STR[val]
+
+ if self.orig_type in (STRING, INT, HEX):
+ for default, cond in self.defaults:
+ if expr_value(cond):
+ return default.str_value
+
+ return ""
+
def _warn_select_unsatisfied_deps(self):
# Helper for printing an informative warning when a symbol with
# unsatisfied direct dependencies (dependencies from 'depends on', ifs,
@@ -3684,6 +3775,10 @@ class Choice(object):
return self.user_selection
# Otherwise, check if we have a default
+ return self._get_selection_from_defaults()
+
+ def _get_selection_from_defaults(self):
+ # Check if we have a default
for sym, cond in self.defaults:
# The default symbol must be visible too
if expr_value(cond) and sym.visibility: