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>
This commit is contained in:
parent
ef5463cf16
commit
640212ae0e
@ -319,7 +319,7 @@ if ((n) & TC_NUMBER ) debug_printf_parse(" NUMBER" ); \
|
|||||||
#define xV OF_RES2
|
#define xV OF_RES2
|
||||||
#define xS (OF_RES2 | OF_STR2)
|
#define xS (OF_RES2 | OF_STR2)
|
||||||
#define Vx OF_RES1
|
#define Vx OF_RES1
|
||||||
#define Rx (OF_RES1 | OF_NUM1 | OF_REQUIRED)
|
#define Rx OF_REQUIRED
|
||||||
#define VV (OF_RES1 | OF_RES2)
|
#define VV (OF_RES1 | OF_RES2)
|
||||||
#define Nx (OF_RES1 | OF_NUM1)
|
#define Nx (OF_RES1 | OF_NUM1)
|
||||||
#define NV (OF_RES1 | OF_NUM1 | OF_RES2)
|
#define NV (OF_RES1 | OF_NUM1 | OF_RES2)
|
||||||
@ -2750,32 +2750,6 @@ static var *evaluate(node *op, var *res)
|
|||||||
op1 = op->l.n;
|
op1 = op->l.n;
|
||||||
debug_printf_eval("opinfo:%08x opn:%08x\n", opinfo, opn);
|
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 */
|
/* execute inevitable things */
|
||||||
if (opinfo & OF_RES1)
|
if (opinfo & OF_RES1)
|
||||||
L.v = evaluate(op1, TMPVAR0);
|
L.v = evaluate(op1, TMPVAR0);
|
||||||
@ -2905,7 +2879,31 @@ static var *evaluate(node *op, var *res)
|
|||||||
break;
|
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 ):
|
case XC( OC_NEWSOURCE ):
|
||||||
debug_printf_eval("NEWSOURCE\n");
|
debug_printf_eval("NEWSOURCE\n");
|
||||||
@ -3342,7 +3340,7 @@ static var *evaluate(node *op, var *res)
|
|||||||
default:
|
default:
|
||||||
syntax_error(EMSG_POSSIBLE_ERROR);
|
syntax_error(EMSG_POSSIBLE_ERROR);
|
||||||
} /* switch */
|
} /* switch */
|
||||||
next:
|
|
||||||
if ((opinfo & OPCLSMASK) <= SHIFT_TIL_THIS)
|
if ((opinfo & OPCLSMASK) <= SHIFT_TIL_THIS)
|
||||||
op = op->a.n;
|
op = op->a.n;
|
||||||
if ((opinfo & OPCLSMASK) >= RECUR_FROM_THIS)
|
if ((opinfo & OPCLSMASK) >= RECUR_FROM_THIS)
|
||||||
|
Loading…
Reference in New Issue
Block a user