diff options
-rw-r--r-- | coreutils/expr.c | 85 |
1 files changed, 45 insertions, 40 deletions
diff --git a/coreutils/expr.c b/coreutils/expr.c index b7e33de..b082de1 100644 --- a/coreutils/expr.c +++ b/coreutils/expr.c @@ -62,15 +62,18 @@ struct valinfo { typedef struct valinfo VALUE; /* The arguments given to the program, minus the program name. */ -static char **args; +struct globals { + char **args; +}; +#define G (*(struct globals*)&bb_common_bufsiz1) static VALUE *docolon(VALUE * sv, VALUE * pv); static VALUE *eval(void); static VALUE *int_value(arith_t i); static VALUE *str_value(const char *s); -static int nextarg(const char *str); +static bool nextarg(const char *str); static int null(VALUE * v); -static int toarith(VALUE * v); +static bool toarith(VALUE * v); static void freev(VALUE * v); static void tostring(VALUE * v); @@ -83,10 +86,10 @@ int expr_main(int argc, char **argv) bb_error_msg_and_die("too few arguments"); } - args = argv + 1; + G.args = argv + 1; v = eval(); - if (*args) + if (*G.args) bb_error_msg_and_die("syntax error"); if (v->type == integer) @@ -152,7 +155,7 @@ static void tostring(VALUE * v) /* Coerce V to an integer value. Return 1 on success, 0 on failure. */ -static int toarith(VALUE * v) +static bool toarith(VALUE * v) { if (v->type == string) { arith_t i; @@ -173,11 +176,11 @@ static int toarith(VALUE * v) /* Return nonzero if the next token matches STR exactly. STR must not be NULL. */ -static int nextarg(const char *str) +static bool nextarg(const char *str) { - if (*args == NULL) + if (*G.args == NULL) return 0; - return strcmp(*args, str) == 0; + return strcmp(*G.args, str) == 0; } /* The comparison operator handling functions. */ @@ -281,53 +284,57 @@ static VALUE *eval7(void) { VALUE *v; - if (!*args) + if (!*G.args) bb_error_msg_and_die("syntax error"); if (nextarg("(")) { - args++; + G.args++; v = eval(); if (!nextarg(")")) bb_error_msg_and_die("syntax error"); - args++; + G.args++; return v; } if (nextarg(")")) bb_error_msg_and_die("syntax error"); - return str_value(*args++); + return str_value(*G.args++); } /* Handle match, substr, index, length, and quote keywords. */ static VALUE *eval6(void) { - VALUE *l, *r, *v, *i1, *i2; + VALUE *l, *r, *v = NULL /* silence gcc */, *i1, *i2; + const char * const keywords[] = { + "quote", "length", "match", "index", "substr", NULL + }; - if (nextarg("quote")) { - args++; - if (!*args) + smalluint key = *G.args ? index_in_str_array(keywords, *G.args) + 1 : 0; + if (key == 0) /* not a keyword */ + return eval7(); + G.args++; /* We have a valid token, so get the next argument. */ + if (key == 1) { /* quote */ + if (!*G.args) bb_error_msg_and_die("syntax error"); - return str_value(*args++); - } else if (nextarg("length")) { - args++; + return str_value(*G.args++); + } + if (key == 2) { /* length */ r = eval6(); tostring(r); v = int_value(strlen(r->u.s)); freev(r); - return v; - } else if (nextarg("match")) { - args++; + } else l = eval6(); + + if (key == 3) { /* match */ r = eval6(); v = docolon(l, r); freev(l); freev(r); - return v; - } else if (nextarg("index")) { - args++; - l = eval6(); + } + if (key == 4) { /* index */ r = eval6(); tostring(l); tostring(r); @@ -336,10 +343,8 @@ static VALUE *eval6(void) v->u.i = 0; freev(l); freev(r); - return v; - } else if (nextarg("substr")) { - args++; - l = eval6(); + } + if (key == 5) { /* substr */ i1 = eval6(); i2 = eval6(); tostring(l); @@ -355,9 +360,9 @@ static VALUE *eval6(void) freev(l); freev(i1); freev(i2); - return v; - } else - return eval7(); + } + return v; + } /* Handle : operator (pattern matching). @@ -369,7 +374,7 @@ static VALUE *eval5(void) l = eval6(); while (nextarg(":")) { - args++; + G.args++; r = eval6(); v = docolon(l, r); freev(l); @@ -397,7 +402,7 @@ static VALUE *eval4(void) op = '%'; else return l; - args++; + G.args++; r = eval5(); val = arithmetic_common(l, r, op); freev(l); @@ -422,7 +427,7 @@ static VALUE *eval3(void) op = '-'; else return l; - args++; + G.args++; r = eval4(); val = arithmetic_common(l, r, op); freev(l); @@ -455,7 +460,7 @@ static VALUE *eval2(void) op = '>'; else return l; - args++; + G.args++; r = eval3(); toarith(l); toarith(r); @@ -474,7 +479,7 @@ static VALUE *eval1(void) l = eval2(); while (nextarg("&")) { - args++; + G.args++; r = eval2(); if (null(l) || null(r)) { freev(l); @@ -494,7 +499,7 @@ static VALUE *eval(void) l = eval1(); while (nextarg("|")) { - args++; + G.args++; r = eval1(); if (null(l)) { freev(l); |