Adopt use of gnulib for portability.
[pspp-builds.git] / src / set.q
index 8683bff7ea7ef500061ce3ccb0862c78cd3a8f68..300111c90b2de5462d95421056be18f2330e18a1 100644 (file)
--- a/src/set.q
+++ b/src/set.q
 
    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., 59 Temple Place - Suite 330, Boston, MA
-   02111-1307, USA. */
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA. */
 
 /*
    Categories of SET subcommands:
 
-   data input: BLANKS, DECIMAL, FORMAT.
+   data input: BLANKS, DECIMAL, FORMAT, EPOCH.
    
    program input: ENDCMD, NULLINE.
    
 */     
    
 #include <config.h>
-#include <assert.h>
+#include "settings.h"
+#include "error.h"
 #include <stdio.h>
 #include <errno.h>
 #include <stdlib.h>
+#include <time.h>
 #include "alloc.h"
 #include "command.h"
 #include "lexer.h"
 #include "output.h"
 #include "var.h"
 #include "format.h"
-#include "settings.h"
+#include "copyleft.h"
+
+#include "signal.h"
+
+#if HAVE_LIBTERMCAP
+#if HAVE_TERMCAP_H
+#include <termcap.h>
+#else /* !HAVE_TERMCAP_H */
+int tgetent (char *, const char *);
+int tgetnum (const char *);
+#endif /* !HAVE_TERMCAP_H */
+#endif /* !HAVE_LIBTERMCAP */
+
+#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;
 
-double set_blanks;
-int set_compression;
-struct set_cust_currency set_cc[5];
-int set_cpi;
-char *set_cprompt;
-int set_decimal;
-int set_grouping;
-char *set_dprompt;
-int set_echo;
-int set_endcmd;
-int set_errorbreak;
-int set_errors, set_messages, set_results;
-struct fmt_spec set_format;
-int set_headers;
-int set_include;
-char *set_journal;
-int set_journaling;
-int set_lpi;
-int set_messages;
-int set_mexpand;
-int set_miterate;
-int set_mnest;
-int set_more;
-int set_mprint;
-int set_mxerrs;
-int set_mxloops;
-int set_mxwarns;
-int set_nullline;
-int set_printback;
-int set_output = 1;
 #if !USE_INTERNAL_PAGER
-char *set_pager;
+static char *set_pager=0;
 #endif /* !USE_INTERNAL_PAGER */
-int set_printer;
-char *set_prompt;
-char *set_results_file;
-int set_safer;
-int set_scompression;
-int set_screen;
-long set_seed;
-int set_seed_used;
-int set_testing_mode;
-int set_undefined;
-int set_viewlength;
-int set_viewwidth;
 
