aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog15
-rw-r--r--awk.h1
-rw-r--r--builtin.c8
-rw-r--r--debug.c1
-rw-r--r--interpret.h4
-rw-r--r--test/ChangeLog5
-rw-r--r--test/Makefile.am4
-rw-r--r--test/Makefile.in4
-rw-r--r--test/typeof3.awk19
-rw-r--r--test/typeof3.ok8
-rw-r--r--test/typeof4.awk13
-rw-r--r--test/typeof4.ok1
12 files changed, 81 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index 9e412428..49c557de 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2015-06-25 Arnold D. Robbins <arnold@skeeve.com>
+
+ Further work straightening out memory management for typeof.
+
+ * awk.h (DEREF): Add an assert.
+ * builtin.c (do_typeof): Add comments, cases where not to deref.
+ * debug.c (print_instruction): Add Op_push_arg_untyped.
+ * interpret.h (r_interpret): Additional comments / tweaks for
+ Op_push_arg_untyped.
+
+ Unrelated. Make `x = @/foo/ ; print x' print something.
+
+ * builtin.c (do_print): Check for Node_typedregex and handle it.
+ Needed for adding test code.
+
2015-06-22 Arnold D. Robbins <arnold@skeeve.com>
* awkgram.y (snode): Make isarray not scalarize untyped parameters
diff --git a/awk.h b/awk.h
index 0c42f2e7..220dba95 100644
--- a/awk.h
+++ b/awk.h
@@ -1182,6 +1182,7 @@ extern void r_unref(NODE *tmp);
static inline void
DEREF(NODE *r)
{
+ assert(r->valref > 0);
if (--r->valref == 0)
r_unref(r);
}
diff --git a/builtin.c b/builtin.c
index e476ec99..1dd7dcbe 100644
--- a/builtin.c
+++ b/builtin.c
@@ -2144,7 +2144,9 @@ do_print(int nargs, int redirtype)
fatal(_("attempt to use array `%s' in a scalar context"), array_vname(tmp));
}
- if ((tmp->flags & (NUMBER|STRING)) == NUMBER) {
+ if (tmp->type == Node_typedregex)
+ args_array[i] = force_string(tmp);
+ else if ((tmp->flags & (NUMBER|STRING)) == NUMBER) {
if (OFMTidx == CONVFMTidx)
args_array[i] = force_string(tmp);
else
@@ -3877,11 +3879,14 @@ do_typeof(int nargs)
arg = POP();
switch (arg->type) {
case Node_var_array:
+ /* Node_var_array is never UPREF'ed */
res = "array";
deref = false;
break;
case Node_typedregex:
+ /* Op_push_re does not UPREF */
res = "regexp";
+ deref = false;
break;
case Node_val:
case Node_var:
@@ -3894,6 +3899,7 @@ do_typeof(int nargs)
break;
case Node_var_new:
res = "untyped";
+ deref = false;
break;
default:
fatal(_("typeof: unknown argument type `%s'"),
diff --git a/debug.c b/debug.c
index 99106e55..d0e47f4a 100644
--- a/debug.c
+++ b/debug.c
@@ -3990,6 +3990,7 @@ print_instruction(INSTRUCTION *pc, Func_print print_func, FILE *fp, int in_dump)
case Op_push_i:
case Op_push:
case Op_push_arg:
+ case Op_push_arg_untyped:
case Op_push_param:
case Op_push_array:
case Op_push_re:
diff --git a/interpret.h b/interpret.h
index 554a7663..1005174a 100644
--- a/interpret.h
+++ b/interpret.h
@@ -177,6 +177,7 @@ top:
case Node_var_new:
uninitialized_scalar:
if (op != Op_push_arg_untyped) {
+ /* convert untyped to scalar */
m->type = Node_var;
m->var_value = dupnode(Nnull_string);
}
@@ -185,7 +186,8 @@ uninitialized_scalar:
_("reference to uninitialized argument `%s'") :
_("reference to uninitialized variable `%s'"),
save_symbol->vname);
- m = dupnode(Nnull_string);
+ if (op != Op_push_arg_untyped)
+ m = dupnode(Nnull_string);
PUSH(m);
break;
diff --git a/test/ChangeLog b/test/ChangeLog
index 393f38e8..8d74c4ef 100644
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -1,3 +1,8 @@
+2015-06-25 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (typeof3, typeof4): New tests.
+ * typeof2.awk, typeof2.ok, typeof3.awk, typeof3.ok: New files.
+
2015-06-21 Arnold D. Robbins <arnold@skeeve.com>
* Makefile.am (typeof2): New test.
diff --git a/test/Makefile.am b/test/Makefile.am
index 25b8b708..0c32fa6c 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -987,6 +987,10 @@ EXTRA_DIST = \
typeof1.ok \
typeof2.awk \
typeof2.ok \
+ typeof3.awk \
+ typeof3.ok \
+ typeof4.awk \
+ typeof4.ok \
uninit2.awk \
uninit2.ok \
uninit3.awk \
diff --git a/test/Makefile.in b/test/Makefile.in
index 1ab60181..81562779 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -1244,6 +1244,10 @@ EXTRA_DIST = \
typeof1.ok \
typeof2.awk \
typeof2.ok \
+ typeof3.awk \
+ typeof3.ok \
+ typeof4.awk \
+ typeof4.ok \
uninit2.awk \
uninit2.ok \
uninit3.awk \
diff --git a/test/typeof3.awk b/test/typeof3.awk
new file mode 100644
index 00000000..d148f373
--- /dev/null
+++ b/test/typeof3.awk
@@ -0,0 +1,19 @@
+BEGIN {
+ x = @/xx/
+ print typeof(x)
+ print x
+}
+
+# this set may not really be needed for the test
+BEGIN {
+ x = 4
+ print typeof(@/xxx/)
+ print typeof(3)
+ print x
+}
+
+BEGIN {
+ print typeof(x)
+ print typeof(a[1])
+ a[1][2] # fatals on this
+}
diff --git a/test/typeof3.ok b/test/typeof3.ok
new file mode 100644
index 00000000..c8f458a1
--- /dev/null
+++ b/test/typeof3.ok
@@ -0,0 +1,8 @@
+regexp
+xx
+regexp
+scalar_n
+4
+scalar_n
+untyped
+gawk: test/typeof3.awk:18: fatal: attempt to use scalar `a["1"]' as an array
diff --git a/test/typeof4.awk b/test/typeof4.awk
new file mode 100644
index 00000000..62c2905c
--- /dev/null
+++ b/test/typeof4.awk
@@ -0,0 +1,13 @@
+BEGIN{ a["x"]["y"]["z"]="scalar" ; walk_array(a, "a")}
+function walk_array(arr, name, i, r)
+{
+ for (i in arr) {
+ r = typeof(arr[i])
+# printf("typeof(%s[%s]) = %s\n", name, i, r) > "/dev/stderr"
+ if (r == "array") {
+ walk_array(arr[i], name "[" i "]")
+ } else {
+ printf "%s[%s] = %s\n", name, i, arr[i]
+ }
+ }
+}
diff --git a/test/typeof4.ok b/test/typeof4.ok
new file mode 100644
index 00000000..fca0263d
--- /dev/null
+++ b/test/typeof4.ok
@@ -0,0 +1 @@
+a[x][y][z] = scalar