diff options
-rw-r--r-- | ChangeLog | 14 | ||||
-rw-r--r-- | doc/ChangeLog | 5 | ||||
-rw-r--r-- | doc/gawktexi.in | 12 | ||||
-rw-r--r-- | gawkapi.c | 46 | ||||
-rw-r--r-- | gawkapi.h | 25 |
5 files changed, 78 insertions, 24 deletions
@@ -1,5 +1,19 @@ 2016-12-04 Andrew J. Schorr <aschorr@telemetry-investments.com> + * gawkapi.h (awk_element_t): Remove obsolete comment claiming that + the index will always be a string. + (gawk_api_t): Add new api_flatten_array_typed function and indicate + that api_flatten_array has been superseded. + (flatten_array_typed): New macro to call api_flatten_array_typed. + (flatten_array): Redefine using the new flatten_array_typed macro. + * gawkapi.c (api_flatten_array_typed): New function renamed from + api_flatten_array to flatten an array with the types requested by the + caller. Also update the comments and error messages. + (api_flatten_array): Now a wrapper around api_flatten_array_typed. + (api_impl): Add new api_flatten_array_typed hook. + +2016-12-04 Andrew J. Schorr <aschorr@telemetry-investments.com> + * gawkapi.h (r_make_string_type): New inline function to create strings of any type, currently AWK_STRING or AWK_REGEX. (r_make_string): Now a wrapper around r_make_string_type. diff --git a/doc/ChangeLog b/doc/ChangeLog index ea02455f..2e08deff 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,8 @@ +2016-12-04 Andrew J. Schorr <aschorr@telemetry-investments.com> + + * gawktexi.in: Document new flatten_array_typed API function, and + indicate that the old flatten_array function has been superseded. + 2016-11-30 Arnold D. Robbins <arnold@skeeve.com> * gawktexi.in: Document typed regex changes as relates to API. diff --git a/doc/gawktexi.in b/doc/gawktexi.in index c79cda32..17206bce 100644 --- a/doc/gawktexi.in +++ b/doc/gawktexi.in @@ -33000,9 +33000,9 @@ The array remains an array, but after calling this function, it has no elements. This is equivalent to using the @code{delete} statement (@pxref{Delete}). -@item awk_bool_t flatten_array(awk_array_t a_cookie, awk_flat_array_t **data); +@item awk_bool_t flatten_array_typed(awk_array_t a_cookie, awk_flat_array_t **data, awk_valtype_t index_type, awk_valtype_t value_type); For the array represented by @code{a_cookie}, create an @code{awk_flat_array_t} -structure and fill it in. Set the pointer whose address is passed as @code{data} +structure and fill it in with indices and values of the requested types. Set the pointer whose address is passed as @code{data} to point to this structure. Return true upon success, or false otherwise. @ifset FOR_PRINT @@ -33014,6 +33014,12 @@ See the next @value{SECTION} for a discussion of how to flatten an array and work with it. +@item awk_bool_t flatten_array(awk_array_t a_cookie, awk_flat_array_t **data); +For the array represented by @code{a_cookie}, create an @code{awk_flat_array_t} +structure and fill it in with @code{AWK_STRING} indices and +@code{AWK_UNDEFINED} values. This is superseded by @code{flatten_array_typed} +and retained only for legacy binary compatibility. + @item awk_bool_t release_flattened_array(awk_array_t a_cookie, @itemx @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ awk_flat_array_t *data); When done with a flattened array, release the storage using this function. @@ -33126,7 +33132,7 @@ to double-check that the count in the @code{awk_flat_array_t} is the same as the count just retrieved: @example - if (! flatten_array(value2.array_cookie, & flat_array)) @{ + if (! flatten_array_typed(value2.array_cookie, & flat_array, AWK_STRING, AWK_UNDEFINED)) @{ printf("dump_array_and_delete: could not flatten array\n"); goto out; @} @@ -995,9 +995,10 @@ api_clear_array(awk_ext_id_t id, awk_array_t a_cookie) /* api_flatten_array --- flatten out an array so that it can be looped over easily. */ static awk_bool_t -api_flatten_array(awk_ext_id_t id, +api_flatten_array_typed(awk_ext_id_t id, awk_array_t a_cookie, - awk_flat_array_t **data) + awk_flat_array_t **data, + awk_valtype_t index_type, awk_valtype_t value_type) { NODE **list; size_t i, j; @@ -1014,7 +1015,7 @@ api_flatten_array(awk_ext_id_t id, (array->table_size - 1) * sizeof(awk_element_t); emalloc(*data, awk_flat_array_t *, alloc_size, - "api_flatten_array"); + "api_flatten_array_typed"); memset(*data, 0, alloc_size); list = assoc_list(array, "@unsorted", ASORTI); @@ -1029,29 +1030,35 @@ api_flatten_array(awk_ext_id_t id, index = list[i]; value = list[i + 1]; /* number or string or subarray */ - /* - * Convert index and value to ext types. Force the - * index to be a string, since indices are always - * conceptually strings, regardless of internal optimizations - * to treat them as integers in some cases. - * - * Regexes are forced to string too. - */ + /* Convert index and value to ext types. */ if (! node_to_awk_value(index, - & (*data)->elements[j].index, AWK_STRING)) { - fatal(_("api_flatten_array: could not convert index %d\n"), - (int) i); + & (*data)->elements[j].index, index_type)) { + fatal(_("api_flatten_array_typed: could not convert index %d to %d\n"), + (int) i, (int) index_type); } if (! node_to_awk_value(value, - & (*data)->elements[j].value, AWK_UNDEFINED)) { - fatal(_("api_flatten_array: could not convert value %d\n"), - (int) i); + & (*data)->elements[j].value, value_type)) { + fatal(_("api_flatten_array_typed: could not convert value %d to %d\n"), + (int) i, (int) value_type); } } return awk_true; } /* + * api_flatten_array -- replaced by api_flatten_array_typed. This function + * is retained only for binary compatibility. + */ + +static awk_bool_t +api_flatten_array(awk_ext_id_t id, + awk_array_t a_cookie, + awk_flat_array_t **data) +{ + return api_flatten_array_typed(id, a_cookie, data, AWK_STRING, AWK_UNDEFINED); +} + +/* * api_release_flattened_array --- release array memory, * delete any marked elements. Count must match what * gawk thinks the size is. @@ -1298,7 +1305,7 @@ gawk_api_t api_impl = { api_del_array_element, api_create_array, api_clear_array, - api_flatten_array, + api_flatten_array, /* for legacy binary compatibility */ api_release_flattened_array, /* Memory allocation */ @@ -1312,6 +1319,9 @@ gawk_api_t api_impl = { /* Print nonfatal error message */ api_nonfatal, + + /* New array flattening function */ + api_flatten_array_typed, }; /* init_ext_api --- init the extension API */ @@ -349,7 +349,7 @@ typedef struct awk_element { AWK_ELEMENT_DELETE = 1 /* set by extension if should be deleted */ } flags; - awk_value_t index; /* guaranteed to be a string! */ + awk_value_t index; awk_value_t value; } awk_element_t; @@ -668,7 +668,13 @@ typedef struct gawk_api { /* Clear out an array */ 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. */ + /* + * Flatten out an array so that it can be looped over easily. + * This function returns all indices as strings and values as + * the native type one would get from an AWK_UNDEFINED request. + * Please use api_flatten_array_typed for more control over the + * type conversions. + */ awk_bool_t (*api_flatten_array)(awk_ext_id_t id, awk_array_t a_cookie, awk_flat_array_t **data); @@ -724,6 +730,16 @@ typedef struct gawk_api { /* Print nonfatal error message */ void (*api_nonfatal)(awk_ext_id_t id, const char *format, ...); + /* + * Flatten out an array with type conversions as requested. + * This supersedes the api_flatten_array function that did not allow + * the caller to specify the requested types. + */ + awk_bool_t (*api_flatten_array_typed)(awk_ext_id_t id, + awk_array_t a_cookie, + awk_flat_array_t **data, + awk_valtype_t index_type, awk_valtype_t value_type); + } gawk_api_t; #ifndef GAWK /* these are not for the gawk code itself! */ @@ -790,8 +806,11 @@ typedef struct gawk_api { #define clear_array(array) (api->api_clear_array(ext_id, array)) +#define flatten_array_typed(array, data, index_type, value_type) \ + (api->api_flatten_array_typed(ext_id, array, data, index_type, value_type)) + #define flatten_array(array, data) \ - (api->api_flatten_array(ext_id, array, data)) + flatten_array_typed(array, data, AWK_STRING, AWK_UNDEFINED) #define release_flattened_array(array, data) \ (api->api_release_flattened_array(ext_id, array, data)) |