source: git/Singular/feOpt.cc @ 70881f7

fieker-DuValspielwiese
Last change on this file since 70881f7 was e287fa, checked in by Hans Schoenemann <hannes@…>, 14 years ago
synatx fix git-svn-id: file:///usr/local/Singular/svn/trunk@12970 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 15.7 KB
RevLine 
[c06a32]1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
[341696]4/* $Id$ */
[c06a32]5/*
6* ABSTRACT: Implementation of option buisness
7*/
8
[50cbdc]9#include <string.h>
[f3a470]10#include <stdlib.h>
[c06a32]11#include "mod2.h"
12#include "feOpt.h"
[487f79]13#if !defined(GENERATE_OPTION_INDEX) && !defined(ESINGULAR) && !defined(TSINGULAR)
14#include "options.h"
15#endif
[c06a32]16
17// Define here which cmd-line options are recognized
18struct fe_option feOptSpec[] =
19{
20//
[3b295e]21//  Has to be of the form
22//    {name, has_arg, val,
23//     arg_name, help, type, value, set}
[c06a32]24//  where:
25//
26//        name   is the name of the long option.
[3b295e]27//
[c06a32]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.
[3b295e]33//
[c06a32]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//
[3b295e]39//        arg_name if set, uses this value as name for argument in
[c06a32]40//                display of help
[3b295e]41//
[c06a32]42//        help  one-line description of option
43//
[3b295e]44//        type  one of feOptUntyped (value is never set),
[b6f537]45//                     feOptBool, feOptInt, feOptString
[3b295e]46//
[c06a32]47//        value (default) value of option
[3b295e]48//
49//       set   only relevant for feOptString:
[c06a32]50//             1: if value different from default value
[3b295e]51//             0: otherwise
[c06a32]52//
[3b295e]53// The order in which options are specified is the order in which
[c06a32]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
[3b295e]58//
[ef0124]59#if defined(ESINGULAR) || defined(TSINGULAR)
[c06a32]60#ifdef ESINGULAR
61// options only relevant for ESINGULAR
[3b295e]62  {"emacs",         required_argument,      LONG_OPTION_RETURN,
[c06a32]63   "EMACS",     "Use EMACS as emacs program to run Singular",          feOptString, 0,   0},
64
[3b295e]65  {"emacs-dir",         required_argument,  LONG_OPTION_RETURN,
[c06a32]66   "DIR",       "Use DIR as directory to look for emacs lisp files",   feOptString, 0,   0},
67
[3b295e]68  {"emacs-load",        required_argument,  LONG_OPTION_RETURN,
[c06a32]69   "FILE",      "Load FILE on emacs start-up, instead of default",     feOptString, 0,   0},
[ef0124]70#else
71  {"xterm",         required_argument,      LONG_OPTION_RETURN,
72   "XTERM",     "Use XTERM as terminal program to run Singular",          feOptString, 0,   0},
[a3bc95e]73#endif
[3b295e]74
75  {"singular",          required_argument,  LONG_OPTION_RETURN,
[c06a32]76   "PROG",      "Start PROG as Singular program within emacs",         feOptString, 0,   0},
77
[ef0124]78  {"no-call",     no_argument,        LONG_OPTION_RETURN,
79   0,          "Do not start program. Print call to stdout",       feOptBool,   0,   0},
[c06a32]80#endif
81
82#ifdef HAVE_MPSR
[3b295e]83  {"batch",             no_argument,        'b',
[c06a32]84   0,          "Run in MP batch mode",                                 feOptBool,    0,     0},
85#endif
86
[3b295e]87  {"execute",           required_argument,  'c',
[c06a32]88   "STRING",   "Execute STRING on start-up",                           feOptString, 0,   0},
[3b295e]89
90  {"sdb",               no_argument,        'd',
[c06a32]91   0,          "Enable source code debugger (experimental)",           feOptBool,    0,      0},
92
[3b295e]93  {"echo",              optional_argument,  'e',
[c06a32]94   "VAL",       "Set value of variable `echo' to (integer) VAL",        feOptInt,    0,      0},
[3b295e]95
96  {"help",              no_argument,        'h',
[b6f537]97   0,          "Print help message and exit",                          feOptUntyped,    0,      0},
[c06a32]98
[3b295e]99  {"quiet",             no_argument,        'q',
[c06a32]100   0,          "Do not print start-up banner and lib load messages",   feOptBool,    0,      0},
[adf4ba]101  {"sort",             no_argument,        's',
102   0,          "// Sort NTL results",                                  feOptBool,    0,      0},
[c06a32]103
[3b295e]104  {"random",            required_argument,  'r',
[c06a32]105   "SEED",     "Seed random generator with integer (integer) SEED",    feOptInt,    0,      0},
106
[3b295e]107  {"no-tty",            no_argument,        't',
[c06a32]108   0,          "Do not redefine the terminal characteristics",         feOptBool,    0,      0},
109
[3b295e]110  {"user-option",       required_argument,  'u',
[c06a32]111   "STRING",   "Return STRING on `system(\"--user-option\")'",         feOptString, 0,   0},
112
[3b295e]113  {"version",           no_argument,        'v',
[b6f537]114   0,          "Print extended version and configuration info",        feOptUntyped,    0,      0},
[c06a32]115
116#ifdef HAVE_TCL
[3b295e]117  {"tclmode",           no_argument,        'x',
[c06a32]118   0,          "Run in TCL mode, i.e., with TCL user interface",       feOptBool,    0,      0},
119#endif
120
[3b295e]121  {"allow-net",         no_argument,        LONG_OPTION_RETURN,
[6123fa2]122   0,          "Allow to fetch (html) help pages from the net",                feOptBool,    0,      0},
123
[3b295e]124  {"browser",           required_argument,  LONG_OPTION_RETURN,
[d5f3509]125   "BROWSER",  "Display help in BROWSER (see help.cnf)",       feOptString, 0,   0},
[c06a32]126
127#ifndef ESINGULAR
[3b295e]128  {"emacs",             no_argument,        LONG_OPTION_RETURN,
[c06a32]129   0,          "Set defaults for running within emacs",                feOptBool,    0,      0},
130#endif
131
[3b295e]132  {"no-stdlib",         no_argument,        LONG_OPTION_RETURN,
[c06a32]133   0,          "Do not load `standard.lib' on start-up",               feOptBool,    0,      0},
[3b295e]134
135  {"no-rc",             no_argument,        LONG_OPTION_RETURN,
[6123fa2]136   0,          "Do not execute `.singularrc' file(s) on start-up",     feOptBool,    0,      0},
[c06a32]137
[3b295e]138  {"no-warn",           no_argument,        LONG_OPTION_RETURN,
[c06a32]139   0,          "Do not display warning messages",                      feOptBool,    0,      0},
140
[3b295e]141  {"no-out",            no_argument,        LONG_OPTION_RETURN,
[c06a32]142   0,          "Suppress all output",                                  feOptBool,    0,      0},
143
[3b295e]144  {"min-time",          required_argument,  LONG_OPTION_RETURN,
[a70441f]145  "SECS",     "Do not display times smaller than SECS (in seconds)",   feOptString, (void*) "0.5",  0},
[c06a32]146
147#ifdef HAVE_MPSR
[3b295e]148  {"MPport",           required_argument,   LONG_OPTION_RETURN,
[c06a32]149   "PORT",     "Use PORT number for MP conections",                    feOptString,    0,      0},
150
[3b295e]151  {"MPhost",           required_argument,   LONG_OPTION_RETURN,
[c06a32]152   "HOST",     "Use HOST for MP connections",                          feOptString,    0,   0},
[d2f3863]153
154  {"MPrsh",           required_argument,   LONG_OPTION_RETURN,
155   "RSH",     "Use RSH for MP connections",                          feOptString,    0,   0},
[c06a32]156#endif
157
[3b295e]158  {"ticks-per-sec",     required_argument,  LONG_OPTION_RETURN,
[c06a32]159   "TICKS",     "Sets unit of timer to TICKS per second",               feOptInt,    (void*)1,      0},
160
161// undocumented options
162#ifdef HAVE_MPSR
[3b295e]163  {"MPtransp",         required_argument,   LONG_OPTION_RETURN,
[c06a32]164   "TRANSP",    "// Use TRANSP for MP connections",                     feOptString,    0,   0},
[3b295e]165
166  {"MPmode",           required_argument,   LONG_OPTION_RETURN,
[c06a32]167   "MODE",      "// Use MODE for MP connections",                       feOptString,    0,   0},
168#endif
[3b295e]169
[c06a32]170// terminator -- do NOT remove
[3b295e]171  { 0, 0, 0, 0, 0, feOptInt, 0, 0}
[c06a32]172};
173
[adf4ba]174const char SHORT_OPTS_STRING[] = "bdhqstvxec:r:u:";
[c06a32]175
176//////////////////////////////////////////////////////////////
177//
178// Generation of feOptIndex
179//
180#ifdef GENERATE_OPTION_INDEX
181
182#include <stdio.h>
[07c5ee]183#include <unistd.h>
[5a39d12]184#include <stdlib.h>
[83c63c]185int main()
[c06a32]186{
187  FILE* fd;
188#ifdef ESINGULAR
[4df19c]189  fd = fopen("feOptES.xx", "w");
[ef0124]190#elif defined(TSINGULAR)
[4df19c]191  fd = fopen("feOptTS.xx", "w");
[a3bc95e]192#else
[e287fa]193  fd = fopen("feOpt.xx", "w");
[c06a32]194#endif
195
196  if (fd == NULL) exit(1);
197
198  int i = 0;
[3b295e]199
200  fputs("typedef enum\n{\n", fd);
201
[c06a32]202  while (feOptSpec[i].name != NULL)
203  {
204    const char* name = feOptSpec[i].name;
205    fputs("FE_OPT_", fd);
206    while (*name != 0)
207    {
[3b295e]208      if (*name == '-')
[c06a32]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  }
[3b295e]229
[c06a32]230  fprintf(fd, "FE_OPT_UNDEF\n} feOptIndex;\n");
231  fclose(fd);
[4df19c]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
[83c63c]239  return(0);
[c06a32]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;
[3b295e]252
[c06a32]253  while (opt != (int) FE_OPT_UNDEF)
254  {
[3b295e]255    if (strcmp(feOptSpec[opt].name, name) == 0)
[c06a32]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;
[3b295e]265
[c06a32]266  if (optc == LONG_OPTION_RETURN) return FE_OPT_UNDEF;
[3b295e]267
[c06a32]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
[2272c33]277void* feGetOptValue(feOptIndex opt)
278{
279  return feOptSpec[(int)opt].value;
280}
281
[c06a32]282///////////////////////////////////////////////////////////////
283//
284// Setting Values
285//
286static void feOptHelp(const char* name);
287//
288// Return: NULL -- everything ok
289//         "error-string" on error
[ef0124]290#if !defined(ESINGULAR) && !defined(TSINGULAR)
[512a2b]291#include "omalloc.h"
[c06a32]292#include "febase.h"
293#include "ipshell.h"
294#include "tok.h"
295#include "sdb.h"
296#include "cntrlc.h"
297#include "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
[0ec43a]305static const char* feOptAction(feOptIndex opt);
306const char* feSetOptValue(feOptIndex opt, char* optarg)
[c06a32]307{
308  if (opt == FE_OPT_UNDEF) return "option undefined";
[3b295e]309
[b6f537]310  if (feOptSpec[opt].type != feOptUntyped)
[c06a32]311  {
[b6f537]312    if (feOptSpec[opt].type != feOptString)
[c06a32]313    {
[b6f537]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      }
[c06a32]324    }
325    else
326    {
[b6f537]327      assume(feOptSpec[opt].type == feOptString);
328      if (feOptSpec[opt].set && feOptSpec[opt].value != NULL)
[c232af]329        omFree(feOptSpec[opt].value);
[b6f537]330      if (optarg != NULL)
[c232af]331        feOptSpec[opt].value = omStrDup(optarg);
[b6f537]332      else
333        feOptSpec[opt].value = NULL;
334      feOptSpec[opt].set = 1;
[c06a32]335    }
336  }
337  return feOptAction(opt);
338}
339
[0ec43a]340const char* feSetOptValue(feOptIndex opt, int optarg)
[c06a32]341{
342  if (opt == FE_OPT_UNDEF) return "option undefined";
[3b295e]343
[b6f537]344  if (feOptSpec[opt].type != feOptUntyped)
345  {
346    if (feOptSpec[opt].type == feOptString)
347      return "option value needs to be an integer";
[3b295e]348
[b6f537]349    feOptSpec[opt].value = (void*) optarg;
350  }
[c06a32]351  return feOptAction(opt);
352}
353
[0ec43a]354static const char* feOptAction(feOptIndex opt)
[c06a32]355{
356  // do some special actions
357  switch(opt)
358  {
359#ifdef HAVE_MPSR
360      case FE_OPT_BATCH:
[b6f537]361        if (feOptSpec[FE_OPT_BATCH].value)
362          fe_fgets_stdin=fe_fgets_dummy;
[c06a32]363        return NULL;
364#endif
365
366      case FE_OPT_HELP:
367        feOptHelp(feArgv0);
368        return NULL;
369
370      case FE_OPT_QUIET:
[b6f537]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);
[c06a32]375        return NULL;
376
377      case FE_OPT_NO_TTY:
378#if defined(HAVE_FEREAD) || defined(HAVE_READLINE)
[b6f537]379        if (feOptSpec[FE_OPT_NO_TTY].value)
380          fe_fgets_stdin=fe_fgets;
[c06a32]381#endif
382        return NULL;
383
384      case FE_OPT_SDB:
[50cbdc]385      #ifdef HAVE_SDB
[b6f537]386        if (feOptSpec[FE_OPT_SDB].value)
387          sdb_flags = 1;
388        else
389          sdb_flags = 0;
[f3a470]390      #endif
[c06a32]391        return NULL;
392
393      case FE_OPT_VERSION:
[6b4ff12]394        printf("%s",versionString());
[c06a32]395        return NULL;
396
397#ifdef HAVE_TCL
398      case FE_OPT_TCLMODE:
[b6f537]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        }
[c06a32]405        return NULL;
406#endif
407
408      case FE_OPT_ECHO:
[7447d8]409        si_echo = (int) ((long)(feOptSpec[FE_OPT_ECHO].value));
[c06a32]410        if (si_echo < 0 || si_echo > 9)
411          return "argument of option is not in valid range 0..9";
412        return NULL;
[3b295e]413
[b6f537]414      case FE_OPT_RANDOM:
[7447d8]415        siRandomStart = (unsigned int) ((unsigned long)
416                                          (feOptSpec[FE_OPT_RANDOM].value));
[c06a32]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:
[b6f537]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        }
[c06a32]437        return NULL;
438
439      case FE_OPT_NO_WARN:
[b6f537]440        if (feOptSpec[FE_OPT_NO_WARN].value)
441          feWarn = FALSE;
442        else
443          feWarn = TRUE;
[c06a32]444        return NULL;
[3b295e]445
[c06a32]446      case FE_OPT_NO_OUT:
[b6f537]447        if (feOptSpec[FE_OPT_NO_OUT].value)
448          feOut = FALSE;
449        else
450          feOut = TRUE;
[c06a32]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:
[6123fa2]462        feHelpBrowser((char*) feOptSpec[FE_OPT_BROWSER].value, 1);
[c06a32]463
464      case FE_OPT_TICKS_PER_SEC:
465      {
[7447d8]466        int ticks = (int) ((long)(feOptSpec[FE_OPT_TICKS_PER_SEC].value));
[c06a32]467        if (ticks <= 0)
468          return "integer argument must be larger than 0";
469        SetTimerResolution(ticks);
470        return NULL;
471      }
[b6f537]472
[c06a32]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  {
[b6f537]485    if (feOptSpec[i].help != NULL && feOptSpec[i].type != feOptUntyped
[c06a32]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      {
[d97aa5]504        Print("// --%-15s %d\n", feOptSpec[i].name, (int)(long)feOptSpec[i].value);
[c06a32]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");
[3b295e]520#endif
[c06a32]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  {
[3b295e]527    if (feOptSpec[i].help != NULL
[c06a32]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");
[f2b960]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");
[c06a32]561}
562
563
564
565#endif // GENERATE_OPTION_INDEX
Note: See TracBrowser for help on using the repository browser.