diff options
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | array.c | 40 | ||||
-rw-r--r-- | awk.h | 1 |
3 files changed, 35 insertions, 13 deletions
@@ -1,7 +1,12 @@ -Fri Apr 29 10:27:18 2011 Arnold D. Robbins <arnold@skeeve.com> +Fri Apr 29 11:33:08 2011 Arnold D. Robbins <arnold@skeeve.com> + * awk.h (NUMIND): New flag, indicates numeric value of an + array index is current. * array.c (awk_hash): Remove code for VAXC, it's no longer needed. Per Pat Rankin. + (assoc_lookup): Only assign the numeric value if it's available. + (do_delete): Add comment about free_subs calling force_string. + (sort_force_index): Use NUMIND. Fri Apr 29 10:15:24 2011 John Haque <j.eh@mchsi.com> @@ -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; } } @@ -373,6 +373,7 @@ typedef struct exp_node { # define FIELD 512 /* this is a field */ # define INTLSTR 1024 /* use localized version */ # define WSTRCUR 2048 /* wide str value is current */ +# define NUMIND 4096 /* numeric val of index is current */ } NODE; |