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);
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)
/* 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;
/* 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. */
{
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);
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);
freev(l);
freev(i1);
freev(i2);
- return v;
- } else
- return eval7();
+ }
+ return v;
+
}
/* Handle : operator (pattern matching).
l = eval6();
while (nextarg(":")) {
- args++;
+ G.args++;
r = eval6();
v = docolon(l, r);
freev(l);
op = '%';
else
return l;
- args++;
+ G.args++;
r = eval5();
val = arithmetic_common(l, r, op);
freev(l);
op = '-';
else
return l;
- args++;
+ G.args++;
r = eval4();
val = arithmetic_common(l, r, op);
freev(l);
op = '>';
else
return l;
- args++;
+ G.args++;
r = eval3();
toarith(l);
toarith(r);
l = eval2();
while (nextarg("&")) {
- args++;
+ G.args++;
r = eval2();
if (null(l) || null(r)) {
freev(l);
l = eval1();
while (nextarg("|")) {
- args++;
+ G.args++;
r = eval1();
if (null(l)) {
freev(l);