From 8e7e8e7e1c3b098700428f2b75b1b4080ab9faf0 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Sat, 6 Nov 2021 20:40:42 -0700 Subject: [PATCH] MATRIX GET works with the active file. --- src/language/stats/matrix.c | 59 +++++++++++++++++++++++----------- tests/language/stats/matrix.at | 30 +++++++++-------- 2 files changed, 57 insertions(+), 32 deletions(-) diff --git a/src/language/stats/matrix.c b/src/language/stats/matrix.c index bcae199717..5542c55c67 100644 --- a/src/language/stats/matrix.c +++ b/src/language/stats/matrix.c @@ -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); +} 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), diff --git a/tests/language/stats/matrix.at b/tests/language/stats/matrix.at index f5e76d0b0a..aed715319a 100644 --- a/tests/language/stats/matrix.at +++ b/tests/language/stats/matrix.at @@ -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 -- 2.30.2