]> git.ipfire.org Git - thirdparty/qemu.git/commitdiff
minikconf: move command-line assignment out of the parser
authorPaolo Bonzini <pbonzini@redhat.com>
Fri, 24 Apr 2026 08:08:34 +0000 (10:08 +0200)
committerPaolo Bonzini <pbonzini@redhat.com>
Thu, 30 Apr 2026 13:50:18 +0000 (15:50 +0200)
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 <marcandre.lureau@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
scripts/minikconf.py

index 08df8d5dabb1aab4826cfd986a8c8286ba949a29..668de577d09738b7ef0a016338638b55a8fe548c 100644 (file)
@@ -278,6 +278,10 @@ class KconfigData:
     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 @@ class KconfigParserError(Exception):
 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 @@ class KconfigParser:
         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 @@ if __name__ == '__main__':
         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()):