diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2010-03-12 21:05:09 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2010-03-12 21:05:09 +0100 |
commit | c6ba9979782309491d7922f8ad205469e6549303 (patch) | |
tree | a080d2b9fa912fe343c2f1dbbe6c222e1678eb17 | |
parent | 7b81db13791c4dc56f1a04737c5a5a47f4965738 (diff) | |
download | busybox-w32-c6ba9979782309491d7922f8ad205469e6549303.tar.gz busybox-w32-c6ba9979782309491d7922f8ad205469e6549303.tar.bz2 busybox-w32-c6ba9979782309491d7922f8ad205469e6549303.zip |
awk: code shrink
function old new delta
hash_find 233 234 +1
evaluate 3899 3550 -349
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | editors/awk.c | 297 |
1 files changed, 154 insertions, 143 deletions
diff --git a/editors/awk.c b/editors/awk.c index d022b7915..c8e78a16c 100644 --- a/editors/awk.c +++ b/editors/awk.c | |||
@@ -2304,22 +2304,17 @@ static var *evaluate(node *op, var *res) | |||
2304 | 2304 | ||
2305 | node *op1; | 2305 | node *op1; |
2306 | var *v1; | 2306 | var *v1; |
2307 | union { | 2307 | struct { |
2308 | var *v; | ||
2309 | const char *s; | ||
2310 | } L = L; /* for compiler */ | ||
2311 | struct { | ||
2308 | var *v; | 2312 | var *v; |
2309 | const char *s; | 2313 | const char *s; |
2310 | double d; | 2314 | } R = R; |
2311 | int i; | 2315 | double L_d = L_d; |
2312 | } L, R; | ||
2313 | uint32_t opinfo; | 2316 | uint32_t opinfo; |
2314 | int opn; | 2317 | int opn; |
2315 | union { | ||
2316 | char *s; | ||
2317 | rstream *rsm; | ||
2318 | FILE *F; | ||
2319 | var *v; | ||
2320 | regex_t *re; | ||
2321 | uint32_t info; | ||
2322 | } X; | ||
2323 | 2318 | ||
2324 | if (!op) | 2319 | if (!op) |
2325 | return setvar_s(res, NULL); | 2320 | return setvar_s(res, NULL); |
@@ -2334,7 +2329,7 @@ static var *evaluate(node *op, var *res) | |||
2334 | /* execute inevitable things */ | 2329 | /* execute inevitable things */ |
2335 | op1 = op->l.n; | 2330 | op1 = op->l.n; |
2336 | if (opinfo & OF_RES1) | 2331 | if (opinfo & OF_RES1) |
2337 | X.v = L.v = evaluate(op1, v1); | 2332 | L.v = evaluate(op1, v1); |
2338 | if (opinfo & OF_RES2) | 2333 | if (opinfo & OF_RES2) |
2339 | R.v = evaluate(op->r.n, v1+1); | 2334 | R.v = evaluate(op->r.n, v1+1); |
2340 | if (opinfo & OF_STR1) | 2335 | if (opinfo & OF_STR1) |
@@ -2342,7 +2337,7 @@ static var *evaluate(node *op, var *res) | |||
2342 | if (opinfo & OF_STR2) | 2337 | if (opinfo & OF_STR2) |
2343 | R.s = getvar_s(R.v); | 2338 | R.s = getvar_s(R.v); |
2344 | if (opinfo & OF_NUM1) | 2339 | if (opinfo & OF_NUM1) |
2345 | L.d = getvar_i(L.v); | 2340 | L_d = getvar_i(L.v); |
2346 | 2341 | ||
2347 | switch (XC(opinfo & OPCLSMASK)) { | 2342 | switch (XC(opinfo & OPCLSMASK)) { |
2348 | 2343 | ||
@@ -2356,7 +2351,6 @@ static var *evaluate(node *op, var *res) | |||
2356 | op->info |= OF_CHECKED; | 2351 | op->info |= OF_CHECKED; |
2357 | if (ptest(op1->r.n)) | 2352 | if (ptest(op1->r.n)) |
2358 | op->info &= ~OF_CHECKED; | 2353 | op->info &= ~OF_CHECKED; |
2359 | |||
2360 | op = op->a.n; | 2354 | op = op->a.n; |
2361 | } else { | 2355 | } else { |
2362 | op = op->r.n; | 2356 | op = op->r.n; |
@@ -2386,56 +2380,58 @@ static var *evaluate(node *op, var *res) | |||
2386 | break; | 2380 | break; |
2387 | 2381 | ||
2388 | case XC( OC_PRINT ): | 2382 | case XC( OC_PRINT ): |
2389 | case XC( OC_PRINTF ): | 2383 | case XC( OC_PRINTF ): { |
2390 | X.F = stdout; | 2384 | FILE *F = stdout; |
2385 | |||
2391 | if (op->r.n) { | 2386 | if (op->r.n) { |
2392 | X.rsm = newfile(R.s); | 2387 | rstream *rsm = newfile(R.s); |
2393 | if (!X.rsm->F) { | 2388 | if (!rsm->F) { |
2394 | if (opn == '|') { | 2389 | if (opn == '|') { |
2395 | X.rsm->F = popen(R.s, "w"); | 2390 | rsm->F = popen(R.s, "w"); |
2396 | if (X.rsm->F == NULL) | 2391 | if (rsm->F == NULL) |
2397 | bb_perror_msg_and_die("popen"); | 2392 | bb_perror_msg_and_die("popen"); |
2398 | X.rsm->is_pipe = 1; | 2393 | rsm->is_pipe = 1; |
2399 | } else { | 2394 | } else { |
2400 | X.rsm->F = xfopen(R.s, opn=='w' ? "w" : "a"); | 2395 | rsm->F = xfopen(R.s, opn=='w' ? "w" : "a"); |
2401 | } | 2396 | } |
2402 | } | 2397 | } |
2403 | X.F = X.rsm->F; | 2398 | F = rsm->F; |
2404 | } | 2399 | } |
2405 | 2400 | ||
2406 | if ((opinfo & OPCLSMASK) == OC_PRINT) { | 2401 | if ((opinfo & OPCLSMASK) == OC_PRINT) { |
2407 | if (!op1) { | 2402 | if (!op1) { |
2408 | fputs(getvar_s(intvar[F0]), X.F); | 2403 | fputs(getvar_s(intvar[F0]), F); |
2409 | } else { | 2404 | } else { |
2410 | while (op1) { | 2405 | while (op1) { |
2411 | L.v = evaluate(nextarg(&op1), v1); | 2406 | var *v = evaluate(nextarg(&op1), v1); |
2412 | if (L.v->type & VF_NUMBER) { | 2407 | if (v->type & VF_NUMBER) { |
2413 | fmt_num(g_buf, MAXVARFMT, getvar_s(intvar[OFMT]), | 2408 | fmt_num(g_buf, MAXVARFMT, getvar_s(intvar[OFMT]), |
2414 | getvar_i(L.v), TRUE); | 2409 | getvar_i(v), TRUE); |
2415 | fputs(g_buf, X.F); | 2410 | fputs(g_buf, F); |
2416 | } else { | 2411 | } else { |
2417 | fputs(getvar_s(L.v), X.F); | 2412 | fputs(getvar_s(v), F); |
2418 | } | 2413 | } |
2419 | 2414 | ||
2420 | if (op1) | 2415 | if (op1) |
2421 | fputs(getvar_s(intvar[OFS]), X.F); | 2416 | fputs(getvar_s(intvar[OFS]), F); |
2422 | } | 2417 | } |
2423 | } | 2418 | } |
2424 | fputs(getvar_s(intvar[ORS]), X.F); | 2419 | fputs(getvar_s(intvar[ORS]), F); |
2425 | 2420 | ||
2426 | } else { /* OC_PRINTF */ | 2421 | } else { /* OC_PRINTF */ |
2427 | L.s = awk_printf(op1); | 2422 | char *s = awk_printf(op1); |
2428 | fputs(L.s, X.F); | 2423 | fputs(s, F); |
2429 | free((char*)L.s); | 2424 | free(s); |
2430 | } | 2425 | } |
2431 | fflush(X.F); | 2426 | fflush(F); |
2432 | break; | 2427 | break; |
2428 | } | ||
2433 | 2429 | ||
2434 | case XC( OC_DELETE ): | 2430 | case XC( OC_DELETE ): { |
2435 | X.info = op1->info & OPCLSMASK; | 2431 | uint32_t info = op1->info & OPCLSMASK; |
2436 | if (X.info == OC_VAR) { | 2432 | if (info == OC_VAR) { |
2437 | R.v = op1->l.v; | 2433 | R.v = op1->l.v; |
2438 | } else if (X.info == OC_FNARG) { | 2434 | } else if (info == OC_FNARG) { |
2439 | R.v = &fnargs[op1->l.aidx]; | 2435 | R.v = &fnargs[op1->l.aidx]; |
2440 | } else { | 2436 | } else { |
2441 | syntax_error(EMSG_NOT_ARRAY); | 2437 | syntax_error(EMSG_NOT_ARRAY); |
@@ -2449,6 +2445,7 @@ static var *evaluate(node *op, var *res) | |||
2449 | clear_array(iamarray(R.v)); | 2445 | clear_array(iamarray(R.v)); |
2450 | } | 2446 | } |
2451 | break; | 2447 | break; |
2448 | } | ||
2452 | 2449 | ||
2453 | case XC( OC_NEWSOURCE ): | 2450 | case XC( OC_NEWSOURCE ): |
2454 | g_progname = op->l.new_progname; | 2451 | g_progname = op->l.new_progname; |
@@ -2467,7 +2464,7 @@ static var *evaluate(node *op, var *res) | |||
2467 | break; | 2464 | break; |
2468 | 2465 | ||
2469 | case XC( OC_EXIT ): | 2466 | case XC( OC_EXIT ): |
2470 | awk_exit(L.d); | 2467 | awk_exit(L_d); |
2471 | 2468 | ||
2472 | /* -- recursive node type -- */ | 2469 | /* -- recursive node type -- */ |
2473 | 2470 | ||
@@ -2495,11 +2492,13 @@ static var *evaluate(node *op, var *res) | |||
2495 | case XC( OC_MATCH ): | 2492 | case XC( OC_MATCH ): |
2496 | op1 = op->r.n; | 2493 | op1 = op->r.n; |
2497 | re_cont: | 2494 | re_cont: |
2498 | X.re = as_regex(op1, &sreg); | 2495 | { |
2499 | R.i = regexec(X.re, L.s, 0, NULL, 0); | 2496 | regex_t *re = as_regex(op1, &sreg); |
2500 | if (X.re == &sreg) | 2497 | int i = regexec(re, L.s, 0, NULL, 0); |
2501 | regfree(X.re); | 2498 | if (re == &sreg) |
2502 | setvar_i(res, (R.i == 0) ^ (opn == '!')); | 2499 | regfree(re); |
2500 | setvar_i(res, (i == 0) ^ (opn == '!')); | ||
2501 | } | ||
2503 | break; | 2502 | break; |
2504 | 2503 | ||
2505 | case XC( OC_MOVE ): | 2504 | case XC( OC_MOVE ): |
@@ -2520,22 +2519,24 @@ static var *evaluate(node *op, var *res) | |||
2520 | res = evaluate(istrue(L.v) ? op->r.n->l.n : op->r.n->r.n, res); | 2519 | res = evaluate(istrue(L.v) ? op->r.n->l.n : op->r.n->r.n, res); |
2521 | break; | 2520 | break; |
2522 | 2521 | ||
2523 | case XC( OC_FUNC ): | 2522 | case XC( OC_FUNC ): { |
2523 | var *v; | ||
2524 | |||
2524 | if (!op->r.f->body.first) | 2525 | if (!op->r.f->body.first) |
2525 | syntax_error(EMSG_UNDEF_FUNC); | 2526 | syntax_error(EMSG_UNDEF_FUNC); |
2526 | 2527 | ||
2527 | X.v = R.v = nvalloc(op->r.f->nargs + 1); | 2528 | v = R.v = nvalloc(op->r.f->nargs + 1); |
2528 | while (op1) { | 2529 | while (op1) { |
2529 | L.v = evaluate(nextarg(&op1), v1); | 2530 | L.v = evaluate(nextarg(&op1), v1); |
2530 | copyvar(R.v, L.v); | 2531 | copyvar(R.v, L.v); |
2531 | R.v->type |= VF_CHILD; | 2532 | R.v->type |= VF_CHILD; |
2532 | R.v->x.parent = L.v; | 2533 | R.v->x.parent = L.v; |
2533 | if (++R.v - X.v >= op->r.f->nargs) | 2534 | if (++R.v - v >= op->r.f->nargs) |
2534 | break; | 2535 | break; |
2535 | } | 2536 | } |
2536 | 2537 | ||
2537 | R.v = fnargs; | 2538 | R.v = fnargs; |
2538 | fnargs = X.v; | 2539 | fnargs = v; |
2539 | 2540 | ||
2540 | L.s = g_progname; | 2541 | L.s = g_progname; |
2541 | res = evaluate(op->r.f->body.first, res); | 2542 | res = evaluate(op->r.f->body.first, res); |
@@ -2544,26 +2545,30 @@ static var *evaluate(node *op, var *res) | |||
2544 | nvfree(fnargs); | 2545 | nvfree(fnargs); |
2545 | fnargs = R.v; | 2546 | fnargs = R.v; |
2546 | break; | 2547 | break; |
2548 | } | ||
2547 | 2549 | ||
2548 | case XC( OC_GETLINE ): | 2550 | case XC( OC_GETLINE ): |
2549 | case XC( OC_PGETLINE ): | 2551 | case XC( OC_PGETLINE ): { |
2552 | rstream *rsm; | ||
2553 | int i; | ||
2554 | |||
2550 | if (op1) { | 2555 | if (op1) { |
2551 | X.rsm = newfile(L.s); | 2556 | rsm = newfile(L.s); |
2552 | if (!X.rsm->F) { | 2557 | if (!rsm->F) { |
2553 | if ((opinfo & OPCLSMASK) == OC_PGETLINE) { | 2558 | if ((opinfo & OPCLSMASK) == OC_PGETLINE) { |
2554 | X.rsm->F = popen(L.s, "r"); | 2559 | rsm->F = popen(L.s, "r"); |
2555 | X.rsm->is_pipe = TRUE; | 2560 | rsm->is_pipe = TRUE; |
2556 | } else { | 2561 | } else { |
2557 | X.rsm->F = fopen_for_read(L.s); /* not xfopen! */ | 2562 | rsm->F = fopen_for_read(L.s); /* not xfopen! */ |
2558 | } | 2563 | } |
2559 | } | 2564 | } |
2560 | } else { | 2565 | } else { |
2561 | if (!iF) | 2566 | if (!iF) |
2562 | iF = next_input_file(); | 2567 | iF = next_input_file(); |
2563 | X.rsm = iF; | 2568 | rsm = iF; |
2564 | } | 2569 | } |
2565 | 2570 | ||
2566 | if (!X.rsm->F) { | 2571 | if (!rsm->F) { |
2567 | setvar_i(intvar[ERRNO], errno); | 2572 | setvar_i(intvar[ERRNO], errno); |
2568 | setvar_i(res, -1); | 2573 | setvar_i(res, -1); |
2569 | break; | 2574 | break; |
@@ -2572,46 +2577,48 @@ static var *evaluate(node *op, var *res) | |||
2572 | if (!op->r.n) | 2577 | if (!op->r.n) |
2573 | R.v = intvar[F0]; | 2578 | R.v = intvar[F0]; |
2574 | 2579 | ||
2575 | L.i = awk_getline(X.rsm, R.v); | 2580 | i = awk_getline(rsm, R.v); |
2576 | if (L.i > 0) { | 2581 | if (i > 0 && !op1) { |
2577 | if (!op1) { | 2582 | incvar(intvar[FNR]); |
2578 | incvar(intvar[FNR]); | 2583 | incvar(intvar[NR]); |
2579 | incvar(intvar[NR]); | ||
2580 | } | ||
2581 | } | 2584 | } |
2582 | setvar_i(res, L.i); | 2585 | setvar_i(res, i); |
2583 | break; | 2586 | break; |
2587 | } | ||
2584 | 2588 | ||
2585 | /* simple builtins */ | 2589 | /* simple builtins */ |
2586 | case XC( OC_FBLTIN ): | 2590 | case XC( OC_FBLTIN ): { |
2587 | switch (opn) { | 2591 | int i; |
2592 | rstream *rsm; | ||
2593 | double R_d = R_d; /* for compiler */ | ||
2588 | 2594 | ||
2595 | switch (opn) { | ||
2589 | case F_in: | 2596 | case F_in: |
2590 | R.d = (int)L.d; | 2597 | R_d = (int)L_d; |
2591 | break; | 2598 | break; |
2592 | 2599 | ||
2593 | case F_rn: | 2600 | case F_rn: |
2594 | R.d = (double)rand() / (double)RAND_MAX; | 2601 | R_d = (double)rand() / (double)RAND_MAX; |
2595 | break; | 2602 | break; |
2596 | #if ENABLE_FEATURE_AWK_LIBM | 2603 | #if ENABLE_FEATURE_AWK_LIBM |
2597 | case F_co: | 2604 | case F_co: |
2598 | R.d = cos(L.d); | 2605 | R_d = cos(L_d); |
2599 | break; | 2606 | break; |
2600 | 2607 | ||
2601 | case F_ex: | 2608 | case F_ex: |
2602 | R.d = exp(L.d); | 2609 | R_d = exp(L_d); |
2603 | break; | 2610 | break; |
2604 | 2611 | ||
2605 | case F_lg: | 2612 | case F_lg: |
2606 | R.d = log(L.d); | 2613 | R_d = log(L_d); |
2607 | break; | 2614 | break; |
2608 | 2615 | ||
2609 | case F_si: | 2616 | case F_si: |
2610 | R.d = sin(L.d); | 2617 | R_d = sin(L_d); |
2611 | break; | 2618 | break; |
2612 | 2619 | ||
2613 | case F_sq: | 2620 | case F_sq: |
2614 | R.d = sqrt(L.d); | 2621 | R_d = sqrt(L_d); |
2615 | break; | 2622 | break; |
2616 | #else | 2623 | #else |
2617 | case F_co: | 2624 | case F_co: |
@@ -2623,54 +2630,54 @@ static var *evaluate(node *op, var *res) | |||
2623 | break; | 2630 | break; |
2624 | #endif | 2631 | #endif |
2625 | case F_sr: | 2632 | case F_sr: |
2626 | R.d = (double)seed; | 2633 | R_d = (double)seed; |
2627 | seed = op1 ? (unsigned)L.d : (unsigned)time(NULL); | 2634 | seed = op1 ? (unsigned)L_d : (unsigned)time(NULL); |
2628 | srand(seed); | 2635 | srand(seed); |
2629 | break; | 2636 | break; |
2630 | 2637 | ||
2631 | case F_ti: | 2638 | case F_ti: |
2632 | R.d = time(NULL); | 2639 | R_d = time(NULL); |
2633 | break; | 2640 | break; |
2634 | 2641 | ||
2635 | case F_le: | 2642 | case F_le: |
2636 | if (!op1) | 2643 | if (!op1) |
2637 | L.s = getvar_s(intvar[F0]); | 2644 | L.s = getvar_s(intvar[F0]); |
2638 | R.d = strlen(L.s); | 2645 | R_d = strlen(L.s); |
2639 | break; | 2646 | break; |
2640 | 2647 | ||
2641 | case F_sy: | 2648 | case F_sy: |
2642 | fflush_all(); | 2649 | fflush_all(); |
2643 | R.d = (ENABLE_FEATURE_ALLOW_EXEC && L.s && *L.s) | 2650 | R_d = (ENABLE_FEATURE_ALLOW_EXEC && L.s && *L.s) |
2644 | ? (system(L.s) >> 8) : 0; | 2651 | ? (system(L.s) >> 8) : 0; |
2645 | break; | 2652 | break; |
2646 | 2653 | ||
2647 | case F_ff: | 2654 | case F_ff: |
2648 | if (!op1) | 2655 | if (!op1) { |
2649 | fflush(stdout); | 2656 | fflush(stdout); |
2650 | else { | 2657 | } else if (L.s && *L.s) { |
2651 | if (L.s && *L.s) { | 2658 | rsm = newfile(L.s); |
2652 | X.rsm = newfile(L.s); | 2659 | fflush(rsm->F); |
2653 | fflush(X.rsm->F); | 2660 | } else { |
2654 | } else { | 2661 | fflush_all(); |
2655 | fflush_all(); | ||
2656 | } | ||
2657 | } | 2662 | } |
2658 | break; | 2663 | break; |
2659 | 2664 | ||
2660 | case F_cl: | 2665 | case F_cl: |
2661 | X.rsm = (rstream *)hash_search(fdhash, L.s); | 2666 | i = 0; |
2662 | if (X.rsm) { | 2667 | rsm = (rstream *)hash_search(fdhash, L.s); |
2663 | R.i = X.rsm->is_pipe ? pclose(X.rsm->F) : fclose(X.rsm->F); | 2668 | if (rsm) { |
2664 | free(X.rsm->buffer); | 2669 | i = rsm->is_pipe ? pclose(rsm->F) : fclose(rsm->F); |
2670 | free(rsm->buffer); | ||
2665 | hash_remove(fdhash, L.s); | 2671 | hash_remove(fdhash, L.s); |
2666 | } | 2672 | } |
2667 | if (R.i != 0) | 2673 | if (i != 0) |
2668 | setvar_i(intvar[ERRNO], errno); | 2674 | setvar_i(intvar[ERRNO], errno); |
2669 | R.d = (double)R.i; | 2675 | R_d = (double)i; |
2670 | break; | 2676 | break; |
2671 | } | 2677 | } |
2672 | setvar_i(res, R.d); | 2678 | setvar_i(res, R_d); |
2673 | break; | 2679 | break; |
2680 | } | ||
2674 | 2681 | ||
2675 | case XC( OC_BUILTIN ): | 2682 | case XC( OC_BUILTIN ): |
2676 | res = exec_builtin(op, res); | 2683 | res = exec_builtin(op, res); |
@@ -2680,60 +2687,58 @@ static var *evaluate(node *op, var *res) | |||
2680 | setvar_p(res, awk_printf(op1)); | 2687 | setvar_p(res, awk_printf(op1)); |
2681 | break; | 2688 | break; |
2682 | 2689 | ||
2683 | case XC( OC_UNARY ): | 2690 | case XC( OC_UNARY ): { |
2684 | X.v = R.v; | 2691 | double Ld, R_d; |
2685 | L.d = R.d = getvar_i(R.v); | 2692 | |
2693 | Ld = R_d = getvar_i(R.v); | ||
2686 | switch (opn) { | 2694 | switch (opn) { |
2687 | case 'P': | 2695 | case 'P': |
2688 | L.d = ++R.d; | 2696 | Ld = ++R_d; |
2689 | goto r_op_change; | 2697 | goto r_op_change; |
2690 | case 'p': | 2698 | case 'p': |
2691 | R.d++; | 2699 | R_d++; |
2692 | goto r_op_change; | 2700 | goto r_op_change; |
2693 | case 'M': | 2701 | case 'M': |
2694 | L.d = --R.d; | 2702 | Ld = --R_d; |
2695 | goto r_op_change; | 2703 | goto r_op_change; |
2696 | case 'm': | 2704 | case 'm': |
2697 | R.d--; | 2705 | R_d--; |
2698 | goto r_op_change; | 2706 | r_op_change: |
2707 | setvar_i(R.v, R_d); | ||
2708 | break; | ||
2699 | case '!': | 2709 | case '!': |
2700 | L.d = !istrue(X.v); | 2710 | Ld = !istrue(R.v); |
2701 | break; | 2711 | break; |
2702 | case '-': | 2712 | case '-': |
2703 | L.d = -R.d; | 2713 | Ld = -R_d; |
2704 | break; | 2714 | break; |
2705 | r_op_change: | ||
2706 | setvar_i(X.v, R.d); | ||
2707 | } | 2715 | } |
2708 | setvar_i(res, L.d); | 2716 | setvar_i(res, Ld); |
2709 | break; | 2717 | break; |
2718 | } | ||
2710 | 2719 | ||
2711 | case XC( OC_FIELD ): | 2720 | case XC( OC_FIELD ): { |
2712 | R.i = (int)getvar_i(R.v); | 2721 | int i = (int)getvar_i(R.v); |
2713 | if (R.i == 0) { | 2722 | if (i == 0) { |
2714 | res = intvar[F0]; | 2723 | res = intvar[F0]; |
2715 | } else { | 2724 | } else { |
2716 | split_f0(); | 2725 | split_f0(); |
2717 | if (R.i > nfields) | 2726 | if (i > nfields) |
2718 | fsrealloc(R.i); | 2727 | fsrealloc(i); |
2719 | res = &Fields[R.i - 1]; | 2728 | res = &Fields[i - 1]; |
2720 | } | 2729 | } |
2721 | break; | 2730 | break; |
2731 | } | ||
2722 | 2732 | ||
2723 | /* concatenation (" ") and index joining (",") */ | 2733 | /* concatenation (" ") and index joining (",") */ |
2724 | case XC( OC_CONCAT ): | 2734 | case XC( OC_CONCAT ): |
2725 | case XC( OC_COMMA ): | 2735 | case XC( OC_COMMA ): { |
2726 | opn = strlen(L.s) + strlen(R.s) + 2; | 2736 | const char *sep = ""; |
2727 | X.s = xmalloc(opn); | 2737 | if ((opinfo & OPCLSMASK) == OC_COMMA) |
2728 | strcpy(X.s, L.s); | 2738 | sep = getvar_s(intvar[SUBSEP]); |
2729 | if ((opinfo & OPCLSMASK) == OC_COMMA) { | 2739 | setvar_p(res, xasprintf("%s%s%s", L.s, sep, R.s)); |
2730 | L.s = getvar_s(intvar[SUBSEP]); | ||
2731 | X.s = xrealloc(X.s, opn + strlen(L.s)); | ||
2732 | strcat(X.s, L.s); | ||
2733 | } | ||
2734 | strcat(X.s, R.s); | ||
2735 | setvar_p(res, X.s); | ||
2736 | break; | 2740 | break; |
2741 | } | ||
2737 | 2742 | ||
2738 | case XC( OC_LAND ): | 2743 | case XC( OC_LAND ): |
2739 | setvar_i(res, istrue(L.v) ? ptest(op->r.n) : 0); | 2744 | setvar_i(res, istrue(L.v) ? ptest(op->r.n) : 0); |
@@ -2744,60 +2749,65 @@ static var *evaluate(node *op, var *res) | |||
2744 | break; | 2749 | break; |
2745 | 2750 | ||
2746 | case XC( OC_BINARY ): | 2751 | case XC( OC_BINARY ): |
2747 | case XC( OC_REPLACE ): | 2752 | case XC( OC_REPLACE ): { |
2748 | R.d = getvar_i(R.v); | 2753 | double R_d = getvar_i(R.v); |
2749 | switch (opn) { | 2754 | switch (opn) { |
2750 | case '+': | 2755 | case '+': |
2751 | L.d += R.d; | 2756 | L_d += R_d; |
2752 | break; | 2757 | break; |
2753 | case '-': | 2758 | case '-': |
2754 | L.d -= R.d; | 2759 | L_d -= R_d; |
2755 | break; | 2760 | break; |
2756 | case '*': | 2761 | case '*': |
2757 | L.d *= R.d; | 2762 | L_d *= R_d; |
2758 | break; | 2763 | break; |
2759 | case '/': | 2764 | case '/': |
2760 | if (R.d == 0) | 2765 | if (R_d == 0) |
2761 | syntax_error(EMSG_DIV_BY_ZERO); | 2766 | syntax_error(EMSG_DIV_BY_ZERO); |
2762 | L.d /= R.d; | 2767 | L_d /= R_d; |
2763 | break; | 2768 | break; |
2764 | case '&': | 2769 | case '&': |
2765 | #if ENABLE_FEATURE_AWK_LIBM | 2770 | #if ENABLE_FEATURE_AWK_LIBM |
2766 | L.d = pow(L.d, R.d); | 2771 | L_d = pow(L_d, R_d); |
2767 | #else | 2772 | #else |
2768 | syntax_error(EMSG_NO_MATH); | 2773 | syntax_error(EMSG_NO_MATH); |
2769 | #endif | 2774 | #endif |
2770 | break; | 2775 | break; |
2771 | case '%': | 2776 | case '%': |
2772 | if (R.d == 0) | 2777 | if (R_d == 0) |
2773 | syntax_error(EMSG_DIV_BY_ZERO); | 2778 | syntax_error(EMSG_DIV_BY_ZERO); |
2774 | L.d -= (int)(L.d / R.d) * R.d; | 2779 | L_d -= (int)(L_d / R_d) * R_d; |
2775 | break; | 2780 | break; |
2776 | } | 2781 | } |
2777 | res = setvar_i(((opinfo & OPCLSMASK) == OC_BINARY) ? res : X.v, L.d); | 2782 | res = setvar_i(((opinfo & OPCLSMASK) == OC_BINARY) ? res : L.v, L_d); |
2778 | break; | 2783 | break; |
2784 | } | ||
2785 | |||
2786 | case XC( OC_COMPARE ): { | ||
2787 | int i = i; /* for compiler */ | ||
2788 | double Ld; | ||
2779 | 2789 | ||
2780 | case XC( OC_COMPARE ): | ||
2781 | if (is_numeric(L.v) && is_numeric(R.v)) { | 2790 | if (is_numeric(L.v) && is_numeric(R.v)) { |
2782 | L.d = getvar_i(L.v) - getvar_i(R.v); | 2791 | Ld = getvar_i(L.v) - getvar_i(R.v); |
2783 | } else { | 2792 | } else { |
2784 | L.s = getvar_s(L.v); | 2793 | L.s = getvar_s(L.v); |
2785 | R.s = getvar_s(R.v); | 2794 | R.s = getvar_s(R.v); |
2786 | L.d = icase ? strcasecmp(L.s, R.s) : strcmp(L.s, R.s); | 2795 | Ld = icase ? strcasecmp(L.s, R.s) : strcmp(L.s, R.s); |
2787 | } | 2796 | } |
2788 | switch (opn & 0xfe) { | 2797 | switch (opn & 0xfe) { |
2789 | case 0: | 2798 | case 0: |
2790 | R.i = (L.d > 0); | 2799 | i = (Ld > 0); |
2791 | break; | 2800 | break; |
2792 | case 2: | 2801 | case 2: |
2793 | R.i = (L.d >= 0); | 2802 | i = (Ld >= 0); |
2794 | break; | 2803 | break; |
2795 | case 4: | 2804 | case 4: |
2796 | R.i = (L.d == 0); | 2805 | i = (Ld == 0); |
2797 | break; | 2806 | break; |
2798 | } | 2807 | } |
2799 | setvar_i(res, (opn & 1 ? R.i : !R.i) ? 1 : 0); | 2808 | setvar_i(res, (i == 0) ^ (opn & 1)); |
2800 | break; | 2809 | break; |
2810 | } | ||
2801 | 2811 | ||
2802 | default: | 2812 | default: |
2803 | syntax_error(EMSG_POSSIBLE_ERROR); | 2813 | syntax_error(EMSG_POSSIBLE_ERROR); |
@@ -2808,7 +2818,8 @@ static var *evaluate(node *op, var *res) | |||
2808 | break; | 2818 | break; |
2809 | if (nextrec) | 2819 | if (nextrec) |
2810 | break; | 2820 | break; |
2811 | } | 2821 | } /* while (op) */ |
2822 | |||
2812 | nvfree(v1); | 2823 | nvfree(v1); |
2813 | return res; | 2824 | return res; |
2814 | #undef fnargs | 2825 | #undef fnargs |