+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_):
@@ -139,14 +144,15 @@ static int set_ccx (const char *cc_string, struct set_cust_currency * cc,
      cce=string;
      color=custom;
      compression=compress:on/off;
-     cpi=integer;
+     cpi=integer "x>0" "%s must be greater than 0";
      cprompt=string;
-     decimal=dec:dot/_comma;
+     decimal=dec:dot/comma;
      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;
@@ -160,16 +166,16 @@ static int set_ccx (const char *cc_string, struct set_cust_currency * cc,
      listing=custom;
      log=custom;
      lowres=lores:auto/on/off;
-     lpi=integer;
+     lpi=integer "x>0" "%s must be greater than 0";
      menus=menus:standard/extended;
      messages=messages:on/off/terminal/listing/both/none;
      mexpand=mexp:on/off;
-     miterate=integer;
-     mnest=integer;
+     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;
-     mxloops=integer;
+     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;
@@ -190,63 +196,185 @@ static int set_ccx (const char *cc_string, struct set_cust_currency * cc,
      tbfonts=string;
      undefined=undef:warn/nowarn;
      viewlength=custom;
-     viewwidth=integer;
+     viewwidth=custom;
      width=custom;
      workdev=custom;
-     workspace=integer;
+     workspace=integer "x>=1024" "%s must be at least 1 MB";
      xsort=xsort:yes/no.
 */
 
 /* (declarations) */
-/* (functions) */
 
-int internal_cmd_set (void);
+/* (_functions) */
 
-int
-cmd_set (void)
+static int
+aux_stc_custom_blanks(struct cmd_set *cmd UNUSED)
 {
-  struct cmd_set cmd;
+  if ( set_blanks == SYSMIS ) 
+    msg(MM, "SYSMIS");
+  else
+    msg(MM, "%g", set_blanks);
+  return 0;
+}
 
-  lex_match_id ("SET");
 
-  if (!parse_set (&cmd))
-    return CMD_FAILURE;
+static int
+aux_stc_custom_color(struct cmd_set *cmd UNUSED)
+{
+  msg (MW, _("%s is obsolete."),"COLOR");
+  return 0;
+}
 
-  if (cmd.sbc_block)
-    msg (SW, _("BLOCK is obsolete."));
+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"));
 
-  if (cmd.sbc_boxstring)
-    msg (SW, _("BOXSTRING is obsolete."));
+  return 0;
+}
 
-  if (cmd.compress != -1)
-    {
-      msg (MW, _("Active file compression is not yet implemented "
-                "(and probably won't be)."));
-      set_compression = cmd.compress == STC_OFF ? 0 : 1;
-    }
-  if (cmd.scompress != -1)
-    set_scompression = cmd.scompress == STC_OFF ? 0 : 1;
-  if (cmd.n_cpi != NOT_LONG)
-    {
-      if (cmd.n_cpi <= 0)
-       msg (SE, _("CPI must be greater than 0."));
-      else
-       set_cpi = cmd.n_cpi;
-    }
-  if (cmd.sbc_histogram)
-    msg (MW, _("HISTOGRAM is obsolete."));
-  if (cmd.n_lpi != NOT_LONG)
-    {
-      if (cmd.n_lpi <= 0)
-       msg (SE, _("LPI must be greater than 0."));
-      else
-       set_lpi = cmd.n_lpi;
-    }
+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)
+{
   
-  /* 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(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;
+}
+
+int
+cmd_set (void)
+{
+
+  if (!parse_set (&cmd))
+    return CMD_FAILURE;
+
   if (cmd.sbc_cca)
     set_ccx (cmd.s_cca, &set_cc[0], 'A');
   if (cmd.sbc_ccb)
@@ -257,125 +385,60 @@ cmd_set (void)
     set_ccx (cmd.s_ccd, &set_cc[3], 'D');
   if (cmd.sbc_cce)
     set_ccx (cmd.s_cce, &set_cc[4], 'E');
-  if (cmd.dec != -1)
-    {
-      set_decimal = cmd.dec == STC_DOT ? '.' : ',';
-      set_grouping = cmd.dec == STC_DOT ? ',' : '.';
-    }
-  if (cmd.errors != -1)
+
+  if (cmd.sbc_errors)
     set_routing (cmd.errors, &set_errors);
-  if (cmd.headers != -1)
-    set_headers = cmd.headers == STC_NO ? 0 : (cmd.headers == STC_YES ? 1 : 2);
-  if (cmd.messages != -1)
+  if (cmd.sbc_messages)
     set_routing (cmd.messages, &set_messages);
-  if (cmd.mexp != -1)
-    set_mexpand = cmd.mexp == STC_OFF ? 0 : 1;
-  if (cmd.n_miterate != NOT_LONG)
-    {
-      if (cmd.n_miterate > 0)
-       set_miterate = cmd.n_miterate;
-      else
-       msg (SE, _("Value for MITERATE (%ld) must be greater than 0."),
-            cmd.n_miterate);
-    }
-  if (cmd.n_mnest != NOT_LONG)
-    {
-      if (cmd.n_mnest > 0)
-       set_mnest = cmd.n_mnest;
-      else
-       msg (SE, _("Value for MNEST (%ld) must be greater than 0."),
-            cmd.n_mnest);
-    }
-  if (cmd.mprint != -1)
-    set_mprint = cmd.mprint == STC_OFF ? 0 : 1;
-  if (cmd.n_mxerrs != NOT_LONG)
-    {
-      if (set_mxerrs < 1)
-       msg (SE, _("MXERRS must be at least 1."));
-      else
-       set_mxerrs = cmd.n_mxerrs;
-    }
-  if (cmd.n_mxloops != NOT_LONG)
-    {
-      if (set_mxloops < 1)
-       msg (SE, _("MXLOOPS must be at least 1."));
-      else
-       set_mxloops = cmd.n_mxloops;
-    }
-  if (cmd.n_mxmemory != NOT_LONG)
-    msg (SE, _("MXMEMORY is obsolete."));
-  if (cmd.n_mxwarns != NOT_LONG)
-    set_mxwarns = cmd.n_mxwarns;
-  if (cmd.prtbck != -1)
-    set_printback = cmd.prtbck == STC_OFF ? 0 : 1;
-  if (cmd.s_scripttab)
-    msg (SE, _("SCRIPTTAB is obsolete."));
-  if (cmd.s_tbfonts)
-    msg (SW, _("TBFONTS not implemented."));
-  if (cmd.s_tb1)
-    msg (SW, _("TB1 not implemented."));
-  if (cmd.undef != -1)
-    set_undefined = cmd.undef == STC_NOWARN ? 0 : 1;
-  if (cmd.n_workspace != NOT_LONG)
-    msg (SE, _("WORKSPACE is obsolete."));
 
   /* PC+ compatible syntax. */
-  if (cmd.scrn != -1)
+  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");
+  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");
+  if (cmd.sbc_tb1 && cmd.s_tb1)
+    msg (SW, _("%s is not yet implemented."),"TB1");
 
-  if (cmd.automenu != -1)
-    msg (SW, _("AUTOMENU is obsolete."));
-  if (cmd.beep != -1)
-    msg (SW, _("BEEP is obsolete."));
+  /* Windows compatible syntax. */
+  if (cmd.sbc_case)
+    msg (SW, _("CASE is not implemented and probably won't be.  "
+       "If you care, complain about it."));
 
-  if (cmd.s_cprompt)
-    {
-      free (set_cprompt);
-      set_cprompt = cmd.s_cprompt;
-      cmd.s_cprompt = NULL;
-    }
-  if (cmd.s_dprompt)
+  if (cmd.sbc_compression)
     {
-      free (set_dprompt);
-      set_dprompt = cmd.s_dprompt;
-      cmd.s_dprompt = NULL;
-    }
-  if (cmd.echo != -1)
-    set_echo = cmd.echo == STC_OFF ? 0 : 1;
-  if (cmd.s_endcmd)
-    set_endcmd = cmd.s_endcmd[0];
-  if (cmd.eject != -1)
-    msg (SW, _("EJECT is obsolete."));
-  if (cmd.errbrk != -1)
-    set_errorbreak = cmd.errbrk == STC_OFF ? 0 : 1;
-  if (cmd.helpwin != -1)
-    msg (SW, _("HELPWINDOWS is obsolete."));
-  if (cmd.inc != -1)
-    set_include = cmd.inc == STC_OFF ? 0 : 1;
-  if (cmd.menus != -1)
-    msg (MW, _("MENUS is obsolete."));
-  if (cmd.null != -1)
-    set_nullline = cmd.null == STC_OFF ? 0 : 1;
-  if (cmd.more != -1)
-    set_more = cmd.more == STC_OFF ? 0 : 1;
-  if (cmd.prtr != -1)
-    outp_enable_device (cmd.prtr == STC_OFF ? 0 : 1, OUTP_DEV_PRINTER);
-  if (cmd.s_prompt)
-    {
-      free (set_prompt);
-      set_prompt = cmd.s_prompt;
-      cmd.s_prompt = NULL;
+      msg (MW, _("Active file compression is not yet implemented "
+                "(and probably won't be)."));
     }
-  if (cmd.ptrans != -1)
-    msg (SW, _("PTRANSLATE is obsolete."));
-  if (cmd.runrev != -1)
-    msg (SW, "RUNREVIEW is obsolete.");
-  if (cmd.safe == STC_ON)
-    set_safer = 1;
-  if (cmd.xsort != -1)
-    msg (SW, _("XSORT is obsolete."));
-
-  free_set (&cmd);
 
   return CMD_SUCCESS;
 }
@@ -452,6 +515,50 @@ set_ccx (const char *cc_string, struct set_cust_currency * cc, int cc_name)
   return 1;
 }
 
