diff --git a/include/prototypes.h b/include/prototypes.h index 07a03b64..13c0ed7c 100644 --- a/include/prototypes.h +++ b/include/prototypes.h @@ -363,6 +363,7 @@ extern int natpass(natid, char *); extern struct player *player; /* current player's context */ extern char *praddr(struct player *); extern void player_main(struct player *); +extern void make_stale_if_command_arg(char *); /* more under Commands */ /* recvclient.c */ extern int recvclient(char *, int); diff --git a/src/lib/player/player.c b/src/lib/player/player.c index 7f40b13e..d93211eb 100644 --- a/src/lib/player/player.c +++ b/src/lib/player/player.c @@ -202,6 +202,36 @@ status(void) return 1; } +/* Is ARG one of the player's last command's arguments? */ +static int +is_command_arg(char *arg) +{ + int i; + + for (i = 1; i < 128 && player->argp[i]; i++) { + if (arg == player->argp[i]) + return 1; + } + return 0; +} + +/* + * Make all objects stale if ARG is one of the player's command arguments. + * See ef_make_stale() for what "making stale" means. + * Useful for functions that prompt for missing arguments. + * These can yield the processor, so we'd like to call ef_make_stale() + * there. Except that leads to false positives when the caller passes + * an argument that is never null, and relies on the fact that the + * function doesn't yield then. We can't know that in general. But + * we do know in the common special case of command arguments. + */ +void +make_stale_if_command_arg(char *arg) +{ + if (is_command_arg(arg)) + ef_make_stale(); +} + /* * XXX This whole mess should be redone; execute block should * start with "exec start", and should end with "exec end". diff --git a/src/lib/subs/getstarg.c b/src/lib/subs/getstarg.c index 20c6af61..731bed1e 100644 --- a/src/lib/subs/getstarg.c +++ b/src/lib/subs/getstarg.c @@ -34,6 +34,7 @@ #include #include "misc.h" +#include "prototypes.h" /* * Get string argument. @@ -50,6 +51,7 @@ getstarg(char *input, char *prompt, char *buf) return NULL; } else { strcpy(buf, input); + make_stale_if_command_arg(input); } return buf; } diff --git a/src/lib/subs/onearg.c b/src/lib/subs/onearg.c index b97ce0a7..3784bdc7 100644 --- a/src/lib/subs/onearg.c +++ b/src/lib/subs/onearg.c @@ -43,7 +43,8 @@ onearg(char *arg, char *prompt) if (!arg || !*arg) { if (!(arg = getstring(prompt, buf))) return -1; - } + } else + make_stale_if_command_arg(arg); n = atoi(arg); if (n < 0) return -1; diff --git a/src/lib/subs/snxtitem.c b/src/lib/subs/snxtitem.c index da8b86ad..bcb8f7d0 100644 --- a/src/lib/subs/snxtitem.c +++ b/src/lib/subs/snxtitem.c @@ -73,9 +73,9 @@ snxtitem(struct nstr_item *np, int type, char *str, char *prompt) str = getstring(prompt, buf); if (!str) return 0; - } + } else + make_stale_if_command_arg(str); if (*str == 0) { - /* empty string passed by player */ return 0; } if (type == EF_NATION && isalpha(*str)) { diff --git a/src/lib/subs/snxtsct.c b/src/lib/subs/snxtsct.c index 7657c456..01d8b597 100644 --- a/src/lib/subs/snxtsct.c +++ b/src/lib/subs/snxtsct.c @@ -44,7 +44,7 @@ /* * setup the nstr_sect structure for sector selection. - * can select on either NS_ALL, NS_AREA, or NS_RANGE + * can select on either NS_ALL, NS_AREA, or NS_DIST * iterate thru the "condarg" string looking * for arguments to compile into the nstr. * Using this function for anything but command arguments is usually @@ -63,7 +63,8 @@ snxtsct(struct nstr_sect *np, char *str) if (!str || !*str) { if (!(str = getstring("(sects)? ", buf))) return 0; - } + } else + make_stale_if_command_arg(str); switch (sarg_type(str)) { case NS_AREA: if (!sarg_area(str, &range))