aboutsummaryrefslogtreecommitdiffstats
path: root/gawkapi.c
diff options
context:
space:
mode:
Diffstat (limited to 'gawkapi.c')
-rw-r--r--gawkapi.c53
1 files changed, 45 insertions, 8 deletions
diff --git a/gawkapi.c b/gawkapi.c
index 4435ad10..90f328f8 100644
--- a/gawkapi.c
+++ b/gawkapi.c
@@ -160,6 +160,9 @@ awk_value_to_node(const awk_value_t *retval)
case AWK_UNDEFINED:
ext_ret_val = dupnode(Nnull_string);
break;
+ case AWK_BOOL:
+ ext_ret_val = make_bool_node(retval->bool_value != awk_false);
+ break;
case AWK_NUMBER:
switch (retval->num_type) {
case AWK_NUMBER_TYPE_DOUBLE:
@@ -173,6 +176,7 @@ awk_value_to_node(const awk_value_t *retval)
mpfr_init(ext_ret_val->mpg_numbr);
tval = mpfr_set(ext_ret_val->mpg_numbr, (mpfr_srcptr) retval->num_ptr, ROUND_MODE);
IEEE_FMT(ext_ret_val->mpg_numbr, tval);
+ mpfr_clear(retval->num_ptr);
#else
fatal(_("awk_value_to_node: MPFR not supported"));
#endif
@@ -182,7 +186,9 @@ awk_value_to_node(const awk_value_t *retval)
if (! do_mpfr)
fatal(_("awk_value_to_node: not in MPFR mode"));
ext_ret_val = make_number_node(MPZN);
+ mpz_init(ext_ret_val->mpg_i);
mpz_set(ext_ret_val->mpg_i, (mpz_ptr) retval->num_ptr);
+ mpz_clear(retval->num_ptr);
#else
fatal(_("awk_value_to_node: MPFR not supported"));
#endif
@@ -533,6 +539,16 @@ assign_regex(NODE *node, awk_value_t *val)
val->val_type = AWK_REGEX;
}
+/* assign_bool --- return a bool node */
+
+static inline void
+assign_bool(NODE *node, awk_value_t *val)
+{
+ assert((node->flags & BOOL) != 0);
+ val->val_type = AWK_BOOL;
+ val->bool_value = get_number_si(node) != 0 ? awk_true : awk_false;
+}
+
/* node_to_awk_value --- convert a node into a value for an extension */
static awk_bool_t
@@ -568,8 +584,16 @@ node_to_awk_value(NODE *node, awk_value_t *val, awk_valtype_t wanted)
case Node_val:
/* a scalar value */
switch (wanted) {
+ case AWK_BOOL:
+ if ((node->flags & BOOL) != 0) {
+ assign_bool(node, val);
+ ret = awk_true;
+ } else
+ ret = awk_false;
+ break;
+
case AWK_NUMBER:
- if (node->flags & REGEX)
+ if ((node->flags & REGEX) != 0)
val->val_type = AWK_REGEX;
else {
(void) force_number(node);
@@ -579,7 +603,10 @@ node_to_awk_value(NODE *node, awk_value_t *val, awk_valtype_t wanted)
break;
case AWK_STRNUM:
- switch (fixtype(node)->flags & (STRING|NUMBER|USER_INPUT|REGEX)) {
+ switch (fixtype(node)->flags & (STRING|NUMBER|USER_INPUT|REGEX|BOOL)) {
+ case NUMBER|BOOL:
+ val->val_type = AWK_BOOL;
+ break;
case STRING:
val->val_type = AWK_STRING;
break;
@@ -613,10 +640,13 @@ node_to_awk_value(NODE *node, awk_value_t *val, awk_valtype_t wanted)
break;
case AWK_REGEX:
- switch (fixtype(node)->flags & (STRING|NUMBER|USER_INPUT|REGEX)) {
+ switch (fixtype(node)->flags & (STRING|NUMBER|USER_INPUT|REGEX|BOOL)) {
case STRING:
val->val_type = AWK_STRING;
break;
+ case NUMBER|BOOL:
+ val->val_type = AWK_BOOL;
+ break;
case NUMBER:
val->val_type = AWK_NUMBER;
break;
@@ -641,7 +671,10 @@ node_to_awk_value(NODE *node, awk_value_t *val, awk_valtype_t wanted)
break;
case AWK_SCALAR:
- switch (fixtype(node)->flags & (STRING|NUMBER|USER_INPUT|REGEX)) {
+ switch (fixtype(node)->flags & (STRING|NUMBER|USER_INPUT|REGEX|BOOL)) {
+ case NUMBER|BOOL:
+ val->val_type = AWK_BOOL;
+ break;
case STRING:
val->val_type = AWK_STRING;
break;
@@ -669,7 +702,11 @@ node_to_awk_value(NODE *node, awk_value_t *val, awk_valtype_t wanted)
case AWK_UNDEFINED:
/* return true and actual type for request of undefined */
- switch (fixtype(node)->flags & (STRING|NUMBER|USER_INPUT|REGEX)) {
+ switch (fixtype(node)->flags & (STRING|NUMBER|USER_INPUT|REGEX|BOOL)) {
+ case NUMBER|BOOL:
+ assign_bool(node, val);
+ ret = awk_true;
+ break;
case STRING:
assign_string(node, val, AWK_STRING);
ret = awk_true;
@@ -847,7 +884,8 @@ api_sym_update(awk_ext_id_t id,
/*
* If we get here, then it exists already. Any valid type is
- * OK except for AWK_ARRAY.
+ * OK except for AWK_ARRAY (unless it is in Node_var_new undefined
+ * state, in which case an array is OK).
*/
if ( (node->flags & NO_EXT_SET) != 0
|| is_off_limits_var(full_name)) { /* most built-in vars not allowed */
@@ -858,8 +896,7 @@ api_sym_update(awk_ext_id_t id,
efree((void *) full_name);
- if ( value->val_type != AWK_ARRAY
- && (node->type == Node_var || node->type == Node_var_new)) {
+ if ((node->type == Node_var && value->val_type != AWK_ARRAY) || node->type == Node_var_new) {
unref(node->var_value);
node->var_value = awk_value_to_node(value);
if (node->type == Node_var_new && value->val_type != AWK_UNDEFINED)