Rewrite expression code.
[pspp-builds.git] / src / set.q
index 8d9afd61cf455776a12992a7ae2327d9d96e6cc2..c7d22771ac35c2cac07cbe243940b3571a3fb250 100644 (file)
--- a/src/set.q
+++ b/src/set.q
@@ -20,7 +20,7 @@
 /*
    Categories of SET subcommands:
 
-   data input: BLANKS, DECIMAL, FORMAT.
+   data input: BLANKS, DECIMAL, FORMAT, EPOCH.
    
    program input: ENDCMD, NULLINE.
    
@@ -64,6 +64,7 @@
 #include <stdio.h>
 #include <errno.h>
 #include <stdlib.h>
+#include <time.h>
 #include "alloc.h"
 #include "command.h"
 #include "lexer.h"
@@ -74,7 +75,6 @@
 #include "var.h"
 #include "format.h"
 #include "copyleft.h"
-#include "random.h"
 
 #include "signal.h"
 
@@ -93,6 +93,8 @@ 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];
@@ -106,8 +108,7 @@ static int set_listing=1;
 static char *set_pager=0;
 #endif /* !USE_INTERNAL_PAGER */
 
-static unsigned long set_seed;
-static int seed_flag=0;
+static gsl_rng *rng;
 
 static int long_view=0;
 int set_testing_mode=0;
@@ -122,6 +123,9 @@ 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;
@@ -145,6 +149,7 @@ static int set_ccx (const char *cc_string, struct set_cust_currency * cc,
      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;
@@ -158,7 +163,7 @@ static int set_ccx (const char *cc_string, struct set_cust_currency * cc,
      listing=custom;
      log=custom;
      lowres=lores:auto/on/off;
-     lpi=integer "x>0" "% must be greater than 0";
+     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;
@@ -234,6 +239,13 @@ 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)
 {
@@ -301,7 +313,6 @@ aux_stc_custom_results(struct cmd_set *cmd UNUSED)
 static int
 aux_stc_custom_seed(struct cmd_set *cmd UNUSED)
 {
-  msg(MM, "%ld",set_seed);
   return 0;
 }
 
@@ -595,12 +606,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;
@@ -631,6 +642,34 @@ 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_epoch (struct cmd_set *cmd UNUSED) 
+{
+  lex_match ('=');
+  if (lex_match_id ("AUTOMATIC"))
+    set_epoch = -1;
+  else if (lex_integer_p ()) 
+    {
+      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)
 {
@@ -704,15 +743,14 @@ stc_custom_seed (struct cmd_set *cmd UNUSED)
 {
   lex_match ('=');
   if (lex_match_id ("RANDOM"))
-    set_seed = random_seed();
+    set_rng (random_seed ());
   else
     {
       if (!lex_force_num ())
        return 0;
-      set_seed = tokval;
+      set_rng (tokval);
       lex_get ();
     }
-  seed_flag = 1;
 
   return 1;
 }
@@ -776,7 +814,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;
@@ -1051,6 +1089,22 @@ set_viewport(int sig_num UNUSED)
 
 /* 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)
 {
@@ -1063,8 +1117,8 @@ init_settings(void)
   cmd.safe = STC_OFF;
 
   cmd.dec = STC_DOT;
-  cmd.n_cpi = 6;
-  cmd.n_lpi = 10;
+  cmd.n_cpi[0] = 6;
+  cmd.n_lpi[0] = 10;
   cmd.echo = STC_OFF;
   cmd.more = STC_ON;
   cmd.headers = STC_YES;
@@ -1080,18 +1134,26 @@ init_settings(void)
   set_journal = xstrdup ("pspp.jnl");
   set_journaling = 1;
 
-  cmd.n_mxwarns = 100;
-  cmd.n_mxerrs = 100;
-  cmd.n_mxloops = 1;
-  cmd.n_workspace = 4L * 1024 * 1024;
+  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
   {
-    char *pager;
+    const char *pager = getenv ("STAT_PAGER");
 
-    pager = getenv ("STAT_PAGER");
-    if (!pager)  set_pager = getenv ("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);
@@ -1155,6 +1217,21 @@ 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)
@@ -1211,13 +1288,13 @@ get_undefined(void)
 int
 get_mxwarns(void)
 {  
-  return cmd.n_mxwarns;
+  return cmd.n_mxwarns[0];
 }
 
 int
 get_mxerrs(void)
 {
-  return cmd.n_mxerrs;
+  return cmd.n_mxerrs[0];
 }
 
 int
@@ -1235,7 +1312,7 @@ get_printback(void)
 int
 get_mxloops(void)
 {
-  return cmd.n_mxloops;
+  return cmd.n_mxloops[0];
 }
 
 int
@@ -1260,7 +1337,7 @@ get_endcmd(void)
 size_t
 get_max_workspace(void)
 {
-  return cmd.n_workspace;
+  return cmd.n_workspace[0];
 }
 
 double
@@ -1313,26 +1390,28 @@ get_pager(void)
   return set_pager;
 }
 
-/* Return 1 if the seed has been set since the last time this function
-   was called.
-   Fill the value pointed to by seed with the seed .
-*/
-int
-seed_is_set(unsigned long *seed)
+gsl_rng *
+get_rng (void)
 {
-  int result = 0;
-
-  *seed = set_seed ;
-
-  if ( seed_flag ) 
-    result = 1;
-  
-  seed_flag = 0;
+  if (rng == NULL)
+    set_rng (random_seed ());
+  return rng;
+}
 
-  return result;
-    
+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;