summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew J. Schorr <aschorr@telemetry-investments.com>2019-01-07 09:37:25 -0500
committerAndrew J. Schorr <aschorr@telemetry-investments.com>2019-01-07 09:37:25 -0500
commit683e1c07a179096aa4bd69000c817ca707019456 (patch)
tree6c7a0e2b99da17be63767595c45bf1f29f67b3c0
parentf2fc8da25ca6fe6c089e89d2a612ec3271cf1ed1 (diff)
downloadgawk-683e1c07a179096aa4bd69000c817ca707019456.tar.gz
Use a struct instead of an array to contain the array methods.
-rwxr-xr-xChangeLog37
-rw-r--r--array.c34
-rw-r--r--awk.h52
-rw-r--r--cint_array.c9
-rw-r--r--int_array.c3
-rw-r--r--str_array.c10
6 files changed, 93 insertions, 52 deletions
diff --git a/ChangeLog b/ChangeLog
index 5efa7213..8dd3b4af 100755
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
diff --git a/array.c b/array.c
index a47660c8..f2e64f6b 100644
--- a/array.c
+++ b/array.c
@@ -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) {
diff --git a/awk.h b/awk.h
index cb98491b..aa1fa91b 100644
--- a/awk.h
+++ b/awk.h
@@ -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;
}