/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* * eg-beginner: examples #1 for beginners * * Authors: * Lloyd ALLISON Lloyd.Allison@infotech.monash.edu.au 10/2003 * from bits in gnumeric_1.2.0 and particularly plugins/fn_d@te, * and writing-functions.sgml (which is maybe not uptodate?) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "plugin.h" #include "plugin-util.h" #include "module-plugin-defs.h" GNUMERIC_MODULE_PLUGIN_INFO_DECL; /***************************************************************************/ /* For each function, blah, define a help_blah and blah code */ /* then add them to the data-structure at the end of the file. */ /* Also see the README.html in this directory. */ static char const * help_add2numbers = { N_("@FUNCTION=add2numbers\n" "@SYNTAX=add2numbers(number,number)\n" "@DESCRIPTION=" "toy demonstration function (it adds two numbers)\n" "to illustrate how to extend gnumeric.\n" "\n" "@EXAMPLES=\n" "add2numbers(1,1) returns 2, in principle.\n " "\n" ) }; /* the above is shown in gnumeric's `Insert' / `Function Selector' */ /* following based on gnumeric-1.2.0/doc/developer/writing-functions.sgml */ static GnmValue * add2numbers (FunctionEvalInfo *ei, GnmValue **argv) { float number_a, number_b; switch (argv [0] -> type){ case VALUE_INTEGER: number_a = value_get_as_int (argv [0]); break; case VALUE_FLOAT: number_a = value_get_as_float (argv [0]); break; default: return value_new_error (&ei->pos, "Invalid argument type"); } switch (argv [1] -> type){ case VALUE_INTEGER: number_b = value_get_as_int (argv [1]); break; case VALUE_FLOAT: number_b = value_get_as_float (argv [1]); break; default: return value_new_error (&ei->pos, "Invalid argument type"); } return value_new_float (number_a + number_b); } /***************************************************************************/ static char const * help_eg_rangefn = { N_("@FUNCTION=eg_rangefn\n" "@SYNTAX=eg_rangefn(dataset)\n" "@DESCRIPTION=" "toy demonstration function on a range\n" "\n" "@EXAMPLES=\n" "eg_rangefn(A1:B5).\n " "\n" ) }; /* worth looking in e.g. plugins/fn-stat/functions.c */ static GnmValue * eg_rangefn (FunctionEvalInfo *ei, GnmValue **argv) { int height = 0, width = 0; if (argv[0] == NULL || (argv[0]->type != VALUE_ARRAY && argv[0]->type != VALUE_CELLRANGE)) return value_new_error (&ei->pos, "Invalid argument type"); if (argv[0]->type == VALUE_CELLRANGE) { width = argv[0]->v_range.cell.b.col - argv[0]->v_range.cell.a.col + 1; height = argv[0]->v_range.cell.b.row - argv[0]->v_range.cell.a.row + 1; return value_new_int (height * width); /* something to do */ } /* VALUE_CELLRANGE */ else /* VALUE_ARRAY */ return value_new_error (&ei->pos, "array not yet implemented"); } /* eg_rangefn */ /***************************************************************************/ /* ??? what about the GNM_... flags below */ GnmFuncDescriptor const beginner_functions[] = { /* see src/func.h */ { "add2numbers", /* name */ "ff", /* args, takes 2 floats (or ints) */ N_("number,number"), /* arg names */ &help_add2numbers, /* Help stuff, see above */ add2numbers, /* Code proper, see above */ NULL, /* fn_args ??? */ NULL, /* linker ??? */ NULL, /* unlinker ??? */ NULL, /* ref_notify ??? */ GNM_FUNC_SIMPLE, /* flags ??? */ GNM_FUNC_IMPL_STATUS_COMPLETE, /* impl_status ??? */ GNM_FUNC_TEST_STATUS_BASIC /* test_status ??? */ }, { "eg_rangefn", "A", /* NB. A == range or array */ N_("dataset"), &help_eg_rangefn, eg_rangefn, NULL, NULL, NULL, NULL, GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_BASIC }, {NULL} /* end of sequence */ }; /***************************************************************************/