From 61affaed37d1f1a805139ebeb2783adf50a1f3bf Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 15 Jul 2024 13:13:01 -0700 Subject: [PATCH] fix #K4202 - O/mO for prompted values treated \ player's input as a comma-separated list of option:value settings Several compound values that aren't amenable to menus prompt for a line of input and pass it to parseoptions() as if it came from the run-time configuration file. That shouldn't be treating commas as option separators. The fix is trival, at least for handling the text properly without introducing new warnings to complain about rejections. Some options notice an unwanted comma and complain, others don't notice and the extra text gets ignored. --- doc/fixes3-7-0.txt | 4 ++++ src/options.c | 20 +++++++++++++++----- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index f34db3b58..4c682601d 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -1445,6 +1445,10 @@ some theft messages by nymphs force "she", others use default monster naming if a nymph stole worn armor and got killed (perhaps by pet) before hero's next turn, feedback would be "You finish taking off your suit." regardless of the type of armor being taken off +when setting an option interactively [via O or 3.7's mO], if the particular + option uses a prompt to get a line of input (for compounds: 'fruit', + 'scores', most numeric ones), input was treated as a comma-separated + list of option[:value] rather than just the new value of that option Fixes to 3.7.0-x General Problems Exposed Via git Repository diff --git a/src/options.c b/src/options.c index e454aa31f..7d7e09fae 100644 --- a/src/options.c +++ b/src/options.c @@ -478,8 +478,19 @@ parseoptions( using_alias = FALSE; go.opt_initial = tinitial; go.opt_from_file = tfrom_file; - if ((op = strchr(opts, ',')) != 0) { + /* + * Process elements of comma-separated list in right to left order. + * When some options are set interactively--notably various compound + * options that issue a prompt for a value--they use parseoptions() + * to handle setting the new value. For those, 'tinitial' is False + * and if user tries to supply a comma-separated list, it will be + * treated as part of the current option, probably failing to parse. + */ + if (tinitial && (op = strchr(opts, ',')) != 0) { *op++ = 0; + /* current element remains pending while the rest of the line gets + handled recursively; if the rest of line contains any commas, + then the process will recurse deeper as it is processed */ if (!parseoptions(op, go.opt_initial, go.opt_from_file)) retval = FALSE; } @@ -8573,8 +8584,7 @@ doset(void) /* changing options via menu by Per Liboriussen */ anything any; menu_item *pick_list; int indexoffset, startpass, endpass; - boolean setinitial = FALSE, fromfile = FALSE, - gavehelp = FALSE, skiphelp = !iflags.cmdassist; + boolean gavehelp = FALSE, skiphelp = !iflags.cmdassist; int clr = NO_COLOR; if (iflags.menu_requested) { @@ -8731,7 +8741,7 @@ doset(void) /* changing options via menu by Per Liboriussen */ /* boolean option */ Sprintf(buf, "%s%s", *allopt[opt_indx].addr ? "!" : "", allopt[opt_indx].name); - (void) parseoptions(buf, setinitial, fromfile); + (void) parseoptions(buf, FALSE, FALSE); } else { /* compound option */ int k = opt_indx, reslt; @@ -8755,7 +8765,7 @@ doset(void) /* changing options via menu by Per Liboriussen */ (void) strncat(eos(buf), abuf, (sizeof buf - 1 - strlen(buf))); /* pass the buck */ - (void) parseoptions(buf, setinitial, fromfile); + (void) parseoptions(buf, FALSE, FALSE); } } if (wc_supported(allopt[opt_indx].name)