tty extmenu option

When the 'extmenu' boolean was set, typing '#' in wizard mode triggered
a crash.  The total number of extended commands exceeded the capacity of
extcmd_via_menu() and the code it had to check for that was only in effect
if DEBUG was defined.  This boosts the limit from 40 (actally 38) to 50 (48)
and enables the checking code for BETA as well as for DEBUG.

     Almost all of this diff is indentation.
This commit is contained in:
nethack.rankin
2012-04-14 11:40:04 +00:00
parent 4c3939bb76
commit 2196861cc6

188
src/cmd.c
View File

@@ -354,13 +354,13 @@ doextlist(VOID_ARGS) /* here after #? - now list all full-word commands */
}
#ifdef TTY_GRAPHICS
#define MAX_EXT_CMD 40 /* Change if we ever have > 40 ext cmds */
#define MAX_EXT_CMD 50 /* Change if we ever have > 50 ext cmds */
/*
* This is currently used only by the tty port and is
* controlled via runtime option 'extmenu'
*/
int
extcmd_via_menu() /* here after # - now show pick-list of possible commands */
extcmd_via_menu() /* here after # - now show pick-list of possible commands */
{
const struct ext_func_tab *efp;
menu_item *pick_list = (menu_item *)0;
@@ -372,108 +372,110 @@ extcmd_via_menu() /* here after # - now show pick-list of possible commands */
int i, n, nchoices, acount;
int ret, biggest;
int accelerator, prevaccelerator;
int matchlevel = 0;
int matchlevel = 0;
ret = 0;
cbuf[0] = '\0';
biggest = 0;
while (!ret) {
i = n = 0;
accelerator = 0;
any = zeroany;
/* populate choices */
for(efp = extcmdlist; efp->ef_txt; efp++) {
if (!matchlevel || !strncmp(efp->ef_txt, cbuf, matchlevel)) {
choices[i++] = efp;
if ((int)strlen(efp->ef_desc) > biggest) {
biggest = strlen(efp->ef_desc);
Sprintf(fmtstr,"%%-%ds", biggest + 15);
}
#ifdef DEBUG
if (i >= MAX_EXT_CMD - 2) {
impossible("Exceeded %d extended commands in doextcmd() menu",
MAX_EXT_CMD - 2);
return 0;
}
#endif
i = n = 0;
accelerator = 0;
any = zeroany;
/* populate choices */
for (efp = extcmdlist; efp->ef_txt; efp++) {
if (!matchlevel || !strncmp(efp->ef_txt, cbuf, matchlevel)) {
choices[i++] = efp;
if ((int)strlen(efp->ef_desc) > biggest) {
biggest = strlen(efp->ef_desc);
Sprintf(fmtstr, "%%-%ds", biggest + 15);
}
# if defined(DEBUG) || defined(BETA)
if (i >= MAX_EXT_CMD - 2) {
impossible(
"Exceeded %d extended commands in doextcmd() menu; 'extmenu' disabled.",
MAX_EXT_CMD - 2);
iflags.extmenu = 0;
return -1;
}
# endif /* DEBUG || BETA */
}
choices[i] = (struct ext_func_tab *)0;
nchoices = i;
/* if we're down to one, we have our selection so get out of here */
if (nchoices == 1) {
for (i = 0; extcmdlist[i].ef_txt != (char *)0; i++)
if (!strncmpi(extcmdlist[i].ef_txt, cbuf, matchlevel)) {
ret = i;
break;
}
break;
}
}
choices[i] = (struct ext_func_tab *)0;
nchoices = i;
/* if we're down to one, we have our selection so get out of here */
if (nchoices == 1) {
for (i = 0; extcmdlist[i].ef_txt != (char *)0; i++)
if (!strncmpi(extcmdlist[i].ef_txt, cbuf, matchlevel)) {
ret = i;
break;
}
break;
}
/* otherwise... */
win = create_nhwindow(NHW_MENU);
start_menu(win);
prevaccelerator = 0;
acount = 0;
for(i = 0; choices[i]; ++i) {
accelerator = choices[i]->ef_txt[matchlevel];
if (accelerator != prevaccelerator || nchoices < (ROWNO - 3)) {
if (acount) {
/* flush the extended commands for that letter already in buf */
Sprintf(buf, fmtstr, prompt);
any.a_char = prevaccelerator;
add_menu(win, NO_GLYPH, &any, any.a_char, 0,
ATR_NONE, buf, FALSE);
acount = 0;
}
/* otherwise... */
win = create_nhwindow(NHW_MENU);
start_menu(win);
prevaccelerator = 0;
acount = 0;
for (i = 0; choices[i]; ++i) {
accelerator = choices[i]->ef_txt[matchlevel];
if (accelerator != prevaccelerator || nchoices < (ROWNO - 3)) {
if (acount) {
/* flush extended cmds for that letter already in buf */
Sprintf(buf, fmtstr, prompt);
any.a_char = prevaccelerator;
add_menu(win, NO_GLYPH, &any, any.a_char, 0,
ATR_NONE, buf, FALSE);
acount = 0;
}
prevaccelerator = accelerator;
if (!acount || nchoices < (ROWNO - 3)) {
Sprintf(prompt, "%s [%s]", choices[i]->ef_txt,
choices[i]->ef_desc);
} else if (acount == 1) {
Sprintf(prompt, "%s or %s", choices[i-1]->ef_txt,
choices[i]->ef_txt);
} else {
Strcat(prompt," or ");
Strcat(prompt, choices[i]->ef_txt);
}
++acount;
}
if (acount) {
/* flush buf */
Sprintf(buf, fmtstr, prompt);
any.a_char = prevaccelerator;
add_menu(win, NO_GLYPH, &any, any.a_char, 0, ATR_NONE, buf, FALSE);
}
Sprintf(prompt, "Extended Command: %s", cbuf);
end_menu(win, prompt);
n = select_menu(win, PICK_ONE, &pick_list);
destroy_nhwindow(win);
if (n==1) {
if (matchlevel > (QBUFSZ - 2)) {
free((genericptr_t)pick_list);
#ifdef DEBUG
impossible("Too many characters (%d) entered in extcmd_via_menu()",
matchlevel);
#endif
ret = -1;
} else {
cbuf[matchlevel++] = pick_list[0].item.a_char;
cbuf[matchlevel] = '\0';
free((genericptr_t)pick_list);
}
prevaccelerator = accelerator;
if (!acount || nchoices < (ROWNO - 3)) {
Sprintf(prompt, "%s [%s]", choices[i]->ef_txt,
choices[i]->ef_desc);
} else if (acount == 1) {
Sprintf(prompt, "%s or %s", choices[i-1]->ef_txt,
choices[i]->ef_txt);
} else {
if (matchlevel) {
ret = 0;
matchlevel = 0;
} else
ret = -1;
Strcat(prompt," or ");
Strcat(prompt, choices[i]->ef_txt);
}
++acount;
}
if (acount) {
/* flush buf */
Sprintf(buf, fmtstr, prompt);
any.a_char = prevaccelerator;
add_menu(win, NO_GLYPH, &any, any.a_char, 0, ATR_NONE, buf, FALSE);
}
Sprintf(prompt, "Extended Command: %s", cbuf);
end_menu(win, prompt);
n = select_menu(win, PICK_ONE, &pick_list);
destroy_nhwindow(win);
if (n == 1) {
if (matchlevel > (QBUFSZ - 2)) {
free((genericptr_t)pick_list);
# if defined(DEBUG) || defined(BETA)
impossible("Too many chars (%d) entered in extcmd_via_menu()",
matchlevel);
# endif
ret = -1;
} else {
cbuf[matchlevel++] = pick_list[0].item.a_char;
cbuf[matchlevel] = '\0';
free((genericptr_t)pick_list);
}
} else {
if (matchlevel) {
ret = 0;
matchlevel = 0;
} else
ret = -1;
}
}
return ret;
}
#endif
#endif /* TTY_GRAPHICS */
/* #monster command - use special monster ability while polymorphed */
STATIC_PTR int
@@ -1307,7 +1309,7 @@ int final; /* ENL_GAMEINPROGRESS:0, ENL_GAVEOVERALIVE, ENL_GAMEOVERDEAD */
/* display role, race, alignment and such to en_win */
STATIC_OVL void
background_enlightenment(unused_mode, final)
int unused_mode; /* not used */
int unused_mode UNUSED;
int final;
{
const char *role_titl, *rank_titl;
@@ -1761,8 +1763,8 @@ int final;
/* attributes: intrinsics and the like, other non-obvious capabilities */
void
attributes_enlightenment(mode, final)
int mode;
attributes_enlightenment(unused_mode, final)
int unused_mode UNUSED;
int final;
{
static NEARDATA const char
@@ -3635,7 +3637,7 @@ parse()
/*ARGUSED*/
void
hangup(sig_unused) /* called as signal() handler, so sent at least one arg */
int sig_unused;
int sig_unused UNUSED;
{
if (program_state.exiting) program_state.in_moveloop = 0;
nhwindows_hangup();