summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlf Magnusson <ulfalizer@gmail.com>2018-08-21 20:55:29 +0200
committerUlf Magnusson <ulfalizer@gmail.com>2018-08-21 21:17:45 +0200
commita3252f620fad970bbe8b7470401a04ee4225193e (patch)
tree5860f52ec628dfc72ba8a4a1dea898270a991e4d
parent67e890cc9d926213fbec93afb3ee14e6c24f9a50 (diff)
Merge Symbol._checked and Symbol._written
These are never used at the same time, and Symbol._visited is a good name for both. Gets rid of an internal attribute.
-rw-r--r--kconfiglib.py67
-rw-r--r--testsuite.py15
2 files changed, 43 insertions, 39 deletions
diff --git a/kconfiglib.py b/kconfiglib.py
index b46ed3e..6f74be6 100644
--- a/kconfiglib.py
+++ b/kconfiglib.py
@@ -1079,18 +1079,22 @@ class Kconfig(object):
with self._open(filename, "w") as f:
f.write(header)
- # Symbol._written is set to True when a symbol config string is
- # fetched, so that symbols defined in multiple locations only get
- # one .config entry. We reset it prior to writing out a new
- # .config. It only needs to be reset for defined symbols, because
- # undefined symbols will never be written out (because they do not
- # appear in the menu tree rooted at Kconfig.top_node).
+ # Symbol._visited is set to True when we visit a symbol, so that
+ # symbols defined in multiple locations only get one .config entry.
+ # We reset it prior to writing out a new .config. It only needs to
+ # be reset for defined symbols, because undefined symbols will
+ # never be written out (because they do not appear in the menu tree
+ # rooted at Kconfig.top_node).
#
# The C tools reuse _write_to_conf for this, but we cache
# _write_to_conf together with the value and don't invalidate
# cached values when writing .config files, so that won't work.
+ #
+ # Note: The usage of _visited here is completely independent from
+ # the usage during dependency loop detection (which runs at the end
+ # of parsing). The attribute is just reused.
for sym in self._unique_def_syms:
- sym._written = False
+ sym._visited = False
# The 'top_node' menu node itself doesn't generate any output, so
# it's skipped over below
@@ -1115,8 +1119,8 @@ class Kconfig(object):
item = node.item
if isinstance(item, Symbol):
- if not item._written:
- item._written = True
+ if not item._visited:
+ item._visited = True
f.write(item.config_string)
elif expr_value(node.dep) and \
@@ -3286,12 +3290,11 @@ class Symbol(object):
"_cached_str_val",
"_cached_tri_val",
"_cached_vis",
- "_checked",
"_dependents",
"_old_val",
+ "_visited",
"_was_set",
"_write_to_conf",
- "_written",
"choice",
"defaults",
"direct_dep",
@@ -3803,7 +3806,6 @@ class Symbol(object):
"""
# These attributes are always set on the instance from outside and
# don't need defaults:
- # _written
# kconfig
# direct_dep
# is_constant
@@ -3835,8 +3837,9 @@ class Symbol(object):
# See Kconfig._build_dep()
self._dependents = set()
- # Used during dependency loop detection
- self._checked = 0
+ # Used during dependency loop detection and (independently) in
+ # write_config()
+ self._visited = 0
def _assignable(self):
# Worker function for the 'assignable' attribute
@@ -4163,8 +4166,8 @@ class Choice(object):
"_cached_assignable",
"_cached_selection",
"_cached_vis",
- "_checked",
"_dependents",
+ "_visited",
"_was_set",
"defaults",
"direct_dep",
@@ -4405,7 +4408,7 @@ class Choice(object):
self._dependents = set()
# Used during dependency loop detection
- self._checked = 0
+ self._visited = 0
def _assignable(self):
# Worker function for the 'assignable' attribute
@@ -5365,20 +5368,20 @@ def _check_dep_loop_sym(sym, ignore_choice):
#
# Algorithm:
#
- # 1. Symbols/choices start out with _checked = 0, meaning unvisited.
+ # 1. Symbols/choices start out with _visited = 0, meaning unvisited.
#
- # 2. When a symbol/choice is first visited, _checked is set to 1, meaning
+ # 2. When a symbol/choice is first visited, _visited is set to 1, meaning
# "visited, potentially part of a dependency loop". The recursive
# search then continues from the symbol/choice.
#
- # 3. If we run into a symbol/choice X with _checked already set to 1,
+ # 3. If we run into a symbol/choice X with _visited already set to 1,
# there's a dependency loop. The loop is found on the call stack by
# recording symbols while returning ("on the way back") until X is seen
# again.
#
# 4. Once a symbol/choice and all its dependencies (or dependents in this
# case) have been checked recursively without detecting any loops, its
- # _checked is set to 2, meaning "visited, not part of a dependency
+ # _visited is set to 2, meaning "visited, not part of a dependency
# loop".
#
# This saves work if we run into the symbol/choice again in later calls
@@ -5392,10 +5395,10 @@ def _check_dep_loop_sym(sym, ignore_choice):
# Maybe there's a better way to handle this (different flags or the
# like...)
- if not sym._checked:
- # sym._checked == 0, unvisited
+ if not sym._visited:
+ # sym._visited == 0, unvisited
- sym._checked = 1
+ sym._visited = 1
for dep in sym._dependents:
# Choices show up in Symbol._dependents when the choice has the
@@ -5419,25 +5422,25 @@ def _check_dep_loop_sym(sym, ignore_choice):
return _found_dep_loop(loop, sym)
# The symbol is not part of a dependency loop
- sym._checked = 2
+ sym._visited = 2
# No dependency loop found
return None
- if sym._checked == 2:
+ if sym._visited == 2:
# The symbol was checked earlier and is already known to not be part of
# a dependency loop
return None
- # sym._checked == 1, found a dependency loop. Return the symbol as the
+ # sym._visited == 1, found a dependency loop. Return the symbol as the
# first element in it.
return (sym,)
def _check_dep_loop_choice(choice, skip):
- if not choice._checked:
- # choice._checked == 0, unvisited
+ if not choice._visited:
+ # choice._visited == 0, unvisited
- choice._checked = 1
+ choice._visited = 1
# Check for loops involving choice symbols. If we came here via a
# choice symbol, skip that one, as we'd get a false positive
@@ -5452,17 +5455,17 @@ def _check_dep_loop_choice(choice, skip):
return _found_dep_loop(loop, choice)
# The choice is not part of a dependency loop
- choice._checked = 2
+ choice._visited = 2
# No dependency loop found
return None
- if choice._checked == 2:
+ if choice._visited == 2:
# The choice was checked earlier and is already known to not be part of
# a dependency loop
return None
- # choice._checked == 1, found a dependency loop. Return the choice as the
+ # choice._visited == 1, found a dependency loop. Return the choice as the
# first element in it.
return (choice,)
diff --git a/testsuite.py b/testsuite.py
index 7f1ccfe..eef8389 100644
--- a/testsuite.py
+++ b/testsuite.py
@@ -2461,6 +2461,11 @@ def test_sanity(arch, srcarch):
kconf = Kconfig()
+ for sym in kconf.defined_syms:
+ verify(sym._visited == 2,
+ "{} has broken dependency loop detection (_visited = {})"
+ .format(sym.name, sym._visited))
+
kconf.modules
kconf.defconfig_list
kconf.defconfig_filename
@@ -2512,14 +2517,10 @@ def test_sanity(arch, srcarch):
sym.visibility
for sym in kconf.defined_syms:
- verify(sym.nodes, sym.name + " is defined but lacks menu nodes")
-
- verify(not (sym.orig_type not in (BOOL, TRISTATE) and sym.choice),
- sym.name + " is a choice symbol but not bool/tristate")
+ verify(sym.nodes, sym.name + " is defined but lacks menu nodes")
- verify(sym._checked == 2,
- "{} has broken dependency loop detection (_checked = {})"
- .format(sym.name, sym._checked))
+ verify(not (sym.orig_type not in (BOOL, TRISTATE) and sym.choice),
+ sym.name + " is a choice symbol but not bool/tristate")
for key, sym in kconf.const_syms.items():
verify(isinstance(key, str),