aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2021-07-02 15:19:14 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2021-07-02 15:21:36 +0200
commit640212ae0ea8a1b47cd73a080d77b25b9f3ccd40 (patch)
tree4bdd98a112118c2a79e073ab6ca474fc7004c30d
parentef5463cf16f88c0992b2073a30ab6081c86fdf23 (diff)
downloadbusybox-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.c56
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)