MATRIX GET works with the active file.
authorBen Pfaff <blp@cs.stanford.edu>
Sun, 7 Nov 2021 03:40:42 +0000 (20:40 -0700)
committerBen Pfaff <blp@cs.stanford.edu>
Sun, 7 Nov 2021 03:40:42 +0000 (20:40 -0700)
src/language/stats/matrix.c
tests/language/stats/matrix.at

index bcae19971750704affa257ef127ca17693ed9b53..5542c55c67e0f20020455a633234a3e827be4983 100644 (file)
@@ -3432,6 +3432,7 @@ struct matrix_cmd
         struct get_command
           {
             struct matrix_lvalue *dst;
+            struct dataset *dataset;
             struct file_handle *file;
             char *encoding;
             struct string_array variables;
@@ -5354,6 +5355,7 @@ matrix_parse_get (struct matrix_state *s)
   *cmd = (struct matrix_cmd) {
     .type = MCMD_GET,
     .get = {
+      .dataset = s->dataset,
       .user = { .treatment = MGET_ERROR },
       .system = { .treatment = MGET_ERROR },
     }
@@ -5376,9 +5378,14 @@ matrix_parse_get (struct matrix_state *s)
           lex_match (s->lexer, T_EQUALS);
 
           fh_unref (get->file);
-          get->file = fh_parse (s->lexer, FH_REF_FILE, s->session);
-          if (!get->file)
-            goto error;
+          if (lex_match (s->lexer, T_ASTERISK))
+            get->file = NULL;
+          else
+            {
+              get->file = fh_parse (s->lexer, FH_REF_FILE, s->session);
+              if (!get->file)
+                goto error;
+            }
         }
       else if (lex_match_id (s->lexer, "ENCODING"))
        {
@@ -5403,7 +5410,7 @@ matrix_parse_get (struct matrix_state *s)
           struct dictionary *dict = NULL;
           if (!get->file)
             {
-              dict = dataset_dict (s->dataset);
+              dict = dict_ref (dataset_dict (s->dataset));
               if (dict_get_var_cnt (dict) == 0)
                 {
                   lex_error (s->lexer, _("GET cannot read empty active file."));
@@ -5502,16 +5509,10 @@ error:
 }
 
 static void
-matrix_cmd_execute_get (struct get_command *get)
+matrix_cmd_execute_get__ (struct get_command *get,
+                          const struct dictionary *dict,
+                          struct casereader *reader)
 {
-  assert (get->file);           /* XXX */
-
-  struct dictionary *dict;
-  struct casereader *reader = any_reader_open_and_decode (
-    get->file, get->encoding, &dict, NULL);
-  if (!reader)
-    return;
-
   const struct variable **vars = xnmalloc (
     get->variables.n ? get->variables.n : dict_get_var_cnt (dict),
     sizeof *vars);
@@ -5527,14 +5528,12 @@ matrix_cmd_execute_get (struct get_command *get)
             {
               msg (SE, _("GET: Data file does not contain variable %s."),
                    name);
-              dict_unref (dict);
               free (vars);
               return;
             }
           if (!var_is_numeric (var))
             {
               msg (SE, _("GET: Variable %s is not numeric."), name);
-              dict_unref (dict);
               free (vars);
               return;
             }
@@ -5550,7 +5549,6 @@ matrix_cmd_execute_get (struct get_command *get)
             {
               msg (SE, _("GET: Variable %s is not numeric."),
                    var_get_name (var));
-              dict_unref (dict);
               free (vars);
               return;
             }
@@ -5632,7 +5630,6 @@ matrix_cmd_execute_get (struct get_command *get)
       if (keep)
         n_rows++;
     }
-  casereader_destroy (reader);
   if (!error)
     {
       m->size1 = n_rows;
@@ -5640,9 +5637,34 @@ matrix_cmd_execute_get (struct get_command *get)
     }
   else
     gsl_matrix_free (m);
-  dict_unref (dict);
   free (vars);
 }
+
+static void
+matrix_cmd_execute_get (struct get_command *get)
+{
+  struct dictionary *dict;
+  struct casereader *reader;
+  if (get->file)
+    {
+       reader = any_reader_open_and_decode (get->file, get->encoding,
+                                            &dict, NULL);
+       if (!reader)
+         return;
+    }
+  else
+    {
+      reader = proc_open (get->dataset);
+      dict = dict_ref (dataset_dict (get->dataset));
+    }
+
+  matrix_cmd_execute_get__ (get, dict, reader);
+
+  dict_unref (dict);
+  casereader_destroy (reader);
+  if (!get->file)
+    proc_commit (get->dataset);
+}
 \f
 static const char *
 match_rowtype (struct lexer *lexer)
@@ -6773,6 +6795,7 @@ cmd_matrix (struct lexer *lexer, struct dataset *ds)
     return CMD_FAILURE;
 
   struct matrix_state state = {
+    .dataset = ds,
     .session = dataset_session (ds),
     .lexer = lexer,
     .vars = HMAP_INITIALIZER (state.vars),
index f5e76d0b0a88a29c872d0864ead4eeea17b9760b..aed715319a779121a3e7bbf2f7b5d4f6ac157723 100644 (file)
@@ -2896,38 +2896,40 @@ BEGIN DATA.
 4 5 6
 7 8 .
 END DATA.
-SAVE OUTFILE='matrix.sav'.
 
 MATRIX.
-GET x0 /FILE='matrix.sav' /NAMES=names0.
+GET x0 /NAMES=names0.
 PRINT x0.
 PRINT names0/FORMAT=A8.
 END MATRIX.
 
 MATRIX.
-GET x1 /FILE='matrix.sav' /VARIABLES=a b c /NAMES=names1 /MISSING=OMIT.
+GET x1 /VARIABLES=a b c /NAMES=names1 /MISSING=OMIT.
 PRINT x1.
 PRINT names1/FORMAT=A8.
 END MATRIX.
 
 MATRIX.
-GET x2 /FILE='matrix.sav' /VARIABLES=a b /NAMES=names2 /MISSING=OMIT.
+GET x2 /VARIABLES=a b /NAMES=names2 /MISSING=OMIT.
 PRINT x2.
 PRINT names2/FORMAT=A8.
 END MATRIX.
 
 MATRIX.
-GET x3 /FILE='matrix.sav' /VARIABLES=a b c /NAMES=names3 /MISSING=5.
+GET x3 /FILE=* /VARIABLES=a b c /NAMES=names3 /MISSING=5.
 PRINT x3.
 PRINT names3/FORMAT=A8.
 END MATRIX.
 
 MATRIX.
-GET x4 /FILE='matrix.sav' /VARIABLES=a b /NAMES=names4 /MISSING=5.
+GET x4 /FILE=* /VARIABLES=a b /NAMES=names4 /MISSING=5.
 PRINT x4.
 PRINT names4/FORMAT=A8.
 END MATRIX.
 
+SAVE OUTFILE='matrix.sav'.
+NEW FILE.
+
 MATRIX.
 GET x5 /FILE='matrix.sav' /VARIABLES=a b c /NAMES=names5 /MISSING=ACCEPT.
 PRINT x5.
@@ -2947,19 +2949,19 @@ PRINT names7/FORMAT=A8.
 END MATRIX.
 ])
 AT_CHECK([pspp matrix.sps], [1], [dnl
-matrix.sps:12: error: MATRIX: GET: Variable a in case 2 has user-missing value
+matrix.sps:11: error: MATRIX: GET: Variable a in case 2 has user-missing value
 1.
 
-matrix.sps:13: error: MATRIX: Uninitialized variable x0 used in expression.
+matrix.sps:12: error: MATRIX: Uninitialized variable x0 used in expression.
 
 names0
  a
  b
  c
 
-matrix.sps:18: error: MATRIX: GET: Variable c in case 4 is system-missing.
+matrix.sps:17: error: MATRIX: GET: Variable c in case 4 is system-missing.
 
-matrix.sps:19: error: MATRIX: Uninitialized variable x1 used in expression.
+matrix.sps:18: error: MATRIX: Uninitialized variable x1 used in expression.
 
 names1
  a
@@ -2974,9 +2976,9 @@ names2
  a
  b
 
-matrix.sps:30: error: MATRIX: GET: Variable c in case 4 is system-missing.
+matrix.sps:29: error: MATRIX: GET: Variable c in case 4 is system-missing.
 
-matrix.sps:31: error: MATRIX: Uninitialized variable x3 used in expression.
+matrix.sps:30: error: MATRIX: Uninitialized variable x3 used in expression.
 
 names3
  a
@@ -2993,9 +2995,9 @@ names4
  a
  b
 
-matrix.sps:42: error: MATRIX: GET: Variable c in case 4 is system-missing.
+matrix.sps:44: error: MATRIX: GET: Variable c in case 4 is system-missing.
 
-matrix.sps:43: error: MATRIX: Uninitialized variable x5 used in expression.
+matrix.sps:45: error: MATRIX: Uninitialized variable x5 used in expression.
 
 names5
  a