Files
calc/custom/c_sysinfo.c
Landon Curt Noll a6824debbc improved calc computation error codes message array
Changed calc_errno a global int variable so that is may be directly
accessed by libcalc users.

Further improve help files for help/errno, help/error, help/newerror,
help/stoponerror and help/strerror by adding to documentation
of the calc error code system as well as libcalc interface
where applicable.

Changed #define E_USERDEF to #define E__USERDEF.

Removed use of E_USERDEF, E__BASE, E__COUNT, and E__HIGHEST
from custom/c_sysinfo because the c_sysinfo is just a demo
and this will simplify the custom/Makefile.

The include file calcerr.h is now the errsym.h include file.
The calcerr.tbl has been replaced by errtbl.c and errtbl.h.

The calcerr_c.awk, calcerr_c.sed, calcerr_h.awk, and
calcerr_h.sed files are now obsolete and have been removed.
The calcerr.c and calcerr.h now obsolete and are no longer built.

The calc computation error codes, symbols and messages are now in
a error_table[] array of struct errtbl.

An E_STRING is a string corresponds to an error code #define.
For example, the E_STRING for the calc error E_STRCAT,
is the string "E_STRING".  An E_STRING must now match
the regular expression: "^E_[A-Z0-9_]+$".

The old array error_table[] of error message strings has been
replaced by a new error_table[] array of struct errtbl.  The struct
errtbl array holds calc errnum error codes, the related E_STRING
symbol as a string, and the original related error message.
To add new computation error codes, add them near the bottom of the
error_table[] array, just before the NULL entry.

The ./errcode utility, when run, will verify the consistency of
the error_table[] array.

The Makefile uses ./errcode -e to generate the contents of
help/errorcodes file.  The help errorcodes now prints
information from the new cstruct errtbl error_table[] array.

The help/errorcodes.hdr and help/errorcodes.sed files are
now obsolete and have been removed.

The Makefile uses ./errcode -d to generate the contents of the
errsym.h include file.

Updated .gitignore and trailblank to support the above changes.
2023-09-13 02:45:33 -07:00

463 lines
14 KiB
C

