Include a dissuader for odd numbered minor releases
[pspp] / src / language / utilities / set.q
index 38a6589b8e4c10aa23d4ccd6825c914b9f58097b..126868dbdb52f107844200b75a9e41f8c8ff9507 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2006, 2009, 2010, 2011 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2006, 2009, 2010, 2011, 2012, 2013, 2014, 2015 Free Software Foundation, Inc.
 
    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
 
 #include <config.h>
 
+#include <float.h>
 #include <stdio.h>
 #include <errno.h>
 #include <stdlib.h>
 #include <time.h>
 #include <unistd.h>
 
+#include "gl/vasnprintf.h"
+
+#include "data/casereader.h"
 #include "data/data-in.h"
 #include "data/data-out.h"
 #include "data/dataset.h"
@@ -76,6 +80,7 @@ int tgetnum (const char *);
      epoch=custom;
      errors=custom;
      format=custom;
+     fuzzbits=integer;
      headers=headers:no/yes/blank;
      highres=hires:on/off;
      histogram=string;
@@ -105,6 +110,7 @@ int tgetnum (const char *);
      scripttab=string;
      seed=custom;
      tnumbers=custom;
+     tvars=custom;
      tb1=string;
      tbfonts=string;
      undefined=undef:warn/nowarn;
@@ -148,6 +154,14 @@ cmd_set (struct lexer *lexer, struct dataset *ds)
 
   if (cmd.sbc_decimal)
     settings_set_decimal_char (cmd.dec == STC_DOT ? '.' : ',');
+  if (cmd.sbc_fuzzbits)
+    {
+      int fuzzbits = cmd.n_fuzzbits[0];
+      if (fuzzbits >= 0 && fuzzbits <= 20)
+        settings_set_fuzzbits (fuzzbits);
+      else
+        msg (SE, _("%s must be between 0 and 20."), "FUZZBITS");
+    }
 
   if (cmd.sbc_include)
     settings_set_include (cmd.inc == STC_ON);
@@ -189,9 +203,9 @@ cmd_set (struct lexer *lexer, struct dataset *ds)
   if (cmd.sbc_workspace)
     {
       if ( cmd.n_workspace[0] < 1024 && ! settings_get_testing_mode ())
-       msg (SE, _("WORKSPACE must be at least 1MB"));
+       msg (SE, _("%s must be at least 1MB"), "WORKSPACE");
       else if (cmd.n_workspace[0] <= 0)
-       msg (SE, _("WORKSPACE must be positive"));
+       msg (SE, _("%s must be positive"), "WORKSPACE");
       else
        settings_set_workspace (cmd.n_workspace[0] * 1024L);
     }
@@ -354,6 +368,35 @@ stc_custom_tnumbers (struct lexer *lexer,
 }
 
 
+static int
+stc_custom_tvars (struct lexer *lexer,
+                  struct dataset *ds UNUSED,
+                  struct cmd_set *cmd UNUSED, void *aux UNUSED)
+{
+  lex_match (lexer, T_EQUALS);
+
+  if (lex_match_id (lexer, "NAMES"))
+    {
+      settings_set_var_style (SETTINGS_VAR_STYLE_NAMES);
+    }
+  else if (lex_match_id (lexer, "LABELS"))
+    {
+      settings_set_var_style (SETTINGS_VAR_STYLE_LABELS);
+    }
+  else if (lex_match_id (lexer, "BOTH"))
+    {
+      settings_set_var_style (SETTINGS_VAR_STYLE_BOTH);
+    }
+  else
+    {
+      lex_error_expecting (lexer, "NAMES", "LABELS", "BOTH", NULL_SENTINEL);
+      return 0;
+    }
+
+  return 1;
+}
+
+
 /* Parses the EPOCH subcommand, which controls the epoch used for
    parsing 2-digit years. */
 static int
@@ -370,14 +413,14 @@ stc_custom_epoch (struct lexer *lexer,
       lex_get (lexer);
       if (new_epoch < 1500)
         {
-          msg (SE, _("EPOCH must be 1500 or later."));
+          msg (SE, _("%s must be 1500 or later."), "EPOCH");
           return 0;
         }
       settings_set_epoch (new_epoch);
     }
   else
     {
-      lex_error (lexer, _("expecting AUTOMATIC or year"));
+      lex_error (lexer, _("expecting %s or year"), "AUTOMATIC");
       return 0;
     }
 
