Commit 5668bf4c authored by Morten Welinder's avatar Morten Welinder Committed by Morten Welinder

Do arg type checking here. (fn_def_new): Not here. (function_remove): Free

2001-06-03  Morten Welinder  <terra@diku.dk>

	* src/func.c (function_add_args): Do arg type checking here.
	(fn_def_new): Not here.
	(function_remove): Free cached arg types.
	(function_add_args): Pre-calculate arg counts and types.
	(function_def_get_full_info_if_needed): Ditto.
	(function_call_with_list): Use pre-calculated arg counts and
 	types.
	(function_add_name_only): Use FUNCTION_NAMEONLY for type.

2001-06-03  Morten Welinder  <terra@diku.dk>

	* fn-information.c (information_functions_init): Don't supply arg
 	spec for node function.
	* fn-lookup.c (lookup_functions_init): Ditto.
	* fn-math.c (math_functions_init): Ditto.
	* fn-eng.c (eng_functions_init): Ditto.

	* fn-date.c (gnumeric_datedif): Constify.
parent 3b01ad11
2001-06-03 Morten Welinder <terra@diku.dk>
* src/func.c (function_add_args): Do arg type checking here.
(fn_def_new): Not here.
(function_remove): Free cached arg types.
(function_add_args): Pre-calculate arg counts and types.
(function_def_get_full_info_if_needed): Ditto.
(function_call_with_list): Use pre-calculated arg counts and
types.
(function_add_name_only): Use FUNCTION_NAMEONLY for type.
2001-06-03 Jody Goldberg <jgoldberg@home.com>
* src/format.c (format_compile) : doh!
......
......@@ -21,6 +21,7 @@ Juan Pablo Mendoza:
Morten:
* Fix PV.
* Applied some much-needed TLC to fn-financial.c and fn-eng.c.
* Speed-up Gnumeric function calls.
Zbigniew:
* More work on plugin system.
......
2001-06-03 Morten Welinder <terra@diku.dk>
* src/func.c (function_add_args): Do arg type checking here.
(fn_def_new): Not here.
(function_remove): Free cached arg types.
(function_add_args): Pre-calculate arg counts and types.
(function_def_get_full_info_if_needed): Ditto.
(function_call_with_list): Use pre-calculated arg counts and
types.
(function_add_name_only): Use FUNCTION_NAMEONLY for type.
2001-06-03 Jody Goldberg <jgoldberg@home.com>
* src/format.c (format_compile) : doh!
......
2001-06-03 Morten Welinder <terra@diku.dk>
* src/func.c (function_add_args): Do arg type checking here.
(fn_def_new): Not here.
(function_remove): Free cached arg types.
(function_add_args): Pre-calculate arg counts and types.
(function_def_get_full_info_if_needed): Ditto.
(function_call_with_list): Use pre-calculated arg counts and
types.
(function_add_name_only): Use FUNCTION_NAMEONLY for type.
2001-06-03 Jody Goldberg <jgoldberg@home.com>
* src/format.c (format_compile) : doh!
......
2001-06-03 Morten Welinder <terra@diku.dk>
* src/func.c (function_add_args): Do arg type checking here.
(fn_def_new): Not here.
(function_remove): Free cached arg types.
(function_add_args): Pre-calculate arg counts and types.
(function_def_get_full_info_if_needed): Ditto.
(function_call_with_list): Use pre-calculated arg counts and
types.
(function_add_name_only): Use FUNCTION_NAMEONLY for type.
2001-06-03 Jody Goldberg <jgoldberg@home.com>
* src/format.c (format_compile) : doh!
......
2001-06-03 Morten Welinder <terra@diku.dk>
* src/func.c (function_add_args): Do arg type checking here.
(fn_def_new): Not here.
(function_remove): Free cached arg types.
(function_add_args): Pre-calculate arg counts and types.
(function_def_get_full_info_if_needed): Ditto.
(function_call_with_list): Use pre-calculated arg counts and
types.
(function_add_name_only): Use FUNCTION_NAMEONLY for type.
2001-06-03 Jody Goldberg <jgoldberg@home.com>
* src/format.c (format_compile) : doh!
......
......@@ -207,7 +207,7 @@ static Value *
gnumeric_datedif (FunctionEvalInfo *ei, Value **argv)
{
int date1, date2;
char *opt;
const char *opt;
GDate *gdate1, *gdate2;
Value *result;
......
......@@ -1939,7 +1939,7 @@ eng_functions_init (void)
cat, "impower", "??", "inumber,inumber",
&help_impower, gnumeric_impower);
function_add_nodes (
cat, "improduct", "??", "inumber,inumber",
cat, "improduct", NULL, "inumber,inumber",
&help_improduct, gnumeric_improduct);
function_add_args (
cat, "imreal", "?", "inumber",
......@@ -1954,7 +1954,7 @@ eng_functions_init (void)
cat, "imsub", "??", "inumber,inumber",
&help_imsub, gnumeric_imsub);
function_add_nodes (
cat, "imsum", "??", "inumber,inumber",
cat, "imsum", NULL, "inumber,inumber",
&help_imsum, gnumeric_imsum);
function_add_args (
cat, "oct2bin", "?|f", "xnum,ynum",
......
......@@ -889,21 +889,21 @@ information_functions_init (void)
&help_countblank, gnumeric_countblank);
function_add_args (cat, "error", "s", "text",
&help_error, gnumeric_error);
function_add_nodes (cat, "error.type", "", "",
function_add_nodes (cat, "error.type", NULL, "",
&help_error_type, gnumeric_error_type);
function_add_args (cat, "info", "s", "info_type",
&help_info, gnumeric_info);
function_add_nodes (cat, "isblank", "?", "value",
function_add_nodes (cat, "isblank", NULL, "value",
&help_isblank, gnumeric_isblank);
function_add_nodes (cat, "iserr", "", "",
function_add_nodes (cat, "iserr", NULL, "",
&help_iserr, gnumeric_iserr);
function_add_nodes (cat, "iserror", "", "",
function_add_nodes (cat, "iserror", NULL, "",
&help_iserror, gnumeric_iserror);
function_add_args (cat, "iseven", "?", "value",
&help_iseven, gnumeric_iseven);
function_add_nodes (cat, "islogical", NULL, "value",
&help_islogical, gnumeric_islogical);
function_add_nodes (cat, "isna", "", "",
function_add_nodes (cat, "isna", NULL, "",
&help_isna, gnumeric_isna);
function_add_nodes (cat, "isnontext", NULL, "value",
&help_isnontext, gnumeric_isnontext);
......@@ -911,7 +911,7 @@ information_functions_init (void)
&help_isnumber, gnumeric_isnumber);
function_add_args (cat, "isodd", "?", "value",
&help_isodd, gnumeric_isodd);
function_add_nodes (cat, "isref", "?", "value",
function_add_nodes (cat, "isref", NULL, "value",
&help_isref, gnumeric_isref);
function_add_nodes (cat, "istext", NULL, "value",
&help_istext, gnumeric_istext);
......
......@@ -1133,7 +1133,7 @@ lookup_functions_init (void)
&help_address, gnumeric_address);
function_add_nodes (cat, "choose", 0, "index,value...",
&help_choose, gnumeric_choose);
function_add_nodes (cat, "column", "?", "ref",
function_add_nodes (cat, "column", NULL, "ref",
&help_column, gnumeric_column);
function_add_args (cat, "columns", "A", "ref",
&help_columns, gnumeric_columns);
......@@ -1153,7 +1153,7 @@ lookup_functions_init (void)
&help_match, gnumeric_match);
function_add_args (cat, "offset", "rff|ff","ref,row,col,hight,width",
&help_offset, gnumeric_offset);
function_add_nodes (cat, "row", "?", "ref",
function_add_nodes (cat, "row", NULL, "ref",
&help_row, gnumeric_row);
function_add_args (cat, "rows", "A", "ref",
&help_rows, gnumeric_rows);
......
......@@ -3443,7 +3443,7 @@ math_functions_init (void)
"number", &help_floor, gnumeric_floor);
auto_format_function_result (def, AF_FIRST_ARG_FORMAT);
function_add_nodes (cat, "gcd", "ff",
function_add_nodes (cat, "gcd", NULL,
"number1,number2",
&help_gcd, gnumeric_gcd);
......
......@@ -116,7 +116,7 @@ union _ExprTree {
/**
* Function parameter structures
*/
enum _FuncType { FUNCTION_ARGS, FUNCTION_NODES };
enum _FuncType { FUNCTION_ARGS, FUNCTION_NODES, FUNCTION_NAMEONLY };
typedef enum _FuncType FuncType;
typedef Value *(FunctionArgs) (FunctionEvalInfo *ei, Value **args);
......
......@@ -39,13 +39,17 @@ struct _FunctionDefinition {
FunctionGetFullInfoCallback get_full_info_callback;
FunctionFlags flags;
gchar const *name;
gchar const *args;
gchar const *named_arguments;
gchar **help;
FuncType fn_type;
union {
FunctionNodes *fn_nodes;
FunctionArgs *fn_args;
struct {
const char *arg_spec;
FunctionArgs *func;
int min_args, max_args;
char *arg_types;
} args;
} fn;
gpointer user_data;
gint ref_count;
......@@ -220,13 +224,29 @@ function_category_remove_func (FunctionCategory *category,
/******************************************************************************/
static void
extract_arg_types (FunctionDefinition *def)
{
int i;
function_def_count_args (def,
&def->fn.args.min_args,
&def->fn.args.max_args);
def->fn.args.arg_types = g_malloc (def->fn.args.max_args + 1);
for (i = 0; i < def->fn.args.max_args; i++)
def->fn.args.arg_types[i] = function_def_get_arg_type (def, i);
def->fn.args.arg_types[i] = 0;
}
static Value *
error_function_no_full_info (FunctionEvalInfo *ei, GList *expr_node_list)
{
return value_new_error (ei->pos, _("Function implementation not available."));
}
static inline void
static void
function_def_get_full_info_if_needed (FunctionDefinition *fn_def)
{
if (fn_def->get_full_info_callback != NULL) {
......@@ -239,12 +259,13 @@ function_def_get_full_info_if_needed (FunctionDefinition *fn_def)
&args, &arg_names, &help,
&fn_args, &fn_nodes);
if (success) {
fn_def->args = args;
fn_def->named_arguments = arg_names;
fn_def->help = help;
if (fn_args != NULL) {
fn_def->fn_type = FUNCTION_ARGS;
fn_def->fn.fn_args = fn_args;
fn_def->fn.args.func = fn_args;
fn_def->fn.args.arg_spec = args;
extract_arg_types (fn_def);
} else if (fn_nodes != NULL) {
fn_def->fn_type = FUNCTION_NODES;
fn_def->fn.fn_nodes = fn_nodes;
......@@ -252,7 +273,6 @@ function_def_get_full_info_if_needed (FunctionDefinition *fn_def)
g_assert_not_reached ();
}
} else {
fn_def->args = "";
fn_def->named_arguments = "";
fn_def->fn_type = FUNCTION_NODES;
fn_def->fn.fn_nodes = &error_function_no_full_info;
......@@ -313,31 +333,30 @@ function_remove (FunctionCategory *category, gchar const *name)
function_category_remove_func (category, fn_def);
sym = symbol_lookup (global_symbol_table, name);
symbol_unref (sym);
switch (fn_def->fn_type) {
case FUNCTION_ARGS:
g_free (fn_def->fn.args.arg_types);
break;
default:
/* Nothing. */
;
}
g_free (fn_def);
}
static FunctionDefinition *
fn_def_new (FunctionCategory *category,
char const *name,
char const *args,
char const *arg_names,
char **help)
{
static char const valid_tokens[] = "fsbraAS?|";
char const *ptr;
FunctionDefinition *fn_def;
/* Check those arguements */
if (args)
for (ptr = args ; *ptr ; ptr++) {
g_return_val_if_fail (strchr (valid_tokens, *ptr), NULL);
}
fn_def = g_new (FunctionDefinition, 1);
fn_def->get_full_info_callback = NULL;
fn_def->flags = 0;
fn_def->name = name;
fn_def->args = args;
fn_def->help = help;
fn_def->named_arguments = arg_names;
fn_def->user_data = NULL;
......@@ -358,14 +377,24 @@ function_add_args (FunctionCategory *category,
char **help,
FunctionArgs *fn)
{
static char const valid_tokens[] = "fsbraAS?|";
FunctionDefinition *fn_def;
char const *ptr;
g_return_val_if_fail (fn != NULL, NULL);
g_return_val_if_fail (args != NULL, NULL);
/* Check those arguements */
for (ptr = args ; *ptr ; ptr++) {
g_return_val_if_fail (strchr (valid_tokens, *ptr), NULL);
}
fn_def = fn_def_new (category, name, args, arg_names, help);
fn_def = fn_def_new (category, name, arg_names, help);
if (fn_def != NULL) {
fn_def->fn_type = FUNCTION_ARGS;
fn_def->fn.fn_args = fn;
fn_def->fn_type = FUNCTION_ARGS;
fn_def->fn.args.func = fn;
fn_def->fn.args.arg_spec = args;
extract_arg_types (fn_def);
}
return fn_def;
}
......@@ -381,8 +410,11 @@ function_add_nodes (FunctionCategory *category,
FunctionDefinition *fn_def;
g_return_val_if_fail (fn != NULL, NULL);
if (args && *args) {
g_warning ("Arg spec for node function -- why?");
}
fn_def = fn_def_new (category, name, args, arg_names, help);
fn_def = fn_def_new (category, name, arg_names, help);
if (fn_def != NULL) {
fn_def->fn_type = FUNCTION_NODES;
fn_def->fn.fn_nodes = fn;
......@@ -397,8 +429,9 @@ function_add_name_only (FunctionCategory *category,
{
FunctionDefinition *fn_def;
fn_def = fn_def_new (category, name, NULL, NULL, NULL);
fn_def = fn_def_new (category, name, NULL, NULL);
if (fn_def != NULL) {
fn_def->fn_type = FUNCTION_NAMEONLY;
fn_def->get_full_info_callback = callback;
}
......@@ -437,7 +470,7 @@ function_add_placeholder (char const *name, char const *type)
* plugin to supply missing functions.
*/
func = function_add_nodes (cat, g_strdup (name),
"", "...", NULL,
0, "...", NULL,
&unknownFunctionHandler);
/* WISHLIST : it would be nice to have a log if these. */
......@@ -498,18 +531,17 @@ function_def_count_args (FunctionDefinition const *fn_def,
function_def_get_full_info_if_needed ((FunctionDefinition *) fn_def);
ptr = fn_def->args;
/*
* FIXME: clearly for 'nodes' functions many of
* the type fields will need to be filled.
*/
if (fn_def->fn_type == FUNCTION_NODES && ptr == NULL) {
if (fn_def->fn_type == FUNCTION_NODES) {
*min = 0;
*max = G_MAXINT;
return;
}
ptr = fn_def->fn.args.arg_spec;
for (i = vararg = 0; ptr && *ptr; ptr++) {
if (*ptr == '|') {
vararg = 1;
......@@ -540,7 +572,7 @@ function_def_get_arg_type (FunctionDefinition const *fn_def,
function_def_get_full_info_if_needed ((FunctionDefinition *) fn_def);
for (ptr = fn_def->args; ptr && *ptr; ptr++) {
for (ptr = fn_def->fn.args.arg_spec; ptr && *ptr; ptr++) {
if (*ptr == '|')
continue;
if (arg_idx-- == 0)
......@@ -692,7 +724,6 @@ function_call_with_list (FunctionEvalInfo *ei, GList *l)
int argc, arg;
Value *v = NULL;
Value **values;
int fn_argc_min = 0, fn_argc_max = 0;
g_return_val_if_fail (ei != NULL, NULL);
g_return_val_if_fail (ei->func_def != NULL, NULL);
......@@ -706,20 +737,19 @@ function_call_with_list (FunctionEvalInfo *ei, GList *l)
/* Functions that take pre-computed Values */
argc = g_list_length (l);
function_def_count_args (fn_def, &fn_argc_min,
&fn_argc_max);
if (argc > fn_argc_max || argc < fn_argc_min)
if (argc > fn_def->fn.args.max_args ||
argc < fn_def->fn.args.min_args) {
return value_new_error (ei->pos,
_("Invalid number of arguments"));
}
values = g_new (Value *, fn_argc_max);
values = g_new (Value *, fn_def->fn.args.max_args);
for (arg = 0; l; l = l->next, ++arg) {
char arg_type;
gboolean type_mismatch;
arg_type = function_def_get_arg_type (fn_def, arg);
arg_type = fn_def->fn.args.arg_types[arg];
values [arg] = function_marshal_arg (ei, l->data, arg_type,
&type_mismatch);
......@@ -729,9 +759,9 @@ function_call_with_list (FunctionEvalInfo *ei, GList *l)
return value_new_error (ei->pos, gnumeric_err_VALUE);
}
}
while (arg < fn_argc_max)
while (arg < fn_def->fn.args.max_args)
values [arg++] = NULL;
v = fn_def->fn.fn_args (ei, values);
v = fn_def->fn.args.func (ei, values);
free_values (values, arg);
return v;
......@@ -802,7 +832,7 @@ function_def_call_with_values (EvalPos const *ep,
}
} else
retval = fn_def->fn.fn_args (&fs, values);
retval = fn_def->fn.args.func (&fs, values);
return retval;
}
......
2001-06-03 Morten Welinder <terra@diku.dk>
* fn-information.c (information_functions_init): Don't supply arg
spec for node function.
* fn-lookup.c (lookup_functions_init): Ditto.
* fn-math.c (math_functions_init): Ditto.
* fn-eng.c (eng_functions_init): Ditto.
* fn-date.c (gnumeric_datedif): Constify.
2001-05-29 Morten Welinder <terra@diku.dk>
* fn-information.c (gnumeric_cell, gnumeric_info, gnumeric_error,
......
......@@ -207,7 +207,7 @@ static Value *
gnumeric_datedif (FunctionEvalInfo *ei, Value **argv)
{
int date1, date2;
char *opt;
const char *opt;
GDate *gdate1, *gdate2;
Value *result;
......
......@@ -1939,7 +1939,7 @@ eng_functions_init (void)
cat, "impower", "??", "inumber,inumber",
&help_impower, gnumeric_impower);
function_add_nodes (
cat, "improduct", "??", "inumber,inumber",
cat, "improduct", NULL, "inumber,inumber",
&help_improduct, gnumeric_improduct);
function_add_args (
cat, "imreal", "?", "inumber",
......@@ -1954,7 +1954,7 @@ eng_functions_init (void)
cat, "imsub", "??", "inumber,inumber",
&help_imsub, gnumeric_imsub);
function_add_nodes (
cat, "imsum", "??", "inumber,inumber",
cat, "imsum", NULL, "inumber,inumber",
&help_imsum, gnumeric_imsum);
function_add_args (
cat, "oct2bin", "?|f", "xnum,ynum",
......
......@@ -889,21 +889,21 @@ information_functions_init (void)
&help_countblank, gnumeric_countblank);
function_add_args (cat, "error", "s", "text",
&help_error, gnumeric_error);
function_add_nodes (cat, "error.type", "", "",
function_add_nodes (cat, "error.type", NULL, "",
&help_error_type, gnumeric_error_type);
function_add_args (cat, "info", "s", "info_type",
&help_info, gnumeric_info);
function_add_nodes (cat, "isblank", "?", "value",
function_add_nodes (cat, "isblank", NULL, "value",
&help_isblank, gnumeric_isblank);
function_add_nodes (cat, "iserr", "", "",
function_add_nodes (cat, "iserr", NULL, "",
&help_iserr, gnumeric_iserr);
function_add_nodes (cat, "iserror", "", "",
function_add_nodes (cat, "iserror", NULL, "",
&help_iserror, gnumeric_iserror);
function_add_args (cat, "iseven", "?", "value",
&help_iseven, gnumeric_iseven);
function_add_nodes (cat, "islogical", NULL, "value",
&help_islogical, gnumeric_islogical);
function_add_nodes (cat, "isna", "", "",
function_add_nodes (cat, "isna", NULL, "",
&help_isna, gnumeric_isna);
function_add_nodes (cat, "isnontext", NULL, "value",
&help_isnontext, gnumeric_isnontext);
......@@ -911,7 +911,7 @@ information_functions_init (void)
&help_isnumber, gnumeric_isnumber);
function_add_args (cat, "isodd", "?", "value",
&help_isodd, gnumeric_isodd);
function_add_nodes (cat, "isref", "?", "value",
function_add_nodes (cat, "isref", NULL, "value",
&help_isref, gnumeric_isref);
function_add_nodes (cat, "istext", NULL, "value",
&help_istext, gnumeric_istext);
......
......@@ -1133,7 +1133,7 @@ lookup_functions_init (void)
&help_address, gnumeric_address);
function_add_nodes (cat, "choose", 0, "index,value...",
&help_choose, gnumeric_choose);
function_add_nodes (cat, "column", "?", "ref",
function_add_nodes (cat, "column", NULL, "ref",
&help_column, gnumeric_column);
function_add_args (cat, "columns", "A", "ref",
&help_columns, gnumeric_columns);
......@@ -1153,7 +1153,7 @@ lookup_functions_init (void)
&help_match, gnumeric_match);
function_add_args (cat, "offset", "rff|ff","ref,row,col,hight,width",
&help_offset, gnumeric_offset);
function_add_nodes (cat, "row", "?", "ref",
function_add_nodes (cat, "row", NULL, "ref",
&help_row, gnumeric_row);
function_add_args (cat, "rows", "A", "ref",
&help_rows, gnumeric_rows);
......
......@@ -3443,7 +3443,7 @@ math_functions_init (void)
"number", &help_floor, gnumeric_floor);
auto_format_function_result (def, AF_FIRST_ARG_FORMAT);
function_add_nodes (cat, "gcd", "ff",
function_add_nodes (cat, "gcd", NULL,
"number1,number2",
&help_gcd, gnumeric_gcd);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment