diff --git a/sh.decls.h b/sh.decls.h index a863fede..395f5e7b 100644 --- a/sh.decls.h +++ b/sh.decls.h @@ -126,8 +126,8 @@ extern int find_cmd (Char *, int); * sh.exp.c */ extern Char *filetest (Char *, Char ***, int); -extern tcsh_number_t expr (Char ***); -extern tcsh_number_t exp0 (Char ***, int); +extern unsigned tcsh_number_t expr (Char ***); +extern unsigned tcsh_number_t exp0 (Char ***, int); /* * sh.file.c @@ -379,8 +379,8 @@ extern void mypipe (int *); extern struct varent *adrof1 (const Char *, struct varent *); extern void doset (Char **, struct command *); extern void dolet (Char **, struct command *); -extern Char *putn (tcsh_number_t); -extern tcsh_number_t getn (const Char *); +extern Char *putn (unsigned tcsh_number_t); +extern unsigned tcsh_number_t getn (const Char *); extern Char *value1 (Char *, struct varent *); extern void setcopy (const Char *, const Char *, int); extern void setv (const Char *, Char *, int); diff --git a/sh.err.c b/sh.err.c index 9d9600ae..1ed53200 100644 --- a/sh.err.c +++ b/sh.err.c @@ -188,7 +188,9 @@ extern int enterhist; #define ERR_BADCOLORVAR 134 #define ERR_EOF 135 #define ERR_UNAVAILABLE 136 -#define NO_ERRORS 137 +#define ERR_DIVOF 137 +#define ERR_MODOF 138 +#define NO_ERRORS 139 static const char *elst[NO_ERRORS] INIT_ZERO_STRUCT; @@ -367,7 +369,8 @@ errinit(void) elst[ERR_BADCOLORVAR] = CSAVS(1, 137, "Unknown %s color variable '%c%c'"); elst[ERR_EOF] = CSAVS(1, 138, "Unexpected end of file"); elst[ERR_UNAVAILABLE] = CSAVS(1, 139, "%s: Feature is not available for this platform"); - + elst[ERR_DIVOF] = CSAVS(1, 140, "Division overflow"); + elst[ERR_MODOF] = CSAVS(1, 141, "Mod overflow"); } /* Cleanup data. */ diff --git a/sh.exp.c b/sh.exp.c index f291a59d..925f776f 100644 --- a/sh.exp.c +++ b/sh.exp.c @@ -51,11 +51,11 @@ #define NOTEQMATCH 8 static int sh_access (const Char *, int); -static tcsh_number_t exp1 (Char ***, int); -static tcsh_number_t exp2x (Char ***, int); -static tcsh_number_t exp2a (Char ***, int); -static tcsh_number_t exp2b (Char ***, int); -static tcsh_number_t exp2c (Char ***, int); +static unsigned tcsh_number_t exp1 (Char ***, int); +static unsigned tcsh_number_t exp2x (Char ***, int); +static unsigned tcsh_number_t exp2a (Char ***, int); +static unsigned tcsh_number_t exp2b (Char ***, int); +static unsigned tcsh_number_t exp2c (Char ***, int); static Char *exp3 (Char ***, int); static Char *exp3a (Char ***, int); static Char *exp4 (Char ***, int); @@ -63,7 +63,7 @@ static Char *exp5 (Char ***, int); static Char *exp6 (Char ***, int); static void evalav (Char **); static int isa (Char *, int); -static tcsh_number_t egetn (const Char *); +static unsigned tcsh_number_t egetn (const Char *); #ifdef EDEBUG static void etracc (const char *, const Char *, Char ***); @@ -177,20 +177,20 @@ sh_access(const Char *fname, int mode) #endif /* !POSIX */ } -tcsh_number_t +unsigned tcsh_number_t expr(Char ***vp) { return (exp0(vp, 0)); } -tcsh_number_t +unsigned tcsh_number_t exp0(Char ***vp, int ignore) { - tcsh_number_t p1 = exp1(vp, ignore); + unsigned tcsh_number_t p1 = exp1(vp, ignore); etraci("exp0 p1", p1, vp); while (**vp && eq(**vp, STRor2)) { - int p2; + unsigned tcsh_number_t p2; (*vp)++; @@ -206,14 +206,14 @@ exp0(Char ***vp, int ignore) return (p1); } -static tcsh_number_t +static unsigned tcsh_number_t exp1(Char ***vp, int ignore) { - tcsh_number_t p1 = exp2x(vp, ignore); + unsigned tcsh_number_t p1 = exp2x(vp, ignore); etraci("exp1 p1", p1, vp); while (**vp && eq(**vp, STRand2)) { - tcsh_number_t p2; + unsigned tcsh_number_t p2; (*vp)++; p2 = compat_expr ? @@ -230,14 +230,14 @@ exp1(Char ***vp, int ignore) return (p1); } -static tcsh_number_t +static unsigned tcsh_number_t exp2x(Char ***vp, int ignore) { - tcsh_number_t p1 = exp2a(vp, ignore); + unsigned tcsh_number_t p1 = exp2a(vp, ignore); etraci("exp2x p1", p1, vp); while (**vp && eq(**vp, STRor)) { - tcsh_number_t p2; + unsigned tcsh_number_t p2; (*vp)++; p2 = compat_expr ? @@ -253,14 +253,14 @@ exp2x(Char ***vp, int ignore) return (p1); } -static tcsh_number_t +static unsigned tcsh_number_t exp2a(Char ***vp, int ignore) { - tcsh_number_t p1 = exp2b(vp, ignore); + unsigned tcsh_number_t p1 = exp2b(vp, ignore); etraci("exp2a p1", p1, vp); while (**vp && eq(**vp, STRcaret)) { - tcsh_number_t p2; + unsigned tcsh_number_t p2; (*vp)++; p2 = compat_expr ? @@ -276,14 +276,14 @@ exp2a(Char ***vp, int ignore) return (p1); } -static tcsh_number_t +static unsigned tcsh_number_t exp2b(Char ***vp, int ignore) { - tcsh_number_t p1 = exp2c(vp, ignore); + unsigned tcsh_number_t p1 = exp2c(vp, ignore); etraci("exp2b p1", p1, vp); while (**vp && eq(**vp, STRand)) { - tcsh_number_t p2; + unsigned tcsh_number_t p2; (*vp)++; p2 = compat_expr ? @@ -299,12 +299,12 @@ exp2b(Char ***vp, int ignore) return (p1); } -static tcsh_number_t +static unsigned tcsh_number_t exp2c(Char ***vp, int ignore) { Char *p1 = exp3(vp, ignore); Char *p2; - tcsh_number_t i; + unsigned tcsh_number_t i; cleanup_push(p1, xfree); etracc("exp2c p1", p1, vp); @@ -346,7 +346,7 @@ static Char * exp3(Char ***vp, int ignore) { Char *p1, *p2; - tcsh_number_t i; + unsigned tcsh_number_t i; p1 = exp3a(vp, ignore); etracc("exp3 p1", p1, vp); @@ -362,21 +362,58 @@ exp3(Char ***vp, int ignore) etracc("exp3 p2", p2, vp); if (!(ignore & TEXP_IGNORE)) switch ((int)i) { + tcsh_number_t is; case GTR: - i = egetn(p1) > egetn(p2); + if ((i = egetn(p1)) & + ~(~(unsigned tcsh_number_t) 0 >> 1)) + is = -(tcsh_number_t) -i; + else + is = i; + if ((i = egetn(p2)) & + ~(~(unsigned tcsh_number_t) 0 >> 1)) + i = is > -(tcsh_number_t) -i; + else + i = is > (tcsh_number_t) i; break; case GTR | 1: - i = egetn(p1) >= egetn(p2); + if ((i = egetn(p1)) & + ~(~(unsigned tcsh_number_t) 0 >> 1)) + is = -(tcsh_number_t) -i; + else + is = i; + if ((i = egetn(p2)) & + ~(~(unsigned tcsh_number_t) 0 >> 1)) + i = is >= -(tcsh_number_t) -i; + else + i = is >= (tcsh_number_t) i; break; case LSS: - i = egetn(p1) < egetn(p2); + if ((i = egetn(p1)) & + ~(~(unsigned tcsh_number_t) 0 >> 1)) + is = -(tcsh_number_t) -i; + else + is = i; + if ((i = egetn(p2)) & + ~(~(unsigned tcsh_number_t) 0 >> 1)) + i = is < -(tcsh_number_t) -i; + else + i = is < (tcsh_number_t) i; break; case LSS | 1: - i = egetn(p1) <= egetn(p2); + if ((i = egetn(p1)) & + ~(~(unsigned tcsh_number_t) 0 >> 1)) + is = -(tcsh_number_t) -i; + else + is = i; + if ((i = egetn(p2)) & + ~(~(unsigned tcsh_number_t) 0 >> 1)) + i = is <= -(tcsh_number_t) -i; + else + i = is <= (tcsh_number_t) i; break; } cleanup_until(p1); @@ -393,7 +430,7 @@ exp3a(Char ***vp, int ignore) { Char *p1, *p2; const Char *op; - tcsh_number_t i; + unsigned tcsh_number_t i; p1 = exp4(vp, ignore); etracc("exp3a p1", p1, vp); @@ -421,7 +458,7 @@ static Char * exp4(Char ***vp, int ignore) { Char *p1, *p2; - tcsh_number_t i = 0; + unsigned tcsh_number_t i = 0; p1 = exp5(vp, ignore); etracc("exp4 p1", p1, vp); @@ -458,7 +495,7 @@ static Char * exp5(Char ***vp, int ignore) { Char *p1, *p2; - tcsh_number_t i = 0; + unsigned tcsh_number_t i = 0; p1 = exp6(vp, ignore); etracc("exp5 p1", p1, vp); @@ -482,23 +519,44 @@ exp5(Char ***vp, int ignore) etracc("exp5 p2", p2, vp); if (!(ignore & TEXP_IGNORE)) switch (op[0]) { + tcsh_number_t is; case '*': i = egetn(p1) * egetn(p2); break; case '/': - i = egetn(p2); - if (i == 0) + if ((i = egetn(p2)) == 0) stderror(ERR_DIV0); - i = egetn(p1) / i; + if (i & ~(~(unsigned tcsh_number_t) 0 >> 1)) + is = -(tcsh_number_t) -i; + else + is = i; + if ((i = egetn(p1)) == + ~(~(unsigned tcsh_number_t) 0 >> 1) && + is == -1) + stderror(ERR_DIVOF); + if (i & ~(~(unsigned tcsh_number_t) 0 >> 1)) + i = -(tcsh_number_t) -i / is; + else + i /= is; break; case '%': - i = egetn(p2); - if (i == 0) + if ((i = egetn(p2)) == 0) stderror(ERR_MOD0); - i = egetn(p1) % i; + if (i & ~(~(unsigned tcsh_number_t) 0 >> 1)) + is = -(tcsh_number_t) -i; + else + is = i; + if ((i = egetn(p1)) == + ~(~(unsigned tcsh_number_t) 0 >> 1) && + is == -1) + stderror(ERR_MODOF); + if (i & ~(~(unsigned tcsh_number_t) 0 >> 1)) + i = -(tcsh_number_t) -i % is; + else + i %= is; break; } cleanup_until(p1); @@ -513,8 +571,8 @@ exp5(Char ***vp, int ignore) static Char * exp6(Char ***vp, int ignore) { - tcsh_number_t ccode; - tcsh_number_t i = 0; + unsigned tcsh_number_t ccode, + i = 0; Char *cp; if (**vp == 0) @@ -1022,7 +1080,7 @@ isa(Char *cp, int what) return (0); } -static tcsh_number_t +static unsigned tcsh_number_t egetn(const Char *cp) { if (*cp && *cp != '-' && !Isdigit(*cp)) diff --git a/sh.func.c b/sh.func.c index a9c0dd6f..9027ddb6 100644 --- a/sh.func.c +++ b/sh.func.c @@ -350,7 +350,7 @@ islogin(void) void doif(Char **v, struct command *kp) { - int i; + unsigned tcsh_number_t i; Char **vv; v++; @@ -558,7 +558,7 @@ doforeach(Char **v, struct command *c) void dowhile(Char **v, struct command *c) { - int status; + unsigned tcsh_number_t status; int again = whyles != 0 && SEEKEQ(&whyles->w_start, &lineloc) && whyles->w_fename == 0; diff --git a/sh.h b/sh.h index 19bf10d6..6fcaa8d2 100644 --- a/sh.h +++ b/sh.h @@ -246,9 +246,9 @@ static __inline void tcsh_ignore(intptr_t a) #endif /* __HP_CXD_SPP && !__hpux */ #ifdef HAVE_LONG_LONG -typedef long long tcsh_number_t; +#define tcsh_number_t long long #else -typedef long tcsh_number_t; +#define tcsh_number_t long #endif /* * This macro compares the st_dev field of struct stat. On aix on ibmESA diff --git a/sh.set.c b/sh.set.c index ac73af9f..1e541ca1 100644 --- a/sh.set.c +++ b/sh.set.c @@ -45,8 +45,8 @@ static Char *getinx (Char *, int *); static void asx (Char *, int, Char *); static struct varent *getvx (Char *, int); static Char *xset (Char *, Char ***); -static Char *operate (int, Char *, Char *); -static void putn1 (tcsh_number_t); +static Char *operate (Char, Char *, Char *); +static void putn1 (unsigned tcsh_number_t); static struct varent *madrof (Char *, struct varent *); static void unsetv1 (struct varent *); static void exportpath (Char **); @@ -491,13 +491,13 @@ xset(Char *cp, Char ***vp) } static Char * -operate(int op, Char *vp, Char *p) +operate(Char op, Char *vp, Char *p) { Char opr[2]; Char *vec[5]; Char **v = vec; Char **vecp = v; - tcsh_number_t i; + unsigned tcsh_number_t i; if (op != '=') { if (*vp) @@ -519,34 +519,47 @@ operate(int op, Char *vp, Char *p) static Char *putp; Char * -putn(tcsh_number_t n) +putn(unsigned tcsh_number_t n) { Char nbuf[1024]; /* Enough even for octal */ putp = nbuf; - if (n < 0) { + if (n & ~(~(unsigned tcsh_number_t) 0 >> 1)) { n = -n; *putp++ = '-'; } putn1(n); +#ifdef IS_ASCII *putp = 0; +#endif return (Strsave(nbuf)); } static void -putn1(tcsh_number_t n) +putn1(unsigned tcsh_number_t n) { +#ifndef IS_ASCII + sprintf(putp, "%l" +#ifdef HAVE_LONG_LONG + "l" +#endif /* HAVE_LONG_LONG */ + "u", n); +#else if (n > 9) putn1(n / 10); *putp++ = (Char)(n % 10 + '0'); +#endif /* !IS_ASCII */ } -tcsh_number_t +unsigned tcsh_number_t getn(const Char *cp) { - tcsh_number_t n; + unsigned tcsh_number_t n; int sign; int base; +#ifndef IS_ASCII + char cps[2]; +#endif if (!cp) /* PWP: extra error checking */ stderror(ERR_NAME | ERR_BADNUM); @@ -566,12 +579,29 @@ getn(const Char *cp) else base = 10; +#ifndef IS_ASCII + cps[1] = +#endif n = 0; while (Isdigit(*cp)) { +#ifndef IS_ASCII + unsigned tcsh_number_t ns; +#endif + if (base == 8 && *cp >= '8') stderror(ERR_NAME | ERR_BADNUM); +#ifndef IS_ASCII + cps[0] = *cp++; + sscanf(cps, "%l" +#ifdef HAVE_LONG_LONG + "l" +#endif /* HAVE_LONG_LONG */ + "u", &ns); + n = n * base + ns; +#else n = n * base + *cp++ - '0'; +#endif /* !IS_ASCII */ } if (*cp) stderror(ERR_NAME | ERR_BADNUM);