+
+const char *
+route_to_string(int routing)
+{
+  static char s[255];
+  
+  s[0]='\0';
+
+  if ( routing == 0 )
+    {
+      strcpy(s, _("None"));
+      return s;
+    }
+
+  if (routing & SET_ROUTE_DISABLE ) 
+    {
+    strcpy(s, _("Disabled") );
+    return s;
+    }
+
+  if (routing & SET_ROUTE_SCREEN)
+    strcat(s, _("Screen") );
+  
+  if (routing & SET_ROUTE_LISTING)
+    {
+      if(s[0] != '\0') 
+       strcat(s,", ");
+       
+      strcat(s, _("Listing") );
+    }
+
+  if (routing & SET_ROUTE_OTHER)
+    {
+      if(s[0] != '\0') 
+       strcat(s,", ");
+      strcat(s, _("Other") );
+    }
+    
+  return s;
+  
+    
+}
+
 /* 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. */
@@ -460,10 +567,10 @@ set_routing (int q, int *setting)
 {
   switch (q)
     {
-    case STC_ON:
+    case STC_OFF:
       *setting |= SET_ROUTE_DISABLE;
       break;
-    case STC_OFF:
+    case STC_ON:
       *setting &= ~SET_ROUTE_DISABLE;
       break;
     case STC_TERMINAL:
@@ -486,7 +593,7 @@ set_routing (int q, int *setting)
 }
 
 static int
-stc_custom_pager (struct cmd_set *cmd unused)
+stc_custom_pager (struct cmd_set *cmd UNUSED)
 {
   lex_match ('=');
 #if !USE_INTERNAL_PAGER
@@ -502,12 +609,12 @@ stc_custom_pager (struct cmd_set *cmd unused)
        return 0;
       if (set_pager)
        free (set_pager);
-      set_pager = xstrdup (ds_value (&tokstr));
+      set_pager = xstrdup (ds_c_str (&tokstr));
       lex_get ();
     }
   return 1;
 #else /* USE_INTERNAL_PAGER */
-  if (match_id (OFF))
+  if (lex_match_id ("OFF"))
     return 1;
   msg (SW, "External pagers not supported.");
   return 0;
@@ -519,7 +626,7 @@ stc_custom_pager (struct cmd_set *cmd unused)
    SYSMIS or a numeric value; PC+: Syntax is '.', which is equivalent
    to SYSMIS, or a numeric value. */
 static int
-stc_custom_blanks (struct cmd_set *cmd unused)
+stc_custom_blanks (struct cmd_set *cmd UNUSED)
 {
   lex_match ('=');
   if ((token == T_ID && lex_id_match ("SYSMIS", tokid))
@@ -538,8 +645,36 @@ stc_custom_blanks (struct cmd_set *cmd unused)
   return 1;
 }
 
+/* Parses the EPOCH subcommand, which controls the epoch used for
+   parsing 2-digit years. */
 static int
-stc_custom_length (struct cmd_set *cmd unused)
+stc_custom_epoch (struct cmd_set *cmd UNUSED) 
+{
+  lex_match ('=');
+  if (lex_match_id ("AUTOMATIC"))
+    set_epoch = -1;
+  else if (lex_is_integer ()) 
+    {
+      int new_epoch = lex_integer ();
+      lex_get ();
+      if (new_epoch < 1500) 
+        {
+          msg (SE, _("EPOCH must be 1500 or later."));
+          return 0;
+        }
+      set_epoch = new_epoch;
+    }
+  else 
+    {
+      lex_error (_("expecting AUTOMATIC or year"));
+      return 0;
+    }
+
+  return 1;
+}
+
+static int
+stc_custom_length (struct cmd_set *cmd UNUSED)
 {
   int page_length;
 
@@ -559,12 +694,14 @@ stc_custom_length (struct cmd_set *cmd unused)
       lex_get ();
     }
 
-  /* FIXME: Set page length. */
+  if ( page_length != -1 ) 
+    set_viewlength = page_length;
+
   return 1;
 }
 
 static int
-stc_custom_results (struct cmd_set *cmd unused)
+stc_custom_results (struct cmd_set *cmd UNUSED)
 {
   struct tuple
     {  
@@ -605,23 +742,24 @@ stc_custom_results (struct cmd_set *cmd unused)
 }
 
 static int
-stc_custom_seed (struct cmd_set *cmd unused)
+stc_custom_seed (struct cmd_set *cmd UNUSED)
 {
   lex_match ('=');
   if (lex_match_id ("RANDOM"))
-    set_seed = NOT_LONG;
+    set_rng (random_seed ());
   else
     {
       if (!lex_force_num ())
        return 0;
-      set_seed = tokval;
+      set_rng (tokval);
       lex_get ();
     }
+
   return 1;
 }
 
 static int
-stc_custom_width (struct cmd_set *cmd unused)
+stc_custom_width (struct cmd_set *cmd UNUSED)
 {
   int page_width;
 
@@ -643,14 +781,14 @@ stc_custom_width (struct cmd_set *cmd unused)
       lex_get ();
     }
 
-  /* FIXME: Set page width. */
+  set_viewwidth = page_width;
   return 1;
 }
 
 /* Parses FORMAT subcommand, which consists of a numeric format
    specifier. */
 static int
-stc_custom_format (struct cmd_set *cmd unused)
+stc_custom_format (struct cmd_set *cmd UNUSED)
 {
   struct fmt_spec fmt;
 
@@ -670,7 +808,7 @@ stc_custom_format (struct cmd_set *cmd unused)
 }
 
 static int
-stc_custom_journal (struct cmd_set *cmd unused)
+stc_custom_journal (struct cmd_set *cmd UNUSED)
 {
   lex_match ('=');
   if (lex_match_id ("ON"))
@@ -679,7 +817,7 @@ stc_custom_journal (struct cmd_set *cmd unused)
     set_journaling = 0;
   if (token == T_STRING)
     {
-      set_journal = xstrdup (ds_value (&tokstr));
+      set_journal = xstrdup (ds_c_str (&tokstr));
       lex_get ();
     }
   return 1;
@@ -688,9 +826,9 @@ stc_custom_journal (struct cmd_set *cmd unused)
 /* 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)
+stc_custom_color (struct cmd_set *cmd UNUSED)
 {
-  msg (MW, "COLOR is obsolete.");
+  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"))
@@ -739,39 +877,39 @@ stc_custom_color (struct cmd_set *cmd unused)
 }
 
 static int
-stc_custom_listing (struct cmd_set *cmd unused)
+stc_custom_listing (struct cmd_set *cmd UNUSED)
 {
   lex_match ('=');
   if (lex_match_id ("ON") || lex_match_id ("YES"))
-    outp_enable_device (1, OUTP_DEV_LISTING);
+    set_listing = 1;
   else if (lex_match_id ("OFF") || lex_match_id ("NO"))
-    outp_enable_device (0, OUTP_DEV_LISTING);
+    set_listing = 0;
   else
     {
       /* FIXME */
+      return 0;
     }
+  outp_enable_device (set_listing, OUTP_DEV_LISTING);
 
-  return 0;
+  return 1;
 }
 
 static int
