diff options
author | Arnold D. Robbins <arnold@skeeve.com> | 2013-01-06 17:36:58 +0200 |
---|---|---|
committer | Arnold D. Robbins <arnold@skeeve.com> | 2013-01-06 17:36:58 +0200 |
commit | 6b4dccf6db4dcaaff9f5a58baeee21329635ec18 (patch) | |
tree | 057f9b6d5c02ad8338c7f5cb71ca6cb295de3fbe /extension/spec_array.c | |
parent | cccfa4aac8863671e7215877f9d582d7c6c63753 (diff) | |
download | egawk-6b4dccf6db4dcaaff9f5a58baeee21329635ec18.tar.gz egawk-6b4dccf6db4dcaaff9f5a58baeee21329635ec18.tar.bz2 egawk-6b4dccf6db4dcaaff9f5a58baeee21329635ec18.zip |
Move old extension stuff into a separate directory.
Diffstat (limited to 'extension/spec_array.c')
-rw-r--r-- | extension/spec_array.c | 416 |
1 files changed, 0 insertions, 416 deletions
diff --git a/extension/spec_array.c b/extension/spec_array.c deleted file mode 100644 index 78b24018..00000000 --- a/extension/spec_array.c +++ /dev/null @@ -1,416 +0,0 @@ -/* - * spec_array.c - Support for specialized associative arrays. - */ - -/* - * Copyright (C) 2012 the Free Software Foundation, Inc. - * - * This file is part of GAWK, the GNU implementation of the - * AWK Programming Language. - * - * GAWK is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * GAWK is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "awk.h" -#include "spec_array.h" - -typedef struct spec_array { - Fetch_func_t fetch_func; - Store_func_t store_func; - Load_func_t load_func; - void *data; -} array_t; - -/* - * The array_t structure is attached to the array itself without - * the necessity to maintain a list of symbols; this works only - * because there is just enough free space in the NODE strcture when - * the base array is str_array. - */ - -#define SUPER(F) (*str_array_func[AFUNC(F)]) - - -/* - * deferred_array --- Deferred loading of array at run-time. - * - * The load routine takes two arguments, the array and - * a void * data: - * - * void load_func(NODE *array, void *data) - * - * Use register_deferred_array(array, load_func, void *data) to - * bind an array to the load routine. - */ - -static NODE **deferred_array_init(NODE *, NODE *); -static NODE **deferred_array_lookup(NODE *, NODE *); -static NODE **deferred_array_exists(NODE *, NODE *); -static NODE **deferred_array_remove(NODE *, NODE *); -static NODE **deferred_array_clear(NODE *, NODE *); -static NODE **deferred_array_list(NODE *, NODE *); -static NODE **deferred_array_copy(NODE *, NODE *); -static NODE **deferred_array_length(NODE *, NODE *); - -static afunc_t deferred_array_func[] = { - deferred_array_init, - (afunc_t) 0, /* typeof */ - deferred_array_length, - deferred_array_lookup, - deferred_array_exists, - deferred_array_clear, - deferred_array_remove, - deferred_array_list, - deferred_array_copy, - null_afunc, /* dump */ - (afunc_t) 0, /* store */ -}; - - -/* deferred_array_init --- called when array becomes empty, e.g: delete BOUND_ARRAY */ - -static NODE ** -deferred_array_init(NODE *symbol, NODE *subs) -{ - if (symbol != NULL) { - array_t *av = (array_t *) symbol->xarray; - symbol->xarray = NULL; /* this is to avoid an assertion failure in null_array */ - null_array(symbol); /* typeless empty array */ - if (symbol->parent_array == NULL) { - /* main array */ - symbol->array_funcs = deferred_array_func; /* restore type */ - symbol->xarray = (NODE *) av; - } else if (av) /* sub-array */ - efree(av); - } - return NULL; -} - -/* deferred_array_length --- get the length of the array */ - -static NODE ** -deferred_array_length(NODE *symbol, NODE *subs) -{ - static NODE *length_node; - array_t *av = (array_t *) symbol->xarray; - if (av) { - symbol->xarray = NULL; - (*av->load_func)(symbol, av->data); - symbol->xarray = (NODE *) av; - } - length_node = symbol; - return & length_node; -} - -#define DEF_ARR(F) static NODE ** \ -deferred_array_##F(NODE *symbol, NODE *subs) \ -{ \ - array_t *av = (array_t *) symbol->xarray; \ - if (av) { \ - symbol->xarray = NULL; \ - (*av->load_func)(symbol, av->data); \ - symbol->xarray = (NODE *) av; \ - } \ - return SUPER(a##F)(symbol, subs); \ -} - -/* the rest of the routines */ - -DEF_ARR(exists) -DEF_ARR(lookup) -DEF_ARR(list) -DEF_ARR(copy) - -#undef DEF_ARR - -/* deferred_array_remove --- remove the index from the array */ - -static NODE ** -deferred_array_remove(NODE *symbol, NODE *subs) -{ - array_t *av = (array_t *) symbol->xarray; - - (void) SUPER(aremove)(symbol, subs); - if (av) { - symbol->xarray = NULL; - (*av->load_func)(symbol, av->data); - symbol->xarray = (NODE *) av; - } - return NULL; -} - -/* deferred_array_clear --- flush all the values in symbol[] */ - -static NODE ** -deferred_array_clear(NODE *symbol, NODE *subs) -{ - array_t *av = (array_t *) symbol->xarray; - - (void) SUPER(aclear)(symbol, subs); - if (av) { - symbol->xarray = NULL; - (*av->load_func)(symbol, av->data); - symbol->xarray = (NODE *) av; - } - return NULL; -} - - -/* - * dyn_array --- array with triggers for reading and writing - * an element. - * - * The fetch routine should expect three arguments, the array, - * the subscript and optional void * data. It should return the value - * if it exists or NULL otherwise. - * - * NODE *fetch_func(NODE *array, NODE *subs, void *data) - * - * The store routine must take an additional argument for the - * value. The value can be NULL if the specific element is - * removed from the array. The subscript (and the value) is NULL - * when the entire array is deleted. - * - * void store_func(NODE *array, NODE *subs, NODE *value, void *data) - * - * Use register_dyn_array(array, fetch_func, store_func, void *data) to - * bind an array to the fetch/store routine. - */ - - -static NODE **dyn_array_init(NODE *, NODE *); -static NODE **dyn_array_lookup(NODE *, NODE *); -static NODE **dyn_array_exists(NODE *, NODE *); -static NODE **dyn_array_remove(NODE *, NODE *); -static NODE **dyn_array_clear(NODE *, NODE *); -static NODE **dyn_array_list(NODE *, NODE *); -static NODE **dyn_array_copy(NODE *, NODE *); -static NODE **dyn_array_store(NODE *, NODE *); - -static afunc_t dyn_array_func[] = { - dyn_array_init, - (afunc_t) 0, /* typeof */ - null_length, /* length */ - dyn_array_lookup, - dyn_array_exists, - dyn_array_clear, - dyn_array_remove, - dyn_array_list, - dyn_array_copy, - null_afunc, /* dump */ - dyn_array_store, -}; - -/* dyn_array_init --- called when array becomes empty */ - -static NODE ** -dyn_array_init(NODE *symbol, NODE *subs) -{ - if (symbol != NULL) { - array_t *av = (array_t *) symbol->xarray; - symbol->xarray = NULL; - null_array(symbol); /* typeless empty array */ - if (symbol->parent_array == NULL) { - /* main array */ - symbol->array_funcs = dyn_array_func; /* restore type */ - symbol->xarray = (NODE *) av; - } else if (av) /* sub-array */ - efree(av); - } - return NULL; -} - -/* dyn_array_exists --- check if the SUBS exists */ - -static NODE ** -dyn_array_exists(NODE *symbol, NODE *subs) -{ - NODE *r; - array_t *av = (array_t *) symbol->xarray; - - if (av && av->fetch_func) { - symbol->xarray = NULL; - r = (*av->fetch_func)(symbol, subs, av->data); - symbol->xarray = (NODE *) av; - if (r != NULL) { - NODE **lhs; - lhs = SUPER(alookup)(symbol, subs); - unref(*lhs); - *lhs = r; - return lhs; - } - } - - return SUPER(aexists)(symbol, subs); -} - -/* dyn_array_lookup --- lookup SUBS and return a pointer to store its value */ - -static NODE ** -dyn_array_lookup(NODE *symbol, NODE *subs) -{ - NODE **lhs; - NODE *r; - array_t *av = (array_t *) symbol->xarray; - - lhs = SUPER(alookup)(symbol, subs); - if (av && av->fetch_func) { - symbol->xarray = NULL; - r = (*av->fetch_func)(symbol, subs, av->data); - symbol->xarray = (NODE *) av; - if (r != NULL) { - unref(*lhs); - *lhs = r; - } - } - return lhs; -} - -/* dyn_array_store --- call the store routine after an assignment */ - -static NODE ** -dyn_array_store(NODE *symbol, NODE *subs) -{ - array_t *av = (array_t *) symbol->xarray; - - if (av && av->store_func) { - NODE **lhs; - lhs = SUPER(aexists)(symbol, subs); - symbol->xarray = NULL; - (*av->store_func)(symbol, subs, *lhs, av->data); - symbol->xarray = (NODE *) av; - } - return NULL; -} - -/* dyn_array_remove --- remove the index from the array */ - -static NODE ** -dyn_array_remove(NODE *symbol, NODE *subs) -{ - array_t *av = (array_t *) symbol->xarray; - - (void) SUPER(aremove)(symbol, subs); - if (av && av->store_func) { - symbol->xarray = NULL; - (*av->store_func)(symbol, subs, NULL, av->data); - symbol->xarray = (NODE *) av; - } - return NULL; -} - -/* dyn_array_clear --- flush all the values in symbol[] */ - -static NODE ** -dyn_array_clear(NODE *symbol, NODE *subs) -{ - array_t *av = (array_t *) symbol->xarray; - - (void) SUPER(aclear)(symbol, subs); - if (av && av->store_func) { - symbol->xarray = NULL; - (*av->store_func)(symbol, NULL, NULL, av->data); - symbol->xarray = (NODE *) av; - } - return NULL; -} - -/* dyn_array_list --- return a list of items in symbol[] */ - -static NODE ** -dyn_array_list(NODE *symbol, NODE *subs) -{ - return SUPER(alist)(symbol, subs); -} - -/* dyn_array_copy --- duplicate the array */ - -static NODE ** -dyn_array_copy(NODE *symbol, NODE *subs) -{ - return SUPER(acopy)(symbol, subs); -} - -/* register_array_s --- attach the specified routine(s) to an array */ - -static void -register_array_s(NODE *symbol, Fetch_func_t fetch_func, - Store_func_t store_func, Load_func_t load_func, void *data) -{ - array_t *av; - - if (symbol->type != Node_var_array) - fatal(_("register_array_s: argument is not an array")); - - if (symbol->array_funcs == deferred_array_func - || symbol->array_funcs == dyn_array_func) - fatal(_("register_array_s: `%s' already is a deferred/dyn array"), - array_vname(symbol)); - - assoc_clear(symbol); - assert(symbol->xarray == NULL); - emalloc(av, array_t *, sizeof (array_t), "register_spec_array"); - av->fetch_func = fetch_func; - av->store_func = store_func; - av->load_func = load_func; - av->data = data; - symbol->xarray = (NODE *) av; -} - -/* register_deferred_array --- make the array to be loaded at run-time */ - -void -register_deferred_array(NODE *symbol, Load_func_t load_func, void *dq) -{ - if (! load_func) - fatal(_("register_deferred_array: null load function")); - register_array_s(symbol, 0, 0, load_func, dq); - symbol->array_funcs = deferred_array_func; -} - -/* register_dyn_array --- attach read and write triggers to an array */ - -void -register_dyn_array(NODE *symbol, Fetch_func_t fetch_func, - Store_func_t store_func, void *dq) -{ - register_array_s(symbol, fetch_func, store_func, 0, dq); - symbol->array_funcs = dyn_array_func; -} - -/* unregister_array_s --- un-special the array */ - -void * -unregister_array_s(NODE *symbol) -{ - void *data = NULL; - if (symbol->type != Node_var_array) - fatal(_("unregister_array_s: argument is not an array")); - - if (symbol->array_funcs == dyn_array_func - || symbol->array_funcs == deferred_array_func - ) { - array_t *av; - - av = (array_t *) symbol->xarray; - assert(av != NULL); - data = av->data; - efree(av); - symbol->array_funcs = str_array_func; - symbol->xarray = NULL; - /* FIXME: do we assoc_clear the array ? */ - } - return data; -} |