X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=coreutils%2Fexpr.c;h=b23de8e9f8b5061125f5aa7cbe14f6e774ce75f2;hb=5fe8d5b9c5930497ecf47817ec3af66bebec52c0;hp=e5816371ad4d174ff8d1c6511a41726d586a5ba1;hpb=c7bda1ce659294d6e22c06e087f6f265983c7578;p=oweals%2Fbusybox.git diff --git a/coreutils/expr.c b/coreutils/expr.c index e5816371a..b23de8e9f 100644 --- a/coreutils/expr.c +++ b/coreutils/expr.c @@ -7,26 +7,28 @@ * * Busybox modifications * Copyright (c) 2000 Edward Betts . - * Aug 2003 Vladimir Oleynik - reduced 464 bytes. + * Copyright (C) 2003-2005 Vladimir Oleynik + * - reduced 464 bytes. + * - 64 math support * - * 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 + * 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. + * 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 + * 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 * */ /* This program evaluates expressions. Each token (operator, operand, - * parenthesis) of the expression must be a seperate argument. The + * parenthesis) of the expression must be a separate argument. The * parser used is a reasonably general one, though any incarnation of * it is language-specific. It is especially nice for expressions. * @@ -52,11 +54,23 @@ enum valtype { }; typedef enum valtype TYPE; +#if ENABLE_EXPR_MATH_SUPPORT_64 +typedef int64_t arith_t; +#define PF_REZ "ll" +#define PF_REZ_TYPE (long long) +#define STRTOL(s, e, b) strtoll(s, e, b) +#else +typedef long arith_t; +#define PF_REZ "l" +#define PF_REZ_TYPE (long) +#define STRTOL(s, e, b) strtol(s, e, b) +#endif + /* A value is.... */ struct valinfo { - TYPE type; /* Which kind. */ - union { /* The value itself. */ - int i; + TYPE type; /* Which kind. */ + union { /* The value itself. */ + arith_t i; char *s; } u; }; @@ -67,7 +81,7 @@ static char **args; static VALUE *docolon (VALUE *sv, VALUE *pv); static VALUE *eval (void); -static VALUE *int_value (int i); +static VALUE *int_value (arith_t i); static VALUE *str_value (char *s); static int nextarg (char *str); static int null (VALUE *v); @@ -90,7 +104,7 @@ int expr_main (int argc, char **argv) bb_error_msg_and_die ("syntax error"); if (v->type == integer) - printf ("%d\n", v->u.i); + printf ("%" PF_REZ "d\n", PF_REZ_TYPE v->u.i); else puts (v->u.s); @@ -99,7 +113,7 @@ int expr_main (int argc, char **argv) /* Return a VALUE for I. */ -static VALUE *int_value (int i) +static VALUE *int_value (arith_t i) { VALUE *v; @@ -147,7 +161,7 @@ static int null (VALUE *v) static void tostring (VALUE *v) { if (v->type == integer) { - bb_xasprintf (&(v->u.s), "%d", v->u.i); + v->u.s = bb_xasprintf ("%" PF_REZ "d", PF_REZ_TYPE v->u.i); v->type = string; } } @@ -157,12 +171,12 @@ static void tostring (VALUE *v) static int toarith (VALUE *v) { if(v->type == string) { - int i; + arith_t i; char *e; /* Don't interpret the empty string as an integer. */ /* Currently does not worry about overflow or int/long differences. */ - i = (int) strtol(v->u.s, &e, 10); + i = STRTOL(v->u.s, &e, 10); if ((v->u.s == e) || *e) return 0; free (v->u.s); @@ -214,9 +228,9 @@ static int cmp_common (VALUE *l, VALUE *r, int op) /* The arithmetic operator handling functions. */ -static int arithmetic_common (VALUE *l, VALUE *r, int op) +static arith_t arithmetic_common (VALUE *l, VALUE *r, int op) { - int li, ri; + arith_t li, ri; if (!toarith (l) || !toarith (r)) bb_error_msg_and_die ("non-numeric argument"); @@ -245,10 +259,9 @@ static int arithmetic_common (VALUE *l, VALUE *r, int op) static VALUE *docolon (VALUE *sv, VALUE *pv) { VALUE *v; - const char *errmsg; - struct re_pattern_buffer re_buffer; - struct re_registers re_regs; - int len; + regex_t re_buffer; + const int NMATCH = 2; + regmatch_t re_regs[NMATCH]; tostring (sv); tostring (pv); @@ -260,27 +273,22 @@ of a basic regular expression is not portable; it is being ignored", pv->u.s); } - len = strlen (pv->u.s); memset (&re_buffer, 0, sizeof (re_buffer)); - memset (&re_regs, 0, sizeof (re_regs)); - re_buffer.allocated = 2 * len; - re_buffer.buffer = (unsigned char *) xmalloc (re_buffer.allocated); - re_buffer.translate = 0; - re_syntax_options = RE_SYNTAX_POSIX_BASIC; - errmsg = re_compile_pattern (pv->u.s, len, &re_buffer); - if (errmsg) { - bb_error_msg_and_die("%s", errmsg); - } - - len = re_match (&re_buffer, sv->u.s, strlen (sv->u.s), 0, &re_regs); - if (len >= 0) { + memset (re_regs, 0, sizeof (*re_regs)); + if( regcomp (&re_buffer, pv->u.s, 0) != 0 ) + bb_error_msg_and_die("Invalid regular expression"); + + /* expr uses an anchored pattern match, so check that there was a + * match and that the match starts at offset 0. */ + if (regexec (&re_buffer, sv->u.s, NMATCH, re_regs, 0) != REG_NOMATCH && + re_regs[0].rm_so == 0) { /* Were \(...\) used? */ - if (re_buffer.re_nsub > 0) { /* was (re_regs.start[1] >= 0) */ - sv->u.s[re_regs.end[1]] = '\0'; - v = str_value (sv->u.s + re_regs.start[1]); + if (re_buffer.re_nsub > 0) { + sv->u.s[re_regs[1].rm_eo] = '\0'; + v = str_value (sv->u.s + re_regs[1].rm_so); } else - v = int_value (len); + v = int_value (re_regs[0].rm_eo); } else { /* Match failed -- return the right kind of null. */ @@ -289,7 +297,6 @@ of a basic regular expression is not portable; it is being ignored", else v = int_value (0); } - free (re_buffer.buffer); return v; } @@ -353,7 +360,7 @@ static VALUE *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 == (arith_t) strlen (l->u.s) + 1) v->u.i = 0; freev (l); freev (r); @@ -366,13 +373,13 @@ static VALUE *eval6 (void) i2 = eval6 (); tostring (l); if (!toarith (i1) || !toarith (i2) - || i1->u.i > (int) strlen (l->u.s) + || i1->u.i > (arith_t) strlen (l->u.s) || i1->u.i <= 0 || i2->u.i <= 0) v = str_value (""); else { v = xmalloc (sizeof(VALUE)); v->type = string; - v->u.s = bb_xstrndup(l->u.s + i1->u.i - 1, i2->u.i); + v->u.s = bb_xstrndup(l->u.s + i1->u.i - 1, i2->u.i); } freev (l); freev (i1); @@ -407,7 +414,8 @@ static VALUE *eval5 (void) static VALUE *eval4 (void) { VALUE *l, *r; - int op, val; + int op; + arith_t val; l = eval5 (); while (1) { @@ -433,7 +441,8 @@ static VALUE *eval4 (void) static VALUE *eval3 (void) { VALUE *l, *r; - int op, val; + int op; + arith_t val; l = eval4 (); while (1) { @@ -457,7 +466,8 @@ static VALUE *eval3 (void) static VALUE *eval2 (void) { VALUE *l, *r; - int op, val; + int op; + arith_t val; l = eval3 (); while (1) {