summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArnold D. Robbins <arnold@skeeve.com>2015-03-31 06:23:04 +0300
committerArnold D. Robbins <arnold@skeeve.com>2015-03-31 06:23:04 +0300
commit2ee1a928483f4fe4f594aebc5c1f8da1253c28b9 (patch)
tree3b98319ddf30a395f38c4575974b204105655306
parent080694ae82635e76992158591b39a06af7363da0 (diff)
downloadgawk-2ee1a928483f4fe4f594aebc5c1f8da1253c28b9.tar.gz
Further improvements. sub/gsub working.
-rw-r--r--ChangeLog7
-rw-r--r--awk.h1
-rw-r--r--builtin.c66
-rw-r--r--eval.c2
-rw-r--r--indirectbuitin.awk54
-rw-r--r--node.c1
6 files changed, 97 insertions, 34 deletions
diff --git a/ChangeLog b/ChangeLog
index 8610df82..47ef45ee 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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.
diff --git a/awk.h b/awk.h
index f23977fb..1205401b 100644
--- a/awk.h
+++ b/awk.h
@@ -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 */
diff --git a/builtin.c b/builtin.c
index 7926a320..c222ce78 100644
--- a/builtin.c
+++ b/builtin.c
@@ -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;
}
diff --git a/eval.c b/eval.c
index 2ba79956..5f66763a 100644
--- a/eval.c
+++ b/eval.c
@@ -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
}
}
diff --git a/node.c b/node.c
index 179d272e..7a1d99f6 100644
--- a/node.c
+++ b/node.c
@@ -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)