Separate settings and the SET command, for modularity.
authorBen Pfaff <blp@gnu.org>
Sun, 11 Dec 2005 02:48:44 +0000 (02:48 +0000)
committerBen Pfaff <blp@gnu.org>
Sun, 11 Dec 2005 02:48:44 +0000 (02:48 +0000)
22 files changed:
doc/configuring.texi
doc/utilities.texi
src/ChangeLog
src/Makefile.am
src/casefile.c
src/cmdline.c
src/command.c
src/data-list.c
src/data-out.c
src/filename.c
src/flip.c
src/getl.c
src/glob.c
src/glob.h
src/lexer.c
src/output.c
src/permissions.c
src/q2c.c
src/set.q
src/settings.c [new file with mode: 0644]
src/settings.h
src/sort.c

index 44de42f9ad5a42aa91666f6232c32987756e82f2..3c1a4adcc1d01c853e53807ab97a279ffa755591 100644 (file)
@@ -166,10 +166,7 @@ Configuration file contents.  @xref{Configuration files}.
 Fallback defaults.
 @end enumerate
 
-Some of the above may not apply to a particular setting.  For instance,
-the current pager (such as @samp{more}, @samp{most}, or @samp{less})
-cannot be determined by configuration file contents because there is no
-appropriate configuration file.
+Some of the above may not apply to a particular setting.
 
 @node Configuration files, Environment variables, Configuration techniques, Configuration
 @section Configuration files
@@ -1641,14 +1638,6 @@ across operating systems:
 No default path.
 @end table
 
-@item STAT_PAGER
-@itemx PAGER
-@cindex pager
-
-When PSPP invokes an external pager, it uses the first of these that
-is defined.  There is a default pager only if the person who compiled
-PSPP defined one.
-
 @item TERM
 
 The terminal type @code{termcap} or @code{ncurses} will use, if such
index ea1cfbb2c8c9c1ea7c213046d1e4b5fd134fb018..96341e9c581a1c2b7bba587a9ddc659e0054bfd8 100644 (file)
@@ -262,8 +262,6 @@ SET
         /MXERRS=max_errs
         /MXWARNS=max_warnings
         /PROMPT='prompt'
-        /VIEWLENGTH=@{MINIMUM,MEDIAN,MAXIMUM,n_lines@}
-        /VIEWWIDTH=n_characters
 
 (program execution)
         /MEXPAND=@{ON,OFF@}
@@ -287,22 +285,15 @@ SET
         /PRINTBACK=@{ON,OFF@}
         /RESULTS=@{ON,OFF,TERMINAL,LISTING,BOTH,NONE@}
 
-(output activation)
-        /LISTING=@{ON,OFF@}
-        /PRINTER=@{ON,OFF@}
-        /SCREEN=@{ON,OFF@}
-
 (output driver options)
         /HEADERS=@{NO,YES,BLANK@}
         /LENGTH=@{NONE,length_in_lines@}
-        /LISTING=filename
+        /LISTING=@{ON,OFF,filename@}
         /MORE=@{ON,OFF@}
-        /PAGER=@{OFF,"pager_name"@}
         /WIDTH=@{NARROW,WIDTH,n_characters@}
 
 (logging)
         /JOURNAL=@{ON,OFF@} [filename]
-        /LOG=@{ON,OFF@} [filename]
 
 (system files)
         /COMPRESSION=@{ON,OFF@}
@@ -312,29 +303,19 @@ SET
         /SAFER=ON
 
 (obsolete settings accepted for compatibility, but ignored)
-        /AUTOMENU=@{ON,OFF@}
-        /BEEP=@{ON,OFF@}
-        /BLOCK='c'
         /BOXSTRING=@{'xxx','xxxxxxxxxxx'@}
         /CASE=@{UPPER,UPLOW@}
-        /COLOR=@dots{}
         /CPI=cpi_value
         /DISK=@{ON,OFF@}
-        /EJECT=@{ON,OFF@}
-        /HELPWINDOWS=@{ON,OFF@}
         /HIGHRES=@{ON,OFF@}
         /HISTOGRAM='c'
         /LOWRES=@{AUTO,ON,OFF@}
         /LPI=lpi_value
         /MENUS=@{STANDARD,EXTENDED@}
         /MXMEMORY=max_memory
-        /PTRANSLATE=@{ON,OFF@}
-        /RCOLORS=@dots{}
-        /RUNREVIEW=@{AUTO,MANUAL@}
         /SCRIPTTAB='c'
         /TB1=@{'xxx','xxxxxxxxxxx'@}
         /TBFONTS='string'
-        /WORKDEV=drive_letter
         /WORKSPACE=workspace_size
         /XSORT=@{YES,NO@}
 @end display
@@ -413,15 +394,6 @@ current command file.  The default is 100.
 
 @item PROMPT
 The command prompt.  The default is @samp{PSPP> }.
-
-@item VIEWLENGTH
-The length of the screen in lines.  MINIMUM means 25 lines, MEDIAN and
-MAXIMUM mean 43 lines.  Otherwise specify the number of lines.  Normally
-PSPP should auto-detect your screen size so this shouldn't have to be
-used.
-
-@item VIEWWIDTH
-The width of the screen in characters.  Normally 80 or 132.
 @end table
 
 Program execution subcommands control the way that PSPP commands
@@ -494,20 +466,6 @@ from command files.  The default is OFF.
 Currently not used.
 @end table
 
-Output activation subcommands affect whether output devices of
-particular types are enabled.  These subcommands are
-
-@table @asis
-@item LISTING
-Enable or disable listing devices.
-
-@item PRINTER
-Enable or disable printer devices.
-
-@item SCREEN
-Enable or disable screen devices.
-@end table
-
 Output driver option subcommands affect output drivers' settings.  These
 subcommands are
 
@@ -580,24 +538,47 @@ obvious security reasons.
 
 @display
 SHOW
-        /@var{subcommand}
-        
+        [ALL]
+        [BLANKS]
+        [CC]
+        [CCA]
+        [CCB]
+        [CCC]
+        [CCD]
+        [CCE]
+        [COPYING]
+        [DECIMALS]
+        [ENDCMD]
+        [FORMAT]
+        [LENGTH]
+        [MXERRS]
+        [MXLOOPS]
+        [MXWARNS]
+        [SCOMPRESSION]
+        [UNDEFINED]
+        [WARRANTY]
+        [WEIGHT]
+        [WIDTH]
 @end display
 
-@cmd{SHOW} can be used to display the current state of PSPP's
-execution parameters.  All of the parameters which can be changed 
-using  @code{SET} @xref{SET}, can be examined using @cmd{SHOW}, by
-using a subcommand with the same name.
-In addition, @code{SHOW} supports the following subcommands:
+@cmd{SHOW} can be used to display the current state of PSPP's execution
+parameters.  Parameters that can be changed using @cmd{SET}
+(@pxref{SET}), can be examined using @cmd{SHOW} using the subcommand
+with the same name.  @code{SHOW} supports the following additional
+subcommands:
 
 @table @code
+@item ALL
+Show all settings.
+@item CC
+Show all custom currency settings (CCA through CCE).
 @item WARRANTY
 Show details of the lack of warranty for PSPP.
 @item COPYING
-Display the terms of PSPP's copyright licence @ref{License}.
+Display the terms of PSPP's copyright licence (@pxref{License}).
 @end table
 
-
+Specifying @cmd{SHOW} without any subcommands is equivalent to SHOW ALL.
 
 @node SUBTITLE, TITLE, SHOW, Utilities
 @section SUBTITLE
index a99cdc8c6341b31fbc2a4e197acef40081d504d4..1fc5fef1f7b28e25ffae2ed6440764f199911674 100644 (file)
@@ -1,3 +1,25 @@
+Sat Dec 10 18:13:36 2005  Ben Pfaff  <blp@gnu.org>
+
+       Separate settings and the SET command, for modularity.
+       
+       * Makefile.am: Add settings.c to sources.
+
+       * glob.c: (global variable test_mode) Removed.
+
+       * set.q: Remove all the set_* variables.  Remove a lot of obsolete
+       SPSS/PC+ settings.  Remove the aux_*() routines.  Moved the
+       get_*() functions into settings.c.  Rewrite the settings code and
+       functions to call the new set_*() functions.  Rewrite custom
+       currency parsing.  Write new by-hand cmd_show().
+
+       * esttings.c: New file.  Moved the get_*() functions here from
+       set.q.  Created new set_*() functions to correspond with them.
+       Regularized the names and types of some functions and updated
+       their callers.  Added static, file-scope variables to support the
+       settings.
+
+       * q2c.c: Remove "aux" support, which was only needed by set.q.
+       
 Sun Nov 27 06:43:46 WST 2005 John Darrington <john@darington.wattle.id.au>
 
        * data-out.c format.h: Added return value to data_out function.
index fbd3ef208a946af0622061daa8e8e0cdafda5e1a..857dd8a59b13476459a77c9e9d9febb67202fa61 100644 (file)
@@ -195,6 +195,7 @@ pspp_SOURCES =                                      \
        repeat.h                                \
        sample.c                                \
        sel-if.c                                \
+       settings.c                              \
        settings.h                              \
        sfm-read.c                              \
        sfm-read.h                              \
