aboutsummaryrefslogtreecommitdiffstats
path: root/eval.c
diff options
context:
space:
mode:
authorArnold D. Robbins <arnold@skeeve.com>2011-07-15 15:35:34 +0300
committerArnold D. Robbins <arnold@skeeve.com>2011-07-15 15:35:34 +0300
commit46f2db24d9e7f792f60149f5ee89ef4f22e3f4a9 (patch)
tree4522982b751d8643ee05022e60bdac757dfd0956 /eval.c
parent84658669a180b3f1e63d20b6ea166f7c5733786b (diff)
downloadegawk-46f2db24d9e7f792f60149f5ee89ef4f22e3f4a9.tar.gz
egawk-46f2db24d9e7f792f60149f5ee89ef4f22e3f4a9.tar.bz2
egawk-46f2db24d9e7f792f60149f5ee89ef4f22e3f4a9.zip
Fix gsub losing white space when working on fields.
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c36
1 files changed, 33 insertions, 3 deletions
diff --git a/eval.c b/eval.c
index 4132474a..bdbd04bd 100644
--- a/eval.c
+++ b/eval.c
@@ -348,6 +348,7 @@ static struct optypetab {
{ "Op_K_getline", "getline" },
{ "Op_K_nextfile", "nextfile" },
{ "Op_builtin", NULL },
+ { "Op_sub_builtin", NULL },
{ "Op_in_array", " in " },
{ "Op_func_call", NULL },
{ "Op_indirect_func_call", NULL },
@@ -2114,11 +2115,13 @@ post:
break;
case Op_var_assign:
- pc->assign_var();
+ if (pc->assign_var)
+ pc->assign_var();
break;
case Op_field_assign:
- pc->field_assign();
+ if (pc->field_assign)
+ pc->field_assign();
break;
case Op_concat:
@@ -2256,7 +2259,34 @@ arrayfor:
#endif
PUSH(r);
break;
-
+
+ case Op_sub_builtin:
+ {
+ /* sub, gsub and gensub */
+
+ int matches = 0;
+
+ r = do_sub(pc->expr_count, pc->sub_flags, & matches);
+ PUSH(r);
+
+ if (matches == 0 && (pc->sub_flags & AFTER_ASSIGN) != 0) {
+
+ /* For sub and gsub, must not execute after_assign code;
+ * If the target is a FIELD, this means no field re-splitting or
+ * $0 reconstruction. For a special variable as target,
+ * set_XX routine is not called.
+ */
+
+ ni = pc->nexti;
+ assert(ni->opcode == Op_field_assign || ni->opcode == Op_var_assign);
+ if (ni->opcode == Op_field_assign)
+ ni->field_assign = (Func_ptr) 0;
+ else
+ ni->assign_var = (Func_ptr) 0;
+ }
+ }
+ break;
+
case Op_K_print:
do_print(pc->expr_count, pc->redir_type);
break;