summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArnold D. Robbins <arnold@skeeve.com>2015-03-31 22:07:53 +0300
committerArnold D. Robbins <arnold@skeeve.com>2015-03-31 22:07:53 +0300
commita47af3141cf4a6b43e20db872e2b45ff9abb071f (patch)
tree43421d099953fc8459f847999a02f0f840932a5e
parent2ee1a928483f4fe4f594aebc5c1f8da1253c28b9 (diff)
downloadgawk-a47af3141cf4a6b43e20db872e2b45ff9abb071f.tar.gz
Get indirect calls working!
-rw-r--r--ChangeLog9
-rw-r--r--awk.h4
-rw-r--r--builtin.c68
-rw-r--r--indirectbuitin.awk131
-rw-r--r--interpret.h6
-rw-r--r--node.c9
6 files changed, 207 insertions, 20 deletions
diff --git a/ChangeLog b/ChangeLog
index 47ef45ee..4b7766d2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
2015-03-31 Arnold D. Robbins <arnold@skeeve.com>
+ * awk.h (call_sub): Renamed from call_sub_func.
+ (call_match, call_split_func): Declare.
+ * builtin.c (call_sub): Renamed from call_sub_func.
+ (call_match, call_split_func): New functions.
+ * interpret.h (r_interpret): Call new functions as appropriate.
+ * node.c (r_unref): Revert change to handle Node_regex, not needed.
+
+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.
diff --git a/awk.h b/awk.h
index 1205401b..4ac32e4a 100644
--- a/awk.h
+++ b/awk.h
@@ -1361,7 +1361,9 @@ extern NODE *do_rand(int nargs);
extern NODE *do_srand(int nargs);
extern NODE *do_match(int nargs);
extern NODE *do_sub(int nargs, unsigned int flags);
-extern NODE *call_sub_func(const char *name, int nargs);
+extern NODE *call_sub(const char *name, int nargs);
+extern NODE *call_match(int nargs);
+extern NODE *call_split_func(const char *name, int nargs);
extern NODE *format_tree(const char *, size_t, NODE **, long);
extern NODE *do_lshift(int nargs);
extern NODE *do_rshift(int nargs);
diff --git a/builtin.c b/builtin.c
index c222ce78..dde3121c 100644
--- a/builtin.c
+++ b/builtin.c
@@ -2994,10 +2994,10 @@ done:
return make_number((AWKNUM) matches);
}
-/* call_sub_func --- call do_sub indirectly */
+/* call_sub --- call do_sub indirectly */
NODE *
-call_sub_func(const char *name, int nargs)
+call_sub(const char *name, int nargs)
{
unsigned int flags = 0;
NODE *regex, *replace, *glob_flag;
@@ -3070,6 +3070,70 @@ call_sub_func(const char *name, int nargs)
return result;
}
+/* call_match --- call do_match indirectly */
+
+NODE *
+call_match(int nargs)
+{
+ NODE *regex, *text, *array;
+ NODE *result;
+
+ regex = text = array = NULL;
+ if (nargs == 3)
+ array = POP();
+ regex = POP();
+
+ /* Don't need to pop the string just to push it back ... */
+
+ regex = make_regnode(Node_regex, regex);
+ PUSH(regex);
+
+ if (array)
+ PUSH(array);
+
+ result = do_match(nargs);
+ return result;
+}
+
+/* call_split_func --- call do_split or do_pat_split indirectly */
+
+NODE *
+call_split_func(const char *name, int nargs)
+{
+ NODE *regex, *seps;
+ NODE *result;
+
+ regex = seps = NULL;
+ if (nargs < 2)
+ fatal(_("indirect call to %s requires at least two arguments"),
+ name);
+
+ if (nargs == 4)
+ seps = POP();
+
+ if (nargs >= 3) {
+ regex = POP_STRING();
+ regex = make_regnode(Node_regex, regex);
+ } else {
+ if (name[0] == 's') {
+ regex = make_regnode(Node_regex, FS_node->var_value);
+ regex->re_flags |= FS_DFLT;
+ } else
+ regex = make_regnode(Node_regex, FPAT_node->var_value);
+ nargs++;
+ }
+
+ /* Don't need to pop the string or the data array */
+
+ PUSH(regex);
+
+ if (seps)
+ PUSH(seps);
+
+ result = (name[0] == 's') ? do_split(nargs) : do_patsplit(nargs);
+
+ return result;
+}
/* make_integer - Convert an integer to a number node. */
diff --git a/indirectbuitin.awk b/indirectbuitin.awk
index de3d5ccd..4d5291d2 100644
--- a/indirectbuitin.awk
+++ b/indirectbuitin.awk
@@ -2,9 +2,11 @@ function print_result(category, fname, builtin_result, indirect_result)
{
if (builtin_result == indirect_result)
printf("%s: %s: pass\n", category, fname)
- else
+ else {
printf("%s: %s: fail: builtin: %s \tindirect: %s\n", category, fname,
builtin_result, indirect_result)
+ exit 1
+ }
}
@@ -189,14 +191,129 @@ BEGIN {
# regexp functions
-# fun = "match"
-# print_result("regexp", fun, b1, i1)
+ fun = "match"
+ b1 = match("o+", "fooob")
+ rstart = RSTART
+ rlength = RLENGTH
+ i1 = @fun("o+", "fooob")
+ print_result("regexp", fun, b1, i1)
+ if (rstart != RSTART) {
+ printf("match: failure: biRSTART (%d) != iRSTART (%d)\n",
+ rstart, RSTART)
+ exit 1
+ }
+ if (rlength != RLENGTH) {
+ printf("match: failure: biRLENGTH (%d) != iRLENGTH (%d)\n",
+ rlength, RLENGTH)
+ exit 1
+ }
-# fun = "patsplit"
-# print_result("regexp", fun, b1, i1)
+ ############## start patsplit ##############
+ fun = "patsplit"
+ delete data
+ delete data2
+ delete seps
+ delete seps2
+ b1 = patsplit("a:b:c:d", data, ":", seps)
+ i1 = @fun("a:b:c:d", data2, ":", seps2)
+ print_result("regexp", fun, b1, i1)
+ for (i in data) {
+ if ((! (i in data2)) || data[i] != data2[i]) {
+ printf("patsplit1a: fail: builtin data[%d] (%s) != indirect data[%d] (%s)\n",
+ i, data[i], i, data2[i])
+ exit 1
+ }
+ }
+ for (i in seps) {
+ if ((! (i in seps2)) || seps[i] != seps2[i]) {
+ printf("patsplit1b: fail: builtin seps[%d] (%s) != indirect seps[%d] (%s)\n",
+ i, seps[i], i, seps2[i])
+ exit 1
+ }
+ }
+
+ fun = "patsplit"
+ delete data
+ delete data2
+ b1 = patsplit("a:b:c:d", data, ":")
+ i1 = @fun("a:b:c:d", data2, ":")
+ print_result("regexp", fun, b1, i1)
+ for (i in data) {
+ if ((! (i in data2)) || data[i] != data2[i]) {
+ printf("patsplit2: fail: builtin data[%d] (%s) != indirect data[%d] (%s)\n",
+ i, data[i], i, data2[i])
+ exit 1
+ }
+ }
-# fun = "split"
-# print_result("regexp", fun, b1, i1)
+ fun = "patsplit"
+ delete data
+ delete data2
+ FPAT = "[a-z]+"
+ b1 = patsplit("a b c d", data)
+ i1 = @fun("a b c d", data2)
+ print_result("regexp", fun, b1, i1)
+ for (i in data) {
+ if ((! (i in data2)) || data[i] != data2[i]) {
+ printf("patsplit3: fail: builtin data[%d] (%s) != indirect data[%d] (%s)\n",
+ i, data[i], i, data2[i])
+ exit 1
+ }
+ }
+ ############## end patsplit ##############
+
+ ############## start split ##############
+ fun = "split"
+ delete data
+ delete data2
+ delete seps
+ delete seps2
+ b1 = split("a:b:c:d", data, ":", seps)
+ i1 = @fun("a:b:c:d", data2, ":", seps2)
+ print_result("regexp", fun, b1, i1)
+ for (i in data) {
+ if ((! (i in data2)) || data[i] != data2[i]) {
+ printf("split1a: fail: builtin data[%d] (%s) != indirect data[%d] (%s)\n",
+ i, data[i], i, data2[i])
+ exit 1
+ }
+ }
+ for (i in seps) {
+ if ((! (i in seps2)) || seps[i] != seps2[i]) {
+ printf("split1b: fail: builtin seps[%d] (%s) != indirect seps[%d] (%s)\n",
+ i, seps[i], i, seps2[i])
+ exit 1
+ }
+ }
+
+ fun = "split"
+ delete data
+ delete data2
+ b1 = split("a:b:c:d", data, ":")
+ i1 = @fun("a:b:c:d", data2, ":")
+ print_result("regexp", fun, b1, i1)
+ for (i in data) {
+ if ((! (i in data2)) || data[i] != data2[i]) {
+ printf("split2: fail: builtin data[%d] (%s) != indirect data[%d] (%s)\n",
+ i, data[i], i, data2[i])
+ exit 1
+ }
+ }
+
+ fun = "split"
+ delete data
+ delete data2
+ b1 = split("a b c d", data)
+ i1 = @fun("a b c d", data2)
+ print_result("regexp", fun, b1, i1)
+ for (i in data) {
+ if ((! (i in data2)) || data[i] != data2[i]) {
+ printf("split3: fail: builtin data[%d] (%s) != indirect data[%d] (%s)\n",
+ i, data[i], i, data2[i])
+ exit 1
+ }
+ }
+ ############## end split ##############
# array functions
diff --git a/interpret.h b/interpret.h
index f9aa3115..6dce863a 100644
--- a/interpret.h
+++ b/interpret.h
@@ -1067,7 +1067,11 @@ match_re:
/* call it */
if (the_func == (builtin_func_t) do_sub)
- r = call_sub_func(t1->stptr, arg_count);
+ r = call_sub(t1->stptr, arg_count);
+ else if (the_func == do_match)
+ r = call_match(arg_count);
+ else if (the_func == do_split || the_func == do_patsplit)
+ r = call_split_func(t1->stptr, arg_count);
else
r = the_func(arg_count);
diff --git a/node.c b/node.c
index 7a1d99f6..9fd4c7b9 100644
--- a/node.c
+++ b/node.c
@@ -431,14 +431,6 @@ r_unref(NODE *tmp)
#ifdef GAWKDEBUG
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)
- unref(tmp->re_text);
- goto free_the_node;
- }
if ((tmp->flags & MALLOC) != 0) {
if (tmp->valref > 1) {
tmp->valref--;
@@ -455,7 +447,6 @@ fprintf(stderr, "got here!\n"); fflush(stderr);
mpfr_unset(tmp);
free_wstr(tmp);
-free_the_node:
freenode(tmp);
}