summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
Diffstat (limited to 'examples')
-rwxr-xr-xexamples/oldconfig.py344
1 files changed, 0 insertions, 344 deletions
diff --git a/examples/oldconfig.py b/examples/oldconfig.py
deleted file mode 100755
index 1b58831..0000000
--- a/examples/oldconfig.py
+++ /dev/null
@@ -1,344 +0,0 @@
-#!/usr/bin/env python
-
-# Implements oldconfig-like functionality:
-#
-# 1. Load existing .config
-# 2. Prompt the user for the value of all changeable symbols/choices
-# that aren't already set in the .config
-# 3. Write new .config
-#
-# Unlike 'make oldconfig', this script doesn't print menu titles and
-# comments, but instead gives the Kconfig locations of all symbols and
-# choices. Printing menu titles and comments as well would be pretty easy to
-# add (look at the parents of each item and print all menu prompts and
-# comments unless they have already been printed).
-#
-# Inputting '?' on the prompt will display the help text of the item, if any.
-# Hopefully no one will want to use that as a value.
-#
-# Sample session:
-#
-# OldconfigExample contents:
-#
-# config MODULES
-# def_bool y
-# option modules
-#
-# config BOOL_SYM
-# bool "BOOL_SYM prompt"
-# default y
-#
-# config TRISTATE_SYM
-# tristate "TRISTATE_SYM prompt"
-# default m
-#
-# config STRING_SYM
-# string "STRING_SYM prompt"
-# default "foo"
-#
-# config INT_SYM
-# int "INT_SYM prompt"
-#
-# config HEX_SYM
-# hex "HEX_SYM prompt"
-#
-# choice
-# bool "A choice that defaults to CHOICE_B"
-# default CHOICE_B
-#
-# config CHOICE_A
-# bool "CHOICE_A's prompt"
-#
-# config CHOICE_B
-# bool "CHOICE_B's prompt"
-#
-# config CHOICE_C
-# bool "CHOICE_C's prompt"
-#
-# endchoice
-#
-#
-# Running:
-#
-# $ touch .config # Run with empty .config
-#
-# $ python(3) oldconfig.py Kconfig
-# BOOL_SYM prompt (BOOL_SYM, defined at Kconfig:5) [n/Y] foo
-# Invalid tristate value
-# BOOL_SYM prompt (BOOL_SYM, defined at Kconfig:5) [n/Y] n
-# TRISTATE_SYM prompt (TRISTATE_SYM, defined at Kconfig:9) [n/M/y]
-# STRING_SYM prompt (STRING_SYM, defined at Kconfig:13) [foo] bar
-# INT_SYM prompt (INT_SYM, defined at Kconfig:17) [] 0x123
-# warning: the value '0x123' is invalid for INT_SYM (defined at Kconfig:17), which has type int. Assignment ignored.
-# INT_SYM prompt (INT_SYM, defined at Kconfig:17) [] 123
-# HEX_SYM prompt (HEX_SYM, defined at Kconfig:20) [] 0x123
-# A choice that default to B (defined at Kconfig:23)
-# 1. CHOICE_A's prompt (CHOICE_A)
-# > 2. CHOICE_B's prompt (CHOICE_B)
-# 3. CHOICE_C's prompt (CHOICE_C)
-# choice[1-3]: 5
-# Bad index
-# A choice that default to B (defined at Kconfig:23)
-# 1. CHOICE_A's prompt (CHOICE_A)
-# > 2. CHOICE_B's prompt (CHOICE_B)
-# 3. CHOICE_C's prompt (CHOICE_C)
-# choice[1-3]: 3
-# Configuration written to .config
-#
-# $ cat .config
-# # Generated by Kconfiglib (https://github.com/ulfalizer/Kconfiglib)
-# CONFIG_MODULES=y
-# # CONFIG_BOOL_SYM is not set
-# CONFIG_TRISTATE_SYM=m
-# CONFIG_STRING_SYM="bar"
-# CONFIG_INT_SYM=123
-# CONFIG_HEX_SYM=0x123
-# # CONFIG_CHOICE_A is not set
-# # CONFIG_CHOICE_B is not set
-# CONFIG_CHOICE_C=y
-#
-# $ python oldconfig.py Kconfig # Everything's already up to date
-# Configuration written to .config
-from __future__ import print_function
-from kconfiglib import Kconfig, Symbol, Choice, BOOL, TRISTATE, HEX
-import os
-import sys
-
-# Python 2/3 compatibility hack
-if sys.version_info[0] < 3:
- input = raw_input
-
-def eprint(*args):
- print(*args, file=sys.stderr)
-
-def print_help(node):
- if node.help is not None:
- print("\n" + node.help)
- else:
- print("\nNo help text\n")
-
-def name_and_loc_str(sym):
- """
- Helper for printing the symbol name along with the location(s) in the
- Kconfig files where the symbol is defined
- """
- return "{}, defined at {}".format(
- sym.name,
- ", ".join("{}:{}".format(node.filename, node.linenr)
- for node in sym.nodes))
-
-def default_value_str(sym):
- """
- Returns the "m/M/y" string in e.g.
-
- TRISTATE_SYM prompt (TRISTATE_SYM, defined at Kconfig:9) [n/M/y]:
-
- For string/int/hex, returns the default value as-is.
- """
- if sym.type in (BOOL, TRISTATE):
- return "/".join(("nmy" if sym.tri_value != tri else "NMY")[tri]
- for tri in sym.assignable)
-
- # string/int/hex
- return sym.str_value
-
-def do_oldconfig_for_node(node):
- """
- Prompts the user for a value for the menu node item, where applicable in
- oldconfig mode
- """
- # See do_oldconfig()
- global conf_changed
-
- # Only symbols and choices can be configured
- if not isinstance(node.item, (Symbol, Choice)):
- return
-
- # Skip symbols and choices that aren't visible
- if not node.item.visibility:
- return
-
- # Skip symbols and choices that don't have a prompt (at this location)
- if not node.prompt:
- return
-
- if isinstance(node.item, Symbol):
- sym = node.item
-
- # Skip symbols that already have a user value
- if sym.user_value is not None:
- return
-
- # Skip symbols that can only have a single value, due to selects
- if len(sym.assignable) == 1:
- return
-
- # Skip symbols in choices in y mode. We ask once for the entire choice
- # instead.
- if sym.choice and sym.choice.tri_value == 2:
- return
-
- # Loop until the user enters a valid value or enters a blank string
- # (for the default value)
- while True:
- val = input("{} ({}) [{}] ".format(
- node.prompt[0], name_and_loc_str(sym),
- default_value_str(sym)))
-
- if val == "?":
- print_help(node)
- continue
-
- # Substitute a blank string with the default value the symbol
- # would get
- if not val:
- val = sym.str_value
-
- # Automatically add a "0x" prefix for hex symbols, like the
- # menuconfig interface does. This isn't done when loading .config
- # files, hence why set_value() doesn't do it automatically.
- if sym.type == HEX and not val.startswith(("0x", "0X")):
- val = "0x" + val
-
- old_str_val = sym.str_value
-
- # Kconfiglib itself will print a warning here if the value
- # is invalid, so we don't need to bother
- if sym.set_value(val):
- # Valid value input. We're done with this node.
-
- if sym.str_value != old_str_val:
- conf_changed = True
-
- return
-
- else:
- choice = node.item
-
- # Skip choices that already have a visible user selection...
- if choice.user_selection and choice.user_selection.visibility == 2:
- # ...unless there are new visible symbols in the choice. (We know
- # they have y (2) visibility in that case, because m-visible
- # symbols get demoted to n-visibility in y-mode choices, and the
- # user-selected symbol had visibility y.)
- for sym in choice.syms:
- if sym is not choice.user_selection and sym.visibility and \
- sym.user_value is None:
- # New visible symbols in the choice
- break
- else:
- # No new visible symbols in the choice
- return
-
- # Get a list of available selections. The mode of the choice limits
- # the visibility of the choice value symbols, so this will indirectly
- # skip choices in n and m mode.
- options = [sym for sym in choice.syms if sym.visibility == 2]
-
- if not options:
- # No y-visible choice value symbols
- return
-
- # Loop until the user enters a valid selection or a blank string (for
- # the default selection)
- while True:
- print("{} (defined at {}:{})".format(
- node.prompt[0], node.filename, node.linenr))
-
- for i, sym in enumerate(options, 1):
- print("{} {}. {} ({})".format(
- ">" if sym is choice.selection else " ",
- i,
- # Assume people don't define choice symbols with multiple
- # prompts. That generates a warning anyway.
- sym.nodes[0].prompt[0],
- sym.name))
-
- sel_index = input("choice[1-{}]: ".format(len(options)))
-
- if sel_index == "??":
- print_help(node)
- continue
-
- # Pick the default selection if the string is blank
- if not sel_index:
- choice.selection.set_value(2)
- break
-
- try:
- sel_index = int(sel_index)
- except ValueError:
- eprint("Bad index")
- continue
-
- if not 1 <= sel_index <= len(options):
- eprint("Bad index")
- continue
-
- # Valid selection
-
- if options[sel_index - 1].tri_value != 2:
- conf_changed = True
-
- options[sel_index - 1].set_value(2)
- break
-
- # Give all of the non-selected visible choice symbols the user value n.
- # This makes it so that the choice is no longer considered new once we
- # do additional passes, if the reason that it was considered new was
- # that it had new visible choice symbols.
- #
- # Only giving visible choice symbols the user value n means we will
- # prompt for the choice again if later user selections make more new
- # choice symbols visible, which is correct.
- for sym in choice.syms:
- if sym is not choice.user_selection and sym.visibility:
- sym.set_value(0)
-
-# Entry point when run as an executable, split out so that setuptools'
-# 'entry_points' can be used. It produces a handy oldconfig.exe launcher on
-# Windows.
-def main():
- if len(sys.argv) > 2:
- sys.exit("usage: {} [Kconfig]".format(sys.argv[0]))
-
- kconf = Kconfig("Kconfig" if len(sys.argv) < 2 else sys.argv[1])
-
- config_filename = os.environ.get("KCONFIG_CONFIG")
- if config_filename is None:
- config_filename = ".config"
-
- if not os.path.exists(config_filename):
- sys.exit("{}: '{}' does not exist"
- .format(sys.argv[0], config_filename))
-
- kconf.load_config(config_filename)
- do_oldconfig(kconf)
- kconf.write_config(config_filename)
-
- print("Configuration saved to '{}'".format(config_filename))
-
-def do_oldconfig(kconf):
- # An earlier symbol in the Kconfig files might depend on a later symbol and
- # become visible if its value changes. This flag is set to True if the
- # value of any symbol changes, in which case we rerun the oldconfig to
- # check for new visible symbols.
- global conf_changed
-
- while True:
- conf_changed = False
- do_oldconfig_rec(kconf.top_node)
- if not conf_changed:
- break
-
-def do_oldconfig_rec(node):
- while node:
- do_oldconfig_for_node(node)
-
- if node.list:
- do_oldconfig_rec(node.list)
-
- node = node.next
-
-if __name__ == "__main__":
- main()