source: git/Singular/feOpt.cc @ e8a9f3

spielwiese
Last change on this file since e8a9f3 was e8a9f3, checked in by Oleksandr Motsak <motsak@…>, 13 years ago
CHG: minor fixes + cleanup of *.inc generation in Singular/
  • Property mode set to 100644
File size: 15.4 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id$ */
5/*
6* ABSTRACT: Implementation of option buisness
7*/
8
9#include <string.h>
10#include <stdlib.h>
11
12#include <kernel/mod2.h>
13
14#ifdef HAVE_FACTORY
15#define SI_DONT_HAVE_GLOBAL_VARS
16#include <factory/factory.h>
17#endif
18
19#include "feOpt.h"
20
21#if !defined(GENERATE_OPTION_INDEX) && !defined(ESINGULAR) && !defined(TSINGULAR)
22#include <misc/options.h>
23#endif
24
25#include "fehelp.h"
26
27// Define here which cmd-line options are recognized
28struct fe_option feOptSpec[] =
29{
30//
31//  Has to be of the form
32//    {name, has_arg, val,
33//     arg_name, help, type, value, set}
34//  where:
35//
36//        name   is the name of the long option.
37//
38//        has_arg
39//               is:  no_argument (or 0) if the option does not take
40//               an argument, required_argument (or 1) if the option
41//               requires  an  argument, or optional_argument (or 2)
42//               if the option takes an optional argument.
43//
44//        val    is  the  value  to  return,  or  to  load  into the
45//               variable pointed to by flag.
46//               NEEDS TO BE LONG_OPTION_RETURN, for long option
47//                           short option char,  for short option
48//
49//        arg_name if set, uses this value as name for argument in
50//                display of help
51//
52//        help  one-line description of option
53//
54//        type  one of feOptUntyped (value is never set),
55//                     feOptBool, feOptInt, feOptString
56//
57//        value (default) value of option
58//
59//       set   only relevant for feOptString:
60//             1: if value different from default value
61//             0: otherwise
62//
63// The order in which options are specified is the order in which
64// their help is printed on -h
65//
66// Options whose hel starts with an "//" are considered undocumented,
67// i.e., their help is not printed on -h
68//
69#if defined(ESINGULAR) || defined(TSINGULAR)
70#ifdef ESINGULAR
71// options only relevant for ESINGULAR
72  {"emacs",         required_argument,      LONG_OPTION_RETURN,
73   "EMACS",     "Use EMACS as emacs program to run Singular",          feOptString, 0,   0},
74
75  {"emacs-dir",         required_argument,  LONG_OPTION_RETURN,
76   "DIR",       "Use DIR as directory to look for emacs lisp files",   feOptString, 0,   0},
77
78  {"emacs-load",        required_argument,  LONG_OPTION_RETURN,
79   "FILE",      "Load FILE on emacs start-up, instead of default",     feOptString, 0,   0},
80#else
81  {"xterm",         required_argument,      LONG_OPTION_RETURN,
82   "XTERM",     "Use XTERM as terminal program to run Singular",       feOptString, 0,   0},
83#endif
84
85  {"singular",          required_argument,  LONG_OPTION_RETURN,
86   "PROG",      "Start PROG as Singular program within emacs",         feOptString, 0,   0},
87
88  {"no-call",     no_argument,        LONG_OPTION_RETURN,
89   0,          "Do not start program. Print call to stdout",           feOptBool,   0,   0},
90#endif
91
92  {"batch",             no_argument,        'b',
93   0,          "Run in batch mode",                                    feOptBool,    0,     0},
94
95  {"execute",           required_argument,  'c',
96   "STRING",   "Execute STRING on start-up",                           feOptString, 0,   0},
97
98  {"sdb",               no_argument,        'd',
99   0,          "Enable source code debugger (experimental)",           feOptBool,    0,      0},
100
101  {"echo",              optional_argument,  'e',
102   "VAL",       "Set value of variable `echo' to (integer) VAL",        feOptInt,    0,      0},
103
104  {"help",              no_argument,        'h',
105   0,          "Print help message and exit",                          feOptUntyped,    0,      0},
106
107  {"quiet",             no_argument,        'q',
108   0,          "Do not print start-up banner and lib load messages",   feOptBool,    0,      0},
109  {"sort",             no_argument,        's',
110   0,          "// Sort NTL results",                                  feOptBool,    0,      0},
111
112  {"random",            required_argument,  'r',
113   "SEED",     "Seed random generator with (integer) SEED",            feOptInt,    0,      0},
114
115  {"no-tty",            no_argument,        't',
116   0,          "Do not redefine the terminal characteristics",         feOptBool,    0,      0},
117
118  {"user-option",       required_argument,  'u',
119   "STRING",   "Return STRING on `system(\"--user-option\")'",         feOptString, 0,   0},
120
121  {"version",           no_argument,        'v',
122   0,          "Print extended version and configuration info",        feOptUntyped,    0,      0},
123
124
125  {"allow-net",         no_argument,        LONG_OPTION_RETURN,
126   0,          "Allow to fetch (html) help pages from the net",                feOptBool,    0,      0},
127
128  {"browser",           required_argument,  LONG_OPTION_RETURN,
129   "BROWSER",  "Display help in BROWSER (see help.cnf)",       feOptString, 0,   0},
130
131#ifndef ESINGULAR
132  {"emacs",             no_argument,        LONG_OPTION_RETURN,
133   0,          "Set defaults for running within emacs",                feOptBool,    0,      0},
134#endif
135
136  {"no-stdlib",         no_argument,        LONG_OPTION_RETURN,
137   0,          "Do not load `standard.lib' on start-up",               feOptBool,    0,      0},
138
139  {"no-rc",             no_argument,        LONG_OPTION_RETURN,
140   0,          "Do not execute `.singularrc' file(s) on start-up",     feOptBool,    0,      0},
141
142  {"no-warn",           no_argument,        LONG_OPTION_RETURN,
143   0,          "Do not display warning messages",                      feOptBool,    0,      0},
144
145  {"no-out",            no_argument,        LONG_OPTION_RETURN,
146   0,          "Suppress all output",                                  feOptBool,    0,      0},
147
148  {"min-time",          required_argument,  LONG_OPTION_RETURN,
149  "SECS",     "Do not display times smaller than SECS (in seconds)",   feOptString, (void*) "0.5",  0},
150
151  {"MPport",           required_argument,   LONG_OPTION_RETURN,
152   "PORT",     "Use PORT number for conections",                       feOptString,    0,      0},
153
154  {"MPhost",           required_argument,   LONG_OPTION_RETURN,
155   "HOST",     "Use HOST for connections",                             feOptString,    0,   0},
156
157  {"link",           required_argument,   LONG_OPTION_RETURN,
158   "LINK",     "Use LINK for connections",                             feOptString,    0,   0},
159
160#ifdef HAVE_MPSR
161  {"MPrsh",           required_argument,   LONG_OPTION_RETURN,
162   "RSH",     "Use RSH for MP connections",                            feOptString,    0,   0},
163#endif
164
165  {"ticks-per-sec",     required_argument,  LONG_OPTION_RETURN,
166   "TICKS",     "Sets unit of timer to TICKS per second",               feOptInt,    (void*)1,      0},
167
168// undocumented options
169#ifdef HAVE_MPSR
170  {"MPtransp",         required_argument,   LONG_OPTION_RETURN,
171   "TRANSP",    "// Use TRANSP for MP connections",                     feOptString,    0,   0},
172
173  {"MPmode",           required_argument,   LONG_OPTION_RETURN,
174   "MODE",      "// Use MODE for MP connections",                       feOptString,    0,   0},
175#endif
176
177// terminator -- do NOT remove
178  { 0, 0, 0, 0, 0, feOptInt, 0, 0}
179};
180
181const char SHORT_OPTS_STRING[] = "bdhqstvxec:r:u:";
182
183//////////////////////////////////////////////////////////////
184//
185// Generation of feOptIndex
186//
187#ifdef GENERATE_OPTION_INDEX
188
189#include <stdio.h>
190#include <unistd.h>
191#include <stdlib.h>
192int main()
193{
194  FILE* fd;
195#ifdef ESINGULAR
196  fd = fopen("feOptES.xx", "w");
197#elif defined(TSINGULAR)
198  fd = fopen("feOptTS.xx", "w");
199#else
200  fd = fopen("feOpt.xx", "w");
201#endif
202
203  if (fd == NULL) exit(1);
204
205  int i = 0;
206
207  fputs("typedef enum\n{\n", fd);
208
209  while (feOptSpec[i].name != NULL)
210  {
211    const char* name = feOptSpec[i].name;
212    fputs("FE_OPT_", fd);
213    while (*name != 0)
214    {
215      if (*name == '-')
216      {
217        putc('_', fd);
218      }
219      else if (*name >= 97 && *name <= 122)
220      {
221        putc(*name - 32, fd);
222      }
223      else
224      {
225        putc(*name, fd);
226      }
227      name++;
228    }
229    if (i == 0)
230    {
231      fputs("=0", fd);
232    }
233    i++;
234    fputs(",\n  ", fd);
235  }
236
237  fprintf(fd, "FE_OPT_UNDEF\n} feOptIndex;\n");
238  fclose(fd);
239#ifdef ESINGULAR
240  rename("feOptES.xx", "feOptES.inc");
241#elif defined(TSINGULAR)
242  rename("feOptTS.xx", "feOptTS.inc");
243#else
244  rename("feOpt.xx", "feOpt.inc");
245#endif
246  return(0);
247}
248
249#else // ! GENERATE_OPTION_INDEX
250
251///////////////////////////////////////////////////////////////
252//
253// Getting Values
254//
255
256feOptIndex feGetOptIndex(const char* name)
257{
258  int opt = 0;
259
260  while (opt != (int) FE_OPT_UNDEF)
261  {
262    if (strcmp(feOptSpec[opt].name, name) == 0)
263      return (feOptIndex) opt;
264    opt = opt + 1;
265  }
266  return FE_OPT_UNDEF;
267}
268
269feOptIndex feGetOptIndex(int optc)
270{
271  int opt = 0;
272
273  if (optc == LONG_OPTION_RETURN) return FE_OPT_UNDEF;
274
275  while (opt != (int) FE_OPT_UNDEF)
276  {
277    if (feOptSpec[opt].val == optc)
278      return (feOptIndex) opt;
279    opt = opt + 1;
280  }
281  return FE_OPT_UNDEF;
282}
283
284void* feGetOptValue(feOptIndex opt)
285{
286  return feOptSpec[(int)opt].value;
287}
288
289///////////////////////////////////////////////////////////////
290//
291// Setting Values
292//
293static void feOptHelp(const char* name);
294//
295// Return: NULL -- everything ok
296//         "error-string" on error
297#if !defined(ESINGULAR) && !defined(TSINGULAR)
298#include <omalloc/omalloc.h>
299#include <kernel/febase.h>
300#include <kernel/timer.h>
301
302#include "ipshell.h"
303#include "tok.h"
304#include "sdb.h"
305#include "cntrlc.h"
306
307#include <errno.h>
308
309static const char* feOptAction(feOptIndex opt);
310const char* feSetOptValue(feOptIndex opt, char* optarg)
311{
312  if (opt == FE_OPT_UNDEF) return "option undefined";
313
314  if (feOptSpec[opt].type != feOptUntyped)
315  {
316    if (feOptSpec[opt].type != feOptString)
317    {
318      if (optarg != NULL)
319      {
320        errno = 0;
321        feOptSpec[opt].value = (void*) strtol(optarg, NULL, 10);
322        if (errno) return "invalid integer argument";
323      }
324      else
325      {
326        feOptSpec[opt].value = (void*) 0;
327      }
328    }
329    else
330    {
331      assume(feOptSpec[opt].type == feOptString);
332      if (feOptSpec[opt].set && feOptSpec[opt].value != NULL)
333        omFree(feOptSpec[opt].value);
334      if (optarg != NULL)
335        feOptSpec[opt].value = omStrDup(optarg);
336      else
337        feOptSpec[opt].value = NULL;
338      feOptSpec[opt].set = 1;
339    }
340  }
341  return feOptAction(opt);
342}
343
344const char* feSetOptValue(feOptIndex opt, int optarg)
345{
346  if (opt == FE_OPT_UNDEF) return "option undefined";
347
348  if (feOptSpec[opt].type != feOptUntyped)
349  {
350    if (feOptSpec[opt].type == feOptString)
351      return "option value needs to be an integer";
352
353    feOptSpec[opt].value = (void*) optarg;
354  }
355  return feOptAction(opt);
356}
357
358static const char* feOptAction(feOptIndex opt)
359{
360  // do some special actions
361  switch(opt)
362  {
363      case FE_OPT_BATCH:
364        if (feOptSpec[FE_OPT_BATCH].value)
365          fe_fgets_stdin=fe_fgets_dummy;
366        return NULL;
367
368      case FE_OPT_HELP:
369        feOptHelp(feArgv0);
370        return NULL;
371
372      case FE_OPT_QUIET:
373        if (feOptSpec[FE_OPT_QUIET].value)
374          verbose &= ~(Sy_bit(0)|Sy_bit(V_LOAD_LIB));
375        else
376          verbose |= Sy_bit(V_LOAD_LIB)|Sy_bit(0);
377        return NULL;
378
379      case FE_OPT_NO_TTY:
380#if defined(HAVE_FEREAD) || defined(HAVE_READLINE)
381        if (feOptSpec[FE_OPT_NO_TTY].value)
382          fe_fgets_stdin=fe_fgets;
383#endif
384        return NULL;
385
386      case FE_OPT_SDB:
387      #ifdef HAVE_SDB
388        if (feOptSpec[FE_OPT_SDB].value)
389          sdb_flags = 1;
390        else
391          sdb_flags = 0;
392      #endif
393        return NULL;
394
395      case FE_OPT_VERSION:
396        printf("%s",versionString());
397        return NULL;
398
399      case FE_OPT_ECHO:
400        si_echo = (int) ((long)(feOptSpec[FE_OPT_ECHO].value));
401        if (si_echo < 0 || si_echo > 9)
402          return "argument of option is not in valid range 0..9";
403        return NULL;
404
405      case FE_OPT_RANDOM:
406        siRandomStart = (unsigned int) ((unsigned long)
407                                          (feOptSpec[FE_OPT_RANDOM].value));
408        siSeed=siRandomStart;
409#ifdef HAVE_FACTORY
410        factoryseed(siRandomStart);
411#endif
412        return NULL;
413
414      case FE_OPT_EMACS:
415        if (feOptSpec[FE_OPT_EMACS].value)
416        {
417          // print EmacsDir and InfoFile so that Emacs
418          // mode can pcik it up
419          Warn("EmacsDir: %s", (feResource('e' /*"EmacsDir"*/) != NULL ?
420                                feResource('e' /*"EmacsDir"*/) : ""));
421          Warn("InfoFile: %s", (feResource('i' /*"InfoFile"*/) != NULL ?
422                                feResource('i' /*"InfoFile"*/) : ""));
423        }
424        return NULL;
425
426      case FE_OPT_NO_WARN:
427        if (feOptSpec[FE_OPT_NO_WARN].value)
428          feWarn = FALSE;
429        else
430          feWarn = TRUE;
431        return NULL;
432
433      case FE_OPT_NO_OUT:
434        if (feOptSpec[FE_OPT_NO_OUT].value)
435          feOut = FALSE;
436        else
437          feOut = TRUE;
438        return NULL;
439
440      case FE_OPT_MIN_TIME:
441      {
442        double mintime = atof((char*) feOptSpec[FE_OPT_MIN_TIME].value);
443        if (mintime <= 0) return "invalid float argument";
444        SetMinDisplayTime(mintime);
445        return NULL;
446      }
447
448      case FE_OPT_BROWSER:
449        feHelpBrowser((char*) feOptSpec[FE_OPT_BROWSER].value, 1);
450
451      case FE_OPT_TICKS_PER_SEC:
452      {
453        int ticks = (int) ((long)(feOptSpec[FE_OPT_TICKS_PER_SEC].value));
454        if (ticks <= 0)
455          return "integer argument must be larger than 0";
456        SetTimerResolution(ticks);
457        return NULL;
458      }
459
460      default:
461        return NULL;
462  }
463}
464
465// Prints usage message
466void fePrintOptValues()
467{
468  int i = 0;
469
470  while (feOptSpec[i].name != 0)
471  {
472    if (feOptSpec[i].help != NULL && feOptSpec[i].type != feOptUntyped
473#ifndef NDEBUG
474        && *(feOptSpec[i].help) != '/'
475#endif
476        )
477    {
478      if (feOptSpec[i].type == feOptString)
479      {
480        if (feOptSpec[i].value == NULL)
481        {
482          Print("// --%-15s\n", feOptSpec[i].name);
483        }
484        else
485        {
486          Print("// --%-15s \"%s\"\n", feOptSpec[i].name, (char*) feOptSpec[i].value);
487        }
488      }
489      else
490      {
491        Print("// --%-15s %d\n", feOptSpec[i].name, (int)(long)feOptSpec[i].value);
492      }
493    }
494    i++;
495  }
496}
497
498#endif // ! ESingular
499
500// Prints help message
501static void feOptHelp(const char* name)
502{
503  int i = 0;
504  char tmp[20];
505#ifdef ESINGULAR
506  printf("ESingular: A Program that starts-up Singular within emacs, for\n");
507#endif
508  printf("Singular version %s -- a CAS for polynomial computations. Usage:\n", S_VERSION1);
509  printf("   %s [options] [file1 [file2 ...]]\n", name);
510  printf("Options:\n");
511
512  while (feOptSpec[i].name != 0)
513  {
514    if (feOptSpec[i].help != NULL
515#ifdef NDEBUG
516        && *(feOptSpec[i].help) != '/'
517#endif
518        )
519    {
520      if (feOptSpec[i].has_arg > 0)
521      {
522        if  (feOptSpec[i].has_arg > 1)
523          sprintf(tmp, "%s[=%s]", feOptSpec[i].name, feOptSpec[i].arg_name);
524        else
525          sprintf(tmp, "%s=%s", feOptSpec[i].name, feOptSpec[i].arg_name);
526
527        printf(" %c%c --%-19s %s\n",
528               (feOptSpec[i].val != 0 ? '-' : ' '),
529               (feOptSpec[i].val != 0 ? feOptSpec[i].val : ' '),
530               tmp,
531               feOptSpec[i].help);
532      }
533      else
534      {
535        printf(" %c%c --%-19s %s\n",
536               (feOptSpec[i].val != 0 ? '-' : ' '),
537               (feOptSpec[i].val != 0 ? feOptSpec[i].val : ' '),
538               feOptSpec[i].name,
539               feOptSpec[i].help);
540      }
541    }
542    i++;
543  }
544
545  printf("\nFor more information, type `help;' from within Singular or visit\n");
546  printf("http://www.singular.uni-kl.de or consult the\n");
547  printf("Singular manual (available as on-line info or html manual).\n");
548}
549
550
551
552#endif // GENERATE_OPTION_INDEX
Note: See TracBrowser for help on using the repository browser.