index aea4a14755565c3c0581a4ea40fd0012c9e4a77f..a49db99d6fcfdedb3b79e16afe758f8699afc824 100644 (file)
@@ -331,7 +331,7 @@ casefile_append (struct casefile *cf, const struct ccase *c)
   /* Try memory first. */
   if (cf->storage == MEMORY) 
     {
-      if (case_bytes < get_max_workspace ())
+      if (case_bytes < get_workspace ())
         {
           size_t block_idx = cf->case_cnt / CASES_PER_BLOCK;
           size_t case_idx = cf->case_cnt % CASES_PER_BLOCK;
index 50214db2717daeac333e2707509c6ea7769bae56..68df7b477df4781488b6607e93a709552eb0b3bb 100644 (file)
@@ -52,7 +52,6 @@ char *subst_vars (char *);
 void
 parse_command_line (int argc, char **argv)
 {
-  static int testing_mode = 0;
   static struct option long_options[] =
   {
     {"algorithm", required_argument, NULL, 'a'},
@@ -73,7 +72,7 @@ parse_command_line (int argc, char **argv)
     {"recon", no_argument, NULL, 'n'},
     {"safer", no_argument, NULL, 's'},
     {"syntax", required_argument, NULL, 'x'},
-    {"testing-mode", no_argument, &testing_mode, 1},
+    {"testing-mode", no_argument, NULL, 'T'},
     {"verbose", no_argument, NULL, 'v'},
     {"version", no_argument, NULL, 'V'},
     {0, 0, 0, 0},
@@ -81,8 +80,8 @@ parse_command_line (int argc, char **argv)
 
   int c, i;
 
-  int cleared_device_defaults = 0;
-  int no_statrc = 0;
+  bool cleared_device_defaults = false;
+  bool no_statrc = false;
 
   for (;;)
     {
@@ -168,7 +167,7 @@ parse_command_line (int argc, char **argv)
          if (!cleared_device_defaults)
            {
              outp_configure_clear ();
-             cleared_device_defaults = 1;
+             cleared_device_defaults = true;
            }
          outp_configure_add (optarg);
          break;
@@ -177,10 +176,10 @@ parse_command_line (int argc, char **argv)
           putchar('\n');
          break;
        case 'r':
-         no_statrc = 1;
+         no_statrc = true;
          break;
        case 's':
-         make_safe();
+         set_safer_mode ();
          break;
        case 'v':
          err_verbosity++;
@@ -189,6 +188,10 @@ parse_command_line (int argc, char **argv)
          puts (version);
          puts (legal);
          err_hcf (1);
+        case 'T':
+          force_long_view ();
+          set_testing_mode (true);
+          break;
        case '?':
          usage ();
          assert (0);
@@ -199,15 +202,6 @@ parse_command_line (int argc, char **argv)
        }
     }
 
-
-  if (testing_mode)
-    {
-      /* FIXME: Later this option should do some other things, too. */
-      force_long_view();
-      test_mode = 1;
-    }
-    
-
   for (i = optind; i < argc; i++)
     {
       int separate = 1;
index 4203ac32d0ea7f478ed1dd65a51bae61ed58f13a..0d557b2092e2c096e7ebfe21b68d6d86d33b8956 100644 (file)
@@ -108,7 +108,7 @@ pspp_completion_function (const char *text,   int state)
 
       cmd = &commands[state + skip];
   
-      if ( cmd->transition[pgm_state] == STATE_ERROR || ( cmd->debug  &&  ! test_mode ) ) 
+      if ( cmd->transition[pgm_state] == STATE_ERROR || ( cmd->debug  &&  ! get_testing_mode () ) ) 
        {
          skip++; 
          continue;
@@ -554,7 +554,7 @@ parse_command_name (void)
             {
               if (command->skip_entire_name)
                 lex_get ();
-             if ( command->debug & !test_mode ) 
+             if ( command->debug & !get_testing_mode () ) 
                goto error;
               free_words (words, word_cnt);
               return command;
@@ -599,7 +599,7 @@ parse_command_name (void)
           free (words[word_cnt]);
         }
 
-      if ( command->debug && !test_mode ) 
+      if ( command->debug && !get_testing_mode () ) 
        goto error;
 
       free_words (words, word_cnt);
@@ -679,7 +679,7 @@ cmd_execute (void)
 int
 cmd_erase (void)
 {
-  if ( safer_mode() 
+  if (get_safer_mode ()
     { 
       msg (SE, _("This command not allowed when the SAFER option is set.")); 
       return CMD_FAILURE; 
@@ -810,7 +810,7 @@ cmd_host (void)
 {
   int code;
 
-  if ( safer_mode() 
+  if (get_safer_mode ()
     { 
       msg (SE, _("This command not allowed when the SAFER option is set.")); 
       return CMD_FAILURE; 
index b615beea4b4925245e16f7b419667d2a7bd6e3c9..ab166f0d65585b9c876ed06333e46240240cbde0 100644 (file)
@@ -844,7 +844,7 @@ parse_free (struct dls_var_spec **first, struct dls_var_spec **last)
        {
          lex_match ('*');
           input = make_input_format (FMT_F, 8, 0);
-         output = get_format ();
+         output = *get_format ();
        }
 
       if (input.type == FMT_A || input.type == FMT_AHEX)
index d26215a9c8cb887db2b827342c18abc7f7b5000d..c9c17a5e642fd6f14fcefe1472df9586dd44bdae 100644 (file)
@@ -965,7 +965,7 @@ year4 (int year)
 static int
 try_CCx (char *dst, const struct fmt_spec *fp, double number)
 {
-  const struct set_cust_currency *cc = get_cc(fp->type - FMT_CCA);
+  const struct custom_currency *cc = get_cc(fp->type - FMT_CCA);
 
   struct fmt_spec f;
 
@@ -975,7 +975,7 @@ try_CCx (char *dst, const struct fmt_spec *fp, double number)
 
   /* Determine length available, decimal character for number
      proper. */
-  f.type = cc->decimal == get_decimal() ? FMT_COMMA : FMT_DOT;
+  f.type = cc->decimal == get_decimal () ? FMT_COMMA : FMT_DOT;
   f.w = fp->w - strlen (cc->prefix) - strlen (cc->suffix);
   if (number < 0)
     f.w -= strlen (cc->neg_prefix) + strlen (cc->neg_suffix) - 1;
index b8f8332fdb9057f753435aedd92e84ae33d27d14..b78897e211bc2be19fec1e01e62e177bcce69e51 100644 (file)
@@ -691,7 +691,7 @@ fn_open (const char *fn, const char *mode)
 #ifdef unix
   if (fn[0] == '|')
     {
-      if (safer_mode())
+      if (get_safer_mode ())
        return safety_violation (fn);
 
       return popen (&fn[1], mode);
@@ -701,7 +701,7 @@ fn_open (const char *fn, const char *mode)
       char *s;
       FILE *f;
 
-      if (safer_mode())
+      if (get_safer_mode ())
        return safety_violation (fn);
       
       s = local_alloc (strlen (fn));
index 9fbea2a4c606b08e80d37ece16f5caa91ace201c..204982357b043ddb45eddec19502b43c9bbf79f0 100644 (file)
@@ -379,7 +379,7 @@ flip_file (struct flip_pgm *flip)
 
   /* Allocate memory for many cases. */
   case_bytes = flip->var_cnt * sizeof *input_buf;
-  case_capacity = get_max_workspace() / case_bytes;
+  case_capacity = get_workspace () / case_bytes;
   if (case_capacity > flip->case_cnt * 2)
     case_capacity = flip->case_cnt * 2;
   if (case_capacity < 2)
index 65ecb12716c9a35834c8767c18c072fa60114299..a02244d7cabd680b2917852819952365390b9e42 100644 (file)
@@ -433,7 +433,7 @@ static int
 read_console (void)
 {
   char *line;
-  char *prompt;
+  const char *prompt;
 
   err_error_count = err_warning_count = 0;
   err_already_flagged = 0;
@@ -453,15 +453,15 @@ read_console (void)
   switch (getl_prompt)
     {
     case GETL_PRPT_STANDARD:
-      prompt = get_prompt();
+      prompt = get_prompt ();
       break;
 
     case GETL_PRPT_CONTINUATION:
-      prompt = get_cprompt();
+      prompt = get_cprompt ();
       break;
 
     case GETL_PRPT_DATA:
-      prompt = get_dprompt();
+      prompt = get_dprompt ();
       break;
 
     default:
index a026ede65ffb13492f5d79c6790d4705864f7d0f..47db10ea780680f46045cca06a959a2ffdd427d4 100644 (file)
@@ -86,8 +86,6 @@ struct expression *process_if_expr;
 struct transformation *t_trns;
 size_t n_trns, m_trns, f_trns;
 
-short test_mode=0;
-
 int FILTER_before_TEMPORARY;
 
 struct file_handle *default_handle;
index 77d51f6e2d5ee733ca4c3016382fa5098f75dd7b..dd5eb95c250d9f47035fa9ffdaff428ef973a15f 100644 (file)
@@ -23,6 +23,4 @@
 void init_glob (int argc UNUSED, char **argv);
 void done_glob (void);
 
-extern short test_mode;
-
 #endif /* glob.h */
index 66324a2508701b65e63261c209e096285bf8b031..fc6bf9d38c575e061c19cd2af27a51b93de3373d 100644 (file)
@@ -806,7 +806,7 @@ lex_preprocess_line (void)
        dot = 1;
        len--;
       }
-    else if (len == 0 && get_nullline() )
+    else if (len == 0 && get_nulline ())
       dot = 1;
     else
       dot = 0;
index ba620e061314f493f5138a6add50117405345ce4..63e1f810c5d66076a665d169b3f573167f24c5ee 100644 (file)
@@ -208,12 +208,12 @@ find_defn_value (const char *key)
       return d->value;
   if (!strcmp (key, "viewwidth"))
     {
-      sprintf (buf, "%d", get_viewwidth());
+      sprintf (buf, "%d", get_viewwidth ());
       return buf;
     }
   else if (!strcmp (key, "viewlength"))
     {
-      sprintf (buf, "%d", get_viewlength());
+      sprintf (buf, "%d", get_viewlength ());
       return buf;
     }
   else
index 140c79ef27fe10a8f722624efb0573ef211b5f0a..0d2369216469e2fe7cecff802884316f2d468350 100644 (file)
@@ -97,7 +97,7 @@ change_permissions(const char *filename, enum PER per)
   struct stat buf;
   mode_t mode;
 
-  if ( safer_mode() )
+  if (get_safer_mode ())
     {
       msg (SE, _("This command not allowed when the SAFER option is set."));
       return CMD_FAILURE;
index 3bba239035f7120ed1ac264ce42f3f156c1db809..f771d466ecc505a30b94fe2c0b2e01cf09f22dba 100644 (file)
--- a/src/q2c.c
+++ b/src/q2c.c
@@ -557,16 +557,6 @@ struct subcommand
     int translatable;           /* Error message is translatable */
   };
 
-typedef struct aux_subcommand aux_subcommand;
-struct aux_subcommand
-  {
-    aux_subcommand *next;      /* Next in the chain. */
-    char *name;                        /* Subcommand name. */
-    char *value;                /* Subcommand value */
-  };
-
-static aux_subcommand *aux_subcommands ;
-
 /* Name of the command; i.e., DESCRIPTIVES. */
 char *cmdname;
 
@@ -1894,152 +1884,6 @@ dump_parser (int persistent)
 }
 
 
-/* Write out the code to parse aux subcommand SBC. */
-static void
-dump_aux_subcommand (const subcommand *sbc)
-{
-  if (sbc->type == SBC_PLAIN )
-    {
-      specifier *spec;
-       
-      for (spec = sbc->spec; spec; spec = spec->next)
-       {
-         char buf[80];
-         sprintf(buf,"p->%s%s",st_lower(sbc->prefix),spec->varname);
-
-         dump (0, "msg(MM,\"%s is %%s\",",sbc->name);
-         dump (0, "(%s < 1000)?\"not set\":settings[%s - 1000]", buf, buf);
-      
-         dump (0, ");");
-       }
-    }
-  else if (sbc->type == SBC_STRING)
-    {
-      dump (0, "msg(MM,\"%s is \\\"%%s\\\"\",p->s_%s);", sbc->name,st_lower(sbc->name) );
-    }
-  else if (sbc->type == SBC_INT)
-    {
-      dump (1, "{");
-      dump (0, "int i;");
-      dump (1, "for (i = 0; i < MAXLISTS; ++i)");
-      dump (0, "msg(MM,\"%s is %%ld\",p->n_%s[i]);", sbc->name,st_lower(sbc->name) ); 
-      outdent();
-      dump (-1, "}");
-    }
-  else if (sbc->type == SBC_CUSTOM)
-    {
-      dump (0, "aux_%scustom_%s(p);",st_lower(prefix),make_identifier(sbc->name));
-    }
-  else
-    assert(0);
-}
-
-
-
-/* Write out auxilliary parser. */
-static void
-dump_aux_parser (void)
-{
-  int f=0;
-  subcommand *sbc;
-  aux_subcommand *asbc;
-
-  /* Write out English strings for all the identifiers in the symbol table. */
-  {
-    int f, k;
-    symbol *sym;
-    char *buf = NULL;
-
-    /* Note the squirmings necessary to make sure that the last string
-       is not followed by a comma (is it necessary to do that ?? ) */
-    for (sym = symtab, f = k = 0; sym; sym = sym->next)
-      if (!sym->unique && !is_keyword (sym->name))
-       {
-         if (!f)
-           {
-             dump (0, "/* Strings for subcommand specifiers. */");
-             dump (1, "static const char *settings[]=");
-             dump (1, "{");
-             f = 1;
-           }
-
-         if (buf == NULL)
-           buf = xmalloc (1024);
-         else
-           dump (0, buf);
-
-         sprintf (buf, "\"%s\",",sym->name);
-       }
-    if (buf)
-      {
-       buf[strlen (buf) - 1] = 0;
-       dump (0, buf);
-       free (buf);
-      }
-    if (f)
-      {
-       dump (-1, "};");
-       dump (-1, nullstr);
-      }
-  }
-
-  
-  indent = 0;
-
-  dump (0, "static int");
-  dump (0, "aux_parse_%s (struct cmd_%s *p)", make_identifier (cmdname),
-       make_identifier (cmdname));
-  dump (1, "{");
-
-  dump (1, "for (;;)");
-  dump (1, "{");
-
-
-  for (sbc = subcommands; sbc; sbc = sbc->next)
-    {
-      dump (1, "%sif (%s)", f ? "else " : "", make_match (sbc->name));
-      f = 1;
-      dump (1, "{");
-
-      dump_aux_subcommand (sbc);
-
-      dump (-1, "}");
-      outdent ();
-    }
-
-  for (asbc = aux_subcommands ; asbc ; asbc = asbc->next)
-    {
-      dump (1, "%sif (%s)", f ? "else " : "", make_match (asbc->name));
-      f = 1;
-      dump (1, "{");
-      dump(0,"aux_%s();",make_identifier(asbc->value));
-      dump (-1, "}");
-      outdent ();
-    }
-  
-  dump (1, "if (!lex_match ('/'))");
-  dump (0, "break;");
-  dump (-2, "}");
-  outdent ();
-  dump (0, nullstr);
-  dump (1, "if (token != '.')");
-  dump (1, "{");
-  dump (0, "lex_error (_(\"expecting end of command\"));");
-  dump (0, "goto lossage;");
-  dump (-1, "}");
-  dump (0, nullstr);
-  dump (-1, "return 1;");
-  dump (0, nullstr);
-  dump (-1, "lossage:");
-  indent ();
-  dump (0, "free_%s (p);", make_identifier (cmdname));
-  dump (0, "return 0;");
-  dump (-1, "} /* aux_parse_%s (struct cmd_%s *p) */", 
-       make_identifier (cmdname), make_identifier (cmdname));
-  dump (0, nullstr);
-}
-
-
 /* Write the output file header. */
 static void
 dump_header (void)
@@ -2145,8 +1989,6 @@ recognize_directive (void)
   return directive;
 }
   
-static void aux_parse (void);
-
 int
 main (int argc, char *argv[])
 {
@@ -2224,11 +2066,6 @@ main (int argc, char *argv[])
          dump_parser (1);
          dump_free (1); 
        }
-      else if (!strcmp (directive, "aux_functions"))
-       {
-         aux_parse();
-         dump_aux_parser ();
-       }
       else
        error ("unknown directive `%s'", directive);
       indent = 0;
@@ -2239,34 +2076,3 @@ main (int argc, char *argv[])
 
   return EXIT_SUCCESS;
 }
-
-/* Parse an entire auxilliary specification. */
-static void
-aux_parse (void)
-{
-  aux_subcommand *sbc;
-  aux_subcommand *prevsbc = 0 ;
-  get_line();
-  lex_get();
-
-  for (;;)
-    {
-       sbc = xmalloc (sizeof *sbc);
-       sbc->next = prevsbc;
-        sbc->name = xstrdup (tokstr);
-       lex_get();
-       skip_token('=');
-       sbc->value = xstrdup (tokstr);
-       lex_get();
-      if (token == '.')
-       break;
-       skip_token(';');
-       prevsbc = sbc;
-
-    }
-  /* Skip trailing star-slash line. */
-  get_line ();
-  aux_subcommands = sbc;
-}
-
-
index eb0a7331023c9f11605922a00e65b342ec5cceb2..9e045fb7ce7981472695601e6d77be4b10ae595d 100644 (file)
--- a/src/set.q
+++ b/src/set.q
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA. */
 
-/*
-   Categories of SET subcommands:
-
-   data input: BLANKS, DECIMAL, FORMAT, EPOCH.
-   
-   program input: ENDCMD, NULLINE.
-   
-   interaction: CPROMPT, DPROMPT, ERRORBREAK, MXERRS, MXWARNS, PROMPT.
-   
-   program execution: MEXPAND, MITERATE, MNEST, MPRINT,
-   MXLOOPS, SEED, UNDEFINED.
-
-   data output: CCA...CCE, DECIMAL, FORMAT, RESULTS-p.
-
-   output routing: ECHO, ERRORS, INCLUDE, MESSAGES, PRINTBACK, ERRORS,
-   RESULTS-rw.
-
-   output activation: LISTING (on/off), SCREEN, PRINTER.
-
-   output driver options: HEADERS, MORE, PAGER, VIEWLENGTH, VIEWWIDTH,
-   LISTING (filename).
-
-   logging: LOG, JOURNAL.
-
-   system files: COMP/COMPRESSION, SCOMP/SCOMPRESSION.
-
-   security: SAFER.
-*/
-
-/*
-   FIXME
-
-   These subcommands remain to be implemented:
-     ECHO, PRINTBACK, INCLUDE
-     MORE, PAGER, VIEWLENGTH, VIEWWIDTH, HEADERS
-
-   These subcommands are not complete:
-     MESSAGES, ERRORS, RESULTS
-     LISTING/DISK, LOG/JOURNAL
-*/     
-   
 #include <config.h>
 #include "settings.h"
 #include "error.h"
@@ -67,6 +26,7 @@
 #include <time.h>
 #include "alloc.h"
 #include "command.h"
+#include "dictionary.h"
 #include "lexer.h"
 #include "error.h"
 #include "magic.h"
@@ -75,8 +35,8 @@
 #include "var.h"
 #include "format.h"
 #include "copyleft.h"
+#include "var.h"
 
-#include "signal.h"
 
 #if HAVE_LIBTERMCAP
 #if HAVE_TERMCAP_H
@@ -90,49 +50,8 @@ int tgetnum (const char *);
 #include "gettext.h"
 #define _(msgid) gettext (msgid)
 
-static int set_errors;
-static int set_messages;
-static int set_results;
-
-static double set_blanks=SYSMIS;
-
-static int set_epoch = -1;
-
-static struct fmt_spec set_format={FMT_F,8,2};
-
-static struct set_cust_currency set_cc[5];
-  
-static char *set_journal;
-static int set_journaling;
-
-static int set_listing=1;
-
-#if !USE_INTERNAL_PAGER
-static char *set_pager=0;
-#endif /* !USE_INTERNAL_PAGER */
-
-static gsl_rng *rng;
-
-static int long_view=0;
-int set_testing_mode=0;
-static int set_viewlength;
-static int set_viewwidth;
-
-void aux_show_warranty(void);
-void aux_show_copying(void);
-
-static const char *route_to_string(int routing);
-static void set_routing (int q, int *setting);
-
-static int set_ccx (const char *cc_string, struct set_cust_currency * cc,
-                   int cc_name);
-static void set_rng (unsigned long);
-static unsigned long random_seed (void);
-
 /* (specification)
    "SET" (stc_):
-     automenu=automenu:on/off;
-     beep=beep:on/off;
      blanks=custom;
      block=string "x==1" "one character long";
      boxstring=string "x==3 || x==11" "3 or 11 characters long";
@@ -142,7 +61,6 @@ static unsigned long random_seed (void);
      ccc=string;
      ccd=string;
      cce=string;
-     color=custom;
      compression=compress:on/off;
      cpi=integer "x>0" "%s must be greater than 0";
      cprompt=string;
@@ -150,21 +68,18 @@ static unsigned long random_seed (void);
      disk=custom;
      dprompt=string;
      echo=echo:on/off;
-     eject=eject:on/off;
      endcmd=string "x==1" "one character long";
      epoch=custom;
      errorbreak=errbrk:on/off;
      errors=errors:on/off/terminal/listing/both/none;
      format=custom;
      headers=headers:no/yes/blank;
-     helpwindows=helpwin:on/off;
      highres=hires:on/off;
      histogram=string "x==1" "one character long";
      include=inc:on/off;
      journal=custom;
      length=custom;
      listing=custom;
-     log=custom;
      lowres=lores:auto/on/off;
      lpi=integer "x>0" "%s must be greater than 0";
      menus=menus:standard/extended;
@@ -172,33 +87,23 @@ static unsigned long random_seed (void);
      mexpand=mexp:on/off;
      miterate=integer "x>0" "%s must be greater than 0";
      mnest=integer "x>0" "%s must be greater than 0";
-     more=more:on/off;
      mprint=mprint:on/off;
      mxerrs=integer "x >= 1" "%s must be at least 1";
      mxloops=integer "x >=1" "%s must be at least 1";
      mxmemory=integer;
      mxwarns=integer;
      nulline=null:on/off;
-     pager=custom;
      printback=prtbck:on/off;
-     printer=prtr:on/off;
      prompt=string;
-     ptranslate=ptrans:on/off;
-     rcolor=custom;
-     results=custom;
-     runreview=runrev:auto/manual;
+     results=res:on/off/terminal/listing/both/none;
      safer=safe:on;
      scompression=scompress:on/off;
-     screen=scrn:on/off;
      scripttab=string "x==1" "one character long";
      seed=custom;
      tb1=string "x==3 || x==11" "3 or 11 characters long";
      tbfonts=string;
      undefined=undef:warn/nowarn;
-     viewlength=custom;
-     viewwidth=custom;
      width=custom;
-     workdev=custom;
      workspace=integer "x>=1024" "%s must be at least 1 MB";
      xsort=xsort:yes/no.
 */
@@ -207,439 +112,191 @@ static unsigned long random_seed (void);
 
 /* (_functions) */
 
-static int
-aux_stc_custom_blanks(struct cmd_set *cmd UNUSED)
-{
-  if ( set_blanks == SYSMIS ) 
-    msg(MM, "SYSMIS");
-  else
-    msg(MM, "%g", set_blanks);
-  return 0;
-}
-
-
-static int
-aux_stc_custom_color(struct cmd_set *cmd UNUSED)
-{
-  msg (MW, _("%s is obsolete."),"COLOR");
-  return 0;
-}
-
-static int
-aux_stc_custom_listing(struct cmd_set *cmd UNUSED)
-{
-  if ( set_listing ) 
-    msg(MM, _("LISTING is ON"));
-  else
-    msg(MM, _("LISTING is OFF"));
-
-  return 0;
-}
-
-static int
-aux_stc_custom_disk(struct cmd_set *cmd UNUSED)
-{
-  return aux_stc_custom_listing(cmd);
-}
-
-static int
-aux_stc_custom_epoch(struct cmd_set *cmd UNUSED) 
-{
-  msg (MM, _("EPOCH is %d"), get_epoch ());
-  return 0;
-}
-
-static int
-aux_stc_custom_format(struct cmd_set *cmd UNUSED)
-{
-  msg(MM, fmt_to_string(&set_format));
-  return 0;
-}
-
-
-
-static int
-aux_stc_custom_journal(struct cmd_set *cmd UNUSED)
-{
-  if (set_journaling) 
-    msg(MM, set_journal);
-  else
-    msg(MM, _("Journalling is off") );
-       
-  return 0;
-}
-
-static int
-aux_stc_custom_length(struct cmd_set *cmd UNUSED)
-{
-  msg(MM, "%d", set_viewlength);
-  return 0;
-}
-
-static int
-aux_stc_custom_log(struct cmd_set *cmd )
-{
-  return aux_stc_custom_journal (cmd);
-}
-
-static int
-aux_stc_custom_pager(struct cmd_set *cmd UNUSED)
-{
-#if !USE_INTERNAL_PAGER 
-  if ( set_pager ) 
-    msg(MM, set_pager);
-  else
-    msg(MM, "No pager");
-#else /* USE_INTERNAL_PAGER */
-  msg (MM, "Internal pager.");
-#endif /* USE_INTERNAL_PAGER */
-
-  return 0;
-}
-
-static int
-aux_stc_custom_rcolor(struct cmd_set *cmd UNUSED)
-{
-  msg (SW, _("%s is obsolete."),"RCOLOR");
-  return 0;
-}
-
-static int
-aux_stc_custom_results(struct cmd_set *cmd UNUSED)
-{
-  
-  msg(MM, route_to_string(set_results) );
-
-  return 0;
-}
-
-static int
-aux_stc_custom_seed(struct cmd_set *cmd UNUSED)
-{
-  return 0;
-}
-
-static int
-aux_stc_custom_viewlength(struct cmd_set *cmd UNUSED)
-{
-  msg(MM, "%d", set_viewlength);
-  return 0;
-}
-
-static int
-aux_stc_custom_viewwidth(struct cmd_set *cmd UNUSED)
-{
-  msg(MM, "%d", set_viewwidth);
-  return 0;
-}
-
-static int
-aux_stc_custom_width(struct cmd_set *cmd UNUSED)
-{
-  msg(MM, "%d", set_viewwidth);
-  return 0;
-}
-
-static int
-aux_stc_custom_workdev(struct cmd_set *cmd UNUSED)
-{
-  msg (SW, _("%s is obsolete."),"WORKDEV");
-  return 0;
-}
-
-
-
-/* (aux_functions) 
-     warranty=show_warranty;
-     copying=show_copying.
-*/
-
-
-static struct cmd_set cmd;
-
-int
-cmd_show (void)
-{
-  lex_match_id ("SHOW");
-
-  if (!aux_parse_set (&cmd))
-    return CMD_FAILURE;
-
-  return CMD_SUCCESS;
-}
+static bool do_cc (const char *cc_string, int idx);
 
 int
 cmd_set (void)
 {
+  struct cmd_set cmd;
+  bool ok = true;
 
   if (!parse_set (&cmd))
     return CMD_FAILURE;
 
   if (cmd.sbc_cca)
-    set_ccx (cmd.s_cca, &set_cc[0], 'A');
+    ok = ok && do_cc (cmd.s_cca, 0);
   if (cmd.sbc_ccb)
-    set_ccx (cmd.s_ccb, &set_cc[1], 'B');
+    ok = ok && do_cc (cmd.s_ccb, 1);
   if (cmd.sbc_ccc)
-    set_ccx (cmd.s_ccc, &set_cc[2], 'C');
+    ok = ok && do_cc (cmd.s_ccc, 2);
   if (cmd.sbc_ccd)
-    set_ccx (cmd.s_ccd, &set_cc[3], 'D');
+    ok = ok && do_cc (cmd.s_ccd, 3);
   if (cmd.sbc_cce)
-    set_ccx (cmd.s_cce, &set_cc[4], 'E');
-
-  if (cmd.sbc_errors)
-    set_routing (cmd.errors, &set_errors);
-  if (cmd.sbc_messages)
-    set_routing (cmd.messages, &set_messages);
-
-  /* PC+ compatible syntax. */
-  if (cmd.sbc_screen)
-    outp_enable_device (cmd.scrn == STC_OFF ? 0 : 1, OUTP_DEV_SCREEN);
-  if (cmd.sbc_printer)
-    outp_enable_device (cmd.prtr == STC_OFF ? 0 : 1, OUTP_DEV_PRINTER);
-
-  if (cmd.sbc_automenu )
-    msg (SW, _("%s is obsolete."),"AUTOMENU");
-  if (cmd.sbc_beep )
-    msg (SW, _("%s is obsolete."),"BEEP");
+    ok = ok && do_cc (cmd.s_cce, 4);
+
+  if (cmd.sbc_prompt)
+    set_prompt (cmd.s_prompt);
+  if (cmd.sbc_cprompt)
+    set_prompt (cmd.s_cprompt);
+  if (cmd.sbc_dprompt)
+    set_prompt (cmd.s_dprompt);
+
+  if (cmd.sbc_decimal)
+    set_decimal (cmd.dec == STC_DOT ? '.' : ',');
+  if (cmd.sbc_echo)
+    set_echo (cmd.echo == STC_ON);
+  if (cmd.sbc_endcmd)
+    set_endcmd (cmd.s_endcmd[0]);
+  if (cmd.sbc_errorbreak)
+    set_errorbreak (cmd.errbrk == STC_ON);
+  if (cmd.sbc_include)
+    set_include (cmd.inc == STC_ON);
+  if (cmd.sbc_mxerrs)
+    set_mxerrs (cmd.n_mxerrs[0]);
+  if (cmd.sbc_mxwarns)
+    set_mxwarns (cmd.n_mxwarns[0]);
+  if (cmd.sbc_nulline)
+    set_nulline (cmd.null == STC_ON);
+  if (cmd.sbc_safer)
+    set_safer_mode ();
+  if (cmd.sbc_scompression)
+    set_scompression (cmd.scompress == STC_ON);
+  if (cmd.sbc_undefined)
+    set_undefined (cmd.undef == STC_WARN);
+  if (cmd.sbc_workspace)
+    set_workspace (cmd.n_workspace[0] * 1024L);
+
   if (cmd.sbc_block)
     msg (SW, _("%s is obsolete."),"BLOCK");
   if (cmd.sbc_boxstring)
     msg (SW, _("%s is obsolete."),"BOXSTRING");
-  if (cmd.sbc_eject )
-    msg (SW, _("%s is obsolete."),"EJECT");
-  if (cmd.sbc_helpwindows )
-    msg (SW, _("%s is obsolete."),"HELPWINDOWS");
   if (cmd.sbc_histogram)
     msg (MW, _("%s is obsolete."),"HISTOGRAM");
   if (cmd.sbc_menus )
     msg (MW, _("%s is obsolete."),"MENUS");
-  if (cmd.sbc_ptranslate )
-    msg (SW, _("%s is obsolete."),"PTRANSLATE");
-  if (cmd.sbc_runreview )
-    msg (SW, _("%s is obsolete."),"RUNREVIEW");
   if (cmd.sbc_xsort )
     msg (SW, _("%s is obsolete."),"XSORT");
   if (cmd.sbc_mxmemory )
     msg (SE, _("%s is obsolete."),"MXMEMORY");
   if (cmd.sbc_scripttab)
     msg (SE, _("%s is obsolete."),"SCRIPTTAB");
-
   if (cmd.sbc_tbfonts)
-    msg (SW, _("%s is not yet implemented."),"TBFONTS");
+    msg (SW, _("%s is obsolete."),"TBFONTS");
   if (cmd.sbc_tb1 && cmd.s_tb1)
-    msg (SW, _("%s is not yet implemented."),"TB1");
+    msg (SW, _("%s is obsolete."),"TB1");
 
-  /* Windows compatible syntax. */
   if (cmd.sbc_case)
-    msg (SW, _("CASE is not implemented and probably won't be.  "
-       "If you care, complain about it."));
+    msg (SW, _("%s is not implemented."), "CASE");
 
   if (cmd.sbc_compression)
-    {
-      msg (MW, _("Active file compression is not yet implemented "
-                "(and probably won't be)."));
-    }
+    msg (MW, _("Active file compression is not implemented."));
 
   return CMD_SUCCESS;
 }
 
-/* Sets custom currency specifier CC having name CC_NAME ('A' through
-   'E') to correspond to the settings in CC_STRING. */
-static int
-set_ccx (const char *cc_string, struct set_cust_currency * cc, int cc_name)
+/* Find the grouping characters in CC_STRING and set CC's
+   grouping and decimal members appropriately.  Returns true if
+   successful, false otherwise. */
+static bool
+find_cc_separators (const char *cc_string, struct custom_currency *cc)
 {
-  if (strlen (cc_string) > 16)
-    {
-      msg (SE, _("CC%c: Length of custom currency string `%s' (%d) "
-                "exceeds maximum length of 16."),
-          cc_name, cc_string, strlen (cc_string));
-      return 0;
-    }
-
-  /* Determine separators. */
-  {
-    const char *sp;
-    int n_commas, n_periods;
+  const char *sp;
+  int comma_cnt, dot_cnt;
   
-    /* Count the number of commas and periods.  There must be exactly
-       three of one or the other. */
-    n_commas = n_periods = 0;
-    for (sp = cc_string; *sp; sp++)
-      if (*sp == ',')
-       n_commas++;
-      else if (*sp == '.')
-       n_periods++;
+  /* Count commas and periods.  There must be exactly three of
+     one or the other, except that an apostrophe acts escapes a
+     following comma or period. */
+  comma_cnt = dot_cnt = 0;
+  for (sp = cc_string; *sp; sp++)
+    if (*sp == ',')
+      comma_cnt++;
+    else if (*sp == '.')
+      dot_cnt++;
+    else if (*sp == '\'' && (sp[1] == '.' || sp[1] == ',' || sp[1] == '\''))
+      sp++;
   
-    if (!((n_commas == 3) ^ (n_periods == 3)))
-      {
-       msg (SE, _("CC%c: Custom currency string `%s' does not contain "
-                  "exactly three periods or commas (not both)."),
-            cc_name, cc_string);
-       return 0;
-      }
-    else if (n_commas == 3)
-      {
-       cc->decimal = '.';
-       cc->grouping = ',';
-      }
-    else
-      {
-       cc->decimal = ',';
-       cc->grouping = '.';
-      }
-  }
-  
-  /* Copy cc_string to cc, changing separators to nulls. */
-  {
-    char *cp;
-    
-    strcpy (cc->buf, cc_string);
-    cp = cc->neg_prefix = cc->buf;
-
-    while (*cp++ != cc->grouping)
-      ;
-    cp[-1] = '\0';
-    cc->prefix = cp;
-
-    while (*cp++ != cc->grouping)
-      ;
-    cp[-1] = '\0';
-    cc->suffix = cp;
-
-    while (*cp++ != cc->grouping)
-      ;
-    cp[-1] = '\0';
-    cc->neg_suffix = cp;
-  }
-  
-  return 1;
-}
+  if ((comma_cnt == 3) == (dot_cnt == 3))
+    return false;
 
-
-const char *
-route_to_string(int routing)
-{
-  static char s[255];
-  
-  s[0]='\0';
-
-  if ( routing == 0 )
+  if (comma_cnt == 3)
     {
-      strcpy(s, _("None"));
-      return s;
+      cc->decimal = '.';
+      cc->grouping = ',';
     }
-
-  if (routing & SET_ROUTE_DISABLE ) 
+  else
     {
-    strcpy(s, _("Disabled") );
-    return s;
+      cc->decimal = ',';
+      cc->grouping = '.';
     }
+  return true;
+}
 
-  if (routing & SET_ROUTE_SCREEN)
-    strcat(s, _("Screen") );
+/* Extracts a token from IN into TOKEn.  Tokens are delimited by
+   GROUPING.  The token is truncated to at most CC_WIDTH
+   characters (including null terminator).  Returns the first
+   character following the token. */
+static const char *
+extract_cc_token (const char *in, int grouping, char token[CC_WIDTH]) 
+{
+  char *out = token;
   
-  if (routing & SET_ROUTE_LISTING)
+  for (; *in != '\0' && *in != grouping; in++) 
     {
-      if(s[0] != '\0') 
-       strcat(s,", ");
-       
-      strcat(s, _("Listing") );
+      if (*in == '\'' && in[1] == grouping)
+        in++;
+      if (out < &token[CC_WIDTH - 1])
+        *out++ = *in;
     }
+  *out = '\0';
 
-  if (routing & SET_ROUTE_OTHER)
-    {
-      if(s[0] != '\0') 
-       strcat(s,", ");
-      strcat(s, _("Other") );
-    }
-    
-  return s;
-  
-    
+  if (*in == grouping)
+    in++;
+  return in;
 }
 
-/* Sets *SETTING, which is a combination of SET_ROUTE_* bits that
-   indicates what to do with some sort of output, to the value
-   indicated by Q, which is a value provided by the input parser. */
-static void
-set_routing (int q, int *setting)
+/* Sets custom currency specifier CC having name CC_NAME ('A' through
+   'E') to correspond to the settings in CC_STRING. */
+static bool
+do_cc (const char *cc_string, int idx)
 {
-  switch (q)
+  struct custom_currency cc;
+  
+  /* Determine separators. */
+  if (!find_cc_separators (cc_string, &cc)) 
     {
-    case STC_OFF:
-      *setting |= SET_ROUTE_DISABLE;
-      break;
-    case STC_ON:
-      *setting &= ~SET_ROUTE_DISABLE;
-      break;
-    case STC_TERMINAL:
-      *setting &= ~(SET_ROUTE_LISTING | SET_ROUTE_OTHER);
-      *setting |= SET_ROUTE_SCREEN;
-      break;
-    case STC_LISTING:
-      *setting &= ~SET_ROUTE_SCREEN;
-      *setting |= SET_ROUTE_LISTING | SET_ROUTE_OTHER;
-      break;
-    case STC_BOTH:
-      *setting |= SET_ROUTE_SCREEN | SET_ROUTE_LISTING | SET_ROUTE_OTHER;
-      break;
-    case STC_NONE:
-      *setting &= ~(SET_ROUTE_SCREEN | SET_ROUTE_LISTING | SET_ROUTE_OTHER);
-      break;
-    default:
-      assert (0);
+      msg (SE, _("CC%c: Custom currency string `%s' does not contain "
+                 "exactly three periods or commas (not both)."),
+           "ABCDE"[idx], cc_string);
+      return false;
     }
-}
+  
+  cc_string = extract_cc_token (cc_string, cc.grouping, cc.neg_prefix);
+  cc_string = extract_cc_token (cc_string, cc.grouping, cc.prefix);
+  cc_string = extract_cc_token (cc_string, cc.grouping, cc.suffix);
+  cc_string = extract_cc_token (cc_string, cc.grouping, cc.neg_suffix);
 
-static int
-stc_custom_pager (struct cmd_set *cmd UNUSED)
-{
-  lex_match ('=');
-#if !USE_INTERNAL_PAGER
-  if (lex_match_id ("OFF"))
-    {
-      if (set_pager)
-       free (set_pager);
-      set_pager = NULL;
-    }
-  else
-    {
-      if (!lex_force_string ())
-       return 0;
-      if (set_pager)
-       free (set_pager);
-      set_pager = xstrdup (ds_c_str (&tokstr));
-      lex_get ();
-    }
-  return 1;
-#else /* USE_INTERNAL_PAGER */
-  if (lex_match_id ("OFF"))
-    return 1;
-  msg (SW, "External pagers not supported.");
-  return 0;
-#endif /* USE_INTERNAL_PAGER */
+  set_cc (idx, &cc);
+  
+  return true;
 }
 
 /* Parses the BLANKS subcommand, which controls the value that
    completely blank fields in numeric data imply.  X, Wnd: Syntax is
-   SYSMIS or a numeric value; PC+: Syntax is '.', which is equivalent
-   to SYSMIS, or a numeric value. */
+   SYSMIS or a numeric value. */
 static int
 stc_custom_blanks (struct cmd_set *cmd UNUSED)
 {
   lex_match ('=');
-  if ((token == T_ID && lex_id_match ("SYSMIS", tokid))
-      || (token == T_STRING && !strcmp (tokid, ".")))
+  if ((token == T_ID && lex_id_match ("SYSMIS", tokid)))
     {
       lex_get ();
-      set_blanks = SYSMIS;
+      set_blanks (SYSMIS);
     }
   else
     {
       if (!lex_force_num ())
        return 0;
-      set_blanks = tokval;
+      set_blanks (lex_number ());
       lex_get ();
     }
   return 1;
@@ -652,7 +309,7 @@ stc_custom_epoch (struct cmd_set *cmd UNUSED)
 {
   lex_match ('=');
   if (lex_match_id ("AUTOMATIC"))
-    set_epoch = -1;
+    set_epoch (-1);
   else if (lex_is_integer ()) 
     {
       int new_epoch = lex_integer ();
@@ -662,7 +319,7 @@ stc_custom_epoch (struct cmd_set *cmd UNUSED)
           msg (SE, _("EPOCH must be 1500 or later."));
           return 0;
         }
-      set_epoch = new_epoch;
+      set_epoch (new_epoch);
     }
   else 
     {
@@ -694,64 +351,23 @@ stc_custom_length (struct cmd_set *cmd UNUSED)
       lex_get ();
     }
 
-  if ( page_length != -1 
-    set_viewlength = page_length;
+  if (page_length != -1
+    set_viewlength (page_length);
 
   return 1;
 }
 
-static int
-stc_custom_results (struct cmd_set *cmd UNUSED)
-{
-  struct tuple
-    {  
-      const char *s;   
-      int v;
-    };
-
-  static struct tuple tab[] =
-    {
-      {"ON", STC_ON},
-      {"OFF", STC_OFF},
-      {"TERMINAL", STC_TERMINAL},
-      {"LISTING", STC_LISTING},
-      {"BOTH", STC_BOTH},
-      {"NONE", STC_NONE},
-      {NULL, 0},
-    };
-
-  struct tuple *t;
-
-  lex_match ('=');
-
-  if (token != T_ID)
-    {
-      msg (SE, _("Missing identifier in RESULTS subcommand."));
-      return 0;
-    }
-  
-  for (t = tab; t->s; t++)
-    if (lex_id_match (t->s, tokid))
-      {
-       lex_get ();
-       set_routing (t->v, &set_results);
-       return 1;
-      }
-  msg (SE, _("Unrecognized identifier in RESULTS subcommand."));
-  return 0;
-}
-
 static int
 stc_custom_seed (struct cmd_set *cmd UNUSED)
 {
   lex_match ('=');
   if (lex_match_id ("RANDOM"))
-    set_rng (random_seed ());
+    set_rng (time (0));
   else
     {
       if (!lex_force_num ())
        return 0;
-      set_rng (tokval);
+      set_rng (lex_number ());
       lex_get ();
     }
 
@@ -761,27 +377,24 @@ stc_custom_seed (struct cmd_set *cmd UNUSED)
 static int
 stc_custom_width (struct cmd_set *cmd UNUSED)
 {
-  int page_width;
-
   lex_match ('=');
   if (lex_match_id ("NARROW"))
-    page_width = 79;
+    set_viewwidth (79);
   else if (lex_match_id ("WIDE"))
-    page_width = 131;
+    set_viewwidth (131);
   else
     {
       if (!lex_force_int ())
        return 0;
-      if (lex_integer () < 1)
+      if (lex_integer () < 40)
        {
-         msg (SE, _("WIDTH must be at least 1."));
+         msg (SE, _("WIDTH must be at least 40."));
          return 0;
        }
-      page_width = lex_integer ();
+      set_viewwidth (lex_integer ());
       lex_get ();
     }
 
-  set_viewwidth = page_width;
   return 1;
 }
 
@@ -803,7 +416,7 @@ stc_custom_format (struct cmd_set *cmd UNUSED)
       return 0;
     }
 
-  set_format = fmt;
+  set_format (&fmt);
   return 1;
 }
 
@@ -811,67 +424,15 @@ static int
 stc_custom_journal (struct cmd_set *cmd UNUSED)
 {
   lex_match ('=');
-  if (lex_match_id ("ON"))
-    set_journaling = 1;
-  else if (lex_match_id ("OFF"))
-    set_journaling = 0;
-  if (token == T_STRING)
+  if (!lex_match_id ("ON") && !lex_match_id ("OFF")) 
     {
-      set_journal = xstrdup (ds_c_str (&tokstr));
-      lex_get ();
-    }
-  return 1;
-}
-
-/* Parses COLOR subcommand.  PC+: either ON or OFF or two or three
-   comma-delimited numbers inside parentheses. */
-static int
-stc_custom_color (struct cmd_set *cmd UNUSED)
-{
-  msg (MW, _("%s is obsolete."),"COLOR");
-
-  lex_match ('=');
-  if (!lex_match_id ("ON") && !lex_match_id ("YES") && !lex_match_id ("OFF") && !lex_match_id ("NO"))
-    {
-      if (!lex_force_match ('('))
-       return 0;
-      if (!lex_match ('*'))
-       {
-         if (!lex_force_int ())
-           return 0;
-         if (lex_integer () < 0 || lex_integer () > 15)
-           {
-             msg (SE, _("Text color must be in range 0-15."));
-             return 0;
-           }
-         lex_get ();
-       }
-      if (!lex_force_match (','))
-       return 0;
-      if (!lex_match ('*'))
-       {
-         if (!lex_force_int ())
-           return 0;
-         if (lex_integer () < 0 || lex_integer () > 7)
-           {
-             msg (SE, _("Background color must be in range 0-7."));
-             return 0;
-           }
-         lex_get ();
-       }
-      if (lex_match (',') && !lex_match ('*'))
-       {
-         if (!lex_force_int ())
-           return 0;
-         if (lex_integer () < 0 || lex_integer () > 7)
-           {
-             msg (SE, _("Border color must be in range 0-7."));
-             return 0;
-           }
-         lex_get ();
-       }
-      if (!lex_force_match (')'))
-       return 0;
+      if (token == T_STRING)
+        lex_get ();
+      else
+        {
+          lex_error (NULL);
+          return 0;
+        }
     }
   return 1;
 }
@@ -879,17 +440,19 @@ stc_custom_color (struct cmd_set *cmd UNUSED)
 static int
 stc_custom_listing (struct cmd_set *cmd UNUSED)
 {
+  bool listing;
+
   lex_match ('=');
   if (lex_match_id ("ON") || lex_match_id ("YES"))
-    set_listing = 1;
+    listing = true;
   else if (lex_match_id ("OFF") || lex_match_id ("NO"))
-    set_listing = 0;
+    listing = false;
   else
     {
       /* FIXME */
       return 0;
     }
-  outp_enable_device (set_listing, OUTP_DEV_LISTING);
+  outp_enable_device (listing, OUTP_DEV_LISTING);
 
   return 1;
 }
@@ -899,572 +462,258 @@ stc_custom_disk (struct cmd_set *cmd UNUSED)
 {
   return stc_custom_listing (cmd);
 }
-
-static int
-stc_custom_log (struct cmd_set *cmd UNUSED)
-{ 
-  return stc_custom_journal (cmd);
-}
-
-static int
-stc_custom_rcolor (struct cmd_set *cmd UNUSED)
-{
-  msg (SW, _("%s is obsolete."),"RCOLOR");
-
-  lex_match ('=');
-  if (!lex_force_match ('('))
-    return 0;
-
-  if (!lex_match ('*'))
-    {
-      if (!lex_force_int ())
-       return 0;
-      if (lex_integer () < 0 || lex_integer () > 6)
-       {
-         msg (SE, _("Lower window color must be between 0 and 6."));
-         return 0;
-       }
-      lex_get ();
-    }
-  if (!lex_force_match (','))
-    return 0;
-
-  if (!lex_match ('*'))
-    {
-      if (!lex_force_int ())
-       return 0;
-      if (lex_integer () < 0 || lex_integer () > 6)
-       {
-         msg (SE, _("Upper window color must be between 0 and 6."));
-         return 0;
-       }
-      lex_get ();
-    }
-
-  if (lex_match (',') && !lex_match ('*'))
-    {
-      if (!lex_force_int ())
-       return 0;
-      if (lex_integer () < 0 || lex_integer () > 6)
-       {
-         msg (SE, _("Frame color must be between 0 and 6."));
-         return 0;
-       }
-      lex_get ();
-    }
-  return 1;
-}
-
-static int
-stc_custom_viewwidth (struct cmd_set *cmd UNUSED)
-{
-  lex_match ('=');
-
-  if ( !lex_force_int() ) 
-    return 0;
-
-  set_viewwidth = lex_integer();
-  lex_get();
-  
-  return 1;
-}
-
-static int
-stc_custom_viewlength (struct cmd_set *cmd UNUSED)
+\f
+static void
+show_blanks (void) 
 {
-  if (lex_match_id ("MINIMUM"))
-    set_viewlength = 25;
-  else if (lex_match_id ("MEDIAN"))
-    set_viewlength = 43;       /* This is not correct for VGA displays. */
-  else if (lex_match_id ("MAXIMUM"))
-    set_viewlength = 43;
+  if (get_blanks () == SYSMIS)
+    msg (MM, _("BLANKS is SYSMIS."));
   else
-    {
-      if (!lex_force_int ())
-       return 0;
-#ifdef __MSDOS__
-      if (lex_integer () >= (43 + 25) / 2)
-       set_viewlength = 43;
-      else
-       set_viewlength = 25;
-#else /* not dos */
-      set_viewlength = lex_integer ();
-#endif /* not dos */
-      lex_get ();
-    }
-
-#ifdef __MSDOS__
-  msg (SW, _("%s is not yet implemented."),"VIEWLENGTH");
-#endif /* dos */
-  return 1;
-}
-
-static int
-stc_custom_workdev (struct cmd_set *cmd UNUSED)
-{
-  char c[2];
-
-  msg (SW, _("%s is obsolete."),"WORKDEV");
-
-  c[1] = 0;
-  for (*c = 'A'; *c <= 'Z'; (*c)++)
-    if (token == T_ID && lex_id_match (c, tokid))
-      {
-       lex_get ();
-       return 1;
-      }
-  msg (SE, _("Drive letter expected in WORKDEV subcommand."));
-  return 0;
-}
-
-
-
-static void 
-set_viewport(int sig_num UNUSED)
-{
-#if HAVE_LIBTERMCAP
-  static char term_buffer[16384];
-#endif
-
-  set_viewwidth = -1;
-  set_viewlength = -1;
-
-#if __DJGPP__ || __BORLANDC__
-  {
-    struct text_info ti;
-
-    gettextinfo (&ti);
-    set_viewlength = max (ti.screenheight, 25);
-    set_viewwidth = max (ti.screenwidth, 79);
-  }
-#elif HAVE_LIBTERMCAP
-  {
-    char *termtype;
-    int success;
-
-    /* This code stolen from termcap.info, though modified. */
-    termtype = getenv ("TERM");
-    if (!termtype)
-      msg (FE, _("Specify a terminal type with the TERM environment variable."));
-
-    success = tgetent (term_buffer, termtype);
-    if (success <= 0)
-      {
-       if (success < 0)
-         msg (IE, _("Could not access the termcap data base."));
-       else
-         msg (IE, _("Terminal type `%s' is not defined."), termtype);
-      }
-    else
-      {
-       /* NOTE: Do not rely upon tgetnum returning -1 if the value is 
-          not available. It's supposed to do it, but not all platforms 
-          do (eg Cygwin) .
-       */
-        if ( -1 != tgetnum("li")) 
-         set_viewlength = tgetnum ("li");
-
-        if ( -1 != tgetnum("co")) 
-         set_viewwidth = tgetnum ("co") - 1;
-      }
-  }
-#endif /* HAVE_LIBTERMCAP */
-
-  /* Try the environment variables */
-  if ( -1 ==  set_viewwidth ) 
-    { 
-      char *s = getenv("COLUMNS");
-      if ( s )  set_viewwidth = atoi(s);
-    }
-
-  if ( -1 ==  set_viewwidth ) 
-    {
-      char *s = getenv("LINES");
-      if ( s )  set_viewlength = atoi(s);
-    }
-
-
-  /* Last resort.  Use hard coded values */
-  if ( 0  >  set_viewwidth ) set_viewwidth = 79;
-  if ( 0  >  set_viewlength ) set_viewlength = 24;
-
-}
-
-/* Public functions */
-
-void
-done_settings(void)
-{
-  if ( rng ) 
-    gsl_rng_free (rng);
-  free (set_pager);
-  free (set_journal);
-
-  free (cmd.s_endcmd);
-  free (cmd.s_prompt);
-  free (cmd.s_cprompt);
-  free (cmd.s_dprompt);
-}
-
-
-
-void
-init_settings(void)
-{
-  cmd.s_dprompt = xstrdup (_("data> "));
-  cmd.s_cprompt = xstrdup ("    > ");  
-  cmd.s_prompt = xstrdup ("PSPP> ");
-  cmd.s_endcmd = xstrdup (".");
-
-  assert(cmd.safe == 0 );
-  cmd.safe = STC_OFF;
-
-  cmd.dec = STC_DOT;
-  cmd.n_cpi[0] = 6;
-  cmd.n_lpi[0] = 10;
-  cmd.echo = STC_OFF;
-  cmd.more = STC_ON;
-  cmd.headers = STC_YES;
-  cmd.errbrk = STC_OFF;
-
-  cmd.scompress = STC_OFF;
-  cmd.undef = STC_WARN;
-  cmd.mprint = STC_ON ;
-  cmd.prtbck = STC_ON ;
-  cmd.null = STC_ON ;
-  cmd.inc = STC_ON ;
-
-  set_journal = xstrdup ("pspp.jnl");
-  set_journaling = 1;
-
-  cmd.n_mxwarns[0] = 100;
-  cmd.n_mxerrs[0] = 100;
-  cmd.n_mxloops[0] = 1;
-  cmd.n_workspace[0] = 4L * 1024 * 1024;
-
-
-#if !USE_INTERNAL_PAGER
-  {
-    const char *pager = getenv ("STAT_PAGER");
-
-    if (!pager) 
-      {
-       const char *p = getenv ("PAGER");
-       
-       if ( p != NULL ) 
-         set_pager = xstrdup (p);
-       else
-         set_pager = 0;
-      }
-    
-
-    if (pager)  
-      set_pager = xstrdup (pager);
-#if DEFAULT_PAGER
-    else
-      set_pager = xstrdup (DEFAULT_PAGER);
-#endif /* DEFAULT_PAGER */
-  }
-#endif /* !USE_INTERNAL_PAGER */
-
-
-  {
-    int i;
-    
-    for (i = 0; i < 5; i++)
-      {
-       struct set_cust_currency *cc = &set_cc[i];
-       strcpy (cc->buf, "-");
-       cc->neg_prefix = cc->buf;
-       cc->prefix = &cc->buf[1];
-       cc->suffix = &cc->buf[1];
-       cc->neg_suffix = &cc->buf[1];
-       cc->decimal = '.';
-       cc->grouping = ',';
-      }
-  }
-
-  if ( ! long_view )
-    {
-      set_viewport (0);
-      signal (SIGWINCH, set_viewport);
-    }
-
-}
-
-void
-force_long_view(void)
-{
-  long_view = 1;
-  set_viewwidth=9999;
-}
-
-int 
-safer_mode(void)
-{
-  return !(cmd.safe != STC_ON) ;
-}
+    msg (MM, _("BLANKS is %g."), get_blanks ());
 
-
-/* Set safer mode */
-void
-make_safe(void)
-{
-  cmd.safe = STC_ON;
-}
-
-
-char 
-get_decimal(void)
-{
-  return (cmd.dec == STC_DOT ? '.' : ',');
 }
 
-int
-get_epoch (void
+static char *
+format_cc (const char *in, char grouping, char *out
 {
-  if (set_epoch < 0
+  while (*in != '\0'
     {
-      time_t t = time (0);
-      struct tm *tm = localtime (&t);
-      if (tm != NULL) 
-        set_epoch = (tm->tm_year + 1900) - 69;
-      else
-        set_epoch = 2000 - 69;
+      if (*in == grouping || *in == '\'')
+        *out++ = '\'';
+      *out++ = *in++;
     }
-
-  return set_epoch;
+  return out;
 }
 
-char
-get_grouping(void)
-{
-  return (cmd.dec == STC_DOT ? ',' : '.');
-}
-
-char * 
-get_prompt(void)
-{
-  return cmd.s_prompt;
-}
-
-char * 
-get_dprompt(void)
-{
-  return cmd.s_dprompt;
-}
-
-char * 
-get_cprompt(void)
-{
-  return cmd.s_cprompt;
-}
-
-
-int
-get_echo(void)
-{
-    return (cmd.echo != STC_OFF );
-}
-
-
-int 
-get_errorbreak(void)
-{
-  return (cmd.errbrk != STC_OFF);
+static void
+show_cc (int idx) 
+{
+  const struct custom_currency *cc = get_cc (idx);
+  char cc_string[CC_WIDTH * 4 * 2 + 3 + 1];
+  char *out;
+
+  out = format_cc (cc->neg_prefix, cc->grouping, cc_string);
+  *out++ = cc->grouping;
+  out = format_cc (cc->prefix, cc->grouping, out);
+  *out++ = cc->grouping;
+  out = format_cc (cc->suffix, cc->grouping, out);
+  *out++ = cc->grouping;
+  out = format_cc (cc->neg_suffix, cc->grouping, out);
+  *out = '\0';
+  
+  msg (MM, _("CC%c is \"%s\"."), "ABCDE"[idx], cc_string);
 }
 
 
-int 
-get_scompression(void)
+static void
+show_cca (void) 
 {
-  return (cmd.scompress != STC_OFF );
+  show_cc (0);
 }
 
-int
-get_undefined(void)
+static void
+show_ccb (void) 
 {
-  return (cmd.undef != STC_NOWARN);
-}
-
-int
-get_mxwarns(void)
-{  
-  return cmd.n_mxwarns[0];
+  show_cc (1);
 }
 
-int
-get_mxerrs(void)
+static void
+show_ccc (void) 
 {
-  return cmd.n_mxerrs[0];
+  show_cc (2);
 }
 
-int
-get_mprint(void)
+static void
+show_ccd (void) 
 {
-  return ( cmd.mprint != STC_OFF );
+  show_cc (3);
 }
 
-int
-get_printback(void)
+static void
+show_cce (void) 
 {
-  return (cmd.prtbck != STC_OFF );
+  show_cc (4);
 }
 
-int
-get_mxloops(void)
+static void
+show_decimals (void) 
 {
-  return cmd.n_mxloops[0];
+  msg (MM, _("DECIMAL is \"%c\"."), get_decimal ());
 }
 
-int
-get_nullline(void)
+static void
+show_endcmd (void) 
 {
-  return (cmd.null != STC_OFF );
+  msg (MM, _("ENDCMD is \"%c\"."), get_endcmd ());
 }
 
-int
-get_include(void)
+static void
+show_format (void) 
 {
return (cmd.inc != STC_OFF );
 msg (MM, _("FORMAT is %s."), fmt_to_string (get_format ()));
 }
 
-char
-get_endcmd(void)
+static void
+show_length (void) 
 {
-  return cmd.s_endcmd[0];
+  msg (MM, _("LENGTH is %d."), get_viewlength ());
 }
 
-
-size_t
-get_max_workspace(void)
+static void
+show_mxerrs (void) 
 {
-  return cmd.n_workspace[0];
+  msg (MM, _("MXERRS is %d."), get_mxerrs ());
 }
 
-double
-get_blanks(void)
+static void
+show_mxloops (void) 
 {
-  return set_blanks;
-}
-
-struct fmt_spec 
-get_format(void)
-{ 
-  return set_format;
+  msg (MM, _("MXLOOPS is %d."), get_mxloops ());
 }
 
-/* CCA through CCE. */
-const struct set_cust_currency *
-get_cc(int i)
+static void
+show_mxwarns (void) 
 {
-  return &set_cc[i];
+  msg (MM, _("MXWARNS is %d."), get_mxwarns ());
 }
 
-void
-aux_show_warranty(void)
+static void
+show_scompression (void) 
 {
-  msg(MM,lack_of_warranty);
+  if (get_scompression ())
+    msg (MM, _("SCOMPRESSION is ON."));
+  else
+    msg (MM, _("SCOMPRESSION is OFF."));
 }
 
-void
-aux_show_copying(void)
+static void
+show_undefined (void) 
 {
-  msg(MM,copyleft);
+  if (get_undefined ())
+    msg (MM, _("UNDEFINED is WARN."));
+  else
+    msg (MM, _("UNDEFINED is NOWARN."));
 }
 
-
-int
-get_viewlength(void)
+static void
+show_weight (void) 
 {
-  return set_viewlength;
+  struct variable *var = dict_get_weight (default_dict);
+  if (var == NULL)
+    msg (MM, _("WEIGHT is off."));
+  else
+    msg (MM, _("WEIGHT is variable %s."), var->name);
 }
 
-int
-get_viewwidth(void)
+static void
+show_width (void) 
 {
-  return set_viewwidth;
+  msg (MM, _("WIDTH is %d."), get_viewwidth ());
 }
 
-const char *
-get_pager(void)
-{
-  return set_pager;
-}
+struct show_sbc 
+  {
+    const char *name;
+    void (*function) (void);
+  };
 
-gsl_rng *
-get_rng (void)
-{
-  if (rng == NULL)
-    set_rng (random_seed ());
-  return rng;
-}
+struct show_sbc show_table[] = 
+  {
+    {"BLANKS", show_blanks},
+    {"CCA", show_cca},
+    {"CCB", show_ccb},
+    {"CCC", show_ccc},
+    {"CCD", show_ccd},
+    {"CCE", show_cce},
+    {"DECIMALS", show_decimals},
+    {"ENDCMD", show_endcmd},
+    {"FORMAT", show_format},
+    {"LENGTH", show_length},
+    {"MXERRS", show_mxerrs},
+    {"MXLOOPS", show_mxloops},
+    {"MXWARNS", show_mxwarns},
+    {"SCOMPRESSION", show_scompression},
+    {"UNDEFINED", show_undefined},
+    {"WEIGHT", show_weight},
+    {"WIDTH", show_width},
+  };
 
 static void
-set_rng (unsigned long seed) 
+show_all (void) 
 {
-  rng = gsl_rng_alloc (gsl_rng_mt19937);
-  if (rng == NULL)
-    xalloc_die ();
-  gsl_rng_set (rng, seed);
+  size_t i;
+  
+  for (i = 0; i < sizeof show_table / sizeof *show_table; i++)
+    show_table[i].function ();
 }
 
-static unsigned long
-random_seed (void) 
+static void
+show_all_cc (void) 
 {
-  return time (0);
-}
+  int i;
 
-static int global_algorithm = ENHANCED;
-static int cmd_algorithm = ENHANCED;
-static int *algorithm = &global_algorithm;
-
-static int syntax = ENHANCED;
-
-/* Set the algorithm option globally */
-void 
-set_algorithm(int x)
-{
-  global_algorithm = x;
+  for (i = 0; i < 5; i++)
+    show_cc (i);
 }
 
-/* Set the algorithm option for this command only */
-void 
-set_cmd_algorithm(int x)
+static void
+show_warranty (void) 
 {
-  cmd_algorithm = x; 
-  algorithm = &cmd_algorithm;
+  msg (MM, lack_of_warranty);
 }
 
-/* Unset the algorithm option for this command */
-void
-unset_cmd_algorithm(void)
+static void
+show_copying (void) 
 {
-  algorithm = &global_algorithm;
+  msg (MM, copyleft);
 }
 
-/* Return the current algorithm setting */
 int
-get_algorithm(void)
+cmd_show (void) 
 {
-  return *algorithm;
-}
+  if (token == '.') 
+    {
+      show_all ();
+      return CMD_SUCCESS;
+    }
 
-/* Set the syntax option */
-void 
-set_syntax(int x)
-{
-  syntax = x;
-}
+  do 
+    {
+      if (lex_match (T_ALL))
+        show_all ();
+      else if (lex_match_id ("CC")) 
+        show_all_cc ();
+      else if (lex_match_id ("WARRANTY"))
+        show_warranty ();
+      else if (lex_match_id ("COPYING"))
+        show_copying ();
+      else if (token == T_ID)
+        {
+          int i;
+
+          for (i = 0; i < sizeof show_table / sizeof *show_table; i++)
+            if (lex_match_id (show_table[i].name)) 
+              {
+                show_table[i].function ();
+                goto found;
+              }
+          lex_error (NULL);
+          return CMD_PART_SUCCESS_MAYBE;
+
+        found: ;
+        }
+      else 
+        {
+          lex_error (NULL);
+          return CMD_PART_SUCCESS_MAYBE;
+        }
 
-/* Get the current syntax setting */
-int
-get_syntax(void)
-{
-  return syntax;
-}
+      lex_match ('/');
+    }
+  while (token != '.');
 
+  return CMD_SUCCESS;
+}
 
 /*
    Local Variables:
diff --git a/src/settings.c b/src/settings.c
new file mode 100644 (file)
index 0000000..749757b
--- /dev/null
@@ -0,0 +1,619 @@
+/* PSPP - computes sample statistics.
+   Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
+   Written by Ben Pfaff <blp@gnu.org>.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA. */
+
+#include <config.h>
+#include "settings.h"
+#include <assert.h>
+#include <time.h>
+#include "format.h"
+#include "val.h"
+#include "xalloc.h"
+
+static int viewlength = 24;
+static int viewwidth = 79;
+static bool long_view = false;
+
+static bool safer_mode = false;
+
+static char decimal = '.';
+static char grouping = ',';
+
+static char *prompt = NULL;
+static char *cprompt = NULL;
+static char *dprompt = NULL;
+
+static bool echo = false;
+static bool include = true;
+
+static int epoch = -1;
+
+static bool errorbreak = false;
+
+static bool scompress = false;
+
+static bool undefined = true;
+static double blanks = SYSMIS;
+
+static int mxwarns = 100;
+static int mxerrs = 100;
+
+static bool printback = true;
+static bool mprint = true;
+
+static int mxloops = 1;
+
+static bool nulline = true;
+
+static char endcmd = '.';
+
+static size_t workspace = 4L * 1024 * 1024;
+
+static struct fmt_spec default_format = {FMT_F, 8, 2};
+
+#define CC_CNT 5
+#define CC_INITIALIZER {"-", "", "", "", '.', ','}
+static struct custom_currency cc[CC_CNT] = 
+  {
+    CC_INITIALIZER,
+    CC_INITIALIZER,
+    CC_INITIALIZER,
+    CC_INITIALIZER,
+    CC_INITIALIZER,
+  };
+
+static gsl_rng *rng;
+
+static bool testing_mode = false;
+
+static int global_algorithm = ENHANCED;
+static int cmd_algorithm = ENHANCED;
+static int *algorithm = &global_algorithm;
+
+static int syntax = ENHANCED;
+
+static void init_viewport (void);
+
+void
+done_settings (void)
+{
+  if (rng != NULL) 
+    gsl_rng_free (rng);
+
+  free (prompt);
+  free (cprompt);
+  free (dprompt);
+}
+
+void
+init_settings (void)
+{
+  init_viewport ();
+}
+
+/* Screen length in lines. */
+int
+get_viewlength (void)
+{
+  return viewlength;
+}
+
+/* Sets the view length. */
+void
+set_viewlength (int viewlength_) 
+{
+  viewlength = viewlength_;
+}
+
+/* Set view width to a very long value, and prevent it from ever
+   changing. */
+void
+force_long_view (void)
+{
+  long_view = true;
+  viewwidth = 9999;
+}
+
+/* Screen width. */
+int
+get_viewwidth(void)
+{
+  return viewwidth;
+}
+
+/* Sets the screen width. */
+void
+set_viewwidth (int viewwidth_) 
+{
+  viewwidth = viewwidth_;
+}
+
+#if HAVE_LIBTERMCAP
+static void
+get_termcap_viewport (void)
+{
+  char term_buffer[16384];
+  if (getenv ("TERM") == NULL)
+    return;
+  else if (tgetent (term_buffer, getenv ("TERM")) <= 0)
+    {
+      msg (IE, _("Could not access definition for terminal `%s'."), termtype);
+      return;
+    }
+
+  if (tgetnum ("li") > 0)
+    viewlength = tgetnum ("li");
+
+  if (tgetnum ("co") > 1)
+    viewwidth = tgetnum ("co") - 1;
+}
+#endif /* HAVE_LIBTERMCAP */
+
+static void 
+init_viewport (void)
+{
+  if (long_view)
+    return;
+  
+  viewwidth = viewlength = -1;
+
+#if HAVE_LIBTERMCAP
+  get_termcap_viewport ();
+#endif /* HAVE_LIBTERMCAP */
+
+  if (viewwidth < 0 && getenv ("COLUMNS") != NULL)
+    viewwidth = atoi (getenv ("COLUMNS"));
+  if (viewlength < 0 && getenv ("LINES") != NULL)
+    viewlength = atoi (getenv ("LINES"));
+
+  if (viewwidth < 0)
+    viewwidth = 79;
+  if (viewlength < 0)
+    viewlength = 24;
+}
+
+/* Whether PSPP can erase and overwrite files. */
+bool
+get_safer_mode (void)
+{
+  return safer_mode;
+}
+
+/* Set safer mode. */
+void
+set_safer_mode (void)
+{
+  safer_mode = true;
+}
+
+/* The character used for a decimal point: ',' or '.'.  Only
+   respected for data input and output. */
+char 
+get_decimal (void)
+{
+  return decimal;
+}
+
+/* Sets the character used for a decimal point, which must be
+   either ',' or '.'. */
+void
+set_decimal (char decimal_) 
+{
+  assert (decimal_ == '.' || decimal_ == ',');
+  decimal = decimal_;
+}
+
+/* The character used for grouping in numbers: '.' or ','; the
+   opposite of set_decimal.  Only used in COMMA data input and
+   output. */
+char
+get_grouping (void)
+{
+  return grouping;
+}
+
+/* Sets the character used for grouping, which must be either ','
+   or '.'. */
+void
+set_grouping (char grouping_) 
+{
+  assert (grouping_ == '.' || grouping_ == ',');
+  grouping = grouping_;
+}
+/* Gets the normal command prompt. */
+const char * 
+get_prompt (void)
+{
+  return prompt != NULL ? prompt : "PSPP> ";
+}
+
+/* Sets the normal command prompt. */
+void
+set_prompt (const char *prompt_)
+{
+  free (prompt);
+  prompt = xstrdup (prompt_);
+}
+
+/* Gets the prompt used for data (after BEGIN DATA and before END
+   DATA). */
+const char * 
+get_dprompt (void)
+{
+  return dprompt != NULL ? dprompt : "data> ";
+}
+
+/* Sets the prompt used for data (after BEGIN DATA and before END
+   DATA). */
+void
+set_dprompt (const char *dprompt_)
+{
+  free (dprompt);
+  dprompt = xstrdup (dprompt_);
+}
+
+/* Gets the continuation prompt used for second and subsequent
+   lines of commands. */
+const char * 
+get_cprompt (void)
+{
+  return cprompt != NULL ? cprompt : "    > ";
+}
+
+/* Sets the continuation prompt used for second and subsequent
+   lines of commands. */
+void
+set_cprompt (const char *cprompt_)
+{
+  free (cprompt);
+  cprompt = xstrdup (cprompt_);
+}
+
+/* Echo commands to the listing file/printer? */
+bool
+get_echo (void)
+{
+  return echo;
+}
+
+/* Set echo. */
+void
+set_echo (bool echo_) 
+{
+  echo = echo_;
+}
+
+/* If echo is on, whether commands from include files are echoed. */
+bool
+get_include (void)
+{
+  return include;
+}
+
+/* Set include file echo. */
+void
+set_include (bool include_) 
+{
+  include = include_;
+}
+
+/* What year to use as the start of the epoch. */
+int
+get_epoch (void) 
+{
+  if (epoch < 0) 
+    {
+      time_t t = time (0);
+      struct tm *tm = localtime (&t);
+      epoch = (tm != NULL ? tm->tm_year + 1900 : 2000) - 69;
+    }
+
+  return epoch;
+}
+
+/* Sets the year that starts the epoch. */
+void
+set_epoch (int epoch_) 
+{
+  epoch = epoch_;
+}
+
+/* Does an error stop execution? */
+bool
+get_errorbreak (void)
+{
+  return errorbreak;
+}
+
+/* Sets whether an error stops execution. */
+void
+set_errorbreak (bool errorbreak_) 
+{
+  errorbreak = errorbreak_;
+}
+
+/* Compress system files by default? */
+bool 
+get_scompression (void)
+{
+  return scompress;
+}
+
+/* Set system file default compression. */
+void
+set_scompression (bool scompress_) 
+{
+  scompress = scompress_;
+}
+
+/* Whether to warn on undefined values in numeric data. */
+bool
+get_undefined (void)
+{
+  return undefined;
+}
+
+/* Set whether to warn on undefined values. */
+void
+set_undefined (bool undefined_) 
+{
+  undefined = undefined_;
+}
+
+/* The value that blank numeric fields are set to when read in. */
+double
+get_blanks (void)
+{
+  return blanks;
+}
+
+/* Set the value that blank numeric fields are set to when read
+   in. */
+void
+set_blanks (double blanks_) 
+{
+  blanks = blanks_;
+}
+
+/* Maximum number of warnings + errors. */
+int
+get_mxwarns (void)
+{  
+  return mxwarns;
+}
+
+/* Sets maximum number of warnings + errors. */
+void
+set_mxwarns (int mxwarns_) 
+{
+  mxwarns = mxwarns_;
+}
+
+/* Maximum number of errors. */
+int
+get_mxerrs (void)
+{
+  return mxerrs;
+}
+
+/* Sets maximum number of errors. */
+void
+set_mxerrs (int mxerrs_) 
+{
+  mxerrs = mxerrs_;
+}
+
+/* Whether commands are written to the display. */
+bool
+get_printback (void)
+{
+  return printback;
+}
+
+/* Sets whether commands are written to the display. */
+void
+set_printback (bool printback_) 
+{
+  printback = printback_;
+}
+
+/* Independent of get_printback, controls whether the commands
+   generated by macro invocations are displayed. */
+bool
+get_mprint (void)
+{
+  return mprint;
+}
+
+/* Sets whether the commands generated by macro invocations are
+   displayed. */
+void
+set_mprint (bool mprint_) 
+{
+  mprint = mprint_;
+}
+
+/* Implied limit of unbounded loop. */
+int
+get_mxloops (void)
+{
+  return mxloops;
+}
+
+/* Set implied limit of unbounded loop. */
+void
+set_mxloops (int mxloops_) 
+{
+  mxloops = mxloops_;
+}
+
+/* Whether a blank line is a command terminator. */
+bool
+get_nulline (void)
+{
+  return nulline;
+}
+
+/* Set whether a blank line is a command terminator. */
+void
+set_nulline (bool nulline_)
+{
+  nulline = nulline_;
+}
+
+/* The character used to terminate commands. */
+char
+get_endcmd (void)
+{
+  return endcmd;
+}
+
+/* Set the character used to terminate commands. */
+void
+set_endcmd (char endcmd_) 
+{
+  endcmd = endcmd_;
+}
+
+/* Approximate maximum amount of memory to use for cases, in
+   bytes. */
+size_t
+get_workspace(void)
+{
+  return workspace;
+}
+
+/* Set approximate maximum amount of memory to use for cases, in
+   bytes. */
+
+void
+set_workspace (size_t workspace_) 
+{
+  workspace = workspace_;
+}
+
+/* Default format for variables created by transformations and by
+   DATA LIST {FREE,LIST}. */
+const struct fmt_spec *
+get_format (void)
+{ 
+  return &default_format;
+}
+
+/* Set default format for variables created by transformations
+   and by DATA LIST {FREE,LIST}. */
+void
+set_format (const struct fmt_spec *default_format_) 
+{
+  default_format = *default_format_;
+}
+
+/* Gets the custom currency specification with the given IDX. */
+const struct custom_currency *
+get_cc (int idx)
+{
+  assert (idx >= 0 && idx < CC_CNT);
+  return &cc[idx];
+}
+
+/* Gets custom currency specification IDX to CC. */
+void
+set_cc (int idx, const struct custom_currency *cc_) 
+{
+  assert (idx >= 0 && idx < CC_CNT);
+  cc[idx] = *cc_;
+}
+
+/* Returns the current random number generator. */
+gsl_rng *
+get_rng (void)
+{
+  if (rng == NULL)
+    set_rng (time (0));
+  return rng;
+}
+
+/* Initializes or reinitializes the random number generator with
+   the given SEED. */
+void
+set_rng (unsigned long seed) 
+{
+  rng = gsl_rng_alloc (gsl_rng_mt19937);
+  if (rng == NULL)
+    xalloc_die ();
+  gsl_rng_set (rng, seed);
+}
+
+/* Are we in testing mode?  (e.g. --testing-mode command line
+   option) */
+bool
+get_testing_mode (void) 
+{
+  return testing_mode;
+}
+
+/* Set testing mode. */
+void
+set_testing_mode (bool testing_mode_) 
+{
+  testing_mode = testing_mode_;
+}
+
+/* Return the current algorithm setting */
+enum behavior_mode
+get_algorithm (void)
+{
+  return *algorithm;
+}
+
+/* Set the algorithm option globally. */
+void 
+set_algorithm (enum behavior_mode mode)
+{
+  global_algorithm = mode;
+}
+
+/* Set the algorithm option for this command only */
+void 
+set_cmd_algorithm (enum behavior_mode mode)
+{
+  cmd_algorithm = mode; 
+  algorithm = &cmd_algorithm;
+}
+
+/* Unset the algorithm option for this command */
+void
+unset_cmd_algorithm (void)
+{
+  algorithm = &global_algorithm;
+}
+
+/* Get the current syntax setting */
+enum behavior_mode
+get_syntax (void)
+{
+  return syntax;
+}
+
+/* Set the syntax option */
+void 
+set_syntax (enum behavior_mode mode)
+{
+  syntax = mode;
+}
index 8cff528ee70fa1494d816cb2ad5622194a3f0466..9e6209250da9b2fcfae9f2c31f0691e9ea3491e4 100644 (file)
 #if !settings_h
 #define settings_h 1
 
-/* Table of mode settings (x=X, w=Windows, p=PC+, f=has relevance for
-   PSPP):
-
-   AUTOMENU: p
-   BEEP: p
-   BLANKS: xwpf
-   BLKSIZE: x (only on SHOW, not on SET)
-   BLOCK: xwp
-   BOX/BOXSTRING: xwp
-   BUFNO: x (only on SHOW, not on SET)
-   CASE: xw
-   CCA...CCE: xwf
-   COLOR: p
-   COMP/COMPRESSION: xwpf (meaning varies between p and xw)
-   CPI: xwp
-   CPROMPT: pf
-   DECIMAL: wf
-   DPROMPT: f
-   ECHO: pf
-   EJECT: p
-   EMULATION: f
-   ENDCMD: xpf
-   ERRORBREAK: pf
-   ERRORS: wf
-   FORMAT: xwf
-   HEADERS: xwf
-   HELPWINDOWS: p
-   HIGHRES: w
-   HISTOGRAM: xp
-   INCLUDE: pf
-   JOURNAL: wf (equivalent to LOG)
-   LENGTH: xwp
-   LISTING: xpf
-   LOG: pf (equivalent to JOURNAL)
-   LOWRES: w
-   LPI: xwp
-   MENUS: p
-   MESSAGES: wf
-   MEXPAND: xwf
-   MITERATE: xwf
-   MNEST: xwf
-   MORE: pf
-   MPRINT: xwf
-   MXERRS: xf
-   MXLOOPS: xwf
-   MXMEMORY: w
-   MXWARNS: xwf
-   N: xw (only on SHOW, not on SET)
-   NULLINE: xpf
-   NUMBERED: x (only on SHOW, not on SET)
-   PAGER: f
-   PRINTBACK: xwf
-   PRINTER: pf
-   PROMPT: pf
-   PTRANSLATE: p
-   RCOLOR: p
-   RESULTS: wpf (semantics differ)
-   RUNREVIEW: p
-   SCOMP/SCOMPRESSION: xwf
-   SCREEN: pf
-   SCRIPTTAB: xw
-   SEED: xwpf (semantics differ)
-   SYSMIS: xwf (only on SHOW, not on SET)
-   TBFONTS: xw
-   TB1: xw
-   TB2: x
-   UNDEFINED: xwf
-   VIEWLENGTH: pf
-   VIEWWIDTH: f
-   WEIGHT: xwf (only on SHOW, not on SET)
-   WIDTH: xwp
-   WORKDEV: p
-   WORKSPACE: w
-   XSORT: x
-   $VARS: wf (only on SHOW, not on SET)
-
- */
-
+#include <stdbool.h>
 #include <stddef.h>
-#include <float.h>
-
-
-/* Describes one custom currency specification. */
-struct set_cust_currency
-  {
-    char buf[32];              /* Buffer for strings. */
-    char *neg_prefix;          /* Negative prefix. */
-    char *prefix;              /* Prefix. */
-    char *suffix;              /* Suffix. */
-    char *neg_suffix;          /* Negative suffix. */
-    int decimal;               /* Decimal point. */
-    int grouping;              /* Grouping character. */
-  };
-
-
-
 
 /* Types of routing. */
 enum
@@ -126,135 +32,108 @@ enum
     SET_ROUTE_DISABLE = 010    /* Disable output--overrides all other bits. */
   };
 
+void init_settings (void);
+void done_settings (void);
 
-/* Set view width to a very long value, and prevent it from 
-   ever changing */
-void force_long_view(void);
-
-
-/* Requested "view length" in lines. */
-int get_viewlength(void);
+void force_long_view (void);
+int get_viewlength (void);
+void set_viewlength (int);
 
-/* Screen width. */
-int get_viewwidth(void);
+int get_viewwidth (void);
+void set_viewwidth (int);
 
-void init_settings(void) ;
-void done_settings(void) ;
+bool get_safer_mode (void);
+void set_safer_mode (void);
 
-/* Whether pspp can erase and overwrite files */
-int safer_mode(void);
+char get_decimal (void);
+void set_decimal (char);
+char get_grouping (void);
+void set_grouping (char);
 
-/* Put into safer mode */
-void make_safe(void);
+const char *get_prompt (void);
+void set_prompt (const char *);
+const char *get_cprompt (void);
+void set_cprompt (const char *);
+const char *get_dprompt (void);
+void set_dprompt (const char *);
 
-/* The character used for a decimal point: ',' or '.'.  Only respected
-   for data input and output. */
-char get_decimal(void);
+bool get_echo (void);
+void set_echo (bool);
+bool get_include (void);
+void set_include (bool);
 
-/* The character used for grouping in numbers: '.' or ','; the
-   opposite of set_decimal.  Only used in COMMA data input and
-   output. */
-
-char get_grouping(void);
-
-char *get_prompt(void);
-
-/* Prompt used for lines between BEGIN DATA and END DATA. */
-char *get_dprompt(void);
-
-/* Continuation prompt. */
-char *get_cprompt(void);
-
-
-/* Whether we echo commands to the listing file/printer;*/
-int get_echo(void);
-
-/* What year to use as the start of the epoch. */
 int get_epoch (void);
+void set_epoch (int);
 
-/* If echo is on, whether commands from include files are echoed */
-int get_include(void);
-
-/* Whether an error stops execution; */
-int  get_errorbreak(void);
-
-/* Whether save files should be compressed by default. */
-int get_scompression(void);
+bool get_errorbreak (void);
+void set_errorbreak (bool);
 
-/* Whether to warn on undefined values in numeric data. */
-int get_undefined(void);
+bool get_scompression (void);
+void set_scompression (bool);
 
-/* Maximum number of warnings + errors. */
-int get_mxwarns(void);
+bool get_undefined (void);
+void set_undefined (bool);
+double get_blanks (void);
+void set_blanks (double);
 
-/* Maximum number of errors. */
-int get_mxerrs(void);
+int get_mxwarns (void);
+void set_mxwarns (int);
+int get_mxerrs (void);
+void set_mxerrs (int);
 
-/* 0=macro expansion is disabled, 1=macro expansion is enabled. */
-int get_mexpand(void);
+bool get_printback (void);
+void set_printback (bool);
+bool get_mprint (void);
+void set_mprint (bool);
 
-/* Whether commands are written to the display */
-int get_printback(void);
+int get_mxloops (void);
+void set_mxloops (int);
 
-/* Independent of get_printback, controls whether the commands
-   generated by macro invocations are displayed. */
-int get_mprint(void);
+bool get_nulline (void);
+void set_nulline (bool);
 
-/* Implied limit of unbounded loop. */
-int get_mxloops(void);
+char get_endcmd (void);
+void set_endcmd (char);
 
-/* Whether a blank line is a command terminator */
-int get_nullline(void);
+size_t get_workspace (void);
+void set_workspace (size_t);
 
-/* The character used to terminate commands. */
-char get_endcmd(void);
+const struct fmt_spec *get_format (void);
+void set_format (const struct fmt_spec *);
 
-/* Approximate maximum amount of memory to use for cases, in
-   bytes. */
-size_t get_max_workspace(void);
-
-/* The value that blank numeric fields are set to when read in;
-   normally SYSMIS. */
-double get_blanks(void);
-
-
-/* Default format for variables created by transformations and by DATA
-   LIST {FREE,LIST}. */
-struct fmt_spec get_format(void);
-
-/* CCA through CCE. */
-const struct set_cust_currency *get_cc(int i);
-
-#if !USE_INTERNAL_PAGER
-/* Name of the pager program. */
-const char *get_pager(void);
-#endif /* !USE_INTERNAL_PAGER */
+/* One custom currency specification. */
+#define CC_WIDTH 16
+struct custom_currency
+  {
+    char neg_prefix[CC_WIDTH]; /* Negative prefix. */
+    char prefix[CC_WIDTH];     /* Prefix. */
+    char suffix[CC_WIDTH];     /* Suffix. */
+    char neg_suffix[CC_WIDTH]; /* Negative suffix. */
+    char decimal;              /* Decimal point. */
+    char grouping;             /* Grouping character. */
+  };
 
+const struct custom_currency *get_cc (int idx);
+void set_cc (int idx, const struct custom_currency *);
 
 #include <gsl/gsl_rng.h>
-gsl_rng *get_rng (void);
-
-
-enum {ENHANCED,COMPATIBLE};
-
-
-/* Set the algorithm option globally */
-void set_algorithm(int x);
-
-/* Set the algorithm option for this command only */
-void set_cmd_algorithm(int x);
-
-/* Unset the algorithm option for this command */
-void unset_cmd_algorithm(void);
-
-/* Return the current algorithm setting */
-int get_algorithm(void);
-
-/* Set the syntax option */
-void set_syntax(int x);
-
-/* Get the current syntax setting */
-int get_syntax(void);
 
+gsl_rng *get_rng (void);
+void set_rng (unsigned long seed);
+
+bool get_testing_mode (void);
+void set_testing_mode (bool);
+
+enum behavior_mode {
+  ENHANCED,             /* Use improved PSPP behavior. */
+  COMPATIBLE            /* Be as compatible as possible. */
+};
+
+enum behavior_mode get_algorithm (void);
+void set_algorithm (enum behavior_mode);
+enum behavior_mode get_syntax (void);
+void set_syntax(enum behavior_mode);
+void set_cmd_algorithm (enum behavior_mode);
+void unset_cmd_algorithm (void);
 
 #endif /* !settings_h */
index 47cd6a095c2435ad5bbad38aa645d348711b5f6b..8dad3566ccdcca1ad8e9fabf63ace81b42d7019f 100644 (file)
@@ -72,7 +72,7 @@ cmd_sort_cases (void)
   if (criteria == NULL)
     return CMD_FAILURE;
 
-  if (test_mode && lex_match ('/')) 
+  if (get_testing_mode () && lex_match ('/')) 
     {
       if (!lex_force_match_id ("BUFFERS") || !lex_match ('=')
           || !lex_force_int ())
@@ -443,7 +443,7 @@ allocate_cases (struct initial_run_state *irs)
   approx_case_cost = (sizeof *irs->records
                       + irs->xsrt->value_cnt * sizeof (union value)
                       + 4 * sizeof (void *));
-  max_cases = get_max_workspace() / approx_case_cost;
+  max_cases = get_workspace() / approx_case_cost;
   if (max_cases > max_buffers)
     max_cases = max_buffers;
   irs->records = nmalloc (sizeof *irs->records, max_cases);
@@ -462,7 +462,7 @@ allocate_cases (struct initial_run_state *irs)
       msg (SE, _("Out of memory.  Could not allocate room for minimum of %d "
                 "cases of %d bytes each.  (PSPP workspace is currently "
                 "restricted to a maximum of %d KB.)"),
-          min_buffers, approx_case_cost, get_max_workspace() / 1024);
+          min_buffers, approx_case_cost, get_workspace() / 1024);
       return 0;
     }
   return 1;