diff options
author | Arnold D. Robbins <arnold@skeeve.com> | 2012-07-11 21:26:37 +0300 |
---|---|---|
committer | Arnold D. Robbins <arnold@skeeve.com> | 2012-07-11 21:26:37 +0300 |
commit | 6d1724214a95330b63a6a557f89fb9b40b4a521f (patch) | |
tree | 829b2da90fcfdd4193beaa187c3325a861706a3b | |
parent | e33b672ff4ab1b7469355a79eaf4c4740f412e45 (diff) | |
download | egawk-6d1724214a95330b63a6a557f89fb9b40b4a521f.tar.gz egawk-6d1724214a95330b63a6a557f89fb9b40b4a521f.tar.bz2 egawk-6d1724214a95330b63a6a557f89fb9b40b4a521f.zip |
API clean up and require strings to be malloced.
-rw-r--r-- | ChangeLog | 27 | ||||
-rw-r--r-- | extension/ChangeLog | 11 | ||||
-rw-r--r-- | extension/filefuncs.c | 10 | ||||
-rw-r--r-- | extension/fork.c | 2 | ||||
-rw-r--r-- | extension/ordchr.c | 2 | ||||
-rw-r--r-- | extension/readfile.c | 4 | ||||
-rw-r--r-- | extension/rwarray.c | 4 | ||||
-rw-r--r-- | extension/testext.c | 28 | ||||
-rw-r--r-- | gawkapi.c | 128 | ||||
-rw-r--r-- | gawkapi.h | 179 |
10 files changed, 284 insertions, 111 deletions
@@ -1,3 +1,30 @@ +2012-07-11 Arnold D. Robbins <arnold@skeeve.com> + + Lots of API work. + + * gawkapi.h: Function pointer members renamed api_XXXX and + macros adjusted. More documentation. + (awk_valtype_t): New AWK_SCALAR enum for scalar cookies. + (awk_scalar_t): New type. + (awk_value_t): New member scalar_cookie. + (api_sym_update_scalar): New API function. + (erealloc): New macro. + (make_const_string): New macro, renamed from dup_string. + (make_malloced_string): New macro, renamed from make_string. + (make_null_string): New inline function. + + * gawkapi.c (awk_value_to_node): Assume that string values came + from malloc. + (node_to_awk_value): Handle AWK_SCALAR. + (api_sym_update): Ditto. + (api_sym_update_scalar): New routine. + (api_get_array_element): Return false if the element doesn't exist. + Always unref the subscript. + (remove_element): New helper routine. + (api_del_array_element): Use it. + (api_release_flattened_array): Ditto. + (api_impl): Add the new routine. + 2012-07-11 Andrew J. Schorr <aschorr@telemetry-investments.com> * gawkapi.c (api_sym_update): Allow val_type to be AWK_UNDEFINED diff --git a/extension/ChangeLog b/extension/ChangeLog index 7e61fc54..be315619 100644 --- a/extension/ChangeLog +++ b/extension/ChangeLog @@ -1,3 +1,14 @@ +2012-07-11 Arnold D. Robbins <arnold@skeeve.com> + + * filefuncs.c (array_set, do_stat): Use make_const_string. + * fork.c (array_set_numeric): Ditto. + * ordchr.c (do_chr): Ditto. + * readfile.c (do_readfile): Use make_null_string, make_malloced_string. + * rwarray.c (read_elem): Ditto. + * testext.c (valrep2str): Add case for AWK_SCALAR. + (test_array_elem): Duplicate strings coming from gawk before passing + them back in. + 2012-07-09 Arnold D. Robbins <arnold@skeeve.com> * filefuncs.c (do_readfile): Return "" and set ERRNO on error diff --git a/extension/filefuncs.c b/extension/filefuncs.c index 32a3cee6..74af8b1b 100644 --- a/extension/filefuncs.c +++ b/extension/filefuncs.c @@ -214,7 +214,7 @@ array_set(awk_array_t array, const char *sub, awk_value_t *value) awk_value_t index; set_array_element(array, - make_string(sub, strlen(sub), & index), + make_const_string(sub, strlen(sub), & index), value); } @@ -292,7 +292,7 @@ do_stat(int nargs, awk_value_t *result) } /* fill in the array */ - array_set(array, "name", make_string(name, file_param.str_value.len, &tmp)); + array_set(array, "name", make_const_string(name, file_param.str_value.len, &tmp)); array_set_numeric(array, "dev", sbuf.st_dev); array_set_numeric(array, "ino", sbuf.st_ino); array_set_numeric(array, "mode", sbuf.st_mode); @@ -317,7 +317,7 @@ do_stat(int nargs, awk_value_t *result) #endif /* HAVE_ST_BLKSIZE */ pmode = format_mode(sbuf.st_mode); - array_set(array, "pmode", make_string(pmode, strlen(pmode), & tmp)); + array_set(array, "pmode", make_const_string(pmode, strlen(pmode), & tmp)); /* for symbolic links, add a linkval field */ if (S_ISLNK(sbuf.st_mode)) { @@ -326,7 +326,7 @@ do_stat(int nargs, awk_value_t *result) if ((buf = read_symlink(name, sbuf.st_size, & linksize)) != NULL) - array_set(array, "linkval", make_string(buf, linksize, & tmp)); + array_set(array, "linkval", make_malloced_string(buf, linksize, & tmp)); else warning(ext_id, "stat: unable to read symbolic link `%s'", name); } @@ -340,7 +340,7 @@ do_stat(int nargs, awk_value_t *result) } } - array_set(array, "type", make_string(type, strlen(type), &tmp)); + array_set(array, "type", make_const_string(type, strlen(type), &tmp)); ret = 1; /* success */ diff --git a/extension/fork.c b/extension/fork.c index efad17eb..84232663 100644 --- a/extension/fork.c +++ b/extension/fork.c @@ -53,7 +53,7 @@ array_set_numeric(awk_array_t array, const char *sub, double num) awk_value_t index, value; set_array_element(array, - make_string(sub, strlen(sub), & index), + make_const_string(sub, strlen(sub), & index), make_number(num, & value)); } diff --git a/extension/ordchr.c b/extension/ordchr.c index 8d7eac8f..3ab0f872 100644 --- a/extension/ordchr.c +++ b/extension/ordchr.c @@ -103,7 +103,7 @@ do_chr(int nargs, awk_value_t *result) } /* Set the return value */ - return dup_string(str, 1, result); + return make_const_string(str, 1, result); } static awk_ext_func_t func_table[] = { diff --git a/extension/readfile.c b/extension/readfile.c index 56bdcbc3..1b6772fe 100644 --- a/extension/readfile.c +++ b/extension/readfile.c @@ -65,7 +65,7 @@ do_readfile(int nargs, awk_value_t *result) int fd; assert(result != NULL); - make_string("", 0, result); /* default return value */ + make_null_string(result); /* default return value */ if (do_lint && nargs > 1) lintwarn(ext_id, "readfile: called with too many arguments"); @@ -98,7 +98,7 @@ do_readfile(int nargs, awk_value_t *result) } close(fd); - make_string(text, sbuf.st_size, result); + make_malloced_string(text, sbuf.st_size, result); goto done; } else if (do_lint) lintwarn(ext_id, "readfile: called with no arguments"); diff --git a/extension/rwarray.c b/extension/rwarray.c index a63fa3d2..64c501dd 100644 --- a/extension/rwarray.c +++ b/extension/rwarray.c @@ -394,9 +394,9 @@ read_elem(int fd, awk_element_t *element) if (read(fd, buffer, index_len) != (ssize_t) index_len) { return 0; } - make_string(buffer, index_len, & element->index); + make_const_string(buffer, index_len, & element->index); } else { - make_string("", 0, & element->index); + make_null_string(& element->index); } if (! read_value(fd, & element->value)) diff --git a/extension/testext.c b/extension/testext.c index e54055cc..8dac1c2b 100644 --- a/extension/testext.c +++ b/extension/testext.c @@ -59,6 +59,9 @@ valrep2str(const awk_value_t *value) case AWK_ARRAY: strcpy(buf, "<array>"); break; + case AWK_SCALAR: + strcpy(buf, "<scalar>"); + break; case AWK_STRING: if (value->str_value.len < size) size = value->str_value.len; @@ -334,7 +337,7 @@ BEGIN { static awk_value_t * test_array_elem(int nargs, awk_value_t *result) { - awk_value_t array, index, value; + awk_value_t array, index, index2, value; make_number(0.0, result); /* default return until full success */ @@ -354,7 +357,8 @@ test_array_elem(int nargs, awk_value_t *result) printf("test_array_elem: get_argument 1 (index) failed\n"); goto out; } - if (! get_array_element(array.array_cookie, & index, AWK_UNDEFINED, & value)) { + (void) make_const_string(index.str_value.str, index.str_value.len, & index2); + if (! get_array_element(array.array_cookie, & index2, AWK_UNDEFINED, & value)) { printf("test_array_elem: get_array_element failed\n"); goto out; } @@ -365,28 +369,29 @@ test_array_elem(int nargs, awk_value_t *result) /* change the element - "3" */ (void) make_number(42.0, & value); - if (! set_array_element(array.array_cookie, & index, & value)) { + (void) make_const_string(index.str_value.str, index.str_value.len, & index2); + if (! set_array_element(array.array_cookie, & index2, & value)) { printf("test_array_elem: set_array_element failed\n"); goto out; } /* delete another element - "5" */ - (void) make_string("5", 1, & index); + (void) make_const_string("5", 1, & index); if (! del_array_element(array.array_cookie, & index)) { printf("test_array_elem: del_array_element failed\n"); goto out; } /* add a new element - "7" */ - (void) make_string("7", 1, & index); - (void) make_string("seven", 5, & value); + (void) make_const_string("7", 1, & index); + (void) make_const_string("seven", 5, & value); if (! set_array_element(array.array_cookie, & index, & value)) { printf("test_array_elem: set_array_element failed\n"); goto out; } /* add a subarray */ - (void) make_string("subarray", 8, & index); + (void) make_const_string("subarray", 8, & index); fill_in_array(& value); if (! set_array_element(array.array_cookie, & index, & value)) { printf("test_array_elem: set_array_element (subarray) failed\n"); @@ -488,14 +493,14 @@ fill_in_array(awk_value_t *new_array) a_cookie = create_array(); - (void) make_string("hello", 5, & index); - (void) make_string("world", 5, & value); + (void) make_const_string("hello", 5, & index); + (void) make_const_string("world", 5, & value); if (! set_array_element(a_cookie, & index, & value)) { printf("fill_in_array:%d: set_array_element failed\n", __LINE__); return; } - (void) make_string("answer", 6, & index); + (void) make_const_string("answer", 6, & index); (void) make_number(42.0, & value); if (! set_array_element(a_cookie, & index, & value)) { printf("fill_in_array:%d: set_array_element failed\n", __LINE__); @@ -620,7 +625,8 @@ BEGIN { if (! sym_update("answer_num", make_number(42, & value))) printf("testext: sym_update(\"answer_num\") failed!\n"); - if (! sym_update("message_string", dup_string(message, strlen(message), & value))) + if (! sym_update("message_string", + make_const_string(message, strlen(message), & value))) printf("testext: sym_update(\"answer_num\") failed!\n"); create_new_array(); @@ -140,8 +140,8 @@ awk_value_to_node(const awk_value_t *retval) } else if (retval->val_type == AWK_NUMBER) { ext_ret_val = make_number(retval->num_value); } else { - ext_ret_val = make_string(retval->str_value.str, - retval->str_value.len); + ext_ret_val = make_str_node(retval->str_value.str, + retval->str_value.len, ALREADY_MALLOCED); } return ext_ret_val; @@ -317,6 +317,14 @@ node_to_awk_value(NODE *node, awk_value_t *val, awk_valtype_t wanted) break; case Node_var: + /* a scalar value */ + if (wanted == AWK_SCALAR) { + val->val_type = AWK_SCALAR; + val->scalar_cookie = (void *) node; + ret = true; + break; + } + node = node->var_value; /* FALL THROUGH */ case Node_val: @@ -343,6 +351,16 @@ node_to_awk_value(NODE *node, awk_value_t *val, awk_valtype_t wanted) } break; + case AWK_SCALAR: + if (node->flags & NUMBER) { + val->val_type = AWK_NUMBER; + } else if (node->flags & STRING) { + val->val_type = AWK_STRING; + } else + val->val_type = AWK_UNDEFINED; + ret = false; + break; + case AWK_UNDEFINED: /* return true and actual type for request of undefined */ if (node->flags & NUMBER) { @@ -466,6 +484,9 @@ api_sym_update(awk_ext_id_t id, const char *name, awk_value_t *value) /* if we get here, then it exists already */ switch (value->val_type) { + case AWK_SCALAR: + return false; + case AWK_STRING: case AWK_NUMBER: case AWK_UNDEFINED: @@ -484,6 +505,33 @@ api_sym_update(awk_ext_id_t id, const char *name, awk_value_t *value) return true; } +/* api_sym_update_scalar --- update a scalar cookie */ + +static awk_bool_t +api_sym_update_scalar(awk_ext_id_t id, + awk_scalar_t cookie, + awk_value_t *value) +{ + NODE *node = (NODE *) cookie; + NODE *new_value; + + if (value == NULL + || node == NULL + || node->type != Node_var) + return false; + + new_value = awk_value_to_node(value); + if (new_value->type != Node_val) { + unref(new_value); + return false; + } + + unref(node->var_value); + node->var_value = new_value; + + return true; +} + /* Array management */ /* * Return the value of an element - read only! @@ -510,10 +558,21 @@ api_get_array_element(awk_ext_id_t id, return false; subscript = awk_value_to_node(index); + + /* if it doesn't exist, return false */ + if (in_array(array, subscript) == NULL) { + unref(subscript); + return false; + } + aptr = assoc_lookup(array, subscript); - unref(subscript); - if (aptr == NULL) + + if (aptr == NULL) { /* can't happen */ + unref(subscript); return false; + } + + unref(subscript); return node_to_awk_value(*aptr, result, wanted); } @@ -556,6 +615,32 @@ api_set_array_element(awk_ext_id_t id, awk_array_t a_cookie, } /* + * remove_element --- remove an array element + * common code used by multiple functions + */ + +static void +remove_element(NODE *array, NODE *subscript) +{ + NODE *val; + + val = in_array(array, subscript); + + if (val == NULL) + return; + + if (val->type == Node_var_array) { + assoc_clear(val); + /* cleared a sub-array, free Node_var_array */ + efree(val->vname); + freenode(val); + } else + unref(val); + + (void) assoc_remove(array, subscript); +} + +/* * Remove the element with the given index. * Returns success if removed or if element did not exist. */ @@ -563,7 +648,7 @@ static awk_bool_t api_del_array_element(awk_ext_id_t id, awk_array_t a_cookie, const awk_value_t* const index) { - NODE *array, *sub, *val; + NODE *array, *sub; array = (NODE *) a_cookie; if ( array == NULL @@ -573,20 +658,7 @@ api_del_array_element(awk_ext_id_t id, return false; sub = awk_value_to_node(index); - val = in_array(array, sub); - - if (val == NULL) - return false; - - if (val->type == Node_var_array) { - assoc_clear(val); - /* cleared a sub-array, free Node_var_array */ - efree(val->vname); - freenode(val); - } else - unref(val); - - (void) assoc_remove(array, sub); + remove_element(array, sub); unref(sub); return true; @@ -698,7 +770,7 @@ api_release_flattened_array(awk_ext_id_t id, { NODE *array = a_cookie; NODE **list; - size_t i; + size_t i, j, k; if ( array == NULL || array->type != Node_var_array @@ -710,17 +782,12 @@ api_release_flattened_array(awk_ext_id_t id, list = (NODE **) data->opaque2; - /* Delete items flagged for delete. */ - for (i = 0; i < data->count; i++) { - if ((data->elements[i].flags & AWK_ELEMENT_DELETE) != 0) { - /* let the other guy do the work */ - (void) api_del_array_element(id, a_cookie, - & data->elements[i].index); - } - } - /* free index nodes */ - for (i = 0; i < 2 * array->table_size; i += 2) { + for (i = j = 0, k = 2 * array->table_size; i < k; i += 2, j++) { + /* Delete items flagged for delete. */ + if ((data->elements[j].flags & AWK_ELEMENT_DELETE) != 0) { + remove_element(array, list[i]); + } unref(list[i]); } @@ -754,6 +821,7 @@ gawk_api_t api_impl = { api_sym_lookup, api_sym_update, + api_sym_update_scalar, api_get_array_element, api_set_array_element, @@ -42,6 +42,26 @@ * functions. If your compiler doesn't support it, you should either * -Dinline='' on your command line, or use the autotools and include a * config.h in your extensions. + * + * Additional important information: + * + * 1. ALL string values in awk_value_t objects need to come from malloc(). + * Gawk will handle releasing the storage if necessary. This is slightly + * awkward, in that you can't take an awk_value_t that you got from gawk + * and reuse it directly, even for something that is conceptually pass + * by value. + * + * 2. The correct way to create new arrays is to work "bottom up". + * + * new_array = create_array(); + * // fill in new array with lots of subscripts and values + * val.val_type = AWK_ARRAY; + * val.array_cookie = new_array; + * sym_update("array", &val); // install array in the symbol table + * + * After doing so, do NOT make further use of the new_array variable; + * instead use sym_lookup to get the array_cookie if you need to do further + * manipulation of the array. */ /* Allow use in C++ code. */ @@ -73,7 +93,8 @@ typedef enum { AWK_UNDEFINED, AWK_NUMBER, AWK_STRING, - AWK_ARRAY + AWK_ARRAY, + AWK_SCALAR, /* opaque access to a variable */ } awk_valtype_t; /* @@ -88,6 +109,9 @@ typedef struct { /* Arrays are represented as an opaque type. */ typedef void *awk_array_t; +/* Scalars can be represented as an opaque type. */ +typedef void *awk_scalar_t; + /* * An awk value. The val_type tag indicates what * is in the union. @@ -98,10 +122,12 @@ typedef struct { awk_string_t s; double d; awk_array_t a; + awk_array_t scl; } u; #define str_value u.s #define num_value u.d #define array_cookie u.a +#define scalar_cookie u.scl } awk_value_t; /* @@ -200,23 +226,23 @@ typedef struct gawk_api { Table entry is type returned: - +-----------------------------------------+ - | Type Requested: | - +----------+----------+-------+-----------+ - | String | Number | Array | Undefined | - +---------+-----------+----------+----------+-------+-----------+ - | Type | String | String | Number if| false | String | - | | | | it can be| | | - | | | |converted,| | | - | | | | else | | | - | | | | false | | | - | of +-----------+----------+----------+-------+-----------+ - | Actual | Number | String | Number | false | Number | - | Value: +-----------+----------+----------+-------+-----------+ - | | Array | false | false | Array | Array | - | +-----------+----------+----------+-------+-----------+ - | | Undefined | false | false | false | Undefined | - +---------+-----------+----------+----------+-------+-----------+ + +---------------------------------------------------+ + | Type Requested: | + +----------+----------+-------+---------+-----------+ + | String | Number | Array | Scalar | Undefined | + +---------+-----------+----------+----------+-------+---------+-----------+ + | Type | String | String | Number if| false | Scalar | String | + | | | | it can be| | | | + | | | |converted,| | | | + | | | | else | | | | + | | | | false | | | | + | of +-----------+----------+----------+-------+---------+-----------+ + | Actual | Number | String | Number | false | Scalar | Number | + | Value: +-----------+----------+----------+-------+---------+-----------+ + | | Array | false | false | Array | false | Array | + | +-----------+----------+----------+-------+---------+-----------+ + | | Undefined | false | false | false | false | Undefined | + +---------+-----------+----------+----------+-------+---------+-----------+ */ /* @@ -225,7 +251,7 @@ typedef struct gawk_api { * does not match what is specified in wanted. In that case, * result->val_type is as described above. */ - awk_bool_t (*get_argument)(awk_ext_id_t id, size_t count, + awk_bool_t (*api_get_argument)(awk_ext_id_t id, size_t count, awk_valtype_t wanted, awk_value_t *result); @@ -235,7 +261,7 @@ typedef struct gawk_api { * if count is too big, or if the argument's type is * not undefined. */ - awk_bool_t (*set_argument)(awk_ext_id_t id, + awk_bool_t (*api_set_argument)(awk_ext_id_t id, size_t count, awk_array_t array); @@ -245,20 +271,20 @@ typedef struct gawk_api { void (*api_lintwarn)(awk_ext_id_t id, const char *format, ...); /* Register an open hook; for opening files read-only */ - void (*register_open_hook)(awk_ext_id_t id, void* (*open_func)(IOBUF_PUBLIC *)); + void (*api_register_open_hook)(awk_ext_id_t id, void* (*open_func)(IOBUF_PUBLIC *)); /* Functions to update ERRNO */ - void (*update_ERRNO_int)(awk_ext_id_t id, int errno_val); - void (*update_ERRNO_string)(awk_ext_id_t id, const char *string, + void (*api_update_ERRNO_int)(awk_ext_id_t id, int errno_val); + void (*api_update_ERRNO_string)(awk_ext_id_t id, const char *string, awk_bool_t translate); - void (*unset_ERRNO)(awk_ext_id_t id); + void (*api_unset_ERRNO)(awk_ext_id_t id); /* Add a function to the interpreter, returns true upon success */ - awk_bool_t (*add_ext_func)(awk_ext_id_t id, const awk_ext_func_t *func, + awk_bool_t (*api_add_ext_func)(awk_ext_id_t id, const awk_ext_func_t *func, const char *namespace); /* Add an exit call back, returns true upon success */ - void (*awk_atexit)(awk_ext_id_t id, + void (*api_awk_atexit)(awk_ext_id_t id, void (*funcp)(void *data, int exit_status), void *arg0); @@ -285,7 +311,7 @@ typedef struct gawk_api { * // safe to use val * } */ - awk_bool_t (*sym_lookup)(awk_ext_id_t id, + awk_bool_t (*api_sym_lookup)(awk_ext_id_t id, const char *name, awk_valtype_t wanted, awk_value_t *result); @@ -296,16 +322,32 @@ typedef struct gawk_api { * In fact, using this to update an array is not allowed, either. * Such an attempt returns false. */ - awk_bool_t (*sym_update)(awk_ext_id_t id, const char *name, awk_value_t *value); + awk_bool_t (*api_sym_update)(awk_ext_id_t id, const char *name, awk_value_t *value); + + /* + * Work with a scalar cookie. + * Flow is + * sym_lookup with wanted == AWK_SCALAR + * if returns false + * sym_update with real initial value + * sym_lookup again with AWK_SCALAR + * else + * use the scalar cookie + * + * Return will be false if the new value is not one of + * AWK_STRING or AWK_NUMBER. + */ + awk_bool_t (*api_sym_update_scalar)(awk_ext_id_t id, + awk_scalar_t cookie, awk_value_t *value); /* Array management */ /* * Return the value of an element - read only! * Use set_array_element() to change it. - * Behavior for value and return is same as for get_argument + * Behavior for value and return is same as for api_get_argument * and sym_lookup. */ - awk_bool_t (*get_array_element)(awk_ext_id_t id, + awk_bool_t (*api_get_array_element)(awk_ext_id_t id, awk_array_t a_cookie, const awk_value_t *const index, awk_valtype_t wanted, @@ -315,7 +357,7 @@ typedef struct gawk_api { * Change (or create) element in existing array with * element->index and element->value. */ - awk_bool_t (*set_array_element)(awk_ext_id_t id, awk_array_t a_cookie, + awk_bool_t (*api_set_array_element)(awk_ext_id_t id, awk_array_t a_cookie, const awk_value_t *const index, const awk_value_t *const value); @@ -323,24 +365,24 @@ typedef struct gawk_api { * Remove the element with the given index. * Returns success if removed or if element did not exist. */ - awk_bool_t (*del_array_element)(awk_ext_id_t id, + awk_bool_t (*api_del_array_element)(awk_ext_id_t id, awk_array_t a_cookie, const awk_value_t* const index); /* * Retrieve total number of elements in array. * Returns false if some kind of error. */ - awk_bool_t (*get_element_count)(awk_ext_id_t id, + awk_bool_t (*api_get_element_count)(awk_ext_id_t id, awk_array_t a_cookie, size_t *count); /* Create a new array cookie to which elements may be added */ - awk_array_t (*create_array)(awk_ext_id_t id); + awk_array_t (*api_create_array)(awk_ext_id_t id); /* Clear out an array */ - awk_bool_t (*clear_array)(awk_ext_id_t id, awk_array_t a_cookie); + awk_bool_t (*api_clear_array)(awk_ext_id_t id, awk_array_t a_cookie); /* Flatten out an array so that it can be looped over easily. */ - awk_bool_t (*flatten_array)(awk_ext_id_t id, + awk_bool_t (*api_flatten_array)(awk_ext_id_t id, awk_array_t a_cookie, awk_flat_array_t **data); @@ -349,7 +391,7 @@ typedef struct gawk_api { * Count must match what gawk thinks the size is. * Otherwise it's a fatal error. */ - awk_bool_t (*release_flattened_array)(awk_ext_id_t id, + awk_bool_t (*api_release_flattened_array)(awk_ext_id_t id, awk_array_t a_cookie, awk_flat_array_t *data); } gawk_api_t; @@ -367,52 +409,54 @@ typedef struct gawk_api { #define do_mpfr (api->do_flags[gawk_do_mpfr]) #define get_argument(count, wanted, result) \ - (api->get_argument(ext_id, count, wanted, result)) + (api->api_get_argument(ext_id, count, wanted, result)) #define set_argument(count, new_array) \ - (api->set_argument(ext_id, count, new_array)) + (api->api_set_argument(ext_id, count, new_array)) #define fatal api->api_fatal #define warning api->api_warning #define lintwarn api->api_lintwarn -#define register_open_hook(func) (api->register_open_hook(ext_id, func)) +#define register_open_hook(func) (api->api_register_open_hook(ext_id, func)) -#define update_ERRNO_int(e) (api->update_ERRNO_int(ext_id, e)) +#define update_ERRNO_int(e) (api->api_update_ERRNO_int(ext_id, e)) #define update_ERRNO_string(str, translate) \ - (api->update_ERRNO_string(ext_id, str, translate)) -#define unset_ERRNO() (api->unset_ERRNO(ext_id)) + (api->api_update_ERRNO_string(ext_id, str, translate)) +#define unset_ERRNO() (api->api_unset_ERRNO(ext_id)) -#define add_ext_func(func, ns) (api->add_ext_func(ext_id, func, ns)) -#define awk_atexit(funcp, arg0) (api->awk_atexit(ext_id, funcp, arg0)) +#define add_ext_func(func, ns) (api->api_add_ext_func(ext_id, func, ns)) +#define awk_atexit(funcp, arg0) (api->api_awk_atexit(ext_id, funcp, arg0)) -#define sym_lookup(name, wanted, result) (api->sym_lookup(ext_id, name, wanted, result)) +#define sym_lookup(name, wanted, result) (api->api_sym_lookup(ext_id, name, wanted, result)) #define sym_update(name, value) \ - (api->sym_update(ext_id, name, value)) + (api->api_sym_update(ext_id, name, value)) +#define sym_update_scalar(scalar_cookie, value) \ + (api->api_sym_update_scalar)(ext_id, scalar_cookie, value) #define get_array_element(array, index, wanted, result) \ - (api->get_array_element(ext_id, array, index, wanted, result)) + (api->api_get_array_element(ext_id, array, index, wanted, result)) #define set_array_element(array, index, value) \ - (api->set_array_element(ext_id, array, index, value)) + (api->api_set_array_element(ext_id, array, index, value)) #define set_array_element_by_elem(array, elem) \ - (set_array_element(array, & (elem)->index, & (elem)->value)) + (api->api_set_array_element(ext_id, array, & (elem)->index, & (elem)->value)) #define del_array_element(array, index) \ - (api->del_array_element(ext_id, array, index)) + (api->api_del_array_element(ext_id, array, index)) #define get_element_count(array, count_p) \ - (api->get_element_count(ext_id, array, count_p)) + (api->api_get_element_count(ext_id, array, count_p)) -#define create_array() (api->create_array(ext_id)) +#define create_array() (api->api_create_array(ext_id)) -#define clear_array(array) (api->clear_array(ext_id, array)) +#define clear_array(array) (api->api_clear_array(ext_id, array)) #define flatten_array(array, data) \ - (api->flatten_array(ext_id, array, data)) + (api->api_flatten_array(ext_id, array, data)) #define release_flattened_array(array, data) \ - (api->release_flattened_array(ext_id, array, data)) + (api->api_release_flattened_array(ext_id, array, data)) #define emalloc(pointer, type, size, message) \ do { \ @@ -420,6 +464,12 @@ typedef struct gawk_api { fatal(ext_id, "malloc of %d bytes failed\n", size); \ } while(0) +#define erealloc(pointer, type, size, message) \ + do { \ + if ((pointer = (type) realloc(pointer, size)) == 0) \ + fatal(ext_id, "realloc of %d bytes failed\n", size); \ + } while(0) + /* Constructor functions */ /* r_make_string --- make a string value in result from the passed-in string */ @@ -440,7 +490,7 @@ r_make_string(const gawk_api_t *api, /* needed for emalloc */ result->str_value.len = length; if (duplicate) { - emalloc(cp, char *, length + 2, "make_string"); + emalloc(cp, char *, length + 2, "r_make_string"); memcpy(cp, string, length); cp[length] = '\0'; result->str_value.str = cp; @@ -451,8 +501,19 @@ r_make_string(const gawk_api_t *api, /* needed for emalloc */ return result; } -#define make_string(str, len, result) r_make_string(api, ext_id, str, len, 0, result) -#define dup_string(str, len, result) r_make_string(api, ext_id, str, len, 1, result) +#define make_const_string(str, len, result) r_make_string(api, ext_id, str, len, 1, result) +#define make_malloced_string(str, len, result) r_make_string(api, ext_id, str, len, 0, result) + +/* make_null_string --- make a null string value */ + +static inline awk_value_t * +make_null_string(awk_value_t *result) +{ + memset(result, 0, sizeof(*result)); + result->val_type = AWK_UNDEFINED; + + return result; +} /* make_number --- make a number value in result */ |