@@ -405,7 +448,7 @@ stc_custom_length (struct lexer *lexer, struct dataset *ds UNUSED, struct cmd_se
        return 0;
       if (lex_integer (lexer) < 1)
        {
-         msg (SE, _("LENGTH must be at least 1."));
+         msg (SE, _("%s must be at least %d."), "LENGTH", 1);
          return 0;
        }
       page_length = lex_integer (lexer);
@@ -502,7 +545,7 @@ stc_custom_width (struct lexer *lexer, struct dataset *ds UNUSED, struct cmd_set
        return 0;
       if (lex_integer (lexer) < 40)
        {
-         msg (SE, _("WIDTH must be at least 40."));
+         msg (SE, _("%s must be at least %d."), "WIDTH", 40);
          return 0;
        }
       settings_set_viewwidth (lex_integer (lexer));
@@ -529,8 +572,9 @@ stc_custom_format (struct lexer *lexer, struct dataset *ds UNUSED, struct cmd_se
   if (fmt_is_string (fmt.type))
     {
       char str[FMT_STRING_LEN_MAX + 1];
-      msg (SE, _("FORMAT requires numeric output format as an argument.  "
+      msg (SE, _("%s requires numeric output format as an argument.  "
                 "Specified format %s is of type string."),
+          "FORMAT",
           fmt_to_string (&fmt, str));
       return 0;
     }
@@ -591,7 +635,7 @@ show_blanks (const struct dataset *ds UNUSED)
 {
   return (settings_get_blanks () == SYSMIS
           ? xstrdup ("SYSMIS")
-          : xasprintf ("%g", settings_get_blanks ()));
+          : xasprintf ("%.*g", DBL_DIG + 1, settings_get_blanks ()));
 }
 
 static void
@@ -675,6 +719,20 @@ show_format (const struct dataset *ds UNUSED)
   return xstrdup (fmt_to_string (settings_get_format (), str));
 }
 
+static char *
+show_fuzzbits (const struct dataset *ds UNUSED)
+{
+  return xasprintf ("%d", settings_get_fuzzbits ());
+}
+
+static char *
+show_journal (const struct dataset *ds UNUSED)
+{
+  return (journal_is_enabled ()
+          ? xasprintf ("\"%s\"", journal_get_file_name ())
+          : xstrdup ("disabled"));
+}
+
 static char *
 show_length (const struct dataset *ds UNUSED)
 {
@@ -831,6 +889,13 @@ show_width (const struct dataset *ds UNUSED)
   return xasprintf ("%d", settings_get_viewwidth ());
 }
 
+static char *
+show_workspace (const struct dataset *ds UNUSED)
+{
+  size_t ws = settings_get_workspace () / 1024L;
+  return xasprintf ("%zu", ws);
+}
+
 static char *
 show_current_directory (const struct dataset *ds UNUSED)
 {
@@ -857,7 +922,7 @@ show_tempdir (const struct dataset *ds UNUSED)
 static char *
 show_version (const struct dataset *ds UNUSED)
 {
-  return strdup (version);
+  return strdup (announced_version);
 }
 
 static char *
@@ -866,6 +931,23 @@ show_system (const struct dataset *ds UNUSED)
   return strdup (host_system);
 }
 
+static char *
+show_n (const struct dataset *ds)
+{
+  casenumber n;
+  size_t l;
+
+  const struct casereader *reader = dataset_source (ds);
+
+  if (reader == NULL)
+    return strdup (_("Unknown"));
+
+  n =  casereader_count_cases (reader);
+
+  return  asnprintf (NULL, &l, "%ld", n);
+}
+
+
 struct show_sbc
   {
     const char *name;
@@ -885,12 +967,15 @@ const struct show_sbc show_table[] =
     {"ENVIRONMENT", show_system},
     {"ERRORS", show_errors},
     {"FORMAT", show_format},
+    {"FUZZBITS", show_fuzzbits},
+    {"JOURNAL", show_journal},
     {"LENGTH", show_length},
     {"LOCALE", show_locale},
     {"MESSAGES", show_messages},
     {"MXERRS", show_mxerrs},
     {"MXLOOPS", show_mxloops},
     {"MXWARNS", show_mxwarns},
+    {"N", show_n},
     {"PRINTBACk", show_printback},
     {"RESULTS", show_results},
     {"RIB", show_rib},
@@ -903,6 +988,7 @@ const struct show_sbc show_table[] =
     {"WIB", show_wib},
     {"WRB", show_wrb},
     {"WIDTH", show_width},
+    {"WORKSPACE", show_workspace},
   };
 
 static void
@@ -1013,8 +1099,9 @@ cmd_preserve (struct lexer *lexer UNUSED, struct dataset *ds UNUSED)
     }
   else
     {
-      msg (SE, _("Too many PRESERVE commands without a RESTORE: at most "
+      msg (SE, _("Too many %s commands without a %s: at most "
                  "%d levels of saved settings are allowed."),
+          "PRESERVE", "RESTORE",
            MAX_SAVED_SETTINGS);
       return CMD_CASCADING_FAILURE;
     }
@@ -1032,7 +1119,7 @@ cmd_restore (struct lexer *lexer UNUSED, struct dataset *ds UNUSED)
     }
   else
     {
-      msg (SE, _("RESTORE without matching PRESERVE."));
+      msg (SE, _("%s without matching %s."), "RESTORE", "PRESERVE");
       return CMD_FAILURE;
     }
 }