/* PSPP - a program for statistical analysis.
- Copyright (C) 1997-9, 2000, 2009, 2010, 2011 Free Software Foundation, Inc.
+ Copyright (C) 1997-9, 2000, 2009, 2010, 2011, 2012, 2013 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
#include "data/casereader-provider.h"
#include "data/dataset.h"
#include "data/dictionary.h"
+#include "data/session.h"
#include "data/transformations.h"
#include "data/variable.h"
#include "language/command.h"
#include "gettext.h"
#define _(msgid) gettext (msgid)
-/* Private result codes for use within INPUT PROGRAM. */
-enum cmd_result_extensions
- {
- CMD_END_CASE = CMD_PRIVATE_FIRST
- };
-
/* Indicates how a `union value' should be initialized. */
struct input_program_pgm
{
+ struct session *session;
+ struct dataset *ds;
struct trns_chain *trns_chain;
enum trns_result restart;
{
struct input_program_pgm *inp;
bool saw_END_CASE = false;
+ bool saw_END_FILE = false;
+ bool saw_DATA_LIST = false;
- dataset_clear (ds);
if (!lex_match (lexer, T_ENDCMD))
return lex_end_of_command (lexer);
inp = xmalloc (sizeof *inp);
+ inp->session = session_create (dataset_session (ds));
+ inp->ds = dataset_create (inp->session, "INPUT PROGRAM");
inp->trns_chain = NULL;
inp->init = NULL;
inp->proto = NULL;
{
enum cmd_result result;
- result = cmd_parse_in_state (lexer, ds, CMD_STATE_INPUT_PROGRAM);
- if (result == CMD_END_CASE)
+ result = cmd_parse_in_state (lexer, inp->ds, CMD_STATE_INPUT_PROGRAM);
+ switch (result)
{
- emit_END_CASE (ds, inp);
+ case CMD_DATA_LIST:
+ saw_DATA_LIST = true;
+ break;
+
+ case CMD_END_CASE:
+ emit_END_CASE (inp->ds, inp);
saw_END_CASE = true;
- }
- else if (cmd_result_is_failure (result) && result != CMD_FAILURE)
- {
- if (result == CMD_EOF)
- msg (SE, _("Unexpected end-of-file within INPUT PROGRAM."));
- inside_input_program = false;
- dataset_clear (ds);
- destroy_input_program (inp);
- return result;
+ break;
+
+ case CMD_END_FILE:
+ saw_END_FILE = true;
+ break;
+
+ case CMD_FAILURE:
+ break;
+
+ default:
+ if (cmd_result_is_failure (result)
+ && lex_get_error_mode (lexer) != LEX_ERROR_TERMINAL)
+ {
+ if (result == CMD_EOF)
+ msg (SE, _("Unexpected end-of-file within INPUT PROGRAM."));
+ inside_input_program = false;
+ destroy_input_program (inp);
+ return result;
+ }
}
}
if (!saw_END_CASE)
- emit_END_CASE (ds, inp);
+ emit_END_CASE (inp->ds, inp);
inside_input_program = false;
- if (dict_get_next_value_idx (dataset_dict (ds)) == 0)
+ if (!saw_DATA_LIST && !saw_END_FILE)
+ {
+ msg (SE, _("Input program must contain DATA LIST or END FILE."));
+ destroy_input_program (inp);
+ return CMD_FAILURE;
+ }
+ if (dict_get_next_value_idx (dataset_dict (inp->ds)) == 0)
{
msg (SE, _("Input program did not create any variables."));
- dataset_clear (ds);
destroy_input_program (inp);
return CMD_FAILURE;
}
- inp->trns_chain = proc_capture_transformations (ds);
+ inp->trns_chain = proc_capture_transformations (inp->ds);
trns_chain_finalize (inp->trns_chain);
inp->restart = TRNS_CONTINUE;
/* Figure out how to initialize each input case. */
inp->init = caseinit_create ();
- caseinit_mark_for_init (inp->init, dataset_dict (ds));
- inp->proto = caseproto_ref (dict_get_proto (dataset_dict (ds)));
+ caseinit_mark_for_init (inp->init, dataset_dict (inp->ds));
+ inp->proto = caseproto_ref (dict_get_proto (dataset_dict (inp->ds)));
+ dataset_set_dict (ds, dict_clone (dataset_dict (inp->ds)));
dataset_set_source (
ds, casereader_create_sequential (NULL, inp->proto, CASENUMBER_MAX,
&input_program_casereader_class, inp));
{
if (pgm != NULL)
{
+ session_destroy (pgm->session);
trns_chain_destroy (pgm->trns_chain);
caseinit_destroy (pgm->init);
caseproto_unref (pgm->proto);
struct file_handle *fh; /* File to be re-read. */
struct expression *e; /* Expression for column to set. */
struct reread_trns *t; /* Created transformation. */
+ char *encoding = NULL;
fh = fh_get_default_handle ();
e = NULL;
if (e)
{
- msg (SE, _("%s subcommand may be given at most once."), "COLUMN");
- expr_free (e);
- return CMD_CASCADING_FAILURE;
+ lex_sbc_only_once ("COLUMN");
+ goto error;
}
e = expr_parse (lexer, ds, EXPR_NUMBER);
if (!e)
- return CMD_CASCADING_FAILURE;
+ goto error;
}
else if (lex_match_id (lexer, "FILE"))
{
lex_match (lexer, T_EQUALS);
fh_unref (fh);
- fh = fh_parse (lexer, FH_REF_FILE | FH_REF_INLINE);
+ fh = fh_parse (lexer, FH_REF_FILE | FH_REF_INLINE, NULL);
if (fh == NULL)
- {
- expr_free (e);
- return CMD_CASCADING_FAILURE;
- }
+ goto error;
+ }
+ else if (lex_match_id (lexer, "ENCODING"))
+ {
+ lex_match (lexer, T_EQUALS);
+ if (!lex_force_string (lexer))
+ goto error;
+
+ free (encoding);
+ encoding = ss_xstrdup (lex_tokss (lexer));
+
+ lex_get (lexer);
}
else
{
lex_error (lexer, NULL);
- expr_free (e);
- return CMD_CASCADING_FAILURE;
+ goto error;
}
}
t = xmalloc (sizeof *t);
- t->reader = dfm_open_reader (fh, lexer);
+ t->reader = dfm_open_reader (fh, lexer, encoding);
t->column = e;
add_transformation (ds, reread_trns_proc, reread_trns_free, t);
fh_unref (fh);
+ free (encoding);
return CMD_SUCCESS;
+
+error:
+ expr_free (e);
+ free (encoding);
+ return CMD_CASCADING_FAILURE;
}
/* Executes a REREAD transformation. */
add_transformation (ds, end_file_trns_proc, NULL, NULL);
- return CMD_SUCCESS;
+ return CMD_END_FILE;
}
/* Executes an END FILE transformation. */