awk: code shrink
authorDenys Vlasenko <vda.linux@googlemail.com>
Fri, 12 Mar 2010 20:05:09 +0000 (21:05 +0100)
committerDenys Vlasenko <vda.linux@googlemail.com>
Fri, 12 Mar 2010 20:05:09 +0000 (21:05 +0100)
function                                             old     new   delta
hash_find                                            233     234      +1
evaluate                                            3899    3550    -349

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
editors/awk.c

index d022b791506332fb6ed54330397753b5493d872a..c8e78a16c6bf2d0e9fd04ab7b38080c707fac518 100644 (file)
@@ -2304,22 +2304,17 @@ static var *evaluate(node *op, var *res)
 
        node *op1;
        var *v1;
-       union {
+       struct {
+               var *v;
+               const char *s;
+       } L = L; /* for compiler */
+       struct {
                var *v;
                const char *s;
-               double d;
-               int i;
-       } L, R;
+       } R = R;
+       double L_d = L_d;
        uint32_t opinfo;
        int opn;
-       union {
-               char *s;
-               rstream *rsm;
-               FILE *F;
-               var *v;
-               regex_t *re;
-               uint32_t info;
-       } X;
 
        if (!op)
                return setvar_s(res, NULL);
@@ -2334,7 +2329,7 @@ static var *evaluate(node *op, var *res)
                /* execute inevitable things */
                op1 = op->l.n;
                if (opinfo & OF_RES1)
-                       X.v = L.v = evaluate(op1, v1);
+                       L.v = evaluate(op1, v1);
                if (opinfo & OF_RES2)
                        R.v = evaluate(op->r.n, v1+1);
                if (opinfo & OF_STR1)
@@ -2342,7 +2337,7 @@ static var *evaluate(node *op, var *res)
                if (opinfo & OF_STR2)
                        R.s = getvar_s(R.v);
                if (opinfo & OF_NUM1)
