From e07ed5548eeca30e5815256a5cc47ea50deaa666 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 24 Apr 2026 10:08:34 +0200 Subject: [PATCH] minikconf: move command-line assignment out of the parser MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit KconfigParser.do_assignment() only exists to handle CONFIG_FOO=y/n arguments from the command line; it is never invoked while parsing a Kconfig source file. Because main() called it on a parser that had never been through parse_file(), a failing CONFIG_ check would raise a KconfigParserError whose __init__ and location() touch fields of "self" that do not exist yet. The regex in main() currently shields this, but it is fragile. Move the prefix-stripping assignment to KconfigData as do_cmdline_assignment(), simplify KconfigParser.parse() to accept an existing KconfigData, and call it from main() so the parser is only used for actual file parsing. Reviewed-by: Marc-André Lureau Signed-off-by: Paolo Bonzini --- scripts/minikconf.py | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/scripts/minikconf.py b/scripts/minikconf.py index 08df8d5dab..668de577d0 100644 --- a/scripts/minikconf.py +++ b/scripts/minikconf.py @@ -278,6 +278,10 @@ def do_var(self, var): def do_assignment(self, var, val): self.clauses.append(KconfigData.AssignmentClause(var, val)) + def do_cmdline_assignment(self, var, val): + assert var.startswith("CONFIG_") + self.do_assignment(self.do_var(var[7:]), val) + def do_default(self, var, val, cond=None): val = self.value_mangler(val) self.clauses.append(KconfigData.DefaultClause(var, val, cond)) @@ -338,11 +342,8 @@ def __str__(self): class KconfigParser: @classmethod - def parse(cls, fp, mode=None): - data = KconfigData(mode or defconfig) - parser = cls(data) - parser.parse_file(fp) - return data + def parse(cls, fp, data): + cls(data).parse_file(fp) def __init__(self, data): self.data = data @@ -361,14 +362,6 @@ def parse_file(self, fp): self.get_token() self.parse_config() - def do_assignment(self, var, val): - if not var.startswith("CONFIG_"): - raise KconfigParserError( - self, "assigned variable should start with CONFIG_" - ) - var = self.data.do_var(var[7:]) - self.data.do_assignment(var, val) - # file management ----- def error_path(self): @@ -688,18 +681,16 @@ def scan_token(self): sys.exit(1) data = KconfigData(mode) - parser = KconfigParser(data) external_vars = set() for arg in argv[3:]: m = re.match(r'^(CONFIG_[A-Z0-9_]+)=([yn]?)$', arg) if m is not None: name, value = m.groups() - parser.do_assignment(name, value == 'y') + data.do_cmdline_assignment(name, value == 'y') external_vars.add(name[7:]) else: - fp = open(arg, 'rt', encoding='utf-8') - parser.parse_file(fp) - fp.close() + with open(arg, 'rt', encoding='utf-8') as fp: + KconfigParser.parse(fp, data) config = data.compute_config() for key in sorted(config.keys()):