diff options
-rw-r--r-- | ChangeLog | 18 | ||||
-rw-r--r-- | awk.h | 3 | ||||
-rw-r--r-- | gawkapi.c | 37 | ||||
-rw-r--r-- | gawkapi.h | 17 | ||||
-rw-r--r-- | node.c | 2 |
5 files changed, 75 insertions, 2 deletions
@@ -1,3 +1,21 @@ +2012-07-17 Arnold D. Robbins <arnold@skeeve.com> + + Speedup: + + * awk.h (r_free_wstr): Renamed from free_wstr. + (free_wstr): Macro to test the WSTRCUR flag first. + * node.c (r_free_wstr): Renamed from free_wstr. + + Support value cookies: + + * gawkapi.h (awk_val_type_t): Add AWK_VALUE_COOKIE. + (awk_value_cookie_t): New type. + (awk_value_t): Support AWK_VALUE_COOKIE. + (api_create_value, api_release_value): New function pointers. + * gawkapi.c (awk_value_to_node, api_sym_update_scalar, + valid_subscript_type): Handle AWK_VALUE_COOKIE. + (api_create_value, api_release_value): New functions. + 2012-07-16 Arnold D. Robbins <arnold@skeeve.com> * gawkapi.c (awk_value_to_node): Support AWK_SCALAR. @@ -1636,7 +1636,8 @@ extern const wchar_t *wstrstr(const wchar_t *haystack, size_t hs_len, const wchar_t *needle, size_t needle_len); extern const wchar_t *wcasestrstr(const wchar_t *haystack, size_t hs_len, const wchar_t *needle, size_t needle_len); -extern void free_wstr(NODE *n); +extern void r_free_wstr(NODE *n); +#define free_wstr(n) (((n)->flags & WSTRCUR) ? r_free_wstr(n) : 0) extern wint_t btowc_cache[]; #define btowc_cache(x) btowc_cache[(x)&0xFF] extern void init_btowc_cache(); @@ -155,6 +155,9 @@ awk_value_to_node(const awk_value_t *retval) else ext_ret_val = dupnode(v->var_value); break; + case AWK_VALUE_COOKIE: + ext_ret_val = dupnode((NODE *)(retval->value_cookie)); + break; default: /* any invalid type */ ext_ret_val = NULL; break; @@ -585,8 +588,24 @@ api_sym_update_scalar(awk_ext_id_t id, switch (value->val_type) { case AWK_NUMBER: + if (node->var_value->valref == 1 && ! do_mpfr) { + NODE *r = node->var_value; + + r->numbr = value->num_value; + if (r->flags & STRCUR) { + efree(r->stptr); + r->stptr = NULL; + r->stlen = 0; + } + free_wstr(r); + r->flags = NUMBER|NUMCUR; + return true; + } + /* otherwise, fall through */ + case AWK_UNDEFINED: case AWK_SCALAR: + case AWK_VALUE_COOKIE: hard_way = true; /* fall through */ case AWK_STRING: @@ -638,6 +657,7 @@ valid_subscript_type(awk_valtype_t valtype) case AWK_UNDEFINED: case AWK_NUMBER: case AWK_STRING: + case AWK_VALUE_COOKIE: return true; default: return false; @@ -908,6 +928,20 @@ api_release_flattened_array(awk_ext_id_t id, return true; } +static awk_bool_t +api_create_value(awk_ext_id_t id, awk_value_t *value, + awk_value_cookie_t *result) +{ + return (*result = awk_value_to_node(value)) != NULL; +} + +static awk_bool_t +api_release_value(awk_ext_id_t id, awk_value_cookie_t value) +{ + unref((NODE *) value); + return true; +} + gawk_api_t api_impl = { GAWK_API_MAJOR_VERSION, /* major and minor versions */ GAWK_API_MINOR_VERSION, @@ -944,6 +978,9 @@ gawk_api_t api_impl = { api_clear_array, api_flatten_array, api_release_flattened_array, + + api_create_value, + api_release_value, }; /* init_ext_api --- init the extension API */ @@ -95,6 +95,7 @@ typedef enum { AWK_STRING, AWK_ARRAY, AWK_SCALAR, /* opaque access to a variable */ + AWK_VALUE_COOKIE, /* for updating to a previously created value */ } awk_valtype_t; /* @@ -112,6 +113,9 @@ typedef void *awk_array_t; /* Scalars can be represented as an opaque type. */ typedef void *awk_scalar_t; +/* Any value can be stored as a cookie. */ +typedef void *awk_value_cookie_t; + /* * An awk value. The val_type tag indicates what * is in the union. @@ -123,11 +127,13 @@ typedef struct { double d; awk_array_t a; awk_scalar_t scl; + awk_value_cookie_t vc; } u; #define str_value u.s #define num_value u.d #define array_cookie u.a #define scalar_cookie u.scl +#define value_cookie u.vc } awk_value_t; /* @@ -414,6 +420,11 @@ typedef struct gawk_api { awk_bool_t (*api_release_flattened_array)(awk_ext_id_t id, awk_array_t a_cookie, awk_flat_array_t *data); + + awk_bool_t (*api_create_value)(awk_ext_id_t id, awk_value_t *value, + awk_value_cookie_t *result); + + awk_bool_t (*api_release_value)(awk_ext_id_t id, awk_value_cookie_t vc); } gawk_api_t; #ifndef GAWK /* these are not for the gawk code itself! */ @@ -483,6 +494,12 @@ typedef struct gawk_api { #define release_flattened_array(array, data) \ (api->api_release_flattened_array(ext_id, array, data)) +#define create_value(value, result) \ + (api->api_create_value(ext_id, value,result)) + +#define release_value(value) \ + (api->api_release_value(ext_id, value)) + #define emalloc(pointer, type, size, message) \ do { \ if ((pointer = (type) malloc(size)) == 0) \ @@ -829,7 +829,7 @@ wstr2str(NODE *n) /* free_wstr --- release the wide string part of a node */ void -free_wstr(NODE *n) +r_free_wstr(NODE *n) { assert(n->type == Node_val); |