-                       L.d = getvar_i(L.v);
+                       L_d = getvar_i(L.v);
 
                switch (XC(opinfo & OPCLSMASK)) {
 
@@ -2356,7 +2351,6 @@ static var *evaluate(node *op, var *res)
                                        op->info |= OF_CHECKED;
                                        if (ptest(op1->r.n))
                                                op->info &= ~OF_CHECKED;
-
                                        op = op->a.n;
                                } else {
                                        op = op->r.n;
@@ -2386,56 +2380,58 @@ static var *evaluate(node *op, var *res)
                        break;
 
                case XC( OC_PRINT ):
-               case XC( OC_PRINTF ):
-                       X.F = stdout;
+               case XC( OC_PRINTF ): {
+                       FILE *F = stdout;
+
                        if (op->r.n) {
-                               X.rsm = newfile(R.s);
-                               if (!X.rsm->F) {
+                               rstream *rsm = newfile(R.s);
+                               if (!rsm->F) {
                                        if (opn == '|') {
-                                               X.rsm->F = popen(R.s, "w");
-                                               if (X.rsm->F == NULL)
+                                               rsm->F = popen(R.s, "w");
+                                               if (rsm->F == NULL)
                                                        bb_perror_msg_and_die("popen");
-                                               X.rsm->is_pipe = 1;
+                                               rsm->is_pipe = 1;
                                        } else {
-                                               X.rsm->F = xfopen(R.s, opn=='w' ? "w" : "a");
+                                               rsm->F = xfopen(R.s, opn=='w' ? "w" : "a");
                                        }
                                }
-                               X.F = X.rsm->F;
+                               F = rsm->F;
                        }
 
                        if ((opinfo & OPCLSMASK) == OC_PRINT) {
                                if (!op1) {
-                                       fputs(getvar_s(intvar[F0]), X.F);
+                                       fputs(getvar_s(intvar[F0]), F);
                                } else {
                                        while (op1) {
-                                               L.v = evaluate(nextarg(&op1), v1);
-                                               if (L.v->type & VF_NUMBER) {
+                                               var *v = evaluate(nextarg(&op1), v1);
+                                               if (v->type & VF_NUMBER) {
                                                        fmt_num(g_buf, MAXVARFMT, getvar_s(intvar[OFMT]),
-                                                                       getvar_i(L.v), TRUE);
-                                                       fputs(g_buf, X.F);
+                                                                       getvar_i(v), TRUE);
+                                                       fputs(g_buf, F);
                                                } else {
-                                                       fputs(getvar_s(L.v), X.F);
+                                                       fputs(getvar_s(v), F);
                                                }
 
                                                if (op1)
-                                                       fputs(getvar_s(intvar[OFS]), X.F);
+                                                       fputs(getvar_s(intvar[OFS]), F);
                                        }
                                }
-                               fputs(getvar_s(intvar[ORS]), X.F);
+                               fputs(getvar_s(intvar[ORS]), F);
 
                        } else {        /* OC_PRINTF */
-                               L.s = awk_printf(op1);
-                               fputs(L.s, X.F);
-                               free((char*)L.s);
+                               char *s = awk_printf(op1);
+                               fputs(s, F);
+                               free(s);
                        }
-                       fflush(X.F);
+                       fflush(F);
                        break;
+               }
 
-               case XC( OC_DELETE ):
-                       X.info = op1->info & OPCLSMASK;
-                       if (X.info == OC_VAR) {
+               case XC( OC_DELETE ): {
+                       uint32_t info = op1->info & OPCLSMASK;
+                       if (info == OC_VAR) {
                                R.v = op1->l.v;
-                       } else if (X.info == OC_FNARG) {
+                       } else if (info == OC_FNARG) {
                                R.v = &fnargs[op1->l.aidx];
                        } else {
                                syntax_error(EMSG_NOT_ARRAY);
@@ -2449,6 +2445,7 @@ static var *evaluate(node *op, var *res)
                                clear_array(iamarray(R.v));
                        }
                        break;
+               }
 
                case XC( OC_NEWSOURCE ):
                        g_progname = op->l.new_progname;
@@ -2467,7 +2464,7 @@ static var *evaluate(node *op, var *res)
                        break;
 
                case XC( OC_EXIT ):
-                       awk_exit(L.d);
+                       awk_exit(L_d);
 
                /* -- recursive node type -- */
 
@@ -2495,11 +2492,13 @@ static var *evaluate(node *op, var *res)
                case XC( OC_MATCH ):
                        op1 = op->r.n;
  re_cont:
-                       X.re = as_regex(op1, &sreg);
-                       R.i = regexec(X.re, L.s, 0, NULL, 0);
-                       if (X.re == &sreg)
-                               regfree(X.re);
-                       setvar_i(res, (R.i == 0) ^ (opn == '!'));
+                       {
+                               regex_t *re = as_regex(op1, &sreg);
+                               int i = regexec(re, L.s, 0, NULL, 0);
+                               if (re == &sreg)
+                                       regfree(re);
+                               setvar_i(res, (i == 0) ^ (opn == '!'));
+                       }
                        break;
 
                case XC( OC_MOVE ):
@@ -2520,22 +2519,24 @@ static var *evaluate(node *op, var *res)
                        res = evaluate(istrue(L.v) ? op->r.n->l.n : op->r.n->r.n, res);
                        break;
 
-               case XC( OC_FUNC ):
+               case XC( OC_FUNC ): {
+                       var *v;
+
                        if (!op->r.f->body.first)
                                syntax_error(EMSG_UNDEF_FUNC);
 
-                       X.v = R.v = nvalloc(op->r.f->nargs + 1);
+                       v = R.v = nvalloc(op->r.f->nargs + 1);
                        while (op1) {
                                L.v = evaluate(nextarg(&op1), v1);
                                copyvar(R.v, L.v);
                                R.v->type |= VF_CHILD;
                                R.v->x.parent = L.v;
-                               if (++R.v - X.v >= op->r.f->nargs)
+                               if (++R.v - v >= op->r.f->nargs)
                                        break;
                        }
 
                        R.v = fnargs;
-                       fnargs = X.v;
+                       fnargs = v;
 
                        L.s = g_progname;
                        res = evaluate(op->r.f->body.first, res);
@@ -2544,26 +2545,30 @@ static var *evaluate(node *op, var *res)
                        nvfree(fnargs);
                        fnargs = R.v;
                        break;
+               }
 
                case XC( OC_GETLINE ):
-               case XC( OC_PGETLINE ):
+               case XC( OC_PGETLINE ): {
+                       rstream *rsm;
+                       int i;
+
                        if (op1) {
-                               X.rsm = newfile(L.s);
-                               if (!X.rsm->F) {
+                               rsm = newfile(L.s);
+                               if (!rsm->F) {
                                        if ((opinfo & OPCLSMASK) == OC_PGETLINE) {
-                                               X.rsm->F = popen(L.s, "r");
-                                               X.rsm->is_pipe = TRUE;
+                                               rsm->F = popen(L.s, "r");
+                                               rsm->is_pipe = TRUE;
                                        } else {
-                                               X.rsm->F = fopen_for_read(L.s);         /* not xfopen! */
+                                               rsm->F = fopen_for_read(L.s);           /* not xfopen! */
                                        }
                                }
                        } else {
                                if (!iF)
                                        iF = next_input_file();
-                               X.rsm = iF;
+                               rsm = iF;
                        }
 
-                       if (!X.rsm->F) {
+                       if (!rsm->F) {
                                setvar_i(intvar[ERRNO], errno);
                                setvar_i(res, -1);
                                break;
@@ -2572,46 +2577,48 @@ static var *evaluate(node *op, var *res)
                        if (!op->r.n)
                                R.v = intvar[F0];
 
-                       L.i = awk_getline(X.rsm, R.v);
-                       if (L.i > 0) {
-                               if (!op1) {
-                                       incvar(intvar[FNR]);
-                                       incvar(intvar[NR]);
-                               }
+                       i = awk_getline(rsm, R.v);
+                       if (i > 0 && !op1) {
+                               incvar(intvar[FNR]);
+                               incvar(intvar[NR]);
                        }
-                       setvar_i(res, L.i);
+                       setvar_i(res, i);
                        break;
+               }
 
                /* simple builtins */
-               case XC( OC_FBLTIN ):
-                       switch (opn) {
+               case XC( OC_FBLTIN ): {
+                       int i;
+                       rstream *rsm;
+                       double R_d = R_d; /* for compiler */
 
+                       switch (opn) {
                        case F_in:
-                               R.d = (int)L.d;
+                               R_d = (int)L_d;
                                break;
 
                        case F_rn:
-                               R.d = (double)rand() / (double)RAND_MAX;
+                               R_d = (double)rand() / (double)RAND_MAX;
                                break;
 #if ENABLE_FEATURE_AWK_LIBM
                        case F_co:
-                               R.d = cos(L.d);
+                               R_d = cos(L_d);
                                break;
 
                        case F_ex:
-                               R.d = exp(L.d);
+                               R_d = exp(L_d);
                                break;
 
                        case F_lg:
-                               R.d = log(L.d);
+                               R_d = log(L_d);
                                break;
 
                        case F_si:
-                               R.d = sin(L.d);
+                               R_d = sin(L_d);
                                break;
 
                        case F_sq:
-                               R.d = sqrt(L.d);
+                               R_d = sqrt(L_d);
                                break;
 #else
                        case F_co:
@@ -2623,54 +2630,54 @@ static var *evaluate(node *op, var *res)
                                break;
 #endif
                        case F_sr:
-                               R.d = (double)seed;
-                               seed = op1 ? (unsigned)L.d : (unsigned)time(NULL);
+                               R_d = (double)seed;
+                               seed = op1 ? (unsigned)L_d : (unsigned)time(NULL);
                                srand(seed);
                                break;
 
                        case F_ti:
-                               R.d = time(NULL);
+                               R_d = time(NULL);
                                break;
 
                        case F_le:
                                if (!op1)
                                        L.s = getvar_s(intvar[F0]);
-                               R.d = strlen(L.s);
+                               R_d = strlen(L.s);
                                break;
 
                        case F_sy:
                                fflush_all();
-                               R.d = (ENABLE_FEATURE_ALLOW_EXEC && L.s && *L.s)
+                               R_d = (ENABLE_FEATURE_ALLOW_EXEC && L.s && *L.s)
                                                ? (system(L.s) >> 8) : 0;
                                break;
 
                        case F_ff:
-                               if (!op1)
+                               if (!op1) {
                                        fflush(stdout);
-                               else {
-                                       if (L.s && *L.s) {
-                                               X.rsm = newfile(L.s);
-                                               fflush(X.rsm->F);
-                                       } else {
-                                               fflush_all();
-                                       }
+                               } else if (L.s && *L.s) {
+                                       rsm = newfile(L.s);
+                                       fflush(rsm->F);
+                               } else {
+                                       fflush_all();
                                }
                                break;
 
                        case F_cl:
-                               X.rsm = (rstream *)hash_search(fdhash, L.s);
-                               if (X.rsm) {
-                                       R.i = X.rsm->is_pipe ? pclose(X.rsm->F) : fclose(X.rsm->F);
-                                       free(X.rsm->buffer);
+                               i = 0;
+                               rsm = (rstream *)hash_search(fdhash, L.s);
+                               if (rsm) {
+                                       i = rsm->is_pipe ? pclose(rsm->F) : fclose(rsm->F);
+                                       free(rsm->buffer);
                                        hash_remove(fdhash, L.s);
                                }
-                               if (R.i != 0)
+                               if (i != 0)
                                        setvar_i(intvar[ERRNO], errno);
-                               R.d = (double)R.i;
+                               R_d = (double)i;
                                break;
                        }
-                       setvar_i(res, R.d);
+                       setvar_i(res, R_d);
                        break;
+               }
 
                case XC( OC_BUILTIN ):
                        res = exec_builtin(op, res);
@@ -2680,60 +2687,58 @@ static var *evaluate(node *op, var *res)
                        setvar_p(res, awk_printf(op1));
                        break;
 
-               case XC( OC_UNARY ):
-                       X.v = R.v;
-                       L.d = R.d = getvar_i(R.v);
+               case XC( OC_UNARY ): {
+                       double Ld, R_d;
+
+                       Ld = R_d = getvar_i(R.v);
                        switch (opn) {
                        case 'P':
-                               L.d = ++R.d;
+                               Ld = ++R_d;
                                goto r_op_change;
                        case 'p':
-                               R.d++;
+                               R_d++;
                                goto r_op_change;
                        case 'M':
-                               L.d = --R.d;
+                               Ld = --R_d;
                                goto r_op_change;
                        case 'm':
-                               R.d--;
-                               goto r_op_change;
+                               R_d--;
+ r_op_change:
+                               setvar_i(R.v, R_d);
+                               break;
                        case '!':
-                               L.d = !istrue(X.v);
+                               Ld = !istrue(R.v);
                                break;
                        case '-':
-                               L.d = -R.d;
+                               Ld = -R_d;
                                break;
- r_op_change:
-                               setvar_i(X.v, R.d);
                        }
-                       setvar_i(res, L.d);
+                       setvar_i(res, Ld);
                        break;
+               }
 
-               case XC( OC_FIELD ):
-                       R.i = (int)getvar_i(R.v);
-                       if (R.i == 0) {
+               case XC( OC_FIELD ): {
+                       int i = (int)getvar_i(R.v);
+                       if (i == 0) {
                                res = intvar[F0];
                        } else {
                                split_f0();
-                               if (R.i > nfields)
-                                       fsrealloc(R.i);
-                               res = &Fields[R.i - 1];
+                               if (i > nfields)
+                                       fsrealloc(i);
+                               res = &Fields[i - 1];
                        }
                        break;
+               }
 
                /* concatenation (" ") and index joining (",") */
                case XC( OC_CONCAT ):
-               case XC( OC_COMMA ):
-                       opn = strlen(L.s) + strlen(R.s) + 2;
-                       X.s = xmalloc(opn);
-                       strcpy(X.s, L.s);
-                       if ((opinfo & OPCLSMASK) == OC_COMMA) {
-                               L.s = getvar_s(intvar[SUBSEP]);
-                               X.s = xrealloc(X.s, opn + strlen(L.s));
-                               strcat(X.s, L.s);
-                       }
-                       strcat(X.s, R.s);
-                       setvar_p(res, X.s);
+               case XC( OC_COMMA ): {
+                       const char *sep = "";
+                       if ((opinfo & OPCLSMASK) == OC_COMMA)
+                               sep = getvar_s(intvar[SUBSEP]);
+                       setvar_p(res, xasprintf("%s%s%s", L.s, sep, R.s));
                        break;
+               }
 
                case XC( OC_LAND ):
                        setvar_i(res, istrue(L.v) ? ptest(op->r.n) : 0);
@@ -2744,60 +2749,65 @@ static var *evaluate(node *op, var *res)
                        break;
 
                case XC( OC_BINARY ):
-               case XC( OC_REPLACE ):
-                       R.d = getvar_i(R.v);
+               case XC( OC_REPLACE ): {
+                       double R_d = getvar_i(R.v);
                        switch (opn) {
                        case '+':
-                               L.d += R.d;
+                               L_d += R_d;
                                break;
                        case '-':
-                               L.d -= R.d;
+                               L_d -= R_d;
                                break;
                        case '*':
-                               L.d *= R.d;
+                               L_d *= R_d;
                                break;
                        case '/':
-                               if (R.d == 0)
+                               if (R_d == 0)
                                        syntax_error(EMSG_DIV_BY_ZERO);
-                               L.d /= R.d;
+                               L_d /= R_d;
                                break;
                        case '&':
 #if ENABLE_FEATURE_AWK_LIBM
-                               L.d = pow(L.d, R.d);
+                               L_d = pow(L_d, R_d);
 #else
                                syntax_error(EMSG_NO_MATH);
 #endif
                                break;
                        case '%':
-                               if (R.d == 0)
+                               if (R_d == 0)
                                        syntax_error(EMSG_DIV_BY_ZERO);
-                               L.d -= (int)(L.d / R.d) * R.d;
+                               L_d -= (int)(L_d / R_d) * R_d;
                                break;
                        }
-                       res = setvar_i(((opinfo & OPCLSMASK) == OC_BINARY) ? res : X.v, L.d);
+                       res = setvar_i(((opinfo & OPCLSMASK) == OC_BINARY) ? res : L.v, L_d);
                        break;
+               }
+
+               case XC( OC_COMPARE ): {
+                       int i = i; /* for compiler */
+                       double Ld;
 
-               case XC( OC_COMPARE ):
                        if (is_numeric(L.v) && is_numeric(R.v)) {
-                               L.d = getvar_i(L.v) - getvar_i(R.v);
+                               Ld = getvar_i(L.v) - getvar_i(R.v);
                        } else {
                                L.s = getvar_s(L.v);
                                R.s = getvar_s(R.v);
-                               L.d = icase ? strcasecmp(L.s, R.s) : strcmp(L.s, R.s);
+                               Ld = icase ? strcasecmp(L.s, R.s) : strcmp(L.s, R.s);
                        }
                        switch (opn & 0xfe) {
                        case 0:
-                               R.i = (L.d > 0);
+                               i = (Ld > 0);
                                break;
                        case 2:
-                               R.i = (L.d >= 0);
+                               i = (Ld >= 0);
                                break;
                        case 4:
-                               R.i = (L.d == 0);
+                               i = (Ld == 0);
                                break;
                        }
-                       setvar_i(res, (opn & 1 ? R.i : !R.i) ? 1 : 0);
+                       setvar_i(res, (i == 0) ^ (opn & 1));
                        break;
+               }
 
                default:
                        syntax_error(EMSG_POSSIBLE_ERROR);
@@ -2808,7 +2818,8 @@ static var *evaluate(node *op, var *res)
                        break;
                if (nextrec)
                        break;
-       }
+       } /* while (op) */
+
        nvfree(v1);
        return res;
 #undef fnargs