awk: code shrink
No binary (build failed)
—
(log yok)
| @@ -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 | |