diff options
author | Arnold D. Robbins <arnold@skeeve.com> | 2012-07-12 21:09:14 +0300 |
---|---|---|
committer | Arnold D. Robbins <arnold@skeeve.com> | 2012-07-12 21:09:14 +0300 |
commit | a49be44686e3d0707c43d643bfcad68d50a75b98 (patch) | |
tree | 8f7a27802f86336a3002d4dfa14c33362a37ad81 | |
parent | 33b647ef23daa8a310701c767098f11ee48cf4e8 (diff) | |
parent | dda2495337929a86cc40017d8f1cd72a46876618 (diff) | |
download | egawk-a49be44686e3d0707c43d643bfcad68d50a75b98.tar.gz egawk-a49be44686e3d0707c43d643bfcad68d50a75b98.tar.bz2 egawk-a49be44686e3d0707c43d643bfcad68d50a75b98.zip |
Merge branch 'extgawk' of ssh://git.sv.gnu.org/srv/git/gawk into extgawk
-rw-r--r-- | ChangeLog | 20 | ||||
-rw-r--r-- | gawkapi.c | 63 | ||||
-rw-r--r-- | gawkapi.h | 21 |
3 files changed, 91 insertions, 13 deletions
@@ -1,3 +1,23 @@ +2012-07-11 Andrew J. Schorr <aschorr@telemetry-investments.com> + + * gawkapi.h: Fix typo in comment. + (awk_value_t): Type for scalar_cookie should be awk_scalar_t, + not awk_array_t. + (gawk_api): Add new api_sym_lookup_scalar function. + (sym_lookup_scalar): New wrapper macro for api_sym_lookup_scalar hook. + * gawkapi.c (api_sym_lookup_scalar): New function for faster scalar + lookup. + (api_impl): Add entry for api_sym_lookup_scalar. + +2012-07-11 Andrew J. Schorr <aschorr@telemetry-investments.com> + + * gawkapi.c (awk_value_to_node): Change to a switch statement + so AWK_SCALAR or other invalid type is handled properly. + (valid_subscript_type): Test whether a value type is acceptable + for use as an array subscript (any scalar value will do). + (api_get_array_element, api_set_array_element, api_del_array_element): + Use new valid_subscript_type instead of restricting to string values. + 2012-07-11 Arnold D. Robbins <arnold@skeeve.com> Lots of API work. @@ -132,16 +132,23 @@ awk_value_to_node(const awk_value_t *retval) if (retval == NULL) fatal(_("awk_value_to_node: received null retval")); - ext_ret_val = NULL; - if (retval->val_type == AWK_ARRAY) { + switch (retval->val_type) { + case AWK_ARRAY: ext_ret_val = (NODE *) retval->array_cookie; - } else if (retval->val_type == AWK_UNDEFINED) { + break; + case AWK_UNDEFINED: ext_ret_val = dupnode(Nnull_string); - } else if (retval->val_type == AWK_NUMBER) { + break; + case AWK_NUMBER: ext_ret_val = make_number(retval->num_value); - } else { + break; + case AWK_STRING: ext_ret_val = make_str_node(retval->str_value.str, retval->str_value.len, ALREADY_MALLOCED); + break; + default: /* AWK_SCALAR or any invalid type */ + ext_ret_val = NULL; + break; } return ext_ret_val; @@ -435,6 +442,24 @@ api_sym_lookup(awk_ext_id_t id, return node_to_awk_value(node, result, wanted); } +/* api_sym_lookup_scalar --- retrieve the current value of a scalar */ + +static awk_bool_t +api_sym_lookup_scalar(awk_ext_id_t id, + awk_scalar_t cookie, + awk_valtype_t wanted, + awk_value_t *result) +{ + NODE *node = (NODE *) cookie; + + if (node == NULL + || result == NULL + || node->type != Node_var) + return false; + + return node_to_awk_value(node, result, wanted); +} + /* api_sym_update --- update a symbol's value, see gawkapi.h for semantics */ static awk_bool_t @@ -532,6 +557,24 @@ api_sym_update_scalar(awk_ext_id_t id, return true; } +/* + * Test if a type is allowed for an array subscript. A string or numeric + * value is fine, and undefined is equivalent to "", so those are OK. + * We reject AWK_ARRAY and AWK_SCALAR. + */ +static inline int +valid_subscript_type(awk_valtype_t valtype) +{ + switch (valtype) { + case AWK_UNDEFINED: + case AWK_NUMBER: + case AWK_STRING: + return true; + default: + return false; + } +} + /* Array management */ /* * Return the value of an element - read only! @@ -553,8 +596,7 @@ api_get_array_element(awk_ext_id_t id, || array->type != Node_var_array || result == NULL || index == NULL - || index->val_type != AWK_STRING - || index->str_value.str == NULL) + || ! valid_subscript_type(index->val_type)) return false; subscript = awk_value_to_node(index); @@ -596,10 +638,10 @@ api_set_array_element(awk_ext_id_t id, awk_array_t a_cookie, || array->type != Node_var_array || index == NULL || value == NULL - || index->str_value.str == NULL) + || ! valid_subscript_type(index->val_type)) return false; - tmp = make_string(index->str_value.str, index->str_value.len); + tmp = awk_value_to_node(index); aptr = assoc_lookup(array, tmp); unref(tmp); unref(*aptr); @@ -654,7 +696,7 @@ api_del_array_element(awk_ext_id_t id, if ( array == NULL || array->type != Node_var_array || index == NULL - || index->val_type != AWK_STRING) + || ! valid_subscript_type(index->val_type)) return false; sub = awk_value_to_node(index); @@ -820,6 +862,7 @@ gawk_api_t api_impl = { api_awk_atexit, api_sym_lookup, + api_sym_lookup_scalar, api_sym_update, api_sym_update_scalar, @@ -34,7 +34,7 @@ /* * General introduction: * - * This API purposely restricts itself to C90 features. In paticular, no + * This API purposely restricts itself to C90 features. In particular, no * bool, no // comments, no use of the restrict keyword, or anything else, * in order to provide maximal portability. * @@ -122,7 +122,7 @@ typedef struct { awk_string_t s; double d; awk_array_t a; - awk_array_t scl; + awk_scalar_t scl; } u; #define str_value u.s #define num_value u.d @@ -317,6 +317,18 @@ typedef struct gawk_api { awk_value_t *result); /* + * Retrieve the current value of a scalar cookie. Once + * you have obtained a saclar_cookie using sym_lookup, you can + * use this function to get its value more efficiently. + * + * Return will be false if the value cannot be retrieved. + */ + awk_bool_t (*api_sym_lookup_scalar)(awk_ext_id_t id, + awk_scalar_t cookie, + awk_valtype_t wanted, + awk_value_t *result); + + /* * Update a value. Adds it to the symbol table if not there. * Changing types (scalar <--> array) is not allowed. * In fact, using this to update an array is not allowed, either. @@ -427,7 +439,10 @@ typedef struct gawk_api { #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->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_lookup_scalar(scalar_cookie, wanted, result) \ + (api->api_sym_lookup_scalar(ext_id, scalar_cookie, wanted, result)) #define sym_update(name, value) \ (api->api_sym_update(ext_id, name, value)) #define sym_update_scalar(scalar_cookie, value) \ |