diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2021-07-02 15:19:14 +0200 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2021-07-02 15:21:36 +0200 |
| commit | 640212ae0ea8a1b47cd73a080d77b25b9f3ccd40 (patch) | |
| tree | 4bdd98a112118c2a79e073ab6ca474fc7004c30d | |
| parent | ef5463cf16f88c0992b2073a30ab6081c86fdf23 (diff) | |
| download | busybox-w32-640212ae0ea8a1b47cd73a080d77b25b9f3ccd40.tar.gz busybox-w32-640212ae0ea8a1b47cd73a080d77b25b9f3ccd40.tar.bz2 busybox-w32-640212ae0ea8a1b47cd73a080d77b25b9f3ccd40.zip | |
awk: do not special-case "delete"
Rework of the previous fix:
Can use operation attributes to disable arg evaluation instead of special-casing.
function old new delta
.rodata 104032 104036 +4
evaluate 3223 3215 -8
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/1 up/down: 4/-8) Total: -4 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
| -rw-r--r-- | editors/awk.c | 56 |
1 files changed, 27 insertions, 29 deletions
diff --git a/editors/awk.c b/editors/awk.c index 068ed687b..a3dda6959 100644 --- a/editors/awk.c +++ b/editors/awk.c | |||
| @@ -319,7 +319,7 @@ if ((n) & TC_NUMBER ) debug_printf_parse(" NUMBER" ); \ | |||
| 319 | #define xV OF_RES2 | 319 | #define xV OF_RES2 |
| 320 | #define xS (OF_RES2 | OF_STR2) | 320 | #define xS (OF_RES2 | OF_STR2) |
| 321 | #define Vx OF_RES1 | 321 | #define Vx OF_RES1 |
| 322 | #define Rx (OF_RES1 | OF_NUM1 | OF_REQUIRED) | 322 | #define Rx OF_REQUIRED |
| 323 | #define VV (OF_RES1 | OF_RES2) | 323 | #define VV (OF_RES1 | OF_RES2) |
| 324 | #define Nx (OF_RES1 | OF_NUM1) | 324 | #define Nx (OF_RES1 | OF_NUM1) |
| 325 | #define NV (OF_RES1 | OF_NUM1 | OF_RES2) | 325 | #define NV (OF_RES1 | OF_NUM1 | OF_RES2) |
| @@ -2750,32 +2750,6 @@ static var *evaluate(node *op, var *res) | |||
| 2750 | op1 = op->l.n; | 2750 | op1 = op->l.n; |
| 2751 | debug_printf_eval("opinfo:%08x opn:%08x\n", opinfo, opn); | 2751 | debug_printf_eval("opinfo:%08x opn:%08x\n", opinfo, opn); |
| 2752 | 2752 | ||
| 2753 | /* "delete" is special: | ||
| 2754 | * "delete array[var--]" must evaluate index expr only once, | ||
| 2755 | * must not evaluate it in "execute inevitable things" part. | ||
| 2756 | */ | ||
| 2757 | if (XC(opinfo & OPCLSMASK) == XC(OC_DELETE)) { | ||
| 2758 | uint32_t info = op1->info & OPCLSMASK; | ||
| 2759 | var *v; | ||
| 2760 | |||
| 2761 | debug_printf_eval("DELETE\n"); | ||
| 2762 | if (info == OC_VAR) { | ||
| 2763 | v = op1->l.v; | ||
| 2764 | } else if (info == OC_FNARG) { | ||
| 2765 | v = &fnargs[op1->l.aidx]; | ||
| 2766 | } else { | ||
| 2767 | syntax_error(EMSG_NOT_ARRAY); | ||
| 2768 | } | ||
| 2769 | if (op1->r.n) { /* array ref? */ | ||
| 2770 | const char *s; | ||
| 2771 | s = getvar_s(evaluate(op1->r.n, TMPVAR0)); | ||
| 2772 | hash_remove(iamarray(v), s); | ||
| 2773 | } else { | ||
| 2774 | clear_array(iamarray(v)); | ||
| 2775 | } | ||
| 2776 | goto next; | ||
| 2777 | } | ||
| 2778 | |||
| 2779 | /* execute inevitable things */ | 2753 | /* execute inevitable things */ |
| 2780 | if (opinfo & OF_RES1) | 2754 | if (opinfo & OF_RES1) |
| 2781 | L.v = evaluate(op1, TMPVAR0); | 2755 | L.v = evaluate(op1, TMPVAR0); |
| @@ -2905,7 +2879,31 @@ static var *evaluate(node *op, var *res) | |||
| 2905 | break; | 2879 | break; |
| 2906 | } | 2880 | } |
| 2907 | 2881 | ||
| 2908 | /* case XC( OC_DELETE ): - moved to happen before arg evaluation */ | 2882 | case XC( OC_DELETE ): |
| 2883 | debug_printf_eval("DELETE\n"); | ||
| 2884 | { | ||
| 2885 | /* "delete" is special: | ||
| 2886 | * "delete array[var--]" must evaluate index expr only once. | ||
| 2887 | */ | ||
| 2888 | uint32_t info = op1->info & OPCLSMASK; | ||
| 2889 | var *v; | ||
| 2890 | |||
| 2891 | if (info == OC_VAR) { | ||
| 2892 | v = op1->l.v; | ||
| 2893 | } else if (info == OC_FNARG) { | ||
| 2894 | v = &fnargs[op1->l.aidx]; | ||
| 2895 | } else { | ||
| 2896 | syntax_error(EMSG_NOT_ARRAY); | ||
| 2897 | } | ||
| 2898 | if (op1->r.n) { /* array ref? */ | ||
| 2899 | const char *s; | ||
| 2900 | s = getvar_s(evaluate(op1->r.n, TMPVAR0)); | ||
| 2901 | hash_remove(iamarray(v), s); | ||
| 2902 | } else { | ||
| 2903 | clear_array(iamarray(v)); | ||
| 2904 | } | ||
| 2905 | break; | ||
| 2906 | } | ||
| 2909 | 2907 | ||
| 2910 | case XC( OC_NEWSOURCE ): | 2908 | case XC( OC_NEWSOURCE ): |
| 2911 | debug_printf_eval("NEWSOURCE\n"); | 2909 | debug_printf_eval("NEWSOURCE\n"); |
| @@ -3342,7 +3340,7 @@ static var *evaluate(node *op, var *res) | |||
| 3342 | default: | 3340 | default: |
| 3343 | syntax_error(EMSG_POSSIBLE_ERROR); | 3341 | syntax_error(EMSG_POSSIBLE_ERROR); |
| 3344 | } /* switch */ | 3342 | } /* switch */ |
| 3345 | next: | 3343 | |
| 3346 | if ((opinfo & OPCLSMASK) <= SHIFT_TIL_THIS) | 3344 | if ((opinfo & OPCLSMASK) <= SHIFT_TIL_THIS) |
| 3347 | op = op->a.n; | 3345 | op = op->a.n; |
| 3348 | if ((opinfo & OPCLSMASK) >= RECUR_FROM_THIS) | 3346 | if ((opinfo & OPCLSMASK) >= RECUR_FROM_THIS) |
