ext: Add a cont_choice keyword to kconfiglib.

This keyword lets you pick up a "choice" entry from elsewhere and add
new entries to it, greatly improving modularity of the Kconfig files.

Change-Id: Id20da6bc573e841e3ca7a42678911de827b53584
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/56756
Maintainer: Gabe Black <gabe.black@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
This commit is contained in:
Gabe Black
2022-02-11 04:00:28 -08:00
parent ee5c751fb5
commit caa5f12e21

View File

@@ -2422,7 +2422,7 @@ class Kconfig(object):
# #
# Named choices ('choice FOO') also end up here. # Named choices ('choice FOO') also end up here.
if token is not _T_CHOICE: if token not in (_T_CHOICE, _T_CONTCHOICE):
self._warn("style: quotes recommended around '{}' in '{}'" self._warn("style: quotes recommended around '{}' in '{}'"
.format(name, self._line.strip()), .format(name, self._line.strip()),
self.filename, self.linenr) self.filename, self.linenr)
@@ -3078,10 +3078,39 @@ class Kconfig(object):
self._parse_props(node) self._parse_props(node)
self._parse_block(_T_ENDCHOICE, node, node) self._parse_block(_T_ENDCHOICE, node, node)
node.list = node.next
node.list = node.next
prev.next = prev = node prev.next = prev = node
elif t0 is _T_CONTCHOICE:
# Named choice
name = self._expect_str_and_eol()
choice = self.named_choices.get(name)
if not choice:
self._parse_error(f"can't continue choice '{name}'")
assert(len(choice.nodes))
# Add more to the earlier node.
node = choice.nodes[-1]
# Find the end of its list so we can add to it.
if node.list:
sub_prev = node.list
while sub_prev.next:
sub_prev = sub_prev.next
else:
# If we don't have a list at all, temporarily make one up.
sub_prev = MenuNode()
# Parse any new properties.
self._parse_props(node)
# Read in new subnodes.
self._parse_block(_T_ENDCHOICE, node, sub_prev)
# If we made up a lead node, move the list to where it belongs.
if not node.list:
node.list = sub_prev.next
elif t0 is _T_MAINMENU: elif t0 is _T_MAINMENU:
self.top_node.prompt = (self._expect_str_and_eol(), self.y) self.top_node.prompt = (self._expect_str_and_eol(), self.y)
@@ -6856,6 +6885,7 @@ except AttributeError:
_T_CLOSE_PAREN, _T_CLOSE_PAREN,
_T_COMMENT, _T_COMMENT,
_T_CONFIG, _T_CONFIG,
_T_CONTCHOICE,
_T_DEFAULT, _T_DEFAULT,
_T_DEFCONFIG_LIST, _T_DEFCONFIG_LIST,
_T_DEF_BOOL, _T_DEF_BOOL,
@@ -6899,7 +6929,7 @@ except AttributeError:
_T_TRISTATE, _T_TRISTATE,
_T_UNEQUAL, _T_UNEQUAL,
_T_VISIBLE, _T_VISIBLE,
) = range(1, 51) ) = range(1, 52)
# Keyword to token map, with the get() method assigned directly as a small # Keyword to token map, with the get() method assigned directly as a small
# optimization # optimization
@@ -6911,6 +6941,7 @@ _get_keyword = {
"choice": _T_CHOICE, "choice": _T_CHOICE,
"comment": _T_COMMENT, "comment": _T_COMMENT,
"config": _T_CONFIG, "config": _T_CONFIG,
"cont_choice": _T_CONTCHOICE,
"def_bool": _T_DEF_BOOL, "def_bool": _T_DEF_BOOL,
"def_hex": _T_DEF_HEX, "def_hex": _T_DEF_HEX,
"def_int": _T_DEF_INT, "def_int": _T_DEF_INT,
@@ -7024,6 +7055,7 @@ _STRING_LEX = frozenset({
_T_BOOL, _T_BOOL,
_T_CHOICE, _T_CHOICE,
_T_COMMENT, _T_COMMENT,
_T_CONTCHOICE,
_T_HEX, _T_HEX,
_T_INT, _T_INT,
_T_MAINMENU, _T_MAINMENU,