diff options
author | Jim Meyering <jim@meyering.net> | 2001-08-18 16:04:16 +0000 |
---|---|---|
committer | Jim Meyering <jim@meyering.net> | 2001-08-18 16:04:16 +0000 |
commit | c6c2071280dc3bbf048381a002da551040f3e3ad (patch) | |
tree | dbb41965e87ab6a64bc9f4f6cda62973799bcbae | |
parent | 28b012a9cc7b971e6e29a437ca7b5db637e559f1 (diff) | |
download | coreutils-c6c2071280dc3bbf048381a002da551040f3e3ad.tar.xz |
Modify 'expr' so that it uses intmax_t, not int, to calculate
the value of integer expressions.
(struct valinfo.i): Now intmax_t, not int.
(docolon, int_value, str_value, isstring, nextarg, toarith,
freev, tostring, trace): Remove unnecessary forward decls.
(int_value, printv, tostring, toarith, arithf, arithdivf, docolon,
eval6, eval4, eval3): Do integer arithmetic using intmax_t, not int.
(docolon): Don't assume size_t fits in int.
-rw-r--r-- | src/expr.c | 84 |
1 files changed, 49 insertions, 35 deletions
diff --git a/src/expr.c b/src/expr.c index 7dea02b75..50930d289 100644 --- a/src/expr.c +++ b/src/expr.c @@ -62,7 +62,7 @@ struct valinfo TYPE type; /* Which kind. */ union { /* The value itself. */ - int i; + intmax_t i; char *s; } u; }; @@ -78,22 +78,10 @@ static char **args; /* The name this program was run with. */ char *program_name; -static VALUE *docolon PARAMS ((VALUE *sv, VALUE *pv)); static VALUE *eval PARAMS ((void)); -static VALUE *int_value PARAMS ((int i)); -static VALUE *str_value PARAMS ((char *s)); -static int isstring PARAMS ((VALUE *v)); -static int nextarg PARAMS ((char *str)); static int nomoreargs PARAMS ((void)); static int null PARAMS ((VALUE *v)); -static int toarith PARAMS ((VALUE *v)); -static void freev PARAMS ((VALUE *v)); static void printv PARAMS ((VALUE *v)); -static void tostring PARAMS ((VALUE *v)); - -#ifdef EVAL_TRACE -static void trace (); -#endif void usage (int status) @@ -197,7 +185,7 @@ main (int argc, char **argv) /* Return a VALUE for I. */ static VALUE * -int_value (int i) +int_value (intmax_t i) { VALUE *v; @@ -230,22 +218,46 @@ freev (VALUE *v) OLD (v); } +/* Store a printable representation of I somewhere into BUF, and + return a pointer to the stored representation. */ + +static char * +inttostr (intmax_t i, char buf[INT_STRLEN_BOUND (intmax_t) + 1]) +{ + uintmax_t ui = i; + char *p = buf + INT_STRLEN_BOUND (intmax_t); + *p = '\0'; + if (i < 0) + ui = -ui; + do + *--p = '0' + ui % 10; + while ((ui /= 10) != 0); + if (i < 0) + *--p = '-'; + return p; +} + /* Print VALUE V. */ static void printv (VALUE *v) { + char *p; + char buf[INT_STRLEN_BOUND (intmax_t) + 1]; + switch (v->type) { case integer: - printf ("%d\n", v->u.i); + p = inttostr (v->u.i, buf); break; case string: - printf ("%s\n", v->u.s); + p = v->u.s; break; default: abort (); } + + puts (p); } /* Return nonzero if V is a null-string or zero-number. */ @@ -277,14 +289,12 @@ isstring (VALUE *v) static void tostring (VALUE *v) { - char *temp; + char buf[INT_STRLEN_BOUND (intmax_t) + 1]; switch (v->type) { case integer: - temp = xmalloc (4 * (sizeof (int) / sizeof (char))); - sprintf (temp, "%d", v->u.i); - v->u.s = temp; + v->u.s = xstrdup (inttostr (v->u.i, buf)); v->type = string; break; case string: @@ -299,7 +309,7 @@ tostring (VALUE *v) static int toarith (VALUE *v) { - int i; + intmax_t i; int neg; char *cp; @@ -378,8 +388,8 @@ int name (l, r) VALUE *l; VALUE *r; \ /* The arithmetic operator handling functions. */ #define arithf(name, op) \ -static \ -int name (l, r) VALUE *l; VALUE *r; \ +static intmax_t \ +name (l, r) VALUE *l; VALUE *r; \ { \ if (!toarith (l) || !toarith (r)) \ error (2, 0, _("non-numeric argument")); \ @@ -387,12 +397,13 @@ int name (l, r) VALUE *l; VALUE *r; \ } #define arithdivf(name, op) \ -int name (l, r) VALUE *l; VALUE *r; \ +static intmax_t \ +name (l, r) VALUE *l; VALUE *r; \ { \ if (!toarith (l) || !toarith (r)) \ error (2, 0, _("non-numeric argument")); \ if (r->u.i == 0) \ - error (2, 0, _("division by zero")); \ + error (2, 0, _("division by zero")); \ return l->u.i op r->u.i; \ } @@ -432,7 +443,8 @@ docolon (VALUE *sv, VALUE *pv) const char *errmsg; struct re_pattern_buffer re_buffer; struct re_registers re_regs; - int len; + size_t len; + int matchlen; tostring (sv); tostring (pv); @@ -449,6 +461,8 @@ of the basic regular expression is not portable; it is being ignored"), memset (&re_buffer, 0, sizeof (re_buffer)); memset (&re_regs, 0, sizeof (re_regs)); re_buffer.allocated = 2 * len; + if (re_buffer.allocated < len) + xalloc_die (); re_buffer.buffer = (unsigned char *) xmalloc (re_buffer.allocated); re_buffer.translate = 0; re_syntax_options = RE_SYNTAX_POSIX_BASIC; @@ -456,8 +470,8 @@ of the basic regular expression is not portable; it is being ignored"), if (errmsg) error (2, 0, "%s", errmsg); - len = re_match (&re_buffer, sv->u.s, strlen (sv->u.s), 0, &re_regs); - if (len >= 0) + matchlen = re_match (&re_buffer, sv->u.s, strlen (sv->u.s), 0, &re_regs); + if (0 <= matchlen) { /* Were \(...\) used? */ if (re_buffer.re_nsub > 0)/* was (re_regs.start[1] >= 0) */ @@ -466,7 +480,7 @@ of the basic regular expression is not portable; it is being ignored"), v = str_value (sv->u.s + re_regs.start[1]); } else - v = int_value (len); + v = int_value (matchlen); } else { @@ -557,7 +571,7 @@ eval6 (void) tostring (l); tostring (r); v = int_value (strcspn (l->u.s, r->u.s) + 1); - if (v->u.i == (int) strlen (l->u.s) + 1) + if (v->u.i == strlen (l->u.s) + 1) v->u.i = 0; freev (l); freev (r); @@ -571,7 +585,7 @@ eval6 (void) i2 = eval6 (); tostring (l); if (!toarith (i1) || !toarith (i2) - || i1->u.i > (int) strlen (l->u.s) + || strlen (l->u.s) < i1->u.i || i1->u.i <= 0 || i2->u.i <= 0) v = str_value (""); else @@ -628,8 +642,8 @@ eval4 (void) { VALUE *l; VALUE *r; - int (*fxn) (); - int val; + intmax_t (*fxn) (); + intmax_t val; #ifdef EVAL_TRACE trace ("eval4"); @@ -661,8 +675,8 @@ eval3 (void) { VALUE *l; VALUE *r; - int (*fxn) (); - int val; + intmax_t (*fxn) (); + intmax_t val; #ifdef EVAL_TRACE trace ("eval3"); |