diff options
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | awk.h | 1 | ||||
-rw-r--r-- | builtin.c | 66 | ||||
-rw-r--r-- | eval.c | 2 | ||||
-rw-r--r-- | indirectbuitin.awk | 54 | ||||
-rw-r--r-- | node.c | 1 |
6 files changed, 97 insertions, 34 deletions
@@ -1,3 +1,10 @@ +2015-03-31 Arnold D. Robbins <arnold@skeeve.com> + + * awk.h (r_get_field): Declare. + * builtin.c (call_sub_func): Rearrange the stack to be what + the buitin function expects. + * eval.c (r_get_field): Make extern. + 2015-03-24 Arnold D. Robbins <arnold@skeeve.com> * awkgram.y (make_regnode): Make extern. @@ -1408,6 +1408,7 @@ extern NODE **r_get_lhs(NODE *n, bool reference); extern STACK_ITEM *grow_stack(void); extern void dump_fcall_stack(FILE *fp); extern int register_exec_hook(Func_pre_exec preh, Func_post_exec posth); +extern NODE **r_get_field(NODE *n, Func_ptr *assign, bool reference); /* ext.c */ extern NODE *do_ext(int nargs); void load_ext(const char *lib_name); /* temporary */ @@ -3000,7 +3000,10 @@ NODE * call_sub_func(const char *name, int nargs) { unsigned int flags = 0; - NODE *regex, *replace; + NODE *regex, *replace, *glob_flag; + NODE **lhs, *rhs; + NODE *zero = make_number(0.0); + NODE *result; if (name[0] == 'g') { if (name[1] == 'e') @@ -3009,17 +3012,62 @@ call_sub_func(const char *name, int nargs) flags = GSUB; } - if ((flags == 0 || flags == GSUB) && nargs != 2) - fatal(_("%s: can be called indirectly only with two arguments"), name); + if (flags == 0 || flags == GSUB) { + /* sub or gsub */ + if (nargs != 2) + fatal(_("%s: can be called indirectly only with two arguments"), name); - replace = POP(); + replace = POP_STRING(); + regex = POP(); /* the regex */ + /* + * push regex + * push replace + * push $0 + */ + regex = make_regnode(Node_regex, regex); + PUSH(regex); + PUSH(replace); + lhs = r_get_field(zero, (Func_ptr *) 0, true); + nargs++; + PUSH_ADDRESS(lhs); + } else { + /* gensub */ + if (nargs == 4) + rhs = POP(); + else + rhs = NULL; + glob_flag = POP_STRING(); + replace = POP_STRING(); + regex = POP(); /* the regex */ + /* + * push regex + * push replace + * push glob_flag + * if (nargs = 3) { + * push $0 + * nargs++ + * } + */ + regex = make_regnode(Node_regex, regex); + PUSH(regex); + PUSH(replace); + PUSH(glob_flag); + if (rhs == NULL) { + lhs = r_get_field(zero, (Func_ptr *) 0, true); + rhs = *lhs; + UPREF(rhs); + PUSH(rhs); + nargs++; + } + PUSH(rhs); + } - regex = POP(); /* the regex */ - regex = make_regnode(Node_regex, regex); - PUSH(regex); - PUSH(replace); - return do_sub(nargs, flags); + unref(zero); + result = do_sub(nargs, flags); + if (flags != GENSUB) + reset_record(); + return result; } @@ -1180,7 +1180,7 @@ r_get_lhs(NODE *n, bool reference) /* r_get_field --- get the address of a field node */ -static inline NODE ** +NODE ** r_get_field(NODE *n, Func_ptr *assign, bool reference) { long field_num; diff --git a/indirectbuitin.awk b/indirectbuitin.awk index 8c78593c..de3d5ccd 100644 --- a/indirectbuitin.awk +++ b/indirectbuitin.awk @@ -7,16 +7,6 @@ function print_result(category, fname, builtin_result, indirect_result) builtin_result, indirect_result) } -BEGIN { - fun = "sub" - $0 = "ff11bb" - b1 = sub("f", "q") - $0 = "ff11bb" - i1 = @fun("f", "q") - print_result("string", fun, b1, i1) - exit -} - BEGIN { # math functions @@ -101,16 +91,24 @@ BEGIN { # string functions -# fun = "gensub" -# b1 = gensub("f", "q","g", "ff11bb") -# i1 = @fun("f", "q", "g", "ff11bb") -# print_result("string", fun, b1, i1) + fun = "gensub" + b1 = gensub("f", "q", "g", "ff11bb") + i1 = @fun("f", "q", "g", "ff11bb") + print_result("string", fun, b1, i1) -# fun = "gsub" -# x = "ff11bb" -# b1 = gsub("f", "q", x) -# i1 = @fun("f", "q", x) -# print_result("string", fun, b1, i1) + fun = "gsub" + $0 = "ff11bb" + b1 = gsub("f", "q") + b2 = $0 + $0 = "ff11bb" + i1 = @fun("f", "q") + i2 = $0 + print_result("string", fun, b1, i1) + if (b2 != i2) { + printf("string: %s: fail: $0 (%s) != $0 (%s)\n", + fun, b2, i2) + exit 1 + } fun = "index" b1 = index("hi, how are you", "how") @@ -143,10 +141,18 @@ BEGIN { print_result("string", fun, b1, i1) fun = "sub" - x = "ff11bb" - b1 = sub("f", "q", x) - i1 = @fun("f", "q", x) + $0 = "ff11bb" + b1 = sub("f", "q") + b2 = $0 + $0 = "ff11bb" + i1 = @fun("f", "q") + i2 = $0 print_result("string", fun, b1, i1) + if (b2 != i2) { + printf("string: %s: fail: $0 (%s) != $0 (%s)\n", + fun, b2, i2) + exit 1 + } fun = "substr" b1 = substr("0xdeadbeef", 7, 4) @@ -210,12 +216,12 @@ BEGIN { data2[data[i]] = i fun = "asorti" - asort(data2, newdata) + asorti(data2, newdata) @fun(data2, newdata2) print_result("array", fun, b1, i1) for (i in newdata) { if (! (i in newdata2) || newdata[i] != newdata2[i]) { - print fun ": failed, index", i + print fun ": failed, index", i, "value", newdata[i], newdata2[i] exit } } @@ -432,6 +432,7 @@ r_unref(NODE *tmp) if (tmp == NULL) return; if (tmp->type == Node_regex) { +fprintf(stderr, "got here!\n"); fflush(stderr); if (tmp->re_reg != NULL) refree(tmp->re_reg); if (tmp->re_text != NULL) |