aboutsummaryrefslogtreecommitdiffstats
path: root/gawkapi.c
diff options
context:
space:
mode:
authorArnold D. Robbins <arnold@skeeve.com>2012-07-12 21:09:14 +0300
committerArnold D. Robbins <arnold@skeeve.com>2012-07-12 21:09:14 +0300
commita49be44686e3d0707c43d643bfcad68d50a75b98 (patch)
tree8f7a27802f86336a3002d4dfa14c33362a37ad81 /gawkapi.c
parent33b647ef23daa8a310701c767098f11ee48cf4e8 (diff)
parentdda2495337929a86cc40017d8f1cd72a46876618 (diff)
downloadegawk-a49be44686e3d0707c43d643bfcad68d50a75b98.tar.gz
egawk-a49be44686e3d0707c43d643bfcad68d50a75b98.tar.bz2
egawk-a49be44686e3d0707c43d643bfcad68d50a75b98.zip
Merge branch 'extgawk' of ssh://git.sv.gnu.org/srv/git/gawk into extgawk
Diffstat (limited to 'gawkapi.c')
-rw-r--r--gawkapi.c63
1 files changed, 53 insertions, 10 deletions
diff --git a/gawkapi.c b/gawkapi.c
index c5f8953d..b6d83acb 100644
--- a/gawkapi.c
+++ b/gawkapi.c
@@ -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,