aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--interpret.h20
-rw-r--r--symbol.c33
-rw-r--r--test/ChangeLog8
-rw-r--r--test/Makefile.am16
-rw-r--r--test/Makefile.in26
-rw-r--r--test/Maketests10
-rw-r--r--test/symtab4.awk1
-rw-r--r--test/symtab4.in2
-rw-r--r--test/symtab4.ok2
-rw-r--r--test/symtab5.awk1
-rw-r--r--test/symtab5.in2
-rw-r--r--test/symtab5.ok2
-rw-r--r--test/symtab6.awk1
14 files changed, 114 insertions, 14 deletions
diff --git a/ChangeLog b/ChangeLog
index af8c2b86..58bf10ed 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -6,6 +6,10 @@
remove_element, run_ext_exit_handlers): Add null pointer checks.
Everywhere: Add / fixup leading comments.
+ * interpret.h (Op_store_sub): If assigning to an unitialized variable
+ through SYMTAB, change it to Node_var. Add explanatory comments.
+ * symbol.c (get_symbol): Rationalized. Skip non-variables in SYMTAB.
+
2012-11-04 Arnold D. Robbins <arnold@skeeve.com>
* gawkapi.h: Minor documentation edit.
diff --git a/interpret.h b/interpret.h
index 0a306848..26725a21 100644
--- a/interpret.h
+++ b/interpret.h
@@ -557,10 +557,26 @@ mod:
}
DEREF(t2);
+ /*
+ * Changing something in FUNCTAB is not allowed.
+ *
+ * SYMTAB is a little more messy. Three kinds of values may
+ * be stored in SYMTAB:
+ * 1. Variables that don"t yet have a value (Node_var_new)
+ * 2. Variables that have a value (Node_var)
+ * 3. Values that awk code stuck into SYMTAB not related to variables (Node_value)
+ * For 1, since we are giving it a value, we have to change the type to Node_var.
+ * For 1 and 2, we have to step through the Node_var to get to the value.
+ * For 3, we just us the value we got from assoc_lookup(), above.
+ */
if (t1 == func_table)
fatal(_("cannot assign to elements of FUNCTAB"));
- else if (t1 == symbol_table && (*lhs)->type == Node_var)
- lhs = & ((*lhs)->var_value);
+ else if ( t1 == symbol_table
+ && ( (*lhs)->type == Node_var
+ || (*lhs)->type == Node_var_new)) {
+ (*lhs)->type = Node_var; /* in case was Node_var_new */
+ lhs = & ((*lhs)->var_value); /* extra level of indirection */
+ }
unref(*lhs);
*lhs = POP_SCALAR();
diff --git a/symbol.c b/symbol.c
index 1e0e474b..e698298f 100644
--- a/symbol.c
+++ b/symbol.c
@@ -379,23 +379,36 @@ get_symbols(SYMBOL_TYPE what, int sort)
if (what == FUNCTION) {
count = func_count;
the_table = func_table;
+
+ max = the_table->table_size * 2;
+ list = assoc_list(the_table, "@unsorted", ASORTI);
+ emalloc(table, NODE **, (count + 1) * sizeof(NODE *), "symbol_list");
+
+ for (i = j = 0; i < max; i += 2) {
+ r = list[i+1];
+ if (r->type == Node_ext_func)
+ continue;
+ assert(r->type == Node_func);
+ table[j++] = r;
+ }
} else { /* what == VARIABLE */
- count = var_count;
the_table = symbol_table;
+ count = var_count;
+
update_global_values();
- }
- emalloc(table, NODE **, (count + 1) * sizeof(NODE *), "symbol_list");
+ max = the_table->table_size * 2;
+ list = assoc_list(the_table, "@unsorted", ASORTI);
+ emalloc(table, NODE **, (count + 1) * sizeof(NODE *), "symbol_list");
- max = the_table->table_size * 2;
- list = assoc_list(the_table, "@unsorted", ASORTI);
- for (i = j = 0; i < max; i += 2) {
- r = list[i+1];
- if (r->type == Node_ext_func)
- continue;
- if (what == VARIABLE || r->type == Node_func)
+ for (i = j = 0; i < max; i += 2) {
+ r = list[i+1];
+ if (r->vname == NULL) /* non-variable in SYMTAB */
+ continue;
table[j++] = r;
+ }
}
+
efree(list);
if (sort && count > 1)
diff --git a/test/ChangeLog b/test/ChangeLog
index feedd95b..55c6494c 100644
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -1,3 +1,11 @@
+2012-11-10 Arnold D. Robbins <arnold@skeeve.com>
+
+ * symtab4.awk, symtab4.in, symtab4.ok, symtab5.awk, symtab5.in,
+ symtab5.ok, symtab6.awk: New files.
+ * Makefile.am (EXTRA_DIST): Add new files.
+ (symtab4, symtab5, symtab6): New tests.
+ Thanks to Assaf Gordon <gordon@cshl.edu>.
+
2012-10-28 Andrew J. Schorr <aschorr@telemetry-investments.com>
* messages.awk, fts.awk: Adjusted so make diffout will work.
diff --git a/test/Makefile.am b/test/Makefile.am
index d3c1b14c..6530f3db 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -799,6 +799,14 @@ EXTRA_DIST = \
symtab2.ok \
symtab3.awk \
symtab3.ok \
+ symtab4.awk \
+ symtab4.in \
+ symtab4.ok \
+ symtab5.awk \
+ symtab5.in \
+ symtab5.ok \
+ symtab6.awk \
+ symtab6.ok \
synerr1.awk \
synerr1.ok \
synerr2.awk \
@@ -919,7 +927,7 @@ GAWK_EXT_TESTS = \
rebuf regx8bit reint reint2 rsstart1 \
rsstart2 rsstart3 rstest6 shadow sortfor sortu splitarg4 strftime \
strtonum switch2 \
- symtab1 symtab2 symtab3 \
+ symtab1 symtab2 symtab3 symtab4 symtab5 symtab6 \
include include2 incdupe incdupe2 incdupe3 \
incdupe4 incdupe5 incdupe6 incdupe7
@@ -1689,6 +1697,12 @@ charasbytes:
od -c -t x1 | sed -e 's/ */ /g' -e 's/ *$$//' >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
@-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+symtab6:
+ @echo $@
+ @$(AWK) -d__$@ -f $(srcdir)/$@.awk
+ @grep -v '^ENVIRON' __$@ > _$@ ; rm __$@
+ @-$(CMP) $@.ok _$@ && rm -f $@.ok _$@
+
# Targets generated for other tests:
include Maketests
diff --git a/test/Makefile.in b/test/Makefile.in
index c148886b..22b5cf8d 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -1011,6 +1011,14 @@ EXTRA_DIST = \
symtab2.ok \
symtab3.awk \
symtab3.ok \
+ symtab4.awk \
+ symtab4.in \
+ symtab4.ok \
+ symtab5.awk \
+ symtab5.in \
+ symtab5.ok \
+ symtab6.awk \
+ symtab6.ok \
synerr1.awk \
synerr1.ok \
synerr2.awk \
@@ -1130,7 +1138,7 @@ GAWK_EXT_TESTS = \
rebuf regx8bit reint reint2 rsstart1 \
rsstart2 rsstart3 rstest6 shadow sortfor sortu splitarg4 strftime \
strtonum switch2 \
- symtab1 symtab2 symtab3 \
+ symtab1 symtab2 symtab3 symtab4 symtab5 symtab6 \
include include2 incdupe incdupe2 incdupe3 \
incdupe4 incdupe5 incdupe6 incdupe7
@@ -2069,6 +2077,12 @@ charasbytes:
AWKPATH=$(srcdir) $(AWK) -b -f $@.awk $(srcdir)/$@.in | \
od -c -t x1 | sed -e 's/ */ /g' -e 's/ *$$//' >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
@-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+symtab6:
+ @echo $@
+ @$(AWK) -d__$@ -f $(srcdir)/$@.awk
+ @grep -v '^ENVIRON' __$@ > _$@ ; rm __$@
+ @-$(CMP) $@.ok _$@ && rm -f $@.ok _$@
Gt-dummy:
# file Maketests, generated from Makefile.am by the Gentests program
addcomma:
@@ -3261,6 +3275,16 @@ symtab3:
@AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
@-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+symtab4:
+ @echo $@
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+symtab5:
+ @echo $@
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
include:
@echo $@
@AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
diff --git a/test/Maketests b/test/Maketests
index 6490410c..1accc80d 100644
--- a/test/Maketests
+++ b/test/Maketests
@@ -1190,6 +1190,16 @@ symtab3:
@AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
@-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+symtab4:
+ @echo $@
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
+symtab5:
+ @echo $@
+ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
+
include:
@echo $@
@AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
diff --git a/test/symtab4.awk b/test/symtab4.awk
new file mode 100644
index 00000000..4eed7e99
--- /dev/null
+++ b/test/symtab4.awk
@@ -0,0 +1 @@
+{SYMTAB["POS"]=1 ; print $POS }
diff --git a/test/symtab4.in b/test/symtab4.in
new file mode 100644
index 00000000..d35e1920
--- /dev/null
+++ b/test/symtab4.in
@@ -0,0 +1,2 @@
+1 a
+2 b
diff --git a/test/symtab4.ok b/test/symtab4.ok
new file mode 100644
index 00000000..1191247b
--- /dev/null
+++ b/test/symtab4.ok
@@ -0,0 +1,2 @@
+1
+2
diff --git a/test/symtab5.awk b/test/symtab5.awk
new file mode 100644
index 00000000..e4fbc85f
--- /dev/null
+++ b/test/symtab5.awk
@@ -0,0 +1 @@
+BEGIN {SYMTAB["POS"]=1} {print $POS}
diff --git a/test/symtab5.in b/test/symtab5.in
new file mode 100644
index 00000000..d35e1920
--- /dev/null
+++ b/test/symtab5.in
@@ -0,0 +1,2 @@
+1 a
+2 b
diff --git a/test/symtab5.ok b/test/symtab5.ok
new file mode 100644
index 00000000..1191247b
--- /dev/null
+++ b/test/symtab5.ok
@@ -0,0 +1,2 @@
+1
+2
diff --git a/test/symtab6.awk b/test/symtab6.awk
new file mode 100644
index 00000000..d8f4cb1d
--- /dev/null
+++ b/test/symtab6.awk
@@ -0,0 +1 @@
+BEGIN {SYMTAB["POS"]=1}