source: git/Singular/feOpt.cc @ 9680805

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