summaryrefslogtreecommitdiff
path: root/array.c
diff options
context:
space:
mode:
authorArnold D. Robbins <arnold@skeeve.com>2011-04-29 11:35:40 +0300
committerArnold D. Robbins <arnold@skeeve.com>2011-04-29 11:35:40 +0300
commit95155e4fa75ef9b29a1f2aab330f4558aa9d5383 (patch)
treef0b21b452c824bad12399218d222be564d0406bb /array.c
parent70a498e0df48c71699797024fcb4c8154599ea5d (diff)
downloadgawk-95155e4fa75ef9b29a1f2aab330f4558aa9d5383.tar.gz
Improve saving of numeric value of index.
Diffstat (limited to 'array.c')
-rw-r--r--array.c40
1 files changed, 28 insertions, 12 deletions
diff --git a/array.c b/array.c
index 7f644ba7..ee8ac9ee 100644
--- a/array.c
+++ b/array.c
@@ -515,8 +515,17 @@ assoc_lookup(NODE *symbol, NODE *subs, int reference)
bucket->ahnext = symbol->var_array[hash1];
bucket->ahcode = code;
- /* set the numeric value for the index */
- bucket->ahname_num = force_number(subs);
+ /*
+ * Set the numeric value for the index if it's available. Useful
+ * for numeric sorting by index. Do this only if the numeric
+ * value is available, instead of all the time, since doing it
+ * all the time is a big performance hit for something that may
+ * never be used.
+ */
+ if ((subs->flags & NUMCUR) != 0) {
+ bucket->ahname_num = subs->numbr;
+ bucket->flags |= NUMIND;
+ }
/* hook it into the symbol table */
symbol->var_array[hash1] = bucket;
@@ -539,6 +548,16 @@ do_delete(NODE *symbol, int nsubs)
assert(symbol->type == Node_var_array);
+ /*
+ * The force_string() call is needed to make sure that
+ * the string subscript is reasonable. For example, with it:
+ *
+ * $ ./gawk --posix 'BEGIN { CONVFMT="%ld"; delete a[1.233]}'
+ * gawk: cmd. line:1: fatal: `%l' is not permitted in POSIX awk formats
+ *
+ * Without it, the code does not fail.
+ */
+
#define free_subs(n) \
do { \
NODE *s = PEEK(n - 1); \
@@ -879,7 +898,10 @@ dup_table(NODE *symbol, NODE *newsymb)
bucket->flags |= MALLOC;
bucket->ahname_ref = 1;
bucket->ahcode = chain->ahcode;
- bucket->ahname_num = chain->ahname_num;
+ if ((chain->flags & NUMIND) != 0) {
+ bucket->ahname_num = chain->ahname_num;
+ bucket->flags |= NUMIND;
+ }
/*
* copy the corresponding name and
@@ -1452,20 +1474,14 @@ sort_force_index_number(NODE **list, size_t num_elems)
for (i = 0; i < num_elems; i++) {
r = list[i];
- /* Kludge: the use of NUMCUR flag for a Node_ahash is only to detect
- * multiple conversion attempts. Also, the flag value of a Node_ahash
- * isn't used anywhere else in the gawk source.
- * Maybe a new flag other than NUMCUR should be used ?
- */
-
- if ((r->flags & NUMCUR) != 0) /* once in a lifetime is more than enough */
+ if ((r->flags & NUMIND) != 0) /* once in a lifetime is more than enough */
continue;
temp_node.type = Node_val;
temp_node.stptr = r->ahname_str;
temp_node.stlen = r->ahname_len;
temp_node.flags = 0; /* only interested in the return value of r_force_number */
- r->ahname_num = r_force_number(&temp_node);
- r->flags |= NUMCUR;
+ r->ahname_num = r_force_number(& temp_node);
+ r->flags |= NUMIND;
}
}