summaryrefslogtreecommitdiff
path: root/gawkapi.c
diff options
context:
space:
mode:
authorArnold D. Robbins <arnold@skeeve.com>2012-07-12 22:45:25 +0300
committerArnold D. Robbins <arnold@skeeve.com>2012-07-12 22:45:25 +0300
commit28daef44c3c08f16002c678319a30b816f6972fd (patch)
tree5bb3ed751db1d4c32b71a72e2fc87c52e1f46de9 /gawkapi.c
parent4319d9141a56cb8ed878d44d0e74bedee51085a6 (diff)
downloadgawk-28daef44c3c08f16002c678319a30b816f6972fd.tar.gz
Allow creation of constants from extensions.
Diffstat (limited to 'gawkapi.c')
-rw-r--r--gawkapi.c42
1 files changed, 40 insertions, 2 deletions
diff --git a/gawkapi.c b/gawkapi.c
index b6d83acb..e8d50e8c 100644
--- a/gawkapi.c
+++ b/gawkapi.c
@@ -26,6 +26,7 @@
#include "awk.h"
static awk_bool_t node_to_awk_value(NODE *node, awk_value_t *result, awk_valtype_t wanted);
+static void set_constant();
/*
* Get the count'th paramater, zero-based.
@@ -460,10 +461,13 @@ api_sym_lookup_scalar(awk_ext_id_t id,
return node_to_awk_value(node, result, wanted);
}
-/* api_sym_update --- update a symbol's value, see gawkapi.h for semantics */
+/* api_sym_update_real --- update a symbol's value, see gawkapi.h for semantics */
static awk_bool_t
-api_sym_update(awk_ext_id_t id, const char *name, awk_value_t *value)
+sym_update_real(awk_ext_id_t id,
+ const char *name,
+ awk_value_t *value,
+ bool is_const)
{
NODE *node;
NODE *array_node;
@@ -503,6 +507,8 @@ api_sym_update(awk_ext_id_t id, const char *name, awk_value_t *value)
Node_var);
unref(node->var_value);
node->var_value = awk_value_to_node(value);
+ if (is_const)
+ node->var_assign = set_constant;
}
return true;
}
@@ -518,6 +524,9 @@ api_sym_update(awk_ext_id_t id, const char *name, awk_value_t *value)
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;
}
@@ -530,6 +539,26 @@ api_sym_update(awk_ext_id_t id, const char *name, awk_value_t *value)
return true;
}
+/* api_sym_update --- update a symbol, non-constant */
+
+static awk_bool_t
+api_sym_update(awk_ext_id_t id,
+ const char *name,
+ awk_value_t *value)
+{
+ return sym_update_real(id, name, value, false);
+}
+
+/* api_sym_update --- update a symbol, constant */
+
+static awk_bool_t
+api_sym_constant(awk_ext_id_t id,
+ const char *name,
+ awk_value_t *value)
+{
+ return sym_update_real(id, name, value, true);
+}
+
/* api_sym_update_scalar --- update a scalar cookie */
static awk_bool_t
@@ -864,6 +893,7 @@ gawk_api_t api_impl = {
api_sym_lookup,
api_sym_lookup_scalar,
api_sym_update,
+ api_sym_constant,
api_sym_update_scalar,
api_get_array_element,
@@ -897,3 +927,11 @@ update_ext_api()
{
api_impl.do_flags[0] = (do_lint ? 1 : 0);
}
+
+/* set_constant --- prevent awk code from changing a constant */
+
+static void
+set_constant()
+{
+ fatal(_("cannot assign to defined constant"));
+}