aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2010-03-12 21:05:09 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2010-03-12 21:05:09 +0100
commitc6ba9979782309491d7922f8ad205469e6549303 (patch)
treea080d2b9fa912fe343c2f1dbbe6c222e1678eb17
parent7b81db13791c4dc56f1a04737c5a5a47f4965738 (diff)
downloadbusybox-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.c297
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