From bb33eed5cc6bdce2b65aa570ecd9a400bcd9c180 Mon Sep 17 00:00:00 2001 From: Ulf Magnusson Date: Sat, 25 May 2019 13:52:09 +0200 Subject: Strip direct deps. from property conditions in Symbol/Choice/MenuNode.__str__() Commit e81a77b ("Consistently put direct deps. last when propagating") makes the position of the direct deps. in property conditions predictable after dependency propagation, making it easy to strip them as needed. Use this to implement MenuNode.orig_{prompt,defaults,selects,implies,ranges}, which work like the non-orig_* versions but omit the direct deps. Use those in turn to omit the direct deps in Symbol/Choice.__str__(). The direct deps. (with propagated parent deps.) can still be seen after 'depends on ...', so there is no loss of information. This unclutters Kconfig definitions shown in menuconfig/guiconfig and in any generated documentation. The old output also had duplicated dependencies, though it doesn't matter for evaluation. Before: config A bool prompt "A" if DEP default y if FOO && DEP depends on DEP After: config A bool prompt "A" default y if FOO depends on DEP --- kconfiglib.py | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 83 insertions(+), 12 deletions(-) (limited to 'kconfiglib.py') 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. @@ -5233,6 +5247,47 @@ class MenuNode(object): self.implies = [] 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): """ @@ -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): """ -- cgit v1.2.3