1 /****************************************
2 * Computer Algebra System SINGULAR *
3 ****************************************/
4 /*
5 * ABSTRACT: Implementation of option buisness
6 */
7
8
9 #include <string.h>
10
11 #include "kernel/mod2.h"
12
13 #include "factory/factory.h"
14
15 #define FE_OPT_STRUCTURE
16 #include "feOpt.h"
17
18 #if !defined(GENERATE_OPTION_INDEX) && !defined(ESINGULAR) && !defined(TSINGULAR)
19 #include "misc/options.h"
20 #include "misc/sirandom.h"
21 #endif
22
23 #include "fehelp.h"
24
25 #ifdef HAVE_FLINT
26 #include <flint/flint.h>
27 #endif
28
29 const char SHORT_OPTS_STRING[] = "bdhpqstvxec:r:u:";
30
31 //////////////////////////////////////////////////////////////
32 //
33 // Generation of feOptIndex
34 //
35 #ifdef GENERATE_OPTION_INDEX
36
37 #include <stdio.h>
38 //#include <unistd.h>
39 //#include <stdlib.h>
main()40 int main()
41 {
42 FILE* fd;
43 #ifdef ESINGULAR
44 fd = fopen("feOptES.xx", "w");
45 #elif defined(TSINGULAR)
46 fd = fopen("feOptTS.xx", "w");
47 #else
48 fd = fopen("feOpt.xx", "w");
49 #endif
50
51 if (fd == NULL) exit(1);
52
53 int i = 0;
54
55 fputs("typedef enum\n{\n", fd);
56
57 while (feOptSpec[i].name != NULL)
58 {
59 const char* name = feOptSpec[i].name;
60 fputs("FE_OPT_", fd);
61 while (*name != 0)
62 {
63 if (*name == '-')
64 {
65 putc('_', fd);
66 }
67 else if (*name >= 97 && *name <= 122)
68 {
69 putc(*name - 32, fd);
70 }
71 else
72 {
73 putc(*name, fd);
74 }
75 name++;
76 }
77 if (i == 0)
78 {
79 fputs("=0", fd);
80 }
81 i++;
82 fputs(",\n ", fd);
83 }
84
85 fprintf(fd, "FE_OPT_UNDEF\n} feOptIndex;\n");
86 fclose(fd);
87 #ifdef ESINGULAR
88 rename("feOptES.xx", "feOptES.inc");
89 #elif defined(TSINGULAR)
90 rename("feOptTS.xx", "feOptTS.inc");
91 #else
92 rename("feOpt.xx", "feOpt.inc");
93 #endif
94 return(0);
95 }
96
97 #else // ! GENERATE_OPTION_INDEX
98
99 ///////////////////////////////////////////////////////////////
100 //
101 // Getting Values
102 //
103
feGetOptIndex(const char * name)104 feOptIndex feGetOptIndex(const char* name)
105 {
106 int opt = 0;
107
108 while (opt != (int) FE_OPT_UNDEF)
109 {
110 if (strcmp(feOptSpec[opt].name, name) == 0)
111 return (feOptIndex) opt;
112 opt = opt + 1;
113 }
114 return FE_OPT_UNDEF;
115 }
116
feGetOptIndex(int optc)117 feOptIndex feGetOptIndex(int optc)
118 {
119 int opt = 0;
120
121 if (optc == LONG_OPTION_RETURN) return FE_OPT_UNDEF;
122
123 while (opt != (int) FE_OPT_UNDEF)
124 {
125 if (feOptSpec[opt].val == optc)
126 return (feOptIndex) opt;
127 opt = opt + 1;
128 }
129 return FE_OPT_UNDEF;
130 }
131
132 ///////////////////////////////////////////////////////////////
133 //
134 // Setting Values
135 //
136 //
137 // Return: NULL -- everything ok
138 // "error-string" on error
139 #if !defined(ESINGULAR) && !defined(TSINGULAR)
140
141 #include "omalloc/omalloc.h"
142 #include "resources/feResource.h"
143 #include "kernel/oswrapper/feread.h"
144 #include "kernel/oswrapper/timer.h"
145
146 #include "ipshell.h"
147 #include "tok.h"
148 #include "sdb.h"
149 #include "cntrlc.h"
150
151 #include <errno.h>
152
153 static const char* feOptAction(feOptIndex opt);
feSetOptValue(feOptIndex opt,char * optarg)154 const char* feSetOptValue(feOptIndex opt, char* optarg)
155 {
156 if (opt == FE_OPT_UNDEF) return "option undefined";
157
158 if (feOptSpec[opt].type != feOptUntyped)
159 {
160 if (feOptSpec[opt].type != feOptString)
161 {
162 if (optarg != NULL)
163 {
164 errno = 0;
165 feOptSpec[opt].value = (void*) strtol(optarg, NULL, 10);
166 if (errno) return "invalid integer argument";
167 }
168 else
169 {
170 feOptSpec[opt].value = (void*) 0;
171 }
172 }
173 else
174 {
175 assume(feOptSpec[opt].type == feOptString);
176 if (feOptSpec[opt].set && feOptSpec[opt].value != NULL)
177 omFree(feOptSpec[opt].value);
178 if (optarg != NULL)
179 feOptSpec[opt].value = omStrDup(optarg);
180 else
181 feOptSpec[opt].value = NULL;
182 feOptSpec[opt].set = 1;
183 }
184 }
185 return feOptAction(opt);
186 }
187
feSetOptValue(feOptIndex opt,int optarg)188 const char* feSetOptValue(feOptIndex opt, int optarg)
189 {
190 if (opt == FE_OPT_UNDEF) return "option undefined";
191
192 if (feOptSpec[opt].type != feOptUntyped)
193 {
194 if (feOptSpec[opt].type == feOptString)
195 return "option value needs to be an integer";
196
197 feOptSpec[opt].value = (void*)(long) optarg;
198 }
199 return feOptAction(opt);
200 }
201
feOptAction(feOptIndex opt)202 static const char* feOptAction(feOptIndex opt)
203 {
204 // do some special actions
205 switch(opt)
206 {
207 case FE_OPT_BATCH:
208 if (feOptSpec[FE_OPT_BATCH].value)
209 fe_fgets_stdin=fe_fgets_dummy;
210 return NULL;
211
212 case FE_OPT_HELP:
213 feOptHelp(feArgv0);
214 return NULL;
215
216 case FE_OPT_PROFILE:
217 traceit=1024;
218 return NULL;
219
220 case FE_OPT_QUIET:
221 if (feOptSpec[FE_OPT_QUIET].value)
222 si_opt_2 &= ~(Sy_bit(0)|Sy_bit(V_LOAD_LIB));
223 else
224 si_opt_2 |= Sy_bit(V_LOAD_LIB)|Sy_bit(0);
225 return NULL;
226
227 case FE_OPT_NO_TTY:
228 if (feOptSpec[FE_OPT_NO_TTY].value)
229 fe_fgets_stdin=fe_fgets;
230 return NULL;
231
232 case FE_OPT_SDB:
233 #ifdef HAVE_SDB
234 if (feOptSpec[FE_OPT_SDB].value)
235 sdb_flags = 1;
236 else
237 sdb_flags = 0;
238 #endif
239 return NULL;
240
241 case FE_OPT_VERSION:
242 {
243 char *s=versionString();
244 printf("%s",s);
245 omFree(s);
246 return NULL;
247 }
248
249 case FE_OPT_ECHO:
250 si_echo = (int) ((long)(feOptSpec[FE_OPT_ECHO].value));
251 if (si_echo < 0 || si_echo > 9)
252 return "argument of option is not in valid range 0..9";
253 return NULL;
254
255 case FE_OPT_RANDOM:
256 siRandomStart = (unsigned int) ((unsigned long)
257 (feOptSpec[FE_OPT_RANDOM].value));
258 siSeed=siRandomStart;
259 factoryseed(siRandomStart);
260 return NULL;
261
262 case FE_OPT_EMACS:
263 if (feOptSpec[FE_OPT_EMACS].value)
264 {
265 // print EmacsDir and InfoFile so that Emacs
266 // mode can pcik it up
267 Warn("EmacsDir: %s", (feResource('e' /*"EmacsDir"*/) != NULL ?
268 feResource('e' /*"EmacsDir"*/) : ""));
269 Warn("InfoFile: %s", (feResource('i' /*"InfoFile"*/) != NULL ?
270 feResource('i' /*"InfoFile"*/) : ""));
271 }
272 return NULL;
273
274 case FE_OPT_NO_WARN:
275 if (feOptSpec[FE_OPT_NO_WARN].value)
276 feWarn = FALSE;
277 else
278 feWarn = TRUE;
279 return NULL;
280
281 case FE_OPT_NO_OUT:
282 if (feOptSpec[FE_OPT_NO_OUT].value)
283 feOut = FALSE;
284 else
285 feOut = TRUE;
286 return NULL;
287
288 case FE_OPT_MIN_TIME:
289 {
290 double mintime = atof((char*) feOptSpec[FE_OPT_MIN_TIME].value);
291 if (mintime <= 0) return "invalid float argument";
292 SetMinDisplayTime(mintime);
293 return NULL;
294 }
295
296 case FE_OPT_BROWSER:
297 feHelpBrowser((char*) feOptSpec[FE_OPT_BROWSER].value, 1);
298
299 case FE_OPT_TICKS_PER_SEC:
300 {
301 int ticks = (int) ((long)(feOptSpec[FE_OPT_TICKS_PER_SEC].value));
302 if (ticks <= 0)
303 return "integer argument must be larger than 0";
304 SetTimerResolution(ticks);
305 return NULL;
306 }
307
308 case FE_OPT_DUMP_VERSIONTUPLE:
309 {
310 feOptDumpVersionTuple();
311 return NULL;
312 }
313
314 #ifdef HAVE_FLINT
315 #if __FLINT_RELEASE >= 20503
316 case FE_OPT_FLINT_THREADS:
317 {
318 slong nthreads = (slong)feOptSpec[FE_OPT_FLINT_THREADS].value;
319 nthreads = FLINT_MAX(nthreads, WORD(1));
320 flint_set_num_threads(nthreads);
321 int * cpu_affinities = new int[nthreads];
322 for (slong i = 0; i < nthreads; i++)
323 cpu_affinities[i] = (int)i;
324 flint_set_thread_affinity(cpu_affinities, nthreads);
325 delete[] cpu_affinities;
326 return NULL;
327 }
328 #endif
329 #endif
330
331 default:
332 return NULL;
333 }
334 }
335
336 // Prints usage message
fePrintOptValues()337 void fePrintOptValues()
338 {
339 int i = 0;
340
341 while (feOptSpec[i].name != 0)
342 {
343 if (feOptSpec[i].help != NULL && feOptSpec[i].type != feOptUntyped
344 #ifndef SING_NDEBUG
345 && *(feOptSpec[i].help) != '/'
346 #endif
347 )
348 {
349 if (feOptSpec[i].type == feOptString)
350 {
351 if (feOptSpec[i].value == NULL)
352 {
353 Print("// --%-15s\n", feOptSpec[i].name);
354 }
355 else
356 {
357 Print("// --%-15s \"%s\"\n", feOptSpec[i].name, (char*) feOptSpec[i].value);
358 }
359 }
360 else
361 {
362 Print("// --%-15s %d\n", feOptSpec[i].name, (int)(long)feOptSpec[i].value);
363 }
364 }
365 i++;
366 }
367 }
368
369 #endif // ! ESingular
370
371 // Prints help message
feOptHelp(const char * name)372 void feOptHelp(const char* name)
373 {
374 int i = 0;
375 char tmp[60];
376 #if defined(ESINGULAR)
377 printf("ESingular starts up Singular within emacs;\n");
378 #elif defined(TSINGULAR)
379 printf("TSingular starts up Singular within a terminal window;\n");
380 #endif
381 printf("Singular is a Computer Algebra System (CAS) for Polynomial Computations.\n");
382 printf("Usage: %s [options] [file1 [file2 ...]]\n", name);
383 printf("Options:\n");
384
385 while (feOptSpec[i].name != 0)
386 {
387 if (feOptSpec[i].help != NULL
388 #ifdef SING_NDEBUG
389 && *(feOptSpec[i].help) != '/'
390 #endif
391 )
392 {
393 if (feOptSpec[i].has_arg > 0)
394 {
395 if (feOptSpec[i].has_arg > 1)
396 sprintf(tmp, "%s[=%s]", feOptSpec[i].name, feOptSpec[i].arg_name);
397 else
398 sprintf(tmp, "%s=%s", feOptSpec[i].name, feOptSpec[i].arg_name);
399
400 printf(" %c%c --%-20s %s\n",
401 (feOptSpec[i].val != LONG_OPTION_RETURN ? '-' : ' '),
402 (feOptSpec[i].val != LONG_OPTION_RETURN ? feOptSpec[i].val : ' '),
403 tmp,
404 feOptSpec[i].help);
405 }
406 else
407 {
408 printf(" %c%c --%-20s %s\n",
409 (feOptSpec[i].val != LONG_OPTION_RETURN ? '-' : ' '),
410 (feOptSpec[i].val != LONG_OPTION_RETURN ? feOptSpec[i].val : ' '),
411 feOptSpec[i].name,
412 feOptSpec[i].help);
413 }
414 }
415 i++;
416 }
417
418 printf("\nFor more information, type `help;' from within Singular or visit\n");
419 printf("https://www.singular.uni-kl.de or consult the\n");
420 printf("Singular manual (available as on-line info or html manual).\n");
421 }
422
feOptDumpVersionTuple(void)423 void feOptDumpVersionTuple(void)
424 {
425 printf("%s\n",VERSION);
426 }
427
428 #endif // GENERATE_OPTION_INDEX
429