/*
* c_sysinfo - names and values of selected #defines
*
* Copyright (C) 1999-2007,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/09 23:14:40
* 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/
*/
/*
* ISO C requires a translation unit to contain at least one declaration,
* so we declare a global variable whose value is based on if CUSTOM is defined.
*/
#if defined(CUSTOM)
int c_sysinfo_allowed = 1; /* CUSTOM defined */
#else /* CUSTOM */
int c_sysinfo_allowed = 0; /* CUSTOM undefined */
#endif /* CUSTOM */
#if defined(CUSTOM)
#include <stdio.h>
#include <ctype.h>
#include "../have_string.h"
#if defined(HAVE_STRING_H)
#include <string.h>
#endif
#include "../have_const.h"
#include "../value.h"
#include "../custom.h"
#include "../config.h"
#include "../lib_calc.h"
#include "../calc.h"
#include "../longbits.h"
#define CHECK_L_FORMAT
#include "../block.h"
#include "../conf.h"
#include "../endian_calc.h"
#include "../fposval.h"
#include "../hist.h"
#include "../prime.h"
#include "../zrand.h"
#include "../zrandom.h"
#include "../have_unused.h"
#include "../attribute.h"
#include "../banned.h" /* include after system header <> includes */
/*
* sys_info - names and values of selected #defines
*/
struct infoname {
char *name; /* name of #define converted to all UPPER_CASE */
char *meaning; /* brief explanation of the #define */
char *str; /* non-NULL ==> value of #define is a string */
FULL nmbr; /* if str==NULL ==> value fo #define as a FULL */
};
STATIC struct infoname sys_info[] = {
{"S100", "slots in an subtractive 100 table", NULL,
(FULL)S100},
{"BASE", "base for calculations", NULL,
(FULL)BASE},
{"BASE1", "one less than base", NULL,
(FULL)BASE},
{"BASEB", "bits in the calculation base", NULL,
(FULL)BASEB},
{"BASEDIG", "number of digits in base", NULL,
(FULL)BASEDIG},
{"BIG_ENDIAN", "Most Significant Byte first symbol", NULL,
(FULL)BIG_ENDIAN},
{"BLK_CHUNKSIZE", "default allocation chunk size for blocks", NULL,
(FULL)BLK_CHUNKSIZE},
{"BLK_DEF_MAXPRINT", "default block octets to print", NULL,
(FULL)BLK_DEF_MAXPRINT},
{"BLUM_PREGEN", "non-default predefined Blum generators", NULL,
(FULL)BLUM_PREGEN},
{"CALCEXT", "extension for files read in", CALCEXT,
(FULL)0},
{"CALC_BYTE_ORDER", "Byte order (LITTLE_ENDIAN or BIG_ENDIAN)", NULL,
(FULL)CALC_BYTE_ORDER},
{"CUSTOMHELPDIR", "location of the custom help directory", CUSTOMHELPDIR,
(FULL)0},
{"DEFAULTCALCBINDINGS", "default key bindings file", DEFAULTCALCBINDINGS,
(FULL)0},
{"DEFAULTCALCHELP", "help file that -h prints", DEFAULTCALCHELP,
(FULL)0},
{"DEFAULTCALCPAGER", "default pager", DEFAULTCALCPAGER,
(FULL)0},
{"DEFAULTCALCPATH", "default :-separated search path", DEFAULTCALCPATH,
(FULL)0},
{"DEFAULTCALCRC", "default :-separated startup file list", DEFAULTCALCRC,
(FULL)0},
{"DEFAULTSHELL", "default shell to use", DEFAULTSHELL,
(FULL)0},
{"DEV_BITS", "device number size in bits", NULL,
(FULL)DEV_BITS},
{"DISPLAY_DEFAULT", "default digits for float display", NULL,
(FULL)DISPLAY_DEFAULT},
{"EPSILONPREC_DEFAULT", "2^-EPSILON_DEFAULT <= EPSILON_DEFAULT", NULL,
(FULL)EPSILONPREC_DEFAULT},
{"EPSILON_DEFAULT", "allowed error for float calculations",
EPSILON_DEFAULT, (FULL)0},
{"ERRMAX", "default errmax value", NULL,
(FULL)ERRMAX},
{"false", "boolean false", NULL,
(FULL)false},
{"FILEPOS_BITS", "file position size in bits", NULL,
(FULL)FILEPOS_BITS},
{"FULL_BITS", "bits in a FULL", NULL,
(FULL)FULL_BITS},
{"HELPDIR", "location of the help directory", HELPDIR,
(FULL)0},
{"HIST_BINDING_FILE", "Default binding file", HIST_BINDING_FILE,
(FULL)0},
{"HIST_SIZE", "Default history size", NULL,
(FULL)HIST_SIZE},
{"INIT_J", "initial 1st walking subtractive 100 shuffle table index", NULL,
(FULL)INIT_J},
{"INIT_K", "initial 2nd walking subtractive 100 shuffle table index", NULL,
(FULL)INIT_K},
{"INODE_BITS", "inode number size in bits", NULL,
(FULL)INODE_BITS},
{"LITTLE_ENDIAN", "Least Significant Byte first symbol",
NULL, (FULL)LITTLE_ENDIAN},
{"LONG_BITS", "bit length of a long", NULL,
(FULL)LONG_BITS},
{"MAP_POPCNT", "number of odd primes in pr_map", NULL,
(FULL)MAP_POPCNT},
{"MAX_CALCRC", "maximum allowed length of $CALCRC", NULL,
(FULL)MAX_CALCRC},
{"MAXCMD", "max length of command invocation", NULL,
(FULL)MAXCMD},
{"MAXDIM", "max number of dimensions in matrices", NULL,
(FULL)MAXDIM},
{"MAXERROR", "max length of error message string", NULL,
(FULL)MAXERROR},
{"MAXFILES", "max number of opened files", NULL,
(FULL)MAXFILES},
{"MAXFULL", "largest SFULL value", NULL,
(FULL)MAXFULL},
{"MAXHALF", "largest SHALF value", NULL,
(FULL)MAXHALF},
{"MAXLABELS", "max number of user labels in function", NULL,
(FULL)MAXLABELS},
{"MAXLEN", "longest storage size allowed", NULL,
(FULL)MAXLEN},
{"MAXLONG", "largest long val", NULL,
(FULL)MAXLONG},
{"MAXPRINT_DEFAULT", "default number of elements printed", NULL,
(FULL)MAXPRINT_DEFAULT},
{"MAXREDC", "number of entries in REDC cache", NULL,
(FULL)MAXREDC},
{"MAXSCANCOUNT", "default max scan errors before an abort", NULL,
(FULL)MAXSCANCOUNT},
{"MAXSTACK", "max depth of evaluation stack", NULL,
(FULL)MAXSTACK},
{"MAXUFULL", "largest FULL value", NULL,
(FULL)MAXUFULL},
{"MAXULONG", "largest unsigned long val", NULL,
(FULL)MAXULONG},
{"MAX_MAP_PRIME", "largest prime in pr_map", NULL,
(FULL)MAX_MAP_PRIME},
{"MAX_MAP_VAL", "largest bit in pr_map", NULL,
(FULL)MAX_MAP_VAL},
{"MAX_PFACT_VAL", "max x, for which pfact(x) is a long", NULL,
(FULL)MAX_PFACT_VAL},
{"MAX_SM_PRIME", "largest 32 bit prime", NULL,
(FULL)MAX_SM_PRIME},
{"MAX_SM_VAL", "largest 32 bit value", NULL,
(FULL)MAX_SM_VAL},
{"MUL_ALG2", "default size for alternative multiply", NULL,
(FULL)MUL_ALG2},
{"NXT_MAP_PRIME", "smallest odd prime not in pr_map", NULL,
(FULL)NXT_MAP_PRIME},
{"NXT_PFACT_VAL", "next prime for higher pfact values", NULL,
(FULL)NXT_PFACT_VAL},
{"OFF_T_BITS", "file offset size in bits", NULL,
(FULL)OFF_T_BITS},
{"PIX_32B", "max pix() value", NULL,
(FULL)PIX_32B},
{"POW_ALG2", "default size for using REDC for powers", NULL,
(FULL)POW_ALG2},
{"REDC_ALG2", "default size using alternative REDC alg", NULL,
(FULL)REDC_ALG2},
{"SBITS", "size of additive or shuffle entry in bits", NULL,
(FULL)SBITS},
{"SBYTES", "size of additive or shuffle entry in bytes", NULL,
(FULL)SBYTES},
{"SCNT", "length of subtractive 100 table in FULLs", NULL,
(FULL)SCNT},
{"SEEDXORBITS", "low bits of subtractive 100 shuffle pseudo-random number generator seed devoted to xor", NULL,
(FULL)SEEDXORBITS},
{"SHALFS", "size of additive or shuffle entry in HALFs", NULL,
(FULL)SHALFS},
{"SHUFCNT", "size of shuffle table in entries", NULL,
(FULL)SHUFCNT},
{"SHUFLEN", "length of shuffle table in FULLs", NULL,
(FULL)SHUFLEN},
{"SHUFMASK", "mask for shuffle table entry selection", NULL,
(FULL)SHUFMASK},
{"SHUFPOW", "power of 2 size of the shuffle table", NULL,
(FULL)SHUFPOW},
{"SLEN", "number of FULLs in a shuffle table entry", NULL,
(FULL)SLEN},
{"SQ_ALG2", "default size for alternative squaring", NULL,
(FULL)SQ_ALG2},
{"SYMBOLSIZE", "max symbol name size", NULL,
(FULL)SYMBOLSIZE},
{"TEN_MAX", "10^(2^TEN_MAX): largest base10 conversion const", NULL,
(FULL)TEN_MAX},
{"TOPFULL", "highest bit in FULL", NULL,
(FULL)TOPFULL},
{"TOPHALF", "highest bit in a HALF", NULL,
(FULL)TOPHALF},
{"TOPLONG", "top long bit", NULL,
(FULL)TOPLONG},
{"true", "boolean true", NULL,
(FULL)true},
{"USUAL_ELEMENTS", "usual number of elements for objects", NULL,
(FULL)USUAL_ELEMENTS},
{"REGNUM_MAX", "highest custom register number", NULL,
(FULL)CUSTOM_REG_MAX},
/* must be last */
{NULL, NULL, NULL, (FULL)0}
};
/*
* forward declarations
*/
S_FUNC void dump_name_meaning(void); /* custom("sysinfo", 0) */
S_FUNC void dump_name_value(void); /* custom("sysinfo", 1) */
S_FUNC void dump_mening_value(void); /* custom("sysinfo", 2) */
/*
* c_sysinfo - return a calc #define value
*
* given:
* vals[0] if given, name of #define to print
* otherwise a list of #defines are printed
*
* returns:
* value of #define if given (int or string)
* null if no #define arg was given
*/
/*ARGSUSED*/
VALUE
c_sysinfo(char *UNUSED(name), int count, VALUE **vals)
{
VALUE result; /* what we will return */
struct infoname *p; /* current infoname */
char *buf; /* upper case value of vals[0] */
char *q; /* to upper case converter */
char *r; /* to upper case converter */
/*
* we will return NULL if a value was not found
*/
result.v_type = V_NULL;
result.v_subtype = V_NOSUBTYPE;
/*
* case 0: if no args, then dump the table with no values
*/
if (count == 0) {
/* dump the entire table */
dump_name_meaning();
/*
* case 1: numeric arg is given
*/
} else if (vals[0]->v_type == V_NUM) {
/* firewall - must be a tiny non-negative integer */
if (qisneg(vals[0]->v_num) ||
qisfrac(vals[0]->v_num) ||
zge31b(vals[0]->v_num->num)) {
math_error("sysinfo: arg must be string, 0, 1 or 2");
not_reached();
}
/*
* select action based on numeric value of arg
*/
switch (z1tol(vals[0]->v_num->num)) {
case 0: /* print all infonames and meanings */
dump_name_meaning();
break;
case 1: /* print all infonames and values */
dump_name_value();
break;
case 2: /* print all values and meanings */
dump_mening_value();
break;
default:
math_error("sysinfo: arg must be string, 0, 1 or 2");
not_reached();
}
/*
* case 2: string arg is given
*
* The string is taken to be the infoname we want to print.
*/
} else if (vals[0]->v_type == V_STR) {
/* convert vals[0] to upper case string */
buf = (char *)malloc(strlen((char *)vals[0]->v_str->s_str)+1);
for (q = (char *)vals[0]->v_str->s_str, r = buf; *q; ++q, ++r)
{
if (isascii((int)*q) && islower((int)*q)) {
*r = *q - 'a' + 'A';
} else {
*r = *q;
}
}
*r = '\0';
/* search the table for the infoname */
for (p = sys_info; p->name != NULL; ++p) {
if (strcmp(p->name, buf) == 0) {
/* found the infoname */
if (p->str == NULL) {
/* return value as integer */
result.v_type = V_NUM;
result.v_num = utoq( p->nmbr);
} else {
/* return value as string */
result.v_type = V_STR;
result.v_subtype = V_NOSUBTYPE;
result.v_str = makestring(p->str);
}
/* return found infotype as value */
break;
}
}
/*
* bad arg given
*/
} else {
math_error("sysinfo: arg must be string, 0, 1 or 2");
not_reached();
}
/*
* return what we found or didn't find
*/
return result;
}
/*
* dump_name_meaning - print all infonames and meanings
*/
S_FUNC void
dump_name_meaning(void)
{
struct infoname *p; /* current infoname */
/* dump the entire table */
for (p = sys_info; p->name != NULL; ++p) {
printf("%s%-23s\t%s\n",
(conf->tab_ok ? "\t" : ""), p->name, p->meaning);
}
}
/*
* dump_name_value - print all infonames and values
*/
S_FUNC void
dump_name_value(void)
{
struct infoname *p; /* current infoname */
/* dump the entire table */
for (p = sys_info; p->name != NULL; ++p) {
if (p->str == NULL) {
#if LONG_BITS == FULL_BITS || FULL_BITS == 32
printf("%s%-23s\t%-8lu\t(0x%lx)\n",
(conf->tab_ok ? "\t" : ""), p->name,
(unsigned long)p->nmbr,
(unsigned long)p->nmbr);
#else
printf("%s%-23s\t%-8llu\t(0x%llx)\n",
(conf->tab_ok ? "\t" : ""), p->name,
(unsigned long long)p->nmbr,
(unsigned long long)p->nmbr);
#endif
} else {
printf("%s%-23s\t\"%s\"\n",
(conf->tab_ok ? "\t" : ""), p->name, p->str);
}
}
}
/*
* dump_mening_value - print all values and meanings
*/
S_FUNC void
dump_mening_value(void)
{
struct infoname *p; /* current infoname */
/* dump the entire table */
for (p = sys_info; p->name != NULL; ++p) {
if (p->str == NULL) {
#if LONG_BITS == FULL_BITS || FULL_BITS == 32
printf("%s%-36.36s\t%-8lu\t(0x%lx)\n",
(conf->tab_ok ? "\t" : ""), p->meaning,
(unsigned long)p->nmbr,
(unsigned long)p->nmbr);
#else
printf("%s%-36.36s\t%-8llu\t(0x%llx)\n",
(conf->tab_ok ? "\t" : ""), p->meaning,
(unsigned long long)p->nmbr,
(unsigned long long)p->nmbr);
#endif
} else {
printf("%s%-36.36s\t\"%s\"\n",
(conf->tab_ok ? "\t" : ""), p->meaning, p->str);
}
}
}
#endif /* CUSTOM */