struct get_command
{
struct matrix_lvalue *dst;
+ 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. */
{
ss_ltrim (&line, ss_cstr (" ,"));
if (!ss_is_empty (line))
- msg (SW, _("Trailing garbage on line \"%.*s\""),
- (int) line.length, line.string);
+ {
+ /* XXX */
+ msg (SW, _("Trailing garbage on line \"%.*s\""),
+ (int) line.length, line.string);
+ }
}
}
}
*cmd = (struct matrix_cmd) {
.type = MCMD_GET,
.get = {
+ .dataset = s->dataset,
.user = { .treatment = MGET_ERROR },
.system = { .treatment = MGET_ERROR },
}
{
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);
- 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"))
{
- 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;
{
lex_match (s->lexer, T_EQUALS);
- struct dictionary *dict = NULL;
- if (!get->file)
- {
- dict = 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"))
{
{
lex_match (s->lexer, T_EQUALS);
if (lex_match_id (s->lexer, "OMIT"))
- get->user.treatment = MGET_OMIT;
+ get->system.treatment = MGET_OMIT;
else if (lex_is_number (s->lexer))
{
- get->user.treatment = MGET_RECODE;
- get->user.substitute = lex_number (s->lexer);
+ get->system.treatment = MGET_RECODE;
+ get->system.substitute = lex_number (s->lexer);
lex_get (s->lexer);
}
else
goto error;
}
}
+
+ if (get->user.treatment != MGET_ACCEPT)
+ get->system.treatment = MGET_ERROR;
+
return cmd;
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);
+ 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);
- 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;
- }
- 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."),
var_get_name (var));
- dict_unref (dict);
free (vars);
return;
}
- vars[n_vars++] = var;
+ vars[i] = var;
}
}
+ if (get->names)
+ {
+ gsl_matrix *names = gsl_matrix_alloc (n_vars, 1);
+ for (size_t i = 0; i < n_vars; i++)
+ {
+ char s[sizeof (double)];
+ double f;
+ buf_copy_str_rpad (s, sizeof s, var_get_name (vars[i]), ' ');
+ memcpy (&f, s, sizeof f);
+ gsl_matrix_set (names, i, 0, f);
+ }
+
+ gsl_matrix_free (get->names->value);
+ get->names->value = names;
+ }
+
size_t n_rows = 0;
gsl_matrix *m = gsl_matrix_alloc (4, n_vars);
long long int casenum = 1;
if (keep)
n_rows++;
}
- casereader_destroy (reader);
if (!error)
{
m->size1 = n_rows;
}
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
+ {
+ 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));
+ }
+
+ 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)
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:
return CMD_FAILURE;
struct matrix_state state = {
+ .dataset = ds,
.session = dataset_session (ds),
.lexer = lexer,
.vars = HMAP_INITIALIZER (state.vars),