aboutsummaryrefslogtreecommitdiffstats
path: root/array.c
diff options
context:
space:
mode:
Diffstat (limited to 'array.c')
-rw-r--r--array.c79
1 files changed, 31 insertions, 48 deletions
diff --git a/array.c b/array.c
index aa52f3a1..2cc76743 100644
--- a/array.c
+++ b/array.c
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 1986, 1988, 1989, 1991-2014, 2016, 2018,
+ * Copyright (C) 1986, 1988, 1989, 1991-2014, 2016, 2018, 2019,
* the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
@@ -37,10 +37,10 @@ static char indent_char[] = " ";
static NODE **null_lookup(NODE *symbol, NODE *subs);
static NODE **null_dump(NODE *symbol, NODE *subs);
-static afunc_t null_array_func[] = {
+static const array_funcs_t null_array_func = {
+ "null",
(afunc_t) 0,
(afunc_t) 0,
- null_length,
null_lookup,
null_afunc,
null_afunc,
@@ -53,23 +53,20 @@ static afunc_t null_array_func[] = {
#define MAX_ATYPE 10
-static afunc_t *array_types[MAX_ATYPE];
+static const array_funcs_t *array_types[MAX_ATYPE];
static int num_array_types = 0;
-/* array func to index mapping */
-#define AFUNC(F) (F ## _ind)
-
/* register_array_func --- add routines to handle arrays */
-int
-register_array_func(afunc_t *afunc)
+static int
+register_array_func(const array_funcs_t *afunc)
{
if (afunc && num_array_types < MAX_ATYPE) {
- if (afunc != str_array_func && ! afunc[AFUNC(atypeof)])
+ if (afunc != & str_array_func && afunc->type_of == NULL)
return false;
array_types[num_array_types++] = afunc;
- if (afunc[AFUNC(ainit)]) /* execute init routine if any */
- (void) (*afunc[AFUNC(ainit)])(NULL, NULL);
+ if (afunc->init) /* execute init routine if any */
+ (void) (*afunc->init)(NULL, NULL);
return true;
}
return false;
@@ -81,10 +78,10 @@ register_array_func(afunc_t *afunc)
void
array_init()
{
- (void) register_array_func(str_array_func); /* the default */
+ (void) register_array_func(& str_array_func); /* the default */
if (! do_mpfr) {
- (void) register_array_func(int_array_func);
- (void) register_array_func(cint_array_func);
+ (void) register_array_func(& int_array_func);
+ (void) register_array_func(& cint_array_func);
}
}
@@ -98,7 +95,7 @@ make_array()
getnode(array);
memset(array, '\0', sizeof(NODE));
array->type = Node_var_array;
- array->array_funcs = null_array_func;
+ array->array_funcs = & null_array_func;
/* vname, flags, and parent_array not set here */
return array;
@@ -111,7 +108,7 @@ void
null_array(NODE *symbol)
{
symbol->type = Node_var_array;
- symbol->array_funcs = null_array_func;
+ symbol->array_funcs = & null_array_func;
symbol->buckets = NULL;
symbol->table_size = symbol->array_size = 0;
symbol->array_capacity = 0;
@@ -129,7 +126,7 @@ static NODE **
null_lookup(NODE *symbol, NODE *subs)
{
int i;
- afunc_t *afunc = NULL;
+ const array_funcs_t *afunc = NULL;
assert(symbol->table_size == 0);
@@ -139,7 +136,7 @@ null_lookup(NODE *symbol, NODE *subs)
*/
for (i = num_array_types - 1; i >= 1; i--) {
afunc = array_types[i];
- if (afunc[AFUNC(atypeof)](symbol, subs) != NULL)
+ if (afunc->type_of(symbol, subs) != NULL)
break;
}
if (i == 0 || afunc == NULL)
@@ -150,15 +147,6 @@ null_lookup(NODE *symbol, NODE *subs)
return symbol->alookup(symbol, subs);
}
-/* null_length --- default function for array length interface */
-
-NODE **
-null_length(NODE *symbol, NODE *subs ATTRIBUTE_UNUSED)
-{
- static NODE *tmp;
- tmp = symbol;
- return & tmp;
-}
/* null_afunc --- default function for array interface */
@@ -618,6 +606,9 @@ do_delete(NODE *symbol, int nsubs)
(void) assoc_remove(symbol, subs);
DEREF(subs);
+ if (assoc_empty(symbol))
+ /* last element was removed, so reset array type to null */
+ null_array(symbol);
#undef free_subs
}
@@ -805,7 +796,7 @@ asort_actual(int nargs, sort_context_t ctxt)
{
NODE *array, *dest = NULL, *result;
NODE *r, *subs, *s;
- NODE **list = NULL, **ptr, **lhs;
+ NODE **list = NULL, **ptr;
unsigned long num_elems, i;
const char *sort_str;
char save;
@@ -893,12 +884,7 @@ asort_actual(int nargs, sort_context_t ctxt)
for (i = 1, ptr = list; i <= num_elems; i++, ptr += 2) {
subs = make_number(i);
- lhs = assoc_lookup(result, subs);
- unref(*lhs);
- *lhs = *ptr;
- if (result->astore != NULL)
- (*result->astore)(result, subs);
- unref(subs);
+ assoc_set(result, subs, *ptr);
}
} else {
/* We want the values of the source array. */
@@ -913,11 +899,11 @@ asort_actual(int nargs, sort_context_t ctxt)
/* value node */
r = *ptr++;
- if (r->type == Node_val) {
- lhs = assoc_lookup(result, subs);
- unref(*lhs);
- *lhs = dupnode(r);
- } else {
+ NODE *value;
+
+ if (r->type == Node_val)
+ value = dupnode(r);
+ else {
NODE *arr;
arr = make_array();
subs = force_string(subs);
@@ -926,13 +912,10 @@ asort_actual(int nargs, sort_context_t ctxt)
subs->stptr = NULL;
subs->flags &= ~STRCUR;
arr->parent_array = array; /* actual parent, not the temporary one. */
- lhs = assoc_lookup(result, subs);
- unref(*lhs);
- *lhs = assoc_copy(r, arr);
+
+ value = assoc_copy(r, arr);
}
- if (result->astore != NULL)
- (*result->astore)(result, subs);
- unref(subs);
+ assoc_set(result, subs, value);
}
}
@@ -1305,7 +1288,7 @@ assoc_list(NODE *symbol, const char *sort_str, sort_context_t sort_ctxt)
cmp_func = sort_funcs[qi].comp_func;
assoc_kind = sort_funcs[qi].kind;
- if (symbol->array_funcs != cint_array_func)
+ if (symbol->array_funcs != & cint_array_func)
assoc_kind &= ~(AASC|ADESC);
if (sort_ctxt != SORTED_IN || (assoc_kind & AVALUE) != 0) {
@@ -1326,7 +1309,7 @@ assoc_list(NODE *symbol, const char *sort_str, sort_context_t sort_ctxt)
if (sp == sort_str || *sp != '\0')
fatal(_("`%s' is invalid as a function name"), sort_str);
- f = lookup(sort_str);
+ f = lookup(sort_str, false);
if (f == NULL || f->type != Node_func)
fatal(_("sort comparison function `%s' is not defined"), sort_str);