GET is well tested.
[pspp] / src / language / stats / matrix.c
index 5542c55c67e0f20020455a633234a3e827be4983..5214ee3d8be73b5b1c088cbe64ea659cb770cf18 100644 (file)
@@ -3435,7 +3435,8 @@ struct matrix_cmd
             struct dataset *dataset;
             struct file_handle *file;
             char *encoding;
-            struct string_array variables;
+            struct var_syntax *vars;
+            size_t n_vars;
             struct matrix_var *names;
 
             /* Treatment of missing values. */
@@ -5370,11 +5371,6 @@ matrix_parse_get (struct matrix_state *s)
     {
       if (lex_match_id (s->lexer, "FILE"))
         {
-          if (get->variables.n)
-            {
-              lex_error (s->lexer, _("FILE must precede VARIABLES"));
-              goto error;
-            }
           lex_match (s->lexer, T_EQUALS);
 
           fh_unref (get->file);
@@ -5389,11 +5385,6 @@ matrix_parse_get (struct matrix_state *s)
         }
       else if (lex_match_id (s->lexer, "ENCODING"))
        {
-          if (get->variables.n)
-            {
-              lex_error (s->lexer, _("ENCODING must precede VARIABLES"));
-              goto error;
-            }
          lex_match (s->lexer, T_EQUALS);
          if (!lex_force_string (s->lexer))
            goto error;
@@ -5407,40 +5398,14 @@ matrix_parse_get (struct matrix_state *s)
         {
           lex_match (s->lexer, T_EQUALS);
 
-          struct dictionary *dict = NULL;
-          if (!get->file)
-            {
-              dict = dict_ref (dataset_dict (s->dataset));
-              if (dict_get_var_cnt (dict) == 0)
-                {
-                  lex_error (s->lexer, _("GET cannot read empty active file."));
-                  goto error;
-                }
-            }
-          else
-            {
-              struct casereader *reader = any_reader_open_and_decode (
-                get->file, get->encoding, &dict, NULL);
-              if (!reader)
-                goto error;
-              casereader_destroy (reader);
-            }
-
-          struct variable **vars;
-          size_t n_vars;
-          bool ok = parse_variables (s->lexer, dict, &vars, &n_vars,
-                                     PV_DUPLICATE | PV_NUMERIC | PV_NO_SCRATCH);
-          if (!ok)
+          if (get->n_vars)
             {
-              dict_unref (dict);
+              lex_sbc_only_once ("VARIABLES");
               goto error;
             }
 
-          string_array_clear (&get->variables);
-          for (size_t i = 0; i < n_vars; i++)
-            string_array_append (&get->variables, var_get_name (vars[i]));
-          free (vars);
-          dict_unref (dict);
+          if (!var_syntax_parse (s->lexer, &get->vars, &get->n_vars))
+            goto error;
         }
       else if (lex_match_id (s->lexer, "NAMES"))
         {
@@ -5513,38 +5478,22 @@ matrix_cmd_execute_get__ (struct get_command *get,
                           const struct dictionary *dict,
                           struct casereader *reader)
 {
-  const struct variable **vars = xnmalloc (
-    get->variables.n ? get->variables.n : dict_get_var_cnt (dict),
-    sizeof *vars);
+  struct variable **vars;
   size_t n_vars = 0;
 
-  if (get->variables.n)
+  if (get->n_vars)
     {
-      for (size_t i = 0; i < get->variables.n; i++)
-        {
-          const char *name = get->variables.strings[i];
-          const struct variable *var = dict_lookup_var (dict, name);
-          if (!var)
-            {
-              msg (SE, _("GET: Data file does not contain variable %s."),
-                   name);
-              free (vars);
-              return;
-            }
-          if (!var_is_numeric (var))
-            {
-              msg (SE, _("GET: Variable %s is not numeric."), name);
-              free (vars);
-              return;
-            }
-          vars[n_vars++] = var;
-        }
+      if (!var_syntax_evaluate (get->vars, get->n_vars, dict,
+                                &vars, &n_vars, PV_NUMERIC))
+        return;
     }
   else
     {
-      for (size_t i = 0; i < dict_get_var_cnt (dict); i++)
+      n_vars = dict_get_var_cnt (dict);
+      vars = xnmalloc (n_vars, sizeof *vars);
+      for (size_t i = 0; i < n_vars; i++)
         {
-          const struct variable *var = dict_get_var (dict, i);
+          struct variable *var = dict_get_var (dict, i);
           if (!var_is_numeric (var))
             {
               msg (SE, _("GET: Variable %s is not numeric."),
@@ -5552,7 +5501,7 @@ matrix_cmd_execute_get__ (struct get_command *get,
               free (vars);
               return;
             }
-          vars[n_vars++] = var;
+          vars[i] = var;
         }
     }
 
@@ -5654,6 +5603,11 @@ matrix_cmd_execute_get (struct get_command *get)
     }
   else
     {
+      if (dict_get_var_cnt (dataset_dict (get->dataset)) == 0)
+        {
+          msg (ME, _("GET cannot read empty active file."));
+          return;
+        }
       reader = proc_open (get->dataset);
       dict = dict_ref (dataset_dict (get->dataset));
     }
@@ -6694,7 +6648,7 @@ matrix_cmd_destroy (struct matrix_cmd *cmd)
       matrix_lvalue_destroy (cmd->get.dst);
       fh_unref (cmd->get.file);
       free (cmd->get.encoding);
-      string_array_destroy (&cmd->get.variables);
+      var_syntax_destroy (cmd->get.vars, cmd->get.n_vars);
       break;
 
     case MCMD_MSAVE: