Merge branch 'NetHack-3.7-Jan2020' into NetHack-3.7
This commit is contained in:
2
src/.gitignore
vendored
2
src/.gitignore
vendored
@@ -11,5 +11,5 @@ tiles.bmp
|
||||
graphicschk
|
||||
nhdat
|
||||
o
|
||||
nhdat370
|
||||
nhdat*
|
||||
|
||||
|
||||
@@ -610,7 +610,11 @@ VA_DECL(const char *, str)
|
||||
{
|
||||
char buf[BUFSZ];
|
||||
|
||||
#if !defined(NO_VSNPRINTF)
|
||||
(void) vsnprintf(buf, sizeof buf, str, VA_ARGS);
|
||||
#else
|
||||
Vsprintf(buf, str, VA_ARGS);
|
||||
#endif
|
||||
raw_print(buf);
|
||||
paniclog("panic", buf);
|
||||
}
|
||||
|
||||
232
src/options.c
232
src/options.c
@@ -42,6 +42,8 @@ enum window_option_types {
|
||||
|
||||
#define PILE_LIMIT_DFLT 5
|
||||
|
||||
static char empty_optstr[] = { '\0' };
|
||||
|
||||
/*
|
||||
* NOTE: If you add (or delete) an option, please update the short
|
||||
* options help (option_help()), the long options help (dat/opthelp),
|
||||
@@ -927,8 +929,8 @@ int maxlen;
|
||||
*/
|
||||
static void
|
||||
escapes(cp, tp)
|
||||
const char *cp;
|
||||
char *tp;
|
||||
const char *cp; /* might be 'tp', updating in place */
|
||||
char *tp; /* result is never longer than 'cp' */
|
||||
{
|
||||
static NEARDATA const char oct[] = "01234567", dec[] = "0123456789",
|
||||
hex[] = "00112233445566778899aAbBcCdDeEfF";
|
||||
@@ -1044,7 +1046,7 @@ boolean val_optional;
|
||||
if (!colon || !*++colon) {
|
||||
if (!val_optional)
|
||||
config_error_add("Missing parameter for '%s'", opts);
|
||||
return (char *) 0;
|
||||
return empty_optstr;
|
||||
}
|
||||
return colon;
|
||||
}
|
||||
@@ -1057,7 +1059,7 @@ boolean val_optional;
|
||||
{
|
||||
if (!g.opt_initial) {
|
||||
rejectoption(optname);
|
||||
return (char *) 0;
|
||||
return empty_optstr;
|
||||
}
|
||||
return string_for_opt(opts, val_optional);
|
||||
}
|
||||
@@ -1136,7 +1138,7 @@ const char *optype;
|
||||
uchar translate[WARNCOUNT];
|
||||
int length, i;
|
||||
|
||||
if (!(opts = string_for_env_opt(optype, opts, FALSE)))
|
||||
if ((opts = string_for_env_opt(optype, opts, FALSE)) == empty_optstr)
|
||||
return FALSE;
|
||||
escapes(opts, opts);
|
||||
|
||||
@@ -1806,15 +1808,16 @@ int c, a;
|
||||
/* parse '"regex_string"=color&attr' and add it to menucoloring */
|
||||
boolean
|
||||
add_menu_coloring(tmpstr)
|
||||
char *tmpstr;
|
||||
char *tmpstr; /* never Null but could be empty */
|
||||
{
|
||||
int c = NO_COLOR, a = ATR_NONE;
|
||||
char *tmps, *cs, *amp;
|
||||
char str[BUFSZ];
|
||||
|
||||
Sprintf(str, "%s", tmpstr);
|
||||
(void) strncpy(str, tmpstr, sizeof str - 1);
|
||||
str[sizeof str - 1] = '\0';
|
||||
|
||||
if (!tmpstr || (cs = index(str, '=')) == 0) {
|
||||
if ((cs = index(str, '=')) == 0) {
|
||||
config_error_add("Malformed MENUCOLOR");
|
||||
return FALSE;
|
||||
}
|
||||
@@ -1928,7 +1931,8 @@ char **opp;
|
||||
|
||||
if (negated) {
|
||||
bad_negation(fullname, FALSE);
|
||||
} else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) {
|
||||
} else if ((op = string_for_env_opt(fullname, opts, FALSE))
|
||||
!= empty_optstr) {
|
||||
boolean val_negated = FALSE;
|
||||
|
||||
while ((*op == '!') || !strncmpi(op, "no", 2)) {
|
||||
@@ -2125,7 +2129,8 @@ boolean tinitial, tfrom_file;
|
||||
if (match_optname(opts, fullname, 3, TRUE)) {
|
||||
if (duplicate)
|
||||
complain_about_duplicate(opts, 1);
|
||||
if ((op = string_for_env_opt(fullname, opts, negated)) != 0) {
|
||||
if ((op = string_for_env_opt(fullname, opts, negated))
|
||||
!= empty_optstr) {
|
||||
if (negated) {
|
||||
bad_negation(fullname, TRUE);
|
||||
return FALSE;
|
||||
@@ -2167,7 +2172,8 @@ boolean tinitial, tfrom_file;
|
||||
if (negated) {
|
||||
bad_negation(fullname, FALSE);
|
||||
return FALSE;
|
||||
} else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) {
|
||||
} else if ((op = string_for_env_opt(fullname, opts, FALSE))
|
||||
!= empty_optstr) {
|
||||
nmcpy(g.catname, op, PL_PSIZ);
|
||||
} else
|
||||
return FALSE;
|
||||
@@ -2182,7 +2188,8 @@ boolean tinitial, tfrom_file;
|
||||
if (negated) {
|
||||
bad_negation(fullname, FALSE);
|
||||
return FALSE;
|
||||
} else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) {
|
||||
} else if ((op = string_for_env_opt(fullname, opts, FALSE))
|
||||
!= empty_optstr) {
|
||||
nmcpy(g.dogname, op, PL_PSIZ);
|
||||
} else
|
||||
return FALSE;
|
||||
@@ -2197,7 +2204,8 @@ boolean tinitial, tfrom_file;
|
||||
if (negated) {
|
||||
bad_negation(fullname, FALSE);
|
||||
return FALSE;
|
||||
} else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) {
|
||||
} else if ((op = string_for_env_opt(fullname, opts, FALSE))
|
||||
!= empty_optstr) {
|
||||
nmcpy(g.horsename, op, PL_PSIZ);
|
||||
} else
|
||||
return FALSE;
|
||||
@@ -2212,7 +2220,7 @@ boolean tinitial, tfrom_file;
|
||||
if (duplicate)
|
||||
complain_about_duplicate(opts, 1);
|
||||
op = string_for_opt(opts, (compat || !g.opt_initial));
|
||||
if (!op) {
|
||||
if (op == empty_optstr) {
|
||||
if (compat || negated || g.opt_initial) {
|
||||
/* for backwards compatibility, "mouse_support" without a
|
||||
value is a synonym for mouse_support:1 */
|
||||
@@ -2241,7 +2249,7 @@ boolean tinitial, tfrom_file;
|
||||
if (duplicate)
|
||||
complain_about_duplicate(opts, 1);
|
||||
op = string_for_opt(opts, (compat || !g.opt_initial));
|
||||
if (!op) {
|
||||
if (op == empty_optstr) {
|
||||
if (compat || negated || g.opt_initial) {
|
||||
/* for backwards compatibility, "number_pad" without a
|
||||
value is a synonym for number_pad:1 */
|
||||
@@ -2284,7 +2292,7 @@ boolean tinitial, tfrom_file;
|
||||
if (negated) {
|
||||
bad_negation(fullname, FALSE);
|
||||
return FALSE;
|
||||
} else if ((op = string_for_opt(opts, FALSE)) != 0) {
|
||||
} else if ((op = string_for_opt(opts, FALSE)) != empty_optstr) {
|
||||
g.symset[ROGUESET].name = dupstr(op);
|
||||
if (!read_sym_file(ROGUESET)) {
|
||||
clear_symsetentry(ROGUESET, TRUE);
|
||||
@@ -2309,7 +2317,7 @@ boolean tinitial, tfrom_file;
|
||||
if (negated) {
|
||||
bad_negation(fullname, FALSE);
|
||||
return FALSE;
|
||||
} else if ((op = string_for_opt(opts, FALSE)) != 0) {
|
||||
} else if ((op = string_for_opt(opts, FALSE)) != empty_optstr) {
|
||||
g.symset[PRIMARY].name = dupstr(op);
|
||||
if (!read_sym_file(PRIMARY)) {
|
||||
clear_symsetentry(PRIMARY, TRUE);
|
||||
@@ -2332,7 +2340,7 @@ boolean tinitial, tfrom_file;
|
||||
complain_about_duplicate(opts, 1);
|
||||
if (negated) {
|
||||
flags.runmode = RUN_TPORT;
|
||||
} else if ((op = string_for_opt(opts, FALSE)) != 0) {
|
||||
} else if ((op = string_for_opt(opts, FALSE)) != empty_optstr) {
|
||||
if (!strncmpi(op, "teleport", strlen(op)))
|
||||
flags.runmode = RUN_TPORT;
|
||||
else if (!strncmpi(op, "run", strlen(op)))
|
||||
@@ -2356,7 +2364,8 @@ boolean tinitial, tfrom_file;
|
||||
if (negated) {
|
||||
bad_negation(fullname, FALSE);
|
||||
return FALSE;
|
||||
} else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) {
|
||||
} else if ((op = string_for_env_opt(fullname, opts, FALSE))
|
||||
!= empty_optstr) {
|
||||
if (!add_menu_coloring(op))
|
||||
return FALSE;
|
||||
} else
|
||||
@@ -2387,7 +2396,8 @@ boolean tinitial, tfrom_file;
|
||||
if (duplicate)
|
||||
complain_about_duplicate(opts, 1);
|
||||
op = string_for_env_opt(fullname, opts, negated);
|
||||
if ((negated && !op) || (!negated && op)) {
|
||||
if ((negated && op == empty_optstr)
|
||||
|| (!negated && op != empty_optstr)) {
|
||||
iflags.msg_history = negated ? 0 : atoi(op);
|
||||
} else if (negated) {
|
||||
bad_negation(fullname, TRUE);
|
||||
@@ -2405,7 +2415,7 @@ boolean tinitial, tfrom_file;
|
||||
|
||||
if (duplicate)
|
||||
complain_about_duplicate(opts, 1);
|
||||
if (!(op = string_for_opt(opts, TRUE))) {
|
||||
if ((op = string_for_opt(opts, TRUE)) == empty_optstr) {
|
||||
tmp = negated ? 's' : 'f';
|
||||
} else {
|
||||
if (negated) {
|
||||
@@ -2474,7 +2484,7 @@ boolean tinitial, tfrom_file;
|
||||
if (duplicate)
|
||||
complain_about_duplicate(opts, 1);
|
||||
if (opttype > 0 && !negated
|
||||
&& (op = string_for_opt(opts, FALSE)) != 0) {
|
||||
&& (op = string_for_opt(opts, FALSE)) != empty_optstr) {
|
||||
switch (opttype) {
|
||||
case MAP_OPTION:
|
||||
iflags.wc_fontsiz_map = atoi(op);
|
||||
@@ -2498,7 +2508,8 @@ boolean tinitial, tfrom_file;
|
||||
config_error_add("Unknown %s parameter '%s'", fullname, opts);
|
||||
return FALSE;
|
||||
}
|
||||
if (opttype > 0 && (op = string_for_opt(opts, FALSE)) != 0) {
|
||||
if (opttype > 0
|
||||
&& (op = string_for_opt(opts, FALSE)) != empty_optstr) {
|
||||
wc_set_font_name(opttype, op);
|
||||
#ifdef MAC
|
||||
set_font_name(opttype, op);
|
||||
@@ -2543,12 +2554,12 @@ boolean tinitial, tfrom_file;
|
||||
}
|
||||
#ifdef WIN32
|
||||
op = string_for_opt(opts, TRUE);
|
||||
if (!alternative_palette(op)) {
|
||||
if (op == empty_optstr || !alternative_palette(op)) {
|
||||
config_error_add("Error in palette parameter '%s'", op);
|
||||
return FALSE;
|
||||
}
|
||||
#else
|
||||
if ((op = string_for_opt(opts, FALSE)) != (char *) 0) {
|
||||
if ((op = string_for_opt(opts, FALSE)) != empty_optstr) {
|
||||
char *pt = op;
|
||||
int cnt, tmp, reverse;
|
||||
long rgb;
|
||||
@@ -2598,22 +2609,21 @@ boolean tinitial, tfrom_file;
|
||||
|
||||
if (match_optname(opts, "fruit", 2, TRUE)) {
|
||||
struct fruit *forig = 0;
|
||||
char empty_str = '\0';
|
||||
|
||||
if (duplicate)
|
||||
complain_about_duplicate(opts, 1);
|
||||
op = string_for_opt(opts, negated || !g.opt_initial);
|
||||
if (negated) {
|
||||
if (op) {
|
||||
if (op != empty_optstr) {
|
||||
bad_negation("fruit", TRUE);
|
||||
return FALSE;
|
||||
}
|
||||
op = &empty_str;
|
||||
op = empty_optstr;
|
||||
goto goodfruit;
|
||||
}
|
||||
if (!op)
|
||||
if (op == empty_optstr)
|
||||
return FALSE;
|
||||
/* stripped leading and trailing spaces, condensed internal ones in 3.6.2 */
|
||||
/* strip leading/trailing spaces, condense internal ones (3.6.2) */
|
||||
mungspaces(op);
|
||||
if (!g.opt_initial) {
|
||||
struct fruit *f;
|
||||
@@ -2662,7 +2672,8 @@ boolean tinitial, tfrom_file;
|
||||
if (negated) {
|
||||
iflags.getpos_coords = GPCOORDS_NONE;
|
||||
return retval;
|
||||
} else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) {
|
||||
} else if ((op = string_for_env_opt(fullname, opts, FALSE))
|
||||
!= empty_optstr) {
|
||||
static char gpcoords[] = { GPCOORDS_NONE, GPCOORDS_COMPASS,
|
||||
GPCOORDS_COMFULL, GPCOORDS_MAP,
|
||||
GPCOORDS_SCREEN, '\0' };
|
||||
@@ -2686,7 +2697,8 @@ boolean tinitial, tfrom_file;
|
||||
if (negated) {
|
||||
iflags.getloc_filter = GFILTER_NONE;
|
||||
return retval;
|
||||
} else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) {
|
||||
} else if ((op = string_for_env_opt(fullname, opts, FALSE))
|
||||
!= empty_optstr) {
|
||||
char c = lowc(*op);
|
||||
|
||||
switch (c) {
|
||||
@@ -2732,9 +2744,10 @@ boolean tinitial, tfrom_file;
|
||||
bad_negation(fullname, FALSE);
|
||||
return FALSE;
|
||||
}
|
||||
/* if (!(opts = string_for_env_opt(fullname, opts, FALSE)))
|
||||
/* if ((opts = string_for_env_opt(fullname, opts, FALSE))
|
||||
== empty_optstr)
|
||||
*/
|
||||
if (!(opts = string_for_opt(opts, FALSE)))
|
||||
if ((opts = string_for_opt(opts, FALSE)) == empty_optstr)
|
||||
return FALSE;
|
||||
escapes(opts, opts);
|
||||
/* note: dummy monclass #0 has symbol value '\0'; we allow that--
|
||||
@@ -2783,7 +2796,8 @@ boolean tinitial, tfrom_file;
|
||||
if (negated) {
|
||||
bad_negation(fullname, FALSE);
|
||||
return FALSE;
|
||||
} else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) {
|
||||
} else if ((op = string_for_env_opt(fullname, opts, FALSE))
|
||||
!= empty_optstr) {
|
||||
nmcpy(g.plname, op, PL_NSIZ);
|
||||
} else
|
||||
return FALSE;
|
||||
@@ -2798,7 +2812,7 @@ boolean tinitial, tfrom_file;
|
||||
if (negated) {
|
||||
bad_negation(fullname, FALSE);
|
||||
return FALSE;
|
||||
} else if ((op = string_for_opt(opts, negated)) != 0) {
|
||||
} else if ((op = string_for_opt(opts, negated)) != empty_optstr) {
|
||||
#if defined(WIN32) && defined(TTY_GRAPHICS)
|
||||
set_altkeyhandler(op);
|
||||
#endif
|
||||
@@ -2812,7 +2826,7 @@ boolean tinitial, tfrom_file;
|
||||
fullname = "align_status";
|
||||
if (match_optname(opts, fullname, sizeof "align_status" - 1, TRUE)) {
|
||||
op = string_for_opt(opts, negated);
|
||||
if (op && !negated) {
|
||||
if ((op != empty_optstr) && !negated) {
|
||||
if (!strncmpi(op, "left", sizeof "left" - 1))
|
||||
iflags.wc_align_status = ALIGN_LEFT;
|
||||
else if (!strncmpi(op, "top", sizeof "top" - 1))
|
||||
@@ -2839,7 +2853,7 @@ boolean tinitial, tfrom_file;
|
||||
if (duplicate)
|
||||
complain_about_duplicate(opts, 1);
|
||||
op = string_for_opt(opts, negated);
|
||||
if (op && !negated) {
|
||||
if ((op != empty_optstr) && !negated) {
|
||||
if (!strncmpi(op, "left", sizeof "left" - 1))
|
||||
iflags.wc_align_message = ALIGN_LEFT;
|
||||
else if (!strncmpi(op, "top", sizeof "top" - 1))
|
||||
@@ -2867,7 +2881,7 @@ boolean tinitial, tfrom_file;
|
||||
if (negated) {
|
||||
bad_negation(fullname, FALSE);
|
||||
return FALSE;
|
||||
} else if (!(op = string_for_opt(opts, FALSE)))
|
||||
} else if ((op = string_for_opt(opts, FALSE)) == empty_optstr)
|
||||
return FALSE;
|
||||
|
||||
if (!change_inv_order(op))
|
||||
@@ -2886,7 +2900,7 @@ boolean tinitial, tfrom_file;
|
||||
flags.paranoia_bits = 0; /* clear all */
|
||||
if (negated) {
|
||||
flags.paranoia_bits = 0; /* [now redundant...] */
|
||||
} else if ((op = string_for_opt(opts, TRUE)) != 0) {
|
||||
} else if ((op = string_for_opt(opts, TRUE)) != empty_optstr) {
|
||||
char *pp, buf[BUFSZ];
|
||||
|
||||
strncpy(buf, op, sizeof buf - 1);
|
||||
@@ -2952,7 +2966,8 @@ boolean tinitial, tfrom_file;
|
||||
if (negated) {
|
||||
bad_negation(fullname, FALSE);
|
||||
return FALSE;
|
||||
} else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) {
|
||||
} else if ((op = string_for_env_opt(fullname, opts, FALSE))
|
||||
!= empty_optstr) {
|
||||
switch (lowc(*op)) {
|
||||
case 'u': /* Unencumbered */
|
||||
flags.pickup_burden = UNENCUMBERED;
|
||||
@@ -2995,7 +3010,7 @@ boolean tinitial, tfrom_file;
|
||||
oc_to_str(flags.pickup_types, tbuf);
|
||||
flags.pickup_types[0] = '\0'; /* all */
|
||||
op = string_for_opt(opts, (compat || !g.opt_initial));
|
||||
if (!op) {
|
||||
if (op == empty_optstr) {
|
||||
if (compat || negated || g.opt_initial) {
|
||||
/* for backwards compatibility, "pickup" without a
|
||||
value is a synonym for autopickup of all types
|
||||
@@ -3067,12 +3082,13 @@ boolean tinitial, tfrom_file;
|
||||
if (duplicate)
|
||||
complain_about_duplicate(opts, 1);
|
||||
op = string_for_opt(opts, negated);
|
||||
if ((negated && !op) || (!negated && op))
|
||||
if ((negated && op == empty_optstr)
|
||||
|| (!negated && op != empty_optstr))
|
||||
flags.pile_limit = negated ? 0 : atoi(op);
|
||||
else if (negated) {
|
||||
bad_negation(fullname, TRUE);
|
||||
return FALSE;
|
||||
} else /* !op */
|
||||
} else /* op == empty_optstr */
|
||||
flags.pile_limit = PILE_LIMIT_DFLT;
|
||||
/* sanity check */
|
||||
if (flags.pile_limit < 0)
|
||||
@@ -3090,7 +3106,7 @@ boolean tinitial, tfrom_file;
|
||||
if (duplicate || negated)
|
||||
return FALSE;
|
||||
op = string_for_opt(opts, FALSE);
|
||||
if (!op)
|
||||
if (op == empty_optstr)
|
||||
return FALSE;
|
||||
if (!strncmpi(op, "normal", 6) || !strcmpi(op, "play")) {
|
||||
wizard = discover = FALSE;
|
||||
@@ -3113,7 +3129,7 @@ boolean tinitial, tfrom_file;
|
||||
if (duplicate)
|
||||
complain_about_duplicate(opts, 1);
|
||||
op = string_for_opt(opts, negated);
|
||||
if (op && !negated) {
|
||||
if (op != empty_optstr && !negated) {
|
||||
if (!strncmpi(op, "dialog", sizeof "dialog" - 1)) {
|
||||
iflags.wc_player_selection = VIA_DIALOG;
|
||||
} else if (!strncmpi(op, "prompt", sizeof "prompt" - 1)) {
|
||||
@@ -3160,14 +3176,15 @@ boolean tinitial, tfrom_file;
|
||||
if (duplicate)
|
||||
complain_about_duplicate(opts, 1);
|
||||
op = string_for_opt(opts, TRUE);
|
||||
if (op && negated) {
|
||||
if (op != empty_optstr && negated) {
|
||||
bad_negation(fullname, TRUE);
|
||||
return FALSE;
|
||||
}
|
||||
/* "disclose" without a value means "all with prompting"
|
||||
and negated means "none without prompting" */
|
||||
if (!op || !strcmpi(op, "all") || !strcmpi(op, "none")) {
|
||||
if (op && !strcmpi(op, "none"))
|
||||
if (op == empty_optstr
|
||||
|| !strcmpi(op, "all") || !strcmpi(op, "none")) {
|
||||
if (op != empty_optstr && !strcmpi(op, "none"))
|
||||
negated = TRUE;
|
||||
for (num = 0; num < NUM_DISCLOSURE_OPTIONS; num++)
|
||||
flags.end_disclose[num] = negated
|
||||
@@ -3232,7 +3249,7 @@ boolean tinitial, tfrom_file;
|
||||
bad_negation(fullname, FALSE);
|
||||
return FALSE;
|
||||
}
|
||||
if (!(op = string_for_opt(opts, FALSE)))
|
||||
if ((op = string_for_opt(opts, FALSE)) == empty_optstr)
|
||||
return FALSE;
|
||||
|
||||
while (*op) {
|
||||
@@ -3281,7 +3298,7 @@ boolean tinitial, tfrom_file;
|
||||
fullname = "sortloot";
|
||||
if (match_optname(opts, fullname, 4, TRUE)) {
|
||||
op = string_for_env_opt(fullname, opts, FALSE);
|
||||
if (op) {
|
||||
if (op != empty_optstr) {
|
||||
char c = lowc(*op);
|
||||
|
||||
switch (c) {
|
||||
@@ -3307,7 +3324,7 @@ boolean tinitial, tfrom_file;
|
||||
if (negated) {
|
||||
bad_negation(fullname, FALSE);
|
||||
return FALSE;
|
||||
} else if (op)
|
||||
} else if (op != empty_optstr)
|
||||
(void) feature_alert_opts(op, fullname);
|
||||
return retval;
|
||||
}
|
||||
@@ -3322,7 +3339,8 @@ boolean tinitial, tfrom_file;
|
||||
if (negated) {
|
||||
bad_negation(fullname, FALSE);
|
||||
return FALSE;
|
||||
} else if (!(opts = string_for_env_opt(fullname, opts, FALSE))) {
|
||||
} else if ((opts = string_for_env_opt(fullname, opts, FALSE))
|
||||
== empty_optstr) {
|
||||
return FALSE;
|
||||
}
|
||||
if (!assign_videocolors(opts)) {
|
||||
@@ -3339,7 +3357,8 @@ boolean tinitial, tfrom_file;
|
||||
if (negated) {
|
||||
bad_negation(fullname, FALSE);
|
||||
return FALSE;
|
||||
} else if (!(opts = string_for_env_opt(fullname, opts, FALSE))) {
|
||||
} else if ((opts = string_for_env_opt(fullname, opts, FALSE))
|
||||
== empty_optstr) {
|
||||
return FALSE;
|
||||
}
|
||||
if (!assign_videoshades(opts)) {
|
||||
@@ -3383,7 +3402,8 @@ boolean tinitial, tfrom_file;
|
||||
if (negated) {
|
||||
bad_negation(fullname, FALSE);
|
||||
return FALSE;
|
||||
} else if (!(opts = string_for_env_opt(fullname, opts, FALSE))) {
|
||||
} else if ((opts = string_for_env_opt(fullname, opts, FALSE))
|
||||
== empty_optstr) {
|
||||
return FALSE;
|
||||
}
|
||||
if (!assign_video(opts)) {
|
||||
@@ -3393,6 +3413,11 @@ boolean tinitial, tfrom_file;
|
||||
return retval;
|
||||
}
|
||||
#endif /* NO_TERMS */
|
||||
} else if ((opts = string_for_env_opt(fullname, opts, FALSE))
|
||||
== empty_optstr) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
#endif /* MSDOS */
|
||||
|
||||
/* WINCAP
|
||||
@@ -3406,7 +3431,7 @@ boolean tinitial, tfrom_file;
|
||||
if (duplicate)
|
||||
complain_about_duplicate(opts, 1);
|
||||
op = string_for_opt(opts, negated);
|
||||
if (op && !negated) {
|
||||
if (op != empty_optstr && !negated) {
|
||||
if (!strcmpi(op, "tiles"))
|
||||
iflags.wc_map_mode = MAP_MODE_TILES;
|
||||
else if (!strncmpi(op, "ascii4x6", sizeof "ascii4x6" - 1))
|
||||
@@ -3454,7 +3479,8 @@ boolean tinitial, tfrom_file;
|
||||
if (duplicate)
|
||||
complain_about_duplicate(opts, 1);
|
||||
op = string_for_opt(opts, negated);
|
||||
if ((negated && !op) || (!negated && op)) {
|
||||
if ((negated && op == empty_optstr)
|
||||
|| (!negated && op != empty_optstr)) {
|
||||
iflags.wc_scroll_amount = negated ? 1 : atoi(op);
|
||||
} else if (negated) {
|
||||
bad_negation(fullname, TRUE);
|
||||
@@ -3470,7 +3496,8 @@ boolean tinitial, tfrom_file;
|
||||
if (duplicate)
|
||||
complain_about_duplicate(opts, 1);
|
||||
op = string_for_opt(opts, negated);
|
||||
if ((negated && !op) || (!negated && op)) {
|
||||
if ((negated && op == empty_optstr)
|
||||
|| (!negated && op != empty_optstr)) {
|
||||
iflags.wc_scroll_margin = negated ? 5 : atoi(op);
|
||||
} else if (negated) {
|
||||
bad_negation(fullname, TRUE);
|
||||
@@ -3488,7 +3515,7 @@ boolean tinitial, tfrom_file;
|
||||
#if defined(WIN32)
|
||||
} else {
|
||||
op = string_for_opt(opts, 0);
|
||||
if (!op)
|
||||
if (op == empty_optstr)
|
||||
return FALSE;
|
||||
#ifdef TTY_GRAPHICS
|
||||
map_subkeyvalue(op);
|
||||
@@ -3505,7 +3532,8 @@ boolean tinitial, tfrom_file;
|
||||
if (duplicate)
|
||||
complain_about_duplicate(opts, 1);
|
||||
op = string_for_opt(opts, negated);
|
||||
if ((negated && !op) || (!negated && op)) {
|
||||
if ((negated && op == empty_optstr)
|
||||
|| (!negated && op != empty_optstr)) {
|
||||
iflags.wc_tile_width = negated ? 0 : atoi(op);
|
||||
} else if (negated) {
|
||||
bad_negation(fullname, TRUE);
|
||||
@@ -3519,7 +3547,7 @@ boolean tinitial, tfrom_file;
|
||||
if (match_optname(opts, fullname, sizeof "tile_file" - 1, TRUE)) {
|
||||
if (duplicate)
|
||||
complain_about_duplicate(opts, 1);
|
||||
if ((op = string_for_opt(opts, FALSE)) != 0) {
|
||||
if ((op = string_for_opt(opts, FALSE)) != empty_optstr) {
|
||||
if (iflags.wc_tile_file)
|
||||
free(iflags.wc_tile_file);
|
||||
iflags.wc_tile_file = dupstr(op);
|
||||
@@ -3534,7 +3562,8 @@ boolean tinitial, tfrom_file;
|
||||
if (duplicate)
|
||||
complain_about_duplicate(opts, 1);
|
||||
op = string_for_opt(opts, negated);
|
||||
if ((negated && !op) || (!negated && op)) {
|
||||
if ((negated && op == empty_optstr)
|
||||
|| (!negated && op != empty_optstr)) {
|
||||
iflags.wc_tile_height = negated ? 0 : atoi(op);
|
||||
} else if (negated) {
|
||||
bad_negation(fullname, TRUE);
|
||||
@@ -3550,7 +3579,8 @@ boolean tinitial, tfrom_file;
|
||||
if (duplicate)
|
||||
complain_about_duplicate(opts, 1);
|
||||
op = string_for_opt(opts, negated);
|
||||
if ((negated && !op) || (!negated && op)) {
|
||||
if ((negated && op == empty_optstr)
|
||||
|| (!negated && op != empty_optstr)) {
|
||||
iflags.wc_vary_msgcount = negated ? 0 : atoi(op);
|
||||
} else if (negated) {
|
||||
bad_negation(fullname, TRUE);
|
||||
@@ -3581,7 +3611,8 @@ boolean tinitial, tfrom_file;
|
||||
if (negated) {
|
||||
bad_negation(fullname, FALSE);
|
||||
return FALSE;
|
||||
} else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) {
|
||||
} else if ((op = string_for_env_opt(fullname, opts, FALSE))
|
||||
!= empty_optstr) {
|
||||
if (!iflags.windowtype_deferred) {
|
||||
char buf[WINTYPELEN];
|
||||
|
||||
@@ -3601,7 +3632,8 @@ boolean tinitial, tfrom_file;
|
||||
if (negated) {
|
||||
bad_negation(fullname, FALSE);
|
||||
return FALSE;
|
||||
} else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) {
|
||||
} else if ((op = string_for_env_opt(fullname, opts, FALSE))
|
||||
!= empty_optstr) {
|
||||
char buf[WINTYPELEN];
|
||||
|
||||
nmcpy(buf, op, WINTYPELEN);
|
||||
@@ -3620,7 +3652,7 @@ boolean tinitial, tfrom_file;
|
||||
if (match_optname(opts, fullname, 7, TRUE)) {
|
||||
if (duplicate)
|
||||
complain_about_duplicate(opts, 1);
|
||||
if ((op = string_for_opt(opts, FALSE)) != 0) {
|
||||
if ((op = string_for_opt(opts, FALSE)) != empty_optstr) {
|
||||
if (!wc_set_window_colors(op)) {
|
||||
config_error_add("Could not set %s '%s'", fullname, op);
|
||||
return FALSE;
|
||||
@@ -3643,22 +3675,23 @@ boolean tinitial, tfrom_file;
|
||||
|| (fullname = "term_rows", match_optname(opts, fullname, 8, TRUE))) {
|
||||
long ltmp;
|
||||
|
||||
op = string_for_opt(opts, negated);
|
||||
ltmp = atol(op);
|
||||
if (negated) {
|
||||
bad_negation(fullname, FALSE);
|
||||
retval = FALSE;
|
||||
if ((op = string_for_opt(opts, negated)) != empty_optstr) {
|
||||
ltmp = atol(op);
|
||||
if (negated) {
|
||||
bad_negation(fullname, FALSE);
|
||||
retval = FALSE;
|
||||
|
||||
/* this just checks atol() sanity, not logical window size sanity */
|
||||
} else if (ltmp <= 0L || ltmp >= (long) LARGEST_INT) {
|
||||
config_error_add("Invalid %s: %ld", fullname, ltmp);
|
||||
retval = FALSE;
|
||||
/* just checks atol() sanity, not logical window size sanity */
|
||||
} else if (ltmp <= 0L || ltmp >= (long) LARGEST_INT) {
|
||||
config_error_add("Invalid %s: %ld", fullname, ltmp);
|
||||
retval = FALSE;
|
||||
|
||||
} else {
|
||||
if (!strcmp(fullname, "term_rows"))
|
||||
iflags.wc2_term_rows = (int) ltmp;
|
||||
else /* !strcmp(fullname, "term_cols") */
|
||||
iflags.wc2_term_cols = (int) ltmp;
|
||||
} else {
|
||||
if (!strcmp(fullname, "term_rows"))
|
||||
iflags.wc2_term_rows = (int) ltmp;
|
||||
else /* !strcmp(fullname, "term_cols") */
|
||||
iflags.wc2_term_cols = (int) ltmp;
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
@@ -3668,10 +3701,10 @@ boolean tinitial, tfrom_file;
|
||||
fullname = "petattr";
|
||||
if (match_optname(opts, fullname, sizeof "petattr" - 1, TRUE)) {
|
||||
op = string_for_opt(opts, negated);
|
||||
if (op && negated) {
|
||||
if (op != empty_optstr && negated) {
|
||||
bad_negation(fullname, TRUE);
|
||||
retval = FALSE;
|
||||
} else if (op) {
|
||||
} else if (op != empty_optstr) {
|
||||
#ifdef CURSES_GRAPHICS
|
||||
int itmp = curses_read_attrs(op);
|
||||
|
||||
@@ -3702,7 +3735,7 @@ boolean tinitial, tfrom_file;
|
||||
fullname = "windowborders";
|
||||
if (match_optname(opts, fullname, 10, TRUE)) {
|
||||
op = string_for_opt(opts, negated);
|
||||
if (negated && op) {
|
||||
if (negated && op != empty_optstr) {
|
||||
bad_negation(fullname, TRUE);
|
||||
retval = FALSE;
|
||||
} else {
|
||||
@@ -3710,7 +3743,7 @@ boolean tinitial, tfrom_file;
|
||||
|
||||
if (negated)
|
||||
itmp = 0; /* Off */
|
||||
else if (!op)
|
||||
else if (op == empty_optstr)
|
||||
itmp = 1; /* On */
|
||||
else /* Value supplied; expect 0 (off), 1 (on), or 2 (auto) */
|
||||
itmp = atoi(op);
|
||||
@@ -3738,7 +3771,7 @@ boolean tinitial, tfrom_file;
|
||||
bad_negation(fullname, TRUE);
|
||||
itmp = 2;
|
||||
retval = FALSE;
|
||||
} else if (op) {
|
||||
} else if (op != empty_optstr) {
|
||||
itmp = atoi(op);
|
||||
}
|
||||
if (itmp < 2 || itmp > 3) {
|
||||
@@ -3760,7 +3793,7 @@ boolean tinitial, tfrom_file;
|
||||
|
||||
if (duplicate)
|
||||
complain_about_duplicate(opts, 1);
|
||||
if (!(op = string_for_opt(opts, !val_required))) {
|
||||
if ((op = string_for_opt(opts, !val_required)) == empty_optstr) {
|
||||
if (val_required)
|
||||
return FALSE; /* string_for_opt gave feedback */
|
||||
tmp = negated ? 'n' : 'f';
|
||||
@@ -3801,7 +3834,8 @@ boolean tinitial, tfrom_file;
|
||||
if (negated) {
|
||||
bad_negation(fullname, FALSE);
|
||||
return FALSE;
|
||||
} else if (!(opts = string_for_env_opt(fullname, opts, FALSE))) {
|
||||
} else if ((opts = string_for_env_opt(fullname, opts, FALSE))
|
||||
== empty_optstr) {
|
||||
return FALSE;
|
||||
}
|
||||
tmpattr = match_str2attr(opts, TRUE);
|
||||
@@ -3821,7 +3855,7 @@ boolean tinitial, tfrom_file;
|
||||
if (negated) {
|
||||
bad_negation(fullname, FALSE);
|
||||
return FALSE;
|
||||
} else if ((op = string_for_opt(opts, FALSE)) != 0) {
|
||||
} else if ((op = string_for_opt(opts, FALSE)) != empty_optstr) {
|
||||
char c, op_buf[BUFSZ];
|
||||
|
||||
escapes(op, op_buf);
|
||||
@@ -3843,10 +3877,10 @@ boolean tinitial, tfrom_file;
|
||||
if (duplicate)
|
||||
complain_about_duplicate(opts, 1);
|
||||
op = string_for_opt(opts, TRUE);
|
||||
if (op && negated) {
|
||||
if (op != empty_optstr && negated) {
|
||||
clear_status_hilites();
|
||||
return retval;
|
||||
} else if (!op) {
|
||||
} else if (op == empty_optstr) {
|
||||
config_error_add("Value is mandatory for hilite_status");
|
||||
return FALSE;
|
||||
}
|
||||
@@ -3867,7 +3901,7 @@ boolean tinitial, tfrom_file;
|
||||
iflags.hilite_delta = 0L;
|
||||
} else {
|
||||
op = string_for_opt(opts, TRUE);
|
||||
iflags.hilite_delta = (!op || !*op) ? 3L : atol(op);
|
||||
iflags.hilite_delta = (op == empty_optstr || !*op) ? 3L : atol(op);
|
||||
if (iflags.hilite_delta < 0L)
|
||||
iflags.hilite_delta = 1L;
|
||||
}
|
||||
@@ -4015,7 +4049,7 @@ boolean tinitial, tfrom_file;
|
||||
}
|
||||
|
||||
op = string_for_opt(opts, TRUE);
|
||||
if (op) {
|
||||
if (op != empty_optstr) {
|
||||
if (negated) {
|
||||
config_error_add(
|
||||
"Negated boolean '%s' should not have a parameter",
|
||||
@@ -6129,9 +6163,9 @@ char *buf;
|
||||
|
||||
int
|
||||
sym_val(strval)
|
||||
const char *strval;
|
||||
const char *strval; /* up to 4*BUFSZ-1 long; only first few chars matter */
|
||||
{
|
||||
char buf[QBUFSZ];
|
||||
char buf[QBUFSZ], tmp[QBUFSZ]; /* to hold trucated copy of 'strval' */
|
||||
|
||||
buf[0] = '\0';
|
||||
if (!strval[0] || !strval[1]) { /* empty, or single character */
|
||||
@@ -6152,8 +6186,9 @@ const char *strval;
|
||||
/* not simple quote or basic backslash;
|
||||
strip closing quote and let escapes() deal with it */
|
||||
} else {
|
||||
char *p, tmp[QBUFSZ];
|
||||
char *p;
|
||||
|
||||
/* +1: skip opening single quote */
|
||||
(void) strncpy(tmp, strval + 1, sizeof tmp - 1);
|
||||
tmp[sizeof tmp - 1] = '\0';
|
||||
if ((p = rindex(tmp, '\'')) != 0) {
|
||||
@@ -6161,8 +6196,11 @@ const char *strval;
|
||||
escapes(tmp, buf);
|
||||
} /* else buf[0] stays '\0' */
|
||||
}
|
||||
} else /* not lone char nor single quote */
|
||||
escapes(strval, buf);
|
||||
} else { /* not lone char nor single quote */
|
||||
(void) strncpy(tmp, strval, sizeof tmp - 1);
|
||||
tmp[sizeof tmp - 1] = '\0';
|
||||
escapes(tmp, buf);
|
||||
}
|
||||
|
||||
return (int) *buf;
|
||||
}
|
||||
|
||||
47
src/pline.c
47
src/pline.c
@@ -6,6 +6,10 @@
|
||||
#define NEED_VARARGS /* Uses ... */ /* comment line for pre-compiled headers */
|
||||
#include "hack.h"
|
||||
|
||||
#define BIGBUFSZ (5 * BUFSZ) /* big enough to format a 4*BUFSZ string (from
|
||||
* config file parsing) with modest decoration;
|
||||
* result will then be truncated to BUFSZ-1 */
|
||||
|
||||
static void FDECL(putmesg, (const char *));
|
||||
static char *FDECL(You_buf, (int));
|
||||
#if defined(MSGHANDLER) && (defined(POSIX_TYPES) || defined(__GNUC__))
|
||||
@@ -114,9 +118,12 @@ VA_DECL(const char *, line)
|
||||
#endif /* USE_STDARG | USE_VARARG */
|
||||
{ /* start of vpline() or of nested block in USE_OLDARG's pline() */
|
||||
static int in_pline = 0;
|
||||
char pbuf[3 * BUFSZ];
|
||||
char pbuf[BIGBUFSZ]; /* will get chopped down to BUFSZ-1 if longer */
|
||||
int ln;
|
||||
int msgtyp;
|
||||
#if !defined(NO_VSNPRINTF)
|
||||
int vlen = 0;
|
||||
#endif
|
||||
boolean no_repeat;
|
||||
/* Do NOT use VA_START and VA_END in here... see above */
|
||||
|
||||
@@ -130,7 +137,16 @@ VA_DECL(const char *, line)
|
||||
return;
|
||||
|
||||
if (index(line, '%')) {
|
||||
#if !defined(NO_VSNPRINTF)
|
||||
vlen = vsnprintf(pbuf, sizeof pbuf, line, VA_ARGS);
|
||||
#if (NH_DEVEL_STATUS != NH_STATUS_RELEASED) && defined(DEBUG)
|
||||
if (vlen >= (int) sizeof pbuf)
|
||||
panic("%s: truncation of buffer at %zu of %d bytes",
|
||||
"pline", sizeof pbuf, vlen);
|
||||
#endif
|
||||
#else
|
||||
Vsprintf(pbuf, line, VA_ARGS);
|
||||
#endif
|
||||
line = pbuf;
|
||||
}
|
||||
if ((ln = (int) strlen(line)) > BUFSZ - 1) {
|
||||
@@ -435,15 +451,18 @@ void raw_printf
|
||||
VA_DECL(const char *, line)
|
||||
#endif
|
||||
{
|
||||
char pbuf[3 * BUFSZ];
|
||||
int ln;
|
||||
char pbuf[BIGBUFSZ]; /* will be chopped down to BUFSZ-1 if longer */
|
||||
/* Do NOT use VA_START and VA_END in here... see above */
|
||||
|
||||
if (index(line, '%')) {
|
||||
#if !defined(NO_VSNPRINTF)
|
||||
(void) vsnprintf(pbuf, sizeof pbuf, line, VA_ARGS);
|
||||
#else
|
||||
Vsprintf(pbuf, line, VA_ARGS);
|
||||
#endif
|
||||
line = pbuf;
|
||||
}
|
||||
if ((ln = (int) strlen(line)) > BUFSZ - 1) {
|
||||
if ((int) strlen(line) > BUFSZ - 1) {
|
||||
if (line != pbuf)
|
||||
line = strncpy(pbuf, line, BUFSZ - 1);
|
||||
/* unlike pline, we don't futz around to keep last few chars */
|
||||
@@ -462,7 +481,7 @@ VA_DECL(const char *, line)
|
||||
void impossible
|
||||
VA_DECL(const char *, s)
|
||||
{
|
||||
char pbuf[2 * BUFSZ];
|
||||
char pbuf[BIGBUFSZ]; /* will be chopped down to BUFSZ-1 if longer */
|
||||
|
||||
VA_START(s);
|
||||
VA_INIT(s, const char *);
|
||||
@@ -470,7 +489,11 @@ VA_DECL(const char *, s)
|
||||
panic("impossible called impossible");
|
||||
|
||||
g.program_state.in_impossible = 1;
|
||||
#if !defined(NO_VSNPRINTF)
|
||||
(void) vsnprintf(pbuf, sizeof pbuf, s, VA_ARGS);
|
||||
#else
|
||||
Vsprintf(pbuf, s, VA_ARGS);
|
||||
#endif
|
||||
pbuf[BUFSZ - 1] = '\0'; /* sanity */
|
||||
paniclog("impossible", pbuf);
|
||||
if (iflags.debug_fuzzer)
|
||||
@@ -567,9 +590,21 @@ config_error_add
|
||||
VA_DECL(const char *, str)
|
||||
#endif /* ?(USE_STDARG || USE_VARARG) */
|
||||
{ /* start of vconf...() or of nested block in USE_OLDARG's conf...() */
|
||||
char buf[2 * BUFSZ];
|
||||
#if !defined(NO_VSNPRINTF)
|
||||
int vlen = 0;
|
||||
#endif
|
||||
char buf[BIGBUFSZ]; /* will be chopped down to BUFSZ-1 if longer */
|
||||
|
||||
#if !defined(NO_VSNPRINTF)
|
||||
vlen = vsnprintf(buf, sizeof buf, str, VA_ARGS);
|
||||
#if (NH_DEVEL_STATUS != NH_STATUS_RELEASED) && defined(DEBUG)
|
||||
if (vlen >= (int) sizeof buf)
|
||||
panic("%s: truncation of buffer at %zu of %d bytes",
|
||||
"config_error_add", sizeof buf, vlen);
|
||||
#endif
|
||||
#else
|
||||
Vsprintf(buf, str, VA_ARGS);
|
||||
#endif
|
||||
buf[BUFSZ - 1] = '\0';
|
||||
config_erradd(buf);
|
||||
|
||||
|
||||
@@ -1036,6 +1036,7 @@ int uid;
|
||||
* print selected parts of score list.
|
||||
* argc >= 2, with argv[0] untrustworthy (directory names, et al.),
|
||||
* and argv[1] starting with "-s".
|
||||
* caveat: some shells might allow argv elements to be arbitrarily long.
|
||||
*/
|
||||
void
|
||||
prscore(argc, argv)
|
||||
|
||||
@@ -241,7 +241,8 @@ void
|
||||
choose_windows(s)
|
||||
const char *s;
|
||||
{
|
||||
register int i;
|
||||
int i;
|
||||
char *tmps = 0;
|
||||
|
||||
for (i = 0; winchoices[i].procs; i++) {
|
||||
if ('+' == winchoices[i].procs->name[0])
|
||||
@@ -267,9 +268,22 @@ const char *s;
|
||||
windowprocs.win_wait_synch = def_wait_synch;
|
||||
|
||||
if (!winchoices[0].procs) {
|
||||
raw_printf("No window types?");
|
||||
raw_printf("No window types supported?");
|
||||
nh_terminate(EXIT_FAILURE);
|
||||
}
|
||||
/* 50: arbitrary, no real window_type names are anywhere near that long;
|
||||
used to prevent potential raw_printf() overflow if user supplies a
|
||||
very long string (on the order of 1200 chars) on the command line
|
||||
(config file options can't get that big; they're truncated at 1023) */
|
||||
#define WINDOW_TYPE_MAXLEN 50
|
||||
if (strlen(s) >= WINDOW_TYPE_MAXLEN) {
|
||||
tmps = (char *) alloc(WINDOW_TYPE_MAXLEN);
|
||||
(void) strncpy(tmps, s, WINDOW_TYPE_MAXLEN - 1);
|
||||
tmps[WINDOW_TYPE_MAXLEN - 1] = '\0';
|
||||
s = tmps;
|
||||
}
|
||||
#undef WINDOW_TYPE_MAXLEN
|
||||
|
||||
if (!winchoices[1].procs) {
|
||||
config_error_add(
|
||||
"Window type %s not recognized. The only choice is: %s",
|
||||
@@ -291,6 +305,8 @@ const char *s;
|
||||
config_error_add("Window type %s not recognized. Choices are: %s",
|
||||
s, buf);
|
||||
}
|
||||
if (tmps)
|
||||
free((genericptr_t) tmps) /*, tmps = 0*/ ;
|
||||
|
||||
if (windowprocs.win_raw_print == def_raw_print
|
||||
|| WINDOWPORT("safe-startup"))
|
||||
@@ -1154,7 +1170,7 @@ boolean fullsubs; /* True -> full substitution for file name, False ->
|
||||
else
|
||||
Strcpy(tmpbuf, "{current date+time}");
|
||||
break;
|
||||
case 'v': /* version, eg. "3.6.4-0" */
|
||||
case 'v': /* version, eg. "3.6.5-0" */
|
||||
Sprintf(tmpbuf, "%s", version_string(verbuf));
|
||||
break;
|
||||
case 'u': /* UID */
|
||||
|
||||
Reference in New Issue
Block a user