summaryrefslogtreecommitdiff
path: root/src/util
diff options
context:
space:
mode:
authorrideout <rideout@17b73243-c579-4c4c-a9d2-2d5706c11dac>2002-04-03 06:28:47 +0000
committerrideout <rideout@17b73243-c579-4c4c-a9d2-2d5706c11dac>2002-04-03 06:28:47 +0000
commitc23ed018c1916d96720e5c2e7c21844dc1958635 (patch)
tree04d13d1df1dacec558ac7669bc55f0546d51e450 /src/util
parentca019314ea14ab5aedfe881f1e91a71eeeb9486b (diff)
[[from Jonathan Thornburg]]
src/util/Table.c src/include/util_Table.h * add new functions (cf my E-mail of 30 Mar 2002) Util_TableClone() Util_TableItClone() * add new functions (cf Erik Schnetter's E-mails of 5 Feb 2002) Util_Table{Set,Get}Generic() Util_Table{Set,Get}GenericArray() * add tests for new functions * fix a memory leak in Util_TableDestroy() * fixed some assert( variable = value ) bugs (yikes!!) * refactor some code to better modularize the implementation * add some more const qualifiers to local vars * reformat code to match flesh standard indentation and { } conventions git-svn-id: http://svn.cactuscode.org/flesh/trunk@2683 17b73243-c579-4c4c-a9d2-2d5706c11dac
Diffstat (limited to 'src/util')
-rw-r--r--src/util/Table.c4225
1 files changed, 2527 insertions, 1698 deletions
diff --git a/src/util/Table.c b/src/util/Table.c
index 2993547b..a4d8c3ef 100644
--- a/src/util/Table.c
+++ b/src/util/Table.c
@@ -25,6 +25,7 @@
* Prototypes for Functions Private to This File
* Main Table API
* Util_TableCreate
+ * Util_TableClone
* Util_TableDestroy
* Util_TableQueryFlags
* Util_TableQueryNKeys
@@ -35,12 +36,17 @@
* Util_TableSetFromString
* Util_TableSetString
* Util_TableGetString
+ * Util_TableSetGeneric
+ * Util_TableSetGenericArray
+ * Util_TableGetGeneric
+ * Util_TableGetGenericArray
* Util_TableSet*
* Util_TableSet*Array
* Util_TableGet*
* Util_TableGet*Array
* Table Iterator API
* Util_TableItCreate
+ * Util_TableItClone
* Util_TableItDestroy
* Util_TableItQueryIsNull
* Util_TableItQueryIsNonNull
@@ -54,10 +60,11 @@
* internal_set
* internal_get
* get_table_header_ptr
- * delete_key
- * free_table_entry
- * bad_key
+ * is_bad_key
* find_table_entry
+ * insert_table_entry
+ * delete_table_entry_by_key
+ * delete_table_entry_by_ptr
* get_iterator_ptr
* grow_pointer_array
#ifdef UTIL_TABLE_TEST
@@ -66,21 +73,22 @@
* print_table
* print_all_iterators
* Standalone Test Driver
- * // low-level routines
- * CHECK_SET_GET_{INT,REAL,COMPLEX}
- * CHECK_SET_GET_{INT,REAL,COMPLEX}_ARRAY
- * check_table_contents(int handle)
- * // higher-level routines
+ * CHECK_SET_GET_{INT,GENERIC_INT,REAL,COMPLEX}
+ * CHECK_SET_GET_{INT,REAL,GENERIC_REAL,COMPLEX}_ARRAY
* main
* test_nonexistent_tables
* test_table_create_destroy
* test_set_get
* test_set_get_array
* test_iterators
- * test_delete_key
+ * test_delete_table_entry
* test_set_create_from_string
* test_set_get_string
- * test_table_contents
+ * test_clone
+ * check_table_contents
+ * check_table_contents_ij
+ * check_table_contents_real1
+ * check_table_contents_real_e
#endif
*/
@@ -93,7 +101,7 @@
typedef enum { false = 0, true = 1 } bool;
#ifndef CCODE
- #define CCODE /* signal Cactus header files that we're C, not Fortran */
+ #define CCODE /* signal Cactus header files that we're C, not Fortran */
#endif
#include "cctk_Types.h"
@@ -136,7 +144,7 @@ typedef enum { false = 0, true = 1 } bool;
* iterators. In both cases we use the same data structure:
*
* int N_objects; // actual number of tables/iterators
- * int N_array; // actual size of growable array
+ * int N_elements; // actual size of growable array
* void *array; // pointer to malloc-allocated growable array
* // indexed by handle/ihandle
*
@@ -177,21 +185,21 @@ typedef enum { false = 0, true = 1 } bool;
* this shouldn't be a problem.
*/
-struct table_entry
- {
- struct table_entry *next;
- char *key;
- int type_code;
- int N_elements;
- void *value;
- };
-
-struct table_header
- {
- struct table_entry *head;
- int flags;
- int handle;
- };
+struct table_entry
+{
+ struct table_entry *next;
+ char *key;
+ int type_code;
+ int N_elements;
+ void *value;
+};
+
+struct table_header
+{
+ struct table_entry *head;
+ int flags;
+ int handle;
+};
/*
* We keep track of all tables with the following variables
@@ -222,12 +230,12 @@ void **thp_array = NULL;
* Note that we never modify the table through an iterator,
* so all the pointers here are to const objects
*/
-struct iterator
- {
- const struct table_header *thp; /* must always be non-NULL */
- const struct table_entry *tep; /* NULL for iterator in */
- /* "null-pointer" state */
- };
+struct iterator
+{
+ const struct table_header *thp; /* must always be non-NULL */
+ const struct table_entry *tep; /* NULL for iterator in */
+ /* "null-pointer" state */
+};
/*
* We keep track of all iterators with the following variables
@@ -252,10 +260,7 @@ void **ip_array = NULL;
/***** Misc Macros for This File **********************************************/
/******************************************************************************/
-#define then /* empty */
-
#define min(x,y) ((x < y) ? (x) : (y))
-#define max(x,y) ((x > y) ? (x) : (y))
/******************************************************************************/
/***** Prototypes for Functions Private to This File **************************/
@@ -306,31 +311,36 @@ static
struct table_header *get_table_header_ptr(int handle);
/*
- * delete a key from a table
+ * check if key is syntactically "bad" (eg contains '/' character)
+ * returns true for bad key, false for ok
+ */
+static
+ bool is_bad_key(const char *key);
+
+/*
+ * delete an entry (specified by its key) from a table
* return same as Util_TableDeleteKey(), i.e.
* 0 for ok (key existed before this call, and has now been deleted)
* -ve for error, including
* UTIL_ERROR_TABLE_NO_SUCH_KEY no such key in table
*/
static
- int delete_key(struct table_header *thp, const char *key);
-
-/* free table entry and key/value it points to */
-static
- void free_table_entry(struct table_entry *tep);
+ int delete_table_entry_by_key(struct table_header *thp, const char *key);
/*
- * check if key is syntactically "bad" (eg contains '/' character)
- * returns true for bad key, false for ok
+ * delete an entry from a table,
+ * specifying the entry by a pointer to the entry *before* it,
+ * or NULL to delete the starting entry in the list
*/
static
- bool bad_key(const char *key);
+ void delete_table_entry_by_ptr(struct table_header *thp,
+ struct table_entry *prev_tep);
/*
* find table entry for a given key
* return pointer to it, or NULL if no such key is present in table
* if prev_tep_ptr != NULL,
- * then also set *prev_tep_ptr to point to table entry one *before*
+ * also set *prev_tep_ptr to point to table entry one *before*
* the one with the given key, or to NULL if the given key is
* the starting entry in the table
*/
@@ -339,6 +349,12 @@ static
(const struct table_header *thp, const char *key,
struct table_entry **prev_tep_ptr);
+/* allocate a new table entry, set its fields to copies of arguments */
+static
+ int insert_table_entry(struct table_header *thp,
+ const char *key,
+ int type_code, int N_elements, const void *value);
+
/* check iterator handle for validity, return pointer to iterator */
static
struct iterator *get_iterator_ptr(int ihandle);
@@ -378,9 +394,14 @@ static void test_table_create_destroy(void);
static void test_set_get(int handle, bool case_insensitive);
static void test_set_get_array(int handle);
static void test_iterators(int handle);
-static void test_delete_key(int handle, bool case_insensitive);
+static void test_delete_table_entry(int handle, bool case_insensitive);
static int test_set_create_from_string(void);
static void test_set_get_string(int handle, bool case_insensitive);
+static void test_clone(int handle);
+static void check_table_contents(int handle, bool order_up_flag);
+static void check_table_contents_ij(int handle, int ihandle);
+static void check_table_contents_real1(int handle, int ihandle);
+static void check_table_contents_real_e(int handle, int ihandle);
#endif
/******************************************************************************/
@@ -412,71 +433,143 @@ static void test_set_get_string(int handle, bool case_insensitive);
@@*/
int Util_TableCreate(int flags)
{
-#ifdef UTIL_TABLE_DEBUG
-printf("Util_TableCreate()\n");
-#endif
+ #ifdef UTIL_TABLE_DEBUG
+ printf("Util_TableCreate()\n");
+ #endif
-if (flags < 0)
- then return UTIL_ERROR_TABLE_BAD_FLAGS;
+ if (flags < 0)
+ return UTIL_ERROR_TABLE_BAD_FLAGS;
-if (N_tables == N_thp_array)
- then {
- /* grow thp_array to get some room to create the new table */
- #ifdef UTIL_TABLE_DEBUG
- printf(" growing thp_array[] from old size %d\n", N_thp_array);
- #endif
- if (grow_pointer_array(&N_thp_array, &thp_array) < 0)
- then return UTIL_ERROR_NO_MEMORY;
- #ifdef UTIL_TABLE_DEBUG
- printf(" to new size %d\n", N_thp_array);
- #endif
- }
+ if (N_tables == N_thp_array)
+ {
+ /* grow thp_array to get some room to create the new table */
+ #ifdef UTIL_TABLE_DEBUG
+ printf(" growing thp_array[] from old size %d\n", N_thp_array);
+ #endif
+ if (grow_pointer_array(&N_thp_array, &thp_array) < 0)
+ {
+ return UTIL_ERROR_NO_MEMORY;
+ }
+ #ifdef UTIL_TABLE_DEBUG
+ printf(" to new size %d\n", N_thp_array);
+ #endif
+ }
-/* we should now have space to create the new table */
-assert(N_tables < N_thp_array);
+ /* we should now have space to create the new table */
+ assert(N_tables < N_thp_array);
+
+ /* find an unused handle */
+ #ifdef UTIL_TABLE_DEBUG
+ printf(" searching for an unused handle (N_tables=%d N_thp_array=%d)\n",
+ N_tables, N_thp_array);
+ #endif
+ {
+ int handle;
+ for (handle = 0 ; handle < N_thp_array ; ++handle)
+ {
+ #ifdef UTIL_TABLE_DEBUG2
+ printf(" checking handle=%d\n", handle);
+ #endif
+ if (thp_array[handle] == NULL)
+ {
+ /* we've found an unused handle ==> create the table */
+ struct table_header *const thp = (struct table_header *)
+ malloc(sizeof(struct table_header));
+ if (thp == NULL)
+ {
+ return UTIL_ERROR_NO_MEMORY;
+ }
+
+ #ifdef UTIL_TABLE_DEBUG
+ printf(" using handle=%d\n", handle);
+ #endif
+
+ thp->head = NULL;
+ thp->flags = flags;
+ thp->handle = handle;
+
+ ++N_tables;
+ thp_array[handle] = (void *) thp;
+
+ return handle;
+ }
+ }
-/* find an unused handle */
-#ifdef UTIL_TABLE_DEBUG
-printf(" searching for an unused handle (N_tables=%d N_thp_array=%d)\n",
- N_tables, N_thp_array);
-#endif
+ /* we should never get to here! */
+ assert(false);
+ abort(); /* internal error (core dump) */
+ /* prevent compiler warning 'function should return a value' */
+ return(0);
+ }
+}
+
+/******************************************************************************/
+
+/*@@
+ @routine Util_TableClone
+ @desc This function clones (makes an exact copy of) a table.
+ (N.b. the order in which an interator sequences through
+ a table may differ in the clone.)
+
+ @var handle
+ @vtype int
+ @vdesc handle to the table to be cloned
+ @endvar
+
+ @returntype int
+ @returndesc a handle to the clone table, or
+ UTIL_ERROR_NO_MEMORY unable to allocate memory
+ UTIL_ERROR_TABLE_BAD_FLAGS flags < 0 in the to-be-cloned
+ table (this should never happen)
+ @endreturndesc
+ @@*/
+int Util_TableClone(int handle)
+{
+ const struct table_header *const thp = get_table_header_ptr(handle);
+ if (thp == NULL)
{
-int handle;
- for (handle = 0 ; handle < N_thp_array ; ++handle)
- {
- #ifdef UTIL_TABLE_DEBUG2
- printf(" checking handle=%d\n", handle);
- #endif
- if (thp_array[handle] == NULL)
- then {
- /* we've found an unused handle ==> create the table */
- struct table_header *const thp
- = (struct table_header *)
- malloc(sizeof(struct table_header));
- if (thp == NULL)
- then return UTIL_ERROR_NO_MEMORY;
-
- #ifdef UTIL_TABLE_DEBUG
- printf(" using handle=%d\n", handle);
- #endif
-
- thp->head = NULL;
- thp->flags = flags;
- thp->handle = handle;
-
- ++N_tables;
- thp_array[handle] = (void *) thp;
-
- return handle;
- }
- }
+ return UTIL_ERROR_BAD_HANDLE;
+ }
+
+ {
+ const int clone_handle = Util_TableCreate(thp->flags);
+ if (clone_handle < 0)
+ {
+ return clone_handle; /* error creating clone table */
+ }
+
+ #ifdef UTIL_TABLE_DEBUG
+ printf("Util_TableClone(handle=%d) ==> clone_handle=%d\n",
+ handle, clone_handle);
+ #endif
-/* we should never get to here! */
-assert(false);
-abort(); /* internal error (core dump) */
-/* prevent compiler warning 'function should return a value' */
-return(0);
+ /* copy all the table entries */
+ {
+ struct table_header *const clone_thp = get_table_header_ptr(clone_handle);
+ const struct table_entry *tep;
+ for (tep = thp->head ; tep != NULL ; tep = tep->next)
+ {
+ #ifdef UTIL_TABLE_DEBUG2
+ printf(" copying key \"%s\"\n", tep->key);
+ #endif
+ {
+ /* insert_table_entry() does the actual copying */
+ int status
+ = insert_table_entry(clone_thp,
+ tep->key,
+ tep->type_code, tep->N_elements, tep->value);
+ if (status < 0)
+ {
+ /* this should cleanup as much as we've done so far */
+ Util_TableDestroy(clone_handle);
+ return status; /* error inserting table entry into clone table */
+ }
+ }
}
+
+ return clone_handle;
+ }
+ }
}
/******************************************************************************/
@@ -500,32 +593,27 @@ return(0);
@@*/
int Util_TableDestroy(int handle)
{
-struct table_header *const thp = get_table_header_ptr(handle);
-if (thp == NULL)
- then return UTIL_ERROR_BAD_HANDLE;
+ struct table_header *const thp = get_table_header_ptr(handle);
+ if (thp == NULL)
+ {
+ return UTIL_ERROR_BAD_HANDLE;
+ }
-#ifdef UTIL_TABLE_DEBUG
-printf("Util_TableDestroy(handle=%d)\n", handle);
-#endif
+ #ifdef UTIL_TABLE_DEBUG
+ printf("Util_TableDestroy(handle=%d)\n", handle);
+ #endif
-/* delete all the keys */
+ /* delete all the keys */
+ while (thp->head != NULL)
{
-struct table_entry *tep, *next_tep;
- for (tep = thp->head ; tep != NULL ; tep = next_tep)
- {
- #ifdef UTIL_TABLE_DEBUG2
- printf(" deleting key \"%s\"\n", tep->key);
- #endif
- next_tep = tep->next;
- free_table_entry(tep);
- }
+ delete_table_entry_by_ptr(thp, NULL);
+ }
---N_tables;
-thp_array[handle] = NULL;
-free(thp);
+ --N_tables;
+ thp_array[handle] = NULL;
+ free(thp);
-return 0;
- }
+ return 0;
}
/******************************************************************************/
@@ -547,11 +635,13 @@ return 0;
@@*/
int Util_TableQueryFlags(int handle)
{
-const struct table_header *const thp = get_table_header_ptr(handle);
-if (thp == NULL)
- then return UTIL_ERROR_BAD_HANDLE;
+ const struct table_header *const thp = get_table_header_ptr(handle);
+ if (thp == NULL)
+ {
+ return UTIL_ERROR_BAD_HANDLE;
+ }
-return thp->flags;
+ return thp->flags;
}
/******************************************************************************/
@@ -574,19 +664,22 @@ return thp->flags;
@@*/
int Util_TableQueryNKeys(int handle)
{
-const struct table_header *const thp = get_table_header_ptr(handle);
-if (thp == NULL)
- then return UTIL_ERROR_BAD_HANDLE;
+ const struct table_header *const thp = get_table_header_ptr(handle);
+ if (thp == NULL)
+ {
+ return UTIL_ERROR_BAD_HANDLE;
+ }
+ {
+ int N = 0;
+ const struct table_entry *tep;
+ for (tep = thp->head ; tep != NULL ; tep = tep->next)
{
-int N = 0;
-const struct table_entry *tep;
- for (tep = thp->head ; tep != NULL ; tep = tep->next)
- {
- ++N;
- }
-return N;
+ ++N;
}
+
+ return N;
+ }
}
/******************************************************************************/
@@ -608,21 +701,26 @@ return N;
@@*/
int Util_TableQueryMaxKeyLength(int handle)
{
-const struct table_header *const thp = get_table_header_ptr(handle);
-if (thp == NULL)
- then return UTIL_ERROR_BAD_HANDLE;
+ const struct table_header *const thp = get_table_header_ptr(handle);
+ if (thp == NULL)
+ {
+ return UTIL_ERROR_BAD_HANDLE;
+ }
+ {
+ int max_length = 0;
+ const struct table_entry *tep;
+ for (tep = thp->head ; tep != NULL ; tep = tep->next)
{
-int max_length = 0;
-const struct table_entry *tep;
- for (tep = thp->head ; tep != NULL ; tep = tep->next)
- {
- const int length = strlen(tep->key);
- if (length > max_length)
- then max_length = length;
- }
-return max_length;
+ const int length = strlen(tep->key);
+ if (length > max_length)
+ {
+ max_length = length;
+ }
}
+
+ return max_length;
+ }
}
/******************************************************************************/
@@ -680,23 +778,34 @@ int Util_TableQueryValueInfo(int handle,
CCTK_INT *type_code, CCTK_INT *N_elements,
const char *key)
{
-const struct table_header *const thp = get_table_header_ptr(handle);
-if (thp == NULL)
- then return UTIL_ERROR_BAD_HANDLE;
+ const struct table_header *const thp = get_table_header_ptr(handle);
+ if (thp == NULL)
+ {
+ return UTIL_ERROR_BAD_HANDLE;
+ }
-if (bad_key(key))
- then return UTIL_ERROR_TABLE_BAD_KEY;
+ if (is_bad_key(key))
{
-const struct table_entry *const tep = find_table_entry(thp, key, NULL);
-if (tep == NULL)
- then return 0; /* no such key in table */
+ return UTIL_ERROR_TABLE_BAD_KEY;
+ }
-if (type_code != NULL)
- then *type_code = tep->type_code;
-if (N_elements != NULL)
- then *N_elements = tep->N_elements;
-return 1; /* key is in table */
+ {
+ const struct table_entry *const tep = find_table_entry(thp, key, NULL);
+ if (tep == NULL)
+ {
+ return 0; /* no such key in table */
+ }
+
+ if (type_code != NULL)
+ {
+ *type_code = tep->type_code;
}
+ if (N_elements != NULL)
+ {
+ *N_elements = tep->N_elements;
+ }
+ return 1; /* key is in table */
+ }
}
/******************************************************************************/
@@ -729,14 +838,18 @@ return 1; /* key is in table */
@@*/
int Util_TableDeleteKey(int handle, const char *key)
{
-struct table_header *const thp = get_table_header_ptr(handle);
-if (thp == NULL)
- then return UTIL_ERROR_BAD_HANDLE;
+ struct table_header *const thp = get_table_header_ptr(handle);
+ if (thp == NULL)
+ {
+ return UTIL_ERROR_BAD_HANDLE;
+ }
-if (bad_key(key))
- then return UTIL_ERROR_TABLE_BAD_KEY;
+ if (is_bad_key(key))
+ {
+ return UTIL_ERROR_TABLE_BAD_KEY;
+ }
-return delete_key(thp, key);
+ return delete_table_entry_by_key(thp, key);
}
/******************************************************************************/
@@ -770,17 +883,21 @@ return delete_key(thp, key);
@@*/
int Util_TableCreateFromString(const char string[])
{
-const int handle = Util_TableCreate(UTIL_TABLE_FLAGS_CASE_INSENSITIVE);
-if (handle < 0)
- then return handle; /* error creating table */
-
+ const int handle = Util_TableCreate(UTIL_TABLE_FLAGS_CASE_INSENSITIVE);
+ if (handle < 0)
{
-const int status = Util_TableSetFromString(handle, string);
-if (status < 0)
- then return status; /* error setting values in table */
+ return handle; /* error creating table */
+ }
-return handle;
+ {
+ const int status = Util_TableSetFromString(handle, string);
+ if (status < 0)
+ {
+ return status; /* error setting values in table */
}
+
+ return handle;
+ }
}
/******************************************************************************/
@@ -857,129 +974,133 @@ return handle;
@@*/
int Util_TableSetFromString(int handle, const char string[])
{
-const char *const delimiters = "; \t\n\r\f\v";
-const char *const whitespace = " \t\n\r\f\v";
-const char *const int_chars = "-+0123456789";
-
-#ifdef UTIL_TABLE_DEBUG
-printf("Util_TableSetFromString(handle=%d, \"%s\")\n", handle, string);
-#endif
-
-/* make a copy of the string so we can write null characters into it */
-/* to partition it into substrings */
+ const char *const delimiters = "; \t\n\r\f\v";
+ const char *const whitespace = " \t\n\r\f\v";
+ const char *const int_chars = "-+0123456789";
+
+ #ifdef UTIL_TABLE_DEBUG
+ printf("Util_TableSetFromString(handle=%d, \"%s\")\n", handle, string);
+ #endif
+
+ /* make a copy of the string so we can write null characters into it */
+ /* to partition it into substrings */
+ {
+ char *const buffer = Util_Strdup(string);
+ if (buffer == NULL)
{
-char *const buffer = Util_Strdup(string);
-if (buffer == NULL)
- then return UTIL_ERROR_NO_MEMORY;
+ return UTIL_ERROR_NO_MEMORY;
+ }
+ {
+ int Set_count = 0;
+ char *p = buffer;
+ while (*p != '\0')
{
-int Set_count = 0;
-char *p = buffer;
- while (*p != '\0')
+ /*
+ * each pass through this loop processes a single key=value
+ * assignment starting at p, creating a table entry for it
+ */
+
+ /* skip over any leading whitespace */
+ const size_t N_white = strspn(p, whitespace);
+ p += N_white;
+ #ifdef UTIL_TABLE_DEBUG2
+ printf(" skipped over delimiters to p-buffer=%d\n", (int) (p-buffer));
+ #endif
+ if (*p == '\0')
+ {
+ break; /* end of string -- nothing more to do */
+ }
+
+ {
+ const char *const key = p; /* key -> "key=value..." */
+ char *q = strchr(p, '=');
+ if (q == NULL)
+ {
+ free(buffer);
+ return UTIL_ERROR_BAD_INPUT; /* no '=" in "key=value" string */
+ }
+ *q++ = '\0'; /* key -> "key", q -> "value..." */
+ if (strcspn(key, delimiters) != strlen(key))
+ {
+ free(buffer);
+ return UTIL_ERROR_TABLE_BAD_KEY; /* key contains invalid character */
+ }
+ {
+ char *const value = q; /* value -> "value..." */
+ const size_t value_length = strcspn(value, delimiters);
+ q = value + value_length; /* q -> delimiter */
+ if (*q != '\0') /* if we're already at the end of the */
+ /* buffer, we don't want to advance further */
+ {
+ *q++ = '\0'; /* value -> "value", q -> "..." */
+ }
+ #ifdef UTIL_TABLE_DEBUG
+ printf(" at p-buffer=%d, got key=\"%s\" value=\"%s\"\n",
+ (int) (p-buffer), key, value);
+ #endif
+
+ if (strspn(value, int_chars) == value_length)
+ {
+ /* value is made up solely of chars which can appear */
+ /* in an integer ==> assume value is an integer */
+ int value_int;
+ if (sscanf(value, "%d", &value_int) != 1)
+ {
+ free(buffer);
+ return UTIL_ERROR_BAD_INPUT; /* can't parse integer value */
+ }
+ #ifdef UTIL_TABLE_DEBUG2
+ printf(" ==> storing key=\"%s\", value_int=%d\n",
+ key, value_int);
+ #endif
{
- /*
- * each pass through this loop processes a single key=value
- * assignment starting at p, creating a table entry for it
- */
-
- /* skip over any leading whitespace */
- const size_t N_white = strspn(p, whitespace);
- p += N_white;
- #ifdef UTIL_TABLE_DEBUG2
- printf(" skipped over delimiters to p-buffer=%d\n", (int) (p-buffer));
- #endif
- if (*p == '\0')
- then break; /* end of string -- nothing more to do */
-
- {
- const char *const key = p; /* key -> "key=value..." */
- char *q = strchr(p, '=');
- if (q == NULL)
- then {
- free(buffer);
- return UTIL_ERROR_BAD_INPUT; /* no '=" in "key=value" string */
- }
- *q++ = '\0'; /* key -> "key", q -> "value..." */
- if (strcspn(key, delimiters) != strlen(key))
- then {
- free(buffer);
- return UTIL_ERROR_TABLE_BAD_KEY; /* key contains */
- /* invalid character */
- }
- {
- char *const value = q; /* value -> "value..." */
- const size_t value_length = strcspn(value, delimiters);
- q = value + value_length; /* q -> delimiter */
- if (*q != '\0') /* if we're already at the end of the */
- /* buffer, we don't want to advance further */
- then *q++ = '\0'; /* value -> "value", q -> "..." */
- #ifdef UTIL_TABLE_DEBUG
- printf(" at p-buffer=%d, got key=\"%s\" value=\"%s\"\n",
- (int) (p-buffer), key, value);
- #endif
-
- if (strspn(value, int_chars) == value_length)
- then {
- /* value is made up solely of chars which can appear */
- /* in an integer ==> assume value is an integer */
- int value_int;
- if (sscanf(value, "%d", &value_int) != 1)
- then {
- free(buffer);
- return UTIL_ERROR_BAD_INPUT;
- /* can't parse integer value */
- }
- #ifdef UTIL_TABLE_DEBUG2
- printf(" ==> storing key=\"%s\", value_int=%d\n",
- key, value_int);
- #endif
- {
- const int status = Util_TableSetInt(handle, value_int, key);
- if (status < 0)
- then {
- free(buffer);
- return status; /* error setting key=integer in table */
- }
- }
- }
- else {
- /* value contains at least one character which can't */
- /* appear in an integer ==> assume value is a real */
- double value_double;
- if (sscanf(value, "%lf", &value_double) != 1)
- then {
- free(buffer);
- return UTIL_ERROR_BAD_INPUT;
- /* can't parse real value */
- }
- #ifdef UTIL_TABLE_DEBUG2
- printf(" ==> storing key=\"%s\", value_double=%g\n",
- key, value_double);
- #endif
- {
- const int status = Util_TableSetReal(handle, value_double, key);
- if (status < 0)
- then {
- free(buffer);
- return status; /* error setting key=real in table */
- }
- }
- }
-
- ++Set_count;
- p = q;
- #ifdef UTIL_TABLE_DEBUG2
- printf(" after key=value, advanced p to p-buffer=%d\n",
- (int) (p-buffer));
- #endif
- }
- }
+ const int status = Util_TableSetInt(handle, value_int, key);
+ if (status < 0)
+ {
+ free(buffer);
+ return status; /* error setting key=integer in table */
+ }
}
-
-free(buffer);
-return Set_count;
- }
+ }
+ else
+ {
+ /* value contains at least one character which can't */
+ /* appear in an integer ==> assume value is a real */
+ double value_double;
+ if (sscanf(value, "%lf", &value_double) != 1)
+ {
+ free(buffer);
+ return UTIL_ERROR_BAD_INPUT; /* can't parse real value */
+ }
+ #ifdef UTIL_TABLE_DEBUG2
+ printf(" ==> storing key=\"%s\", value_double=%g\n",
+ key, value_double);
+ #endif
+ {
+ const int status = Util_TableSetReal(handle, value_double, key);
+ if (status < 0)
+ {
+ free(buffer);
+ return status; /* error setting key=real in table */
+ }
+ }
+ }
+
+ ++Set_count;
+ p = q;
+ #ifdef UTIL_TABLE_DEBUG2
+ printf(" after key=value, advanced p to p-buffer=%d\n",
+ (int) (p-buffer));
+ #endif
+ }
+ }
}
+
+ free(buffer);
+ return Set_count;
+ }
+ }
}
/******************************************************************************/
@@ -1035,9 +1156,9 @@ int Util_TableSetString(int handle,
const char *string,
const char *key)
{
-return internal_set(handle,
- CCTK_VARIABLE_CHAR, strlen(string), (const void *) string,
- key);
+ return internal_set(handle,
+ CCTK_VARIABLE_CHAR, strlen(string), (const void *) string,
+ key);
}
/******************************************************************************/
@@ -1101,7 +1222,7 @@ return internal_set(handle,
buffer is non-NULL), followed by a null character to
properly terminate the string in the buffer. If any
other error code is returned, the user's value buffer
- (pointed to by buffer if this is non-NULL) is unchanged.
+ (pointed to by buffer if this is non-NULL) is unchanged.
@endcomment
@endreturndesc
@@*/
@@ -1109,30 +1230,287 @@ int Util_TableGetString(int handle,
int buffer_length, char buffer[],
const char *key)
{
-/* actual length of string, not counting terminating null character */
-int string_length = internal_get(handle,
- CCTK_VARIABLE_CHAR,
- buffer_length-1, (void *) buffer,
- key);
-if (string_length < 0)
- then return string_length; /* error return from internal_get() */
-
-/* explicitly add the terminating null character */
-if (buffer != NULL)
- then {
- assert(buffer_length >= 1); /* this should never fail: */
- /* internal_get() should return */
- /* an error if buffer != NULL */
- /* and buffer_length-1 < 0 */
- {
- int null_posn = min(string_length, buffer_length-1);
- buffer[null_posn] = '\0';
- }
- }
+ /* string_length = actual length of string, not counting terminating '\0' */
+ const int string_length = internal_get(handle,
+ CCTK_VARIABLE_CHAR,
+ buffer_length-1, (void *) buffer,
+ key);
+ if (string_length < 0)
+ {
+ return string_length; /* error return from internal_get() */
+ }
-return ((buffer != NULL) && (string_length > buffer_length-1))
- ? UTIL_ERROR_TABLE_STRING_TRUNCATED
- : string_length;
+ /* explicitly add the terminating null character */
+ if (buffer != NULL)
+ {
+ assert(buffer_length >= 1); /* this should never fail: */
+ /* internal_get() should return an error */
+ /* if buffer != NULL and buffer_length <= 0 */
+ {
+ const int null_posn = min(string_length, buffer_length-1);
+ buffer[null_posn] = '\0';
+ }
+ }
+
+ return ((buffer != NULL) && (string_length > buffer_length-1))
+ ? UTIL_ERROR_TABLE_STRING_TRUNCATED
+ : string_length;
+}
+
+/******************************************************************************/
+
+/*@@
+ @routine Util_TableSetGeneric
+ @desc This function sets the value associated with a specified
+ key to be a specified value (treated as a 1-element array),
+ whose datatype is specified by a CCTK_VARIABLE_* type code.
+
+ Note that this invalidates any iterators for this table.
+
+ @var handle
+ @vtype int
+ @vdesc handle to the table
+ @endvar
+
+ @var type_code
+ @vtype int
+ @vdesc one of the CCTK_VARIABLE_* constants from "cctk_Types.h",
+ describing the actual data type of *value_ptr
+ @endvar
+
+ @var value_ptr
+ @vtype const void *
+ @vdesc a pointer to the value to be associated with the specified key
+ @endvar
+
+ @var key
+ @vtype const char *
+ @vdesc pointer to the key (a C-style null-terminated string)
+ @endvar
+
+ @returntype int
+ @returndesc 1 for key was already in table before this call
+ (old value was replaced)
+ (it doesn't matter what the old value's type_code and
+ N_elements were, i.e. these do *not* have to match the
+ new value),
+ 0 for key was not in table before this call,
+ -ve for error, including
+ UTIL_ERROR_BAD_HANDLE handle is invalid
+ UTIL_ERROR_TABLE_BAD_KEY key contains '/' character
+ UTIL_ERROR_NO_MEMORY unable to allocate memory
+ @endreturndesc
+ @@*/
+int Util_TableSetGeneric(int handle,
+ int type_code, const void *value_ptr,
+ const char *key)
+{
+ return Util_TableSetGenericArray(handle, type_code, 1, value_ptr, key);
+}
+
+/******************************************************************************/
+
+/*@@
+ @routine Util_TableSetGenericArray
+ @desc This function sets the value associated with a specified
+ key to be (a copy of) a specified array, whose datatype is
+ specified by a CCTK_VARIABLE_* type code.
+
+ Note that this invalidates any iterators for this table.
+
+ @var handle
+ @vtype int
+ @vdesc handle to the table
+ @endvar
+
+ @var type_code
+ @vtype int
+ @vdesc one of the CCTK_VARIABLE_* constants from "cctk_Types.h",
+ describing the actual data type of array[]
+ @endvar
+
+ @var N_elements
+ @vtype int (must be >= 0)
+ @vdesc number of elements in array[]
+ @endvar
+
+ @var array
+ @vtype const void *
+ @vdesc a pointer to the array (a copy of) which
+ is to be associated with the specified key
+ @endvar
+
+ @var key
+ @vtype const char *
+ @vdesc pointer to the key (a C-style null-terminated string)
+ @endvar
+
+ @returntype int
+ @returndesc 1 for key was already in table before this call
+ (old value was replaced)
+ (it doesn't matter what the old value's type_code and
+ N_elements were, i.e. these do *not* have to match the
+ new value),
+ 0 for key was not in table before this call,
+ -ve for error, including
+ UTIL_ERROR_BAD_HANDLE handle is invalid
+ UTIL_ERROR_TABLE_BAD_KEY key contains '/' character
+ UTIL_ERROR_BAD_INPUT N_elements < 0
+ UTIL_ERROR_NO_MEMORY unable to allocate memory
+ @endreturndesc
+ @@*/
+int Util_TableSetGenericArray(int handle,
+ int type_code, int N_elements, const void *array,
+ const char *key)
+{
+ return internal_set(handle,
+ type_code, N_elements, array,
+ key);
+}
+
+/******************************************************************************/
+
+/*@@
+ @routine Util_TableGetGeneric
+ @desc This function gets the value of the scalar (1-element array)
+ value, or more generally the first array element of the value,
+ associated with a specified key. The value may be of any
+ supported datatype; the caller specifies the expected type
+ by a CCTK_VARIABLE_* type code.
+
+ @var handle
+ @vtype int
+ @vdesc handle to the table
+ @endvar
+
+ @var type_code
+ @vtype int
+ @vdesc one of the CCTK_VARIABLE_* constants from "cctk_Types.h",
+ describing the expected data type of the table entry.
+ @endvar
+
+ @var value_ptr
+ @vtype void *
+ @vdesc pointer to where this function should store
+ a copy of the value associated with the specified key,
+ or NULL pointer to skip storing this
+ @endvar
+
+ @var key
+ @vtype const char *
+ @vdesc pointer to the key (a C-style null-terminated string)
+ @endvar
+
+ @returntype int
+ @returndesc the number of elements in the value,
+ -ve for error, including
+ UTIL_ERROR_BAD_HANDLE handle is invalid
+ UTIL_ERROR_TABLE_BAD_KEY key contains '/' character
+ UTIL_ERROR_TABLE_NO_SUCH_KEY no such key in table
+ UTIL_ERROR_TABLE_WRONG_DATA_TYPE value has wrong data type
+ UTIL_ERROR_TABLE_VALUE_IS_EMPTY value is an empty
+ (0-element) array
+ @comment Note that it is *not* an error for the value to actually
+ be an array with > 1 elements elements; in this case only
+ the first element is stored.
+
+ The rationale for this design is that the caller may
+ know or suspect that the value is a large array, but
+ may only want the first array element; in this case
+ this design avoids the caller having to allocate a
+ large buffer unnecessarily.
+
+ In contrast, it *is* an error for the value to actually
+ be an empty (0-length) array, because then there is no
+ ``first array element'' to get.
+ @endcomment
+ @endreturndesc
+ @@*/
+int Util_TableGetGeneric(int handle,
+ int type_code, void *value_ptr,
+ const char *key)
+{
+ const int status
+ = Util_TableGetGenericArray(handle, type_code, 1, value_ptr, key);
+ return (status == 0)
+ ? UTIL_ERROR_TABLE_VALUE_IS_EMPTY
+ : status;
+}
+
+/******************************************************************************/
+
+/*@@
+ @routine Util_TableGetGenericArray
+ @desc This is a family of functions, one for each Cactus data type,
+ to get a copy of the value associated with a specified key
+ (or at least as much of the value as will fit into the
+ caller's array).
+
+ @var handle
+ @vtype int
+ @vdesc handle to the table
+ @endvar
+
+ @var type_code
+ @vtype int
+ @vdesc one of the CCTK_VARIABLE_* constants from "cctk_Types.h",
+ describing the expected data type of the table entry.
+ @endvar
+
+ @var N_elements
+ @vtype int (must be >= 0)
+ @vdesc number of elements in array[]
+ @endvar
+
+ @var array
+ @vtype void *
+ @vdesc a pointer to an array into which this function should store
+ (at most N_elements elements of) a copy of the value
+ associated with the specified key,
+ or NULL pointer to skip storing this
+ @endvar
+
+ @var key
+ @vtype const char *
+ @vdesc pointer to the key (a C-style null-terminated string)
+ @endvar
+
+ @returntype int
+ @returndesc the number of elements in the value,
+ -ve for error, including
+ UTIL_ERROR_BAD_HANDLE handle is invalid
+ UTIL_ERROR_TABLE_BAD_KEY key contains '/' character
+ UTIL_ERROR_BAD_INPUT array != NULL and N_elements < 0
+ UTIL_ERROR_TABLE_NO_SUCH_KEY no such key in table
+ UTIL_ERROR_TABLE_WRONG_DATA_TYPE value has wrong data type
+ @comment Note that it is *not* an error for the value to have
+ > N_elements elements; in this case only N_elements are
+ stored. The caller can detect this by comparing the
+ return value with N_elements.
+
+ The rationale for this design is that the caller may
+ know or suspect that the value is a large array, but
+ may only want the first few array elements; in this
+ case this design avoids the caller having to allocate
+ a large buffer unnecessarily.
+
+ It is also *not* an error for the value to have < N_elements
+ elements; again the caller can detect this by comparing the
+ return value with N_elements.
+
+ Note also that if any error code is returned, the
+ caller's value buffer (pointed to by value_buffer)
+ is unchanged.
+ @endcomment
+ @endreturndesc
+ @@*/
+int Util_TableGetGenericArray(int handle,
+ int type_code, int N_elements, void *array,
+ const char *key)
+{
+ return internal_get(handle,
+ type_code, N_elements, array,
+ key);
}
/******************************************************************************/
@@ -1188,12 +1566,12 @@ return ((buffer != NULL) && (string_length > buffer_length-1))
int Util_TableSetPointer(int handle, CCTK_POINTER value, const char *key)
{
-return Util_TableSetPointerArray(handle, 1, &value, key);
+ return Util_TableSetPointerArray(handle, 1, &value, key);
}
int Util_TableSetFnPointer(int handle, CCTK_FN_POINTER value, const char *key)
{
-return Util_TableSetFnPointerArray(handle, 1, &value, key);
+ return Util_TableSetFnPointerArray(handle, 1, &value, key);
}
/**************************************/
@@ -1204,7 +1582,7 @@ return Util_TableSetFnPointerArray(handle, 1, &value, key);
int Util_TableSetChar(int handle, CCTK_CHAR value, const char *key)
{
-return Util_TableSetCharArray(handle, 1, &value, key);
+ return Util_TableSetCharArray(handle, 1, &value, key);
}
/**************************************/
@@ -1215,27 +1593,27 @@ return Util_TableSetCharArray(handle, 1, &value, key);
int Util_TableSetInt(int handle, CCTK_INT value, const char *key)
{
-return Util_TableSetIntArray(handle, 1, &value, key);
+ return Util_TableSetIntArray(handle, 1, &value, key);
}
#ifdef CCTK_INTEGER_PRECISION_2
int Util_TableSetInt2(int handle, CCTK_INT2 value, const char *key)
{
-return Util_TableSetInt2Array(handle, 1, &value, key);
+ return Util_TableSetInt2Array(handle, 1, &value, key);
}
#endif
#ifdef CCTK_INTEGER_PRECISION_4
int Util_TableSetInt4(int handle, CCTK_INT4 value, const char *key)
{
-return Util_TableSetInt4Array(handle, 1, &value, key);
+ return Util_TableSetInt4Array(handle, 1, &value, key);
}
#endif
#ifdef CCTK_INTEGER_PRECISION_8
int Util_TableSetInt8(int handle, CCTK_INT8 value, const char *key)
{
-return Util_TableSetInt8Array(handle, 1, &value, key);
+ return Util_TableSetInt8Array(handle, 1, &value, key);
}
#endif
@@ -1247,27 +1625,27 @@ return Util_TableSetInt8Array(handle, 1, &value, key);
int Util_TableSetReal(int handle, CCTK_REAL value, const char *key)
{
-return Util_TableSetRealArray(handle, 1, &value, key);
+ return Util_TableSetRealArray(handle, 1, &value, key);
}
#ifdef CCTK_REAL_PRECISION_4
int Util_TableSetReal4(int handle, CCTK_REAL4 value, const char *key)
{
-return Util_TableSetReal4Array(handle, 1, &value, key);
+ return Util_TableSetReal4Array(handle, 1, &value, key);
}
#endif
#ifdef CCTK_REAL_PRECISION_8
int Util_TableSetReal8(int handle, CCTK_REAL8 value, const char *key)
{
-return Util_TableSetReal8Array(handle, 1, &value, key);
+ return Util_TableSetReal8Array(handle, 1, &value, key);
}
#endif
#ifdef CCTK_REAL_PRECISION_16
int Util_TableSetReal16(int handle, CCTK_REAL16 value, const char *key)
{
-return Util_TableSetReal16Array(handle, 1, &value, key);
+ return Util_TableSetReal16Array(handle, 1, &value, key);
}
#endif
@@ -1279,27 +1657,27 @@ return Util_TableSetReal16Array(handle, 1, &value, key);
int Util_TableSetComplex(int handle, CCTK_COMPLEX value, const char *key)
{
-return Util_TableSetComplexArray(handle, 1, &value, key);
+ return Util_TableSetComplexArray(handle, 1, &value, key);
}
#ifdef CCTK_COMPLEX_PRECISION_8
int Util_TableSetComplex8(int handle, CCTK_COMPLEX8 value, const char *key)
{
-return Util_TableSetComplex8Array(handle, 1, &value, key);
+ return Util_TableSetComplex8Array(handle, 1, &value, key);
}
#endif
#ifdef CCTK_COMPLEX_PRECISION_16
int Util_TableSetComplex16(int handle, CCTK_COMPLEX16 value, const char *key)
{
-return Util_TableSetComplex16Array(handle, 1, &value, key);
+ return Util_TableSetComplex16Array(handle, 1, &value, key);
}
#endif
#ifdef CCTK_COMPLEX_PRECISION_32
int Util_TableSetComplex32(int handle, CCTK_COMPLEX32 value, const char *key)
{
-return Util_TableSetComplex32Array(handle, 1, &value, key);
+ return Util_TableSetComplex32Array(handle, 1, &value, key);
}
#endif
@@ -1365,18 +1743,19 @@ int Util_TableSetPointerArray(int handle,
int N_elements, const CCTK_POINTER array[],
const char *key)
{
-return internal_set(handle,
- CCTK_VARIABLE_POINTER, N_elements, (const void *) array,
- key);
+ return internal_set(handle,
+ CCTK_VARIABLE_POINTER, N_elements, (const void *) array,
+ key);
}
int Util_TableSetFnPointerArray(int handle,
int N_elements, const CCTK_FN_POINTER array[],
const char *key)
{
-return internal_set(handle,
- CCTK_VARIABLE_FN_POINTER, N_elements, (const void *) array,
- key);
+ return
+ internal_set(handle,
+ CCTK_VARIABLE_FN_POINTER, N_elements, (const void *) array,
+ key);
}
/**************************************/
@@ -1389,9 +1768,9 @@ int Util_TableSetCharArray(int handle,
int N_elements, const CCTK_CHAR array[],
const char *key)
{
-return internal_set(handle,
- CCTK_VARIABLE_CHAR, N_elements, (const void *) array,
- key);
+ return internal_set(handle,
+ CCTK_VARIABLE_CHAR, N_elements, (const void *) array,
+ key);
}
/**************************************/
@@ -1404,9 +1783,9 @@ int Util_TableSetIntArray(int handle,
int N_elements, const CCTK_INT array[],
const char *key)
{
-return internal_set(handle,
- CCTK_VARIABLE_INT, N_elements, (const void *) array,
- key);
+ return internal_set(handle,
+ CCTK_VARIABLE_INT, N_elements, (const void *) array,
+ key);
}
#ifdef CCTK_INTEGER_PRECISION_2
@@ -1414,9 +1793,9 @@ int Util_TableSetInt2Array(int handle,
int N_elements, const CCTK_INT2 array[],
const char *key)
{
-return internal_set(handle,
- CCTK_VARIABLE_INT2, N_elements, (const void *) array,
- key);
+ return internal_set(handle,
+ CCTK_VARIABLE_INT2, N_elements, (const void *) array,
+ key);
}
#endif
@@ -1425,9 +1804,9 @@ int Util_TableSetInt4Array(int handle,
int N_elements, const CCTK_INT4 array[],
const char *key)
{
-return internal_set(handle,
- CCTK_VARIABLE_INT4, N_elements, (const void *) array,
- key);
+ return internal_set(handle,
+ CCTK_VARIABLE_INT4, N_elements, (const void *) array,
+ key);
}
#endif
@@ -1436,9 +1815,9 @@ int Util_TableSetInt8Array(int handle,
int N_elements, const CCTK_INT8 array[],
const char *key)
{
-return internal_set(handle,
- CCTK_VARIABLE_INT8, N_elements, (const void *) array,
- key);
+ return internal_set(handle,
+ CCTK_VARIABLE_INT8, N_elements, (const void *) array,
+ key);
}
#endif
@@ -1452,10 +1831,10 @@ int Util_TableSetRealArray(int handle,
int N_elements, const CCTK_REAL array[],
const char *key)
{
-return
- internal_set(handle,
- CCTK_VARIABLE_REAL, N_elements, (const void *) array,
- key);
+ return
+ internal_set(handle,
+ CCTK_VARIABLE_REAL, N_elements, (const void *) array,
+ key);
}
#ifdef CCTK_REAL_PRECISION_4
@@ -1463,9 +1842,9 @@ int Util_TableSetReal4Array(int handle,
int N_elements, const CCTK_REAL4 array[],
const char *key)
{
-return internal_set(handle,
- CCTK_VARIABLE_REAL4, N_elements, (const void *) array,
- key);
+ return internal_set(handle,
+ CCTK_VARIABLE_REAL4, N_elements, (const void *) array,
+ key);
}
#endif
@@ -1474,9 +1853,9 @@ int Util_TableSetReal8Array(int handle,
int N_elements, const CCTK_REAL8 array[],
const char *key)
{
-return internal_set(handle,
- CCTK_VARIABLE_REAL8, N_elements, (const void *) array,
- key);
+ return internal_set(handle,
+ CCTK_VARIABLE_REAL8, N_elements, (const void *) array,
+ key);
}
#endif
@@ -1485,9 +1864,9 @@ int Util_TableSetReal16Array(int handle,
int N_elements, const CCTK_REAL16 array[],
const char *key)
{
-return internal_set(handle,
- CCTK_VARIABLE_REAL16, N_elements, (const void *) array,
- key);
+ return internal_set(handle,
+ CCTK_VARIABLE_REAL16, N_elements, (const void *) array,
+ key);
}
#endif
@@ -1501,9 +1880,9 @@ int Util_TableSetComplexArray(int handle,
int N_elements, const CCTK_COMPLEX array[],
const char *key)
{
-return internal_set(handle,
- CCTK_VARIABLE_COMPLEX, N_elements, (const void *) array,
- key);
+ return internal_set(handle,
+ CCTK_VARIABLE_COMPLEX, N_elements, (const void *) array,
+ key);
}
#ifdef CCTK_COMPLEX_PRECISION_8
@@ -1511,9 +1890,9 @@ int Util_TableSetComplex8Array(int handle,
int N_elements, const CCTK_COMPLEX8 array[],
const char *key)
{
-return internal_set(handle,
- CCTK_VARIABLE_COMPLEX8, N_elements, (const void *) array,
- key);
+ return internal_set(handle,
+ CCTK_VARIABLE_COMPLEX8, N_elements, (const void *) array,
+ key);
}
#endif
@@ -1522,9 +1901,9 @@ int Util_TableSetComplex16Array(int handle,
int N_elements, const CCTK_COMPLEX16 array[],
const char *key)
{
-return internal_set(handle,
- CCTK_VARIABLE_COMPLEX16, N_elements, (const void *) array,
- key);
+ return internal_set(handle,
+ CCTK_VARIABLE_COMPLEX16, N_elements, (const void *) array,
+ key);
}
#endif
@@ -1533,9 +1912,9 @@ int Util_TableSetComplex32Array(int handle,
int N_elements, const CCTK_COMPLEX32 array[],
const char *key)
{
-return internal_set(handle,
- CCTK_VARIABLE_COMPLEX32, N_elements, (const void *) array,
- key);
+ return internal_set(handle,
+ CCTK_VARIABLE_COMPLEX32, N_elements, (const void *) array,
+ key);
}
#endif
@@ -1602,18 +1981,18 @@ return internal_set(handle,
/* pointers */
int Util_TableGetPointer(int handle, CCTK_POINTER *value, const char *key)
{
-int status = Util_TableGetPointerArray(handle, 1, value, key);
-return (status == 0)
- ? UTIL_ERROR_TABLE_VALUE_IS_EMPTY
- : status;
+ const int status = Util_TableGetPointerArray(handle, 1, value, key);
+ return (status == 0)
+ ? UTIL_ERROR_TABLE_VALUE_IS_EMPTY
+ : status;
}
int Util_TableGetFnPointer(int handle, CCTK_FN_POINTER *value, const char *key)
{
-int status = Util_TableGetFnPointerArray(handle, 1, value, key);
-return (status == 0)
- ? UTIL_ERROR_TABLE_VALUE_IS_EMPTY
- : status;
+ const int status = Util_TableGetFnPointerArray(handle, 1, value, key);
+ return (status == 0)
+ ? UTIL_ERROR_TABLE_VALUE_IS_EMPTY
+ : status;
}
/**************************************/
@@ -1621,10 +2000,10 @@ return (status == 0)
/* a single character */
int Util_TableGetChar(int handle, CCTK_CHAR *value, const char *key)
{
-int status = Util_TableGetCharArray(handle, 1, value, key);
-return (status == 0)
- ? UTIL_ERROR_TABLE_VALUE_IS_EMPTY
- : status;
+ const int status = Util_TableGetCharArray(handle, 1, value, key);
+ return (status == 0)
+ ? UTIL_ERROR_TABLE_VALUE_IS_EMPTY
+ : status;
}
/**************************************/
@@ -1632,39 +2011,39 @@ return (status == 0)
/* integers */
int Util_TableGetInt(int handle, CCTK_INT *value, const char *key)
{
-int status = Util_TableGetIntArray(handle, 1, value, key);
-return (status == 0)
- ? UTIL_ERROR_TABLE_VALUE_IS_EMPTY
- : status;
+ const int status = Util_TableGetIntArray(handle, 1, value, key);
+ return (status == 0)
+ ? UTIL_ERROR_TABLE_VALUE_IS_EMPTY
+ : status;
}
#ifdef CCTK_INTEGER_PRECISION_2
int Util_TableGetInt2(int handle, CCTK_INT2 *value, const char *key)
{
-int status = Util_TableGetInt2Array(handle, 1, value, key);
-return (status == 0)
- ? UTIL_ERROR_TABLE_VALUE_IS_EMPTY
- : status;
+ const int status = Util_TableGetInt2Array(handle, 1, value, key);
+ return (status == 0)
+ ? UTIL_ERROR_TABLE_VALUE_IS_EMPTY
+ : status;
}
#endif
#ifdef CCTK_INTEGER_PRECISION_4
int Util_TableGetInt4(int handle, CCTK_INT4 *value, const char *key)
{
-int status = Util_TableGetInt4Array(handle, 1, value, key);
-return (status == 0)
- ? UTIL_ERROR_TABLE_VALUE_IS_EMPTY
- : status;
+ const int status = Util_TableGetInt4Array(handle, 1, value, key);
+ return (status == 0)
+ ? UTIL_ERROR_TABLE_VALUE_IS_EMPTY
+ : status;
}
#endif
#ifdef CCTK_INTEGER_PRECISION_8
int Util_TableGetInt8(int handle, CCTK_INT8 *value, const char *key)
{
-int status = Util_TableGetInt8Array(handle, 1, value, key);
-return (status == 0)
- ? UTIL_ERROR_TABLE_VALUE_IS_EMPTY
- : status;
+ const int status = Util_TableGetInt8Array(handle, 1, value, key);
+ return (status == 0)
+ ? UTIL_ERROR_TABLE_VALUE_IS_EMPTY
+ : status;
}
#endif
@@ -1673,39 +2052,39 @@ return (status == 0)
/* real numbers */
int Util_TableGetReal(int handle, CCTK_REAL *value, const char *key)
{
-int status = Util_TableGetRealArray(handle, 1, value, key);
-return (status == 0)
- ? UTIL_ERROR_TABLE_VALUE_IS_EMPTY
- : status;
+ const int status = Util_TableGetRealArray(handle, 1, value, key);
+ return (status == 0)
+ ? UTIL_ERROR_TABLE_VALUE_IS_EMPTY
+ : status;
}
#ifdef CCTK_REAL_PRECISION_4
int Util_TableGetReal4(int handle, CCTK_REAL4 *value, const char *key)
{
-int status = Util_TableGetReal4Array(handle, 1, value, key);
-return (status == 0)
- ? UTIL_ERROR_TABLE_VALUE_IS_EMPTY
- : status;
+ const int status = Util_TableGetReal4Array(handle, 1, value, key);
+ return (status == 0)
+ ? UTIL_ERROR_TABLE_VALUE_IS_EMPTY
+ : status;
}
#endif
#ifdef CCTK_REAL_PRECISION_8
int Util_TableGetReal8(int handle, CCTK_REAL8 *value, const char *key)
{
-int status = Util_TableGetReal8Array(handle, 1, value, key);
-return (status == 0)
- ? UTIL_ERROR_TABLE_VALUE_IS_EMPTY
- : status;
+ const int status = Util_TableGetReal8Array(handle, 1, value, key);
+ return (status == 0)
+ ? UTIL_ERROR_TABLE_VALUE_IS_EMPTY
+ : status;
}
#endif
#ifdef CCTK_REAL_PRECISION_16
int Util_TableGetReal16(int handle, CCTK_REAL16 *value, const char *key)
{
-int status = Util_TableGetReal16Array(handle, 1, value, key);
-return (status == 0)
- ? UTIL_ERROR_TABLE_VALUE_IS_EMPTY
- : status;
+ const int status = Util_TableGetReal16Array(handle, 1, value, key);
+ return (status == 0)
+ ? UTIL_ERROR_TABLE_VALUE_IS_EMPTY
+ : status;
}
#endif
@@ -1714,39 +2093,39 @@ return (status == 0)
/* complex numbers */
int Util_TableGetComplex(int handle, CCTK_COMPLEX *value, const char *key)
{
-int status = Util_TableGetComplexArray(handle, 1, value, key);
-return (status == 0)
- ? UTIL_ERROR_TABLE_VALUE_IS_EMPTY
- : status;
+ const int status = Util_TableGetComplexArray(handle, 1, value, key);
+ return (status == 0)
+ ? UTIL_ERROR_TABLE_VALUE_IS_EMPTY
+ : status;
}
#ifdef CCTK_COMPLEX_PRECISION_8
int Util_TableGetComplex8(int handle, CCTK_COMPLEX8 *value, const char *key)
{
-int status = Util_TableGetComplex8Array(handle, 1, value, key);
-return (status == 0)
- ? UTIL_ERROR_TABLE_VALUE_IS_EMPTY
- : status;
+ const int status = Util_TableGetComplex8Array(handle, 1, value, key);
+ return (status == 0)
+ ? UTIL_ERROR_TABLE_VALUE_IS_EMPTY
+ : status;
}
#endif
#ifdef CCTK_COMPLEX_PRECISION_16
int Util_TableGetComplex16(int handle, CCTK_COMPLEX16 *value, const char *key)
{
-int status = Util_TableGetComplex16Array(handle, 1, value, key);
-return (status == 0)
- ? UTIL_ERROR_TABLE_VALUE_IS_EMPTY
- : status;
+ const int status = Util_TableGetComplex16Array(handle, 1, value, key);
+ return (status == 0)
+ ? UTIL_ERROR_TABLE_VALUE_IS_EMPTY
+ : status;
}
#endif
#ifdef CCTK_COMPLEX_PRECISION_32
int Util_TableGetComplex32(int handle, CCTK_COMPLEX32 *value, const char *key)
{
-int status = Util_TableGetComplex32Array(handle, 1, value, key);
-return (status == 0)
- ? UTIL_ERROR_TABLE_VALUE_IS_EMPTY
- : status;
+ const int status = Util_TableGetComplex32Array(handle, 1, value, key);
+ return (status == 0)
+ ? UTIL_ERROR_TABLE_VALUE_IS_EMPTY
+ : status;
}
#endif
@@ -1764,7 +2143,7 @@ return (status == 0)
@vdesc handle to the table
@endvar
- @var N_array
+ @var N_elements
@vtype int (must be >= 0)
@vdesc number of elements in array[]
@endvar
@@ -1778,7 +2157,7 @@ return (status == 0)
CCTK_COMPLEX, CCTK_COMPLEX8, CCTK_COMPLEX16, CCTK_COMPLEX32
(not all of these may be supported on any given system)
@vdesc an array into which this function should store
- (at most N_array elements of) a copy of the value
+ (at most N_elements elements of) a copy of the value
associated with the specified key,
or NULL pointer to skip storing this
@endvar
@@ -1793,13 +2172,13 @@ return (status == 0)
-ve for error, including
UTIL_ERROR_BAD_HANDLE handle is invalid
UTIL_ERROR_TABLE_BAD_KEY key contains '/' character
- UTIL_ERROR_BAD_INPUT array != NULL and N_array < 0
+ UTIL_ERROR_BAD_INPUT array != NULL and N_elements < 0
UTIL_ERROR_TABLE_NO_SUCH_KEY no such key in table
UTIL_ERROR_TABLE_WRONG_DATA_TYPE value has wrong data type
@comment Note that it is *not* an error for the value to have
- > N_array elements; in this case only N_array are
+ > N_elements elements; in this case only N_elements are
stored. The caller can detect this by comparing the
- return value with N_array.
+ return value with N_elements.
The rationale for this design is that the caller may
know or suspect that the value is a large array, but
@@ -1807,9 +2186,9 @@ return (status == 0)
case this design avoids the caller having to allocate
a large buffer unnecessarily.
- It is also *not* an error for the value to have < N_array
+ It is also *not* an error for the value to have < N_elements
elements; again the caller can detect this by comparing the
- return value with N_array.
+ return value with N_elements.
Note also that if any error code is returned, the
caller's value buffer (pointed to by value_buffer)
@@ -1822,77 +2201,77 @@ return (status == 0)
/* arrays of pointers */
int Util_TableGetPointerArray(int handle,
- int N_array, CCTK_POINTER array[],
+ int N_elements, CCTK_POINTER array[],
const char *key)
{
-return internal_get(handle,
- CCTK_VARIABLE_POINTER, N_array, (void *) array,
- key);
+ return internal_get(handle,
+ CCTK_VARIABLE_POINTER, N_elements, (void *) array,
+ key);
}
int Util_TableGetFnPointerArray(int handle,
- int N_array, CCTK_FN_POINTER array[],
+ int N_elements, CCTK_FN_POINTER array[],
const char *key)
{
-return internal_get(handle,
- CCTK_VARIABLE_FN_POINTER, N_array, (void *) array,
- key);
+ return internal_get(handle,
+ CCTK_VARIABLE_FN_POINTER, N_elements, (void *) array,
+ key);
}
/**************************************/
/* arrays of characters (i.e. character strings) */
int Util_TableGetCharArray(int handle,
- int N_array, CCTK_CHAR array[],
+ int N_elements, CCTK_CHAR array[],
const char *key)
{
-return internal_get(handle,
- CCTK_VARIABLE_CHAR, N_array, (void *) array,
- key);
+ return internal_get(handle,
+ CCTK_VARIABLE_CHAR, N_elements, (void *) array,
+ key);
}
/**************************************/
/* integers */
int Util_TableGetIntArray(int handle,
- int N_array, CCTK_INT array[],
+ int N_elements, CCTK_INT array[],
const char *key)
{
-return internal_get(handle,
- CCTK_VARIABLE_INT, N_array, (void *) array,
- key);
+ return internal_get(handle,
+ CCTK_VARIABLE_INT, N_elements, (void *) array,
+ key);
}
#ifdef CCTK_INTEGER_PRECISION_2
int Util_TableGetInt2Array(int handle,
- int N_array, CCTK_INT2 array[],
+ int N_elements, CCTK_INT2 array[],
const char *key)
{
-return internal_get(handle,
- CCTK_VARIABLE_INT2, N_array, (void *) array,
- key);
+ return internal_get(handle,
+ CCTK_VARIABLE_INT2, N_elements, (void *) array,
+ key);
}
#endif
#ifdef CCTK_INTEGER_PRECISION_4
int Util_TableGetInt4Array(int handle,
- int N_array, CCTK_INT4 array[],
+ int N_elements, CCTK_INT4 array[],
const char *key)
{
-return internal_get(handle,
- CCTK_VARIABLE_INT4, N_array, (void *) array,
- key);
+ return internal_get(handle,
+ CCTK_VARIABLE_INT4, N_elements, (void *) array,
+ key);
}
#endif
#ifdef CCTK_INTEGER_PRECISION_8
int Util_TableGetInt8Array(int handle,
- int N_array, CCTK_INT8 array[],
+ int N_elements, CCTK_INT8 array[],
const char *key)
{
-return internal_get(handle,
- CCTK_VARIABLE_INT8, N_array, (void *) array,
- key);
+ return internal_get(handle,
+ CCTK_VARIABLE_INT8, N_elements, (void *) array,
+ key);
}
#endif
@@ -1900,44 +2279,44 @@ return internal_get(handle,
/* real numbers */
int Util_TableGetRealArray(int handle,
- int N_array, CCTK_REAL array[],
+ int N_elements, CCTK_REAL array[],
const char *key)
{
-return internal_get(handle,
- CCTK_VARIABLE_REAL, N_array, (void *) array,
- key);
+ return internal_get(handle,
+ CCTK_VARIABLE_REAL, N_elements, (void *) array,
+ key);
}
#ifdef CCTK_REAL_PRECISION_4
int Util_TableGetReal4Array(int handle,
- int N_array, CCTK_REAL4 array[],
+ int N_elements, CCTK_REAL4 array[],
const char *key)
{
-return internal_get(handle,
- CCTK_VARIABLE_REAL4, N_array, (void *) array,
- key);
+ return internal_get(handle,
+ CCTK_VARIABLE_REAL4, N_elements, (void *) array,
+ key);
}
#endif
#ifdef CCTK_REAL_PRECISION_8
int Util_TableGetReal8Array(int handle,
- int N_array, CCTK_REAL8 array[],
+ int N_elements, CCTK_REAL8 array[],
const char *key)
{
-return internal_get(handle,
- CCTK_VARIABLE_REAL8, N_array, (void *) array,
- key);
+ return internal_get(handle,
+ CCTK_VARIABLE_REAL8, N_elements, (void *) array,
+ key);
}
#endif
#ifdef CCTK_REAL_PRECISION_16
int Util_TableGetReal16Array(int handle,
- int N_array, CCTK_REAL16 array[],
+ int N_elements, CCTK_REAL16 array[],
const char *key)
{
-return internal_get(handle,
- CCTK_VARIABLE_REAL16, N_array, (void *) array,
- key);
+ return internal_get(handle,
+ CCTK_VARIABLE_REAL16, N_elements, (void *) array,
+ key);
}
#endif
@@ -1945,44 +2324,44 @@ return internal_get(handle,
/* complex numbers */
int Util_TableGetComplexArray(int handle,
- int N_array, CCTK_COMPLEX array[],
+ int N_elements, CCTK_COMPLEX array[],
const char *key)
{
-return internal_get(handle,
- CCTK_VARIABLE_COMPLEX, N_array, (void *) array,
- key);
+ return internal_get(handle,
+ CCTK_VARIABLE_COMPLEX, N_elements, (void *) array,
+ key);
}
#ifdef CCTK_COMPLEX_PRECISION_8
int Util_TableGetComplex8Array(int handle,
- int N_array, CCTK_COMPLEX8 array[],
+ int N_elements, CCTK_COMPLEX8 array[],
const char *key)
{
-return internal_get(handle,
- CCTK_VARIABLE_COMPLEX8, N_array, (void *) array,
- key);
+ return internal_get(handle,
+ CCTK_VARIABLE_COMPLEX8, N_elements, (void *) array,
+ key);
}
#endif
#ifdef CCTK_COMPLEX_PRECISION_16
int Util_TableGetComplex16Array(int handle,
- int N_array, CCTK_COMPLEX16 array[],
+ int N_elements, CCTK_COMPLEX16 array[],
const char *key)
{
-return internal_get(handle,
- CCTK_VARIABLE_COMPLEX16, N_array, (void *) array,
- key);
+ return internal_get(handle,
+ CCTK_VARIABLE_COMPLEX16, N_elements, (void *) array,
+ key);
}
#endif
#ifdef CCTK_COMPLEX_PRECISION_32
int Util_TableGetComplex32Array(int handle,
- int N_array, CCTK_COMPLEX32 array[],
+ int N_elements, CCTK_COMPLEX32 array[],
const char *key)
{
-return internal_get(handle,
- CCTK_VARIABLE_COMPLEX16, N_array, (void *) array,
- key);
+ return internal_get(handle,
+ CCTK_VARIABLE_COMPLEX16, N_elements, (void *) array,
+ key);
}
#endif
@@ -2009,74 +2388,121 @@ return internal_get(handle,
@@*/
int Util_TableItCreate(int handle)
{
-const struct table_header *const thp = get_table_header_ptr(handle);
-if (thp == NULL)
- then return UTIL_ERROR_BAD_HANDLE;
-
-#ifdef UTIL_TABLE_DEBUG
-printf("Util_TableItCreate(handle=%d)\n", handle);
-#endif
-
-if (N_iterators == N_ip_array)
- then {
- /* grow iterator_array to get some room to create the new table */
- #ifdef UTIL_TABLE_DEBUG
- printf(" growing ip_array[] from old size %d\n",
- N_ip_array);
- #endif
- if (grow_pointer_array(&N_ip_array, &ip_array) < 0)
- then return UTIL_ERROR_NO_MEMORY; /* can't grow array */
- #ifdef UTIL_TABLE_DEBUG
- printf(" to new size %d\n",
- N_ip_array);
- #endif
- }
+ const struct table_header *const thp = get_table_header_ptr(handle);
+ if (thp == NULL)
+ {
+ return UTIL_ERROR_BAD_HANDLE;
+ }
-/* we should now have space to create the new iterator */
-assert(N_iterators < N_ip_array);
+ #ifdef UTIL_TABLE_DEBUG
+ printf("Util_TableItCreate(handle=%d)\n", handle);
+ #endif
-/* find an unused iterator handle */
-#ifdef UTIL_TABLE_DEBUG
-printf(" searching for an unused iterator handle\n");
-printf(" (N_iterators=%d N_ip_array=%d\n", N_iterators, N_ip_array);
-#endif
+ if (N_iterators == N_ip_array)
{
-int ihandle;
- for (ihandle = 0 ; ihandle < N_ip_array ; ++ihandle)
+ /* grow iterator_array to get some room to create the new table */
+ #ifdef UTIL_TABLE_DEBUG
+ printf(" growing ip_array[] from old size %d\n",
+ N_ip_array);
+ #endif
+ if (grow_pointer_array(&N_ip_array, &ip_array) < 0)
+ {
+ return UTIL_ERROR_NO_MEMORY; /* can't grow array */
+ }
+ #ifdef UTIL_TABLE_DEBUG
+ printf(" to new size %d\n",
+ N_ip_array);
+ #endif
+ }
+
+ /* we should now have space to create the new iterator */
+ assert(N_iterators < N_ip_array);
+
+ /* find an unused iterator handle */
+ #ifdef UTIL_TABLE_DEBUG
+ printf(" searching for an unused iterator handle\n");
+ printf(" (N_iterators=%d N_ip_array=%d\n", N_iterators, N_ip_array);
+ #endif
+ {
+ int ihandle;
+ for (ihandle = 0 ; ihandle < N_ip_array ; ++ihandle)
+ {
+ #ifdef UTIL_TABLE_DEBUG2
+ printf(" checking ihandle=%d\n", ihandle);
+ #endif
+ if (ip_array[ihandle] == NULL)
+ {
+ /* we've found an unused ihandle ==> create the iterator */
+ struct iterator *const ip = (struct iterator *)
+ malloc(sizeof(struct iterator));
+ if (ip == NULL)
{
+ return UTIL_ERROR_NO_MEMORY; /* can't allocate new iterator */
+ }
+
#ifdef UTIL_TABLE_DEBUG2
- printf(" checking ihandle=%d\n", ihandle);
+ printf(" using ihandle=%d\n", ihandle);
#endif
- if (ip_array[ihandle] == NULL)
- then {
- /* we've found an unused ihandle ==> create the iterator */
- struct iterator *const ip
- = (struct iterator *) malloc(sizeof(struct iterator));
- if (ip == NULL)
- then return UTIL_ERROR_NO_MEMORY;
- /* can't allocate new iterator */
-
- #ifdef UTIL_TABLE_DEBUG2
- printf(" using ihandle=%d\n", ihandle);
- #endif
-
- ip->thp = thp;
- ip->tep = thp->head; /* iterator initially */
- /* -> start of table */
-
- ++N_iterators;
- ip_array[ihandle] = (void *) ip;
-
- return ihandle;
- }
- }
-/* we should never get to here! */
-assert(false);
-abort(); /* internal error (core dump) */
-/* prevent compiler warning 'function should return a value' */
-return(0);
+ ip->thp = thp;
+ ip->tep = thp->head; /* iterator initially -> start of table */
+
+ ++N_iterators;
+ ip_array[ihandle] = (void *) ip;
+
+ return ihandle; /* NORMAL RETURN */
+ }
+ }
+
+ /* we should never get to here! */
+ assert(false);
+ abort(); /* internal error (core dump) */
+ /* prevent compiler warning 'function should return a value' */
+ return(0);
+ }
+}
+
+/******************************************************************************/
+
+/*@@
+ @routine Util_TableItClone
+ @desc This function clones (makes an exact copy of) a table
+ iterator. That is, it creates a new iterator which points
+ to the same table entry as an existing iterator.
+
+ @var ihandle
+ @vtype int
+ @vdesc handle to the iterator to be cloned
+ @endvar
+
+ @returntype int
+ @returndesc a handle to the newly-created iterator,
+ -ve for error, including
+ UTIL_ERROR_BAD_HANDLE iterator handle is invalid
+ UTIL_ERROR_NO_MEMORY unable to allocate memory
+ @endreturndesc
+ @@*/
+int Util_TableItClone(int ihandle)
+{
+ struct iterator *const ip = get_iterator_ptr(ihandle);
+ if (ip == NULL)
+ {
+ return UTIL_ERROR_BAD_HANDLE;
+ }
+
+ {
+ const int clone_ihandle = Util_TableItCreate(ip->thp->handle);
+ if (clone_ihandle < 0)
+ {
+ return clone_ihandle; /* error in creating clone iterator */
}
+
+ {
+ struct iterator *const clone_ip = get_iterator_ptr(clone_ihandle);
+ clone_ip->tep = ip->tep;
+ return clone_ihandle;
+ }
+ }
}
/******************************************************************************/
@@ -2098,19 +2524,21 @@ return(0);
@@*/
int Util_TableItDestroy(int ihandle)
{
-struct iterator *const ip = get_iterator_ptr(ihandle);
-if (ip == NULL)
- then return UTIL_ERROR_BAD_HANDLE;
+ struct iterator *const ip = get_iterator_ptr(ihandle);
+ if (ip == NULL)
+ {
+ return UTIL_ERROR_BAD_HANDLE;
+ }
-#ifdef UTIL_TABLE_DEBUG
-printf("Util_TableItDestroy(ihandle=%d)\n", ihandle);
-#endif
+ #ifdef UTIL_TABLE_DEBUG
+ printf("Util_TableItDestroy(ihandle=%d)\n", ihandle);
+ #endif
---N_iterators;
-ip_array[ihandle] = NULL;
-free(ip);
+ --N_iterators;
+ ip_array[ihandle] = NULL;
+ free(ip);
-return 0; /* ok */
+ return 0; /* ok */
}
/******************************************************************************/
@@ -2139,13 +2567,15 @@ return 0; /* ok */
@@*/
int Util_TableItQueryIsNull(int ihandle)
{
-const struct iterator *const ip = get_iterator_ptr(ihandle);
-if (ip == NULL)
- then return UTIL_ERROR_BAD_HANDLE;
+ const struct iterator *const ip = get_iterator_ptr(ihandle);
+ if (ip == NULL)
+ {
+ return UTIL_ERROR_BAD_HANDLE;
+ }
-return (ip->tep == NULL)
- ? 1 /* iterator in "null-pointer" state */
- : 0; /* iterator -> some table entry */
+ return (ip->tep == NULL)
+ ? 1 /* iterator in "null-pointer" state */
+ : 0; /* iterator -> some table entry */
}
/******************************************************************************/
@@ -2174,13 +2604,15 @@ return (ip->tep == NULL)
@@*/
int Util_TableItQueryIsNonNull(int ihandle)
{
-const struct iterator *const ip = get_iterator_ptr(ihandle);
-if (ip == NULL)
- then return UTIL_ERROR_BAD_HANDLE;
+ const struct iterator *const ip = get_iterator_ptr(ihandle);
+ if (ip == NULL)
+ {
+ return UTIL_ERROR_BAD_HANDLE;
+ }
-return (ip->tep == NULL)
- ? 0 /* iterator in "null-pointer" state */
- : 1; /* iterator -> some table entry */
+ return (ip->tep == NULL)
+ ? 0 /* iterator in "null-pointer" state */
+ : 1; /* iterator -> some table entry */
}
/******************************************************************************/
@@ -2207,11 +2639,13 @@ return (ip->tep == NULL)
@@*/
int Util_TableItQueryTableHandle(int ihandle)
{
-const struct iterator *const ip = get_iterator_ptr(ihandle);
-if (ip == NULL)
- then return UTIL_ERROR_BAD_HANDLE;
+ const struct iterator *const ip = get_iterator_ptr(ihandle);
+ if (ip == NULL)
+ {
+ return UTIL_ERROR_BAD_HANDLE;
+ }
-return ip->thp->handle;
+ return ip->thp->handle;
}
/******************************************************************************/
@@ -2275,7 +2709,7 @@ return ip->thp->handle;
key_buffer is non-NULL), followed by a null character to
properly terminate the string in the buffer. If any
other error code is returned, the user's key buffer
- (pointed to by key_buffer if this is non-NULL) is unchanged.
+ (pointed to by key_buffer if this is non-NULL) is unchanged.
@endcomment
@endreturndesc
@@*/
@@ -2283,47 +2717,57 @@ int Util_TableItQueryKeyValueInfo(int ihandle,
int key_buffer_length, char key_buffer[],
CCTK_INT *type_code, CCTK_INT *N_elements)
{
-const struct iterator *const ip = get_iterator_ptr(ihandle);
-if (ip == NULL)
- then return UTIL_ERROR_BAD_HANDLE;
-
- {
-const struct table_entry *const tep = ip->tep;
-if (tep == NULL)
- then return UTIL_ERROR_TABLE_ITERATOR_IS_NULL;
-
- {
-const int actual_key_length = strlen(tep->key);
-
-/* store the fixed-length output arguments first, so the caller */
-/* will have them even if we hit an error trying to copy the key */
-if (type_code != NULL)
- then *type_code = tep->type_code;
-if (N_elements != NULL)
- then *N_elements = tep->N_elements;
-
-if (key_buffer != NULL)
- then {
- const int N_key_copy = min(key_buffer_length-1, actual_key_length);
- if (N_key_copy < 0) /* can only happen if key_buffer_length <= 0 */
- then {
- /*
- * We have to bail out now, before trying the memcpy(),
- * because memcpy() takes a size_t (= unsigned) value for
- * its count of how many chars to copy, and converting our
- * -ve N_key_copy to size_t would give a huge +ve count :( :(
- */
- return UTIL_ERROR_TABLE_STRING_TRUNCATED;
- }
- memcpy(key_buffer, tep->key, N_key_copy);
- key_buffer[N_key_copy] = '\0';
- if (N_key_copy < actual_key_length)
- then return UTIL_ERROR_TABLE_STRING_TRUNCATED;
- }
+ const struct iterator *const ip = get_iterator_ptr(ihandle);
+ if (ip == NULL)
+ {
+ return UTIL_ERROR_BAD_HANDLE;
+ }
-return actual_key_length; /* ok */
+ {
+ const struct table_entry *const tep = ip->tep;
+ if (tep == NULL)
+ {
+ return UTIL_ERROR_TABLE_ITERATOR_IS_NULL;
}
+
+ {
+ const int actual_key_length = strlen(tep->key);
+
+ /* store the fixed-length output arguments first, so the caller */
+ /* will have them even if we hit an error trying to copy the key */
+ if (type_code != NULL)
+ {
+ *type_code = tep->type_code;
}
+ if (N_elements != NULL)
+ {
+ *N_elements = tep->N_elements;
+ }
+
+ if (key_buffer != NULL)
+ {
+ const int N_key_copy = min(key_buffer_length-1, actual_key_length);
+ if (N_key_copy < 0) /* can only happen if key_buffer_length <= 0 */
+ {
+ /*
+ * We have to bail out now, before trying the memcpy(), because
+ * memcpy() takes a size_t (= unsigned) value for its count of how
+ * many chars to copy, and converting our -ve N_key_copy to size_t
+ * would give a huge +ve count :( :(
+ */
+ return UTIL_ERROR_TABLE_STRING_TRUNCATED;
+ }
+ memcpy(key_buffer, tep->key, N_key_copy);
+ key_buffer[N_key_copy] = '\0';
+ if (N_key_copy < actual_key_length)
+ {
+ return UTIL_ERROR_TABLE_STRING_TRUNCATED;
+ }
+ }
+
+ return actual_key_length; /* ok */
+ }
+ }
}
/******************************************************************************/
@@ -2356,20 +2800,23 @@ return actual_key_length; /* ok */
@@*/
int Util_TableItAdvance(int ihandle)
{
-struct iterator *const ip = get_iterator_ptr(ihandle);
-if (ip == NULL)
- then return UTIL_ERROR_BAD_HANDLE;
+ struct iterator *const ip = get_iterator_ptr(ihandle);
+ if (ip == NULL)
+ {
+ return UTIL_ERROR_BAD_HANDLE;
+ }
-if (ip->tep == NULL)
- then return 0; /* iterator was already in */
- /* "null-pointer" state */
+ if (ip->tep == NULL)
+ {
+ return 0; /* iterator was already in "null-pointer" state */
+ }
-ip->tep = ip->tep->next;
+ ip->tep = ip->tep->next;
-return (ip->tep == NULL)
- ? 0 /* advance past last entry */
- /* ==> iterator now in "null-pointer" state */
- : 1; /* ok */
+ return (ip->tep == NULL)
+ ? 0 /* advance past last entry */
+ /* ==> iterator now in "null-pointer" state */
+ : 1; /* ok */
}
/******************************************************************************/
@@ -2400,15 +2847,17 @@ return (ip->tep == NULL)
@@*/
int Util_TableItResetToStart(int ihandle)
{
-struct iterator *const ip = get_iterator_ptr(ihandle);
-if (ip == NULL)
- then return UTIL_ERROR_BAD_HANDLE;
+ struct iterator *const ip = get_iterator_ptr(ihandle);
+ if (ip == NULL)
+ {
+ return UTIL_ERROR_BAD_HANDLE;
+ }
-ip->tep = ip->thp->head;
-return (ip->tep == NULL)
- ? 0 /* ok, iterator is now in "null-pointer" state */
- /* (table must be empty) */
- : 1; /* ok, iterator points to some table element */
+ ip->tep = ip->thp->head;
+ return (ip->tep == NULL)
+ ? 0 /* ok, iterator is now in "null-pointer" state */
+ /* (table must be empty) */
+ : 1; /* ok, iterator points to some table element */
}
/******************************************************************************/
@@ -2435,12 +2884,14 @@ return (ip->tep == NULL)
@@*/
int Util_TableItSetToNull(int ihandle)
{
-struct iterator *const ip = get_iterator_ptr(ihandle);
-if (ip == NULL)
- then return UTIL_ERROR_BAD_HANDLE;
+ struct iterator *const ip = get_iterator_ptr(ihandle);
+ if (ip == NULL)
+ {
+ return UTIL_ERROR_BAD_HANDLE;
+ }
-ip->tep = NULL;
-return 0; /* ok */
+ ip->tep = NULL;
+ return 0; /* ok */
}
/******************************************************************************/
@@ -2476,18 +2927,24 @@ return 0; /* ok */
@@*/
int Util_TableItSetToKey(int ihandle, const char *key)
{
-struct iterator *const ip = get_iterator_ptr(ihandle);
-if (ip == NULL)
- then return UTIL_ERROR_BAD_HANDLE;
+ struct iterator *const ip = get_iterator_ptr(ihandle);
+ if (ip == NULL)
+ {
+ return UTIL_ERROR_BAD_HANDLE;
+ }
-if (bad_key(key))
- then return UTIL_ERROR_TABLE_BAD_KEY;
+ if (is_bad_key(key))
+ {
+ return UTIL_ERROR_TABLE_BAD_KEY;
+ }
-ip->tep = find_table_entry(ip->thp, key, NULL);
-if (ip->tep == NULL)
- then return UTIL_ERROR_TABLE_NO_SUCH_KEY;
+ ip->tep = find_table_entry(ip->thp, key, NULL);
+ if (ip->tep == NULL)
+ {
+ return UTIL_ERROR_TABLE_NO_SUCH_KEY;
+ }
-return 0;
+ return 0;
}
/******************************************************************************/
@@ -2551,90 +3008,59 @@ static
int type_code, int N_elements, const void *value,
const char *key)
{
-struct table_header *const thp = get_table_header_ptr(handle);
-if (thp == NULL)
- then return UTIL_ERROR_BAD_HANDLE;
-
-#ifdef UTIL_TABLE_DEBUG
-printf("internal_set(handle=%d, type_code=%d, N_elements=%d, key=\"%s\")\n",
- handle, type_code, N_elements, key);
-#endif
-
-if (bad_key(key))
- then return UTIL_ERROR_TABLE_BAD_KEY;
-if (N_elements < 0)
- then return UTIL_ERROR_BAD_INPUT;
-
-/* if key is already in table, delete it */
-/* ... this is a harmless no-op if it's not already in the table */
- {
-int return_value;
-switch (delete_key(thp, key))
- {
-case 0:
- return_value = 1; /* key was already in table before this call */
- /* (we've just deleted it, and we're about */
- /* to set the replacement in the table) */
- break;
-case UTIL_ERROR_TABLE_NO_SUCH_KEY:
- return_value = 0; /* key was not in table before this call */
- break;
-default:
- /* unexpected return code from delete_key() */
- /* (this should never happen!) */
- assert(false);
- abort(); /* internal error (core dump) */
- }
-
-/* allocate a new table entry */
+ struct table_header *const thp = get_table_header_ptr(handle);
+ if (thp == NULL)
{
-struct table_entry *tep
- = (struct table_entry *) malloc(sizeof(struct table_entry));
-if (tep == NULL)
- then return UTIL_ERROR_NO_MEMORY; /* can't allocate new table entry */
-
-/* set up the new table entry */
-tep->key = Util_Strdup(key);
-if (tep->key == NULL)
- then {
- free(tep);
- return UTIL_ERROR_NO_MEMORY; /* can't allocate memory to copy key */
- }
-
-tep->type_code = type_code;
-tep->N_elements = N_elements;
+ return UTIL_ERROR_BAD_HANDLE;
+ }
+ if (is_bad_key(key))
{
-size_t sizeof_value = N_elements * CCTK_VarTypeSize(type_code);
-#ifdef UTIL_TABLE_DEBUG2
-printf(" allocating new buffer of size sizeof_value=%d bytes\n",
- (int) sizeof_value);
-#endif
+ return UTIL_ERROR_TABLE_BAD_KEY;
+ }
+ if (N_elements < 0)
{
-void *buffer = malloc(sizeof_value);
-if (buffer == NULL)
- then {
- free(tep->key);
- free(tep);
- return UTIL_ERROR_NO_MEMORY; /* can't allocate memory */
- /* to copy value */
- }
-#ifdef UTIL_TABLE_DEBUG
-printf(" copying sizeof_value=%d bytes into buffer\n", (int) sizeof_value);
-#endif
-memcpy(buffer, value, sizeof_value);
-tep->value = buffer;
+ return UTIL_ERROR_BAD_INPUT;
+ }
-/* insert the table entry into the table's linked list */
-/* (we could insert it anywhere; for simplicity we insert it at the head) */
-tep->next = thp->head;
-thp->head = tep;
+ #ifdef UTIL_TABLE_DEBUG
+ printf("internal_set(handle=%d, type_code=%d, N_elements=%d, key=\"%s\")\n",
+ handle, type_code, N_elements, key);
+ #endif
-return return_value;
- }
- }
+ /* if key is already in table, delete it */
+ /* ... this is a harmless no-op if it's not already in the table */
+ {
+ int return_value;
+ switch (delete_table_entry_by_key(thp, key))
+ {
+ case 0:
+ return_value = 1; /* key was already in table before this call */
+ /* (we've just deleted it, and we're about */
+ /* to set the replacement in the table) */
+ break;
+ case UTIL_ERROR_TABLE_NO_SUCH_KEY:
+ return_value = 0; /* key was not in table before this call */
+ break;
+ default:
+ /* unexpected return code from delete_table_entry_by_key() */
+ /* (this should never happen!) */
+ assert(false);
+ abort(); /* internal error (core dump) */
}
+
+ {
+ const int status = insert_table_entry(thp,
+ key,
+ type_code, N_elements, value);
+ if (status < 0)
+ {
+ return status; /* error inserting entry into table */
}
+
+ return return_value;
+ }
+ }
}
/******************************************************************************/
@@ -2703,45 +3129,55 @@ static
int type_code, int N_value_buffer, void *value_buffer,
const char *key)
{
-const struct table_header *const thp = get_table_header_ptr(handle);
-if (thp == NULL)
- then return UTIL_ERROR_BAD_HANDLE;
+ const struct table_header *const thp = get_table_header_ptr(handle);
+ if (thp == NULL)
+ {
+ return UTIL_ERROR_BAD_HANDLE;
+ }
-#ifdef UTIL_TABLE_DEBUG
-printf("internal_get(handle=%d, type_code=%d, N_value_buffer=%d, key=\"%s\")\n",
- handle, type_code, N_value_buffer, key);
-#endif
+ if (is_bad_key(key))
+ {
+ return UTIL_ERROR_TABLE_BAD_KEY;
+ }
-if (bad_key(key))
- then return UTIL_ERROR_TABLE_BAD_KEY;
+ #ifdef UTIL_TABLE_DEBUG
+ printf(
+ "internal_get(handle=%d, type_code=%d, N_value_buffer=%d, key=\"%s\")\n",
+ handle, type_code, N_value_buffer, key);
+ #endif
+ {
+ const struct table_entry *const tep = find_table_entry(thp, key, NULL);
+ if (tep == NULL)
{
-const struct table_entry *const tep = find_table_entry(thp, key, NULL);
-if (tep == NULL)
- then return UTIL_ERROR_TABLE_NO_SUCH_KEY; /* no such key in table */
-
-if (tep->type_code != type_code)
- then return UTIL_ERROR_TABLE_WRONG_DATA_TYPE; /* value has wrong data type */
+ return UTIL_ERROR_TABLE_NO_SUCH_KEY; /* no such key in table */
+ }
-if (value_buffer != NULL)
- then {
- if (N_value_buffer < 0)
- then return UTIL_ERROR_BAD_INPUT;
- {
- const int N_copy = min(N_value_buffer, tep->N_elements);
- const size_t sizeof_N_copy_elements
- = N_copy * CCTK_VarTypeSize(type_code);
- #ifdef UTIL_TABLE_DEBUG
- printf(
- " copying N_copy=%d elements (sizeof_N_copy_elements=%d bytes)\n",
- N_copy, (int) sizeof_N_copy_elements);
- #endif
- memcpy(value_buffer, tep->value, sizeof_N_copy_elements);
- }
- }
+ if (tep->type_code != type_code)
+ {
+ return UTIL_ERROR_TABLE_WRONG_DATA_TYPE; /* value has wrong data type */
+ }
-return tep->N_elements;
+ if (value_buffer != NULL)
+ {
+ if (N_value_buffer < 0)
+ {
+ return UTIL_ERROR_BAD_INPUT;
+ }
+ {
+ const int N_copy = min(N_value_buffer, tep->N_elements);
+ const size_t sizeof_N_copy_elements = N_copy * CCTK_VarTypeSize(type_code);
+ #ifdef UTIL_TABLE_DEBUG
+ printf(
+ " copying N_copy=%d elements (sizeof_N_copy_elements=%d bytes)\n",
+ N_copy, (int) sizeof_N_copy_elements);
+ #endif
+ memcpy(value_buffer, tep->value, sizeof_N_copy_elements);
+ }
}
+
+ return tep->N_elements;
+ }
}
/******************************************************************************/
@@ -2760,64 +3196,9 @@ return tep->N_elements;
static
struct table_header *get_table_header_ptr(int handle)
{
-return ((handle >= 0) && (handle < N_thp_array))
- ? (struct table_header *) thp_array[handle] /* valid handle */
- : NULL; /* invalid handle */
-}
-
-/******************************************************************************/
-
-/*
- * This function deletes a key from a table.
- *
- * Results:
- * The return value is the same as for Util_TableDeleteKey(), i.e.
- * 0 for ok (key existed before this call, and has now been deleted)
- * -ve for error, including
- * UTIL_ERROR_TABLE_NO_SUCH_KEY no such key in table
- */
-static
- int delete_key(struct table_header *thp, const char *key)
-{
-struct table_entry *prev_tep;
-struct table_entry *const tep = find_table_entry(thp, key, &prev_tep);
-if (tep == NULL)
- then return UTIL_ERROR_TABLE_NO_SUCH_KEY;
-
- {
-/* unlink the table entry from the list */
-struct table_entry *next_tep = tep->next;
-if (prev_tep == NULL)
- then thp->head = next_tep; /* it was the starting entry */
- /* in the list */
- else prev_tep->next = next_tep; /* it was somewhere in the middle */
-
-free_table_entry(tep);
-return 0; /* ok: key existed before this call, */
- /* and has now been deleted */
- }
-}
-
-/******************************************************************************/
-
-/*
- * This function frees a table entry and the key/value it holds.
- *
- * Arguments:
- * tep -> The table entry to be freed.
- */
-static
- void free_table_entry(struct table_entry *tep)
-{
-assert(tep != NULL);
-
-assert(tep->key != NULL);
-free(tep->key);
-
-assert(tep->value != NULL);
-free(tep->value);
-
-free(tep);
+ return ((handle >= 0) && (handle < N_thp_array))
+ ? (struct table_header *) thp_array[handle] /* valid handle */
+ : NULL; /* invalid handle */
}
/******************************************************************************/
@@ -2827,14 +3208,16 @@ free(tep);
* returns true for bad key, false for ok
*/
static
- bool bad_key(const char *key)
+ bool is_bad_key(const char *key)
{
-assert(key != NULL);
+ assert(key != NULL);
-if (strchr(key, '/') != NULL)
- then return true;
+ if (strchr(key, '/') != NULL)
+ {
+ return true;
+ }
-return false; /* ok */
+ return false; /* ok */
}
/******************************************************************************/
@@ -2864,27 +3247,198 @@ static
const char *key,
struct table_entry **prev_tep_ptr)
{
-assert(thp != NULL);
-assert(key != NULL);
+ assert(thp != NULL);
+ assert(key != NULL);
+
+ {
+ const bool case_insensitive_flag
+ = thp->flags & UTIL_TABLE_FLAGS_CASE_INSENSITIVE;
+ struct table_entry *prev_tep = NULL;
+ struct table_entry *tep = thp->head;
+ for ( ; tep != NULL ; prev_tep = tep, tep = tep->next)
+ {
+ if ( case_insensitive_flag
+ ? (Util_StrCmpi(key, tep->key) == 0)
+ : ( strcmp (key, tep->key) == 0) )
+ {
+ if (prev_tep_ptr != NULL)
+ {
+ *prev_tep_ptr = prev_tep;
+ }
+ return tep; /* key found in table */
+ }
+ }
+
+ return NULL; /* key not found in table */
+ }
+}
+
+/******************************************************************************/
+
+/*@@
+ @routine insert_table_entry
+ @desc This is an internal function used in implementing
+ Util_TableClone() and internal_set(). It allocates
+ a new table entry and sets the fields in it to be
+ copies of the arguments.
+
+ @var thp
+ @vtype struct table_header *
+ @vdesc pointer to the table header
+ @endvar
+
+ @var key
+ @vtype const char *
+ @vdesc pointer to a (C-style null-terminated) string, a copy
+ of which is to be the new table entry's key
+ @endvar
+
+ @var type_code
+ @vtype int
+ @vdesc the value to be the new table entry's type code
+ (one of the CCTK_VARIABLE_* constants from "cctk_Types.h"),
+ @endvar
+
+ @var N_elements
+ @vtype int (must be >= 0)
+ @vdesc number of elements in array[]
+ @endvar
+
+ @var array
+ @vtype const T[], where T is one of
+ CCTK_POINTER, CCTK_FN_POINTER,
+ CCTK_CHAR,
+ CCTK_INT, CCTK_INT2, CCTK_INT4, CCTK_INT8,
+ CCTK_REAL, CCTK_REAL4, CCTK_REAL8, CCTK_REAL16,
+ CCTK_COMPLEX, CCTK_COMPLEX8, CCTK_COMPLEX16, CCTK_COMPLEX32
+ (not all of these may be supported on any given system)
+ @vdesc (pointer to) an array, a copy of which is to be
+ the new table entry's value
+ @endvar
+
+ @returntype int
+ @returndesc 0 for ok,
+ UTIL_ERROR_NO_MEMORY unable to allocate memory
+ @endreturndesc
+ @@*/
+static
+ int insert_table_entry(struct table_header *thp,
+ const char *key,
+ int type_code, int N_elements, const void *value)
+{
+ struct table_entry *tep = (struct table_entry *)
+ malloc(sizeof(struct table_entry));
+ if (tep == NULL)
+ {
+ return UTIL_ERROR_NO_MEMORY; /* can't allocate new table entry */
+ }
+ #ifdef UTIL_TABLE_DEBUG
+ printf("insert_table_entry(type_code=%d, N_elements=%d, key=\"%s\")...\n",
+ type_code, N_elements, key);
+ #endif
+
+ tep->key = Util_Strdup(key);
+ if (tep->key == NULL)
{
-const int flags = thp->flags;
-struct table_entry *prev_tep = NULL;
-struct table_entry *tep = thp->head;
- for ( ; tep != NULL ; prev_tep = tep, tep = tep->next)
- {
- if ( (flags & UTIL_TABLE_FLAGS_CASE_INSENSITIVE)
- ? (Util_StrCmpi(key, tep->key) == 0)
- : ( strcmp (key, tep->key) == 0) )
- then {
- if (prev_tep_ptr != NULL)
- *prev_tep_ptr = prev_tep;
- return tep; /* key found in table */
- }
- }
+ free(tep);
+ return UTIL_ERROR_NO_MEMORY; /* can't allocate memory to copy key */
+ }
-return NULL; /* key not found in table */
+ tep->type_code = type_code;
+ tep->N_elements = N_elements;
+
+ {
+ const size_t sizeof_value = N_elements * CCTK_VarTypeSize(type_code);
+ #ifdef UTIL_TABLE_DEBUG2
+ printf(" allocating new buffer of size sizeof_value=%d bytes\n",
+ (int) sizeof_value);
+ #endif
+ {
+ void *const buffer = malloc(sizeof_value);
+ if (buffer == NULL)
+ {
+ free(tep->key);
+ free(tep);
+ return UTIL_ERROR_NO_MEMORY; /* can't allocate memory for copy of value */
}
+ #ifdef UTIL_TABLE_DEBUG
+ printf(" copying sizeof_value=%d bytes into buffer\n", (int) sizeof_value);
+ #endif
+ memcpy(buffer, value, sizeof_value);
+ tep->value = buffer;
+
+ /* insert the table entry into the table's linked list */
+ /* (we could insert it anywhere; for simplicity we insert it at the head) */
+ tep->next = thp->head;
+ thp->head = tep;
+
+ return 0;
+ }
+ }
+}
+
+/******************************************************************************/
+
+/*
+ * This function deletes an entry (specified by its key) from a table,
+ * freeing its table entry and the pointed-to key and value.
+ *
+ * Results:
+ * The return value is the same as for Util_TableDeleteKey(), i.e.
+ * 0 for ok (key existed before this call, and has now been deleted)
+ * -ve for error, including
+ * UTIL_ERROR_TABLE_NO_SUCH_KEY no such key in table
+ */
+static
+ int delete_table_entry_by_key(struct table_header *thp, const char *key)
+{
+ struct table_entry *prev_tep;
+ struct table_entry *const tep = find_table_entry(thp, key, &prev_tep);
+ if (tep == NULL)
+ {
+ return UTIL_ERROR_TABLE_NO_SUCH_KEY;
+ }
+
+ delete_table_entry_by_ptr(thp, prev_tep);
+ return 0; /* ok: key existed before this call, */
+ /* and has now been deleted */
+}
+
+/******************************************************************************/
+
+/*
+ * This function deletes an entry from a table, freeing its table entry
+ * and the pointed-to key and value. The entry to be deleted is specified
+ * by a pointer to the *previous* table entry, or NULL to delete the
+ * starting entry in the list.
+ */
+static
+ void delete_table_entry_by_ptr(struct table_header *thp,
+ struct table_entry *prev_tep)
+{
+/* this is the entry we want to delete */
+struct table_entry *const tep = (prev_tep == NULL) ? thp->head
+ : prev_tep->next;
+assert(tep != NULL);
+
+/* unlink it from the list */
+if (prev_tep == NULL)
+{
+ thp->head = tep->next;
+}
+else
+{
+ prev_tep->next = tep->next;
+}
+
+assert(tep->key != NULL);
+free(tep->key);
+
+assert(tep->value != NULL);
+free(tep->value);
+
+free(tep);
}
/******************************************************************************/
@@ -2896,16 +3450,16 @@ return NULL; /* key not found in table */
* ihandle = The iterator handle.
*
* Results:
+ * If the handle is valid, this function returns a pointer to the iterator.
* If the handle is invalid (i.e. there is no such table), this function
* returns NULL.
- * If the handle is valid, this function returns a pointer to the iterator.
*/
static
struct iterator *get_iterator_ptr(int ihandle)
{
-return ((ihandle >= 0) && (ihandle < N_ip_array))
- ? (struct iterator *) ip_array[ihandle] /* valid handle */
- : NULL; /* invalid handle */
+ return ((ihandle >= 0) && (ihandle < N_ip_array))
+ ? (struct iterator *) ip_array[ihandle] /* valid handle */
+ : NULL; /* invalid handle */
}
/******************************************************************************/
@@ -2927,25 +3481,27 @@ return ((ihandle >= 0) && (ihandle < N_ip_array))
static
int grow_pointer_array(int *pN, void ***pvp_array)
{
-int N = *pN;
-void **vp_array = *pvp_array;
-int new_N = GROW(N);
-void **new_vp_array = realloc(vp_array, new_N*sizeof(void *));
-if (new_vp_array == NULL)
- then return UTIL_ERROR_NO_MEMORY; /* can't grow array */
+const int N = *pN;
+ void **vp_array = *pvp_array;
+ const int new_N = GROW(N);
+ void **new_vp_array = realloc(vp_array, new_N*sizeof(void *));
+ if (new_vp_array == NULL)
+ {
+ return UTIL_ERROR_NO_MEMORY; /* can't grow array */
+ }
-/* initialize the new space to NULL pointers */
+ /* initialize the new space to NULL pointers */
+ {
+ int i;
+ for (i = N ; i < new_N ; ++i)
{
-int i;
- for (i = N ; i < new_N ; ++i)
- {
- new_vp_array[i] = NULL;
- }
+ new_vp_array[i] = NULL;
}
+ }
-*pvp_array = new_vp_array;
-*pN = new_N;
-return 0; /* ok */
+ *pvp_array = new_vp_array;
+ *pN = new_N;
+ return 0; /* ok */
}
/******************************************************************************/
@@ -2954,18 +3510,18 @@ return 0; /* ok */
#ifdef UTIL_TABLE_TEST
/*
- * This function prints out all the tables and their data structures.
- */
+* This function prints out all the tables and their data structures.
+*/
static
- void print_all_tables(void)
+void print_all_tables(void)
{
-int handle;
+ int handle;
-printf("N_tables=%d N_thp_array=%d\n", N_tables, N_thp_array);
- for (handle = 0 ; handle < N_thp_array ; ++handle)
- {
- print_table(handle);
- }
+ printf("N_tables=%d N_thp_array=%d\n", N_tables, N_thp_array);
+ for (handle = 0 ; handle < N_thp_array ; ++handle)
+ {
+ print_table(handle);
+ }
}
#endif /* UTIL_TABLE_TEST */
@@ -2978,60 +3534,71 @@ printf("N_tables=%d N_thp_array=%d\n", N_tables, N_thp_array);
static
void print_table(int handle)
{
-printf("thp_array[%d]: ", handle);
+ printf("thp_array[%d]: ", handle);
+ {
+ const struct table_header *const thp = get_table_header_ptr(handle);
+ if (thp == NULL)
+ {
+ printf("NULL\n");
+ }
+ else
{
-const struct table_header *const thp = get_table_header_ptr(handle);
-if (thp == NULL)
- then printf("NULL\n");
- else {
- printf("flags=0x%x handle=%d\n", thp->flags, thp->handle);
+ printf("flags=0x%x handle=%d\n", thp->flags, thp->handle);
+ {
+ const struct table_entry *tep = thp->head;
+ for ( ; tep != NULL ; tep = tep->next)
+ {
+ printf(" [tep=%p]\n", (const void *) tep);
+ printf("\tkey=\"%s\"\n", tep->key);
+ printf("\ttype_code=%d N_elements=%d\n", tep->type_code, tep->N_elements);
+ {
+ int i;
+ switch (tep->type_code)
+ {
+ case CCTK_VARIABLE_INT:
+ printf("\t[int]");
+ {
+ const CCTK_INT *const value_ptr_int = (const CCTK_INT *) tep->value;
+ for (i = 0 ; i < tep->N_elements ; ++i)
+ {
+ printf("\t%d", (int) value_ptr_int[i]);
+ }
+ }
+ break;
+ case CCTK_VARIABLE_REAL:
+ printf("\t[real]");
+ {
+ const CCTK_REAL *const value_ptr_real
+ = (const CCTK_REAL *) tep->value;
+ for (i = 0 ; i < tep->N_elements ; ++i)
{
- const struct table_entry *tep = thp->head;
- for ( ; tep != NULL ; tep = tep->next)
- {
- printf(" [tep=%p]\n", (const void *) tep);
- printf("\tkey=\"%s\"\n", tep->key);
- printf("\ttype_code=%d N_elements=%d\n",
- tep->type_code, tep->N_elements);
- {
- int i;
- switch (tep->type_code)
- {
- case CCTK_VARIABLE_INT:
- printf("\t[int]");
- for (i = 0 ; i < tep->N_elements ; ++i)
- {
- const CCTK_INT *value_int
- = (const CCTK_INT *) tep->value;
- printf("\t%d", (int) value_int[i]);
- }
- break;
- case CCTK_VARIABLE_REAL:
- printf("\t[real]");
- for (i = 0 ; i < tep->N_elements ; ++i)
- {
- const CCTK_REAL *value_real
- = (const CCTK_REAL *) tep->value;
- printf("\t%g", (double) value_real[i]);
- }
- break;
- case CCTK_VARIABLE_COMPLEX:
- printf("\t[complex]");
- for (i = 0 ; i < tep->N_elements ; ++i)
- {
- const CCTK_COMPLEX *value_complex
- = (const CCTK_COMPLEX *) tep->value;
- printf("\t(%g,%g)",
- (double) value_complex[i].Re,
- (double) value_complex[i].Im);
- }
- }
- printf("\n");
- }
- }
+ printf("\t%g", (double) value_ptr_real[i]);
}
+ }
+ break;
+ case CCTK_VARIABLE_COMPLEX:
+ printf("\t[complex]");
+ {
+ const CCTK_COMPLEX *const value_ptr_complex
+ = (const CCTK_COMPLEX *) tep->value;
+ for (i = 0 ; i < tep->N_elements ; ++i)
+ {
+ printf("\t(%g,%g)",
+ (double) value_ptr_complex[i].Re,
+ (double) value_ptr_complex[i].Im);
+ }
+ }
+ break;
+ default:
+ printf("\t[sorry, don't know how to print this type!]");
+ break;
+ }
+ printf("\n");
}
+ }
+ }
}
+ }
}
#endif /* UTIL_TABLE_TEST */
@@ -3044,18 +3611,22 @@ if (thp == NULL)
static
void print_all_iterators(void)
{
-int ihandle;
+ int ihandle;
-printf("N_iterators=%d N_ip_array=%d\n", N_iterators, N_ip_array);
- for (ihandle = 0 ; ihandle < N_ip_array ; ++ihandle)
- {
- const struct iterator *const ip = get_iterator_ptr(ihandle);
- printf("ip_array[%d]: ", ihandle);
- if (ip == NULL)
- then printf("NULL\n");
- else printf("thp=%p tep=%p\n",
- (const void *) ip->thp, (const void *) ip->tep);
- }
+ printf("N_iterators=%d N_ip_array=%d\n", N_iterators, N_ip_array);
+ for (ihandle = 0 ; ihandle < N_ip_array ; ++ihandle)
+ {
+ const struct iterator *const ip = get_iterator_ptr(ihandle);
+ printf("ip_array[%d]: ", ihandle);
+ if (ip == NULL)
+ {
+ printf("NULL\n");
+ }
+ else
+ {
+ printf("thp=%p tep=%p\n", (const void *) ip->thp, (const void *) ip->tep);
+ }
+ }
}
#endif /* UTIL_TABLE_TEST */
@@ -3069,223 +3640,195 @@ printf("N_iterators=%d N_ip_array=%d\n", N_iterators, N_ip_array);
* low-level macros to test set/get of scalars of various types
*/
-#define CHECK_SET_GET_INT(handle, type, \
- key_already_exists, case_insensitive, \
- set_fn, get_fn) \
- { \
-type x = 42; \
-assert( set_fn(handle, x, "int_x") == key_already_exists ); \
-x = 1; \
-assert( get_fn(handle, &x, "int_x") == 1 ); \
-assert( x == 42 ); \
-if (case_insensitive) \
- then { \
- x = 2; \
- assert( get_fn(handle, &x, "Int_X") == 1 ); \
- assert( x == 42 ); \
- } \
- else assert( get_fn(handle, &x, "Int_X") \
- == UTIL_ERROR_TABLE_NO_SUCH_KEY ); \
- } /* end macro */
-
-/**************************************/
-
-#define CHECK_SET_GET_REAL(handle, type, \
- key_already_exists, case_insensitive, \
+#define CHECK_SET_GET_INT(handle, type, \
+ key_already_exists, case_insensitive, \
set_fn, get_fn) \
+ { \
+ type x = 42; \
+ assert( set_fn(handle, x, "int_x") == key_already_exists ); \
+ x = 1; \
+ assert( get_fn(handle, &x, "int_x") == 1 ); \
+ assert( x == 42 ); \
+ if (case_insensitive) \
{ \
-type y = 42.25; \
-assert( set_fn(handle, y, "REAL_y") == key_already_exists ); \
-y = 1.25; \
-assert( get_fn(handle, &y, "REAL_y") == 1 ); \
-assert( y == 42.25 ); \
-if (case_insensitive) \
- then { \
- y = 1.5; \
- assert( get_fn(handle, &y, "real_y") == 1 ); \
- assert( y == 42.25 ); \
- } \
- else assert( get_fn(handle, &y, "real_y") \
- == UTIL_ERROR_TABLE_NO_SUCH_KEY ); \
- } /* end macro */
+ x = 2; \
+ assert( get_fn(handle, &x, "Int_X") == 1 ); \
+ assert( x == 42 ); \
+ } \
+ else \
+ { \
+ assert( get_fn(handle, &x, "Int_X") \
+ == UTIL_ERROR_TABLE_NO_SUCH_KEY ); \
+ } \
+ } /* end macro */
/**************************************/
-#define CHECK_SET_GET_COMPLEX(handle, type, \
- key_already_exists, case_insensitive, \
- set_fn, get_fn) \
+#define CHECK_SET_GET_GENERIC_INT(handle, type_code, type, \
+ key_already_exists, case_insensitive) \
+ { \
+ type gx = 42; \
+ assert( Util_TableSetGeneric(handle, \
+ type_code, (const void *) &gx, \
+ "gint_x") == key_already_exists ); \
+ gx = 1; \
+ assert( Util_TableGetGeneric(handle, \
+ type_code, (void *) &gx, \
+ "gint_x") == 1 ); \
+ assert( gx == 42 ); \
+ if (case_insensitive) \
{ \
-static type z = { 42.25, 105.5 }; \
-assert( set_fn(handle, z, "COMPlex_Z") == key_already_exists ); \
-z.Re = 1.25; z.Im = -2.78; \
-assert( get_fn(handle, &z, "COMPlex_Z") == 1 ); \
-assert( z.Re == 42.25 ); \
-assert( z.Im == 105.5 ); \
-if (case_insensitive) \
- then { \
- z.Re = 1.5; z.Im = -2.83; \
- assert( get_fn(handle, &z, "COMPLEX_Z") == 1 ); \
- assert( z.Re == 42.25 ); \
- assert( z.Im == 105.5 ); \
- } \
- else assert( get_fn(handle, &z, "COMPLEX_Z") \
- == UTIL_ERROR_TABLE_NO_SUCH_KEY ); \
- } /* end macro */
-
-/******************************************************************************/
-
-/*
- * low-level macros to test set/get of arrays of various types
- */
-
-#define CHECK_SET_GET_INT_ARRAY(handle, type, key_already_exists, \
- set_fn, get_fn) \
+ gx = 2; \
+ assert( Util_TableGetGeneric(handle, \
+ type_code, (void *) &gx, \
+ "GInt_X") == 1 ); \
+ assert( gx == 42 ); \
+ } \
+ else \
{ \
-static type xx[5] = { 41, 42, 48, 45, 47 }; \
-assert( set_fn(handle, 3, xx, "xx") == key_already_exists ); \
-xx[0] = 14; xx[1] = 15; xx[2] = 16; xx[3] = 17; xx[4] = 19; \
-/* try to get 4 values, but only 3 were stored ==> only get 3 */ \
-assert( get_fn(handle, 4, xx, "xx") == 3 ); \
-assert( xx[0] == 41 ); \
-assert( xx[1] == 42 ); \
-assert( xx[2] == 48 ); \
-assert( xx[3] == 17 ); \
-assert( xx[4] == 19 ); \
- } /* end macro */
+ assert( Util_TableGetGeneric(handle, \
+ type_code, (void *) &gx, \
+ "GInt_X") \
+ == UTIL_ERROR_TABLE_NO_SUCH_KEY ); \
+ } \
+ } /* end macro */
/**************************************/
-#define CHECK_SET_GET_REAL_ARRAY(handle, type, key_already_exists, \
- set_fn, get_fn) \
+#define CHECK_SET_GET_REAL(handle, type, \
+ key_already_exists, case_insensitive, \
+ set_fn, get_fn) \
+ { \
+ type y = 42.25; \
+ assert( set_fn(handle, y, "REAL_y") == key_already_exists ); \
+ y = 1.25; \
+ assert( get_fn(handle, &y, "REAL_y") == 1 ); \
+ assert( y == 42.25 ); \
+ if (case_insensitive) \
+ { \
+ y = 1.5; \
+ assert( get_fn(handle, &y, "real_y") == 1 ); \
+ assert( y == 42.25 ); \
+ } \
+ else \
{ \
-static type yy[5] = { 41.25, 42.5, 48.0, 45.75, 47.125 }; \
-assert( set_fn(handle, 4, yy, "yy") == key_already_exists ); \
-yy[0] = 14.0; yy[1] = 15.5; yy[2] = 16.0; \
-yy[3] = 17.5; yy[4] = 19.5; \
-/* only get 3 of 4 stored values */ \
-assert( get_fn(handle, 3, yy, "yy") == 4 ); \
-assert( yy[0] == 41.25 ); \
-assert( yy[1] == 42.5 ); \
-assert( yy[2] == 48.0 ); \
-assert( yy[3] == 17.5 ); \
-assert( yy[4] == 19.5 ); \
- } /* end macro */
+ assert( get_fn(handle, &y, "real_y") \
+ == UTIL_ERROR_TABLE_NO_SUCH_KEY ); \
+ } \
+ } /* end macro */
/**************************************/
-#define CHECK_SET_GET_COMPLEX_ARRAY(handle, type, key_already_exists, \
- set_fn, get_fn) \
+#define CHECK_SET_GET_COMPLEX(handle, type, \
+ key_already_exists, case_insensitive, \
+ set_fn, get_fn) \
+ { \
+ static type z = { 42.25, 105.5 }; \
+ assert( set_fn(handle, z, "COMPlex_Z") == key_already_exists ); \
+ z.Re = 1.25; z.Im = -2.78; \
+ assert( get_fn(handle, &z, "COMPlex_Z") == 1 ); \
+ assert( z.Re == 42.25 ); \
+ assert( z.Im == 105.5 ); \
+ if (case_insensitive) \
{ \
-static type zz[5] \
- = { {3.5,1.25}, {9.5,4.5}, {0.5,8.0}, {5.0,5.5}, {4.5,7.25} }; \
-assert( set_fn(handle, 4, zz, "zz") == key_already_exists ); \
-zz[0].Re = 10.25; zz[0].Im = 11.75; \
-zz[1].Re = -2.5; zz[1].Im = 3.5; \
-zz[2].Re = 14.0; zz[2].Im = -8.5; \
-zz[3].Re = 0.25; zz[3].Im = 8.875; \
-zz[4].Re = -0.25; zz[4].Im = -0.75; \
-/* only get 3 of 4 stored values */ \
-assert( get_fn(handle, 3, zz, "zz") == 4 ); \
-assert( zz[0].Re == 3.5 ); assert( zz[0].Im == 1.25 ); \
-assert( zz[1].Re == 9.5 ); assert( zz[1].Im == 4.5 ); \
-assert( zz[2].Re == 0.5 ); assert( zz[2].Im == 8.0 ); \
-assert( zz[3].Re == 0.25 ); assert( zz[3].Im == 8.875 ); \
-assert( zz[4].Re == -0.25 ); assert( zz[4].Im == -0.75 ); \
- } /* end macro */
-
-#endif /* UTIL_TABLE_TEST */
+ z.Re = 1.5; z.Im = -2.83; \
+ assert( get_fn(handle, &z, "COMPLEX_Z") == 1 ); \
+ assert( z.Re == 42.25 ); \
+ assert( z.Im == 105.5 ); \
+ } \
+ else \
+ { \
+ assert( get_fn(handle, &z, "COMPLEX_Z") \
+ == UTIL_ERROR_TABLE_NO_SUCH_KEY ); \
+ } \
+ } /* end macro */
/******************************************************************************/
-#ifdef UTIL_TABLE_TEST
/*
- * This function does a sequence of assert() calls to verify that
- * a table contains the 3 keys
- * ij = 42
- * real1 = 3.5
- * real_e = 2.75
- * inserted in that order.
- *
- * Bugs:
- * This test is tied to the present implementation -- it assumes a
- * specific ordering of table elements returned by an iterator.
+ * low-level macros to test set/get of arrays of various types
*/
-static
- void check_table_contents(int handle)
-{
-assert( Util_TableQueryNKeys(handle) == 3 );
-/* set up the key buffer */
- {
-int max_key_length = Util_TableQueryMaxKeyLength(handle);
-assert( max_key_length == (int)strlen("real_e") );
- {
-const int N_key_buffer = max_key_length + 1;
-char *const key_buffer = malloc(N_key_buffer);
-assert( key_buffer != NULL );
+#define CHECK_SET_GET_INT_ARRAY(handle, type, key_already_exists, \
+ set_fn, get_fn) \
+ { \
+ static type xx[5] = { 41, 42, 48, 45, 47 }; \
+ assert( set_fn(handle, 3, xx, "xx") == key_already_exists ); \
+ xx[0] = 14; xx[1] = 15; xx[2] = 16; xx[3] = 17; xx[4] = 19; \
+ /* try to get 4 values, but only 3 were stored ==> only get 3 */ \
+ assert( get_fn(handle, 4, xx, "xx") == 3 ); \
+ assert( xx[0] == 41 ); \
+ assert( xx[1] == 42 ); \
+ assert( xx[2] == 48 ); \
+ assert( xx[3] == 17 ); \
+ assert( xx[4] == 19 ); \
+ } /* end macro */
-/* walk through the table to verify contents {"real_e", "real1", "ij"} */
-/* n.b. implementation-dependence here for order of table elements */
- {
-int ihandle = Util_TableItCreate(handle);
-CCTK_INT key_length, type_code, N_elements;
+/**************************************/
-/* real_e = 2.75 */
-type_code = 123456;
-N_elements = 54321;
-assert( Util_TableItQueryKeyValueInfo(ihandle,
- N_key_buffer, key_buffer,
- &type_code, &N_elements)
- == (int)strlen("real_e") );
-assert( strcmp(key_buffer, "real_e") == 0 );
-assert( type_code = CCTK_VARIABLE_REAL );
-assert( N_elements == 1 );
- {
-CCTK_REAL value_real;
-assert( Util_TableGetReal(handle, &value_real, key_buffer) == 1 );
-assert( value_real == 2.75 );
+#define CHECK_SET_GET_REAL_ARRAY(handle, type, key_already_exists, \
+ set_fn, get_fn) \
+ { \
+ static type yy[5] = { 41.25, 42.5, 48.0, 45.75, 47.125 }; \
+ assert( set_fn(handle, 4, yy, "yy") == key_already_exists ); \
+ yy[0] = 14.0; yy[1] = 15.5; yy[2] = 16.0; \
+ yy[3] = 17.5; yy[4] = 19.5; \
+ /* only get 3 of 4 stored values */ \
+ assert( get_fn(handle, 3, yy, "yy") == 4 ); \
+ assert( yy[0] == 41.25 ); \
+ assert( yy[1] == 42.5 ); \
+ assert( yy[2] == 48.0 ); \
+ assert( yy[3] == 17.5 ); \
+ assert( yy[4] == 19.5 ); \
+ } /* end macro */
-/* real1 = 3.5 */
-assert( Util_TableItAdvance(ihandle) == 1 );
-type_code = 123456;
-N_elements = 54321;
-assert( Util_TableItQueryKeyValueInfo(ihandle,
- N_key_buffer, key_buffer,
- &type_code, &N_elements)
- == (int)strlen("real1") );
-assert( strcmp(key_buffer, "real1") == 0 );
-assert( type_code = CCTK_VARIABLE_REAL );
-assert( N_elements == 1 );
-assert( Util_TableGetReal(handle, &value_real, key_buffer) == 1 );
-assert( value_real == 3.5 );
+/**************************************/
-/* ij = 42 */
-assert( Util_TableItAdvance(ihandle) == 1 );
-type_code = 123456;
-N_elements = 54321;
-assert( Util_TableItQueryKeyValueInfo(ihandle,
- N_key_buffer, key_buffer,
- &type_code, &N_elements)
- == (int)strlen("ij") );
-assert( strcmp(key_buffer, "ij") == 0 );
-assert( type_code = CCTK_VARIABLE_REAL );
-assert( N_elements == 1 );
- {
-CCTK_INT value_int;
-assert( Util_TableGetInt(handle, &value_int, key_buffer) == 1 );
-assert( value_int == 42 );
+#define CHECK_SET_GET_GENERIC_REAL_ARRAY(handle, type_code, type, \
+ key_already_exists) \
+ { \
+ static type gyy[5] = { 41.25, 42.5, 48.0, 45.75, 47.125 }; \
+ assert( Util_TableSetGenericArray(handle, \
+ type_code, 4, (const void *) gyy, \
+ "gyy") == key_already_exists ); \
+ gyy[0] = 14.0; gyy[1] = 15.5; gyy[2] = 16.0; \
+ gyy[3] = 17.5; gyy[4] = 19.5; \
+ /* only get 3 of 4 stored values */ \
+ assert( Util_TableGetGenericArray(handle, \
+ type_code, 3, gyy, \
+ "gyy") == 4 ); \
+ assert( gyy[0] == 41.25 ); \
+ assert( gyy[1] == 42.5 ); \
+ assert( gyy[2] == 48.0 ); \
+ assert( gyy[3] == 17.5 ); \
+ assert( gyy[4] == 19.5 ); \
+ } /* end macro */
+
+/**************************************/
+
+#define CHECK_SET_GET_COMPLEX_ARRAY(handle, type, key_already_exists, \
+ set_fn, get_fn) \
+ { \
+ static type zz[5] \
+ = { {3.5,1.25}, {9.5,4.5}, {0.5,8.0}, {5.0,5.5}, {4.5,7.25} };\
+ assert( set_fn(handle, 4, zz, "zz") == key_already_exists ); \
+ zz[0].Re = 10.25; zz[0].Im = 11.75; \
+ zz[1].Re = -2.5; zz[1].Im = 3.5; \
+ zz[2].Re = 14.0; zz[2].Im = -8.5; \
+ zz[3].Re = 0.25; zz[3].Im = 8.875; \
+ zz[4].Re = -0.25; zz[4].Im = -0.75; \
+ /* only get 3 of 4 stored values */ \
+ assert( get_fn(handle, 3, zz, "zz") == 4 ); \
+ assert( zz[0].Re == 3.5 ); assert( zz[0].Im == 1.25 ); \
+ assert( zz[1].Re == 9.5 ); assert( zz[1].Im == 4.5 ); \
+ assert( zz[2].Re == 0.5 ); assert( zz[2].Im == 8.0 ); \
+ assert( zz[3].Re == 0.25 ); assert( zz[3].Im == 8.875 ); \
+ assert( zz[4].Re == -0.25 ); assert( zz[4].Im == -0.75 ); \
+ } /* end macro */
-assert( Util_TableItAdvance(ihandle) == 0 );
- }
- }
- }
- }
- }
-}
#endif /* UTIL_TABLE_TEST */
/******************************************************************************/
-/******************************************************************************/
#ifdef UTIL_TABLE_TEST
/*
@@ -3293,49 +3836,49 @@ assert( Util_TableItAdvance(ihandle) == 0 );
*/
int main(void)
{
-test_nonexistent_tables();
-test_table_create_destroy();
-
- {
-int handle = Util_TableCreate(UTIL_TABLE_FLAGS_DEFAULT);
-assert( handle == 0 );
-assert( Util_TableSetInt(handle, 42, "foo/") == UTIL_ERROR_TABLE_BAD_KEY );
-
- {
-int HANDLE = Util_TableCreate(UTIL_TABLE_FLAGS_CASE_INSENSITIVE);
-
-#ifdef UTIL_TABLE_DEBUG
-printf("--- printing handle=%d table (should be empty)\n", handle);
-print_table(handle);
-printf("--- about to test set/get on handle=%d table\n", handle);
-#endif
-test_set_get(handle, false);
-test_set_get(HANDLE, true);
-
-test_iterators(handle);
-test_delete_key(handle, false);
-test_iterators(HANDLE);
-test_delete_key(HANDLE, true);
-
-test_set_get_array(handle);
-test_set_get_array(HANDLE);
-
-test_set_get_string(handle, false);
-
- {
-int HANDLE2 = test_set_create_from_string();
-test_set_get_string(HANDLE2, true);
-
-printf("all ok!\n" );
-return 0;
- }
- }
- }
+ test_nonexistent_tables();
+ test_table_create_destroy();
+
+ {
+ const int handle = Util_TableCreate(UTIL_TABLE_FLAGS_DEFAULT);
+ assert( handle == 0 );
+ assert( Util_TableSetInt(handle, 42, "foo/") == UTIL_ERROR_TABLE_BAD_KEY );
+
+ {
+ const int HANDLE = Util_TableCreate(UTIL_TABLE_FLAGS_CASE_INSENSITIVE);
+
+ #ifdef UTIL_TABLE_DEBUG
+ printf("--- printing handle=%d table (should be empty)\n", handle);
+ print_table(handle);
+ printf("--- about to test set/get on handle=%d table\n", handle);
+ #endif
+ test_set_get(handle, false);
+ test_set_get(HANDLE, true);
+
+ test_iterators(handle);
+ test_delete_table_entry(handle, false);
+ test_iterators(HANDLE);
+ test_delete_table_entry(HANDLE, true);
+
+ test_set_get_array(handle);
+ test_set_get_array(HANDLE);
+
+ test_set_get_string(handle, false);
+
+ {
+ const int HANDLE2 = test_set_create_from_string();
+ test_clone(HANDLE2);
+ test_set_get_string(HANDLE2, true);
+
+ printf("all ok!\n" );
+ return 0;
+ }
+ }
+ }
}
#endif /* UTIL_TABLE_TEST */
/******************************************************************************/
-/******************************************************************************/
#ifdef UTIL_TABLE_TEST
/*
@@ -3345,25 +3888,25 @@ return 0;
static
void test_nonexistent_tables(void)
{
-assert( Util_TableDestroy(42) == UTIL_ERROR_BAD_HANDLE );
-assert( Util_TableQueryFlags(-42) == UTIL_ERROR_BAD_HANDLE );
-assert( Util_TableQueryNKeys(0) == UTIL_ERROR_BAD_HANDLE );
-assert( Util_TableDeleteKey(-1, "pickle") == UTIL_ERROR_BAD_HANDLE );
-assert( Util_TableSetInt(-1, 42, "fourty-two") == UTIL_ERROR_BAD_HANDLE );
-assert( Util_TableGetReal(-1, NULL, "something wierd")
- == UTIL_ERROR_BAD_HANDLE );
-
-assert( Util_TableItCreate(42) == UTIL_ERROR_BAD_HANDLE );
-assert( Util_TableItDestroy(42) == UTIL_ERROR_BAD_HANDLE );
-assert( Util_TableItQueryIsNull(42) == UTIL_ERROR_BAD_HANDLE );
-assert( Util_TableItQueryIsNonNull(42) == UTIL_ERROR_BAD_HANDLE );
-assert( Util_TableItQueryTableHandle(42) == UTIL_ERROR_BAD_HANDLE );
-assert( Util_TableItQueryKeyValueInfo(42,
- 0, NULL,
- NULL, NULL) == UTIL_ERROR_BAD_HANDLE );
-assert( Util_TableItAdvance(42) == UTIL_ERROR_BAD_HANDLE );
-assert( Util_TableItResetToStart(42) == UTIL_ERROR_BAD_HANDLE );
-assert( Util_TableItSetToNull(42) == UTIL_ERROR_BAD_HANDLE );
+ assert( Util_TableDestroy(42) == UTIL_ERROR_BAD_HANDLE );
+ assert( Util_TableQueryFlags(-42) == UTIL_ERROR_BAD_HANDLE );
+ assert( Util_TableQueryNKeys(0) == UTIL_ERROR_BAD_HANDLE );
+ assert( Util_TableDeleteKey(-1, "pickle") == UTIL_ERROR_BAD_HANDLE );
+ assert( Util_TableSetInt(-1, 42, "fourty-two") == UTIL_ERROR_BAD_HANDLE );
+ assert( Util_TableGetReal(-1, NULL, "something wierd")
+ == UTIL_ERROR_BAD_HANDLE );
+
+ assert( Util_TableItCreate(42) == UTIL_ERROR_BAD_HANDLE );
+ assert( Util_TableItDestroy(42) == UTIL_ERROR_BAD_HANDLE );
+ assert( Util_TableItQueryIsNull(42) == UTIL_ERROR_BAD_HANDLE );
+ assert( Util_TableItQueryIsNonNull(42) == UTIL_ERROR_BAD_HANDLE );
+ assert( Util_TableItQueryTableHandle(42) == UTIL_ERROR_BAD_HANDLE );
+ assert( Util_TableItQueryKeyValueInfo(42,
+ 0, NULL,
+ NULL, NULL) == UTIL_ERROR_BAD_HANDLE );
+ assert( Util_TableItAdvance(42) == UTIL_ERROR_BAD_HANDLE );
+ assert( Util_TableItResetToStart(42) == UTIL_ERROR_BAD_HANDLE );
+ assert( Util_TableItSetToNull(42) == UTIL_ERROR_BAD_HANDLE );
}
#endif /* UTIL_TABLE_TEST */
@@ -3388,67 +3931,67 @@ assert( Util_TableItSetToNull(42) == UTIL_ERROR_BAD_HANDLE );
static
void test_table_create_destroy(void)
{
-assert( N_tables == 0 );
-
-assert( Util_TableCreate(UTIL_TABLE_FLAGS_DEFAULT) == 0 );
-assert( N_tables == 1 );
-assert( Util_TableCreate(UTIL_TABLE_FLAGS_CASE_INSENSITIVE) == 1 );
-assert( N_tables == 2 );
-assert( Util_TableCreate(UTIL_TABLE_FLAGS_DEFAULT) == 2 );
-assert( N_tables == 3 );
-assert( Util_TableCreate(UTIL_TABLE_FLAGS_CASE_INSENSITIVE) == 3 );
-assert( N_tables == 4 );
-assert( get_table_header_ptr(0) != NULL );
-assert( get_table_header_ptr(1) != NULL );
-assert( get_table_header_ptr(2) != NULL );
-assert( get_table_header_ptr(3) != NULL );
-assert( Util_TableQueryFlags(0) == UTIL_TABLE_FLAGS_DEFAULT );
-assert( Util_TableQueryFlags(1) == UTIL_TABLE_FLAGS_CASE_INSENSITIVE );
-assert( Util_TableQueryFlags(2) == UTIL_TABLE_FLAGS_DEFAULT );
-assert( Util_TableQueryFlags(3) == UTIL_TABLE_FLAGS_CASE_INSENSITIVE );
-
-assert( Util_TableDeleteKey(3, "pickle") == UTIL_ERROR_TABLE_NO_SUCH_KEY );
-assert( Util_TableDeleteKey(3, "Pickle") == UTIL_ERROR_TABLE_NO_SUCH_KEY );
-assert( Util_TableDeleteKey(3, "PICKLE") == UTIL_ERROR_TABLE_NO_SUCH_KEY );
-
-assert( Util_TableDestroy(2) == 0 );
-assert( N_tables == 3 );
-assert( get_table_header_ptr(0) != NULL );
-assert( get_table_header_ptr(1) != NULL );
-assert( get_table_header_ptr(2) == NULL );
-assert( get_table_header_ptr(3) != NULL );
-
-assert( Util_TableCreate(0x43) == 2 );
-assert( N_tables == 4 );
-assert( get_table_header_ptr(0) != NULL );
-assert( get_table_header_ptr(1) != NULL );
-assert( get_table_header_ptr(2) != NULL );
-assert( Util_TableQueryFlags(2) == 0x43);
-assert( get_table_header_ptr(3) != NULL );
-
-assert( Util_TableDestroy(1) == 0 );
-assert( N_tables == 3 );
-assert( get_table_header_ptr(0) != NULL );
-assert( Util_TableQueryNKeys(0) == 0 );
-assert( get_table_header_ptr(1) == NULL );
-assert( Util_TableQueryMaxKeyLength(1) == UTIL_ERROR_BAD_HANDLE );
-assert( get_table_header_ptr(2) != NULL );
-assert( Util_TableQueryMaxKeyLength(2) == 0 );
-assert( get_table_header_ptr(3) != NULL );
-assert( Util_TableDeleteKey(3, "pickle") == UTIL_ERROR_TABLE_NO_SUCH_KEY );
-
-assert( Util_TableDestroy(1) == UTIL_ERROR_BAD_HANDLE );
-assert( N_tables == 3 );
-assert( get_table_header_ptr(0) != NULL );
-assert( get_table_header_ptr(1) == NULL );
-assert( get_table_header_ptr(2) != NULL );
-assert( get_table_header_ptr(3) != NULL );
-
-assert( Util_TableDestroy(0) == 0 );
-assert( Util_TableDestroy(2) == 0 );
-assert( Util_TableDestroy(3) == 0 );
-
-assert( N_tables == 0 );
+ assert( N_tables == 0 );
+
+ assert( Util_TableCreate(UTIL_TABLE_FLAGS_DEFAULT) == 0 );
+ assert( N_tables == 1 );
+ assert( Util_TableCreate(UTIL_TABLE_FLAGS_CASE_INSENSITIVE) == 1 );
+ assert( N_tables == 2 );
+ assert( Util_TableCreate(UTIL_TABLE_FLAGS_DEFAULT) == 2 );
+ assert( N_tables == 3 );
+ assert( Util_TableCreate(UTIL_TABLE_FLAGS_CASE_INSENSITIVE) == 3 );
+ assert( N_tables == 4 );
+ assert( get_table_header_ptr(0) != NULL );
+ assert( get_table_header_ptr(1) != NULL );
+ assert( get_table_header_ptr(2) != NULL );
+ assert( get_table_header_ptr(3) != NULL );
+ assert( Util_TableQueryFlags(0) == UTIL_TABLE_FLAGS_DEFAULT );
+ assert( Util_TableQueryFlags(1) == UTIL_TABLE_FLAGS_CASE_INSENSITIVE );
+ assert( Util_TableQueryFlags(2) == UTIL_TABLE_FLAGS_DEFAULT );
+ assert( Util_TableQueryFlags(3) == UTIL_TABLE_FLAGS_CASE_INSENSITIVE );
+
+ assert( Util_TableDeleteKey(3, "pickle") == UTIL_ERROR_TABLE_NO_SUCH_KEY );
+ assert( Util_TableDeleteKey(3, "Pickle") == UTIL_ERROR_TABLE_NO_SUCH_KEY );
+ assert( Util_TableDeleteKey(3, "PICKLE") == UTIL_ERROR_TABLE_NO_SUCH_KEY );
+
+ assert( Util_TableDestroy(2) == 0 );
+ assert( N_tables == 3 );
+ assert( get_table_header_ptr(0) != NULL );
+ assert( get_table_header_ptr(1) != NULL );
+ assert( get_table_header_ptr(2) == NULL );
+ assert( get_table_header_ptr(3) != NULL );
+
+ assert( Util_TableCreate(0x43) == 2 );
+ assert( N_tables == 4 );
+ assert( get_table_header_ptr(0) != NULL );
+ assert( get_table_header_ptr(1) != NULL );
+ assert( get_table_header_ptr(2) != NULL );
+ assert( Util_TableQueryFlags(2) == 0x43);
+ assert( get_table_header_ptr(3) != NULL );
+
+ assert( Util_TableDestroy(1) == 0 );
+ assert( N_tables == 3 );
+ assert( get_table_header_ptr(0) != NULL );
+ assert( Util_TableQueryNKeys(0) == 0 );
+ assert( get_table_header_ptr(1) == NULL );
+ assert( Util_TableQueryMaxKeyLength(1) == UTIL_ERROR_BAD_HANDLE );
+ assert( get_table_header_ptr(2) != NULL );
+ assert( Util_TableQueryMaxKeyLength(2) == 0 );
+ assert( get_table_header_ptr(3) != NULL );
+ assert( Util_TableDeleteKey(3, "pickle") == UTIL_ERROR_TABLE_NO_SUCH_KEY );
+
+ assert( Util_TableDestroy(1) == UTIL_ERROR_BAD_HANDLE );
+ assert( N_tables == 3 );
+ assert( get_table_header_ptr(0) != NULL );
+ assert( get_table_header_ptr(1) == NULL );
+ assert( get_table_header_ptr(2) != NULL );
+ assert( get_table_header_ptr(3) != NULL );
+
+ assert( Util_TableDestroy(0) == 0 );
+ assert( Util_TableDestroy(2) == 0 );
+ assert( Util_TableDestroy(3) == 0 );
+
+ assert( N_tables == 0 );
}
#endif /* UTIL_TABLE_TEST */
@@ -3465,90 +4008,114 @@ assert( N_tables == 0 );
static
void test_set_get(int handle, bool case_insensitive)
{
-/*
- * Note we put a test of a type that's guaranteed to be defined...
- * - at the *beginning* of each group of tests, so we can properly
- * assert whether or not the key was already in table beforehand.
- * - at the *end* of each group of tests, so the final table contents
- * are known independently of which types are and aren't defined.
- */
-
-/* integers */
-CHECK_SET_GET_INT(handle, CCTK_INT, 0, case_insensitive,
- Util_TableSetInt, Util_TableGetInt);
-#ifdef CCTK_INTEGER_PRECISION_2
-CHECK_SET_GET_INT(handle, CCTK_INT2, 1, case_insensitive,
- Util_TableSetInt2, Util_TableGetInt2);
-#endif
-#ifdef CCTK_INTEGER_PRECISION_4
-CHECK_SET_GET_INT(handle, CCTK_INT4, 1, case_insensitive,
- Util_TableSetInt4, Util_TableGetInt4);
-#endif
-#ifdef CCTK_INTEGER_PRECISION_8
-CHECK_SET_GET_INT(handle, CCTK_INT8, 1, case_insensitive,
- Util_TableSetInt8, Util_TableGetInt8);
-#endif
-CHECK_SET_GET_INT(handle, CCTK_INT, 1, case_insensitive,
- Util_TableSetInt, Util_TableGetInt);
-assert( Util_TableQueryNKeys(handle) == 1 );
-assert( Util_TableQueryMaxKeyLength(handle) == (int)strlen("int_x") );
-
-/* complex numbers */
-CHECK_SET_GET_COMPLEX(handle, CCTK_COMPLEX, 0, case_insensitive,
- Util_TableSetComplex, Util_TableGetComplex);
-#ifdef CCTK_COMPLEX_PRECISION_8
-CHECK_SET_GET_COMPLEX(handle, CCTK_COMPLEX8, 1, case_insensitive,
- Util_TableSetComplex8, Util_TableGetComplex8);
-#endif
-#ifdef CCTK_COMPLEX_PRECISION_16
-CHECK_SET_GET_COMPLEX(handle, CCTK_COMPLEX16, 1, case_insensitive,
- Util_TableSetComplex16, Util_TableGetComplex16);
-#endif
-#ifdef CCTK_COMPLEX_PRECISION_32
-CHECK_SET_GET_COMPLEX(handle, CCTK_COMPLEX32, 1, case_insensitive,
- Util_TableSetComplex32, Util_TableGetComplex32);
-#endif
-CHECK_SET_GET_COMPLEX(handle, CCTK_COMPLEX, 1, case_insensitive,
- Util_TableSetComplex, Util_TableGetComplex);
-assert( Util_TableQueryNKeys(handle) == 2 );
-assert( Util_TableQueryMaxKeyLength(handle) == (int)strlen("COMPlex_Z") );
-
-/* reals */
-CHECK_SET_GET_REAL(handle, CCTK_REAL, 0, case_insensitive,
- Util_TableSetReal, Util_TableGetReal);
-#ifdef CCTK_REAL_PRECISION_4
-CHECK_SET_GET_REAL(handle, CCTK_REAL4, 1, case_insensitive,
- Util_TableSetReal4, Util_TableGetReal4);
-#endif
-#ifdef CCTK_REAL_PRECISION_8
-CHECK_SET_GET_REAL(handle, CCTK_REAL8, 1, case_insensitive,
- Util_TableSetReal8, Util_TableGetReal8);
-#endif
-#ifdef CCTK_REAL_PRECISION_16
-CHECK_SET_GET_REAL(handle, CCTK_REAL16, 1, case_insensitive,
- Util_TableSetReal16, Util_TableGetReal16);
-#endif
-CHECK_SET_GET_REAL(handle, CCTK_REAL, 1, case_insensitive,
- Util_TableSetReal, Util_TableGetReal);
-assert( Util_TableQueryNKeys(handle) == 3 );
-assert( Util_TableQueryMaxKeyLength(handle) == (int)strlen("COMPlex_Z") );
-
- {
-CCTK_INT type_code, N_elements;
-assert( Util_TableQueryValueInfo(handle, &type_code, &N_elements, "COMPlex_Z") == 1 );
-assert( type_code == CCTK_VARIABLE_COMPLEX );
-assert( N_elements == 1 );
-
-assert( Util_TableQueryValueInfo(handle, &type_code, &N_elements, "pickle") == 0 );
-
-assert( Util_TableQueryValueInfo(handle, NULL, NULL, "int_x") == 1 );
-assert( Util_TableQueryValueInfo(handle, NULL, NULL, "Int_x")
- == (case_insensitive ? 1 : 0) );
-assert( Util_TableQueryValueInfo(handle, NULL, NULL, "real_y")
- == (case_insensitive ? 1 : 0) );
-assert( Util_TableQueryValueInfo(handle, NULL, NULL, "COMPLEX_Z")
- == (case_insensitive ? 1 : 0) );
- }
+ /*
+ * Note we put a test of a type that's guaranteed to be defined...
+ * - at the *beginning* of each group of tests, so we can properly
+ * assert whether or not the key was already in table beforehand.
+ * - at the *end* of each group of tests, so the final table contents
+ * are known independently of which types are and aren't defined.
+ */
+
+ /* integers */
+ CHECK_SET_GET_INT(handle, CCTK_INT, 0, case_insensitive,
+ Util_TableSetInt, Util_TableGetInt);
+ #ifdef CCTK_INTEGER_PRECISION_2
+ CHECK_SET_GET_INT(handle, CCTK_INT2, 1, case_insensitive,
+ Util_TableSetInt2, Util_TableGetInt2);
+ #endif
+ #ifdef CCTK_INTEGER_PRECISION_4
+ CHECK_SET_GET_INT(handle, CCTK_INT4, 1, case_insensitive,
+ Util_TableSetInt4, Util_TableGetInt4);
+ #endif
+ #ifdef CCTK_INTEGER_PRECISION_8
+ CHECK_SET_GET_INT(handle, CCTK_INT8, 1, case_insensitive,
+ Util_TableSetInt8, Util_TableGetInt8);
+ #endif
+ CHECK_SET_GET_INT(handle, CCTK_INT, 1, case_insensitive,
+ Util_TableSetInt, Util_TableGetInt);
+ assert( Util_TableQueryNKeys(handle) == 1 );
+ assert( Util_TableQueryMaxKeyLength(handle) == (int)strlen("int_x") );
+
+ /* generic scalars which are actually integers */
+ CHECK_SET_GET_GENERIC_INT(handle, CCTK_VARIABLE_INT, CCTK_INT,
+ 0, case_insensitive);
+ #ifdef CCTK_INTEGER_PRECISION_2
+ CHECK_SET_GET_GENERIC_INT(handle, CCTK_VARIABLE_INT2, CCTK_INT2,
+ 1, case_insensitive);
+ #endif
+ #ifdef CCTK_INTEGER_PRECISION_4
+ CHECK_SET_GET_GENERIC_INT(handle, CCTK_VARIABLE_INT4, CCTK_INT4,
+ 1, case_insensitive);
+ #endif
+ #ifdef CCTK_INTEGER_PRECISION_8
+ CHECK_SET_GET_GENERIC_INT(handle, CCTK_VARIABLE_INT8, CCTK_INT8,
+ 1, case_insensitive);
+ #endif
+ CHECK_SET_GET_GENERIC_INT(handle, CCTK_VARIABLE_INT, CCTK_INT,
+ 1, case_insensitive);
+ assert( Util_TableQueryNKeys(handle) == 2 );
+ assert( Util_TableQueryMaxKeyLength(handle) == (int)strlen("gint_x") );
+ assert( Util_TableDeleteKey(handle, "gint_x") == 0 );
+ assert( Util_TableQueryNKeys(handle) == 1 );
+
+ /* complex numbers */
+ CHECK_SET_GET_COMPLEX(handle, CCTK_COMPLEX, 0, case_insensitive,
+ Util_TableSetComplex, Util_TableGetComplex);
+ #ifdef CCTK_COMPLEX_PRECISION_8
+ CHECK_SET_GET_COMPLEX(handle, CCTK_COMPLEX8, 1, case_insensitive,
+ Util_TableSetComplex8, Util_TableGetComplex8);
+ #endif
+ #ifdef CCTK_COMPLEX_PRECISION_16
+ CHECK_SET_GET_COMPLEX(handle, CCTK_COMPLEX16, 1, case_insensitive,
+ Util_TableSetComplex16, Util_TableGetComplex16);
+ #endif
+ #ifdef CCTK_COMPLEX_PRECISION_32
+ CHECK_SET_GET_COMPLEX(handle, CCTK_COMPLEX32, 1, case_insensitive,
+ Util_TableSetComplex32, Util_TableGetComplex32);
+ #endif
+ CHECK_SET_GET_COMPLEX(handle, CCTK_COMPLEX, 1, case_insensitive,
+ Util_TableSetComplex, Util_TableGetComplex);
+ assert( Util_TableQueryNKeys(handle) == 2 );
+ assert( Util_TableQueryMaxKeyLength(handle) == (int)strlen("COMPlex_Z") );
+
+ /* reals */
+ CHECK_SET_GET_REAL(handle, CCTK_REAL, 0, case_insensitive,
+ Util_TableSetReal, Util_TableGetReal);
+ #ifdef CCTK_REAL_PRECISION_4
+ CHECK_SET_GET_REAL(handle, CCTK_REAL4, 1, case_insensitive,
+ Util_TableSetReal4, Util_TableGetReal4);
+ #endif
+ #ifdef CCTK_REAL_PRECISION_8
+ CHECK_SET_GET_REAL(handle, CCTK_REAL8, 1, case_insensitive,
+ Util_TableSetReal8, Util_TableGetReal8);
+ #endif
+ #ifdef CCTK_REAL_PRECISION_16
+ CHECK_SET_GET_REAL(handle, CCTK_REAL16, 1, case_insensitive,
+ Util_TableSetReal16, Util_TableGetReal16);
+ #endif
+ CHECK_SET_GET_REAL(handle, CCTK_REAL, 1, case_insensitive,
+ Util_TableSetReal, Util_TableGetReal);
+ assert( Util_TableQueryNKeys(handle) == 3 );
+ assert( Util_TableQueryMaxKeyLength(handle) == (int)strlen("COMPlex_Z") );
+
+ {
+ CCTK_INT type_code, N_elements;
+ assert( Util_TableQueryValueInfo(handle, &type_code, &N_elements, "COMPlex_Z")
+ == 1 );
+ assert( type_code == CCTK_VARIABLE_COMPLEX );
+ assert( N_elements == 1 );
+
+ assert( Util_TableQueryValueInfo(handle, &type_code, &N_elements, "pickle")
+ == 0 );
+
+ assert( Util_TableQueryValueInfo(handle, NULL, NULL, "int_x") == 1 );
+ assert( Util_TableQueryValueInfo(handle, NULL, NULL, "Int_x")
+ == (case_insensitive ? 1 : 0) );
+ assert( Util_TableQueryValueInfo(handle, NULL, NULL, "real_y")
+ == (case_insensitive ? 1 : 0) );
+ assert( Util_TableQueryValueInfo(handle, NULL, NULL, "COMPLEX_Z")
+ == (case_insensitive ? 1 : 0) );
+ }
}
#endif /* UTIL_TABLE_TEST */
@@ -3564,68 +4131,82 @@ assert( Util_TableQueryValueInfo(handle, NULL, NULL, "COMPLEX_Z")
static
void test_set_get_array(int handle)
{
-/* the comments of test_set_get() about test ordering, also apply here */
-
-/* integers */
-CHECK_SET_GET_INT_ARRAY(handle, CCTK_CHAR, 0,
- Util_TableSetCharArray, Util_TableGetCharArray);
-CHECK_SET_GET_INT_ARRAY(handle, CCTK_INT, 1,
- Util_TableSetIntArray, Util_TableGetIntArray);
-#ifdef CCTK_INTEGER_PRECISION_2
-CHECK_SET_GET_INT_ARRAY(handle, CCTK_INT2, 1,
- Util_TableSetInt2Array, Util_TableGetInt2Array);
-#endif
-#ifdef CCTK_INTEGER_PRECISION_4
-CHECK_SET_GET_INT_ARRAY(handle, CCTK_INT4, 1,
- Util_TableSetInt4Array, Util_TableGetInt4Array);
-#endif
-#ifdef CCTK_INTEGER_PRECISION_8
-CHECK_SET_GET_INT_ARRAY(handle, CCTK_INT8, 1,
- Util_TableSetInt8Array, Util_TableGetInt8Array);
-#endif
-CHECK_SET_GET_INT_ARRAY(handle, CCTK_INT, 1,
- Util_TableSetIntArray, Util_TableGetIntArray);
-
-/* reals */
-CHECK_SET_GET_REAL_ARRAY(handle, CCTK_REAL, 0,
- Util_TableSetRealArray, Util_TableGetRealArray);
-#ifdef CCTK_REAL_PRECISION_4
-CHECK_SET_GET_REAL_ARRAY(handle, CCTK_REAL4, 1,
- Util_TableSetReal4Array, Util_TableGetReal4Array);
-#endif
-#ifdef CCTK_REAL_PRECISION_8
-CHECK_SET_GET_REAL_ARRAY(handle, CCTK_REAL8, 1,
- Util_TableSetReal8Array, Util_TableGetReal8Array);
-#endif
-#ifdef CCTK_REAL_PRECISION_16
-CHECK_SET_GET_REAL_ARRAY(handle, CCTK_REAL16, 1,
- Util_TableSetReal16Array, Util_TableGetReal16Array);
-#endif
-CHECK_SET_GET_REAL_ARRAY(handle, CCTK_REAL, 1,
- Util_TableSetRealArray, Util_TableGetRealArray);
-
-/* complex numbers */
-CHECK_SET_GET_COMPLEX_ARRAY(handle, CCTK_COMPLEX, 0,
- Util_TableSetComplexArray,
- Util_TableGetComplexArray);
-#ifdef CCTK_COMPLEX_PRECISION_8
-CHECK_SET_GET_COMPLEX_ARRAY(handle, CCTK_COMPLEX8, 1,
- Util_TableSetComplex8Array,
- Util_TableGetComplex8Array);
-#endif
-#ifdef CCTK_COMPLEX_PRECISION_16
-CHECK_SET_GET_COMPLEX_ARRAY(handle, CCTK_COMPLEX16, 1,
- Util_TableSetComplex16Array,
- Util_TableGetComplex16Array);
-#endif
-#ifdef CCTK_COMPLEX_PRECISION_32
-CHECK_SET_GET_COMPLEX_ARRAY(handle, CCTK_COMPLEX32, 1,
- Util_TableSetComplex32Array,
- Util_TableGetComplex32Array);
-#endif
-CHECK_SET_GET_COMPLEX_ARRAY(handle, CCTK_COMPLEX, 1,
- Util_TableSetComplexArray,
- Util_TableGetComplexArray);
+ /* the comments of test_set_get() about test ordering, also apply here */
+
+ /* integers */
+ CHECK_SET_GET_INT_ARRAY(handle, CCTK_CHAR, 0,
+ Util_TableSetCharArray, Util_TableGetCharArray);
+ CHECK_SET_GET_INT_ARRAY(handle, CCTK_INT, 1,
+ Util_TableSetIntArray, Util_TableGetIntArray);
+ #ifdef CCTK_INTEGER_PRECISION_2
+ CHECK_SET_GET_INT_ARRAY(handle, CCTK_INT2, 1,
+ Util_TableSetInt2Array, Util_TableGetInt2Array);
+ #endif
+ #ifdef CCTK_INTEGER_PRECISION_4
+ CHECK_SET_GET_INT_ARRAY(handle, CCTK_INT4, 1,
+ Util_TableSetInt4Array, Util_TableGetInt4Array);
+ #endif
+ #ifdef CCTK_INTEGER_PRECISION_8
+ CHECK_SET_GET_INT_ARRAY(handle, CCTK_INT8, 1,
+ Util_TableSetInt8Array, Util_TableGetInt8Array);
+ #endif
+ CHECK_SET_GET_INT_ARRAY(handle, CCTK_INT, 1,
+ Util_TableSetIntArray, Util_TableGetIntArray);
+
+ /* reals */
+ CHECK_SET_GET_REAL_ARRAY(handle, CCTK_REAL, 0,
+ Util_TableSetRealArray, Util_TableGetRealArray);
+ #ifdef CCTK_REAL_PRECISION_4
+ CHECK_SET_GET_REAL_ARRAY(handle, CCTK_REAL4, 1,
+ Util_TableSetReal4Array, Util_TableGetReal4Array);
+ #endif
+ #ifdef CCTK_REAL_PRECISION_8
+ CHECK_SET_GET_REAL_ARRAY(handle, CCTK_REAL8, 1,
+ Util_TableSetReal8Array, Util_TableGetReal8Array);
+ #endif
+ #ifdef CCTK_REAL_PRECISION_16
+ CHECK_SET_GET_REAL_ARRAY(handle, CCTK_REAL16, 1,
+ Util_TableSetReal16Array, Util_TableGetReal16Array);
+ #endif
+ CHECK_SET_GET_REAL_ARRAY(handle, CCTK_REAL, 1,
+ Util_TableSetRealArray, Util_TableGetRealArray);
+
+ /* generic arrays which are actually reals */
+ CHECK_SET_GET_GENERIC_REAL_ARRAY(handle, CCTK_VARIABLE_REAL, CCTK_REAL, 0);
+ #ifdef CCTK_REAL_PRECISION_4
+ CHECK_SET_GET_GENERIC_REAL_ARRAY(handle, CCTK_VARIABLE_REAL4, CCTK_REAL4, 1);
+ #endif
+ #ifdef CCTK_REAL_PRECISION_8
+ CHECK_SET_GET_GENERIC_REAL_ARRAY(handle, CCTK_VARIABLE_REAL8, CCTK_REAL8, 1);
+ #endif
+ #ifdef CCTK_REAL_PRECISION_16
+ CHECK_SET_GET_GENERIC_REAL_ARRAY(handle,
+ CCTK_VARIABLE_REAL16, CCTK_REAL16, 1);
+ #endif
+ CHECK_SET_GET_GENERIC_REAL_ARRAY(handle, CCTK_VARIABLE_REAL, CCTK_REAL, 1);
+
+ /* complex numbers */
+ CHECK_SET_GET_COMPLEX_ARRAY(handle, CCTK_COMPLEX, 0,
+ Util_TableSetComplexArray,
+ Util_TableGetComplexArray);
+ #ifdef CCTK_COMPLEX_PRECISION_8
+ CHECK_SET_GET_COMPLEX_ARRAY(handle, CCTK_COMPLEX8, 1,
+ Util_TableSetComplex8Array,
+ Util_TableGetComplex8Array);
+ #endif
+ #ifdef CCTK_COMPLEX_PRECISION_16
+ CHECK_SET_GET_COMPLEX_ARRAY(handle, CCTK_COMPLEX16, 1,
+ Util_TableSetComplex16Array,
+ Util_TableGetComplex16Array);
+ #endif
+ #ifdef CCTK_COMPLEX_PRECISION_32
+ CHECK_SET_GET_COMPLEX_ARRAY(handle, CCTK_COMPLEX32, 1,
+ Util_TableSetComplex32Array,
+ Util_TableGetComplex32Array);
+ #endif
+ CHECK_SET_GET_COMPLEX_ARRAY(handle, CCTK_COMPLEX, 1,
+ Util_TableSetComplexArray,
+ Util_TableGetComplexArray);
}
#endif /* UTIL_TABLE_TEST */
@@ -3644,110 +4225,129 @@ CHECK_SET_GET_COMPLEX_ARRAY(handle, CCTK_COMPLEX, 1,
static
void test_iterators(int handle)
{
-int ihandle = Util_TableItCreate(handle);
-assert( ihandle >= 0 );
-assert( Util_TableItQueryTableHandle(ihandle) == handle );
-assert( Util_TableItQueryIsNonNull(ihandle) == 1);
-assert( Util_TableItQueryIsNull(ihandle) == 0);
-
-/* set up the key buffer */
- {
-int max_key_length = Util_TableQueryMaxKeyLength(handle);
-assert( max_key_length == (int)strlen("COMPlex_Z") );
- {
-const int N_key_buffer = max_key_length + 1;
-char *const key_buffer = malloc(N_key_buffer);
-assert( key_buffer != NULL );
-
-/* walk the table to verify iterator traversal */
- {
-CCTK_INT type_code, N_elements;
-
-/* REAL_y */
-assert( Util_TableItQueryKeyValueInfo(ihandle,
- N_key_buffer, key_buffer,
- &type_code, &N_elements)
- == (int)strlen("REAL_y") );
-assert( strcmp(key_buffer, "REAL_y") == 0 );
-assert( type_code == CCTK_VARIABLE_REAL );
-assert( N_elements == 1 );
-
-/* COMPlex_Z */
-type_code = 123456;
-N_elements = 54321;
-assert( Util_TableItAdvance(ihandle) == 1 );
-assert( Util_TableItQueryKeyValueInfo(ihandle,
- N_key_buffer, key_buffer,
- &type_code, &N_elements)
- == (int)strlen("COMPlex_Z") );
-assert( strcmp(key_buffer, "COMPlex_Z") == 0 );
-assert( type_code = CCTK_VARIABLE_COMPLEX );
-assert( N_elements == 1 );
-
-/* int_x */
-type_code = 123456;
-N_elements = 54321;
-assert( Util_TableItAdvance(ihandle) == 1 );
-assert( Util_TableItQueryKeyValueInfo(ihandle,
- N_key_buffer, key_buffer,
- &type_code, &N_elements)
- == (int)strlen("int_x") );
-assert( strcmp(key_buffer, "int_x") == 0 );
-assert( type_code = CCTK_VARIABLE_INT );
-assert( N_elements == 1 );
-
-/* advance past last table entry ==> "null-pointer" state */
-assert( Util_TableItAdvance(ihandle) == 0 );
-assert( Util_TableItQueryIsNull(ihandle) == 1);
-assert( Util_TableItQueryIsNonNull(ihandle) == 0);
-
-/* advance again ==> stays in "null-pointer" state */
-assert( Util_TableItAdvance(ihandle) == 0 );
-assert( Util_TableItQueryIsNull(ihandle) == 1);
-assert( Util_TableItQueryIsNonNull(ihandle) == 0);
-assert( Util_TableItQueryKeyValueInfo(ihandle,
- 0, NULL,
- NULL, NULL)
- == UTIL_ERROR_TABLE_ITERATOR_IS_NULL );
-
-/* test reset to starting point */
-assert( Util_TableItResetToStart(ihandle) == 1 );
-assert( Util_TableItQueryIsNonNull(ihandle) == 1 );
-assert( Util_TableItQueryIsNull(ihandle) == 0 );
-
-/* COMPlex_Z */
-type_code = 123456;
-N_elements = 54321;
-assert( Util_TableItAdvance(ihandle) == 1 );
-assert( Util_TableItQueryKeyValueInfo(ihandle,
- N_key_buffer, key_buffer,
- &type_code, &N_elements)
- == (int)strlen("COMPlex_Z") );
-assert( strcmp(key_buffer, "COMPlex_Z") == 0 );
-assert( type_code = CCTK_VARIABLE_COMPLEX );
-assert( N_elements == 1 );
-
-/* test reset to "null-pointer" state */
-assert( Util_TableItSetToNull(ihandle) == 0 );
-assert( Util_TableItQueryIsNull(ihandle) == 1);
-assert( Util_TableItQueryIsNonNull(ihandle) == 0);
-
-/* test set to key "REAL_y" */
-assert( Util_TableItSetToKey(ihandle, "REAL_y") == 0 );
-assert( Util_TableItQueryIsNonNull(ihandle) == 1);
-assert( Util_TableItQueryIsNull(ihandle) == 0);
-assert( Util_TableItQueryKeyValueInfo(ihandle,
- N_key_buffer, key_buffer,
- &type_code, &N_elements)
- == (int)strlen("REAL_y") );
-assert( strcmp(key_buffer, "REAL_y") == 0 );
-assert( type_code == CCTK_VARIABLE_REAL );
-assert( N_elements == 1 );
-
-free(key_buffer);
- }
- }
- }
+ const int ihandle = Util_TableItCreate(handle);
+ assert( ihandle >= 0 );
+ assert( Util_TableItQueryTableHandle(ihandle) == handle );
+ assert( Util_TableItQueryIsNonNull(ihandle) == 1);
+ assert( Util_TableItQueryIsNull(ihandle) == 0);
+
+ /* set up the key buffer */
+ {
+ const int max_key_length = Util_TableQueryMaxKeyLength(handle);
+ assert( max_key_length == (int)strlen("COMPlex_Z") );
+ {
+ const int N_key_buffer = max_key_length + 1;
+ char *const key_buffer = malloc(N_key_buffer);
+ assert( key_buffer != NULL );
+
+ /* walk the table to verify iterator traversal */
+ {
+ CCTK_INT type_code, N_elements;
+
+ /* REAL_y */
+ assert( Util_TableItQueryKeyValueInfo(ihandle,
+ N_key_buffer, key_buffer,
+ &type_code, &N_elements)
+ == (int)strlen("REAL_y") );
+ assert( strcmp(key_buffer, "REAL_y") == 0 );
+ assert( type_code == CCTK_VARIABLE_REAL );
+ assert( N_elements == 1 );
+
+ assert( Util_TableItAdvance(ihandle) == 1 );
+
+ /* COMPlex_Z */
+ type_code = 123456;
+ N_elements = 54321;
+ assert( Util_TableItQueryKeyValueInfo(ihandle,
+ N_key_buffer, key_buffer,
+ &type_code, &N_elements)
+ == (int)strlen("COMPlex_Z") );
+ assert( strcmp(key_buffer, "COMPlex_Z") == 0 );
+ assert( type_code == CCTK_VARIABLE_COMPLEX );
+ assert( N_elements == 1 );
+
+ assert( Util_TableItAdvance(ihandle) == 1 );
+
+ /* clone the iterator and check the clone */
+ {
+ const int clone_ihandle = Util_TableItClone(ihandle);
+ type_code = 123456;
+ N_elements = 54321;
+ assert( Util_TableItQueryKeyValueInfo(clone_ihandle,
+ N_key_buffer, key_buffer,
+ &type_code, &N_elements)
+ == (int)strlen("int_x") );
+ assert( strcmp(key_buffer, "int_x") == 0 );
+ assert( type_code == CCTK_VARIABLE_INT );
+ assert( N_elements == 1 );
+
+ /* int_x */
+ type_code = 123456;
+ N_elements = 54321;
+ assert( Util_TableItQueryKeyValueInfo(ihandle,
+ N_key_buffer, key_buffer,
+ &type_code, &N_elements)
+ == (int)strlen("int_x") );
+ assert( strcmp(key_buffer, "int_x") == 0 );
+ assert( type_code == CCTK_VARIABLE_INT );
+ assert( N_elements == 1 );
+
+ /* advance past last table entry ==> "null-pointer" state */
+ assert( Util_TableItAdvance(ihandle) == 0 );
+ assert( Util_TableItQueryIsNull(ihandle) == 1);
+ assert( Util_TableItQueryIsNonNull(ihandle) == 0);
+
+ /* advance again ==> stays in "null-pointer" state */
+ assert( Util_TableItAdvance(ihandle) == 0 );
+ assert( Util_TableItQueryIsNull(ihandle) == 1);
+ assert( Util_TableItQueryIsNonNull(ihandle) == 0);
+ assert( Util_TableItQueryKeyValueInfo(ihandle,
+ 0, NULL,
+ NULL, NULL)
+ == UTIL_ERROR_TABLE_ITERATOR_IS_NULL );
+
+ /* test reset to starting point */
+ assert( Util_TableItResetToStart(ihandle) == 1 );
+ assert( Util_TableItQueryIsNonNull(ihandle) == 1 );
+ assert( Util_TableItQueryIsNull(ihandle) == 0 );
+
+ /* COMPlex_Z */
+ type_code = 123456;
+ N_elements = 54321;
+ assert( Util_TableItAdvance(ihandle) == 1 );
+ assert( Util_TableItQueryKeyValueInfo(ihandle,
+ N_key_buffer, key_buffer,
+ &type_code, &N_elements)
+ == (int)strlen("COMPlex_Z") );
+ assert( strcmp(key_buffer, "COMPlex_Z") == 0 );
+ assert( type_code == CCTK_VARIABLE_COMPLEX );
+ assert( N_elements == 1 );
+
+ /* test reset to "null-pointer" state */
+ assert( Util_TableItSetToNull(ihandle) == 0 );
+ assert( Util_TableItQueryIsNull(ihandle) == 1);
+ assert( Util_TableItQueryIsNonNull(ihandle) == 0);
+
+ /* test set to key "REAL_y" */
+ assert( Util_TableItSetToKey(ihandle, "REAL_y") == 0 );
+ assert( Util_TableItQueryIsNonNull(ihandle) == 1);
+ assert( Util_TableItQueryIsNull(ihandle) == 0);
+ assert( Util_TableItQueryKeyValueInfo(ihandle,
+ N_key_buffer, key_buffer,
+ &type_code, &N_elements)
+ == (int)strlen("REAL_y") );
+ assert( strcmp(key_buffer, "REAL_y") == 0 );
+ assert( type_code == CCTK_VARIABLE_REAL );
+ assert( N_elements == 1 );
+
+ assert( Util_TableItDestroy(ihandle) == 0 );
+ assert( Util_TableItDestroy(clone_ihandle) == 0 );
+
+ free(key_buffer);
+ }
+ }
+ }
+ }
}
/******************************************************************************/
@@ -3762,124 +4362,124 @@ free(key_buffer);
* specific ordering of table elements returned by an iterator.
*/
static
- void test_delete_key(int handle, bool case_insensitive)
+ void test_delete_table_entry(int handle, bool case_insensitive)
{
-/* set up the key buffer */
-int max_key_length = Util_TableQueryMaxKeyLength(handle);
-assert( max_key_length == (int)strlen("COMPlex_Z") );
- {
-const int N_key_buffer = max_key_length + 1;
-char *const key_buffer = malloc(N_key_buffer);
-assert( key_buffer != NULL );
-
-/*
- * delete the starting table entry "REAL_y"
- * (this is a special case in the implementation)
- */
-
-assert( Util_TableQueryNKeys(handle) == 3 );
-assert( Util_TableDeleteKey(handle,
- case_insensitive ? "rEAL_y" : "REAL_y")
- == 0 );
-assert( Util_TableQueryNKeys(handle) == 2 );
-
-/* walk the table again to verify remaining keys {"COMPlex_Z", "int_x"} */
-assert( Util_TableQueryNKeys(handle) == 2 );
- {
-int ihandle = Util_TableItCreate(handle);
-assert( ihandle >= 0 );
-assert( Util_TableItQueryTableHandle(ihandle) == handle );
-assert( Util_TableItQueryIsNonNull(ihandle) == 1);
-assert( Util_TableItQueryIsNull(ihandle) == 0);
-
-/* COMPlex_Z */
- {
-CCTK_INT type_code = 123456;
-CCTK_INT N_elements = 54321;
-assert( Util_TableItQueryKeyValueInfo(ihandle,
- N_key_buffer, key_buffer,
- &type_code, &N_elements)
- == (int)strlen("COMPlex_Z") );
-assert( strcmp(key_buffer, "COMPlex_Z") == 0 );
-assert( type_code = CCTK_VARIABLE_COMPLEX );
-assert( N_elements == 1 );
-
-/* int_x */
-type_code = 123456;
-N_elements = 54321;
-assert( Util_TableItAdvance(ihandle) == 1 );
-assert( Util_TableItQueryKeyValueInfo(ihandle,
- N_key_buffer, key_buffer,
- &type_code, &N_elements)
- == (int)strlen("int_x") );
-assert( strcmp(key_buffer, "int_x") == 0 );
-assert( type_code = CCTK_VARIABLE_INT );
-assert( N_elements == 1 );
-
-/* advance past last table entry ==> "null-pointer" state */
-assert( Util_TableItAdvance(ihandle) == 0 );
-assert( Util_TableItQueryIsNull(ihandle) == 1);
-assert( Util_TableItQueryIsNonNull(ihandle) == 0);
-
-/* delete the last key "int_x" */
-assert( Util_TableDeleteKey(handle,
- case_insensitive ? "INT_X" : "int_x")
- == 0 );
-
-/* walk the table again to verify remaining key {"COMPlex_Z"} */
-assert( Util_TableQueryNKeys(handle) == 1 );
- {
-int ihandle2 = Util_TableItCreate(handle);
-assert( ihandle2 >= 0 );
-assert( Util_TableItQueryTableHandle(ihandle2) == handle );
-assert( Util_TableItQueryIsNonNull(ihandle2) == 1);
-assert( Util_TableItQueryIsNull(ihandle2) == 0);
-
-/* COMPlex_Z */
-type_code = 123456;
-N_elements = 54321;
-assert( Util_TableItQueryKeyValueInfo(ihandle2,
- N_key_buffer, key_buffer,
- &type_code, &N_elements)
- == (int)strlen("COMPlex_Z") );
-assert( strcmp(key_buffer, "COMPlex_Z") == 0 );
-assert( type_code = CCTK_VARIABLE_COMPLEX );
-assert( N_elements == 1 );
-
-/* advance past last table entry ==> "null-pointer" state */
-assert( Util_TableItAdvance(ihandle2) == 0 );
-assert( Util_TableItQueryIsNull(ihandle2) == 1);
-assert( Util_TableItQueryIsNonNull(ihandle2) == 0);
-
-/* delete the last key "COMPlex_Z" */
-assert( Util_TableQueryNKeys(handle) == 1 );
-assert( Util_TableDeleteKey(handle,
- case_insensitive ? "INT_X" : "int_x")
- == UTIL_ERROR_TABLE_NO_SUCH_KEY );
-assert( Util_TableQueryNKeys(handle) == 1 );
-assert( Util_TableDeleteKey(handle,
- case_insensitive ? "compLEX_z" : "COMPlex_Z")
- == 0 );
-assert( Util_TableQueryNKeys(handle) == 0 );
-
- {
-/* check that table is indeed now empty */
-int ihandle3 = Util_TableItCreate(handle);
-assert( ihandle3 >= 0 );
-assert( Util_TableItQueryIsNull(ihandle3) == 1);
-assert( Util_TableItQueryIsNonNull(ihandle3) == 0);
-
-/* clean up our iterators */
-assert( Util_TableItDestroy(ihandle2) == 0 );
-assert( Util_TableItDestroy(42) == UTIL_ERROR_BAD_HANDLE );
-assert( Util_TableItDestroy(ihandle3) == 0 );
-assert( Util_TableItDestroy(ihandle) == 0 );
-free(key_buffer);
- }
- }
- }
- }
- }
+ /* set up the key buffer */
+ const int max_key_length = Util_TableQueryMaxKeyLength(handle);
+ assert( max_key_length == (int)strlen("COMPlex_Z") );
+ {
+ const int N_key_buffer = max_key_length + 1;
+ char *const key_buffer = malloc(N_key_buffer);
+ assert( key_buffer != NULL );
+
+ /*
+ * delete the starting table entry "REAL_y"
+ * (this is a special case in the implementation)
+ */
+
+ assert( Util_TableQueryNKeys(handle) == 3 );
+ assert( Util_TableDeleteKey(handle,
+ case_insensitive ? "rEAL_y" : "REAL_y")
+ == 0 );
+ assert( Util_TableQueryNKeys(handle) == 2 );
+
+ /* walk the table again to verify remaining keys {"COMPlex_Z", "int_x"} */
+ assert( Util_TableQueryNKeys(handle) == 2 );
+ {
+ int ihandle = Util_TableItCreate(handle);
+ assert( ihandle >= 0 );
+ assert( Util_TableItQueryTableHandle(ihandle) == handle );
+ assert( Util_TableItQueryIsNonNull(ihandle) == 1);
+ assert( Util_TableItQueryIsNull(ihandle) == 0);
+
+ /* COMPlex_Z */
+ {
+ CCTK_INT type_code = 123456;
+ CCTK_INT N_elements = 54321;
+ assert( Util_TableItQueryKeyValueInfo(ihandle,
+ N_key_buffer, key_buffer,
+ &type_code, &N_elements)
+ == (int)strlen("COMPlex_Z") );
+ assert( strcmp(key_buffer, "COMPlex_Z") == 0 );
+ assert( type_code == CCTK_VARIABLE_COMPLEX );
+ assert( N_elements == 1 );
+
+ /* int_x */
+ type_code = 123456;
+ N_elements = 54321;
+ assert( Util_TableItAdvance(ihandle) == 1 );
+ assert( Util_TableItQueryKeyValueInfo(ihandle,
+ N_key_buffer, key_buffer,
+ &type_code, &N_elements)
+ == (int)strlen("int_x") );
+ assert( strcmp(key_buffer, "int_x") == 0 );
+ assert( type_code == CCTK_VARIABLE_INT );
+ assert( N_elements == 1 );
+
+ /* advance past last table entry ==> "null-pointer" state */
+ assert( Util_TableItAdvance(ihandle) == 0 );
+ assert( Util_TableItQueryIsNull(ihandle) == 1);
+ assert( Util_TableItQueryIsNonNull(ihandle) == 0);
+
+ /* delete the last key "int_x" */
+ assert( Util_TableDeleteKey(handle,
+ case_insensitive ? "INT_X" : "int_x")
+ == 0 );
+
+ /* walk the table again to verify remaining key {"COMPlex_Z"} */
+ assert( Util_TableQueryNKeys(handle) == 1 );
+ {
+ int ihandle2 = Util_TableItCreate(handle);
+ assert( ihandle2 >= 0 );
+ assert( Util_TableItQueryTableHandle(ihandle2) == handle );
+ assert( Util_TableItQueryIsNonNull(ihandle2) == 1);
+ assert( Util_TableItQueryIsNull(ihandle2) == 0);
+
+ /* COMPlex_Z */
+ type_code = 123456;
+ N_elements = 54321;
+ assert( Util_TableItQueryKeyValueInfo(ihandle2,
+ N_key_buffer, key_buffer,
+ &type_code, &N_elements)
+ == (int)strlen("COMPlex_Z") );
+ assert( strcmp(key_buffer, "COMPlex_Z") == 0 );
+ assert( type_code == CCTK_VARIABLE_COMPLEX );
+ assert( N_elements == 1 );
+
+ /* advance past last table entry ==> "null-pointer" state */
+ assert( Util_TableItAdvance(ihandle2) == 0 );
+ assert( Util_TableItQueryIsNull(ihandle2) == 1);
+ assert( Util_TableItQueryIsNonNull(ihandle2) == 0);
+
+ /* delete the last key "COMPlex_Z" */
+ assert( Util_TableQueryNKeys(handle) == 1 );
+ assert( Util_TableDeleteKey(handle,
+ case_insensitive ? "INT_X" : "int_x")
+ == UTIL_ERROR_TABLE_NO_SUCH_KEY );
+ assert( Util_TableQueryNKeys(handle) == 1 );
+ assert( Util_TableDeleteKey(handle,
+ case_insensitive ? "compLEX_z" : "COMPlex_Z")
+ == 0 );
+ assert( Util_TableQueryNKeys(handle) == 0 );
+
+ {
+ /* check that table is indeed now empty */
+ int ihandle3 = Util_TableItCreate(handle);
+ assert( ihandle3 >= 0 );
+ assert( Util_TableItQueryIsNull(ihandle3) == 1);
+ assert( Util_TableItQueryIsNonNull(ihandle3) == 0);
+
+ /* clean up our iterators */
+ assert( Util_TableItDestroy(ihandle2) == 0 );
+ assert( Util_TableItDestroy(42) == UTIL_ERROR_BAD_HANDLE );
+ assert( Util_TableItDestroy(ihandle3) == 0 );
+ assert( Util_TableItDestroy(ihandle) == 0 );
+ free(key_buffer);
+ }
+ }
+ }
+ }
+ }
}
#endif /* UTIL_TABLE_TEST */
@@ -3899,52 +4499,240 @@ free(key_buffer);
static
int test_set_create_from_string(void)
{
+ /*
+ * Test an empty string
+ */
+ const int handle = Util_TableCreateFromString("");
+ assert( Util_TableQueryNKeys(handle) == 0 );
+
+ /*
+ * Test some error cases
+ */
+ assert( Util_TableSetFromString(handle, "foo" ) == UTIL_ERROR_BAD_INPUT );
+ assert( Util_TableSetFromString(handle, "foo/" ) == UTIL_ERROR_BAD_INPUT );
+ assert( Util_TableSetFromString(handle, "foo;=12" )
+ == UTIL_ERROR_TABLE_BAD_KEY );
+ assert( Util_TableSetFromString(handle, "foo =12" )
+ == UTIL_ERROR_TABLE_BAD_KEY );
+ assert( Util_TableSetFromString(handle, "foo/=12" )
+ == UTIL_ERROR_TABLE_BAD_KEY );
+ assert( Util_TableSetFromString(handle, "foo= 12") == UTIL_ERROR_BAD_INPUT );
+ assert( Util_TableCreateFromString("foo" ) == UTIL_ERROR_BAD_INPUT );
+ assert( Util_TableCreateFromString("foo/" ) == UTIL_ERROR_BAD_INPUT );
+ assert( Util_TableCreateFromString("foo/=12" ) == UTIL_ERROR_TABLE_BAD_KEY );
+ assert( Util_TableCreateFromString("foo= 12") == UTIL_ERROR_BAD_INPUT );
+
+ /*
+ * Test some "good" strings
+ */
+ {
+ const int handle2
+ = Util_TableCreateFromString(" ij=42 real1=3.5; real_e=2.75 ");
+ assert( handle2 >= 0 );
+ assert( Util_TableQueryFlags(handle2) == UTIL_TABLE_FLAGS_CASE_INSENSITIVE );
+ assert( Util_TableQueryNKeys(handle2) == 3 );
+ check_table_contents(handle2, true);
+
+ {
+ const int handle3 = Util_TableCreate(UTIL_TABLE_FLAGS_DEFAULT);
+ assert( Util_TableSetFromString(handle3, "ij=42 real1=3.5;") == 2);
+ assert( Util_TableQueryNKeys(handle3) == 2 );
+ assert( Util_TableSetFromString(handle3, "real_e=2.75") == 1);
+ assert( Util_TableQueryNKeys(handle3) == 3 );
+ check_table_contents(handle3, true);
+
+ assert( Util_TableDestroy(handle3) == 0 );
+
+ return handle2;
+ }
+ }
+}
+#endif /* UTIL_TABLE_TEST */
+
+/******************************************************************************/
+
+#ifdef UTIL_TABLE_TEST
/*
- * Test an empty string
+ * This function tests Util_Table{Set,Get}String()
*/
-int handle = Util_TableCreateFromString("");
-assert( Util_TableQueryNKeys(handle) == 0 );
+static
+ void test_set_get_string(int handle, bool case_insensitive)
+{
+ assert( Util_TableSetString(handle, "Germany", "AEI") == 0 );
+ assert( Util_TableSetString(handle, "Golm", "AEI") == 1 );
+
+ {
+ CCTK_INT type_code, N_elements;
+ assert( Util_TableQueryValueInfo(handle,
+ &type_code, &N_elements,
+ case_insensitive ? "aei" : "AEI") == 1 );
+ assert( type_code == CCTK_VARIABLE_CHAR );
+ assert( N_elements == (int)strlen("Golm") );
+
+ {
+ const int N_buffer = N_elements+1;
+ char *const buffer = (char *) malloc(N_buffer);
+ assert( buffer != NULL );
+ assert( Util_TableGetCharArray(handle,
+ N_buffer, buffer,
+ "AEI") == (int)strlen("Golm") );
+ assert( Util_TableGetString(handle,
+ 0, NULL,
+ "AEI") == (int)strlen("Golm") );
+ assert( Util_TableGetString(handle,
+ N_buffer, buffer,
+ case_insensitive ? "aEI" : "AEI")
+ == (int)strlen("Golm") );
+ assert( strcmp(buffer, "Golm") == 0 );
+
+ /* check getting string longer than buffer */
+ assert( Util_TableSetString(handle, "Max-Planck", "famous") == 0 );
+ assert( Util_TableGetString(handle,
+ N_buffer, buffer,
+ case_insensitive ? "FAMouS" : "famous")
+ == UTIL_ERROR_TABLE_STRING_TRUNCATED );
+ assert( strcmp(buffer, "Max-") == 0 );
+ }
+ }
+}
+#endif /* UTIL_TABLE_TEST */
+
+/******************************************************************************/
+#ifdef UTIL_TABLE_TEST
/*
- * Test some error cases
+ * This function tests cloning a table. We assume that on entry the
+ * table contains the 3 keys
+ * real_e = 2.75
+ * real1 = 3.5
+ * ij = 42
+ * in that order.
*/
-assert( Util_TableSetFromString(handle, "foo" ) == UTIL_ERROR_BAD_INPUT );
-assert( Util_TableSetFromString(handle, "foo/" ) == UTIL_ERROR_BAD_INPUT );
-assert( Util_TableSetFromString(handle, "foo;=12" )
- == UTIL_ERROR_TABLE_BAD_KEY );
-assert( Util_TableSetFromString(handle, "foo =12" )
- == UTIL_ERROR_TABLE_BAD_KEY );
-assert( Util_TableSetFromString(handle, "foo/=12" )
- == UTIL_ERROR_TABLE_BAD_KEY );
-assert( Util_TableSetFromString(handle, "foo= 12") == UTIL_ERROR_BAD_INPUT );
-assert( Util_TableCreateFromString("foo" ) == UTIL_ERROR_BAD_INPUT );
-assert( Util_TableCreateFromString("foo/" ) == UTIL_ERROR_BAD_INPUT );
-assert( Util_TableCreateFromString("foo/=12" ) == UTIL_ERROR_TABLE_BAD_KEY );
-assert( Util_TableCreateFromString("foo= 12") == UTIL_ERROR_BAD_INPUT );
+void test_clone(int handle)
+{
+ check_table_contents(handle, true); /* entry assumption */
+ {
+ const int clone_handle = Util_TableClone(handle);
+
+ /* make sure we didn't modify the table that we cloned */
+ check_table_contents(handle, true);
+
+ /* check the clone */
+ check_table_contents(clone_handle, false);
+
+ /*
+ * check that the tables are now distinct by
+ * changing each of them and checking that the other is unchanged
+ */
+ assert( Util_TableSetInt(handle, 105, "universal number") == 0 );
+ check_table_contents(clone_handle, false);
+ assert( Util_TableDeleteKey(handle, "universal number") == 0 );
+
+ assert( Util_TableSetInt(clone_handle, 105, "universal number #2") == 0 );
+ check_table_contents(handle, true);
+ assert( Util_TableDeleteKey(clone_handle, "universal number #2") == 0 );
+
+ assert( Util_TableDestroy(clone_handle) == 0 );
+ }
+}
+#endif /* UTIL_TABLE_TEST */
+/******************************************************************************/
+
+#ifdef UTIL_TABLE_TEST
/*
- * Test some "good" strings
+ * This function does a sequence of assert() calls to verify that
+ * a table contains the 3 keys
+ * real_e = 2.75
+ * real1 = 3.5
+ * ij = 42
+ * in a specified order.
+ *
+ * Arguments:
+ * order_up_flag = true --> check for the order {real_e,real1,ij}
+ * false --> check for the order {ij,real1,real_e}
+ *
+ * Bugs:
+ * Having to test for a specific order is a kludge.
*/
+static
+ void check_table_contents(int handle, bool order_up_flag)
+{
+ assert( Util_TableQueryNKeys(handle) == 3 );
+
+ /* set up the key buffer */
+ {
+ const int max_key_length = Util_TableQueryMaxKeyLength(handle);
+ assert( max_key_length == (int)strlen("real_e") );
+ {
+ const int N_key_buffer = max_key_length + 1;
+ char *const key_buffer = malloc(N_key_buffer);
+ assert( key_buffer != NULL );
+
+ /* walk through the table to verify contents in the right order */
+ {
+ const int ihandle = Util_TableItCreate(handle);
+ if (order_up_flag)
{
-int handle2 = Util_TableCreateFromString(" ij=42 real1=3.5; real_e=2.75 ");
-assert( handle2 >= 0 );
-assert( Util_TableQueryFlags(handle2) == UTIL_TABLE_FLAGS_CASE_INSENSITIVE );
-assert( Util_TableQueryNKeys(handle2) == 3 );
-check_table_contents(handle2);
-
+ check_table_contents_real_e(handle,ihandle);
+ assert( Util_TableItAdvance(ihandle) == 1 );
+ check_table_contents_real1(handle,ihandle);
+ assert( Util_TableItAdvance(ihandle) == 1 );
+ check_table_contents_ij(handle, ihandle);
+ }
+ else
{
-int handle3 = Util_TableCreate(UTIL_TABLE_FLAGS_DEFAULT);
-assert( Util_TableSetFromString(handle3, "ij=42 real1=3.5;") == 2);
-assert( Util_TableQueryNKeys(handle3) == 2 );
-assert( Util_TableSetFromString(handle3, "real_e=2.75") == 1);
-assert( Util_TableQueryNKeys(handle3) == 3 );
-check_table_contents(handle3);
+ check_table_contents_ij(handle, ihandle);
+ assert( Util_TableItAdvance(ihandle) == 1 );
+ check_table_contents_real1(handle,ihandle);
+ assert( Util_TableItAdvance(ihandle) == 1 );
+ check_table_contents_real_e(handle,ihandle);
+ }
+ assert( Util_TableItAdvance(ihandle) == 0 );
+ assert(Util_TableItDestroy(ihandle) == 0 );
+ }
+ }
+ }
+}
+#endif /* UTIL_TABLE_TEST */
-assert( Util_TableDestroy(handle3) == 0 );
+/******************************************************************************/
-return handle2;
- }
- }
+#ifdef UTIL_TABLE_TEST
+/*
+ * This function does a sequence of assert() calls to verify that
+ * the longest key in a table has the length of "real_e", and that
+ * a table iterator points to the key ij = 42 .
+ */
+static
+ void check_table_contents_ij(int handle, int ihandle)
+{
+ /* set up the key buffer */
+ const int max_key_length = Util_TableQueryMaxKeyLength(handle);
+ assert( max_key_length == (int)strlen("real_e") );
+ {
+ const int N_key_buffer = max_key_length + 1;
+ char *const key_buffer = malloc(N_key_buffer);
+ assert( key_buffer != NULL );
+
+ /* check ij = 42 */
+ {
+ int type_code = 123456;
+ int N_elements = 54321;
+ assert( Util_TableItQueryKeyValueInfo(ihandle,
+ N_key_buffer, key_buffer,
+ &type_code, &N_elements)
+ == (int)strlen("ij") );
+ assert( strcmp(key_buffer, "ij") == 0 );
+ assert( type_code == CCTK_VARIABLE_INT );
+ assert( N_elements == 1 );
+ {
+ CCTK_INT value_int;
+ assert( Util_TableGetInt(handle, &value_int, "ij") == 1 );
+ assert( value_int == 42 );
+ }
+ }
+ }
}
#endif /* UTIL_TABLE_TEST */
@@ -3952,53 +4740,94 @@ return handle2;
#ifdef UTIL_TABLE_TEST
/*
- * This function tests Util_Table{Set,Get}String()
+ * This function does a sequence of assert() calls to verify that
+ * the longest key in a table has the length of "real_e", and that
+ * a table iterator points to the key real1 = 3.5 . (N.b. 3.5 is
+ * assumed to be exactly representable as a floating point number.)
*/
static
- void test_set_get_string(int handle, bool case_insensitive)
+ void check_table_contents_real1(int handle, int ihandle)
{
-assert( Util_TableSetString(handle, "Germany", "AEI") == 0 );
-assert( Util_TableSetString(handle, "Golm", "AEI") == 1 );
-
- {
-CCTK_INT type_code, N_elements;
-assert( Util_TableQueryValueInfo(handle,
- &type_code, &N_elements,
- case_insensitive ? "aei" : "AEI") == 1 );
-assert( type_code = CCTK_VARIABLE_CHAR );
-assert( N_elements = (int)strlen("Golm") );
-
- {
-const int N_buffer = N_elements+1;
-char *const buffer = (char *) malloc(N_buffer);
-assert( buffer != NULL );
-assert( Util_TableGetCharArray(handle,
- N_buffer, buffer,
- "AEI") == (int)strlen("Golm") );
-assert( Util_TableGetString(handle,
- 0, NULL,
- "AEI") == (int)strlen("Golm") );
-assert( Util_TableGetString(handle,
- N_buffer, buffer,
- case_insensitive ? "aEI" : "AEI")
- == (int)strlen("Golm") );
-assert( strcmp(buffer, "Golm") == 0 );
-
-/* check getting string longer than buffer */
-assert( Util_TableSetString(handle, "Max-Planck", "famous") == 0 );
-type_code = 123;
-N_elements = 456;
-assert( Util_TableQueryValueInfo(handle,
- &type_code, &N_elements,
- case_insensitive ? "aei" : "AEI") == 1 );
-assert( type_code = CCTK_VARIABLE_CHAR );
-assert( N_elements = (int)strlen("Max-Planck") );
-assert( Util_TableGetString(handle,
- N_buffer, buffer,
- case_insensitive ? "FAMouS" : "famous")
- == UTIL_ERROR_TABLE_STRING_TRUNCATED );
-assert( strcmp(buffer, "Max-") == 0 );
- }
- }
+ /* set up the key buffer */
+ const int max_key_length = Util_TableQueryMaxKeyLength(handle);
+ assert( max_key_length == (int)strlen("real_e") );
+ {
+ const int N_key_buffer = max_key_length + 1;
+ char *const key_buffer = malloc(N_key_buffer);
+ assert( key_buffer != NULL );
+
+ /* check real1 = 3.5 */
+ {
+ int type_code = 123456;
+ int N_elements = 54321;
+ assert( Util_TableItQueryKeyValueInfo(ihandle,
+ N_key_buffer, key_buffer,
+ &type_code, &N_elements)
+ == (int)strlen("real1") );
+ assert( strcmp(key_buffer, "real1") == 0 );
+ assert( type_code == CCTK_VARIABLE_REAL );
+ assert( N_elements == 1 );
+ {
+ CCTK_REAL value_real;
+ assert( Util_TableGetReal(handle, &value_real, key_buffer) == 1 );
+ assert( value_real == 3.5 );
+ }
+ }
+ }
+}
+#endif /* UTIL_TABLE_TEST */
+
+/******************************************************************************/
+
+#ifdef UTIL_TABLE_TEST
+/*
+ * This function does a sequence of assert() calls to verify that
+ * the longest key in a table has the length of "real_e", and that
+ * a table iterator points to the key real_e = 2.75 . (N.b. 2.75 is
+ * assumed to be exactly representable as a floating point number.)
+ */
+static
+ void check_table_contents_real_e(int handle, int ihandle)
+{
+ /* set up the key buffer */
+ const int max_key_length = Util_TableQueryMaxKeyLength(handle);
+ assert( max_key_length == (int)strlen("real_e") );
+ {
+ const int N_key_buffer = max_key_length + 1;
+ char *const key_buffer = malloc(N_key_buffer);
+ assert( key_buffer != NULL );
+
+ /* check real_e = 2.75 */
+ {
+ int type_code = 123456;
+ int N_elements = 54321;
+ assert( Util_TableItQueryKeyValueInfo(ihandle,
+ N_key_buffer, key_buffer,
+ &type_code, &N_elements)
+ == (int)strlen("real_e") );
+ assert( strcmp(key_buffer, "real_e") == 0 );
+ assert( type_code == CCTK_VARIABLE_REAL );
+ assert( N_elements == 1 );
+ {
+ CCTK_REAL value_real;
+ assert( Util_TableGetReal(handle, &value_real, key_buffer) == 1 );
+ assert( value_real == 2.75 );
+
+ value_real = 314159.271828;
+ assert( Util_TableGetGeneric(handle,
+ CCTK_VARIABLE_REAL, (void *) &value_real,
+ key_buffer)
+ == 1 );
+ assert( value_real == 2.75 );
+
+ value_real = 314159.271828;
+ assert( Util_TableGetGenericArray(handle,
+ CCTK_VARIABLE_REAL, 1, (void *) &value_real,
+ key_buffer)
+ == 1 );
+ assert( value_real == 2.75 );
+ }
+ }
+ }
}
#endif /* UTIL_TABLE_TEST */