minikconf: move command-line assignment out of the parser
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>
This commit is contained in:
@@ -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()):
|
||||
|
||||
Reference in New Issue
Block a user