aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew J. Schorr <aschorr@telemetry-investments.com>2012-07-17 17:23:42 -0400
committerAndrew J. Schorr <aschorr@telemetry-investments.com>2012-07-17 17:23:42 -0400
commitffbf8454171c0ef037db425f436c735da3691d9f (patch)
tree221c84cc8b3cc882435cbf44d466b2eaf27e3a28
parent2abd3979c829934905f5a84dd2f5836b1d8eec37 (diff)
downloadegawk-ffbf8454171c0ef037db425f436c735da3691d9f.tar.gz
egawk-ffbf8454171c0ef037db425f436c735da3691d9f.tar.bz2
egawk-ffbf8454171c0ef037db425f436c735da3691d9f.zip
Clean up support for AWK_SCALAR and AWK_VALUE_COOKIE.
-rw-r--r--ChangeLog18
-rw-r--r--gawkapi.c55
-rw-r--r--gawkapi.h11
3 files changed, 48 insertions, 36 deletions
diff --git a/ChangeLog b/ChangeLog
index 2ebb17de..60e560af 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2012-07-17 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * gawkapi.h: Add comments explaining new api_create_value and
+ api_release_value functions.
+ * gawkapi.c (sym_update_real): Allow updates with AWK_SCALAR and
+ AWK_VALUE_COOKIE types. After creating a regular variable,
+ remove the call to unref(node->var_value), since this is not
+ done elsewhere in the code (see, for example, main.c:init_vars).
+ If the update is for an existing variable, allow any val_type
+ except AWK_ARRAY (was previously disallowing AWK_SCALAR and
+ AWK_VALUE_COOKIE for no apparent reason).
+ (api_sym_update_scalar): The switch should return false for an
+ invalid val_type value, so change the AWK_ARRAY case to default.
+ (valid_subscript_type): Any scalar value is good, so accept any valid
+ type except AWK_ARRAY.
+ (api_create_value): Accept only AWK_NUMBER and AWK_STRING values.
+ Anything else should fail.
+
2012-07-17 Arnold D. Robbins <arnold@skeeve.com>
Speedup:
diff --git a/gawkapi.c b/gawkapi.c
index c750f064..50ebc457 100644
--- a/gawkapi.c
+++ b/gawkapi.c
@@ -495,6 +495,8 @@ sym_update_real(awk_ext_id_t id,
case AWK_STRING:
case AWK_UNDEFINED:
case AWK_ARRAY:
+ case AWK_SCALAR:
+ case AWK_VALUE_COOKIE:
break;
default:
@@ -517,7 +519,6 @@ sym_update_real(awk_ext_id_t id,
/* regular variable */
node = install_symbol(estrdup((char *) name, strlen(name)),
Node_var);
- unref(node->var_value);
node->var_value = awk_value_to_node(value);
if (is_const)
node->var_assign = set_constant;
@@ -525,31 +526,18 @@ sym_update_real(awk_ext_id_t id,
return true;
}
- /* 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:
- if (node->type == Node_var || node->type == Node_var_new) {
- unref(node->var_value);
- node->var_value = awk_value_to_node(value);
- /* let the extension change its own variable */
- if (is_const)
- node->var_assign = set_constant;
- } else {
- return false;
- }
- break;
-
- case AWK_ARRAY:
- case AWK_VALUE_COOKIE:
- return false; /* not allowed */
+ /* If we get here, then it exists already. Any valid type is
+ * OK except for AWK_ARRAY. */
+ if ((value->val_type != AWK_ARRAY) &&
+ (node->type == Node_var || node->type == Node_var_new)) {
+ unref(node->var_value);
+ node->var_value = awk_value_to_node(value);
+ /* let the extension change its own variable */
+ if (is_const)
+ node->var_assign = set_constant;
+ return true;
}
-
- return true;
+ return false;
}
/* api_sym_update --- update a symbol, non-constant */
@@ -629,7 +617,7 @@ api_sym_update_scalar(awk_ext_id_t id,
return true;
}
break;
- case AWK_ARRAY:
+ default: /* reject AWK_ARRAY or an invalid type */
return false;
break;
}
@@ -643,9 +631,8 @@ api_sym_update_scalar(awk_ext_id_t id,
}
/*
- * 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.
+ * Test if a type is allowed for an array subscript.
+ * Any scalar value is fine, so only AWK_ARRAY (or an invalid type) is illegal.
*/
static inline int
valid_subscript_type(awk_valtype_t valtype)
@@ -654,13 +641,12 @@ valid_subscript_type(awk_valtype_t valtype)
case AWK_UNDEFINED:
case AWK_NUMBER:
case AWK_STRING:
+ case AWK_SCALAR:
case AWK_VALUE_COOKIE:
return true;
- case AWK_SCALAR:
- case AWK_ARRAY:
+ default: /* AWK_ARRAY or an invalid type */
return false;
}
- return false;
}
/* Array management */
@@ -934,11 +920,8 @@ api_create_value(awk_ext_id_t id, awk_value_t *value,
switch (value->val_type) {
case AWK_NUMBER:
case AWK_STRING:
- case AWK_UNDEFINED:
break;
- case AWK_ARRAY:
- case AWK_SCALAR:
- case AWK_VALUE_COOKIE:
+ default:
/* reject anything other than a simple scalar */
return false;
}
diff --git a/gawkapi.h b/gawkapi.h
index 29631cdd..5d9936fb 100644
--- a/gawkapi.h
+++ b/gawkapi.h
@@ -421,9 +421,20 @@ typedef struct gawk_api {
awk_array_t a_cookie,
awk_flat_array_t *data);
+ /*
+ * Cache a string or numeric value for efficient later assignment.
+ * This improves performance when you want to assign the same value
+ * to one or more variables repeatedly. Only AWK_NUMBER and AWK_STRING
+ * values are allowed. Any other type is rejected. We disallow
+ * AWK_UNDEFINED since that case would result in inferior performance.
+ */
awk_bool_t (*api_create_value)(awk_ext_id_t id, awk_value_t *value,
awk_value_cookie_t *result);
+ /*
+ * Release the memory associated with a cookie from api_create_value.
+ * Please call this to free memory when the value is no longer needed.
+ */
awk_bool_t (*api_release_value)(awk_ext_id_t id, awk_value_cookie_t vc);
} gawk_api_t;