@@ -338,10 +338,27 @@ void sym_calc_value(struct symbol *sym)
switch (sym_get_type(sym)) {
case S_BOOLEAN:
- case S_TRISTATE:
- if (sym_is_choice_value(sym) && sym->visible == yes) {
- prop = sym_get_choice_prop(sym);
- newval.tri = (prop_get_symbol(prop)->curr.val == sym) ? yes : no;
+ case S_TRISTATE: {
+ struct symbol *choice_sym = NULL;
+
+ if (sym_is_choice_value(sym))
+ choice_sym = prop_get_symbol(sym_get_choice_prop(sym));
+
+ /*
+ * If this is a visible choice_value we want to check
+ * if it is the currently selected, in two cases:
+ *
+ * 1) If it's visibility is 'yes'.
+ * 2) If it's visibility is 'mod' and the correspondig
+ * choice symbols' value is 'yes'.
+ *
+ * If a choice symbol is 'yes', only the selected
+ * choice_value may be 'yes' and all others (also
+ * those currently set to 'mod') must be set to 'no'.
+ */
+ if (choice_sym &&
+ (sym->visible == yes || (sym->visible == mod && choice_sym->curr.tri == yes))) {
+ newval.tri = choice_sym->curr.val == sym ? yes : no;
} else {
if (sym->visible != no) {
/* if the symbol is visible use the user value
@@ -382,6 +399,7 @@ void sym_calc_value(struct symbol *sym)
if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN)
newval.tri = yes;
break;
+ }
case S_STRING:
case S_HEX:
case S_INT: