summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko2021-07-02 15:19:14 +0200
committerDenys Vlasenko2021-07-02 15:21:36 +0200
commit640212ae0ea8a1b47cd73a080d77b25b9f3ccd40 (patch)
tree4bdd98a112118c2a79e073ab6ca474fc7004c30d
parentef5463cf16f88c0992b2073a30ab6081c86fdf23 (diff)
downloadbusybox-640212ae0ea8a1b47cd73a080d77b25b9f3ccd40.zip
busybox-640212ae0ea8a1b47cd73a080d77b25b9f3ccd40.tar.gz
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 068ed68..a3dda69 100644
--- a/editors/awk.c
+++ b/editors/awk.c
@@ -319,7 +319,7 @@ if ((n) & TC_NUMBER ) debug_printf_parse(" NUMBER" ); \
#define xV OF_RES2
#define xS (OF_RES2 | OF_STR2)
#define Vx OF_RES1
-#define Rx (OF_RES1 | OF_NUM1 | OF_REQUIRED)
+#define Rx OF_REQUIRED
#define VV (OF_RES1 | OF_RES2)
#define Nx (OF_RES1 | OF_NUM1)
#define NV (OF_RES1 | OF_NUM1 | OF_RES2)
@@ -2750,32 +2750,6 @@ static var *evaluate(node *op, var *res)
op1 = op->l.n;
debug_printf_eval("opinfo:%08x opn:%08x\n", opinfo, opn);
- /* "delete" is special:
- * "delete array[var--]" must evaluate index expr only once,
- * must not evaluate it in "execute inevitable things" part.
- */
- if (XC(opinfo & OPCLSMASK) == XC(OC_DELETE)) {
- uint32_t info = op1->info & OPCLSMASK;
- var *v;
-
- debug_printf_eval("DELETE\n");
- if (info == OC_VAR) {
- v = op1->l.v;
- } else if (info == OC_FNARG) {
- v = &fnargs[op1->l.aidx];
- } else {
- syntax_error(EMSG_NOT_ARRAY);
- }
- if (op1->r.n) { /* array ref? */
- const char *s;
- s = getvar_s(evaluate(op1->r.n, TMPVAR0));
- hash_remove(iamarray(v), s);
- } else {
- clear_array(iamarray(v));
- }
- goto next;
- }
-
/* execute inevitable things */
if (opinfo & OF_RES1)
L.v = evaluate(op1, TMPVAR0);
@@ -2905,7 +2879,31 @@ static var *evaluate(node *op, var *res)
break;
}
- /* case XC( OC_DELETE ): - moved to happen before arg evaluation */
+ case XC( OC_DELETE ):
+ debug_printf_eval("DELETE\n");
+ {
+ /* "delete" is special:
+ * "delete array[var--]" must evaluate index expr only once.
+ */
+ uint32_t info = op1->info & OPCLSMASK;
+ var *v;
+
+ if (info == OC_VAR) {
+ v = op1->l.v;
+ } else if (info == OC_FNARG) {
+ v = &fnargs[op1->l.aidx];
+ } else {
+ syntax_error(EMSG_NOT_ARRAY);
+ }
+ if (op1->r.n) { /* array ref? */
+ const char *s;
+ s = getvar_s(evaluate(op1->r.n, TMPVAR0));
+ hash_remove(iamarray(v), s);
+ } else {
+ clear_array(iamarray(v));
+ }
+ break;
+ }
case XC( OC_NEWSOURCE ):
debug_printf_eval("NEWSOURCE\n");
@@ -3342,7 +3340,7 @@ static var *evaluate(node *op, var *res)
default:
syntax_error(EMSG_POSSIBLE_ERROR);
} /* switch */
- next:
+
if ((opinfo & OPCLSMASK) <= SHIFT_TIL_THIS)
op = op->a.n;
if ((opinfo & OPCLSMASK) >= RECUR_FROM_THIS)