From 3bc14098d8fb05b98e01c4abd901f77b55d19331 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Fri, 20 Sep 2019 17:42:07 -0400 Subject: genboardscfg.py: Convert to Python 3 Convert this tool to requiring Python 3. The bulk of this is done with the 2to3 tool In addition, we need to use the '//' operator to have our division result return an int rather than a float and ensure that we use UTF-8 when reading/writing files. Cc: Masahiro Yamada Signed-off-by: Tom Rini --- tools/genboardscfg.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/tools/genboardscfg.py b/tools/genboardscfg.py index e9bbd15e15..e9a9c11865 100755 --- a/tools/genboardscfg.py +++ b/tools/genboardscfg.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 # SPDX-License-Identifier: GPL-2.0+ # # Author: Masahiro Yamada @@ -91,7 +91,7 @@ def output_is_new(output): # Detect a board that has been removed since the current board database # was generated - with open(output) as f: + with open(output, encoding="utf-8") as f: for line in f: if line[0] == '#' or line == '\n': continue @@ -168,7 +168,7 @@ class KconfigScanner: warnings = self._conf.load_config(self._tmpfile) if warnings: for warning in warnings: - print '%s: %s' % (defconfig, warning) + print('%s: %s' % (defconfig, warning)) try_remove(self._tmpfile) self._tmpfile = None @@ -177,7 +177,7 @@ class KconfigScanner: # Get the value of CONFIG_SYS_ARCH, CONFIG_SYS_CPU, ... etc. # Set '-' if the value is empty. - for key, symbol in self._SYMBOL_TABLE.items(): + for key, symbol in list(self._SYMBOL_TABLE.items()): value = self._conf.get_symbol(symbol).get_value() if value: params[key] = value @@ -242,8 +242,8 @@ def scan_defconfigs(jobs=1): processes = [] queues = [] for i in range(jobs): - defconfigs = all_defconfigs[total_boards * i / jobs : - total_boards * (i + 1) / jobs] + defconfigs = all_defconfigs[total_boards * i // jobs : + total_boards * (i + 1) // jobs] q = multiprocessing.Queue(maxsize=-1) p = multiprocessing.Process(target=scan_defconfigs_for_multiprocess, args=(q, defconfigs)) @@ -290,7 +290,7 @@ class MaintainersDatabase: 'Active', 'Orphan' or '-'. """ if not target in self.database: - print >> sys.stderr, "WARNING: no status info for '%s'" % target + print("WARNING: no status info for '%s'" % target, file=sys.stderr) return '-' tmp = self.database[target][0] @@ -301,8 +301,8 @@ class MaintainersDatabase: elif tmp.startswith('Orphan'): return 'Orphan' else: - print >> sys.stderr, ("WARNING: %s: unknown status for '%s'" % - (tmp, target)) + print(("WARNING: %s: unknown status for '%s'" % + (tmp, target)), file=sys.stderr) return '-' def get_maintainers(self, target): @@ -313,7 +313,7 @@ class MaintainersDatabase: they are separated with colons. """ if not target in self.database: - print >> sys.stderr, "WARNING: no maintainers for '%s'" % target + print("WARNING: no maintainers for '%s'" % target, file=sys.stderr) return '' return ':'.join(self.database[target][1]) @@ -330,7 +330,7 @@ class MaintainersDatabase: targets = [] maintainers = [] status = '-' - for line in open(file): + for line in open(file, encoding="utf-8"): # Check also commented maintainers if line[:3] == '#M:': line = line[1:] @@ -404,7 +404,7 @@ def format_and_output(params_list, output): # ignore case when sorting output_lines.sort(key=str.lower) - with open(output, 'w') as f: + with open(output, 'w', encoding="utf-8") as f: f.write(COMMENT_BLOCK + '\n'.join(output_lines) + '\n') def gen_boards_cfg(output, jobs=1, force=False): @@ -418,7 +418,7 @@ def gen_boards_cfg(output, jobs=1, force=False): check_top_directory() if not force and output_is_new(output): - print "%s is up to date. Nothing to do." % output + print("%s is up to date. Nothing to do." % output) sys.exit(0) params_list = scan_defconfigs(jobs) -- cgit From 5e7c8a39e634235e2ee696a39bf1f404fc707fda Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Fri, 20 Sep 2019 17:42:08 -0400 Subject: genboardscfg.py: Remove "warnings" print section We tell kconfiglib to not print any warnings to us so drop this code as it will be unused. Cc: Masahiro Yamada Signed-off-by: Tom Rini --- tools/genboardscfg.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/tools/genboardscfg.py b/tools/genboardscfg.py index e9a9c11865..9fd2bd30ef 100755 --- a/tools/genboardscfg.py +++ b/tools/genboardscfg.py @@ -165,11 +165,7 @@ class KconfigScanner: else: f.write(line[colon + 1:]) - warnings = self._conf.load_config(self._tmpfile) - if warnings: - for warning in warnings: - print('%s: %s' % (defconfig, warning)) - + self._conf.load_config(self._tmpfile) try_remove(self._tmpfile) self._tmpfile = None -- cgit From 65e05ddc1ae25210a9865622e9e618e5ba8488c8 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Fri, 20 Sep 2019 17:42:09 -0400 Subject: kconfiglib: Update to the 12.14.0 release A large number of changes have happened upstream since our last sync which was to 375506d. The reason to do the upgrade at this point is for improved Python 3 support. As part of this upgrade we need to update moveconfig.py and genboardscfg.py the current API. This is: - Change "kconfiglib.Config" calls to "kconfiglib.Kconfig" - Change get_symbol() calls to syms.get(). - Change get_value() to str_value. Cc: Masahiro Yamada Signed-off-by: Tom Rini --- tools/buildman/kconfiglib.py | 9812 ++++++++++++++++++++++++++++-------------- tools/genboardscfg.py | 6 +- tools/moveconfig.py | 12 +- 3 files changed, 6658 insertions(+), 3172 deletions(-) diff --git a/tools/buildman/kconfiglib.py b/tools/buildman/kconfiglib.py index d68af056b6..3908985c7b 100644 --- a/tools/buildman/kconfiglib.py +++ b/tools/buildman/kconfiglib.py @@ -1,3409 +1,6219 @@ +# Copyright (c) 2011-2019, Ulf Magnusson # SPDX-License-Identifier: ISC -# -# Author: Ulf Magnusson -# https://github.com/ulfalizer/Kconfiglib - -# This is Kconfiglib, a Python library for scripting, debugging, and extracting -# information from Kconfig-based configuration systems. To view the -# documentation, run -# -# $ pydoc kconfiglib -# -# or, if you prefer HTML, -# -# $ pydoc -w kconfiglib -# -# The examples/ subdirectory contains examples, to be run with e.g. -# -# $ make scriptconfig SCRIPT=Kconfiglib/examples/print_tree.py -# -# Look in testsuite.py for the test suite. """ -Kconfiglib is a Python library for scripting and extracting information from -Kconfig-based configuration systems. Features include the following: +Overview +======== - - Symbol values and properties can be looked up and values assigned - programmatically. - - .config files can be read and written. - - Expressions can be evaluated in the context of a Kconfig configuration. - - Relations between symbols can be quickly determined, such as finding all - symbols that reference a particular symbol. - - Highly compatible with the scripts/kconfig/*conf utilities. The test suite - automatically compares outputs between Kconfiglib and the C implementation - for a large number of cases. +Kconfiglib is a Python 2/3 library for scripting and extracting information +from Kconfig (https://www.kernel.org/doc/Documentation/kbuild/kconfig-language.txt) +configuration systems. -For the Linux kernel, scripts are run using +See the homepage at https://github.com/ulfalizer/Kconfiglib for a longer +overview. - $ make scriptconfig [ARCH=] SCRIPT= [SCRIPT_ARG=] +Since Kconfiglib 12.0.0, the library version is available in +kconfiglib.VERSION, which is a (, , ) tuple, e.g. +(12, 0, 0). -Using the 'scriptconfig' target ensures that required environment variables -(SRCARCH, ARCH, srctree, KERNELVERSION, etc.) are set up correctly. -Scripts receive the name of the Kconfig file to load in sys.argv[1]. As of -Linux 4.1.0-rc5, this is always "Kconfig" from the kernel top-level directory. -If an argument is provided with SCRIPT_ARG, it appears as sys.argv[2]. +Using Kconfiglib on the Linux kernel with the Makefile targets +============================================================== -To get an interactive Python prompt with Kconfiglib preloaded and a Config -object 'c' created, run +For the Linux kernel, a handy interface is provided by the +scripts/kconfig/Makefile patch, which can be applied with either 'git am' or +the 'patch' utility: - $ make iscriptconfig [ARCH=] + $ wget -qO- https://raw.githubusercontent.com/ulfalizer/Kconfiglib/master/makefile.patch | git am + $ wget -qO- https://raw.githubusercontent.com/ulfalizer/Kconfiglib/master/makefile.patch | patch -p1 -Kconfiglib supports both Python 2 and Python 3. For (i)scriptconfig, the Python -interpreter to use can be passed in PYTHONCMD, which defaults to 'python'. PyPy -works well too, and might give a nice speedup for long-running jobs. +Warning: Not passing -p1 to patch will cause the wrong file to be patched. -The examples/ directory contains short example scripts, which can be run with -e.g. +Please tell me if the patch does not apply. It should be trivial to apply +manually, as it's just a block of text that needs to be inserted near the other +*conf: targets in scripts/kconfig/Makefile. - $ make scriptconfig SCRIPT=Kconfiglib/examples/print_tree.py +Look further down for a motivation for the Makefile patch and for instructions +on how you can use Kconfiglib without it. -or +If you do not wish to install Kconfiglib via pip, the Makefile patch is set up +so that you can also just clone Kconfiglib into the kernel root: - $ make scriptconfig SCRIPT=Kconfiglib/examples/help_grep.py SCRIPT_ARG=kernel + $ git clone git://github.com/ulfalizer/Kconfiglib.git + $ git am Kconfiglib/makefile.patch (or 'patch -p1 < Kconfiglib/makefile.patch') -testsuite.py contains the test suite. See the top of the script for how to run -it. +Warning: The directory name Kconfiglib/ is significant in this case, because +it's added to PYTHONPATH by the new targets in makefile.patch. -Credits: Written by Ulf "Ulfalizer" Magnusson +The targets added by the Makefile patch are described in the following +sections. -Send bug reports, suggestions and other feedback to ulfalizer a.t Google's -email service. Don't wrestle with internal APIs. Tell me what you need and I -might add it in a safe way as a client API instead.""" -import os -import platform -import re -import sys +make kmenuconfig +---------------- -# File layout: -# -# Public classes -# Public functions -# Internal classes -# Internal functions -# Internal global constants +This target runs the curses menuconfig interface with Python 3. As of +Kconfiglib 12.2.0, both Python 2 and Python 3 are supported (previously, only +Python 3 was supported, so this was a backport). -# Line length: 79 columns -# -# Public classes -# +make guiconfig +-------------- -class Config(object): +This target runs the Tkinter menuconfig interface. Both Python 2 and Python 3 +are supported. To change the Python interpreter used, pass +PYTHONCMD= to 'make'. The default is 'python'. - """Represents a Kconfig configuration, e.g. for i386 or ARM. This is the - set of symbols and other items appearing in the configuration together with - their values. Creating any number of Config objects -- including for - different architectures -- is safe; Kconfiglib has no global state.""" - # - # Public interface - # +make [ARCH=] iscriptconfig +-------------------------------- - def __init__(self, filename="Kconfig", base_dir=None, print_warnings=True, - print_undef_assign=False): - """Creates a new Config object, representing a Kconfig configuration. - Raises Kconfig_Syntax_Error on syntax errors. - - filename (default: "Kconfig"): The base Kconfig file of the - configuration. For the Linux kernel, you'll probably want "Kconfig" - from the top-level directory, as environment variables will make - sure the right Kconfig is included from there - (arch//Kconfig). If you are using Kconfiglib via 'make - scriptconfig', the filename of the base base Kconfig file will be in - sys.argv[1]. - - base_dir (default: None): The base directory relative to which 'source' - statements within Kconfig files will work. For the Linux kernel this - should be the top-level directory of the kernel tree. $-references - to existing environment variables will be expanded. - - If None (the default), the environment variable 'srctree' will be - used if set, and the current directory otherwise. 'srctree' is set - by the Linux makefiles to the top-level kernel directory. A default - of "." would not work with an alternative build directory. - - print_warnings (default: True): Set to True if warnings related to this - configuration should be printed to stderr. This can be changed later - with Config.set_print_warnings(). It is provided as a constructor - argument since warnings might be generated during parsing. - - print_undef_assign (default: False): Set to True if informational - messages related to assignments to undefined symbols should be - printed to stderr for this configuration. Can be changed later with - Config.set_print_undef_assign().""" - - # The set of all symbols, indexed by name (a string) - self.syms = {} - # Python 2/3 compatibility hack. This is the only one needed. - self.syms_iter = self.syms.values if sys.version_info[0] >= 3 else \ - self.syms.itervalues +This target gives an interactive Python prompt where a Kconfig instance has +been preloaded and is available in 'kconf'. To change the Python interpreter +used, pass PYTHONCMD= to 'make'. The default is 'python'. - # The set of all defined symbols in the configuration in the order they - # appear in the Kconfig files. This excludes the special symbols n, m, - # and y as well as symbols that are referenced but never defined. - self.kconfig_syms = [] +To get a feel for the API, try evaluating and printing the symbols in +kconf.defined_syms, and explore the MenuNode menu tree starting at +kconf.top_node by following 'next' and 'list' pointers. - # The set of all named choices (yes, choices can have names), indexed - # by name (a string) - self.named_choices = {} +The item contained in a menu node is found in MenuNode.item (note that this can +be one of the constants kconfiglib.MENU and kconfiglib.COMMENT), and all +symbols and choices have a 'nodes' attribute containing their menu nodes +(usually only one). Printing a menu node will print its item, in Kconfig +format. - # Lists containing all choices, menus and comments in the configuration - self.choices = [] - self.menus = [] - self.comments = [] +If you want to look up a symbol by name, use the kconf.syms dictionary. - def register_special_symbol(type_, name, val): - sym = Symbol() - sym.is_special_ = True - sym.is_defined_ = True - sym.config = self - sym.name = name - sym.type = type_ - sym.cached_val = val - self.syms[name] = sym - return sym - - # The special symbols n, m and y, used as shorthand for "n", "m" and - # "y" - self.n = register_special_symbol(TRISTATE, "n", "n") - self.m = register_special_symbol(TRISTATE, "m", "m") - self.y = register_special_symbol(TRISTATE, "y", "y") - # DEFCONFIG_LIST uses this - register_special_symbol(STRING, "UNAME_RELEASE", platform.uname()[2]) - - # The symbol with "option defconfig_list" set, containing a list of - # default .config files - self.defconfig_sym = None - - # See Symbol.get_(src)arch() - self.arch = os.environ.get("ARCH") - self.srcarch = os.environ.get("SRCARCH") - - # If you set CONFIG_ in the environment, Kconfig will prefix all symbols - # with its value when saving the configuration, instead of using the default, "CONFIG_". - self.config_prefix = os.environ.get("CONFIG_") - if self.config_prefix is None: - self.config_prefix = "CONFIG_" - - # See Config.__init__(). We need this for get_defconfig_filename(). - self.srctree = os.environ.get("srctree") - if self.srctree is None: - self.srctree = "." - self.filename = filename - self.base_dir = self.srctree if base_dir is None else \ - os.path.expandvars(base_dir) +make scriptconfig SCRIPT=