1 /*
2  * c_sysinfo - names and values of selected #defines
3  *
4  * Copyright (C) 1999-2007,2021  Landon Curt Noll
5  *
6  * Calc is open software; you can redistribute it and/or modify it under
7  * the terms of the version 2.1 of the GNU Lesser General Public License
8  * as published by the Free Software Foundation.
9  *
10  * Calc is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12  * or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU Lesser General
13  * Public License for more details.
14  *
15  * A copy of version 2.1 of the GNU Lesser General Public License is
16  * distributed with calc under the filename COPYING-LGPL.  You should have
17  * received a copy with calc; if not, write to Free Software Foundation, Inc.
18  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19  *
20  * Under source code control:	1997/03/09 23:14:40
21  * File existed as early as:	1997
22  *
23  * chongo <was here> /\oo/\	http://www.isthe.com/chongo/
24  * Share and enjoy!  :-)	http://www.isthe.com/chongo/tech/comp/calc/
25  */
26 
27 
28 #if defined(CUSTOM)
29 
30 #include <stdio.h>
31 #include <ctype.h>
32 
33 #include "have_string.h"
34 #if defined(HAVE_STRING_H)
35 #include <string.h>
36 #endif
37 
38 #include "have_const.h"
39 #include "value.h"
40 #include "custom.h"
41 
42 #include "config.h"
43 #include "lib_calc.h"
44 #include "calc.h"
45 #include "longbits.h"
46 #define CHECK_L_FORMAT
47 #include "block.h"
48 #include "calcerr.h"
49 #include "conf.h"
50 #include "endian_calc.h"
51 #include "fposval.h"
52 #include "hist.h"
53 #include "prime.h"
54 #include "zrand.h"
55 #include "zrandom.h"
56 
57 #include "have_unused.h"
58 
59 
60 #include "banned.h"	/* include after system header <> includes */
61 
62 
63 /*
64  * sys_info - names and values of selected #defines
65  */
66 struct infoname {
67 	char *name;	/* name of #define converted to all UPPER_CASE */
68 	char *meaning;	/* brief explanation of the #define */
69 	char *str;	/* non-NULL ==> value of #define is a string */
70 	FULL nmbr;	/* if str==NULL ==> value fo #define as a FULL */
71 };
72 STATIC struct infoname sys_info[] = {
73     {"S100", "slots in an subtractive 100 table", NULL,
74      (FULL)S100},
75     {"BASE", "base for calculations", NULL,
76      (FULL)BASE},
77     {"BASE1", "one less than base", NULL,
78      (FULL)BASE},
79     {"BASEB", "bits in the calculation base", NULL,
80      (FULL)BASEB},
81     {"BASEDIG", "number of digits in base", NULL,
82      (FULL)BASEDIG},
83     {"BIG_ENDIAN", "Most Significant Byte first symbol", NULL,
84      (FULL)BIG_ENDIAN},
85     {"BLK_CHUNKSIZE", "default allocation chunk size for blocks", NULL,
86      (FULL)BLK_CHUNKSIZE},
87     {"BLK_DEF_MAXPRINT", "default block octets to print", NULL,
88      (FULL)BLK_DEF_MAXPRINT},
89     {"BLUM_PREGEN", "non-default predefined Blum generators", NULL,
90      (FULL)BLUM_PREGEN},
91     {"CALCEXT", "extension for files read in", CALCEXT,
92      (FULL)0},
93     {"CALC_BYTE_ORDER", "Byte order (LITTLE_ENDIAN or BIG_ENDIAN)", NULL,
94      (FULL)CALC_BYTE_ORDER},
95     {"CUSTOMHELPDIR", "location of the custom help directory", CUSTOMHELPDIR,
96      (FULL)0},
97     {"DEFAULTCALCBINDINGS", "default key bindings file", DEFAULTCALCBINDINGS,
98      (FULL)0},
99     {"DEFAULTCALCHELP", "help file that -h prints", DEFAULTCALCHELP,
100      (FULL)0},
101     {"DEFAULTCALCPAGER", "default pager", DEFAULTCALCPAGER,
102      (FULL)0},
103     {"DEFAULTCALCPATH", "default :-separated search path", DEFAULTCALCPATH,
104      (FULL)0},
105     {"DEFAULTCALCRC", "default :-separated startup file list", DEFAULTCALCRC,
106      (FULL)0},
107     {"DEFAULTSHELL", "default shell to use", DEFAULTSHELL,
108      (FULL)0},
109     {"DEV_BITS", "device number size in bits", NULL,
110      (FULL)DEV_BITS},
111     {"DISPLAY_DEFAULT", "default digits for float display", NULL,
112      (FULL)DISPLAY_DEFAULT},
113     {"EPSILONPREC_DEFAULT", "2^-EPSILON_DEFAULT <= EPSILON_DEFAULT", NULL,
114      (FULL)EPSILONPREC_DEFAULT},
115     {"EPSILON_DEFAULT", "allowed error for float calculations",
116      EPSILON_DEFAULT, (FULL)0},
117     {"ERRMAX", "default errmax value", NULL,
118      (FULL)ERRMAX},
119     {"E_USERDEF", "base of user defined errors", NULL,
120      (FULL)E_USERDEF},
121     {"E__BASE", "calc errors start above here", NULL,
122      (FULL)E__BASE},
123     {"E__COUNT", "number of calc errors", NULL,
124      (FULL)E__COUNT},
125     {"E__HIGHEST", "highest calc error", NULL,
126      (FULL)E__HIGHEST},
127     {"FALSE", "boolean false", NULL,
128      (FULL)FALSE},
129     {"FILEPOS_BITS", "file position size in bits", NULL,
130      (FULL)FILEPOS_BITS},
131     {"FULL_BITS", "bits in a FULL", NULL,
132      (FULL)FULL_BITS},
133     {"HELPDIR", "location of the help directory", HELPDIR,
134      (FULL)0},
135     {"HIST_BINDING_FILE", "Default binding file", HIST_BINDING_FILE,
136      (FULL)0},
137     {"HIST_SIZE", "Default history size", NULL,
138      (FULL)HIST_SIZE},
139     {"INIT_J", "initial 1st walking a55 table index", NULL,
140      (FULL)INIT_J},
141     {"INIT_K", "initial 2nd walking a55 table index", NULL,
142      (FULL)INIT_K},
143     {"INODE_BITS", "inode number size in bits", NULL,
144      (FULL)INODE_BITS},
145     {"LITTLE_ENDIAN", "Least Significant Byte first symbol",
146      NULL, (FULL)LITTLE_ENDIAN},
147     {"LONG_BITS", "bit length of a long", NULL,
148      (FULL)LONG_BITS},
149     {"MAP_POPCNT", "number of odd primes in pr_map", NULL,
150      (FULL)MAP_POPCNT},
151     {"MAX_CALCRC", "maximum allowed length of $CALCRC", NULL,
152      (FULL)MAX_CALCRC},
153     {"MAXCMD", "max length of command invocation", NULL,
154      (FULL)MAXCMD},
155     {"MAXDIM", "max number of dimensions in matrices", NULL,
156      (FULL)MAXDIM},
157     {"MAXERROR", "max length of error message string", NULL,
158      (FULL)MAXERROR},
159     {"MAXFILES", "max number of opened files", NULL,
160      (FULL)MAXFILES},
161     {"MAXFULL", "largest SFULL value", NULL,
162      (FULL)MAXFULL},
163     {"MAXHALF", "largest SHALF value", NULL,
164      (FULL)MAXHALF},
165     {"MAXLABELS", "max number of user labels in function", NULL,
166      (FULL)MAXLABELS},
167     {"MAXLEN", "longest storage size allowed", NULL,
168      (FULL)MAXLEN},
169     {"MAXLONG", "largest long val", NULL,
170      (FULL)MAXLONG},
171     {"MAXPRINT_DEFAULT", "default number of elements printed", NULL,
172      (FULL)MAXPRINT_DEFAULT},
173     {"MAXREDC", "number of entries in REDC cache", NULL,
174      (FULL)MAXREDC},
175     {"MAXSCANCOUNT", "default max scan errors before an abort", NULL,
176      (FULL)MAXSCANCOUNT},
177     {"MAXSTACK", "max depth of evaluation stack", NULL,
178      (FULL)MAXSTACK},
179     {"MAXUFULL", "largest FULL value", NULL,
180      (FULL)MAXUFULL},
181     {"MAXULONG", "largest unsigned long val", NULL,
182      (FULL)MAXULONG},
183     {"MAX_MAP_PRIME", "largest prime in pr_map", NULL,
184      (FULL)MAX_MAP_PRIME},
185     {"MAX_MAP_VAL", "largest bit in pr_map", NULL,
186      (FULL)MAX_MAP_VAL},
187     {"MAX_PFACT_VAL", "max x, for which pfact(x) is a long", NULL,
188      (FULL)MAX_PFACT_VAL},
189     {"MAX_SM_PRIME", "largest 32 bit prime", NULL,
190      (FULL)MAX_SM_PRIME},
191     {"MAX_SM_VAL", "largest 32 bit value", NULL,
192      (FULL)MAX_SM_VAL},
193     {"MUL_ALG2", "default size for alternative multiply", NULL,
194      (FULL)MUL_ALG2},
195     {"NXT_MAP_PRIME", "smallest odd prime not in pr_map", NULL,
196      (FULL)NXT_MAP_PRIME},
197     {"NXT_PFACT_VAL", "next prime for higher pfact values", NULL,
198      (FULL)NXT_PFACT_VAL},
199     {"OFF_T_BITS", "file offset size in bits", NULL,
200      (FULL)OFF_T_BITS},
201     {"PIX_32B", "max pix() value", NULL,
202      (FULL)PIX_32B},
203     {"POW_ALG2", "default size for using REDC for powers", NULL,
204      (FULL)POW_ALG2},
205     {"REDC_ALG2", "default size using alternative REDC alg", NULL,
206      (FULL)REDC_ALG2},
207     {"SBITS", "size of additive or shuffle entry in bits", NULL,
208      (FULL)SBITS},
209     {"SBYTES", "size of additive or shuffle entry in bytes", NULL,
210      (FULL)SBYTES},
211     {"SCNT", "length of subtractive 100 table in FULLs", NULL,
212      (FULL)SCNT},
213     {"SEEDXORBITS", "low bits of a55 seed devoted to xor", NULL,
214      (FULL)SEEDXORBITS},
215     {"SHALFS", "size of additive or shuffle entry in HALFs", NULL,
216      (FULL)SHALFS},
217     {"SHUFCNT", "size of shuffle table in entries", NULL,
218      (FULL)SHUFCNT},
219     {"SHUFLEN", "length of shuffle table in FULLs", NULL,
220      (FULL)SHUFLEN},
221     {"SHUFMASK", "mask for shuffle table entry selection", NULL,
222      (FULL)SHUFMASK},
223     {"SHUFPOW", "power of 2 size of the shuffle table", NULL,
224      (FULL)SHUFPOW},
225     {"SLEN", "number of FULLs in a shuffle table entry", NULL,
226      (FULL)SLEN},
227     {"SQ_ALG2", "default size for alternative squaring", NULL,
228      (FULL)SQ_ALG2},
229     {"SYMBOLSIZE", "max symbol name size", NULL,
230      (FULL)SYMBOLSIZE},
231     {"TEN_MAX", "10^(2^TEN_MAX): largest base10 conversion const", NULL,
232      (FULL)TEN_MAX},
233     {"TOPFULL", "highest bit in FULL", NULL,
234      (FULL)TOPFULL},
235     {"TOPHALF", "highest bit in a HALF", NULL,
236      (FULL)TOPHALF},
237     {"TOPLONG", "top long bit", NULL,
238      (FULL)TOPLONG},
239     {"TRUE", "boolean true", NULL,
240      (FULL)TRUE},
241     {"USUAL_ELEMENTS", "usual number of elements for objects", NULL,
242      (FULL)USUAL_ELEMENTS},
243     {"REGNUM_MAX", "highest custom register number", NULL,
244      (FULL)CUSTOM_REG_MAX},
245 
246      /* must be last */
247     {NULL, NULL, NULL, (FULL)0}
248 };
249 
250 
251 /*
252  * forward declarations
253  */
254 S_FUNC void dump_name_meaning(void);	/* custom("sysinfo", 0) */
255 S_FUNC void dump_name_value(void);	/* custom("sysinfo", 1) */
256 S_FUNC void dump_mening_value(void);	/* custom("sysinfo", 2) */
257 
258 
259 /*
260  * c_sysinfo - return a calc #define value
261  *
262  * given:
263  *	vals[0]	  if given, name of #define to print
264  *		  otherwise a list of #defines are printed
265  *
266  * returns:
267  *	value of #define if given (int or string)
268  *	null if no #define arg was given
269  */
270 /*ARGSUSED*/
271 VALUE
c_sysinfo(char * UNUSED (name),int count,VALUE ** vals)272 c_sysinfo(char *UNUSED(name), int count, VALUE **vals)
273 {
274 	VALUE result;		/* what we will return */
275 	struct infoname *p;	/* current infoname */
276 	char *buf;		/* upper case value of vals[0] */
277 	char *q;		/* to upper case converter */
278 	char *r;		/* to upper case converter */
279 
280 	/*
281 	 * we will return NULL if a value was not found
282 	 */
283 	result.v_type = V_NULL;
284 	result.v_subtype = V_NOSUBTYPE;
285 
286 	/*
287 	 * case 0: if no args, then dump the table with no values
288 	 */
289 	if (count == 0) {
290 
291 		/* dump the entire table */
292 		dump_name_meaning();
293 
294 	/*
295 	 * case 1: numeric arg is given
296 	 */
297 	} else if (vals[0]->v_type == V_NUM) {
298 
299 		/* firewall - must be a tiny non-negative integer */
300 		if (qisneg(vals[0]->v_num) ||
301 		    qisfrac(vals[0]->v_num) ||
302 		    zge31b(vals[0]->v_num->num)) {
303 			math_error("sysinfo: arg must be string, 0, 1 or 2");
304 			/*NOTREACHED*/
305 		}
306 
307 		/*
308 		 * select action based on numeric value of arg
309 		 */
310 		switch (z1tol(vals[0]->v_num->num)) {
311 		case 0:		/* print all infonames and meanings */
312 			dump_name_meaning();
313 			break;
314 		case 1:		/* print all infonames and values */
315 			dump_name_value();
316 			break;
317 		case 2:		/* print all values and meanings */
318 			dump_mening_value();
319 			break;
320 		default:
321 			math_error("sysinfo: arg must be string, 0, 1 or 2");
322 			/*NOTREACHED*/
323 		}
324 
325 	/*
326 	 * case 2: string arg is given
327 	 *
328 	 * The string is taken to be the infoname we want to print.
329 	 */
330 	} else if (vals[0]->v_type == V_STR) {
331 
332 		/* convert vals[0] to upper case string */
333 		buf = (char *)malloc(strlen((char *)vals[0]->v_str->s_str)+1);
334 		for (q = (char *)vals[0]->v_str->s_str, r = buf; *q; ++q, ++r)
335 		{
336 			if (isascii((int)*q) && islower((int)*q)) {
337 				*r = *q - 'a' + 'A';
338 			} else {
339 				*r = *q;
340 			}
341 		}
342 		*r = '\0';
343 
344 		/* search the table for the infoname */
345 		for (p = sys_info; p->name != NULL; ++p) {
346 
347 			if (strcmp(p->name, buf) == 0) {
348 
349 				/* found the infoname */
350 				if (p->str == NULL) {
351 					/* return value as integer */
352 					result.v_type = V_NUM;
353 					result.v_num = utoq( p->nmbr);
354 				} else {
355 					/* return value as string */
356 					result.v_type = V_STR;
357 					result.v_subtype = V_NOSUBTYPE;
358 					result.v_str = makestring(p->str);
359 				}
360 
361 				/* return found infotype as value */
362 				break;
363 			}
364 		}
365 
366 	/*
367 	 * bad arg given
368 	 */
369 	} else {
370 		math_error("sysinfo: arg must be string, 0, 1 or 2");
371 		/*NOTREACHED*/
372 	}
373 
374 	/*
375 	 * return what we found or didn't find
376 	 */
377 	return result;
378 }
379 
380 
381 /*
382  * dump_name_meaning - print all infonames and meanings
383  */
384 S_FUNC void
dump_name_meaning(void)385 dump_name_meaning(void)
386 {
387 	struct infoname *p;	/* current infoname */
388 
389 	/* dump the entire table */
390 	for (p = sys_info; p->name != NULL; ++p) {
391 		printf("%s%-23s\t%s\n",
392 		    (conf->tab_ok ? "\t" : ""), p->name, p->meaning);
393 	}
394 
395 }
396 
397 
398 /*
399  * dump_name_value - print all infonames and values
400  */
401 S_FUNC void
dump_name_value(void)402 dump_name_value(void)
403 {
404 	struct infoname *p;	/* current infoname */
405 
406 	/* dump the entire table */
407 	for (p = sys_info; p->name != NULL; ++p) {
408 		if (p->str == NULL) {
409 #if LONG_BITS == FULL_BITS || FULL_BITS == 32
410 			printf("%s%-23s\t%-8lu\t(0x%lx)\n",
411 			    (conf->tab_ok ? "\t" : ""), p->name,
412 			    (unsigned long)p->nmbr,
413 			    (unsigned long)p->nmbr);
414 #else
415 			printf("%s%-23s\t%-8llu\t(0x%llx)\n",
416 			    (conf->tab_ok ? "\t" : ""), p->name,
417 			    (unsigned long long)p->nmbr,
418 			    (unsigned long long)p->nmbr);
419 #endif
420 		} else {
421 			printf("%s%-23s\t\"%s\"\n",
422 			    (conf->tab_ok ? "\t" : ""), p->name, p->str);
423 		}
424 	}
425 
426 }
427 
428 
429 /*
430  * dump_mening_value - print all values and meanings
431  */
432 S_FUNC void
dump_mening_value(void)433 dump_mening_value(void)
434 {
435 	struct infoname *p;	/* current infoname */
436 
437 	/* dump the entire table */
438 	for (p = sys_info; p->name != NULL; ++p) {
439 		if (p->str == NULL) {
440 #if LONG_BITS == FULL_BITS || FULL_BITS == 32
441 			printf("%s%-36.36s\t%-8lu\t(0x%lx)\n",
442 			    (conf->tab_ok ? "\t" : ""), p->meaning,
443 			    (unsigned long)p->nmbr,
444 			    (unsigned long)p->nmbr);
445 #else
446 			printf("%s%-36.36s\t%-8llu\t(0x%llx)\n",
447 			    (conf->tab_ok ? "\t" : ""), p->meaning,
448 			    (unsigned long long)p->nmbr,
449 			    (unsigned long long)p->nmbr);
450 #endif
451 		} else {
452 			printf("%s%-36.36s\t\"%s\"\n",
453 			    (conf->tab_ok ? "\t" : ""), p->meaning, p->str);
454 		}
455 	}
456 
457 }
458 
459 #endif /* CUSTOM */
460