aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog18
-rw-r--r--awk.h3
-rw-r--r--gawkapi.c37
-rw-r--r--gawkapi.h17
-rw-r--r--node.c2
5 files changed, 75 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index bc403ce9..2ebb17de 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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.
diff --git a/awk.h b/awk.h
index f08d7d9c..a85fef85 100644
--- a/awk.h
+++ b/awk.h
@@ -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();
diff --git a/gawkapi.c b/gawkapi.c
index 6c03dd0b..22d218d8 100644
--- a/gawkapi.c
+++ b/gawkapi.c
@@ -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 */
diff --git a/gawkapi.h b/gawkapi.h
index a84fbf52..29631cdd 100644
--- a/gawkapi.h
+++ b/gawkapi.h
@@ -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) \
diff --git a/node.c b/node.c
index ff593d22..c7316dcb 100644
--- a/node.c
+++ b/node.c
@@ -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);