-stc_custom_disk (struct cmd_set *cmd unused)
+stc_custom_disk (struct cmd_set *cmd UNUSED)
 {
-  stc_custom_listing (cmd);
-  return 0;
+  return stc_custom_listing (cmd);
 }
 
 static int
-stc_custom_log (struct cmd_set *cmd unused)
+stc_custom_log (struct cmd_set *cmd UNUSED)
 { 
-  stc_custom_journal (cmd);
-  return 0;
+  return stc_custom_journal (cmd);
 }
 
 static int
-stc_custom_rcolor (struct cmd_set *cmd unused)
+stc_custom_rcolor (struct cmd_set *cmd UNUSED)
 {
-  msg (SW, _("RCOLOR is obsolete."));
+  msg (SW, _("%s is obsolete."),"RCOLOR");
 
   lex_match ('=');
   if (!lex_force_match ('('))
@@ -818,7 +956,21 @@ stc_custom_rcolor (struct cmd_set *cmd unused)
 }
 
 static int
-stc_custom_viewlength (struct cmd_set *cmd unused)
+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)
 {
   if (lex_match_id ("MINIMUM"))
     set_viewlength = 25;
@@ -830,7 +982,7 @@ stc_custom_viewlength (struct cmd_set *cmd unused)
     {
       if (!lex_force_int ())
        return 0;
-#if __MSDOS__
+#ifdef __MSDOS__
       if (lex_integer () >= (43 + 25) / 2)
        set_viewlength = 43;
       else
@@ -841,18 +993,18 @@ stc_custom_viewlength (struct cmd_set *cmd unused)
       lex_get ();
     }
 
-#if __MSDOS__
-  msg (SW, _("VIEWLENGTH not implemented."));
+#ifdef __MSDOS__
+  msg (SW, _("%s is not yet implemented."),"VIEWLENGTH");
 #endif /* dos */
   return 1;
 }
 
 static int
