diff options
author | Arnold D. Robbins <arnold@skeeve.com> | 2010-07-16 12:59:03 +0300 |
---|---|---|
committer | Arnold D. Robbins <arnold@skeeve.com> | 2010-07-16 12:59:03 +0300 |
commit | b9e4a1fd4c8c8753ab8a9887bab55f03efe1e3e2 (patch) | |
tree | e6f86edd2f661aff2cd81eb4d4a54fa86fd4fe60 /array.c | |
parent | 3ca7f0b16d0a5c105380b284a81c6a1b2c210908 (diff) | |
download | egawk-b9e4a1fd4c8c8753ab8a9887bab55f03efe1e3e2.tar.gz egawk-b9e4a1fd4c8c8753ab8a9887bab55f03efe1e3e2.tar.bz2 egawk-b9e4a1fd4c8c8753ab8a9887bab55f03efe1e3e2.zip |
Move to gawk-3.0.6.
Diffstat (limited to 'array.c')
-rw-r--r-- | array.c | 104 |
1 files changed, 92 insertions, 12 deletions
@@ -223,11 +223,14 @@ int hash1; * Array indexes are strings; compare as such, always! */ s1 = bucket->ahname; + s1 = force_string(s1); s2 = subs; - if (s1->stlen == s2->stlen - && STREQN(s1->stptr, s2->stptr, s1->stlen)) - return bucket; + if (s1->stlen == s2->stlen) { + if (s1->stlen == 0 /* "" is a valid index */ + || STREQN(s1->stptr, s2->stptr, s1->stlen)) + return bucket; + } } return NULL; } @@ -324,9 +327,6 @@ NODE *symbol, *subs; bucket->ahname = dupnode(subs); free_temp(subs); - /* array subscripts are strings */ - bucket->ahname->flags &= ~NUMBER; - bucket->ahname->flags |= STRING; bucket->ahvalue = Nnull_string; bucket->ahnext = symbol->var_array[hash1]; symbol->var_array[hash1] = bucket; @@ -367,9 +367,24 @@ NODE *symbol, *tree; last = NULL; for (bucket = symbol->var_array[hash1]; bucket != NULL; - last = bucket, bucket = bucket->ahnext) - if (cmp_nodes(bucket->ahname, subs) == 0) - break; + last = bucket, bucket = bucket->ahnext) { + /* + * This used to use cmp_nodes() here. That's wrong. + * Array indexes are strings; compare as such, always! + */ + NODE *s1, *s2; + + s1 = bucket->ahname; + s1 = force_string(s1); + s2 = subs; + + if (s1->stlen == s2->stlen) { + if (s1->stlen == 0 /* "" is a valid index */ + || STREQN(s1->stptr, s2->stptr, s1->stlen)) + break; + } + } + if (bucket == NULL) { if (do_lint) warning("delete: index `%s' not in array `%s'", @@ -396,6 +411,50 @@ NODE *symbol, *tree; } } +/* do_delete_loop --- simulate ``for (iggy in foo) delete foo[iggy]'' */ + +/* + * The primary hassle here is that `iggy' needs to have some arbitrary + * array index put in it before we can clear the array, we can't + * just replace the loop with `delete foo'. + */ + +void +do_delete_loop(symbol, tree) +NODE *symbol, *tree; +{ + size_t i; + NODE *n, **lhs; + Func_ptr after_assign = NULL; + + if (symbol->type == Node_param_list) { + symbol = stack_ptr[symbol->param_cnt]; + if (symbol->type == Node_var) + return; + } + if (symbol->type == Node_array_ref) + symbol = symbol->orig_array; + if (symbol->type == Node_var_array) { + if (symbol->var_array == NULL) + return; + } else + fatal("delete: illegal use of variable `%s' as array", + symbol->vname); + + /* get first index value */ + for (i = 0; i < symbol->array_size; i++) { + if (symbol->var_array[i] != NULL) { + lhs = get_lhs(tree->lnode, & after_assign); + unref(*lhs); + *lhs = dupnode(symbol->var_array[i]->ahname); + break; + } + } + + /* blast the array in one shot */ + assoc_clear(symbol); +} + /* assoc_scan --- start a ``for (iggy in foo)'' loop */ void @@ -558,22 +617,31 @@ NODE *symbol; NODE *bucket; if (symbol->var_array == NULL) { - printf("%s: empty\n", symbol->vname); + printf("%s: empty (null)\n", symbol->vname); return tmp_number((AWKNUM) 0); } + if (symbol->table_size == 0) { + printf("%s: empty (zero)\n", symbol->vname); + return tmp_number((AWKNUM) 0); + } + + printf("%s: table_size = %d, array_size = %d\n", symbol->vname, + symbol->table_size, symbol->array_size); + for (i = 0; i < symbol->array_size; i++) { for (bucket = symbol->var_array[i]; bucket != NULL; bucket = bucket->ahnext) { - printf("%s: i: (%p, %ld, %s) %.*s, v: ", + printf("%s: I: [(%p, %ld, %s) len %d <%.*s>] V: [", symbol->vname, bucket->ahname, bucket->ahname->stref, flags2str(bucket->ahname->flags), (int) bucket->ahname->stlen, + (int) bucket->ahname->stlen, bucket->ahname->stptr); pr_node(bucket->ahvalue); - printf("\n"); + printf("]\n"); } } @@ -589,6 +657,18 @@ NODE *tree; NODE *r, *a; a = tree->lnode; + + if (a->type == Node_param_list) { + printf("%s: is paramater\n", a->vname); + a = stack_ptr[a->param_cnt]; + } + + if (a->type == Node_array_ref) { + printf("%s: array_ref to %s\n", a->vname, + a->orig_array->vname); + a = a->orig_array; + } + r = assoc_dump(a); return r; |