diff options
-rwxr-xr-x | ChangeLog | 37 | ||||
-rw-r--r-- | array.c | 34 | ||||
-rw-r--r-- | awk.h | 52 | ||||
-rw-r--r-- | cint_array.c | 9 | ||||
-rw-r--r-- | int_array.c | 3 | ||||
-rw-r--r-- | str_array.c | 10 |
6 files changed, 93 insertions, 52 deletions
@@ -1,3 +1,40 @@ +2019-01-07 Andrew J. Schorr <aschorr@telemetry-investments.com> + + Use a struct instead of an array to contain the array methods + for improved code clarity and flexibility. + + * awk.h (array_funcs_t): Define new struct to contain the array + methods. + (NODE): Change type of array_funcs (sub.nodep.l.lp) from `afunc_t *' + to `const array_funcs_t *' (from a pointer to an array of function + methods to a pointer to a struct containing the methods). + (a*_ind): Remove obsolete method array index defines. + (a*): Redefine array methods to use struct members instead of + array elements. + (str_array_func, cint_array_func, int_array_func): Change type + from array of afunc_t to 'const array_funcs_t'. + (register_array_func): Remove global declaration, since this function + is called only inside array.c. + * array.c (null_array_func): Change from array of methods to a struct. + (array_types): Now an array of pointers to array_funcs_t. + (AFUNC): Remove obsolete macro. + (register_array_func): Change scope to static, and change argument + to a pointer to array_funcs_t instead of a pointer to an array of + methods. + (array_init): Modify calls to register_array_func to pass the address + of the new array method structs. + (make_array): Set array_funcs to & null_array_func. + (null_lookup): Modify to use new array method structs. + (assoc_list): Update cint check to use & cint_array_func. + * str_array.c (str_array_func, env_array_func): Change from array of + methods to an array_funcs_t struct. + (env_clear, init_env_array): Set array_funcs to & env_array_func. + * int_array.c (int_array_func): Change from array of methods to an + array_funcs_t struct. + * cint_array.c (cint_array_func): Ditto. + (cint_lookup): When setting xn->array_funcs, must now use &. + (cint_dump): Compare xn->array_funcs to & int_array_func. + 2019-01-06 Andrew J. Schorr <aschorr@telemetry-investments.com> * array.c (do_delete): If the array is now empty, reset it to the @@ -37,7 +37,8 @@ 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_lookup, @@ -52,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; @@ -80,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); } } @@ -97,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; @@ -110,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; @@ -128,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); @@ -138,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) @@ -1298,7 +1296,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) { @@ -320,6 +320,19 @@ struct exp_instruction; typedef int (*Func_print)(FILE *, const char *, ...); typedef struct exp_node **(*afunc_t)(struct exp_node *, struct exp_node *); +typedef struct { + const char *name; + afunc_t init; + afunc_t type_of; /* avoid reserved word typeof */ + afunc_t lookup; + afunc_t exists; + afunc_t clear; + afunc_t remove; + afunc_t list; + afunc_t copy; + afunc_t dump; + afunc_t store; +} array_funcs_t; /* * NOTE - this struct is a rather kludgey -- it is packed to minimize @@ -332,7 +345,7 @@ typedef struct exp_node { struct exp_node *lptr; struct exp_instruction *li; long ll; - afunc_t *lp; + const array_funcs_t *lp; } l; union { struct exp_node *rptr; @@ -540,26 +553,16 @@ typedef struct exp_node { #define xarray sub.nodep.rn #define parent_array sub.nodep.x.extra -#define ainit_ind 0 -#define ainit array_funcs[ainit_ind] -#define atypeof_ind 1 -#define atypeof array_funcs[atypeof_ind] -#define alookup_ind 2 -#define alookup array_funcs[alookup_ind] -#define aexists_ind 3 -#define aexists array_funcs[aexists_ind] -#define aclear_ind 4 -#define aclear array_funcs[aclear_ind] -#define aremove_ind 5 -#define aremove array_funcs[aremove_ind] -#define alist_ind 6 -#define alist array_funcs[alist_ind] -#define acopy_ind 7 -#define acopy array_funcs[acopy_ind] -#define adump_ind 8 -#define adump array_funcs[adump_ind] -#define astore_ind 9 -#define astore array_funcs[astore_ind] +#define ainit array_funcs->init +#define atypeof array_funcs->type_of +#define alookup array_funcs->lookup +#define aexists array_funcs->exists +#define aclear array_funcs->clear +#define aremove array_funcs->remove +#define alist array_funcs->list +#define acopy array_funcs->copy +#define adump array_funcs->dump +#define astore array_funcs->store /* Node_array_ref: */ #define orig_array lnode @@ -1114,9 +1117,9 @@ extern NODE *(*format_val)(const char *, int, NODE *); extern int (*cmp_numbers)(const NODE *, const NODE *); /* built-in array types */ -extern afunc_t str_array_func[]; -extern afunc_t cint_array_func[]; -extern afunc_t int_array_func[]; +extern const array_funcs_t str_array_func; +extern const array_funcs_t cint_array_func; +extern const array_funcs_t int_array_func; /* special node used to indicate success in array routines (not NULL) */ extern NODE *success_node; @@ -1372,7 +1375,6 @@ extern NODE *force_array(NODE *symbol, bool canfatal); extern const char *make_aname(const NODE *symbol); extern const char *array_vname(const NODE *symbol); extern void array_init(void); -extern int register_array_func(afunc_t *afunc); extern NODE **null_afunc(NODE *symbol, NODE *subs); extern void set_SUBSEP(void); extern NODE *concat_exp(int nargs, bool do_subsep); diff --git a/cint_array.c b/cint_array.c index 7db45fd2..497bd792 100644 --- a/cint_array.c +++ b/cint_array.c @@ -59,7 +59,8 @@ static NODE **cint_dump(NODE *symbol, NODE *ndump); static void cint_print(NODE *symbol); #endif -afunc_t cint_array_func[] = { +const array_funcs_t cint_array_func = { + "cint", cint_array_init, is_uinteger, cint_lookup, @@ -255,9 +256,9 @@ xinstall: */ if (is_integer(xn, subs)) - xn->array_funcs = int_array_func; + xn->array_funcs = & int_array_func; else - xn->array_funcs = str_array_func; + xn->array_funcs = & str_array_func; xn->flags |= XARRAY; } return xn->alookup(xn, subs); @@ -525,7 +526,7 @@ cint_dump(NODE *symbol, NODE *ndump) kb += (INT32_BIT * sizeof(NODE *)) / 1024.0; /* symbol->nodes */ kb += (symbol->array_capacity * sizeof(NODE *)) / 1024.0; /* value nodes in Node_array_leaf(s) */ if (xn != NULL) { - if (xn->array_funcs == int_array_func) + if (xn->array_funcs == & int_array_func) kb += int_kilobytes(xn); else kb += str_kilobytes(xn); diff --git a/int_array.c b/int_array.c index 9f705176..475f16fe 100644 --- a/int_array.c +++ b/int_array.c @@ -46,7 +46,8 @@ static inline NODE **int_find(NODE *symbol, long k, uint32_t hash1); static NODE **int_insert(NODE *symbol, long k, uint32_t hash1); static void grow_int_table(NODE *symbol); -afunc_t int_array_func[] = { +const array_funcs_t int_array_func = { + "int", int_array_init, is_integer, int_lookup, diff --git a/str_array.c b/str_array.c index 4972a92b..2fdd1bf2 100644 --- a/str_array.c +++ b/str_array.c @@ -56,7 +56,8 @@ static NODE **str_list(NODE *symbol, NODE *subs); static NODE **str_copy(NODE *symbol, NODE *newsymb); static NODE **str_dump(NODE *symbol, NODE *ndump); -afunc_t str_array_func[] = { +const array_funcs_t str_array_func = { + "str", str_array_init, (afunc_t) 0, str_lookup, @@ -74,7 +75,8 @@ static NODE **env_store(NODE *symbol, NODE *subs); static NODE **env_clear(NODE *symbol, NODE *subs); /* special case for ENVIRON */ -afunc_t env_array_func[] = { +const array_funcs_t env_array_func = { + "env", str_array_init, (afunc_t) 0, str_lookup, @@ -796,7 +798,7 @@ env_clear(NODE *symbol, NODE *subs) environ = NULL; /* ZAP! */ /* str_clear zaps the vtable, reset it */ - symbol->array_funcs = env_array_func; + symbol->array_funcs = & env_array_func; return val; } @@ -829,5 +831,5 @@ init_env_array(NODE *env_node) if (do_posix) return; - env_node->array_funcs = env_array_func; + env_node->array_funcs = & env_array_func; } |