-stc_custom_workdev (struct cmd_set *cmd unused)
+stc_custom_workdev (struct cmd_set *cmd UNUSED)
 {
   char c[2];
 
-  msg (SW, _("WORKDEV is obsolete."));
+  msg (SW, _("%s is obsolete."),"WORKDEV");
 
   c[1] = 0;
   for (*c = 'A'; *c <= 'Z'; (*c)++)
@@ -865,16 +1017,455 @@ stc_custom_workdev (struct cmd_set *cmd unused)
   return 0;
 }
 
-\f
-/* GSET. */
 
+
+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) ;
+}
+
+
+/* Set safer mode */
+void
+make_safe(void)
+{
+  cmd.safe = STC_ON;
+}
+
+
+char 
+get_decimal(void)
+{
+  return (cmd.dec == STC_DOT ? '.' : ',');
+}
+
+int
+get_epoch (void) 
+{
+  if (set_epoch < 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;
+    }
+
+  return set_epoch;
+}
+
+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);
+}
+
+
+int 
+get_scompression(void)
+{
+  return (cmd.scompress != STC_OFF );
+}
+
+int
+get_undefined(void)
+{
+  return (cmd.undef != STC_NOWARN);
+}
+
+int
+get_mxwarns(void)
+{  
+  return cmd.n_mxwarns[0];
+}
+
+int
+get_mxerrs(void)
+{
+  return cmd.n_mxerrs[0];
+}
+
+int
+get_mprint(void)
+{
+  return ( cmd.mprint != STC_OFF );
+}
+
+int
+get_printback(void)
+{
+  return (cmd.prtbck != STC_OFF );
+}
+
+int
+get_mxloops(void)
+{
+  return cmd.n_mxloops[0];
+}
+
+int
+get_nullline(void)
+{
+  return (cmd.null != STC_OFF );
+}
+
+int
+get_include(void)
+{
+ return (cmd.inc != STC_OFF );
+}
+
+unsigned char
+get_endcmd(void)
+{
+  return cmd.s_endcmd[0];
+}
+
+
+size_t
+get_max_workspace(void)
+{
+  return cmd.n_workspace[0];
+}
+
+double
+get_blanks(void)
+{
+  return set_blanks;
+}
+
+struct fmt_spec 
+get_format(void)
+{ 
+  return set_format;
+}
+
+/* CCA through CCE. */
+const struct set_cust_currency *
+get_cc(int i)
+{
+  return &set_cc[i];
+}
+
+void
+aux_show_warranty(void)
+{
+  msg(MM,lack_of_warranty);
+}
+
+void
+aux_show_copying(void)
+{
+  msg(MM,copyleft);
+}
+
+
+int
+get_viewlength(void)
+{
+  return set_viewlength;
+}
+
+int
+get_viewwidth(void)
+{
+  return set_viewwidth;
+}
+
+const char *
+get_pager(void)
+{
+  return set_pager;
+}
+
+gsl_rng *
+get_rng (void)
+{
+  if (rng == NULL)
+    set_rng (random_seed ());
+  return rng;
+}
+
+static void
+set_rng (unsigned long seed) 
+{
+  rng = gsl_rng_alloc (gsl_rng_mt19937);
+  if (rng == NULL)
+    out_of_memory ();
+  gsl_rng_set (rng, seed);
+}
+
+static unsigned long
+random_seed (void) 
+{
+  return time (0);
+}
+
+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;
+}
+
+/* Set the algorithm option for this command only */
+void 
+set_cmd_algorithm(int x)
+{
+  cmd_algorithm = x; 
+  algorithm = &cmd_algorithm;
+}
+
+/* Unset the algorithm option for this command */
+void
+unset_cmd_algorithm(void)
+{
+  algorithm = &global_algorithm;
+}
+
+/* Return the current algorithm setting */
 int
-cmd_gset (void)
+get_algorithm(void)
 {
-  /* FIXME */
-  return CMD_FAILURE;
+  return *algorithm;
 }
 
+/* Set the syntax option */
+void 
+set_syntax(int x)
+{
+  syntax = x;
+}
+
+/* Get the current syntax setting */
+int
+get_syntax(void)
+{
+  return syntax;
+}
+
+
 /*
    Local Variables:
    mode: c