t-test-parser: Force values to be specified with a string vars on GROUPS.
[pspp] / src / language / stats / autorecode.c
index 7c1b766750fb4319218c34a7ff8a30f47e9cc6fe..aabef142e10731a4b299b5917872485e661a7014 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2009, 2010, 2012, 2013 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2009, 2010, 2012, 2013, 2014 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
@@ -16,6 +16,7 @@
 
 #include <config.h>
 
+#include <float.h>
 #include <stdlib.h>
 
 #include "data/case.h"
@@ -139,7 +140,6 @@ cmd_autorecode (struct lexer *lexer, struct dataset *ds)
   struct casereader *input;
   struct ccase *c;
 
-  size_t i;
   bool ok;
 
   /* Create procedure. */
@@ -152,6 +152,7 @@ cmd_autorecode (struct lexer *lexer, struct dataset *ds)
   if (!parse_variables_const (lexer, dict, &src_vars, &n_srcs,
                               PV_NO_DUPLICATE | PV_NO_SCRATCH))
     goto error;
+  lex_match (lexer, T_SLASH);
   if (!lex_force_match_id (lexer, "INTO"))
     goto error;
   lex_match (lexer, T_EQUALS);
@@ -166,7 +167,7 @@ cmd_autorecode (struct lexer *lexer, struct dataset *ds)
 
       goto error;
     }
-  for (i = 0; i < n_dsts; i++)
+  for (size_t i = 0; i < n_dsts; i++)
     {
       const char *name = dst_names[i];
 
@@ -205,10 +206,16 @@ cmd_autorecode (struct lexer *lexer, struct dataset *ds)
              arc->blank_valid = false;
            }
          else
-           goto error;
+            {
+              lex_error_expecting (lexer, "VALID", "MISSING");
+              goto error;
+            }
        }
       else
-       goto error;
+        {
+          lex_error_expecting (lexer, "DESCENDING", "PRINT", "GROUP", "BLANK");
+          goto error;
+        }
     }
 
   if (lex_token (lexer) != T_ENDCMD)
@@ -221,7 +228,7 @@ cmd_autorecode (struct lexer *lexer, struct dataset *ds)
   arc->n_specs = n_dsts;
 
 
-  for (i = 0; i < n_dsts; i++)
+  for (size_t i = 0; i < n_dsts; i++)
     {
       struct arc_spec *spec = &arc->specs[i];
 
@@ -245,7 +252,7 @@ cmd_autorecode (struct lexer *lexer, struct dataset *ds)
   /* Execute procedure. */
   input = proc_open (ds);
   for (; (c = casereader_read (input)) != NULL; case_unref (c))
-    for (i = 0; i < arc->n_specs; i++)
+    for (size_t i = 0; i < arc->n_specs; i++)
       {
         struct arc_spec *spec = &arc->specs[i];
         int width = spec->width;
@@ -255,7 +262,7 @@ cmd_autorecode (struct lexer *lexer, struct dataset *ds)
 
         item = find_arc_item (spec, value, hash);
         if ( (item == NULL)
-            &&  
+            &&
             ( arc->blank_valid
                || val_type_from_width (spec->width) == VAL_NUMERIC
                || ! value_is_blank (value, width, dict))
@@ -275,7 +282,7 @@ cmd_autorecode (struct lexer *lexer, struct dataset *ds)
   dict = dataset_dict (ds);
 
   /* Create transformation. */
-  for (i = 0; i < arc->n_specs; i++)
+  for (size_t i = 0; i < arc->n_specs; i++)
     {
       struct arc_spec *spec = &arc->specs[i];
       struct arc_item **items;
@@ -310,7 +317,7 @@ cmd_autorecode (struct lexer *lexer, struct dataset *ds)
          value_init (&to_val, 0);
 
          items[j]->to = direction == ASCENDING ? j + 1 : n_items - j;
-         
+
          to_val.f = items[j]->to;
 
          /* Add value labels to the destination variable which indicate
@@ -323,8 +330,8 @@ cmd_autorecode (struct lexer *lexer, struct dataset *ds)
                                              str, src_width);
            }
          else
-           recoded_value = c_xasprintf ("%g", from->f);
-         
+           recoded_value = c_xasprintf ("%.*g", DBL_DIG + 1, from->f);
+
          /* Remove trailing whitespace */
           len = strlen (recoded_value);
           while (len > 0 && recoded_value[len - 1] == ' ')
@@ -340,7 +347,7 @@ cmd_autorecode (struct lexer *lexer, struct dataset *ds)
     }
   add_transformation (ds, autorecode_trns_proc, autorecode_trns_free, arc);
 
-  for (i = 0; i < n_dsts; i++)
+  for (size_t i = 0; i < n_dsts; i++)
     free (dst_names[i]);
   free (dst_names);
   free (src_vars);
@@ -348,7 +355,7 @@ cmd_autorecode (struct lexer *lexer, struct dataset *ds)
   return ok ? CMD_SUCCESS : CMD_CASCADING_FAILURE;
 
 error:
-  for (i = 0; i < n_dsts; i++)
+  for (size_t i = 0; i < n_dsts; i++)
     free (dst_names[i]);
   free (dst_names);
   free (src_vars);
@@ -361,9 +368,7 @@ arc_free (struct autorecode_pgm *arc)
 {
   if (arc != NULL)
     {
-      size_t i;
-
-      for (i = 0; i < arc->n_specs; i++)
+      for (size_t i = 0; i < arc->n_specs; i++)
         {
           struct arc_spec *spec = &arc->specs[i];
           struct arc_item *item, *next;
@@ -377,10 +382,10 @@ arc_free (struct autorecode_pgm *arc)
            }
         }
 
-      for (i = 0; i < arc->n_specs; i++)
+      for (size_t i = 0; i < arc->n_specs; i++)
        {
          struct arc_spec *spec = &arc->specs[i];
-         
+
          if (--spec->items->refcnt == 0)
            {
              hmap_destroy (&spec->items->ht);
@@ -393,7 +398,7 @@ arc_free (struct autorecode_pgm *arc)
          hmap_destroy (&arc->global_items->ht);
          free (arc->global_items);
        }
-      
+
       free (arc->specs);
       free (arc);
     }
@@ -437,10 +442,9 @@ autorecode_trns_proc (void *arc_, struct ccase **c,
                       casenumber case_idx UNUSED)
 {
   struct autorecode_pgm *arc = arc_;
-  size_t i;
 
   *c = case_unshare (*c);
-  for (i = 0; i < arc->n_specs; i++)
+  for (size_t i = 0; i < arc->n_specs; i++)
     {
       const struct arc_spec *spec = &arc->specs[i];
       const union value *value = case_data_idx (*c, spec->src_idx);