summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kconfiglib.py203
-rw-r--r--testsuite.py186
2 files changed, 250 insertions, 139 deletions
diff --git a/kconfiglib.py b/kconfiglib.py
index 25bb380..3262b43 100644
--- a/kconfiglib.py
+++ b/kconfiglib.py
@@ -360,13 +360,13 @@ class Config(object):
# Predefined symbol. DEFCONFIG_LIST uses this.
uname_sym = self._lookup_const_sym("UNAME_RELEASE")
uname_sym._type = STRING
- uname_sym.defaults.append(
- (self._lookup_const_sym(platform.uname()[2]),
- self.y))
# env_var doubles as the SYMBOL_AUTO flag from the C implementation, so
# just set it to something. The naming breaks a bit here, but it's
# pretty obscure.
uname_sym.env_var = "<uname release>"
+ uname_sym.defaults.append(
+ (self._lookup_const_sym(platform.uname()[2]),
+ self.y))
self.syms["UNAME_RELEASE"] = uname_sym
self.top_node = MenuNode()
@@ -418,8 +418,8 @@ class Config(object):
if self.defconfig_list is None:
return None
- for filename, cond_expr in self.defconfig_list.defaults:
- if eval_expr(cond_expr):
+ for filename, cond in self.defconfig_list.defaults:
+ if expr_value(cond):
filename = self._expand_sym_refs(filename.str_value)
try:
with self._open(filename) as f:
@@ -559,7 +559,7 @@ class Config(object):
self._line = s
del self._tokens[0]
- return eval_expr(self._parse_expr(True))
+ return expr_value(self._parse_expr(True))
def unset_values(self):
"""
@@ -921,7 +921,6 @@ class Config(object):
self._reuse_line = False
while self._line.endswith("\\\n"):
- # TODO: Can hang if the file ends with a backslash
self._line = self._line[:-2] + self._file.readline()
self._linenr += 1
@@ -1346,39 +1345,39 @@ class Config(object):
node.prompt = None
# Add the new defaults, with dependencies propagated
- for val_expr, cond_expr in defaults:
+ for val_expr, cond in defaults:
node.item.defaults.append(
- (val_expr, self._make_and(cond_expr, node.dep)))
+ (val_expr, self._make_and(cond, node.dep)))
# Add the new ranges, with dependencies propagated
- for low, high, cond_expr in ranges:
+ for low, high, cond in ranges:
node.item.ranges.append(
- (low, high, self._make_and(cond_expr, node.dep)))
+ (low, high, self._make_and(cond, node.dep)))
# Handle selects
- for target, cond_expr in selects:
+ for target, cond in selects:
# Only stored for convenience. Not used during evaluation.
node.item.selects.append(
- (target, self._make_and(cond_expr, node.dep)))
+ (target, self._make_and(cond, node.dep)))
# Modify the dependencies of the selected symbol
target.rev_dep = \
self._make_or(target.rev_dep,
self._make_and(node.item,
- self._make_and(cond_expr,
+ self._make_and(cond,
node.dep)))
# Handle implies
- for target, cond_expr in implies:
+ for target, cond in implies:
# Only stored for convenience. Not used during evaluation.
node.item.implies.append(
- (target, self._make_and(cond_expr, node.dep)))
+ (target, self._make_and(cond, node.dep)))
# Modify the dependencies of the implied symbol
target.weak_rev_dep = \
self._make_or(target.weak_rev_dep,
self._make_and(node.item,
- self._make_and(cond_expr,
+ self._make_and(cond,
node.dep)))
def _parse_expr(self, transform_m):
@@ -1559,8 +1558,8 @@ class Config(object):
add_fn(config_string)
sym._already_written = True
- elif eval_expr(node.dep) and \
- ((node.item == MENU and eval_expr(node.visibility)) or
+ elif expr_value(node.dep) and \
+ ((node.item == MENU and expr_value(node.visibility)) or
node.item == COMMENT):
add_fn("\n#\n# {}\n#\n".format(node.prompt[0]))
@@ -1994,8 +1993,8 @@ class Symbol(object):
base = _TYPE_TO_BASE[self._type]
# Check if a range is in effect
- for low_expr, high_expr, cond_expr in self.ranges:
- if eval_expr(cond_expr):
+ for low_expr, high_expr, cond in self.ranges:
+ if expr_value(cond):
has_active_range = True
low = int(low_expr.str_value, base) if \
@@ -2020,8 +2019,8 @@ class Symbol(object):
else:
# No user value or invalid user value. Look at defaults.
- for val_expr, cond_expr in self.defaults:
- if eval_expr(cond_expr):
+ for val_expr, cond in self.defaults:
+ if expr_value(cond):
self._write_to_conf = True
# Similarly to above, well-formed defaults are
@@ -2059,8 +2058,8 @@ class Symbol(object):
if vis and self.user_str_value is not None:
val = self.user_str_value
else:
- for val_expr, cond_expr in self.defaults:
- if eval_expr(cond_expr):
+ for val_expr, cond in self.defaults:
+ if expr_value(cond):
self._write_to_conf = True
val = val_expr.str_value
break
@@ -2096,22 +2095,22 @@ class Symbol(object):
# (implies)
for default, cond in self.defaults:
- cond_val = eval_expr(cond)
+ cond_val = expr_value(cond)
if cond_val:
- val = min(cond_val, eval_expr(default))
+ val = min(cond_val, expr_value(default))
self._write_to_conf = True
break
# Weak reverse dependencies are only considered if our
# direct dependencies are met
- if eval_expr(self.direct_dep):
- weak_rev_dep_val = eval_expr(self.weak_rev_dep)
+ if expr_value(self.direct_dep):
+ weak_rev_dep_val = expr_value(self.weak_rev_dep)
if weak_rev_dep_val:
val = max(weak_rev_dep_val, val)
self._write_to_conf = True
# Reverse (select-related) dependencies take precedence
- rev_dep_val = eval_expr(self.rev_dep)
+ rev_dep_val = expr_value(self.rev_dep)
if rev_dep_val:
val = max(rev_dep_val, val)
self._write_to_conf = True
@@ -2139,7 +2138,7 @@ class Symbol(object):
# 1) If our type is boolean
# 2) If our weak_rev_dep (from IMPLY) is y
if val == 1 and \
- (self.type == BOOL or eval_expr(self.weak_rev_dep) == 2):
+ (self.type == BOOL or expr_value(self.weak_rev_dep) == 2):
val = 2
self._cached_tri_val = val
@@ -2259,38 +2258,51 @@ class Symbol(object):
Prints some information about the symbol (including its name, value,
visibility, and location(s)) when it is evaluated.
"""
- fields = [
- "symbol " + self.name,
- _TYPENAME[self.type],
- 'value "{}"'.format(self.str_value),
- "visibility " + TRI_TO_STR[self.visibility],
- ]
+ fields = []
- if self.user_str_value is not None:
- fields.append('user value "{}"'.format(self.user_str_value))
+ fields.append("symbol " + self.name)
+ fields.append(_TYPENAME[self.type])
- if self.choice is not None:
- fields.append("choice symbol")
+ for node in self.nodes:
+ if node.prompt is not None:
+ fields.append('"{}"'.format(node.prompt[0]))
- if self.is_allnoconfig_y:
- fields.append("allnoconfig_y")
+ fields.append('value "{}"'.format(self.str_value))
- if self is self.config.defconfig_list:
- fields.append("is the defconfig_list symbol")
+ if not self.is_constant:
+ # These aren't helpful to show for constant symbols
- if self.env_var is not None:
- fields.append("from environment variable " + self.env_var)
+ if self.user_str_value is not None:
+ fields.append('user value "{}"'.format(self.user_str_value))
- if self is self.config.modules:
- fields.append("is the modules symbol")
+ fields.append("visibility " + TRI_TO_STR[self.visibility])
- fields.append("direct deps " + TRI_TO_STR[eval_expr(self.direct_dep)])
+ if self.choice is not None:
+ fields.append("choice symbol")
+
+ if self.is_allnoconfig_y:
+ fields.append("allnoconfig_y")
+
+ if self is self.config.defconfig_list:
+ fields.append("is the defconfig_list symbol")
+
+ if self.env_var is not None:
+ fields.append("from environment variable " + self.env_var)
+
+ if self is self.config.modules:
+ fields.append("is the modules symbol")
+
+ fields.append("direct deps " +
+ TRI_TO_STR[expr_value(self.direct_dep)])
if self.nodes:
for node in self.nodes:
fields.append("{}:{}".format(node.filename, node.linenr))
else:
- fields.append("undefined")
+ if self.is_constant:
+ fields.append("constant")
+ else:
+ fields.append("undefined")
return "<{}>".format(", ".join(fields))
@@ -2358,11 +2370,11 @@ class Symbol(object):
if not vis:
return ""
- rev_dep_val = eval_expr(self.rev_dep)
+ rev_dep_val = expr_value(self.rev_dep)
if vis == 2:
if not rev_dep_val:
- if self.type == BOOL or eval_expr(self.weak_rev_dep) == 2:
+ if self.type == BOOL or expr_value(self.weak_rev_dep) == 2:
return "ny"
return "nmy"
@@ -2371,14 +2383,14 @@ class Symbol(object):
# rev_dep_val == 1
- if self.type == BOOL or eval_expr(self.weak_rev_dep) == 2:
+ if self.type == BOOL or expr_value(self.weak_rev_dep) == 2:
return "y"
return "my"
# vis == 1
if not rev_dep_val:
- return "m" if eval_expr(self.weak_rev_dep) != 2 else "y"
+ return "m" if expr_value(self.weak_rev_dep) != 2 else "y"
if rev_dep_val == 2:
return "y"
@@ -2451,10 +2463,14 @@ class Symbol(object):
Invalidates the symbol and all symbols and choices that (possibly
indirectly) depend on it
"""
- self._invalidate()
+ # Constant symbols must never be invalidated, because they lose their
+ # value. They never appear as dependencies, but can still be manually
+ # assigned a user value (and that's OK, though pointless).
+ if not self.is_constant:
+ self._invalidate()
- for item in self._get_dependent():
- item._invalidate()
+ for item in self._get_dependent():
+ item._invalidate()
def _get_dependent(self):
"""
@@ -2708,8 +2724,8 @@ class Choice(object):
"""
See the class documentation.
"""
- for sym, cond_expr in self.defaults:
- if eval_expr(cond_expr) and sym.visibility:
+ for sym, cond in self.defaults:
+ if expr_value(cond) and sym.visibility:
return sym
# Otherwise, pick the first visible symbol, if any
@@ -2761,19 +2777,38 @@ class Choice(object):
"""
TODO
"""
- fields = [
- "choice" if self.name is None else "choice " + self.name,
- _TYPENAME[self.type],
- "mode " + self.str_value,
- "visibility " + TRI_TO_STR[self.visibility],
- ]
+ fields = []
- if self.is_optional:
- fields.append("optional")
+ fields.append("choice" if self.name is None else \
+ "choice " + self.name)
+ fields.append(_TYPENAME[self.type])
+
+ for node in self.nodes:
+ if node.prompt is not None:
+ fields.append('"{}"'.format(node.prompt[0]))
+
+ fields.append("mode " + self.str_value)
+
+ if self.user_str_value is not None:
+ fields.append('user mode {}'.format(self.user_str_value))
if self.selection is not None:
fields.append("{} selected".format(self.selection.name))
+ if self.user_selection is not None:
+ user_sel_str = "{} selected by user" \
+ .format(self.user_selection.name)
+
+ if self.selection is not self.user_selection:
+ user_sel_str += " (overriden)"
+
+ fields.append(user_sel_str)
+
+ fields.append("visibility " + TRI_TO_STR[self.visibility])
+
+ if self.is_optional:
+ fields.append("optional")
+
for node in self.nodes:
fields.append("{}:{}".format(node.filename, node.linenr))
@@ -2932,46 +2967,42 @@ class MenuNode(object):
)
def __repr__(self):
+ """
+ TODO
+ """
fields = []
if isinstance(self.item, Symbol):
fields.append("menu node for symbol " + self.item.name)
-
elif isinstance(self.item, Choice):
s = "menu node for choice"
if self.item.name is not None:
s += " " + self.item.name
fields.append(s)
-
elif self.item == MENU:
fields.append("menu node for menu")
-
elif self.item == COMMENT:
fields.append("menu node for comment")
-
elif self.item is None:
fields.append("menu node for if (should not appear in the final "
" tree)")
-
else:
raise InternalError("unable to determine type in "
"MenuNode.__repr__()")
- fields.append("{}:{}".format(self.filename, self.linenr))
-
if self.prompt is not None:
fields.append('prompt "{}" (visibility {})'
.format(self.prompt[0],
- TRI_TO_STR[eval_expr(self.prompt[1])]))
+ TRI_TO_STR[expr_value(self.prompt[1])]))
if isinstance(self.item, Symbol) and self.is_menuconfig:
fields.append("is menuconfig")
- fields.append("deps " + TRI_TO_STR[eval_expr(self.dep)])
+ fields.append("deps " + TRI_TO_STR[expr_value(self.dep)])
if self.item == MENU:
fields.append("'visible if' deps " + \
- TRI_TO_STR[eval_expr(self.visibility)])
+ TRI_TO_STR[expr_value(self.visibility)])
if isinstance(self.item, (Symbol, Choice)) and self.help is not None:
fields.append("has help")
@@ -2982,6 +3013,8 @@ class MenuNode(object):
if self.next is not None:
fields.append("has next")
+ fields.append("{}:{}".format(self.filename, self.linenr))
+
return "<{}>".format(", ".join(fields))
class KconfigSyntaxError(Exception):
@@ -3000,7 +3033,7 @@ class InternalError(Exception):
# Public functions
#
-def eval_expr(expr):
+def expr_value(expr):
"""
TODO
"""
@@ -3008,18 +3041,18 @@ def eval_expr(expr):
return expr.tri_value
if expr[0] == AND:
- v1 = eval_expr(expr[1])
+ v1 = expr_value(expr[1])
# Short-circuit the n case as an optimization (~5% faster
# allnoconfig.py and allyesconfig.py, as of writing)
- return 0 if not v1 else min(v1, eval_expr(expr[2]))
+ return 0 if not v1 else min(v1, expr_value(expr[2]))
if expr[0] == OR:
- v1 = eval_expr(expr[1])
+ v1 = expr_value(expr[1])
# Short-circuit the y case as an optimization
- return 2 if v1 == 2 else max(v1, eval_expr(expr[2]))
+ return 2 if v1 == 2 else max(v1, expr_value(expr[2]))
if expr[0] == NOT:
- return 2 - eval_expr(expr[1])
+ return 2 - expr_value(expr[1])
if expr[0] in _RELATIONS:
# Implements <, <=, >, >= comparisons as well. These were added to
@@ -3096,7 +3129,7 @@ def _get_visibility(sc):
for node in sc.nodes:
if node.prompt:
- vis = max(vis, eval_expr(node.prompt[1]))
+ vis = max(vis, expr_value(node.prompt[1]))
if isinstance(sc, Symbol) and sc.choice is not None:
if sc.choice._type == TRISTATE and sc._type != TRISTATE and \
diff --git a/testsuite.py b/testsuite.py
index 711a0fb..4af7c19 100644
--- a/testsuite.py
+++ b/testsuite.py
@@ -56,7 +56,7 @@ def fail(msg=None):
global all_passed
all_passed = False
if msg is not None:
- print("Fail: " + msg)
+ print("fail: " + msg)
def verify(cond, msg):
if not cond:
@@ -587,6 +587,18 @@ choice
c = kconfiglib.Config("Kconfiglib/tests/Krepr", warn=False)
+ verify_repr(c.n, """
+<symbol n, tristate, value "n", constant>
+""")
+
+ verify_repr(c.m, """
+<symbol m, tristate, value "m", constant>
+""")
+
+ verify_repr(c.y, """
+<symbol y, tristate, value "y", constant>
+""")
+
verify_repr(c.syms["UNDEFINED"], """
<symbol UNDEFINED, unknown, value "UNDEFINED", visibility n, direct deps n, undefined>
""")
@@ -596,7 +608,13 @@ choice
""")
verify_repr(c.syms["VISIBLE"], """
-<symbol VISIBLE, bool, value "n", visibility y, direct deps y, Kconfiglib/tests/Krepr:14>
+<symbol VISIBLE, bool, "visible", value "n", visibility y, direct deps y, Kconfiglib/tests/Krepr:14>
+""")
+
+ c.syms["VISIBLE"].set_value("y")
+
+ verify_repr(c.syms["VISIBLE"], """
+<symbol VISIBLE, bool, "visible", value "y", user value "y", visibility y, direct deps y, Kconfiglib/tests/Krepr:14>
""")
verify_repr(c.syms["DIR_DEP_N"], """
@@ -612,7 +630,7 @@ choice
""")
verify_repr(c.syms["CHOICE_1"], """
-<symbol CHOICE_1, tristate, value "n", visibility y, choice symbol, direct deps y, Kconfiglib/tests/Krepr:33>
+<symbol CHOICE_1, tristate, "choice sym", value "n", visibility y, choice symbol, direct deps y, Kconfiglib/tests/Krepr:33>
""")
verify_repr(c.modules, """
@@ -623,66 +641,72 @@ choice
print("Testing Choice.__repr__()")
verify_repr(c.named_choices["CHOICE"], """
-<choice CHOICE, tristate, mode m, visibility y, Kconfiglib/tests/Krepr:30>
+<choice CHOICE, tristate, "choice", mode m, visibility y, Kconfiglib/tests/Krepr:30>
""")
c.named_choices["CHOICE"].set_value("y")
verify_repr(c.named_choices["CHOICE"], """
-<choice CHOICE, tristate, mode y, visibility y, CHOICE_1 selected, Kconfiglib/tests/Krepr:30>
+<choice CHOICE, tristate, "choice", mode y, user mode y, CHOICE_1 selected, visibility y, Kconfiglib/tests/Krepr:30>
""")
c.syms["CHOICE_2"].set_value("y")
verify_repr(c.named_choices["CHOICE"], """
-<choice CHOICE, tristate, mode y, visibility y, CHOICE_2 selected, Kconfiglib/tests/Krepr:30>
+<choice CHOICE, tristate, "choice", mode y, user mode y, CHOICE_2 selected, CHOICE_2 selected by user, visibility y, Kconfiglib/tests/Krepr:30>
+""")
+
+ c.syms["CHOICE_1"].set_value("m")
+
+ verify_repr(c.named_choices["CHOICE"], """
+<choice CHOICE, tristate, "choice", mode m, user mode m, CHOICE_2 selected by user (overriden), visibility y, Kconfiglib/tests/Krepr:30>
""")
verify_repr(c.syms["CHOICE_HOOK"].nodes[0].next.item, """
-<choice, tristate, mode n, visibility n, optional, Kconfiglib/tests/Krepr:43>
+<choice, tristate, "optional choice", mode n, visibility n, optional, Kconfiglib/tests/Krepr:43>
""")
print("Testing MenuNode.__repr__()")
verify_repr(c.syms["BASIC"].nodes[0], """
-<menu node for symbol BASIC, Kconfiglib/tests/Krepr:9, deps y, has help, has next>
+<menu node for symbol BASIC, deps y, has help, has next, Kconfiglib/tests/Krepr:9>
""")
verify_repr(c.syms["DIR_DEP_N"].nodes[0], """
-<menu node for symbol DIR_DEP_N, Kconfiglib/tests/Krepr:17, deps n, has next>
+<menu node for symbol DIR_DEP_N, deps n, has next, Kconfiglib/tests/Krepr:17>
""")
verify_repr(c.syms["MULTI_DEF"].nodes[0], """
-<menu node for symbol MULTI_DEF, Kconfiglib/tests/Krepr:25, deps y, has next>
+<menu node for symbol MULTI_DEF, deps y, has next, Kconfiglib/tests/Krepr:25>
""")
verify_repr(c.syms["MULTI_DEF"].nodes[1], """
-<menu node for symbol MULTI_DEF, Kconfiglib/tests/Krepr:26, deps y, has next>
+<menu node for symbol MULTI_DEF, deps y, has next, Kconfiglib/tests/Krepr:26>
""")
verify_repr(c.syms["MENUCONFIG"].nodes[0], """
-<menu node for symbol MENUCONFIG, Kconfiglib/tests/Krepr:28, is menuconfig, deps y, has next>
+<menu node for symbol MENUCONFIG, is menuconfig, deps y, has next, Kconfiglib/tests/Krepr:28>
""")
verify_repr(c.named_choices["CHOICE"].nodes[0], """
-<menu node for choice CHOICE, Kconfiglib/tests/Krepr:30, prompt "choice" (visibility y), deps y, has child, has next>
+<menu node for choice CHOICE, prompt "choice" (visibility y), deps y, has child, has next, Kconfiglib/tests/Krepr:30>
""")
verify_repr(c.syms["CHOICE_HOOK"].nodes[0].next, """
-<menu node for choice, Kconfiglib/tests/Krepr:43, prompt "choice" (visibility n), deps y, has next>
+<menu node for choice, prompt "optional choice" (visibility n), deps y, has next, Kconfiglib/tests/Krepr:43>
""")
verify_repr(c.syms["NO_VISIBLE_IF_HOOK"].nodes[0].next, """
-<menu node for menu, Kconfiglib/tests/Krepr:50, prompt "no visible if" (visibility y), deps y, 'visible if' deps y, has next>
+<menu node for menu, prompt "no visible if" (visibility y), deps y, 'visible if' deps y, has next, Kconfiglib/tests/Krepr:50>
""")
verify_repr(c.syms["VISIBLE_IF_HOOK"].nodes[0].next, """
-<menu node for menu, Kconfiglib/tests/Krepr:55, prompt "visible if" (visibility y), deps y, 'visible if' deps m, has next>
+<menu node for menu, prompt "visible if" (visibility y), deps y, 'visible if' deps m, has next, Kconfiglib/tests/Krepr:55>
""")
verify_repr(c.syms["COMMENT_HOOK"].nodes[0].next, """
-<menu node for comment, Kconfiglib/tests/Krepr:61, prompt "comment" (visibility y), deps y>
+<menu node for comment, prompt "comment" (visibility y), deps y, Kconfiglib/tests/Krepr:61>
""")
@@ -869,14 +893,14 @@ g
def verify_menu_visibility(menu, no_module_vis, module_vis):
c.modules.set_value("n")
- menu_vis = kconfiglib.eval_expr(menu.node.dep)
+ menu_vis = kconfiglib.expr_value(menu.node.dep)
verify(menu_vis == no_module_vis,
"menu \"{}\" should have visibility '{}' without modules, "
"has visibility '{}'"
.format(menu.title, no_module_vis, menu_vis))
c.modules.set_value("y")
- menu_vis = kconfiglib.eval_expr(menu.node.dep)
+ menu_vis = kconfiglib.expr_value(menu.node.dep)
verify(menu_vis == module_vis,
"menu \"{}\" should have visibility '{}' with modules, "
"has visibility '{}'".
@@ -939,14 +963,14 @@ g
def verify_comment_visibility(comment, no_module_vis, module_vis):
c.modules.set_value("n")
# TODO: uninternalize
- comment_vis = kconfiglib.eval_expr(comment.node.dep)
+ comment_vis = kconfiglib.expr_value(comment.node.dep)
verify(comment_vis == no_module_vis,
"comment \"{}\" should have visibility '{}' without "
"modules, has visibility '{}'".
format(comment.text, no_module_vis, comment_vis))
c.modules.set_value("y")
- comment_vis = kconfiglib.eval_expr(comment.node.dep)
+ comment_vis = kconfiglib.expr_value(comment.node.dep)
verify(comment_vis == module_vis,
"comment \"{}\" should have visibility '{}' with "
"modules, has visibility '{}'".
@@ -1731,11 +1755,11 @@ def run_compatibility_tests():
# (generated by the C implementation) should be compared to ._config
# (generated by us) after each invocation.
all_arch_tests = [(test_load, False),
- (test_config_absent, True),
- (test_call_all, False),
+ (test_alldefconfig, True),
+ (test_sanity, False),
(test_all_no, True),
- (test_all_yes, True),
(test_all_no_simpler, True),
+ (test_all_yes, True),
# Needs to report success/failure for each arch/defconfig
# combo, hence False.
(test_defconfig, False)]
@@ -1857,49 +1881,78 @@ def test_all_yes(conf, arch):
else:
shell("make allyesconfig")
-def test_call_all(conf, arch):
+def test_sanity(conf, arch):
"""
- Call all public methods on all symbols, choices, and TODO menu nodes for
- all architectures to make sure we never crash or hang. (Nearly all public
- methods: some are hard to test like this, but are exercised by other
- tests.)
+ Do sanity checks on each configuration and call all public methods on all
+ symbols, choices, and menu nodes for all architectures to make sure we
+ never crash or hang.
"""
print("For {}...".format(arch))
+ conf.modules
+ conf.defconfig_list
conf.defconfig_filename
- conf.mainmenu_text
conf.enable_undef_warnings()
conf.disable_undef_warnings()
- conf.disable_warnings()
conf.enable_warnings()
+ conf.disable_warnings()
+ conf.mainmenu_text
conf.unset_values()
# Python 2/3 compatible
- for _, s in conf.syms.items():
- s.__str__()
- s.__repr__()
- s.assignable
- s.type
- s.str_value
- s.tri_value
- s.visibility
- s.unset_value()
+ for _, sym in conf.syms.items():
+ if sym.name != "UNAME_RELEASE":
+ verify(not sym.is_constant, sym.name + " in 'syms' and constant")
+
+ verify(sym not in conf.const_syms,
+ sym.name + " in both 'syms' and 'const_syms'")
+
+ for dep in sym._direct_dependents:
+ verify(not dep.is_constant,
+ "the constant symbol {} depends on {}"
+ .format(dep.name, sym.name))
+
+ sym.__repr__()
+ sym.__str__()
+ sym.assignable
+ conf.disable_warnings()
+ sym.set_value("y")
+ conf.enable_warnings()
+ sym.str_value
+ sym.tri_value
+ sym.type
+ sym.unset_value()
+ sym.user_str_value
+ sym.user_tri_value
+ sym.visibility
+
+ for sym in conf.defined_syms:
+ verify(sym.nodes, sym.name + " is defined but lacks menu nodes")
+
+ for _, sym in conf.const_syms.items():
+ verify(sym.is_constant,
+ '"{}" is in const_syms but not marked constant'
+ .format(sym.name))
- # TODO: verify that constant symbols do not:
- # 1) have a non-empty dep
- # 2) have nodes
+ verify(not sym.nodes,
+ '"{}" is constant but has menu nodes'
+ .format(sym.name))
- # TODO: Look for weird stuff in the dictionaries
+ verify(not sym._direct_dependents,
+ '"{}" is constant but is a dependency of some symbol'
+ .format(sym.name))
- # TODO: infinite recursion action
- #for _, s in conf.const_syms.items():
- # s.__str__()
- # s.__repr__()
- # s.assignable
- # s.type
- # s.value
- # s.visibility
- # s.unset_value()
+ sym.__repr__()
+ sym.__str__()
+ sym.assignable
+ conf.disable_warnings()
+ sym.set_value("y")
+ conf.enable_warnings()
+ sym.str_value
+ sym.tri_value
+ sym.type
+ sym.unset_value()
+ sym.visibility
# Cheat with internals
for c in conf._choices:
@@ -1907,13 +1960,38 @@ def test_call_all(conf, arch):
c.__repr__()
c.str_value
c.tri_value
+ c.user_str_value
+ c.user_tri_value
c.assignable
c.selection
c.default_selection
c.type
c.visibility
-def test_config_absent(conf, arch):
+ # Menu nodes
+
+ node = conf.top_node
+
+ while 1:
+ # Everything else should be well exercised elsewhere
+ node.__repr__()
+
+ if node.list is not None:
+ node = node.list
+
+ elif node.next is not None:
+ node = node.next
+
+ else:
+ while node.parent is not None:
+ node = node.parent
+ if node.next is not None:
+ node = node.next
+ break
+ else:
+ break
+
+def test_alldefconfig(conf, arch):
"""
Verify that Kconfiglib generates the same .config as 'make alldefconfig',
for each architecture