diff options
| author | Ulf Magnusson <ulfalizer@gmail.com> | 2018-03-05 20:10:01 +0100 |
|---|---|---|
| committer | Ulf Magnusson <ulfalizer@gmail.com> | 2018-03-11 07:29:19 +0100 |
| commit | 652f11b60f7b738440fe0e919d4de0c188e80395 (patch) | |
| tree | 4f8b8754f0b8abeba60f3973ab765943dbb2cc52 /kconfiglib.py | |
| parent | 0bd841def7f3911771afa2346acae4938033ace9 (diff) | |
Add minimal configuration file generation support
Works like 'make savedefconfig' in the C tools. Call it
write_min_config() rather than write_defconfig() to be a bit more
explicit.
Add a test similar to test_defconfig that compares Kconfiglib minimal
configuration output against the C implementation, for all defconfig
files.
Disable the tests for now. The C tools have a bug that causes an
incorrect configuration to be generated for tristate choices in some
cases. They will be re-enabled once those are fixed.
Diffstat (limited to 'kconfiglib.py')
| -rw-r--r-- | kconfiglib.py | 95 |
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: |
