|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
* gawkapi.c -- Implement the functions defined for gawkapi.h
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
* Copyright (C) 2012-2018 the Free Software Foundation, Inc.
|
|
Packit Service |
f629e6 |
*
|
|
Packit Service |
f629e6 |
* This file is part of GAWK, the GNU implementation of the
|
|
Packit Service |
f629e6 |
* AWK Programming Language.
|
|
Packit Service |
f629e6 |
*
|
|
Packit Service |
f629e6 |
* GAWK is free software; you can redistribute it and/or modify
|
|
Packit Service |
f629e6 |
* it under the terms of the GNU General Public License as published by
|
|
Packit Service |
f629e6 |
* the Free Software Foundation; either version 3 of the License, or
|
|
Packit Service |
f629e6 |
* (at your option) any later version.
|
|
Packit Service |
f629e6 |
*
|
|
Packit Service |
f629e6 |
* GAWK is distributed in the hope that it will be useful,
|
|
Packit Service |
f629e6 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
f629e6 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit Service |
f629e6 |
* GNU General Public License for more details.
|
|
Packit Service |
f629e6 |
*
|
|
Packit Service |
f629e6 |
* You should have received a copy of the GNU General Public License
|
|
Packit Service |
f629e6 |
* along with this program; if not, write to the Free Software
|
|
Packit Service |
f629e6 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
#include "awk.h"
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
#ifdef HAVE_MPFR
|
|
Packit Service |
f629e6 |
#define getmpfr(n) getblock(n, BLOCK_MPFR, mpfr_ptr)
|
|
Packit Service |
f629e6 |
#define freempfr(n) freeblock(n, BLOCK_MPFR)
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
#define getmpz(n) getblock(n, BLOCK_MPZ, mpz_ptr)
|
|
Packit Service |
f629e6 |
#define freempz(n) freeblock(n, BLOCK_MPZ)
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* Declare some globals used by api_get_file: */
|
|
Packit Service |
f629e6 |
extern IOBUF *curfile;
|
|
Packit Service |
f629e6 |
extern INSTRUCTION *main_beginfile;
|
|
Packit Service |
f629e6 |
extern int currule;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static awk_bool_t node_to_awk_value(NODE *node, awk_value_t *result, awk_valtype_t wanted);
|
|
Packit Service |
f629e6 |
static char *valtype2str(awk_valtype_t type);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
* api_get_argument --- get the count'th paramater, zero-based.
|
|
Packit Service |
f629e6 |
*
|
|
Packit Service |
f629e6 |
* Returns false if count is out of range, or if actual paramater
|
|
Packit Service |
f629e6 |
* does not match what is specified in wanted. In the latter
|
|
Packit Service |
f629e6 |
* case, fills in result->val_type with the actual type.
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static awk_bool_t
|
|
Packit Service |
f629e6 |
api_get_argument(awk_ext_id_t id, size_t count,
|
|
Packit Service |
f629e6 |
awk_valtype_t wanted, awk_value_t *result)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
#ifdef DYNAMIC
|
|
Packit Service |
f629e6 |
NODE *arg;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (result == NULL)
|
|
Packit Service |
f629e6 |
return awk_false;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
(void) id;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* set up default result */
|
|
Packit Service |
f629e6 |
memset(result, 0, sizeof(*result));
|
|
Packit Service |
f629e6 |
result->val_type = AWK_UNDEFINED;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
* Song and dance here. get_array_argument() and get_scalar_argument()
|
|
Packit Service |
f629e6 |
* will force a change in type of a parameter that is Node_var_new.
|
|
Packit Service |
f629e6 |
*
|
|
Packit Service |
f629e6 |
* Start by looking at the unadulterated argument as it was passed.
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
arg = get_argument(count);
|
|
Packit Service |
f629e6 |
if (arg == NULL)
|
|
Packit Service |
f629e6 |
return awk_false;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* if type is undefined */
|
|
Packit Service |
f629e6 |
if (arg->type == Node_var_new) {
|
|
Packit Service |
f629e6 |
if (wanted == AWK_UNDEFINED)
|
|
Packit Service |
f629e6 |
return true;
|
|
Packit Service |
f629e6 |
else if (wanted == AWK_ARRAY) {
|
|
Packit Service |
f629e6 |
goto array;
|
|
Packit Service |
f629e6 |
} else {
|
|
Packit Service |
f629e6 |
goto scalar;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* at this point, we have real type */
|
|
Packit Service |
f629e6 |
if (arg->type == Node_var_array || arg->type == Node_array_ref) {
|
|
Packit Service |
f629e6 |
if (wanted != AWK_ARRAY && wanted != AWK_UNDEFINED)
|
|
Packit Service |
f629e6 |
return false;
|
|
Packit Service |
f629e6 |
goto array;
|
|
Packit Service |
f629e6 |
} else
|
|
Packit Service |
f629e6 |
goto scalar;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
array:
|
|
Packit Service |
f629e6 |
/* get the array here */
|
|
Packit Service |
f629e6 |
arg = get_array_argument(arg, count);
|
|
Packit Service |
f629e6 |
if (arg == NULL)
|
|
Packit Service |
f629e6 |
return awk_false;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
return node_to_awk_value(arg, result, wanted);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
scalar:
|
|
Packit Service |
f629e6 |
/* at this point we have a real type that is not an array */
|
|
Packit Service |
f629e6 |
arg = get_scalar_argument(arg, count);
|
|
Packit Service |
f629e6 |
if (arg == NULL)
|
|
Packit Service |
f629e6 |
return awk_false;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
return node_to_awk_value(arg, result, wanted);
|
|
Packit Service |
f629e6 |
#else
|
|
Packit Service |
f629e6 |
return awk_false;
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* api_set_argument --- convert an argument to an array */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static awk_bool_t
|
|
Packit Service |
f629e6 |
api_set_argument(awk_ext_id_t id,
|
|
Packit Service |
f629e6 |
size_t count,
|
|
Packit Service |
f629e6 |
awk_array_t new_array)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
#ifdef DYNAMIC
|
|
Packit Service |
f629e6 |
NODE *arg;
|
|
Packit Service |
f629e6 |
NODE *array = (NODE *) new_array;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
(void) id;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (array == NULL || array->type != Node_var_array)
|
|
Packit Service |
f629e6 |
return awk_false;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if ( (arg = get_argument(count)) == NULL
|
|
Packit Service |
f629e6 |
|| arg->type != Node_var_new)
|
|
Packit Service |
f629e6 |
return awk_false;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
arg = get_array_argument(arg, count);
|
|
Packit Service |
f629e6 |
if (arg == NULL)
|
|
Packit Service |
f629e6 |
return awk_false;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
array->vname = arg->vname;
|
|
Packit Service |
f629e6 |
*arg = *array;
|
|
Packit Service |
f629e6 |
freenode(array);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
return awk_true;
|
|
Packit Service |
f629e6 |
#else
|
|
Packit Service |
f629e6 |
return awk_false;
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* awk_value_to_node --- convert a value into a NODE */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
NODE *
|
|
Packit Service |
f629e6 |
awk_value_to_node(const awk_value_t *retval)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
NODE *ext_ret_val = NULL;
|
|
Packit Service |
f629e6 |
NODE *v;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (retval == NULL)
|
|
Packit Service |
f629e6 |
fatal(_("awk_value_to_node: received null retval"));
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
switch (retval->val_type) {
|
|
Packit Service |
f629e6 |
case AWK_ARRAY:
|
|
Packit Service |
f629e6 |
ext_ret_val = (NODE *) retval->array_cookie;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
case AWK_UNDEFINED:
|
|
Packit Service |
f629e6 |
ext_ret_val = dupnode(Nnull_string);
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
case AWK_NUMBER:
|
|
Packit Service |
f629e6 |
switch (retval->num_type) {
|
|
Packit Service |
f629e6 |
case AWK_NUMBER_TYPE_DOUBLE:
|
|
Packit Service |
f629e6 |
ext_ret_val = make_number(retval->num_value);
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
case AWK_NUMBER_TYPE_MPFR:
|
|
Packit Service |
f629e6 |
#ifdef HAVE_MPFR
|
|
Packit Service |
f629e6 |
if (! do_mpfr)
|
|
Packit Service |
f629e6 |
fatal(_("awk_value_to_node: not in MPFR mode"));
|
|
Packit Service |
f629e6 |
ext_ret_val = make_number_node(MPFN);
|
|
Packit Service |
f629e6 |
memcpy(&ext_ret_val->mpg_numbr, retval->num_ptr, sizeof(ext_ret_val->mpg_numbr));
|
|
Packit Service |
f629e6 |
freempfr(retval->num_ptr);
|
|
Packit Service |
f629e6 |
#else
|
|
Packit Service |
f629e6 |
fatal(_("awk_value_to_node: MPFR not supported"));
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
case AWK_NUMBER_TYPE_MPZ:
|
|
Packit Service |
f629e6 |
#ifdef HAVE_MPFR
|
|
Packit Service |
f629e6 |
if (! do_mpfr)
|
|
Packit Service |
f629e6 |
fatal(_("awk_value_to_node: not in MPFR mode"));
|
|
Packit Service |
f629e6 |
ext_ret_val = make_number_node(MPZN);
|
|
Packit Service |
f629e6 |
memcpy(&ext_ret_val->mpg_i, retval->num_ptr, sizeof(ext_ret_val->mpg_i));
|
|
Packit Service |
f629e6 |
freempz(retval->num_ptr);
|
|
Packit Service |
f629e6 |
#else
|
|
Packit Service |
f629e6 |
fatal(_("awk_value_to_node: MPFR not supported"));
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
default:
|
|
Packit Service |
f629e6 |
fatal(_("awk_value_to_node: invalid number type `%d'"), retval->num_type);
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
case AWK_STRING:
|
|
Packit Service |
f629e6 |
ext_ret_val = make_str_node(retval->str_value.str,
|
|
Packit Service |
f629e6 |
retval->str_value.len, ALREADY_MALLOCED);
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
case AWK_STRNUM:
|
|
Packit Service |
f629e6 |
ext_ret_val = make_str_node(retval->str_value.str,
|
|
Packit Service |
f629e6 |
retval->str_value.len, ALREADY_MALLOCED);
|
|
Packit Service |
f629e6 |
ext_ret_val->flags |= USER_INPUT;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
case AWK_REGEX:
|
|
Packit Service |
f629e6 |
ext_ret_val = make_typed_regex(retval->str_value.str,
|
|
Packit Service |
f629e6 |
retval->str_value.len);
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
case AWK_SCALAR:
|
|
Packit Service |
f629e6 |
v = (NODE *) retval->scalar_cookie;
|
|
Packit Service |
f629e6 |
if (v->type != Node_var)
|
|
Packit Service |
f629e6 |
ext_ret_val = NULL;
|
|
Packit Service |
f629e6 |
else
|
|
Packit Service |
f629e6 |
ext_ret_val = dupnode(v->var_value);
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
case AWK_VALUE_COOKIE:
|
|
Packit Service |
f629e6 |
ext_ret_val = dupnode((NODE *)(retval->value_cookie));
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
default: /* any invalid type */
|
|
Packit Service |
f629e6 |
ext_ret_val = NULL;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
return ext_ret_val;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* Functions to print messages */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* api_fatal --- print a fatal message and exit */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static void
|
|
Packit Service |
f629e6 |
api_fatal(awk_ext_id_t id, const char *format, ...)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
va_list args;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
(void) id;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
va_start(args, format);
|
|
Packit Service |
f629e6 |
err(true, _("fatal: "), format, args);
|
|
Packit Service |
f629e6 |
va_end(args);
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* api_nonfatal --- print a non fatal error message */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static void
|
|
Packit Service |
f629e6 |
api_nonfatal(awk_ext_id_t id, const char *format, ...)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
va_list args;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
(void) id;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
va_start(args, format);
|
|
Packit Service |
f629e6 |
err(false, _("error: "), format, args);
|
|
Packit Service |
f629e6 |
va_end(args);
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* api_warning --- print a warning message */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static void
|
|
Packit Service |
f629e6 |
api_warning(awk_ext_id_t id, const char *format, ...)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
va_list args;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
(void) id;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
va_start(args, format);
|
|
Packit Service |
f629e6 |
err(false, _("warning: "), format, args);
|
|
Packit Service |
f629e6 |
va_end(args);
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* api_lintwarn --- print a lint warning message and exit if appropriate */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static void
|
|
Packit Service |
f629e6 |
api_lintwarn(awk_ext_id_t id, const char *format, ...)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
va_list args;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
(void) id;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
va_start(args, format);
|
|
Packit Service |
f629e6 |
if (lintwarn == r_fatal) {
|
|
Packit Service |
f629e6 |
err(true, _("fatal: "), format, args);
|
|
Packit Service |
f629e6 |
} else {
|
|
Packit Service |
f629e6 |
err(false, _("warning: "), format, args);
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
va_end(args);
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* api_register_input_parser --- register an input_parser; for opening files read-only */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static void
|
|
Packit Service |
f629e6 |
api_register_input_parser(awk_ext_id_t id, awk_input_parser_t *input_parser)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
(void) id;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (input_parser == NULL)
|
|
Packit Service |
f629e6 |
return;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
register_input_parser(input_parser);
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* api_register_output_wrapper --- register an output wrapper, for writing files / two-way pipes */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static void api_register_output_wrapper(awk_ext_id_t id,
|
|
Packit Service |
f629e6 |
awk_output_wrapper_t *output_wrapper)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
(void) id;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (output_wrapper == NULL)
|
|
Packit Service |
f629e6 |
return;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
register_output_wrapper(output_wrapper);
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* api_register_two_way_processor --- register a processor for two way I/O */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static void
|
|
Packit Service |
f629e6 |
api_register_two_way_processor(awk_ext_id_t id,
|
|
Packit Service |
f629e6 |
awk_two_way_processor_t *two_way_processor)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
(void) id;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (two_way_processor == NULL)
|
|
Packit Service |
f629e6 |
return;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
register_two_way_processor(two_way_processor);
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* Functions to update ERRNO */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* api_update_ERRNO_int --- update ERRNO with an integer value */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static void
|
|
Packit Service |
f629e6 |
api_update_ERRNO_int(awk_ext_id_t id, int errno_val)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
(void) id;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
update_ERRNO_int(errno_val);
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* api_update_ERRNO_string --- update ERRNO with a string value */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static void
|
|
Packit Service |
f629e6 |
api_update_ERRNO_string(awk_ext_id_t id,
|
|
Packit Service |
f629e6 |
const char *string)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
(void) id;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (string == NULL)
|
|
Packit Service |
f629e6 |
return;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
update_ERRNO_string(string);
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* api_unset_ERRNO --- unset ERRNO */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static void
|
|
Packit Service |
f629e6 |
api_unset_ERRNO(awk_ext_id_t id)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
(void) id;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
unset_ERRNO();
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* api_add_ext_func --- add a function to the interpreter, returns true upon success */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static awk_bool_t
|
|
Packit Service |
f629e6 |
api_add_ext_func(awk_ext_id_t id,
|
|
Packit Service |
f629e6 |
const char *namespace,
|
|
Packit Service |
f629e6 |
awk_ext_func_t *func)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
(void) id;
|
|
Packit Service |
f629e6 |
(void) namespace;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (func == NULL)
|
|
Packit Service |
f629e6 |
return awk_false;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
#ifdef DYNAMIC
|
|
Packit Service |
f629e6 |
return make_builtin(func);
|
|
Packit Service |
f629e6 |
#else
|
|
Packit Service |
f629e6 |
return awk_false;
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* Stuff for exit handler - do it as linked list */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
struct ext_exit_handler {
|
|
Packit Service |
f629e6 |
struct ext_exit_handler *next;
|
|
Packit Service |
f629e6 |
void (*funcp)(void *data, int exit_status);
|
|
Packit Service |
f629e6 |
void *arg0;
|
|
Packit Service |
f629e6 |
};
|
|
Packit Service |
f629e6 |
static struct ext_exit_handler *list_head = NULL;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* run_ext_exit_handlers --- run the extension exit handlers, LIFO order */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
void
|
|
Packit Service |
f629e6 |
run_ext_exit_handlers(int exitval)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
struct ext_exit_handler *p, *next;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
for (p = list_head; p != NULL; p = next) {
|
|
Packit Service |
f629e6 |
next = p->next;
|
|
Packit Service |
f629e6 |
p->funcp(p->arg0, exitval);
|
|
Packit Service |
f629e6 |
free(p);
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
list_head = NULL;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* api_awk_atexit --- add an exit call back */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static void
|
|
Packit Service |
f629e6 |
api_awk_atexit(awk_ext_id_t id,
|
|
Packit Service |
f629e6 |
void (*funcp)(void *data, int exit_status),
|
|
Packit Service |
f629e6 |
void *arg0)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
struct ext_exit_handler *p;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
(void) id;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (funcp == NULL)
|
|
Packit Service |
f629e6 |
return;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* allocate memory */
|
|
Packit Service |
f629e6 |
emalloc(p, struct ext_exit_handler *, sizeof(struct ext_exit_handler), "api_awk_atexit");
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* fill it in */
|
|
Packit Service |
f629e6 |
p->funcp = funcp;
|
|
Packit Service |
f629e6 |
p->arg0 = arg0;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* add to linked list, LIFO order */
|
|
Packit Service |
f629e6 |
p->next = list_head;
|
|
Packit Service |
f629e6 |
list_head = p;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static struct {
|
|
Packit Service |
f629e6 |
char **strings;
|
|
Packit Service |
f629e6 |
size_t i, size;
|
|
Packit Service |
f629e6 |
} scopy;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* free_api_string_copies --- release memory used by string copies */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
void
|
|
Packit Service |
f629e6 |
free_api_string_copies()
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
size_t i;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
for (i = 0; i < scopy.i; i++)
|
|
Packit Service |
f629e6 |
free(scopy.strings[i]);
|
|
Packit Service |
f629e6 |
scopy.i = 0;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* assign_string --- return a string node with NUL termination */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static inline void
|
|
Packit Service |
f629e6 |
assign_string(NODE *node, awk_value_t *val, awk_valtype_t val_type)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
val->val_type = val_type;
|
|
Packit Service |
f629e6 |
if (node->stptr[node->stlen] != '\0') {
|
|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
* This is an unterminated field string, so make a copy.
|
|
Packit Service |
f629e6 |
* This should happen only for $n where n > 0 and n < NF.
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
char *s;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
assert((node->flags & MALLOC) == 0);
|
|
Packit Service |
f629e6 |
if (scopy.i == scopy.size) {
|
|
Packit Service |
f629e6 |
/* expand list */
|
|
Packit Service |
f629e6 |
if (scopy.size == 0)
|
|
Packit Service |
f629e6 |
scopy.size = 8; /* initial size */
|
|
Packit Service |
f629e6 |
else
|
|
Packit Service |
f629e6 |
scopy.size *= 2;
|
|
Packit Service |
f629e6 |
erealloc(scopy.strings, char **, scopy.size * sizeof(char *), "assign_string");
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
emalloc(s, char *, node->stlen + 1, "assign_string");
|
|
Packit Service |
f629e6 |
memcpy(s, node->stptr, node->stlen);
|
|
Packit Service |
f629e6 |
s[node->stlen] = '\0';
|
|
Packit Service |
f629e6 |
val->str_value.str = scopy.strings[scopy.i++] = s;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
else
|
|
Packit Service |
f629e6 |
val->str_value.str = node->stptr;
|
|
Packit Service |
f629e6 |
val->str_value.len = node->stlen;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* assign_number -- return a number node */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
#define assign_double(val) \
|
|
Packit Service |
f629e6 |
val->num_value = node->numbr; \
|
|
Packit Service |
f629e6 |
val->num_type = AWK_NUMBER_TYPE_DOUBLE; \
|
|
Packit Service |
f629e6 |
val->num_ptr = NULL
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static inline void
|
|
Packit Service |
f629e6 |
assign_number(NODE *node, awk_value_t *val)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
val->val_type = AWK_NUMBER;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
#ifndef HAVE_MPFR
|
|
Packit Service |
f629e6 |
assign_double(val);
|
|
Packit Service |
f629e6 |
#else
|
|
Packit Service |
f629e6 |
switch (node->flags & (MPFN|MPZN)) {
|
|
Packit Service |
f629e6 |
case 0:
|
|
Packit Service |
f629e6 |
assign_double(val);
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
case MPFN:
|
|
Packit Service |
f629e6 |
val->num_value = mpfr_get_d(node->mpg_numbr, ROUND_MODE);
|
|
Packit Service |
f629e6 |
val->num_type = AWK_NUMBER_TYPE_MPFR;
|
|
Packit Service |
f629e6 |
val->num_ptr = &node->mpg_numbr;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
case MPZN:
|
|
Packit Service |
f629e6 |
val->num_value = mpz_get_d(node->mpg_i);
|
|
Packit Service |
f629e6 |
val->num_type = AWK_NUMBER_TYPE_MPZ;
|
|
Packit Service |
f629e6 |
val->num_ptr = &node->mpg_i;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
default:
|
|
Packit Service |
f629e6 |
fatal(_("node_to_awk_value: detected invalid numeric flags combination `%s'; please file a bug report."), flags2str(node->flags));
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
#undef assign_double
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* assign_regex --- return a regex node */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static inline void
|
|
Packit Service |
f629e6 |
assign_regex(NODE *node, awk_value_t *val)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
/* a REGEX node cannot be an unterminated field string */
|
|
Packit Service |
f629e6 |
assert((node->flags & MALLOC) != 0);
|
|
Packit Service |
f629e6 |
assert(node->stptr[node->stlen] == '\0');
|
|
Packit Service |
f629e6 |
val->str_value.str = node->stptr;
|
|
Packit Service |
f629e6 |
val->str_value.len = node->stlen;
|
|
Packit Service |
f629e6 |
val->val_type = AWK_REGEX;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* node_to_awk_value --- convert a node into a value for an extension */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static awk_bool_t
|
|
Packit Service |
f629e6 |
node_to_awk_value(NODE *node, awk_value_t *val, awk_valtype_t wanted)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
awk_bool_t ret = awk_false;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (node == NULL)
|
|
Packit Service |
f629e6 |
fatal(_("node_to_awk_value: received null node"));
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (val == NULL)
|
|
Packit Service |
f629e6 |
fatal(_("node_to_awk_value: received null val"));
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
switch (node->type) {
|
|
Packit Service |
f629e6 |
case Node_var_new: /* undefined variable */
|
|
Packit Service |
f629e6 |
val->val_type = AWK_UNDEFINED;
|
|
Packit Service |
f629e6 |
if (wanted == AWK_UNDEFINED) {
|
|
Packit Service |
f629e6 |
ret = awk_true;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
case Node_var:
|
|
Packit Service |
f629e6 |
/* a scalar value */
|
|
Packit Service |
f629e6 |
if (wanted == AWK_SCALAR) {
|
|
Packit Service |
f629e6 |
val->val_type = AWK_SCALAR;
|
|
Packit Service |
f629e6 |
val->scalar_cookie = (void *) node;
|
|
Packit Service |
f629e6 |
ret = awk_true;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
node = node->var_value;
|
|
Packit Service |
f629e6 |
/* FALL THROUGH */
|
|
Packit Service |
f629e6 |
case Node_val:
|
|
Packit Service |
f629e6 |
/* a scalar value */
|
|
Packit Service |
f629e6 |
switch (wanted) {
|
|
Packit Service |
f629e6 |
case AWK_NUMBER:
|
|
Packit Service |
f629e6 |
if (node->flags & REGEX)
|
|
Packit Service |
f629e6 |
val->val_type = AWK_REGEX;
|
|
Packit Service |
f629e6 |
else {
|
|
Packit Service |
f629e6 |
(void) force_number(node);
|
|
Packit Service |
f629e6 |
assign_number(node, val);
|
|
Packit Service |
f629e6 |
ret = awk_true;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
case AWK_STRNUM:
|
|
Packit Service |
f629e6 |
switch (fixtype(node)->flags & (STRING|NUMBER|USER_INPUT|REGEX)) {
|
|
Packit Service |
f629e6 |
case STRING:
|
|
Packit Service |
f629e6 |
val->val_type = AWK_STRING;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
case NUMBER:
|
|
Packit Service |
f629e6 |
(void) force_string(node);
|
|
Packit Service |
f629e6 |
/* fall through */
|
|
Packit Service |
f629e6 |
case NUMBER|USER_INPUT:
|
|
Packit Service |
f629e6 |
assign_string(node, val, AWK_STRNUM);
|
|
Packit Service |
f629e6 |
ret = awk_true;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
case REGEX:
|
|
Packit Service |
f629e6 |
val->val_type = AWK_REGEX;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
case NUMBER|STRING:
|
|
Packit Service |
f629e6 |
if (node == Nnull_string) {
|
|
Packit Service |
f629e6 |
val->val_type = AWK_UNDEFINED;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
/* fall through */
|
|
Packit Service |
f629e6 |
default:
|
|
Packit Service |
f629e6 |
warning(_("node_to_awk_value detected invalid flags combination `%s'; please file a bug report."), flags2str(node->flags));
|
|
Packit Service |
f629e6 |
val->val_type = AWK_UNDEFINED;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
case AWK_STRING:
|
|
Packit Service |
f629e6 |
(void) force_string(node);
|
|
Packit Service |
f629e6 |
assign_string(node, val, AWK_STRING);
|
|
Packit Service |
f629e6 |
ret = awk_true;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
case AWK_REGEX:
|
|
Packit Service |
f629e6 |
switch (fixtype(node)->flags & (STRING|NUMBER|USER_INPUT|REGEX)) {
|
|
Packit Service |
f629e6 |
case STRING:
|
|
Packit Service |
f629e6 |
val->val_type = AWK_STRING;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
case NUMBER:
|
|
Packit Service |
f629e6 |
val->val_type = AWK_NUMBER;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
case NUMBER|USER_INPUT:
|
|
Packit Service |
f629e6 |
val->val_type = AWK_STRNUM;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
case REGEX:
|
|
Packit Service |
f629e6 |
assign_regex(node, val);
|
|
Packit Service |
f629e6 |
ret = awk_true;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
case NUMBER|STRING:
|
|
Packit Service |
f629e6 |
if (node == Nnull_string) {
|
|
Packit Service |
f629e6 |
val->val_type = AWK_UNDEFINED;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
/* fall through */
|
|
Packit Service |
f629e6 |
default:
|
|
Packit Service |
f629e6 |
warning(_("node_to_awk_value detected invalid flags combination `%s'; please file a bug report."), flags2str(node->flags));
|
|
Packit Service |
f629e6 |
val->val_type = AWK_UNDEFINED;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
case AWK_SCALAR:
|
|
Packit Service |
f629e6 |
switch (fixtype(node)->flags & (STRING|NUMBER|USER_INPUT|REGEX)) {
|
|
Packit Service |
f629e6 |
case STRING:
|
|
Packit Service |
f629e6 |
val->val_type = AWK_STRING;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
case NUMBER:
|
|
Packit Service |
f629e6 |
val->val_type = AWK_NUMBER;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
case NUMBER|USER_INPUT:
|
|
Packit Service |
f629e6 |
val->val_type = AWK_STRNUM;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
case REGEX:
|
|
Packit Service |
f629e6 |
val->val_type = AWK_REGEX;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
case NUMBER|STRING:
|
|
Packit Service |
f629e6 |
if (node == Nnull_string) {
|
|
Packit Service |
f629e6 |
val->val_type = AWK_UNDEFINED;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
/* fall through */
|
|
Packit Service |
f629e6 |
default:
|
|
Packit Service |
f629e6 |
warning(_("node_to_awk_value detected invalid flags combination `%s'; please file a bug report."), flags2str(node->flags));
|
|
Packit Service |
f629e6 |
val->val_type = AWK_UNDEFINED;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
case AWK_UNDEFINED:
|
|
Packit Service |
f629e6 |
/* return true and actual type for request of undefined */
|
|
Packit Service |
f629e6 |
switch (fixtype(node)->flags & (STRING|NUMBER|USER_INPUT|REGEX)) {
|
|
Packit Service |
f629e6 |
case STRING:
|
|
Packit Service |
f629e6 |
assign_string(node, val, AWK_STRING);
|
|
Packit Service |
f629e6 |
ret = awk_true;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
case NUMBER:
|
|
Packit Service |
f629e6 |
assign_number(node, val);
|
|
Packit Service |
f629e6 |
ret = awk_true;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
case NUMBER|USER_INPUT:
|
|
Packit Service |
f629e6 |
assign_string(node, val, AWK_STRNUM);
|
|
Packit Service |
f629e6 |
ret = awk_true;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
case REGEX:
|
|
Packit Service |
f629e6 |
assign_regex(node, val);
|
|
Packit Service |
f629e6 |
ret = awk_true;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
case NUMBER|STRING:
|
|
Packit Service |
f629e6 |
if (node == Nnull_string) {
|
|
Packit Service |
f629e6 |
val->val_type = AWK_UNDEFINED;
|
|
Packit Service |
f629e6 |
ret = awk_true;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
/* fall through */
|
|
Packit Service |
f629e6 |
default:
|
|
Packit Service |
f629e6 |
warning(_("node_to_awk_value detected invalid flags combination `%s'; please file a bug report."), flags2str(node->flags));
|
|
Packit Service |
f629e6 |
val->val_type = AWK_UNDEFINED;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
case AWK_ARRAY:
|
|
Packit Service |
f629e6 |
case AWK_VALUE_COOKIE:
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
case Node_var_array:
|
|
Packit Service |
f629e6 |
val->val_type = AWK_ARRAY;
|
|
Packit Service |
f629e6 |
if (wanted == AWK_ARRAY || wanted == AWK_UNDEFINED) {
|
|
Packit Service |
f629e6 |
val->array_cookie = node;
|
|
Packit Service |
f629e6 |
ret = awk_true;
|
|
Packit Service |
f629e6 |
} else
|
|
Packit Service |
f629e6 |
ret = awk_false;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
default:
|
|
Packit Service |
f629e6 |
val->val_type = AWK_UNDEFINED;
|
|
Packit Service |
f629e6 |
ret = awk_false;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
return ret;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
* Symbol table access:
|
|
Packit Service |
f629e6 |
* - No access to special variables (NF, etc.)
|
|
Packit Service |
f629e6 |
* - One special exception: PROCINFO.
|
|
Packit Service |
f629e6 |
* - Use sym_update() to change a value, including from UNDEFINED
|
|
Packit Service |
f629e6 |
* to scalar or array.
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
* Lookup a variable, fills in value. No messing with the value
|
|
Packit Service |
f629e6 |
* returned. Returns false if the variable doesn't exist
|
|
Packit Service |
f629e6 |
* or the wrong type was requested.
|
|
Packit Service |
f629e6 |
* In the latter case, fills in vaule->val_type with the real type.
|
|
Packit Service |
f629e6 |
* Built-in variables (except PROCINFO) may not be accessed by an extension.
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* api_sym_lookup --- look up a symbol */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static awk_bool_t
|
|
Packit Service |
f629e6 |
api_sym_lookup(awk_ext_id_t id,
|
|
Packit Service |
f629e6 |
const char *name,
|
|
Packit Service |
f629e6 |
awk_valtype_t wanted,
|
|
Packit Service |
f629e6 |
awk_value_t *result)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
NODE *node;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
update_global_values(); /* make sure stuff like NF, NR, are up to date */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if ( name == NULL
|
|
Packit Service |
f629e6 |
|| *name == '\0'
|
|
Packit Service |
f629e6 |
|| result == NULL
|
|
Packit Service |
f629e6 |
|| (node = lookup(name)) == NULL)
|
|
Packit Service |
f629e6 |
return awk_false;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (is_off_limits_var(name)) /* a built-in variable */
|
|
Packit Service |
f629e6 |
node->flags |= NO_EXT_SET;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
return node_to_awk_value(node, result, wanted);
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* api_sym_lookup_scalar --- retrieve the current value of a scalar */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static awk_bool_t
|
|
Packit Service |
f629e6 |
api_sym_lookup_scalar(awk_ext_id_t id,
|
|
Packit Service |
f629e6 |
awk_scalar_t cookie,
|
|
Packit Service |
f629e6 |
awk_valtype_t wanted,
|
|
Packit Service |
f629e6 |
awk_value_t *result)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
NODE *node = (NODE *) cookie;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (node == NULL
|
|
Packit Service |
f629e6 |
|| result == NULL
|
|
Packit Service |
f629e6 |
|| node->type != Node_var)
|
|
Packit Service |
f629e6 |
return awk_false;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
update_global_values(); /* make sure stuff like NF, NR, are up to date */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
return node_to_awk_value(node, result, wanted);
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* api_sym_update --- update a symbol's value, see gawkapi.h for semantics */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static awk_bool_t
|
|
Packit Service |
f629e6 |
api_sym_update(awk_ext_id_t id,
|
|
Packit Service |
f629e6 |
const char *name,
|
|
Packit Service |
f629e6 |
awk_value_t *value)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
NODE *node;
|
|
Packit Service |
f629e6 |
NODE *array_node;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if ( name == NULL
|
|
Packit Service |
f629e6 |
|| *name == '\0'
|
|
Packit Service |
f629e6 |
|| value == NULL)
|
|
Packit Service |
f629e6 |
return awk_false;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
switch (value->val_type) {
|
|
Packit Service |
f629e6 |
case AWK_NUMBER:
|
|
Packit Service |
f629e6 |
case AWK_STRNUM:
|
|
Packit Service |
f629e6 |
case AWK_STRING:
|
|
Packit Service |
f629e6 |
case AWK_REGEX:
|
|
Packit Service |
f629e6 |
case AWK_UNDEFINED:
|
|
Packit Service |
f629e6 |
case AWK_ARRAY:
|
|
Packit Service |
f629e6 |
case AWK_SCALAR:
|
|
Packit Service |
f629e6 |
case AWK_VALUE_COOKIE:
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
default:
|
|
Packit Service |
f629e6 |
/* fatal(_("api_sym_update: invalid value for type of new value (%d)"), value->val_type); */
|
|
Packit Service |
f629e6 |
return awk_false;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
node = lookup(name);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (node == NULL) {
|
|
Packit Service |
f629e6 |
/* new value to be installed */
|
|
Packit Service |
f629e6 |
if (value->val_type == AWK_ARRAY) {
|
|
Packit Service |
f629e6 |
array_node = awk_value_to_node(value);
|
|
Packit Service |
f629e6 |
node = install_symbol(estrdup((char *) name, strlen(name)),
|
|
Packit Service |
f629e6 |
Node_var_array);
|
|
Packit Service |
f629e6 |
array_node->vname = node->vname;
|
|
Packit Service |
f629e6 |
*node = *array_node;
|
|
Packit Service |
f629e6 |
freenode(array_node);
|
|
Packit Service |
f629e6 |
value->array_cookie = node; /* pass new cookie back to extension */
|
|
Packit Service |
f629e6 |
} else {
|
|
Packit Service |
f629e6 |
/* regular variable */
|
|
Packit Service |
f629e6 |
node = install_symbol(estrdup((char *) name, strlen(name)),
|
|
Packit Service |
f629e6 |
Node_var);
|
|
Packit Service |
f629e6 |
node->var_value = awk_value_to_node(value);
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
return awk_true;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
* If we get here, then it exists already. Any valid type is
|
|
Packit Service |
f629e6 |
* OK except for AWK_ARRAY.
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
if ( (node->flags & NO_EXT_SET) != 0
|
|
Packit Service |
f629e6 |
|| is_off_limits_var(name)) { /* most built-in vars not allowed */
|
|
Packit Service |
f629e6 |
node->flags |= NO_EXT_SET;
|
|
Packit Service |
f629e6 |
return awk_false;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if ( value->val_type != AWK_ARRAY
|
|
Packit Service |
f629e6 |
&& (node->type == Node_var || node->type == Node_var_new)) {
|
|
Packit Service |
f629e6 |
unref(node->var_value);
|
|
Packit Service |
f629e6 |
node->var_value = awk_value_to_node(value);
|
|
Packit Service |
f629e6 |
if (node->type == Node_var_new && value->val_type != AWK_UNDEFINED)
|
|
Packit Service |
f629e6 |
node->type = Node_var;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
return awk_true;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
return awk_false;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* api_sym_update_scalar --- update a scalar cookie */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static awk_bool_t
|
|
Packit Service |
f629e6 |
api_sym_update_scalar(awk_ext_id_t id,
|
|
Packit Service |
f629e6 |
awk_scalar_t cookie,
|
|
Packit Service |
f629e6 |
awk_value_t *value)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
NODE *node = (NODE *) cookie;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (value == NULL
|
|
Packit Service |
f629e6 |
|| node == NULL
|
|
Packit Service |
f629e6 |
|| node->type != Node_var
|
|
Packit Service |
f629e6 |
|| (node->flags & NO_EXT_SET) != 0)
|
|
Packit Service |
f629e6 |
return awk_false;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
* Optimization: if valref is 1, and the new value is a string or
|
|
Packit Service |
f629e6 |
* a number, we can avoid calling unref and then making a new node
|
|
Packit Service |
f629e6 |
* by simply installing the new value. First, we follow the same
|
|
Packit Service |
f629e6 |
* recipe used by node.c:r_unref to wipe the current values, and then
|
|
Packit Service |
f629e6 |
* we copy the logic from r_make_number or make_str_node to install
|
|
Packit Service |
f629e6 |
* the new value.
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
switch (value->val_type) {
|
|
Packit Service |
f629e6 |
case AWK_NUMBER:
|
|
Packit Service |
f629e6 |
if (node->var_value->valref == 1 && ! do_mpfr) {
|
|
Packit Service |
f629e6 |
NODE *r = node->var_value;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* r_unref: */
|
|
Packit Service |
f629e6 |
if ((r->flags & (MALLOC|STRCUR)) == (MALLOC|STRCUR))
|
|
Packit Service |
f629e6 |
efree(r->stptr);
|
|
Packit Service |
f629e6 |
free_wstr(r);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* r_make_number: */
|
|
Packit Service |
f629e6 |
r->numbr = value->num_value;
|
|
Packit Service |
f629e6 |
r->flags = MALLOC|NUMBER|NUMCUR;
|
|
Packit Service |
f629e6 |
r->stptr = NULL;
|
|
Packit Service |
f629e6 |
r->stlen = 0;
|
|
Packit Service |
f629e6 |
return awk_true;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
case AWK_STRING:
|
|
Packit Service |
f629e6 |
case AWK_STRNUM:
|
|
Packit Service |
f629e6 |
if (node->var_value->valref == 1) {
|
|
Packit Service |
f629e6 |
NODE *r = node->var_value;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* r_unref: */
|
|
Packit Service |
f629e6 |
if ((r->flags & (MALLOC|STRCUR)) == (MALLOC|STRCUR))
|
|
Packit Service |
f629e6 |
efree(r->stptr);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
mpfr_unset(r);
|
|
Packit Service |
f629e6 |
free_wstr(r);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* make_str_node(s, l, ALREADY_MALLOCED): */
|
|
Packit Service |
f629e6 |
r->numbr = 0;
|
|
Packit Service |
f629e6 |
r->flags = (MALLOC|STRING|STRCUR);
|
|
Packit Service |
f629e6 |
if (value->val_type == AWK_STRNUM)
|
|
Packit Service |
f629e6 |
r->flags |= USER_INPUT;
|
|
Packit Service |
f629e6 |
r->stfmt = STFMT_UNUSED;
|
|
Packit Service |
f629e6 |
r->stptr = value->str_value.str;
|
|
Packit Service |
f629e6 |
r->stlen = value->str_value.len;
|
|
Packit Service |
f629e6 |
#ifdef HAVE_MPFR
|
|
Packit Service |
f629e6 |
r->strndmode = MPFR_round_mode;
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
return awk_true;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
case AWK_REGEX:
|
|
Packit Service |
f629e6 |
case AWK_UNDEFINED:
|
|
Packit Service |
f629e6 |
case AWK_SCALAR:
|
|
Packit Service |
f629e6 |
case AWK_VALUE_COOKIE:
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
default: /* AWK_ARRAY or invalid type */
|
|
Packit Service |
f629e6 |
return awk_false;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* do it the hard (slow) way */
|
|
Packit Service |
f629e6 |
unref(node->var_value);
|
|
Packit Service |
f629e6 |
node->var_value = awk_value_to_node(value);
|
|
Packit Service |
f629e6 |
return awk_true;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
* valid_subscript_type --- test if a type is allowed for an array subscript.
|
|
Packit Service |
f629e6 |
*
|
|
Packit Service |
f629e6 |
* Any scalar value is fine, so only AWK_ARRAY (or an invalid type) is illegal.
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static inline bool
|
|
Packit Service |
f629e6 |
valid_subscript_type(awk_valtype_t valtype)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
switch (valtype) {
|
|
Packit Service |
f629e6 |
case AWK_UNDEFINED:
|
|
Packit Service |
f629e6 |
case AWK_NUMBER:
|
|
Packit Service |
f629e6 |
case AWK_STRNUM:
|
|
Packit Service |
f629e6 |
case AWK_STRING:
|
|
Packit Service |
f629e6 |
case AWK_REGEX:
|
|
Packit Service |
f629e6 |
case AWK_SCALAR:
|
|
Packit Service |
f629e6 |
case AWK_VALUE_COOKIE:
|
|
Packit Service |
f629e6 |
return true;
|
|
Packit Service |
f629e6 |
default: /* AWK_ARRAY or an invalid type */
|
|
Packit Service |
f629e6 |
return false;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* Array management */
|
|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
* api_get_array_element --- teturn the value of an element - read only!
|
|
Packit Service |
f629e6 |
*
|
|
Packit Service |
f629e6 |
* Use set_array_element to change it.
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static awk_bool_t
|
|
Packit Service |
f629e6 |
api_get_array_element(awk_ext_id_t id,
|
|
Packit Service |
f629e6 |
awk_array_t a_cookie,
|
|
Packit Service |
f629e6 |
const awk_value_t *const index,
|
|
Packit Service |
f629e6 |
awk_valtype_t wanted,
|
|
Packit Service |
f629e6 |
awk_value_t *result)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
NODE *array = (NODE *) a_cookie;
|
|
Packit Service |
f629e6 |
NODE *subscript;
|
|
Packit Service |
f629e6 |
NODE **aptr;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* don't check for index len zero, null str is ok as index */
|
|
Packit Service |
f629e6 |
if ( array == NULL
|
|
Packit Service |
f629e6 |
|| array->type != Node_var_array
|
|
Packit Service |
f629e6 |
|| result == NULL
|
|
Packit Service |
f629e6 |
|| index == NULL
|
|
Packit Service |
f629e6 |
|| ! valid_subscript_type(index->val_type))
|
|
Packit Service |
f629e6 |
return awk_false;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
subscript = awk_value_to_node(index);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* if it doesn't exist, return false */
|
|
Packit Service |
f629e6 |
if (in_array(array, subscript) == NULL) {
|
|
Packit Service |
f629e6 |
unref(subscript);
|
|
Packit Service |
f629e6 |
return awk_false;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
aptr = assoc_lookup(array, subscript);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (aptr == NULL) { /* can't happen */
|
|
Packit Service |
f629e6 |
unref(subscript);
|
|
Packit Service |
f629e6 |
return awk_false;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
unref(subscript);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
return node_to_awk_value(*aptr, result, wanted);
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
* api_set_array_element --- change (or create) element in existing array
|
|
Packit Service |
f629e6 |
* with element->index and element->value.
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static awk_bool_t
|
|
Packit Service |
f629e6 |
api_set_array_element(awk_ext_id_t id, awk_array_t a_cookie,
|
|
Packit Service |
f629e6 |
const awk_value_t *const index,
|
|
Packit Service |
f629e6 |
const awk_value_t *const value)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
NODE *array = (NODE *)a_cookie;
|
|
Packit Service |
f629e6 |
NODE *tmp;
|
|
Packit Service |
f629e6 |
NODE *elem;
|
|
Packit Service |
f629e6 |
NODE **aptr;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* don't check for index len zero, null str is ok as index */
|
|
Packit Service |
f629e6 |
if ( array == NULL
|
|
Packit Service |
f629e6 |
|| array->type != Node_var_array
|
|
Packit Service |
f629e6 |
|| (array->flags & NO_EXT_SET) != 0
|
|
Packit Service |
f629e6 |
|| index == NULL
|
|
Packit Service |
f629e6 |
|| value == NULL
|
|
Packit Service |
f629e6 |
|| ! valid_subscript_type(index->val_type))
|
|
Packit Service |
f629e6 |
return awk_false;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
tmp = awk_value_to_node(index);
|
|
Packit Service |
f629e6 |
aptr = assoc_lookup(array, tmp);
|
|
Packit Service |
f629e6 |
unref(*aptr);
|
|
Packit Service |
f629e6 |
elem = *aptr = awk_value_to_node(value);
|
|
Packit Service |
f629e6 |
if (elem->type == Node_var_array) {
|
|
Packit Service |
f629e6 |
elem->parent_array = array;
|
|
Packit Service |
f629e6 |
elem->vname = estrdup(index->str_value.str,
|
|
Packit Service |
f629e6 |
index->str_value.len);
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
if (array->astore != NULL)
|
|
Packit Service |
f629e6 |
(*array->astore)(array, tmp);
|
|
Packit Service |
f629e6 |
unref(tmp);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
return awk_true;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
* remove_element --- remove an array element
|
|
Packit Service |
f629e6 |
* common code used by multiple functions
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static void
|
|
Packit Service |
f629e6 |
remove_element(NODE *array, NODE *subscript)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
NODE *val;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (array == NULL)
|
|
Packit Service |
f629e6 |
fatal(_("remove_element: received null array"));
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (subscript == NULL)
|
|
Packit Service |
f629e6 |
fatal(_("remove_element: received null subscript"));
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
val = in_array(array, subscript);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (val == NULL)
|
|
Packit Service |
f629e6 |
return;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (val->type == Node_var_array) {
|
|
Packit Service |
f629e6 |
assoc_clear(val);
|
|
Packit Service |
f629e6 |
/* cleared a sub-array, free Node_var_array */
|
|
Packit Service |
f629e6 |
efree(val->vname);
|
|
Packit Service |
f629e6 |
freenode(val);
|
|
Packit Service |
f629e6 |
} else
|
|
Packit Service |
f629e6 |
unref(val);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
(void) assoc_remove(array, subscript);
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
* api_del_array_element --- remove the element with the given index.
|
|
Packit Service |
f629e6 |
* Return success if removed or if element did not exist.
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static awk_bool_t
|
|
Packit Service |
f629e6 |
api_del_array_element(awk_ext_id_t id,
|
|
Packit Service |
f629e6 |
awk_array_t a_cookie, const awk_value_t* const index)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
NODE *array, *sub;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
array = (NODE *) a_cookie;
|
|
Packit Service |
f629e6 |
if ( array == NULL
|
|
Packit Service |
f629e6 |
|| array->type != Node_var_array
|
|
Packit Service |
f629e6 |
|| (array->flags & NO_EXT_SET) != 0
|
|
Packit Service |
f629e6 |
|| index == NULL
|
|
Packit Service |
f629e6 |
|| ! valid_subscript_type(index->val_type))
|
|
Packit Service |
f629e6 |
return awk_false;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
sub = awk_value_to_node(index);
|
|
Packit Service |
f629e6 |
remove_element(array, sub);
|
|
Packit Service |
f629e6 |
unref(sub);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
return awk_true;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
* api_get_element_count --- retrieve total number of elements in array.
|
|
Packit Service |
f629e6 |
* Return false if some kind of error.
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static awk_bool_t
|
|
Packit Service |
f629e6 |
api_get_element_count(awk_ext_id_t id,
|
|
Packit Service |
f629e6 |
awk_array_t a_cookie, size_t *count)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
NODE *node = (NODE *) a_cookie;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (count == NULL || node == NULL || node->type != Node_var_array)
|
|
Packit Service |
f629e6 |
return awk_false;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
*count = node->table_size;
|
|
Packit Service |
f629e6 |
return awk_true;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* api_create_array --- create a new array cookie to which elements may be added */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static awk_array_t
|
|
Packit Service |
f629e6 |
api_create_array(awk_ext_id_t id)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
NODE *n;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
getnode(n);
|
|
Packit Service |
f629e6 |
memset(n, 0, sizeof(NODE));
|
|
Packit Service |
f629e6 |
null_array(n);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
return (awk_array_t) n;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* api_clear_array --- clear out an array */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static awk_bool_t
|
|
Packit Service |
f629e6 |
api_clear_array(awk_ext_id_t id, awk_array_t a_cookie)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
NODE *node = (NODE *) a_cookie;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if ( node == NULL
|
|
Packit Service |
f629e6 |
|| node->type != Node_var_array
|
|
Packit Service |
f629e6 |
|| (node->flags & NO_EXT_SET) != 0)
|
|
Packit Service |
f629e6 |
return awk_false;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
assoc_clear(node);
|
|
Packit Service |
f629e6 |
return awk_true;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* api_flatten_array_typed --- flatten out an array so that it can be looped over easily. */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static awk_bool_t
|
|
Packit Service |
f629e6 |
api_flatten_array_typed(awk_ext_id_t id,
|
|
Packit Service |
f629e6 |
awk_array_t a_cookie,
|
|
Packit Service |
f629e6 |
awk_flat_array_t **data,
|
|
Packit Service |
f629e6 |
awk_valtype_t index_type, awk_valtype_t value_type)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
NODE **list;
|
|
Packit Service |
f629e6 |
size_t i, j;
|
|
Packit Service |
f629e6 |
NODE *array = (NODE *) a_cookie;
|
|
Packit Service |
f629e6 |
size_t alloc_size;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if ( array == NULL
|
|
Packit Service |
f629e6 |
|| array->type != Node_var_array
|
|
Packit Service |
f629e6 |
|| array->table_size == 0
|
|
Packit Service |
f629e6 |
|| data == NULL)
|
|
Packit Service |
f629e6 |
return awk_false;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
alloc_size = sizeof(awk_flat_array_t) +
|
|
Packit Service |
f629e6 |
(array->table_size - 1) * sizeof(awk_element_t);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
ezalloc(*data, awk_flat_array_t *, alloc_size,
|
|
Packit Service |
f629e6 |
"api_flatten_array_typed");
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
list = assoc_list(array, "@unsorted", ASORTI);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
(*data)->opaque1 = array;
|
|
Packit Service |
f629e6 |
(*data)->opaque2 = list;
|
|
Packit Service |
f629e6 |
(*data)->count = array->table_size;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
for (i = j = 0; i < 2 * array->table_size; i += 2, j++) {
|
|
Packit Service |
f629e6 |
NODE *index, *value;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
index = list[i];
|
|
Packit Service |
f629e6 |
value = list[i + 1]; /* number or string or subarray */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* Convert index and value to API types. */
|
|
Packit Service |
f629e6 |
if (! node_to_awk_value(index,
|
|
Packit Service |
f629e6 |
& (*data)->elements[j].index, index_type)) {
|
|
Packit Service |
f629e6 |
fatal(_("api_flatten_array_typed: could not convert index %d to %s\n"),
|
|
Packit Service |
f629e6 |
(int) i, valtype2str(index_type));
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
if (! node_to_awk_value(value,
|
|
Packit Service |
f629e6 |
& (*data)->elements[j].value, value_type)) {
|
|
Packit Service |
f629e6 |
fatal(_("api_flatten_array_typed: could not convert value %d to %s\n"),
|
|
Packit Service |
f629e6 |
(int) i, valtype2str(value_type));
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
return awk_true;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
* api_release_flattened_array --- release array memory,
|
|
Packit Service |
f629e6 |
* delete any marked elements. Count must match what
|
|
Packit Service |
f629e6 |
* gawk thinks the size is.
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static awk_bool_t
|
|
Packit Service |
f629e6 |
api_release_flattened_array(awk_ext_id_t id,
|
|
Packit Service |
f629e6 |
awk_array_t a_cookie,
|
|
Packit Service |
f629e6 |
awk_flat_array_t *data)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
NODE *array = a_cookie;
|
|
Packit Service |
f629e6 |
NODE **list;
|
|
Packit Service |
f629e6 |
size_t i, j, k;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if ( array == NULL
|
|
Packit Service |
f629e6 |
|| array->type != Node_var_array
|
|
Packit Service |
f629e6 |
|| data == NULL
|
|
Packit Service |
f629e6 |
|| array != (NODE *) data->opaque1
|
|
Packit Service |
f629e6 |
|| data->count != array->table_size
|
|
Packit Service |
f629e6 |
|| data->opaque2 == NULL)
|
|
Packit Service |
f629e6 |
return awk_false;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
list = (NODE **) data->opaque2;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* free index nodes */
|
|
Packit Service |
f629e6 |
for (i = j = 0, k = 2 * array->table_size; i < k; i += 2, j++) {
|
|
Packit Service |
f629e6 |
/* Delete items flagged for delete. */
|
|
Packit Service |
f629e6 |
if ( (data->elements[j].flags & AWK_ELEMENT_DELETE) != 0
|
|
Packit Service |
f629e6 |
&& (array->flags & NO_EXT_SET) == 0) {
|
|
Packit Service |
f629e6 |
remove_element(array, list[i]);
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
unref(list[i]);
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
efree(list);
|
|
Packit Service |
f629e6 |
efree(data);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
return awk_true;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* api_create_value --- create a cached value */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static awk_bool_t
|
|
Packit Service |
f629e6 |
api_create_value(awk_ext_id_t id, awk_value_t *value,
|
|
Packit Service |
f629e6 |
awk_value_cookie_t *result)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
if (value == NULL || result == NULL)
|
|
Packit Service |
f629e6 |
return awk_false;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
switch (value->val_type) {
|
|
Packit Service |
f629e6 |
case AWK_NUMBER:
|
|
Packit Service |
f629e6 |
case AWK_STRNUM:
|
|
Packit Service |
f629e6 |
case AWK_STRING:
|
|
Packit Service |
f629e6 |
case AWK_REGEX:
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
default:
|
|
Packit Service |
f629e6 |
/* reject anything other than a simple scalar */
|
|
Packit Service |
f629e6 |
return awk_false;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
return (awk_bool_t) ((*result = awk_value_to_node(value)) != NULL);
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* api_release_value --- release a cached value */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static awk_bool_t
|
|
Packit Service |
f629e6 |
api_release_value(awk_ext_id_t id, awk_value_cookie_t value)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
NODE *val = (NODE *) value;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (val == NULL)
|
|
Packit Service |
f629e6 |
return awk_false;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
unref(val);
|
|
Packit Service |
f629e6 |
return awk_true;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* api_get_mpfr --- allocate an mpfr_ptr */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static void *
|
|
Packit Service |
f629e6 |
api_get_mpfr(awk_ext_id_t id)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
#ifdef HAVE_MPFR
|
|
Packit Service |
f629e6 |
mpfr_ptr p;
|
|
Packit Service |
f629e6 |
getmpfr(p);
|
|
Packit Service |
f629e6 |
mpfr_init(p);
|
|
Packit Service |
f629e6 |
return p;
|
|
Packit Service |
f629e6 |
#else
|
|
Packit Service |
f629e6 |
fatal(_("api_get_mpfr: MPFR not supported"));
|
|
Packit Service |
f629e6 |
return NULL; // silence compiler warning
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* api_get_mpz --- allocate an mpz_ptr */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static void *
|
|
Packit Service |
f629e6 |
api_get_mpz(awk_ext_id_t id)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
#ifdef HAVE_MPFR
|
|
Packit Service |
f629e6 |
mpz_ptr p;
|
|
Packit Service |
f629e6 |
getmpz(p);
|
|
Packit Service |
f629e6 |
mpz_init(p);
|
|
Packit Service |
f629e6 |
return p;
|
|
Packit Service |
f629e6 |
#else
|
|
Packit Service |
f629e6 |
fatal(_("api_get_mpfr: MPFR not supported"));
|
|
Packit Service |
f629e6 |
return NULL; // silence compiler warning
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* api_get_file --- return a handle to an existing or newly opened file */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static awk_bool_t
|
|
Packit Service |
f629e6 |
api_get_file(awk_ext_id_t id, const char *name, size_t namelen, const char *filetype,
|
|
Packit Service |
f629e6 |
int fd, const awk_input_buf_t **ibufp, const awk_output_buf_t **obufp)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
const struct redirect *f;
|
|
Packit Service |
f629e6 |
int flag; /* not used, sigh */
|
|
Packit Service |
f629e6 |
enum redirval redirtype;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (name == NULL || namelen == 0) {
|
|
Packit Service |
f629e6 |
if (curfile == NULL) {
|
|
Packit Service |
f629e6 |
INSTRUCTION *pc;
|
|
Packit Service |
f629e6 |
int save_rule;
|
|
Packit Service |
f629e6 |
char *save_source;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (nextfile(& curfile, false) <= 0)
|
|
Packit Service |
f629e6 |
return awk_false;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
pc = main_beginfile;
|
|
Packit Service |
f629e6 |
/* save execution state */
|
|
Packit Service |
f629e6 |
save_rule = currule;
|
|
Packit Service |
f629e6 |
save_source = source;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
for (;;) {
|
|
Packit Service |
f629e6 |
if (pc == NULL)
|
|
Packit Service |
f629e6 |
fatal(_("cannot find end of BEGINFILE rule"));
|
|
Packit Service |
f629e6 |
if (pc->opcode == Op_after_beginfile)
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
pc = pc->nexti;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
pc->opcode = Op_stop;
|
|
Packit Service |
f629e6 |
(void) (*interpret)(main_beginfile);
|
|
Packit Service |
f629e6 |
pc->opcode = Op_after_beginfile;
|
|
Packit Service |
f629e6 |
after_beginfile(& curfile);
|
|
Packit Service |
f629e6 |
/* restore execution state */
|
|
Packit Service |
f629e6 |
currule = save_rule;
|
|
Packit Service |
f629e6 |
source = save_source;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
*ibufp = &curfile->public;
|
|
Packit Service |
f629e6 |
*obufp = NULL;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
return awk_true;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
redirtype = redirect_none;
|
|
Packit Service |
f629e6 |
switch (filetype[0]) {
|
|
Packit Service |
f629e6 |
case '<':
|
|
Packit Service |
f629e6 |
if (filetype[1] == '\0')
|
|
Packit Service |
f629e6 |
redirtype = redirect_input;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
case '>':
|
|
Packit Service |
f629e6 |
switch (filetype[1]) {
|
|
Packit Service |
f629e6 |
case '\0':
|
|
Packit Service |
f629e6 |
redirtype = redirect_output;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
case '>':
|
|
Packit Service |
f629e6 |
if (filetype[2] == '\0')
|
|
Packit Service |
f629e6 |
redirtype = redirect_append;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
case '|':
|
|
Packit Service |
f629e6 |
if (filetype[2] == '\0') {
|
|
Packit Service |
f629e6 |
switch (filetype[1]) {
|
|
Packit Service |
f629e6 |
case '>':
|
|
Packit Service |
f629e6 |
redirtype = redirect_pipe;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
case '<':
|
|
Packit Service |
f629e6 |
redirtype = redirect_pipein;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
case '&':
|
|
Packit Service |
f629e6 |
redirtype = redirect_twoway;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (redirtype == redirect_none) {
|
|
Packit Service |
f629e6 |
warning(_("cannot open unrecognized file type `%s' for `%s'"),
|
|
Packit Service |
f629e6 |
filetype, name);
|
|
Packit Service |
f629e6 |
return awk_false;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if ((f = redirect_string(name, namelen, 0, redirtype, &flag, fd, false)) == NULL)
|
|
Packit Service |
f629e6 |
return awk_false;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
*ibufp = f->iop ? & f->iop->public : NULL;
|
|
Packit Service |
f629e6 |
*obufp = f->output.fp ? & f->output : NULL;
|
|
Packit Service |
f629e6 |
return awk_true;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
* Register a version string for this extension with gawk.
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
struct version_info {
|
|
Packit Service |
f629e6 |
const char *version;
|
|
Packit Service |
f629e6 |
struct version_info *next;
|
|
Packit Service |
f629e6 |
};
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static struct version_info *vi_head;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* api_register_ext_version --- add an extension version string to the list */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static void
|
|
Packit Service |
f629e6 |
api_register_ext_version(awk_ext_id_t id, const char *version)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
struct version_info *info;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (version == NULL)
|
|
Packit Service |
f629e6 |
return;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
(void) id;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
emalloc(info, struct version_info *, sizeof(struct version_info), "register_ext_version");
|
|
Packit Service |
f629e6 |
info->version = version;
|
|
Packit Service |
f629e6 |
info->next = vi_head;
|
|
Packit Service |
f629e6 |
vi_head = info;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* the struct api */
|
|
Packit Service |
f629e6 |
gawk_api_t api_impl = {
|
|
Packit Service |
f629e6 |
/* data */
|
|
Packit Service |
f629e6 |
GAWK_API_MAJOR_VERSION, /* major and minor versions */
|
|
Packit Service |
f629e6 |
GAWK_API_MINOR_VERSION,
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
#ifdef HAVE_MPFR
|
|
Packit Service |
f629e6 |
__GNU_MP_VERSION,
|
|
Packit Service |
f629e6 |
__GNU_MP_VERSION_MINOR,
|
|
Packit Service |
f629e6 |
MPFR_VERSION_MAJOR,
|
|
Packit Service |
f629e6 |
MPFR_VERSION_MINOR,
|
|
Packit Service |
f629e6 |
#else
|
|
Packit Service |
f629e6 |
0, 0, 0, 0,
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
{ 0 }, /* do_flags */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* registration functions */
|
|
Packit Service |
f629e6 |
api_add_ext_func,
|
|
Packit Service |
f629e6 |
api_register_input_parser,
|
|
Packit Service |
f629e6 |
api_register_output_wrapper,
|
|
Packit Service |
f629e6 |
api_register_two_way_processor,
|
|
Packit Service |
f629e6 |
api_awk_atexit,
|
|
Packit Service |
f629e6 |
api_register_ext_version,
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* message printing functions */
|
|
Packit Service |
f629e6 |
api_fatal,
|
|
Packit Service |
f629e6 |
api_warning,
|
|
Packit Service |
f629e6 |
api_lintwarn,
|
|
Packit Service |
f629e6 |
api_nonfatal,
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* updating ERRNO */
|
|
Packit Service |
f629e6 |
api_update_ERRNO_int,
|
|
Packit Service |
f629e6 |
api_update_ERRNO_string,
|
|
Packit Service |
f629e6 |
api_unset_ERRNO,
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* Function arguments */
|
|
Packit Service |
f629e6 |
api_get_argument,
|
|
Packit Service |
f629e6 |
api_set_argument,
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* Accessing and installing variables and constants */
|
|
Packit Service |
f629e6 |
api_sym_lookup,
|
|
Packit Service |
f629e6 |
api_sym_update,
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* Accessing and modifying variables via scalar cookies */
|
|
Packit Service |
f629e6 |
api_sym_lookup_scalar,
|
|
Packit Service |
f629e6 |
api_sym_update_scalar,
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* Cached values */
|
|
Packit Service |
f629e6 |
api_create_value,
|
|
Packit Service |
f629e6 |
api_release_value,
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* Array management */
|
|
Packit Service |
f629e6 |
api_get_element_count,
|
|
Packit Service |
f629e6 |
api_get_array_element,
|
|
Packit Service |
f629e6 |
api_set_array_element,
|
|
Packit Service |
f629e6 |
api_del_array_element,
|
|
Packit Service |
f629e6 |
api_create_array,
|
|
Packit Service |
f629e6 |
api_clear_array,
|
|
Packit Service |
f629e6 |
api_flatten_array_typed,
|
|
Packit Service |
f629e6 |
api_release_flattened_array,
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* Memory allocation */
|
|
Packit Service |
f629e6 |
malloc,
|
|
Packit Service |
f629e6 |
calloc,
|
|
Packit Service |
f629e6 |
realloc,
|
|
Packit Service |
f629e6 |
free,
|
|
Packit Service |
f629e6 |
api_get_mpfr,
|
|
Packit Service |
f629e6 |
api_get_mpz,
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* Find/open a file */
|
|
Packit Service |
f629e6 |
api_get_file,
|
|
Packit Service |
f629e6 |
};
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* init_ext_api --- init the extension API */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
void
|
|
Packit Service |
f629e6 |
init_ext_api()
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
/* force values to 1 / 0 */
|
|
Packit Service |
f629e6 |
api_impl.do_flags[0] = (do_lint ? 1 : 0);
|
|
Packit Service |
f629e6 |
api_impl.do_flags[1] = (do_traditional ? 1 : 0);
|
|
Packit Service |
f629e6 |
api_impl.do_flags[2] = (do_profile ? 1 : 0);
|
|
Packit Service |
f629e6 |
api_impl.do_flags[3] = (do_sandbox ? 1 : 0);
|
|
Packit Service |
f629e6 |
api_impl.do_flags[4] = (do_debug ? 1 : 0);
|
|
Packit Service |
f629e6 |
api_impl.do_flags[5] = (do_mpfr ? 1 : 0);
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* update_ext_api --- update the variables in the API that can change */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
void
|
|
Packit Service |
f629e6 |
update_ext_api()
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
api_impl.do_flags[0] = (do_lint ? 1 : 0);
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* print_ext_versions --- print the list */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
extern void
|
|
Packit Service |
f629e6 |
print_ext_versions(void)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
struct version_info *p;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
for (p = vi_head; p != NULL; p = p->next)
|
|
Packit Service |
f629e6 |
printf("%s\n", p->version);
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* valtype2str --- return a printable representation of a value type */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static char *
|
|
Packit Service |
f629e6 |
valtype2str(awk_valtype_t type)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
static char buf[100];
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
// Important: keep in same order as in gawkapi.h!
|
|
Packit Service |
f629e6 |
static char *values[] = {
|
|
Packit Service |
f629e6 |
"AWK_UNDEFINED",
|
|
Packit Service |
f629e6 |
"AWK_NUMBER",
|
|
Packit Service |
f629e6 |
"AWK_STRING",
|
|
Packit Service |
f629e6 |
"AWK_REGEX",
|
|
Packit Service |
f629e6 |
"AWK_STRNUM",
|
|
Packit Service |
f629e6 |
"AWK_ARRAY",
|
|
Packit Service |
f629e6 |
"AWK_SCALAR",
|
|
Packit Service |
f629e6 |
"AWK_VALUE_COOKIE",
|
|
Packit Service |
f629e6 |
};
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (AWK_UNDEFINED <= type && type <= AWK_VALUE_COOKIE)
|
|
Packit Service |
f629e6 |
return values[(int) type];
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
sprintf(buf, "unknown type! (%d)", (int) type);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
return buf;
|
|
Packit Service |
f629e6 |
}
|