summaryrefslogtreecommitdiff
path: root/examples/allyesconfig.py
diff options
context:
space:
mode:
Diffstat (limited to 'examples/allyesconfig.py')
-rw-r--r--examples/allyesconfig.py117
1 files changed, 71 insertions, 46 deletions
diff --git a/examples/allyesconfig.py b/examples/allyesconfig.py
index 906343c..1bac713 100644
--- a/examples/allyesconfig.py
+++ b/examples/allyesconfig.py
@@ -1,65 +1,90 @@
-# Works like allyesconfig. This is a bit more involved than allnoconfig as we
-# need to handle choices in two different modes:
+# Works like 'make allyesconfig'. Verified by the test suite to generate output
+# identical to 'make allyesconfig', for all ARCHES.
#
-# "y": One symbol is "y", the rest are "n".
-# "m": Any number of symbols are "m", the rest are "n".
+# This example is implemented a bit differently from allnoconfig.py to
+# demonstrate some other possibilities. A variant similar to
+# allnoconfig_simpler.py could be constructed too.
#
-# Only tristate choices can be in "m" mode. It is safe since the code for two
-# conflicting options will appear as separate modules instead of simultaneously
-# in the kernel.
+# In theory, we need to handle choices in two different modes:
#
-# If a choice can be in "y" mode, it will be. If it can only be in "m" mode
-# (due to dependencies), then all the options will be set to "m".
+# y: One symbol is y, the rest are n
+# m: Any number of symbols are m, the rest are n
#
-# The looping is in case setting one symbol to "y" (or "m") allows the value of
-# other symbols to be raised.
+# Only tristate choices can be in m mode.
+#
+# In practice, no m mode choices appear for allyesconfig as of 4.14, as
+# expected, but we still handle them here for completeness. Here's a convoluted
+# example of how you might get an m-mode choice even during allyesconfig:
+#
+# choice
+# tristate "weird choice"
+# depends on m
+#
+# ...
+#
+# endchoice
+#
+#
+# Usage:
+#
+# $ make [ARCH=<arch>] scriptconfig SCRIPT=Kconfiglib/examples/allyesconfig.py
-import kconfiglib
+from kconfiglib import Kconfig, Choice, STR_TO_TRI
import sys
-conf = kconfiglib.Config(sys.argv[1])
+def all_choices(node):
+ """
+ Returns all choices in the menu tree rooted at 'node'. See the
+ Kconfig.write_config() implementation in kconfiglib.py for an example of
+ how the tree can be walked iteratively instead.
-# Get a list of all symbols that are not in choices
-non_choice_syms = [sym for sym in conf.get_symbols() if
- not sym.is_choice_symbol()]
+ (I was thinking of making a list of choices available directly in the API,
+ but I'm not sure it will always be needed internally, and I'm trying to
+ spam the API with less seldomly-used stuff compared to Kconfiglib 1.)
+ """
+ res = []
-done = False
-while not done:
- done = True
+ while node:
+ if isinstance(node.item, Choice):
+ res.append(node.item)
- # Handle symbols outside of choices
+ if node.list:
+ res.extend(all_choices(node.list))
- for sym in non_choice_syms:
- upper_bound = sym.get_upper_bound()
+ node = node.next
- # See corresponding comment for allnoconfig implementation
- if upper_bound is not None and \
- kconfiglib.tri_less(sym.get_value(), upper_bound):
- sym.set_user_value(upper_bound)
- done = False
+ return res
- # Handle symbols within choices
+kconf = Kconfig(sys.argv[1])
- for choice in conf.get_choices():
+non_choice_syms = [sym for sym in kconf.defined_syms if not sym.choice]
+choices = all_choices(kconf.top_node) # All choices in the configuration
- # Handle choices whose visibility allow them to be in "y" mode
+while True:
+ changed = False
+
+ for sym in non_choice_syms:
+ # Set the symbol to the highest assignable value, unless it already has
+ # that value. sym.assignable[-1] gives the last element in assignable.
+ if sym.assignable and sym.tri_value < sym.assignable[-1]:
+ sym.set_value(sym.assignable[-1])
+ changed = True
- if choice.get_visibility() == "y":
- selection = choice.get_selection_from_defaults()
- if selection is not None and \
- selection is not choice.get_user_selection():
- selection.set_user_value("y")
- done = False
+ for choice in choices:
+ # Same logic as above for choices
+ if choice.assignable and choice.tri_value < choice.assignable[-1]:
+ choice.set_value(choice.assignable[-1])
+ changed = True
- # Handle choices whose visibility only allow them to be in "m" mode.
- # This might happen if a choice depends on a symbol that can only be
- # "m" for example.
+ # For y-mode choices, we just let the choice get its default
+ # selection. For m-mode choices, we set all choice symbols to m.
+ if choice.tri_value == 1:
+ for sym in choice.syms:
+ sym.set_value(1)
- elif choice.get_visibility() == "m":
- for sym in choice.get_symbols():
- if sym.get_value() != "m" and \
- sym.get_upper_bound() != "n":
- sym.set_user_value("m")
- done = False
+ # Do multiple passes until we longer manage to raise any symbols or
+ # choices, like in allnoconfig.py
+ if not changed:
+ break
-conf.write_config(".config")
+kconf.write_config(".config")