Files
calc/custom.c
Landon Curt Noll db77e29a23 convert ASCII TABs to ASCII SPACEs
Converted all ASCII tabs to ASCII spaces using a 8 character
tab stop, for all files, except for all Makefiles (plus rpm.mk).
The `git diff -w` reports no changes.
2024-07-11 22:03:52 -07:00

254 lines
7.2 KiB
C

/*
* custom - interface for custom software and hardware interfaces
*
* Copyright (C) 1999-2006,2018,2021-2023 Landon Curt Noll
*
* Calc is open software; you can redistribute it and/or modify it under
* the terms of the version 2.1 of the GNU Lesser General Public License
* as published by the Free Software Foundation.
*
* Calc 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 Lesser General
* Public License for more details.
*
* A copy of version 2.1 of the GNU Lesser General Public License is
* distributed with calc under the filename COPYING-LGPL. You should have
* received a copy with calc; if not, write to Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Under source code control: 1997/03/03 04:53:08
* File existed as early as: 1997
*
* chongo <was here> /\oo/\ http://www.isthe.com/chongo/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
*/
/* these include files are needed regardless of CUSTOM */
#include "have_const.h"
#include "value.h"
#include "custom.h"
#include <stdio.h>
#if defined(CUSTOM)
#include "calc.h"
#include "have_string.h"
#ifdef HAVE_STRING_H
# include <string.h>
#endif
EXTERN CONST struct custom cust[]; /* custom interface table */
#else /* CUSTOM */
#include "config.h"
#endif /* CUSTOM */
#include "errtbl.h"
#include "banned.h" /* include after system header <> includes */
bool allow_custom = false; /* true => custom builtins allowed */
/*
* custom - custom callout function
*/
/*ARGSUSED*/
VALUE
custom(char *name, int count, VALUE **vals)
{
#if defined(CUSTOM)
CONST struct custom *p; /* current function */
/*
* error if libcustcalc was compiled with CUSTOM undefined
*/
if (custom_compiled() != true) {
math_error("libcustcalc was compiled with CUSTOM undefined "
"custom_compiled() returned: %d != %d",
custom_compiled(), true);
not_reached();
}
/*
* search the custom interface table for a function
*/
for (p = cust; p->name != NULL; ++p) {
/* look for the first match */
if (strcmp(name, p->name) == 0) {
/* arg count check */
if (count < p->minargs) {
math_error("Too few arguments for custom "
"function \"%s\"", p->name);
not_reached();
}
if (count > p->maxargs) {
math_error("Too many arguments for custom "
"function \"%s\"", p->name);
not_reached();
}
/* call the custom function */
return p->func(name, count, vals);
}
}
/*
* no such custom function
*/
return error_value(E_UNK_CUSTOM);
#else /* CUSTOM */
/*
* error if libcustcalc was compiled with CUSTOM defined
*/
if (custom_compiled() != false) {
math_error("libcustcalc was compiled with CUSTOM defined "
"custom_compiled() returned: %d != %d",
custom_compiled(), false);
not_reached();
}
fprintf(stderr,
"%sCalc was built with custom functions disabled\n",
(conf->tab_ok ? "\t" : ""));
if (conf->calc_debug & CALCDBG_CUSTOM) {
fprintf(stderr,
"%scustom function %s with %d args, %s vals not executed\n",
(conf->tab_ok ? "\t" : ""), name, count,
(vals == NULL) ? "NULL" : "non-NULL");
}
return error_value(E_NO_CUSTOM);
#endif /* CUSTOM */
}
/*
* showcustom - display the names and brief descriptions of custom functions
*/
/*ARGSUSED*/
void
showcustom(void)
{
#if defined(CUSTOM)
CONST struct custom *p; /* current function */
/*
* disable custom functions unless -C was given
*/
if (!allow_custom) {
fprintf(stderr,
"%sCalc must be run with a -C argument to "
"show custom functions\n",
(conf->tab_ok ? "\t" : ""));
return;
}
/*
* print header
*/
printf("\nName\tArgs\tDescription\n\n");
for (p = cust; p->name != NULL; ++p) {
printf("%-9s ", p->name);
if (p->maxargs == MAX_CUSTOM_ARGS)
printf("%d+ ", p->minargs);
else if (p->minargs == p->maxargs)
printf("%-6d", p->minargs);
else
printf("%d-%-4d", p->minargs, p->maxargs);
printf("%s\n", p->desc);
}
printf("\n");
#else /* CUSTOM */
fprintf(stderr,
"%sCalc was built with custom functions disabled\n",
(conf->tab_ok ? "\t" : ""));
#endif /* CUSTOM */
}
/*
* customhelp - standard help interface to a custom function
*
* This function assumes that a help file with the same name as
* the custom function has been installed by the custom/Makefile
* (as listed in the CUSTOM_HELP makefile variable) under the
* CUSTOMHELPDIR == HELPDIR/custhelp directory.
*
* The help command first does a search in HELPDIR and later
* in CUSTOMHELPDIR. If a custom help file has the same name
* as a file under HELPDIR then help will display the HELPDIR
* file and NOT the custom file. This function will ignore
* and HELPDIR file and work directly with the custom help file.
*
* given:
* name name of the custom help file to directly access
*/
/*ARGSUSED*/
void
customhelp(char *name)
{
#if defined(CUSTOM)
char *customname; /* a string of the form: custom/name */
size_t snprintf_len; /* malloced snprintf buffer length */
/*
* firewall
*/
if (name == NULL) {
name = "help";
}
/*
* form the custom help name
*/
snprintf_len = sizeof("custhelp")+1+strlen(name)+1;
customname = (char *)malloc(snprintf_len+1);
if (customname == NULL) {
math_error("bad malloc of customname");
not_reached();
}
snprintf(customname, snprintf_len, "custhelp/%s", name);
customname[snprintf_len] = '\0'; /* paranoia */
/*
* give help directly to the custom file
*/
givehelp(customname);
/*
* all done
*/
free(customname);
#else /* CUSTOM */
fprintf(stderr,
"%sCalc was built with custom functions disabled\n",
(conf->tab_ok ? "\t" : ""));
if (conf->calc_debug & CALCDBG_CUSTOM) {
fprintf(stderr, "%scustom help for %s unavailable\n",
(conf->tab_ok ? "\t" : ""),
((name == NULL) ? "((NULL))" : name));
}
#endif /* CUSTOM */
}