boolean option processing

In addition to 'true', 'yes', 'on' and 'false', 'no', 'off',
accept 1 and 0 for the value of a boolean option.  Other numeric
values are rejected rather than treated as non-zero.

Relax the parsing for true, false, yes, no to accept one or more
letters instead of requiring at least three for true and false
and full word for yes and no.  Full word is still required for
on and off.

Don't report two errors for the same mistake:
 |% NETHACKOPTIONS='legacy:flase' ./nethack
 | * Illegal parameter for a boolean.
 | * Unknown option 'legacy:flase'.
 |2 errors in NETHACKOPTIONS.
is changed to
 | * 'legacy:flase' is not valid for a boolean.
 |1 error in NETHACKOPTIONS.
This commit is contained in:
PatR
2020-09-09 14:19:48 -07:00
parent d3181e20ba
commit e9df383bd6
2 changed files with 32 additions and 14 deletions

View File

@@ -1,4 +1,4 @@
NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.299 $ $NHDT-Date: 1599559379 2020/09/08 10:02:59 $
NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.300 $ $NHDT-Date: 1599686385 2020/09/09 21:19:45 $
General Fixes and Modified Features
-----------------------------------
@@ -507,7 +507,7 @@ new monsters: displacer beast ('f') and genetic engineer ('Q')
make camera flash which reveals previously unseen map features or objects or
monsters record those on the hero's map; monsters revert to 'unseen'
boolean options can optionally have the form "name:value" with value taken
from among "true", "yes", "on", or "false", "no", "off"
from among "true", "yes", "on", or 1 and "false", "no", "off", or 0
record number of wishes and artifact wishes in xlogfile
give feedback for '#chat' directed at walls
add 'Sokoban' conduct, tracking the number of times the special Sokoban rules

View File

@@ -1,4 +1,4 @@
/* NetHack 3.7 options.c $NHDT-Date: 1597357458 2020/08/13 22:24:18 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.470 $ */
/* NetHack 3.7 options.c $NHDT-Date: 1599686385 2020/09/09 21:19:45 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.471 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Michael Allison, 2008. */
/* NetHack may be freely redistributed. See license for details. */
@@ -4445,6 +4445,8 @@ char *op;
return optn_ok;
}
if (req == do_set) {
boolean nosexchange = FALSE;
if (!allopt[optidx].addr)
return optn_ok; /* silent retreat */
@@ -4460,18 +4462,23 @@ char *op;
config_error_add(
"Negated boolean '%s' should not have a parameter",
allopt[optidx].name);
return optn_err;
return optn_silenterr;
}
/* length is greater than 0 or we wouldn't have gotten here */
ln = (int) strlen(op);
if (!strncmpi(op, "true", max(ln, 3))
|| !strcmpi(op, "yes") || !strcmpi(op, "on")) {
if (!strncmpi(op, "true", ln)
|| !strncmpi(op, "yes", ln)
|| !strcmpi(op, "on")
|| (digit(*op) && atoi(op) == 1)) {
negated = FALSE;
} else if (!strncmpi(op, "false", max(ln, 3))
|| !strcmpi(op, "no") || !strcmpi(op, "off")) {
} else if (!strncmpi(op, "false", ln)
|| !strncmpi(op, "no", ln)
|| !strcmpi(op, "off")
|| (digit(*op) && atoi(op) == 0)) {
negated = TRUE;
} else if (!allopt[optidx].valok) {
config_error_add("Illegal parameter for a boolean");
return optn_err;
config_error_add("'%s' is not valid for a boolean", opts);
return optn_silenterr;
}
}
if (iflags.debug_fuzzer && !g.opt_initial) {
@@ -4484,8 +4491,7 @@ char *op;
case opt_female:
if (!strncmpi(opts, "female", 3)) {
if (!g.opt_initial && flags.female == negated) {
config_error_add("That is not anatomically possible.");
return optn_err;
nosexchange = TRUE;
} else {
flags.initgend = flags.female = !negated;
return optn_ok;
@@ -4493,8 +4499,7 @@ char *op;
}
if (!strncmpi(opts, "male", 3)) {
if (!g.opt_initial && flags.female != negated) {
config_error_add("That is not anatomically possible.");
return optn_err;
nosexchange = TRUE;
} else {
flags.initgend = flags.female = negated;
return optn_ok;
@@ -4502,6 +4507,19 @@ char *op;
}
break;
}
/* this dates from when 'O' prompted for a line of options text
rather than use a menu to control access to which options can
be modified during play; it was possible to attempt to use
'O' to specify female or negate male when playing as male or
to specify male or negate female when playing as female;
options processing rejects that for !opt_initial; not possible
now but kept in case someone brings the old 'O' behavior back */
if (nosexchange) {
/* can't arbitrarily change sex after game has started;
magic (amulet or polymorph) is required for that */
config_error_add("'%s' is not anatomically possible.", opts);
return optn_silenterr;
}
*(allopt[optidx].addr) = !negated; /* <==== SET IT HERE */