diff options
author | Arnold D. Robbins <arnold@skeeve.com> | 2012-05-30 21:47:18 +0300 |
---|---|---|
committer | Arnold D. Robbins <arnold@skeeve.com> | 2012-05-30 21:47:18 +0300 |
commit | e6ddb0631c88b591792e3486f857ca26875de310 (patch) | |
tree | e55826965fc73e1c4615f16490b619f823c8239f /gawkapi.c | |
parent | 04dc190623f0d99d80387b33ca747b8cbad37724 (diff) | |
download | egawk-e6ddb0631c88b591792e3486f857ca26875de310.tar.gz egawk-e6ddb0631c88b591792e3486f857ca26875de310.tar.bz2 egawk-e6ddb0631c88b591792e3486f857ca26875de310.zip |
Continue refining extension API and implementation.
Diffstat (limited to 'gawkapi.c')
-rw-r--r-- | gawkapi.c | 112 |
1 files changed, 80 insertions, 32 deletions
@@ -59,8 +59,7 @@ awk_value_to_node(const awk_value_t *retval) ext_ret_val = NULL; if (retval->val_type == AWK_ARRAY) { - getnode(ext_ret_val); - *ext_ret_val = *((NODE *) retval->array_cookie); + ext_ret_val = (NODE *) retval->array_cookie; } else if (retval->val_type == AWK_UNDEFINED) { ext_ret_val = dupnode(Nnull_string); } else if (retval->val_type == AWK_NUMBER) { @@ -68,6 +67,7 @@ awk_value_to_node(const awk_value_t *retval) } else { ext_ret_val = make_string(retval->str_value.str, retval->str_value.len); } + return ext_ret_val; } @@ -175,7 +175,8 @@ run_ext_exit_handlers(int exitval) list_head = NULL; } -/* Add an exit call back, returns true upon success */ +/* api_awk_atexit --- add an exit call back, returns true upon success */ + static awk_bool_t api_awk_atexit(awk_ext_id_t id, void (*funcp)(void *data, int exit_status), @@ -196,61 +197,80 @@ api_awk_atexit(awk_ext_id_t id, return true; /* for now */ } -/* - * Symbol table access: - * - No access to special variables (NF, etc.) - * - One special exception: PROCINFO. - * - Use sym_update() to change a value, including from UNDEFINED - * to scalar or array. - */ +/* node_to_awk_value --- convert a node into a value for an extension */ + static awk_value_t * node_to_awk_value(NODE *node, awk_value_t *val, awk_valtype_t wanted) { + /* clear out the result */ memset(val, 0, sizeof(*val)); - if (node->type != Node_var_array) { - /* make sure both values are valid */ - (void) force_number(node); - (void) force_string(node); + switch (wanted) { + case AWK_NUMBER: + case AWK_STRING: + /* handle it below */ + break; + + case AWK_UNDEFINED: + /* ignore the actual value. weird but could happen */ + val->val_type = AWK_UNDEFINED; + return val; + + case AWK_ARRAY: + if (node->type == Node_var_array) { + val->val_type = AWK_ARRAY; + val->array_cookie = node; + + return val; + } + return NULL; + + default: + fatal(_("node_to_awk_value: invalid value for `wanted' (%d)"), wanted); + break; } + /* get here only for string or number */ + switch (node->type) { case Node_var: node = node->var_value; /* FALL THROUGH */ case Node_val: - if (node->flags & NUMBER) { + /* make sure both values are valid */ + (void) force_number(node); + (void) force_string(node); + + if (wanted == AWK_NUMBER) { val->val_type = AWK_NUMBER; val->num_value = get_number_d(node); val->str_value.str = node->stptr; val->str_value.len = node->stlen; - } else if (node->flags & STRING) { + } else if (wanted == AWK_STRING) { val->val_type = AWK_STRING; val->str_value.str = node->stptr; val->str_value.len = node->stlen; val->num_value = get_number_d(node); - } else { - return NULL; } - break; + return val; case Node_var_new: - val->val_type = AWK_UNDEFINED; - break; - case Node_var_array: - val->val_type = AWK_ARRAY; - val->array_cookie = node; - break; - default: - return NULL; + break; } - return val; + return NULL; } /* + * Symbol table access: + * - No access to special variables (NF, etc.) + * - One special exception: PROCINFO. + * - Use sym_update() to change a value, including from UNDEFINED + * to scalar or array. + */ +/* * Lookup a variable, return its value. No messing with the value * returned. Return value is NULL if the variable doesn't exist. * Built-in variables (except PROCINFO) may not be changed by an extension. @@ -271,13 +291,41 @@ api_sym_lookup(awk_ext_id_t id, return node_to_awk_value(node, result, wanted); } -/* - * Update a value. Adds it to the symbol table if not there. - * Changing types is not allowed. - */ +/* api_sym_update --- update a 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) { + NODE *node; + + if ( name == NULL + || *name == '\0' + || value == NULL + || is_off_limits_var(name)) /* most built-in vars not allowed */ + return false; + + node = lookup(name); + + if (node == NULL) { + /* new value to be installed */ + } else { + /* existing value to be updated */ + } + + switch (value->val_type) { + case AWK_NUMBER: + case AWK_STRING: + case AWK_UNDEFINED: + break; + + case AWK_ARRAY: + return false; + + default: + fatal(_("api_sym_update: invalid value for type of new value (%d)"), value->val_type); + return false; + } + return true; /* for now */ } |