From f66cd7155158943987570937be37b09d9ca58028 Mon Sep 17 00:00:00 2001 From: Ulf Magnusson Date: Wed, 7 Feb 2018 02:30:16 +0100 Subject: Allow "n"/"m"/"y" as aliases for 0/1/2 in set_value() More experience working with the API convinced me that it's worth it. Gets rid of ugly conversions in the menuconfig.py and oldconfig.py examples, and streamlines some things internally as well. Include two other small fixes as well: - Make warnings generated by Choice.set_value() match those generated by Symbol.set_value(). - Get rid of the input stripping in menuconfig.py. It's not like the interface is usable as-is anyway, and it just complicates the example. --- examples/menuconfig.py | 14 +-------- examples/oldconfig.py | 8 +---- kconfiglib.py | 84 ++++++++++++++++++++++++++++---------------------- 3 files changed, 49 insertions(+), 57 deletions(-) diff --git a/examples/menuconfig.py b/examples/menuconfig.py index b55af6d..753ac40 100644 --- a/examples/menuconfig.py +++ b/examples/menuconfig.py @@ -258,19 +258,7 @@ def get_value_from_user(sc): .format(", ".join([TRI_TO_STR[val] for val in sc.assignable])) prompt += ": " - val_str = input(prompt).strip() - if sc.type in (BOOL, TRISTATE): - if val_str not in STR_TO_TRI: - print("'{}' is not a valid tristate value".format(val_str)) - return False - - # I was thinking of having set_value() accept "n", "m", "y" as well as - # a convenience for BOOL / TRISTATE symbols. Consistently using 0, 1, 2 - # makes the format clearer though. That's the best format in all ways - # except for readability (where it isn't horrible either). - val = STR_TO_TRI[val_str] - else: - val = val_str + val = input(prompt) # Automatically add a "0x" prefix for hex symbols, like the menuconfig # interface does. This isn't done when loading .config files, hence why diff --git a/examples/oldconfig.py b/examples/oldconfig.py index 3550cec..aa8e253 100644 --- a/examples/oldconfig.py +++ b/examples/oldconfig.py @@ -98,7 +98,7 @@ # $ python oldconfig.py Kconfig # Everything's already up to date # Configuration written to .config from __future__ import print_function -from kconfiglib import Kconfig, Symbol, Choice, BOOL, TRISTATE, HEX, STR_TO_TRI +from kconfiglib import Kconfig, Symbol, Choice, BOOL, TRISTATE, HEX import os import sys @@ -202,12 +202,6 @@ def do_oldconfig_for_node(node): if not val: val = sym.str_value - if sym.type in (BOOL, TRISTATE): - if val not in STR_TO_TRI: - eprint("Invalid tristate value") - continue - val = STR_TO_TRI[val] - # Automatically add a "0x" prefix for hex symbols, like the # menuconfig interface does. This isn't done when loading .config # files, hence why set_value() doesn't do it automatically. diff --git a/kconfiglib.py b/kconfiglib.py index c7c34bc..e246055 100644 --- a/kconfiglib.py +++ b/kconfiglib.py @@ -704,16 +704,17 @@ class Kconfig(object): _name_and_loc_str(sym))) continue - # We represent tristate values as 0, 1, 2 - val = STR_TO_TRI[val[0]] + val = val[0] - if sym.choice and val: + if sym.choice and val != "n": # During .config loading, we infer the mode of the # choice from the kind of values that are assigned # to the choice symbols prev_mode = sym.choice.user_value - if prev_mode is not None and prev_mode != val: + if prev_mode is not None and \ + TRI_TO_STR[prev_mode] != val: + self._warn("both m and y assigned to symbols " "within the same choice", filename, linenr) @@ -747,24 +748,22 @@ class Kconfig(object): if sym.orig_type not in (BOOL, TRISTATE): continue - val = 0 + val = "n" # Done parsing the assignment. Set the value. if sym._was_set: - # Use strings for tristate values in the warning + # Use strings for bool/tristate user values in the warning if sym.orig_type in (BOOL, TRISTATE): - display_val = TRI_TO_STR[val] display_user_val = TRI_TO_STR[sym.user_value] else: - display_val = val display_user_val = sym.user_value warn_msg = '{} set more than once. Old value: "{}", new value: "{}".'.format( - _name_and_loc_str(sym), display_user_val, display_val + _name_and_loc_str(sym), display_user_val, val ) - if display_user_val == display_val: + if display_user_val == val: self._warn_redun_assign(warn_msg, filename, linenr) else: self._warn( warn_msg, filename, linenr) @@ -2712,13 +2711,14 @@ class Symbol(object): value: The user value to give to the symbol. For bool and tristate symbols, - pass 0, 1, 2 for n, m, and y, respectively. For other symbol types, - pass a string. + n/m/y can be specified either as 0/1/2 (the usual format for tristate + values in Kconfiglib) or as one of the strings "n"/"m"/"y". For other + symbol types, pass a string. Values that are invalid for the type (such as "foo" or 1 (m) for a - BOOL) are ignored and won't be stored in Symbol.user_value. - Kconfiglib will print a warning by default for invalid assignments, - and set_value() will return False. + BOOL or "0x123" for an INT) are ignored and won't be stored in + Symbol.user_value. Kconfiglib will print a warning by default for + invalid assignments, and set_value() will return False. Returns True if the value is valid for the type of the symbol, and False otherwise. This only looks at the form of the value. For BOOL and @@ -2734,27 +2734,23 @@ class Symbol(object): return True # Check if the value is valid for our type - if not ((self.orig_type == BOOL and value in (0, 2) ) or - (self.orig_type == TRISTATE and value in (0, 1, 2) ) or - (self.orig_type == STRING and isinstance(value, str)) or + if not ((self.orig_type == BOOL and value in (0, 2, "n", "y") ) or + (self.orig_type == TRISTATE and value in (0, 1, 2, "n", "m", "y")) or + (self.orig_type == STRING and isinstance(value, str) ) or (self.orig_type == INT and isinstance(value, str) - and _is_base_n(value, 10) ) or + and _is_base_n(value, 10) ) or (self.orig_type == HEX and isinstance(value, str) and _is_base_n(value, 16) and int(value, 16) >= 0)): # Display tristate values as n, m, y in the warning - warning = "the value {} is invalid for {}, which has type {}. " \ - "Assignment ignored." \ - .format(TRI_TO_STR[value] if value in (0, 1, 2) else - "'{}'".format(value), - _name_and_loc_str(self), - TYPE_TO_STR[self.orig_type]) - - if self.orig_type in (BOOL, TRISTATE) and value in ("n", "m", "y"): - warning += " Pass 0, 1, 2 for n, m, y, respectively." - - self.kconfig._warn(warning) + self.kconfig._warn( + "the value {} is invalid for {}, which has type {} -- " + "assignment ignored" + .format(TRI_TO_STR[value] if value in (0, 1, 2) else + "'{}'".format(value), + _name_and_loc_str(self), + TYPE_TO_STR[self.orig_type])) return False @@ -2764,6 +2760,9 @@ class Symbol(object): .format(_name_and_loc_str(self))) return False + if self.orig_type in (BOOL, TRISTATE) and value in ("n", "m", "y"): + value = STR_TO_TRI[value] + if self.choice and value == 2: # Remember this as a choice selection only. Makes switching back # and forth between choice modes work as expected, and makes the @@ -3306,8 +3305,9 @@ class Choice(object): """ Sets the user value (mode) of the choice. Like for Symbol.set_value(), the visibility might truncate the value. Choices without the 'optional' - attribute (is_optional) can never be in n mode, but 0 is still accepted - since it's not a malformed value (though it will have no effect). + attribute (is_optional) can never be in n mode, but 0/"n" is still + accepted since it's not a malformed value (though it will have no + effect). Returns True if the value is valid for the type of the choice, and False otherwise. This only looks at the form of the value. Check the @@ -3320,13 +3320,23 @@ class Choice(object): self._was_set = True return True - if not ((self.orig_type == BOOL and value in (0, 2) ) or - (self.orig_type == TRISTATE and value in (0, 1, 2))): - self.kconfig._warn("the value '{}' is invalid for the choice, " - "which has type {}. Assignment ignored" - .format(value, TYPE_TO_STR[self.orig_type])) + if not ((self.orig_type == BOOL and value in (0, 2, "n", "y") ) or + (self.orig_type == TRISTATE and value in (0, 1, 2, "n", "m", "y"))): + + # Display tristate values as n, m, y in the warning + self.kconfig._warn( + "the value {} is invalid for {}, which has type {} -- " + "assignment ignored" + .format(TRI_TO_STR[value] if value in (0, 1, 2) else + "'{}'".format(value), + _name_and_loc_str(self), + TYPE_TO_STR[self.orig_type])) + return False + if value in ("n", "m", "y"): + value = STR_TO_TRI[value] + self.user_value = value self._was_set = True self._rec_invalidate() -- cgit v1.2.3