diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2021-07-03 13:29:32 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2021-07-03 13:30:45 +0200 |
commit | cb042b05828c4c89320bc9c7454c04c2761bbb9a (patch) | |
tree | 4147eab7da10a0b3987856d1e19788fe7c8f4119 | |
parent | 90404ed2f62a872ffd9a555660b7ce17fae372d8 (diff) | |
download | busybox-w32-cb042b05828c4c89320bc9c7454c04c2761bbb9a.tar.gz busybox-w32-cb042b05828c4c89320bc9c7454c04c2761bbb9a.tar.bz2 busybox-w32-cb042b05828c4c89320bc9c7454c04c2761bbb9a.zip |
awk: restore strdup elision optimization in assignment
function old new delta
evaluate 3339 3387 +48
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | editors/awk.c | 25 |
1 files changed, 17 insertions, 8 deletions
diff --git a/editors/awk.c b/editors/awk.c index 649198d15..20672db9a 100644 --- a/editors/awk.c +++ b/editors/awk.c | |||
@@ -102,7 +102,7 @@ enum { | |||
102 | #define VF_USER 0x0200 /* 1 = user input (may be numeric string) */ | 102 | #define VF_USER 0x0200 /* 1 = user input (may be numeric string) */ |
103 | #define VF_SPECIAL 0x0400 /* 1 = requires extra handling when changed */ | 103 | #define VF_SPECIAL 0x0400 /* 1 = requires extra handling when changed */ |
104 | #define VF_WALK 0x0800 /* 1 = variable has alloc'd x.walker list */ | 104 | #define VF_WALK 0x0800 /* 1 = variable has alloc'd x.walker list */ |
105 | #define VF_FSTR 0x1000 /* 1 = var::string points to fstring buffer */ | 105 | #define VF_FSTR 0x1000 /* 1 = don't free() var::string (not malloced, or is owned by something else) */ |
106 | #define VF_CHILD 0x2000 /* 1 = function arg; x.parent points to source */ | 106 | #define VF_CHILD 0x2000 /* 1 = function arg; x.parent points to source */ |
107 | #define VF_DIRTY 0x4000 /* 1 = variable was set explicitly */ | 107 | #define VF_DIRTY 0x4000 /* 1 = variable was set explicitly */ |
108 | 108 | ||
@@ -1371,6 +1371,12 @@ static node *parse_expr(uint32_t term_tc) | |||
1371 | cn->a.n = vn->a.n; | 1371 | cn->a.n = vn->a.n; |
1372 | if (tc & TS_BINOP) { | 1372 | if (tc & TS_BINOP) { |
1373 | cn->l.n = vn; | 1373 | cn->l.n = vn; |
1374 | //FIXME: this is the place to detect and reject assignments to non-lvalues. | ||
1375 | //Currently we allow "assignments" to consts and temporaries, nonsense like this: | ||
1376 | // awk 'BEGIN { "qwe" = 1 }' | ||
1377 | // awk 'BEGIN { 7 *= 7 }' | ||
1378 | // awk 'BEGIN { length("qwe") = 1 }' | ||
1379 | // awk 'BEGIN { (1+1) += 3 }' | ||
1374 | expected_tc = TS_OPERAND | TS_UOPPRE | TC_REGEXP; | 1380 | expected_tc = TS_OPERAND | TS_UOPPRE | TC_REGEXP; |
1375 | if ((t_info & OPCLSMASK) == OC_PGETLINE) { | 1381 | if ((t_info & OPCLSMASK) == OC_PGETLINE) { |
1376 | /* it's a pipe */ | 1382 | /* it's a pipe */ |
@@ -3043,14 +3049,17 @@ static var *evaluate(node *op, var *res) | |||
3043 | case XC( OC_MOVE ): | 3049 | case XC( OC_MOVE ): |
3044 | debug_printf_eval("MOVE\n"); | 3050 | debug_printf_eval("MOVE\n"); |
3045 | /* if source is a temporary string, jusk relink it to dest */ | 3051 | /* if source is a temporary string, jusk relink it to dest */ |
3046 | //Disabled: if R.v is numeric but happens to have cached R.v->string, | 3052 | if (R.v == TMPVAR1 |
3047 | //then L.v ends up being a string, which is wrong | 3053 | && !(R.v->type & VF_NUMBER) |
3048 | // if (R.v == TMPVAR1 && R.v->string) { | 3054 | /* Why check !NUMBER? if R.v is a number but has cached R.v->string, |
3049 | // res = setvar_p(L.v, R.v->string); | 3055 | * L.v ends up a string, which is wrong */ |
3050 | // R.v->string = NULL; | 3056 | /*&& R.v->string - always not NULL (right?) */ |
3051 | // } else { | 3057 | ) { |
3058 | res = setvar_p(L.v, R.v->string); /* avoids strdup */ | ||
3059 | R.v->string = NULL; | ||
3060 | } else { | ||
3052 | res = copyvar(L.v, R.v); | 3061 | res = copyvar(L.v, R.v); |
3053 | // } | 3062 | } |
3054 | break; | 3063 | break; |
3055 | 3064 | ||
3056 | case XC( OC_TERNARY ): | 3065 | case XC( OC_TERNARY ): |