source: git/kernel/feOpt.cc @ 6b4fbf7

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