From 5d302eaad5899d430767b861e4c9efb1ce874164 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 7 Apr 2004 17:13:47 +0000 Subject: [PATCH] (strtox, strtoy): New. Use it instead of inputxy() to avoid the double-remainder problem: x-coordinate SHRT_MAX+1 is truncated to 0 by cast to coord, then converted by xabs(). This is wrong unless WORLD_X divides SHRT_MAX+1. (sarg_xy, sarg_getrange, sarg_range): Use them. (inputxy): No longer used, remove. (sarg_type): Use NS_UNDEF instead of 0. (sarg_list): Change confusing loop control. Properly diagnose overlong lists; used to silently ignore list tail and return MAX+1, which made a later snxtitem_list() fail. (atoip): No longer used, remove. Parsing was broken anyway. (sarg_type, sarg_xy, sarg_area, sarg_range, sarg_list, sarg_getrange): Use plain char * instead of s_char *. --- include/prototypes.h | 11 ++- include/xy.h | 3 +- src/lib/common/xy.c | 43 ++++++++++-- src/lib/gen/Makefile | 4 +- src/lib/gen/atoip.c | 60 ---------------- src/lib/subs/sarg.c | 160 +++++++++++++++++++++++-------------------- 6 files changed, 131 insertions(+), 150 deletions(-) delete mode 100644 src/lib/gen/atoip.c diff --git a/include/prototypes.h b/include/prototypes.h index f21940fcc..7e2c2b0dc 100644 --- a/include/prototypes.h +++ b/include/prototypes.h @@ -204,7 +204,6 @@ extern int updates_disabled(void); extern int emp_config(char *file); extern void print_config(FILE * fp); -extern int atoip(s_char **); extern int roll(int); extern int roundavg(double); extern int chance(double); @@ -460,11 +459,11 @@ extern void retreat_land(struct lndstr *, s_char); extern int check_retreat_and_do_shipdamage(struct shpstr *, int); extern int check_retreat_and_do_landdamage(struct lndstr *, int); /* sarg.c */ -extern ns_seltype sarg_type(s_char *); -extern int sarg_xy(s_char *, coord *, coord *); -extern int sarg_area(s_char *, register struct range *); -extern int sarg_range(s_char *, coord *, coord *, int *); -extern int sarg_list(s_char *, register int *, int); +extern ns_seltype sarg_type(char *); +extern int sarg_xy(char *, coord *, coord *); +extern int sarg_area(char *, register struct range *); +extern int sarg_range(char *, coord *, coord *, int *); +extern int sarg_list(char *, register int *, int); /* satmap.c */ extern void satdisp(struct sctstr *, int, int); extern void satmap(int, int, int, int, int, int); diff --git a/include/xy.h b/include/xy.h index bb8276276..707df1f55 100644 --- a/include/xy.h +++ b/include/xy.h @@ -61,7 +61,8 @@ extern void xyrelrange(struct natstr *np, struct range *src, struct range *dst); extern void xyabsrange(struct natstr *np, struct range *src, struct range *dst); -extern void inputxy(coord *xp, coord *yp, natid cn); +extern coord strtox(char *str, char **end); +extern coord strtoy(char *str, char **end); extern coord xabs(struct natstr *np, coord relx); extern coord yabs(struct natstr *np, coord rely); extern coord xnorm(register coord x); diff --git a/src/lib/common/xy.c b/src/lib/common/xy.c index 469d96154..a5a398b45 100644 --- a/src/lib/common/xy.c +++ b/src/lib/common/xy.c @@ -32,13 +32,14 @@ */ #include +#include #include +#include #include "misc.h" #include "xy.h" #include "nat.h" #include "sect.h" #include "file.h" -#include #include "common.h" #include "optlist.h" @@ -117,14 +118,42 @@ xyabsrange(struct natstr *np, struct range *src, struct range *dst) dst->height = src->height; } -void -inputxy(coord *xp, coord *yp, natid cn) +/* + * Convert initial part of STR to normalized x-coordinate. + * Return -1 on error. This works, as normalized coordinates are + * non-negative. + * Assign pointer to first character after the coordinate to *END, + * unless END is a null pointer. + */ +coord +strtox(char *str, char **end) { - struct natstr *np; + long l; + + errno = 0; + l = strtol(str, end, 10); + if (*end == str || errno != 0) + return -1; + return XNORM(l); +} + +/* + * Convert initial part of STR to normalized y-coordinate. + * Return -1 on error. This works, as normalized coordinates are + * non-negative. + * Assign pointer to first character after the coordinate to *END, + * unless END is a null pointer. + */ +coord +strtoy(char *str, char **end) +{ + long l; - np = getnatp(cn); - *xp = xabs(np, *xp); - *yp = yabs(np, *yp); + errno = 0; + l = strtol(str, end, 10); + if (*end == str || errno != 0) + return -1; + return YNORM(l); } coord diff --git a/src/lib/gen/Makefile b/src/lib/gen/Makefile index 677b31f96..a20f313c3 100644 --- a/src/lib/gen/Makefile +++ b/src/lib/gen/Makefile @@ -35,13 +35,13 @@ include ../../make.defs LIB = $(SRCDIR)/lib/libgen.a NTLIB = $(SRCDIR)\lib\libgen.lib -OBJS = atoip.o chance.o copy.o disassoc.o \ +OBJS = chance.o copy.o disassoc.o \ emp_config.o getstarg.o getstring.o io.o \ ioqueue.o mapdist.o minmax.o numstr.o onearg.o \ parse.o plur.o queue.o round.o scthash.o \ strdup.o -NTOBJS = atoip.obj chance.obj copy.obj disassoc.obj \ +NTOBJS = chance.obj copy.obj disassoc.obj \ emp_config.obj getstarg.obj getstring.obj \ io.obj ioqueue.obj mapdist.obj minmax.obj \ numstr.obj onearg.obj parse.obj plur.obj queue.obj round.obj \ diff --git a/src/lib/gen/atoip.c b/src/lib/gen/atoip.c deleted file mode 100644 index d575378a7..000000000 --- a/src/lib/gen/atoip.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Empire - A multi-player, client/server Internet based war game. - * Copyright (C) 1986-2000, Dave Pare, Jeff Bailey, Thomas Ruschak, - * Ken Stevens, Steve McClure - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * --- - * - * See the "LEGAL", "LICENSE", "CREDITS" and "README" files for all the - * related information and legal notices. It is expected that any future - * projects/authors will amend these files as needed. - * - * --- - * - * atoip.c: Convert from decimal string to integer. - * - * Known contributors to this file: - * - */ - -#include "gen.h" - -int -atoip(s_char **ptrptr) -{ - register int num; - register s_char *cp; - register int neg; - - if (ptrptr == 0 || *ptrptr == 0) - return 0; - cp = *ptrptr; - num = 0; - neg = 0; - loop: - while (*cp == ' ' || *cp == '\t') - cp++; - if (*cp == '-') { - neg++; - cp++; - goto loop; - } - while (*cp >= '0' && *cp <= '9') - num = num * 10 + *cp++ - '0'; - *ptrptr = cp; - return (neg ? -num : num); -} diff --git a/src/lib/subs/sarg.c b/src/lib/subs/sarg.c index ef2a14996..c919790d8 100644 --- a/src/lib/subs/sarg.c +++ b/src/lib/subs/sarg.c @@ -54,61 +54,63 @@ * or 0 for none of the above. */ ns_seltype -sarg_type(s_char *ptr) +sarg_type(char *str) { int c; - c = *ptr; + c = *str; if (c == '@') return NS_DIST; if (c == '*') return NS_ALL; - if (c == '#' || strchr(ptr, ',') != 0) + if (c == '#' || strchr(str, ',') != 0) return NS_AREA; if (isdigit(c)) return NS_LIST; if (c == '~' || isupper(c) || islower(c)) return NS_GROUP; - return 0; + return NS_UNDEF; } int -sarg_xy(s_char *ptr, coord *xp, coord *yp) +sarg_xy(char *str, coord *xp, coord *yp) { - if (sarg_type(ptr) != NS_AREA) - return 0; - *xp = atoip(&ptr); - if (*ptr++ != ',') + coord x, y; + struct natstr *np; + + x = strtox(str, &str); + if (x < 0 || *str++ != ',') return 0; - if (!isdigit(*ptr) && *ptr != '-') + y = strtoy(str, &str); + if (y < 0 || *str != 0) return 0; - *yp = atoi(ptr); - inputxy(xp, yp, player->cnum); - if ((*xp ^ *yp) & 01) + if ((x ^ y) & 1) return 0; + np = getnatp(player->cnum); + *xp = xabs(np, x); + *yp = yabs(np, y); return 1; } /* returns absolute coords */ static int -sarg_getrange(s_char *buf, register struct range *rp) +sarg_getrange(char *str, struct range *rp) { - register int rlm; - register int c; + long rlm; struct natstr *np; - s_char *bp; + char *end; - bp = buf; - c = *bp; - if (c == '#') { + if (*str == '#') { /* * realm #X where (X > 0 && X < MAXNOR) * Assumes realms are in abs coordinates */ - bp++; - rlm = atoi(bp); - if (rlm < 0 || rlm >= MAXNOR) - return 0; + if (*++str) { + rlm = strtol(str, &end, 10); + if (end == str || *end != 0 || rlm < 0 || MAXNOR <= rlm) + return 0; + } else + rlm = 0; np = getnatp(player->cnum); rp->lx = np->nat_b[rlm].b_xl; rp->hx = np->nat_b[rlm].b_xh; @@ -120,24 +122,31 @@ sarg_getrange(s_char *buf, register struct range *rp) * LX:LY,HX:HY where * ly, hy are optional. */ - if (!isdigit(c) && c != '-') + rp->lx = rp->hx = strtox(str, &str); + if (rp->lx < 0) return 0; - rp->lx = rp->hx = atoip(&bp); - if (*bp == ':') { - bp++; - rp->hx = atoip(&bp); + if (*str == ':') { + rp->hx = strtox(str + 1, &str); + if (rp->hx < 0) + return 0; } - if (*bp++ != ',') + if (*str++ != ',') return 0; - if (!isdigit(c) && c != '-') + rp->ly = rp->hy = strtoy(str, &str); + if (rp->ly < 0) return 0; - rp->ly = rp->hy = atoip(&bp); - if (*bp == ':') { - bp++; - rp->hy = atoip(&bp); + if (*str == ':') { + rp->hy = strtoy(str + 1, &str); + if (rp->hy < 0) + return 0; } - inputxy(&rp->lx, &rp->ly, player->cnum); - inputxy(&rp->hx, &rp->hy, player->cnum); + if (*str != 0) + return 0; + np = getnatp(player->cnum); + rp->lx = xabs(np, rp->lx); + rp->hx = xabs(np, rp->hx); + rp->ly = yabs(np, rp->ly); + rp->hy = yabs(np, rp->hy); } xysize_range(rp); return 1; @@ -148,9 +157,9 @@ sarg_getrange(s_char *buf, register struct range *rp) * a result range struct */ int -sarg_area(s_char *buf, register struct range *rp) +sarg_area(char *str, struct range *rp) { - if (!sarg_getrange(buf, rp)) + if (!sarg_getrange(str, rp)) return 0; rp->hx += 1; if (rp->hx >= WORLD_X) @@ -167,23 +176,28 @@ sarg_area(s_char *buf, register struct range *rp) * result params */ int -sarg_range(s_char *buf, coord *xp, coord *yp, int *dist) +sarg_range(char *str, coord *xp, coord *yp, int *dist) { - s_char *bp; + coord x, y; + long d; + char *end; + struct natstr *np; - bp = buf; - if (bp == 0 || *bp == 0) + if (*str++ != '@') return 0; - if (*bp++ != '@') + x = strtox(str, &str); + if (x < 0 || *str++ != ',') return 0; - *xp = atoip(&bp); - if (*bp++ != ',') + y = strtoy(str, &str); + if (y < 0 || *str++ != ':') return 0; - *yp = atoip(&bp); - if (*bp++ != ':') + d = strtol(str, &end, 10); + if (end == str || d < 0 || *end != 0) return 0; - inputxy(xp, yp, player->cnum); - *dist = atoi(bp); + *dist = d; + np = getnatp(player->cnum); + *xp = xabs(np, x); + *yp = yabs(np, y); return 1; } @@ -191,38 +205,36 @@ sarg_range(s_char *buf, coord *xp, coord *yp, int *dist) * list of idents; id/id/id/id/id */ int -sarg_list(s_char *str, register int *list, int max) +sarg_list(char *str, int *list, int max) { - register int i; - register int j; - register int n; - s_char *arg; + int i, j; + long n; + char *end; - arg = str; - for (i = 0; i < max; i++) { - if (!isdigit(*arg)) { - pr("Illegal character '%c'\n", *arg); + i = 0; + do { + n = strtol(str, &end, 10); + if (end == str || n < 0) { + pr("Illegal character '%c'\n", *str); return 0; } - n = atoip(&arg); for (j = 0; j < i; j++) { if (list[j] == n) break; } - if (j != i) { - /* duplicate; ignore */ - i--; - } else - list[i] = n; - if (*arg == 0) - break; - if (*arg != '/') { - pr("Expecting '/', got '%c'\n", *arg); - return 0; + if (j == i) { + if (i >= max) { + pr("List too long (limit is %d)\n", max); + return 0; + } + list[i++] = n; } - arg++; - if (*arg == 0) - break; + str = end; + } while (*str++ == '/'); + + if (str[-1] != 0) { + pr("Expecting '/', got '%c'\n", str[-1]); + return 0; } - return i + 1; + return i; } -- 2.43.0