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