summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlf Magnusson <ulfalizer@gmail.com>2012-12-06 17:01:09 +0100
committerUlf Magnusson <ulfalizer@gmail.com>2012-12-06 17:01:29 +0100
commitc805e3143bada2df897927996ae23a469cf83eb3 (patch)
tree38212ced8df505ee2814ac5b8d29460f0fa5e98b
parent94fb111d02b95413f7c36d923dabd4ec1ca1c90e (diff)
Move examples into separate directory.
-rw-r--r--examples/allnoconfig.py36
-rw-r--r--examples/allyesconfig.py66
-rw-r--r--examples/defconfig.py17
-rw-r--r--examples/eval_expr.py8
-rw-r--r--examples/print_refs.py13
-rw-r--r--examples/print_sym_info.py18
-rw-r--r--examples/print_tree.py23
-rw-r--r--examples/print_undefined.py15
-rw-r--r--kconfiglib.py377
9 files changed, 221 insertions, 352 deletions
diff --git a/examples/allnoconfig.py b/examples/allnoconfig.py
new file mode 100644
index 0000000..2fe151d
--- /dev/null
+++ b/examples/allnoconfig.py
@@ -0,0 +1,36 @@
+# Works like allnoconfig. Verified to produce identical output to 'make
+# allnoconfig' for all ARCHes. The looping is done in case setting one symbol
+# to "n" allows other symbols to be set to "n" (due to dependencies).
+
+import kconfiglib
+import sys
+
+conf = kconfiglib.Config(sys.argv[1])
+
+while True:
+ done = True
+
+ for sym in conf:
+ # Choices take care of themselves for allnoconfig, so we only need to
+ # worry about non-choice symbols
+ if not sym.is_choice_item():
+ lower_bound = sym.get_lower_bound()
+
+ # If we can assign a lower value to the symbol (where "n", "m" and
+ # "y" are ordered from lowest to highest), then do so.
+ # lower_bound() returns None for symbols whose values cannot
+ # (currently) be changed, as well as for non-bool, non-tristate
+ # symbols.
+ if lower_bound is not None and \
+ kconfiglib.tri_less(lower_bound, sym.calc_value()):
+
+ sym.set_value(lower_bound)
+
+ # We just changed the value of some symbol. As this may affect
+ # other symbols, keep going.
+ done = False
+
+ if done:
+ break
+
+conf.write_config(".config")
diff --git a/examples/allyesconfig.py b/examples/allyesconfig.py
new file mode 100644
index 0000000..12dc19e
--- /dev/null
+++ b/examples/allyesconfig.py
@@ -0,0 +1,66 @@
+# Works like allyesconfig. This is a bit more involved than allnoconfig as we
+# need to handle choices in two different modes:
+#
+# "y": One symbol is "y", the rest are "n".
+# "m": Any number of symbols are "m", the rest are "n".
+#
+# 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.
+#
+# 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".
+#
+# The looping is in case setting one symbol to "y" (or "m") allows the value of
+# other symbols to be raised.
+
+import kconfiglib
+import sys
+
+conf = kconfiglib.Config(sys.argv[1])
+
+# 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_item()]
+
+while True:
+ done = True
+
+ # Handle symbols outside of choices
+
+ for sym in non_choice_syms:
+ upper_bound = sym.get_upper_bound()
+
+ # See corresponding comment for allnoconfig implementation
+ if upper_bound is not None and \
+ kconfiglib.tri_less(sym.calc_value(), upper_bound):
+ sym.set_value(upper_bound)
+ done = False
+
+ # Handle symbols within choices
+
+ for choice in conf.get_choices():
+
+ # Handle choices whose visibility allow them to be in "y" mode
+
+ 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_value("y")
+ done = False
+
+ # Handle choices whose visibility only allow them to be in "m" mode
+
+ elif choice.get_visibility() == "m":
+ for sym in choice.get_items():
+ if sym.calc_value() != "m" and \
+ sym.get_upper_bound() != "n":
+ sym.set_value("m")
+ done = False
+
+
+ if done:
+ break
+
+conf.write_config(".config")
diff --git a/examples/defconfig.py b/examples/defconfig.py
new file mode 100644
index 0000000..3ed09fa
--- /dev/null
+++ b/examples/defconfig.py
@@ -0,0 +1,17 @@
+# Works like entering "make menuconfig" and immediately saving and exiting
+
+import kconfiglib
+import os
+import sys
+
+conf = kconfiglib.Config(sys.argv[1])
+
+if os.path.exists(".config"):
+ conf.load_config(".config")
+else:
+ defconfig = conf.get_defconfig_filename()
+ if defconfig is not None:
+ print "Using " + defconfig
+ conf.load_config(defconfig)
+
+conf.write_config(".config")
diff --git a/examples/eval_expr.py b/examples/eval_expr.py
new file mode 100644
index 0000000..f8e0f65
--- /dev/null
+++ b/examples/eval_expr.py
@@ -0,0 +1,8 @@
+# Evaluates an expression in the context of a configuration. (Here we could
+# load a .config as well.)
+
+import kconfiglib
+import sys
+
+conf = kconfiglib.Config(sys.argv[1])
+print conf.eval("(TRACE_IRQFLAGS_SUPPORT || PPC32) && STACKTRACE_SUPPORT")
diff --git a/examples/print_refs.py b/examples/print_refs.py
new file mode 100644
index 0000000..b2d9f5f
--- /dev/null
+++ b/examples/print_refs.py
@@ -0,0 +1,13 @@
+# Prints the names of all symbols that reference a particular symbol. (There's
+# also a method get_selected_symbols() for determining just selection
+# relations.)
+
+import kconfiglib
+import sys
+
+conf = kconfiglib.Config(sys.argv[1])
+
+x86 = conf["X86"]
+for sym in conf:
+ if x86 in sym.get_referenced_symbols():
+ print sym.get_name()
diff --git a/examples/print_sym_info.py b/examples/print_sym_info.py
new file mode 100644
index 0000000..8c69cac
--- /dev/null
+++ b/examples/print_sym_info.py
@@ -0,0 +1,18 @@
+# Loads a Kconfig and a .config and prints information about a symbol.
+
+import kconfiglib
+import sys
+
+# Create a Config object representing a Kconfig configuration. (Any number of
+# these can be created -- the library has no global state.)
+conf = kconfiglib.Config(sys.argv[1])
+
+# Load values from a .config file. 'srctree' is an environment variable set by
+# the Linux makefiles to the top-level directory of the kernel tree. It needs
+# to be used here for the script to work with alternative build directories
+# (specified e.g. with O=).
+conf.load_config("$srctree/arch/x86/configs/i386_defconfig")
+
+# Print some information about a symbol. (The Config class implements
+# __getitem__() to provide a handy syntax for getting symbols.)
+print conf["SERIAL_UARTLITE_CONSOLE"]
diff --git a/examples/print_tree.py b/examples/print_tree.py
new file mode 100644
index 0000000..35ad23e
--- /dev/null
+++ b/examples/print_tree.py
@@ -0,0 +1,23 @@
+# Prints a tree of all items in the configuration
+
+import kconfiglib
+import sys
+
+def print_with_indent(s, indent):
+ print (" " * indent) + s
+
+def print_items(items, indent):
+ for item in items:
+ if item.is_symbol():
+ print_with_indent("config {0}".format(item.get_name()), indent)
+ elif item.is_menu():
+ print_with_indent('menu "{0}"'.format(item.get_title()), indent)
+ print_items(item.get_items(), indent + 2)
+ elif item.is_choice():
+ print_with_indent('choice', indent)
+ print_items(item.get_items(), indent + 2)
+ elif item.is_comment():
+ print_with_indent('comment "{0}"'.format(item.get_text()), indent)
+
+conf = kconfiglib.Config(sys.argv[1])
+print_items(conf.get_top_level_items(), 0)
diff --git a/examples/print_undefined.py b/examples/print_undefined.py
new file mode 100644
index 0000000..82a29d3
--- /dev/null
+++ b/examples/print_undefined.py
@@ -0,0 +1,15 @@
+# Prints the names of all symbols that are referenced but never defined in the
+# current configuration together with the locations where they are referenced.
+# Integers being included in the list is not a bug, as these need to be treated
+# as symbols per the design of Kconfig.
+
+import kconfiglib
+import sys
+
+conf = kconfiglib.Config(sys.argv[1])
+
+for sym in conf.get_symbols():
+ if not sym.is_defined():
+ print sym.get_name()
+ for (filename, linenr) in sym.get_ref_locations():
+ print " {0}:{1}".format(filename, linenr)
diff --git a/kconfiglib.py b/kconfiglib.py
index 9300021..8cdb543 100644
--- a/kconfiglib.py
+++ b/kconfiglib.py
@@ -2,18 +2,21 @@
# information from Kconfig-based configuration systems. To view the
# documentation, run
#
-# $ pydoc kconfiglib
+# $ pydoc kconfiglib
#
# or, if you prefer HTML,
#
-# $ pydoc -w kconfiglib
+# $ pydoc -w kconfiglib
#
-# By Ulf "Ulfalizer" Magnusson.
+# The examples/ subdirectory contains examples, to be run with e.g.
+#
+# $ make scriptconfig SCRIPT=Kconfiglib/examples/print_tree.py
+#
+# Look in kconfigtest.py for the test suite.
"""
-Kconfiglib is a Python library for scripting, debugging, and extracting
-information from Kconfig-based configuration systems. Features include the
-following:
+Kconfiglib is a Python library for scripting and extracting information from
+Kconfig-based configuration systems. Features include the following:
- Symbol values and properties can be looked up and values assigned
programmatically.
@@ -31,368 +34,38 @@ following:
Linux 2.6.38-rc3.
* Also generates a .config that is character-for-character identical to the
one generated by mconf for all architectures when no .config is supplied.
- * The 'make allyesconfig' and 'make allnoconfig' implementations below
+ * The 'make allyesconfig' and 'make allnoconfig' implementations in the
generate output character-for-character identical to the C implementation
for all architectures.
- See scripts/kconfig/kconfigtest.py for the Kconfiglib test suite.
+For the Linux kernel, scripts are run using
-For the Linux kernel, scripts should be run with
+ $ make scriptconfig SCRIPT=<path to script>
-$ make scriptconfig SCRIPT=<path to script>
+This ensures that needed environment variables (SRCARCH, ARCH, srctree,
+KERNELVERSION, etc.) are set up correctly. Alternative architectures can be
+specified like for other 'make *config' targets:
-to ensure that the environment (SRCARCH, ARCH, and KERNELVERSION) is set up
-correctly. Alternative architectures can be specified like for other 'make
-*config' targets:
+ $ make scriptconfig ARCH=mips SCRIPT=<path to script>
-$ make scriptconfig ARCH=mips SCRIPT=<path to script>
-
-The script will receive the name of the Kconfig file to load in sys.argv[1]. (As
+The script will receive the name of the Kconfig file to load in sys.argv[1]. As
of Linux 2.6.38-rc3 this is always "Kconfig" from the kernel top-level
-directory.)
+directory.
-To get an interactive Python prompt with Kconfiglib preloaded, use
+To get an interactive Python prompt with Kconfiglib preloaded and a Config
+object 'c' created, use
-$ make iscriptconfig [ARCH=<architecture>]
+ $ make iscriptconfig [ARCH=<architecture>]
Kconfiglib requires Python 2. For (i)scriptconfig the command to run the Python
interpreter can be passed in the environment variable PYTHONCMD (defaults to
-'python').
-
-Learning to use the library is probably easiest by looking at a few examples,
-reading the documentation, and experimenting. The API is designed to be
-intuitive and easy to use.
-
-===============================================================================
-Example 1: Load a configuration and a .config and print information about a
- symbol.
-
-import kconfiglib
-import sys
-
-# Create a Config object representing a Kconfig configuration. (Any number of
-# these can be created -- the library has no global state.)
-conf = kconfiglib.Config(sys.argv[1])
-
-# Load values from a .config file. 'srctree' is an environment variable set by
-# the Linux makefiles to the top-level directory of the kernel tree. It needs
-# to be used here for the script to work with alternative build directories
-# (specified e.g. with O=).
-conf.load_config("$srctree/arch/x86/configs/i386_defconfig")
-
-# Print some information about a symbol. (The Config class implements
-# __getitem__() to provide a handy syntax for getting symbols.)
-print conf["SERIAL_UARTLITE_CONSOLE"]
-
-Output for ARCH=i386:
-Symbol SERIAL_UARTLITE_CONSOLE
-Type : bool
-Value : "n"
-User value : (no user value)
-Visibility : "n"
-Is choice item : false
-Is defined : true
-Is from env. : false
-Is special : false
-Prompts:
- "Support for console on Xilinx uartlite serial port" if SERIAL_UARTLITE = y (value: "n")
-Default values:
- (no default values)
-Selects:
- SERIAL_CORE_CONSOLE if SERIAL_UARTLITE = y (value: "n")
-Reverse dependencies:
- (no reverse dependencies)
-Additional dependencies from enclosing menus and if's:
- HAS_IOMEM (value: "y")
-Locations: drivers/serial/Kconfig:913
-
-===============================================================================
-Example 2: Evaluate an expression in the context of a configuration. (Here we
- could load a .config as well.)
-
-import kconfiglib
-import sys
-
-conf = kconfiglib.Config(sys.argv[1])
-print conf.eval("(TRACE_IRQFLAGS_SUPPORT || PPC32) && STACKTRACE_SUPPORT")
-
-Output for ARCH=mips:
-y
-
-===============================================================================
-Example 3: Print the names of all symbols that are referenced but never defined
- in the current configuration together with the locations where they
- are referenced. Integers being included in the list is not a bug, as
- these need to be treated as symbols per the design of Kconfig.
-
-import kconfiglib
-import sys
-
-conf = kconfiglib.Config(sys.argv[1])
-
-for sym in conf.get_symbols():
- if not sym.is_defined():
- print sym.get_name()
- for (filename, linenr) in sym.get_ref_locations():
- print " {0}:{1}".format(filename, linenr)
-
-Output for ARCH=i386:
-MACH_NET2BIG_V2
- drivers/leds/Kconfig:365
-MACH_OMAP3517EVM
- sound/soc/omap/Kconfig:84
-ARCH_OMAP16XX
- drivers/pcmcia/Kconfig:271
- drivers/char/hw_random/Kconfig:117
- drivers/watchdog/Kconfig:210
- drivers/rtc/Kconfig:694
-SOC_JZ4740
- sound/soc/codecs/Kconfig:30
-MACH_AT91SAM9261EK
- drivers/video/Kconfig:1055
-PPC_83xx
- drivers/mtd/nand/Kconfig:463
- drivers/watchdog/Kconfig:951
- drivers/usb/Kconfig:58
- drivers/edac/Kconfig:221
-PPC_PSERIES
- init/Kconfig:999
- drivers/pci/hotplug/Kconfig:146
- drivers/scsi/Kconfig:964
- drivers/scsi/Kconfig:975
- drivers/scsi/Kconfig:989
- drivers/net/Kconfig:1353
- drivers/serial/Kconfig:1261
- drivers/char/Kconfig:628
- drivers/char/Kconfig:712
- drivers/char/Kconfig:729
-... (lots more)
-
-===============================================================================
-Example 4: Print the names of all symbols that reference a particular symbol.
- (There's also a method get_selected_symbols() for determining
- just selection relations.)
-
-import kconfiglib
-import sys
-
-conf = kconfiglib.Config(sys.argv[1])
-
-x86 = conf["X86"]
-for sym in conf:
- if x86 in sym.get_referenced_symbols():
- print sym.get_name()
-
-Output for ARCH=i386:
-AUDITSYSCALL
-PCSPKR_PLATFORM
-OPROFILE_EVENT_MULTIPLEX
-GCOV_PROFILE_ALL
-SCHED_OMIT_FRAME_POINTER
-MEMORY_HOTPLUG
-PM_TRACE_RTC
-ACPI
-ACPI_AC
-ACPI_BATTERY
-ACPI_VIDEO
-ACPI_PROCESSOR_AGGREGATOR
-ACPI_NUMA
-X86_PM_TIMER
-ACPI_SBS
-ACPI_APEI
-ACPI_APEI_GHES
-INTEL_IDLE
-XEN_PCIDEV_FRONTEND
-EISA_VLB_PRIMING
-EISA_VIRTUAL_ROOT
-HOTPLUG_PCI_COMPAQ
-HOTPLUG_PCI_IBM
-HOTPLUG_PCI_CPCI_ZT5550
-HOTPLUG_PCI_CPCI_GENERIC
-MTD_SC520CDP
-... (lots more)
-
-===============================================================================
-Example 5: Print a tree of all items in the configuration.
-
-import kconfiglib
-import sys
-
-def print_with_indent(s, indent):
- print (" " * indent) + s
-
-def print_items(items, indent):
- for item in items:
- if item.is_symbol():
- print_with_indent("config {0}".format(item.get_name()), indent)
- elif item.is_menu():
- print_with_indent('menu "{0}"'.format(item.get_title()), indent)
- print_items(item.get_items(), indent + 2)
- elif item.is_choice():
- print_with_indent('choice', indent)
- print_items(item.get_items(), indent + 2)
- elif item.is_comment():
- print_with_indent('comment "{0}"'.format(item.get_text()), indent)
-
-conf = kconfiglib.Config(sys.argv[1])
-print_items(conf.get_top_level_items(), 0)
-
-Output for ARCH=i386:
-...
-config ARCH
-config KERNELVERSION
-config CONSTRUCTORS
-config HAVE_IRQ_WORK
-config IRQ_WORK
-menu "General setup"
- config EXPERIMENTAL
- config BROKEN
- config BROKEN_ON_SMP
- config LOCK_KERNEL
- config INIT_ENV_ARG_LIMIT
- config CROSS_COMPILE
- config LOCALVERSION
- config LOCALVERSION_AUTO
- config HAVE_KERNEL_GZIP
- config HAVE_KERNEL_BZIP2
- config HAVE_KERNEL_LZMA
- config HAVE_KERNEL_XZ
- config HAVE_KERNEL_LZO
- choice
- config KERNEL_GZIP
- config KERNEL_BZIP2
- config KERNEL_LZMA
- config KERNEL_XZ
- config KERNEL_LZO
- config SWAP
- config SYSVIPC
- config SYSVIPC_SYSCTL
- config POSIX_MQUEUE
- config POSIX_MQUEUE_SYSCTL
- config BSD_PROCESS_ACCT
- config BSD_PROCESS_ACCT_V3
-...
-
-===============================================================================
-Example 6: This does the same thing as entering "make menuconfig" and
- immediately saving and exiting.
-
-import kconfiglib
-import os
-import sys
-
-conf = kconfiglib.Config(sys.argv[1])
-
-if os.path.exists(".config"):
- conf.load_config(".config")
-else:
- defconfig = conf.get_defconfig_filename()
- if defconfig is not None:
- print "Using " + defconfig
- conf.load_config(defconfig)
-
-conf.write_config(".config")
-
-===============================================================================
-Example 7: As a more complex example, this is a reimplementation of allnoconfig
- (verified to produce identical output to 'make allnoconfig' for all
- ARCHes). The looping is done in case setting one symbol to "n"
- allows other symbols to be set to "n" (due to dependencies).
-
-import kconfiglib
-import sys
-
-conf = kconfiglib.Config(sys.argv[1])
-
-while True:
- done = True
-
- for sym in conf:
- # Choices take care of themselves for allnoconfig, so we only need to
- # worry about non-choice symbols
- if not sym.is_choice_item():
- lower_bound = sym.get_lower_bound()
-
- # If we can assign a lower value to the symbol (where "n", "m" and
- # "y" are ordered from lowest to highest), then do so.
- # lower_bound() returns None for symbols whose values cannot
- # (currently) be changed, as well as for non-bool, non-tristate
- # symbols.
- if lower_bound is not None and \\
- kconfiglib.tri_less(lower_bound, sym.calc_value()):
-
- sym.set_value(lower_bound)
-
- # We just changed the value of some symbol. As this may affect
- # other symbols, keep going.
- done = False
-
- if done:
- break
-
-conf.write_config(".config")
-
-===============================================================================
-Example 8: here's allyesconfig (also verified), which is a bit more involved
- as we need to handle choices in two different modes ("y", i.e.
- one-is-y-rest-is-n, and "m", i.e.
- any-number-of-symbols-are-m-rest-are-n). The looping is in case
- setting one symbol to "y" (or "m") allows the value of other symbols
- to be raised.
-
-import kconfiglib
-import sys
-
-conf = kconfiglib.Config(sys.argv[1])
-
-# 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_item()]
-
-while True:
- done = True
-
- # Handle symbols outside of choices
-
- for sym in non_choice_syms:
- upper_bound = sym.get_upper_bound()
-
- # See corresponding comment for allnoconfig implementation
- if upper_bound is not None and \\
- kconfiglib.tri_less(sym.calc_value(), upper_bound):
- sym.set_value(upper_bound)
- done = False
-
- # Handle symbols within choices
-
- for choice in conf.get_choices():
-
- # Handle choices whose visibility allow them to be in "y" mode
-
- 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_value("y")
- done = False
-
- # Handle choices whose visibility only allow them to be in "m" mode
-
- elif choice.get_visibility() == "m":
- for sym in choice.get_items():
- if sym.calc_value() != "m" and \\
- sym.get_upper_bound() != "n":
- sym.set_value("m")
- done = False
-
-
- if done:
- break
+'python'; PyPy works too and is a bit faster).
-conf.write_config(".config")
+Look in the examples/ subdirectory for examples.
+Look in kconfigtest.py for the test suite.
-Credits: written by Ulf "Ulfalizer" Magnusson
+Credits: Written by Ulf "Ulfalizer" Magnusson
Send bug reports, suggestions (any missing APIs that would make your life
easier?) and other feedback to kconfiglib@gmail.com ."""