source: git/Singular/feOpt.cc @ 8ed989

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