(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 *.
This commit is contained in:
parent
543b0cba4f
commit
5d302eaad5
6 changed files with 131 additions and 150 deletions
|
@ -204,7 +204,6 @@ extern int updates_disabled(void);
|
||||||
extern int emp_config(char *file);
|
extern int emp_config(char *file);
|
||||||
extern void print_config(FILE * fp);
|
extern void print_config(FILE * fp);
|
||||||
|
|
||||||
extern int atoip(s_char **);
|
|
||||||
extern int roll(int);
|
extern int roll(int);
|
||||||
extern int roundavg(double);
|
extern int roundavg(double);
|
||||||
extern int chance(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_shipdamage(struct shpstr *, int);
|
||||||
extern int check_retreat_and_do_landdamage(struct lndstr *, int);
|
extern int check_retreat_and_do_landdamage(struct lndstr *, int);
|
||||||
/* sarg.c */
|
/* sarg.c */
|
||||||
extern ns_seltype sarg_type(s_char *);
|
extern ns_seltype sarg_type(char *);
|
||||||
extern int sarg_xy(s_char *, coord *, coord *);
|
extern int sarg_xy(char *, coord *, coord *);
|
||||||
extern int sarg_area(s_char *, register struct range *);
|
extern int sarg_area(char *, register struct range *);
|
||||||
extern int sarg_range(s_char *, coord *, coord *, int *);
|
extern int sarg_range(char *, coord *, coord *, int *);
|
||||||
extern int sarg_list(s_char *, register int *, int);
|
extern int sarg_list(char *, register int *, int);
|
||||||
/* satmap.c */
|
/* satmap.c */
|
||||||
extern void satdisp(struct sctstr *, int, int);
|
extern void satdisp(struct sctstr *, int, int);
|
||||||
extern void satmap(int, int, int, int, int, int);
|
extern void satmap(int, int, int, int, int, int);
|
||||||
|
|
|
@ -61,7 +61,8 @@ extern void xyrelrange(struct natstr *np, struct range *src,
|
||||||
struct range *dst);
|
struct range *dst);
|
||||||
extern void xyabsrange(struct natstr *np, struct range *src,
|
extern void xyabsrange(struct natstr *np, struct range *src,
|
||||||
struct range *dst);
|
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 xabs(struct natstr *np, coord relx);
|
||||||
extern coord yabs(struct natstr *np, coord rely);
|
extern coord yabs(struct natstr *np, coord rely);
|
||||||
extern coord xnorm(register coord x);
|
extern coord xnorm(register coord x);
|
||||||
|
|
|
@ -32,13 +32,14 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "xy.h"
|
#include "xy.h"
|
||||||
#include "nat.h"
|
#include "nat.h"
|
||||||
#include "sect.h"
|
#include "sect.h"
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
#include <stdio.h>
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "optlist.h"
|
#include "optlist.h"
|
||||||
|
|
||||||
|
@ -117,14 +118,42 @@ xyabsrange(struct natstr *np, struct range *src, struct range *dst)
|
||||||
dst->height = src->height;
|
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;
|
||||||
|
|
||||||
np = getnatp(cn);
|
errno = 0;
|
||||||
*xp = xabs(np, *xp);
|
l = strtol(str, end, 10);
|
||||||
*yp = yabs(np, *yp);
|
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;
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
l = strtol(str, end, 10);
|
||||||
|
if (*end == str || errno != 0)
|
||||||
|
return -1;
|
||||||
|
return YNORM(l);
|
||||||
}
|
}
|
||||||
|
|
||||||
coord
|
coord
|
||||||
|
|
|
@ -35,13 +35,13 @@ include ../../make.defs
|
||||||
LIB = $(SRCDIR)/lib/libgen.a
|
LIB = $(SRCDIR)/lib/libgen.a
|
||||||
NTLIB = $(SRCDIR)\lib\libgen.lib
|
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 \
|
emp_config.o getstarg.o getstring.o io.o \
|
||||||
ioqueue.o mapdist.o minmax.o numstr.o onearg.o \
|
ioqueue.o mapdist.o minmax.o numstr.o onearg.o \
|
||||||
parse.o plur.o queue.o round.o scthash.o \
|
parse.o plur.o queue.o round.o scthash.o \
|
||||||
strdup.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 \
|
emp_config.obj getstarg.obj getstring.obj \
|
||||||
io.obj ioqueue.obj mapdist.obj minmax.obj \
|
io.obj ioqueue.obj mapdist.obj minmax.obj \
|
||||||
numstr.obj onearg.obj parse.obj plur.obj queue.obj round.obj \
|
numstr.obj onearg.obj parse.obj plur.obj queue.obj round.obj \
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -54,61 +54,63 @@
|
||||||
* or 0 for none of the above.
|
* or 0 for none of the above.
|
||||||
*/
|
*/
|
||||||
ns_seltype
|
ns_seltype
|
||||||
sarg_type(s_char *ptr)
|
sarg_type(char *str)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
c = *ptr;
|
c = *str;
|
||||||
if (c == '@')
|
if (c == '@')
|
||||||
return NS_DIST;
|
return NS_DIST;
|
||||||
if (c == '*')
|
if (c == '*')
|
||||||
return NS_ALL;
|
return NS_ALL;
|
||||||
if (c == '#' || strchr(ptr, ',') != 0)
|
if (c == '#' || strchr(str, ',') != 0)
|
||||||
return NS_AREA;
|
return NS_AREA;
|
||||||
if (isdigit(c))
|
if (isdigit(c))
|
||||||
return NS_LIST;
|
return NS_LIST;
|
||||||
if (c == '~' || isupper(c) || islower(c))
|
if (c == '~' || isupper(c) || islower(c))
|
||||||
return NS_GROUP;
|
return NS_GROUP;
|
||||||
return 0;
|
return NS_UNDEF;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
sarg_xy(s_char *ptr, coord *xp, coord *yp)
|
sarg_xy(char *str, coord *xp, coord *yp)
|
||||||
{
|
{
|
||||||
if (sarg_type(ptr) != NS_AREA)
|
coord x, y;
|
||||||
|
struct natstr *np;
|
||||||
|
|
||||||
|
x = strtox(str, &str);
|
||||||
|
if (x < 0 || *str++ != ',')
|
||||||
return 0;
|
return 0;
|
||||||
*xp = atoip(&ptr);
|
y = strtoy(str, &str);
|
||||||
if (*ptr++ != ',')
|
if (y < 0 || *str != 0)
|
||||||
return 0;
|
return 0;
|
||||||
if (!isdigit(*ptr) && *ptr != '-')
|
if ((x ^ y) & 1)
|
||||||
return 0;
|
|
||||||
*yp = atoi(ptr);
|
|
||||||
inputxy(xp, yp, player->cnum);
|
|
||||||
if ((*xp ^ *yp) & 01)
|
|
||||||
return 0;
|
return 0;
|
||||||
|
np = getnatp(player->cnum);
|
||||||
|
*xp = xabs(np, x);
|
||||||
|
*yp = yabs(np, y);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* returns absolute coords */
|
/* returns absolute coords */
|
||||||
static int
|
static int
|
||||||
sarg_getrange(s_char *buf, register struct range *rp)
|
sarg_getrange(char *str, struct range *rp)
|
||||||
{
|
{
|
||||||
register int rlm;
|
long rlm;
|
||||||
register int c;
|
|
||||||
struct natstr *np;
|
struct natstr *np;
|
||||||
s_char *bp;
|
char *end;
|
||||||
|
|
||||||
bp = buf;
|
if (*str == '#') {
|
||||||
c = *bp;
|
|
||||||
if (c == '#') {
|
|
||||||
/*
|
/*
|
||||||
* realm #X where (X > 0 && X < MAXNOR)
|
* realm #X where (X > 0 && X < MAXNOR)
|
||||||
* Assumes realms are in abs coordinates
|
* Assumes realms are in abs coordinates
|
||||||
*/
|
*/
|
||||||
bp++;
|
if (*++str) {
|
||||||
rlm = atoi(bp);
|
rlm = strtol(str, &end, 10);
|
||||||
if (rlm < 0 || rlm >= MAXNOR)
|
if (end == str || *end != 0 || rlm < 0 || MAXNOR <= rlm)
|
||||||
return 0;
|
return 0;
|
||||||
|
} else
|
||||||
|
rlm = 0;
|
||||||
np = getnatp(player->cnum);
|
np = getnatp(player->cnum);
|
||||||
rp->lx = np->nat_b[rlm].b_xl;
|
rp->lx = np->nat_b[rlm].b_xl;
|
||||||
rp->hx = np->nat_b[rlm].b_xh;
|
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
|
* LX:LY,HX:HY where
|
||||||
* ly, hy are optional.
|
* ly, hy are optional.
|
||||||
*/
|
*/
|
||||||
if (!isdigit(c) && c != '-')
|
rp->lx = rp->hx = strtox(str, &str);
|
||||||
|
if (rp->lx < 0)
|
||||||
return 0;
|
return 0;
|
||||||
rp->lx = rp->hx = atoip(&bp);
|
if (*str == ':') {
|
||||||
if (*bp == ':') {
|
rp->hx = strtox(str + 1, &str);
|
||||||
bp++;
|
if (rp->hx < 0)
|
||||||
rp->hx = atoip(&bp);
|
return 0;
|
||||||
}
|
}
|
||||||
if (*bp++ != ',')
|
if (*str++ != ',')
|
||||||
return 0;
|
return 0;
|
||||||
if (!isdigit(c) && c != '-')
|
rp->ly = rp->hy = strtoy(str, &str);
|
||||||
|
if (rp->ly < 0)
|
||||||
return 0;
|
return 0;
|
||||||
rp->ly = rp->hy = atoip(&bp);
|
if (*str == ':') {
|
||||||
if (*bp == ':') {
|
rp->hy = strtoy(str + 1, &str);
|
||||||
bp++;
|
if (rp->hy < 0)
|
||||||
rp->hy = atoip(&bp);
|
return 0;
|
||||||
}
|
}
|
||||||
inputxy(&rp->lx, &rp->ly, player->cnum);
|
if (*str != 0)
|
||||||
inputxy(&rp->hx, &rp->hy, player->cnum);
|
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);
|
xysize_range(rp);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -148,9 +157,9 @@ sarg_getrange(s_char *buf, register struct range *rp)
|
||||||
* a result range struct
|
* a result range struct
|
||||||
*/
|
*/
|
||||||
int
|
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;
|
return 0;
|
||||||
rp->hx += 1;
|
rp->hx += 1;
|
||||||
if (rp->hx >= WORLD_X)
|
if (rp->hx >= WORLD_X)
|
||||||
|
@ -167,23 +176,28 @@ sarg_area(s_char *buf, register struct range *rp)
|
||||||
* result params
|
* result params
|
||||||
*/
|
*/
|
||||||
int
|
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 (*str++ != '@')
|
||||||
if (bp == 0 || *bp == 0)
|
|
||||||
return 0;
|
return 0;
|
||||||
if (*bp++ != '@')
|
x = strtox(str, &str);
|
||||||
|
if (x < 0 || *str++ != ',')
|
||||||
return 0;
|
return 0;
|
||||||
*xp = atoip(&bp);
|
y = strtoy(str, &str);
|
||||||
if (*bp++ != ',')
|
if (y < 0 || *str++ != ':')
|
||||||
return 0;
|
return 0;
|
||||||
*yp = atoip(&bp);
|
d = strtol(str, &end, 10);
|
||||||
if (*bp++ != ':')
|
if (end == str || d < 0 || *end != 0)
|
||||||
return 0;
|
return 0;
|
||||||
inputxy(xp, yp, player->cnum);
|
*dist = d;
|
||||||
*dist = atoi(bp);
|
np = getnatp(player->cnum);
|
||||||
|
*xp = xabs(np, x);
|
||||||
|
*yp = yabs(np, y);
|
||||||
return 1;
|
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
|
* list of idents; id/id/id/id/id
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
sarg_list(s_char *str, register int *list, int max)
|
sarg_list(char *str, int *list, int max)
|
||||||
{
|
{
|
||||||
register int i;
|
int i, j;
|
||||||
register int j;
|
long n;
|
||||||
register int n;
|
char *end;
|
||||||
s_char *arg;
|
|
||||||
|
|
||||||
arg = str;
|
i = 0;
|
||||||
for (i = 0; i < max; i++) {
|
do {
|
||||||
if (!isdigit(*arg)) {
|
n = strtol(str, &end, 10);
|
||||||
pr("Illegal character '%c'\n", *arg);
|
if (end == str || n < 0) {
|
||||||
|
pr("Illegal character '%c'\n", *str);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
n = atoip(&arg);
|
|
||||||
for (j = 0; j < i; j++) {
|
for (j = 0; j < i; j++) {
|
||||||
if (list[j] == n)
|
if (list[j] == n)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (j != i) {
|
if (j == i) {
|
||||||
/* duplicate; ignore */
|
if (i >= max) {
|
||||||
i--;
|
pr("List too long (limit is %d)\n", max);
|
||||||
} else
|
return 0;
|
||||||
list[i] = n;
|
}
|
||||||
if (*arg == 0)
|
list[i++] = n;
|
||||||
break;
|
|
||||||
if (*arg != '/') {
|
|
||||||
pr("Expecting '/', got '%c'\n", *arg);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
arg++;
|
str = end;
|
||||||
if (*arg == 0)
|
} while (*str++ == '/');
|
||||||
break;
|
|
||||||
|
if (str[-1] != 0) {
|
||||||
|
pr("Expecting '/', got '%c'\n", str[-1]);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
return i + 1;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue