summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/find_symbol.py10
-rwxr-xr-xguiconfig.py2
-rw-r--r--kconfiglib.py95
-rwxr-xr-xmenuconfig.py2
-rw-r--r--tests/Kstr37
-rw-r--r--testsuite.py121
6 files changed, 209 insertions, 58 deletions
diff --git a/examples/find_symbol.py b/examples/find_symbol.py
index 132d45f..f747103 100644
--- a/examples/find_symbol.py
+++ b/examples/find_symbol.py
@@ -42,8 +42,8 @@
#
# config OPROFILE_EVENT_MULTIPLEX
# bool
-# prompt "OProfile multiplexing support (EXPERIMENTAL)" if OPROFILE && X86
-# default "n" if OPROFILE && X86
+# prompt "OProfile multiplexing support (EXPERIMENTAL)"
+# default "n"
# depends on OPROFILE && X86
# help
# The number of hardware counters is limited. The multiplexing
@@ -57,9 +57,9 @@
#
# config OPROFILE
# tristate
-# prompt "OProfile system profiling" if PROFILING && HAVE_OPROFILE
-# select RING_BUFFER if PROFILING && HAVE_OPROFILE
-# select RING_BUFFER_ALLOW_SWAP if PROFILING && HAVE_OPROFILE
+# prompt "OProfile system profiling"
+# select RING_BUFFER
+# select RING_BUFFER_ALLOW_SWAP
# depends on PROFILING && HAVE_OPROFILE
# help
# OProfile is a profiling system capable of profiling the
diff --git a/guiconfig.py b/guiconfig.py
index c709c4e..9563ab4 100755
--- a/guiconfig.py
+++ b/guiconfig.py
@@ -2222,7 +2222,7 @@ def _kconfig_def_info(item):
nodes = [item] if isinstance(item, MenuNode) else item.nodes
- s = "Kconfig definition{}, with propagated dependencies\n" \
+ s = "Kconfig definition{}, with parent deps. propagated to 'depends on'\n" \
.format("s" if len(nodes) > 1 else "")
s += (len(s) - 1)*"="
diff --git a/kconfiglib.py b/kconfiglib.py
index 2725787..8112e11 100644
--- a/kconfiglib.py
+++ b/kconfiglib.py
@@ -4378,8 +4378,9 @@ class Symbol(object):
def __str__(self):
"""
- Returns a string representation of the symbol when it is printed,
- matching the Kconfig format, with parent dependencies propagated.
+ Returns a string representation of the symbol when it is printed.
+ Matches the Kconfig format, with any parent dependencies propagated to
+ the 'depends on' condition.
The string is constructed by joining the strings returned by
MenuNode.__str__() for each of the symbol's menu nodes, so symbols
@@ -4954,9 +4955,10 @@ class Choice(object):
def __str__(self):
"""
- Returns a string representation of the choice when it is printed,
- matching the Kconfig format (though without the contained choice
- symbols).
+ Returns a string representation of the choice when it is printed.
+ Matches the Kconfig format (though without the contained choice
+ symbols), with any parent dependencies propagated to the 'depends on'
+ condition.
The returned string does not end in a newline.
@@ -5135,6 +5137,18 @@ class MenuNode(object):
ranges:
Like MenuNode.defaults, for ranges.
+ orig_prompt:
+ orig_defaults:
+ orig_selects:
+ orig_implies:
+ orig_ranges:
+ These work the like the corresponding attributes without orig_*, but omit
+ any dependencies propagated from 'depends on' and surrounding 'if's (the
+ direct dependencies, stored in MenuNode.dep).
+
+ One use for this is generating less cluttered documentation, by only
+ showing the direct dependencies in one place.
+
help:
The help text for the menu node for Symbols and Choices. None if there is
no help text. Always stored in the node rather than the Symbol or Choice.
@@ -5234,6 +5248,47 @@ class MenuNode(object):
self.ranges = []
@property
+ def orig_prompt(self):
+ """
+ See the class documentation.
+ """
+ if not self.prompt:
+ return None
+ return (self.prompt[0], self._strip_dep(self.prompt[1]))
+
+ @property
+ def orig_defaults(self):
+ """
+ See the class documentation.
+ """
+ return [(default, self._strip_dep(cond))
+ for default, cond in self.defaults]
+
+ @property
+ def orig_selects(self):
+ """
+ See the class documentation.
+ """
+ return [(select, self._strip_dep(cond))
+ for select, cond in self.selects]
+
+ @property
+ def orig_implies(self):
+ """
+ See the class documentation.
+ """
+ return [(imply, self._strip_dep(cond))
+ for imply, cond in self.implies]
+
+ @property
+ def orig_ranges(self):
+ """
+ See the class documentation.
+ """
+ return [(low, high, self._strip_dep(cond))
+ for low, high, cond in self.ranges]
+
+ @property
def referenced(self):
"""
See the class documentation.
@@ -5318,8 +5373,9 @@ class MenuNode(object):
def __str__(self):
"""
- Returns a string representation of the menu node, matching the Kconfig
- format.
+ Returns a string representation of the menu node. Matches the Kconfig
+ format, with any parent dependencies propagated to the 'depends on'
+ condition.
The output could (almost) be fed back into a Kconfig parser to redefine
the object associated with the menu node. See the module documentation
@@ -5379,7 +5435,7 @@ class MenuNode(object):
if self.prompt:
indent_add_cond(
'prompt "{}"'.format(escape(self.prompt[0])),
- self.prompt[1])
+ self.orig_prompt[1])
if sc.__class__ is Symbol:
if sc.is_allnoconfig_y:
@@ -5394,13 +5450,13 @@ class MenuNode(object):
if sc is sc.kconfig.modules:
indent_add("option modules")
- for low, high, cond in self.ranges:
+ for low, high, cond in self.orig_ranges:
indent_add_cond(
"range {} {}".format(sc_expr_str_fn(low),
sc_expr_str_fn(high)),
cond)
- for default, cond in self.defaults:
+ for default, cond in self.orig_defaults:
indent_add_cond("default " + expr_str(default, sc_expr_str_fn),
cond)
@@ -5408,10 +5464,10 @@ class MenuNode(object):
indent_add("optional")
if sc.__class__ is Symbol:
- for select, cond in self.selects:
+ for select, cond in self.orig_selects:
indent_add_cond("select " + sc_expr_str_fn(select), cond)
- for imply, cond in self.implies:
+ for imply, cond in self.orig_implies:
indent_add_cond("imply " + sc_expr_str_fn(imply), cond)
if self.dep is not sc.kconfig.y:
@@ -5424,6 +5480,21 @@ class MenuNode(object):
return "\n".join(lines)
+ def _strip_dep(self, expr):
+ # Helper function for removing MenuNode.dep from 'expr'. Uses two
+ # pieces of internal knowledge: (1) Expressions are reused rather than
+ # copied, and (2) the direct dependencies always appear at the end.
+
+ # ... if dep -> ... if y
+ if self.dep is expr:
+ return self.kconfig.y
+
+ # (AND, X, dep) -> X
+ if expr.__class__ is tuple and expr[0] is AND and expr[2] is self.dep:
+ return expr[1]
+
+ return expr
+
class Variable(object):
"""
diff --git a/menuconfig.py b/menuconfig.py
index 8ecf611..3dbee95 100755
--- a/menuconfig.py
+++ b/menuconfig.py
@@ -2739,7 +2739,7 @@ def _kconfig_def_info(item):
nodes = [item] if isinstance(item, MenuNode) else item.nodes
- s = "Kconfig definition{}, with propagated dependencies\n" \
+ s = "Kconfig definition{}, with parent deps. propagated to 'depends on'\n" \
.format("s" if len(nodes) > 1 else "")
s += (len(s) - 1)*"="
diff --git a/tests/Kstr b/tests/Kstr
index 58d25e6..07d7b8d 100644
--- a/tests/Kstr
+++ b/tests/Kstr
@@ -201,3 +201,40 @@ config ADVANCED_COMMENT_HOOK
comment "advanced comment"
depends on A
depends on B
+
+# Corner cases when removing direct dependencies
+
+config DEP_REM_CORNER_CASES
+ bool
+ default A
+ depends on n
+
+config DEP_REM_CORNER_CASES
+ default B if n
+
+config DEP_REM_CORNER_CASES
+ default C
+ depends on m
+
+config DEP_REM_CORNER_CASES
+ default D if A && y
+ depends on y
+
+config DEP_REM_CORNER_CASES
+ default E if !E1
+ default F if F1 = F2
+ default G if G1 || H1
+ depends on !H
+
+config DEP_REM_CORNER_CASES
+ default H
+ depends on "foo" = "bar"
+
+menu "menu"
+ visible if FOO || BAR
+
+config DEP_REM_CORNER_CASES
+ prompt "prompt"
+ depends on BAZ && QAZ
+
+endmenu
diff --git a/testsuite.py b/testsuite.py
index c1690d3..f3f2b42 100644
--- a/testsuite.py
+++ b/testsuite.py
@@ -557,7 +557,7 @@ config ADVANCED
config ADVANCED
tristate
- prompt "prompt 4" if VIS && DEP4 && DEP3
+ prompt "prompt 4" if VIS
depends on DEP4 && DEP3
""")
@@ -590,7 +590,7 @@ config ADVANCED
config ADVANCED
tristate
- prompt "prompt 4" if [VIS] && [DEP4] && [DEP3]
+ prompt "prompt 4" if [VIS]
depends on [DEP4] && [DEP3]
""")
@@ -645,39 +645,39 @@ config OPTIONS
verify_str(c.syms["CORRECT_PROP_LOCS_BOOL"], """
config CORRECT_PROP_LOCS_BOOL
bool
- prompt "prompt 1" if LOC_1
- default DEFAULT_1 if LOC_1
- default DEFAULT_2 if LOC_1
- select SELECT_1 if LOC_1
- select SELECT_2 if LOC_1
- imply IMPLY_1 if LOC_1
- imply IMPLY_2 if LOC_1
+ prompt "prompt 1"
+ default DEFAULT_1
+ default DEFAULT_2
+ select SELECT_1
+ select SELECT_2
+ imply IMPLY_1
+ imply IMPLY_2
depends on LOC_1
help
help 1
menuconfig CORRECT_PROP_LOCS_BOOL
bool
- prompt "prompt 2" if LOC_2
- default DEFAULT_3 if LOC_2
- default DEFAULT_4 if LOC_2
- select SELECT_3 if LOC_2
- select SELECT_4 if LOC_2
- imply IMPLY_3 if LOC_2
- imply IMPLY_4 if LOC_2
+ prompt "prompt 2"
+ default DEFAULT_3
+ default DEFAULT_4
+ select SELECT_3
+ select SELECT_4
+ imply IMPLY_3
+ imply IMPLY_4
depends on LOC_2
help
help 2
config CORRECT_PROP_LOCS_BOOL
bool
- prompt "prompt 3" if LOC_3
- default DEFAULT_5 if LOC_3
- default DEFAULT_6 if LOC_3
- select SELECT_5 if LOC_3
- select SELECT_6 if LOC_3
- imply IMPLY_5 if LOC_3
- imply IMPLY_6 if LOC_3
+ prompt "prompt 3"
+ default DEFAULT_5
+ default DEFAULT_6
+ select SELECT_5
+ select SELECT_6
+ imply IMPLY_5
+ imply IMPLY_6
depends on LOC_3
help
help 2
@@ -686,28 +686,28 @@ config CORRECT_PROP_LOCS_BOOL
verify_str(c.syms["CORRECT_PROP_LOCS_INT"], """
config CORRECT_PROP_LOCS_INT
int
- range 1 2 if LOC_1
- range 3 4 if LOC_1
+ range 1 2
+ range 3 4
depends on LOC_1
config CORRECT_PROP_LOCS_INT
int
- range 5 6 if LOC_2
- range 7 8 if LOC_2
+ range 5 6
+ range 7 8
depends on LOC_2
""")
verify_custom_str(c.syms["CORRECT_PROP_LOCS_INT"], """
config CORRECT_PROP_LOCS_INT
int
- range [1] [2] if [LOC_1]
- range [3] [4] if [LOC_1]
+ range [1] [2]
+ range [3] [4]
depends on [LOC_1]
config CORRECT_PROP_LOCS_INT
int
- range [5] [6] if [LOC_2]
- range [7] [8] if [LOC_2]
+ range [5] [6]
+ range [7] [8]
depends on [LOC_2]
""")
@@ -733,34 +733,34 @@ choice
verify_str(c.named_choices["CORRECT_PROP_LOCS_CHOICE"], """
choice CORRECT_PROP_LOCS_CHOICE
bool
- default CHOICE_3 if LOC_1
+ default CHOICE_3
depends on LOC_1
choice CORRECT_PROP_LOCS_CHOICE
bool
- default CHOICE_4 if LOC_2
+ default CHOICE_4
depends on LOC_2
choice CORRECT_PROP_LOCS_CHOICE
bool
- default CHOICE_5 if LOC_3
+ default CHOICE_5
depends on LOC_3
""")
verify_custom_str(c.named_choices["CORRECT_PROP_LOCS_CHOICE"], """
choice CORRECT_PROP_LOCS_CHOICE
bool
- default [CHOICE_3] if [LOC_1]
+ default [CHOICE_3]
depends on [LOC_1]
choice CORRECT_PROP_LOCS_CHOICE
bool
- default [CHOICE_4] if [LOC_2]
+ default [CHOICE_4]
depends on [LOC_2]
choice CORRECT_PROP_LOCS_CHOICE
bool
- default [CHOICE_5] if [LOC_3]
+ default [CHOICE_5]
depends on [LOC_3]
""")
@@ -798,6 +798,49 @@ comment "advanced comment"
""")
+ print("Testing MenuNode.orig_*")
+
+ # Just test some corner cases here. These are already tested above. Use
+ # MenuNode.__str__() as a proxy.
+
+ verify_str(c.syms["DEP_REM_CORNER_CASES"], """
+config DEP_REM_CORNER_CASES
+ bool
+ default A
+ depends on "n"
+
+config DEP_REM_CORNER_CASES
+ bool
+ default B if "n"
+
+config DEP_REM_CORNER_CASES
+ bool
+ default C
+ depends on "m" && MODULES
+
+config DEP_REM_CORNER_CASES
+ bool
+ default D if A
+
+config DEP_REM_CORNER_CASES
+ bool
+ default E if !E1
+ default F if F1 = F2
+ default G if G1 || H1
+ depends on !H
+
+config DEP_REM_CORNER_CASES
+ bool
+ default H
+ depends on "foo" = "bar"
+
+config DEP_REM_CORNER_CASES
+ bool
+ prompt "prompt" if FOO || BAR
+ depends on BAZ && QAZ
+""")
+
+
print("Testing Symbol.__repr__()")
def verify_repr(item, s):
@@ -2349,14 +2392,14 @@ config G
config H
bool
- prompt "H" if I && <choice>
+ prompt "H"
depends on I && <choice>
...depends on the choice symbol I (defined at Kconfiglib/tests/Kdeploop10:41), with definition...
config I
bool
- prompt "I" if <choice>
+ prompt "I"
depends on <choice>
...depends on <choice> (defined at Kconfiglib/tests/Kdeploop10:38), with definition...