/* PSPP - a program for statistical analysis.
- Copyright (C) 2010, 2011, 2012 Free Software Foundation, Inc.
+ Copyright (C) 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
struct session
{
+ struct session *parent;
struct hmapx datasets;
struct dataset *active;
char *syntax_encoding; /* Default encoding for syntax files. */
const char *name);
struct session *
-session_create (void)
+session_create (struct session *parent)
{
struct session *s;
s = xmalloc (sizeof *s);
+ s->parent = parent;
hmapx_init (&s->datasets);
s->active = NULL;
- s->syntax_encoding = xstrdup ("Auto");
+ s->syntax_encoding = xstrdup (s->parent != NULL
+ ? s->parent->syntax_encoding : "Auto");
s->n_dataset_names = 0;
return s;
}
session_lookup_dataset (const struct session *s, const char *name)
{
struct hmapx_node *node = session_lookup_dataset__ (s, name);
- return node != NULL ? node->data : NULL;
+ return (node != NULL ? node->data
+ : s->parent != NULL ? session_lookup_dataset (s->parent, name)
+ : NULL);
}
struct dataset *
/* PSPP - a program for statistical analysis.
- Copyright (C) 2010, 2011, 2012 Free Software Foundation, Inc.
+ Copyright (C) 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
struct dataset;
-struct session *session_create (void);
+struct session *session_create (struct session *parent);
void session_destroy (struct session *);
struct dataset *session_active_dataset (struct session *);
#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"
/* 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;
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);
+ result = cmd_parse_in_state (lexer, inp->ds, CMD_STATE_INPUT_PROGRAM);
switch (result)
{
case CMD_DATA_LIST:
break;
case CMD_END_CASE:
- emit_END_CASE (ds, inp);
+ emit_END_CASE (inp->ds, inp);
saw_END_CASE = true;
break;
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;
}
}
}
if (!saw_END_CASE)
- emit_END_CASE (ds, inp);
+ emit_END_CASE (inp->ds, inp);
inside_input_program = false;
if (!saw_DATA_LIST && !saw_END_FILE)
{
msg (SE, _("Input program must contain DATA LIST or END FILE."));
- dataset_clear (ds);
destroy_input_program (inp);
return CMD_FAILURE;
}
- if (dict_get_next_value_idx (dataset_dict (ds)) == 0)
+ 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);
/* PSPPIRE - a graphical user interface for PSPP.
- Copyright (C) 2008, 2009, 2010, 2011, 2012 Free Software Foundation
+ Copyright (C) 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation
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
GtkWidget *dw;
if (the_session == NULL)
- the_session = session_create ();
+ the_session = session_create (NULL);
if (ds == NULL)
{
/* PSPP - a program for statistical analysis.
- Copyright (C) 1997-2000, 2006-2007, 2009-2012 Free Software Foundation, Inc.
+ Copyright (C) 1997-2000, 2006-2007, 2009-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
random_init ();
lexer = lex_create ();
- the_session = session_create ();
+ the_session = session_create (NULL);
dataset_create (the_session, "");
parser = argv_parser_create ();
input-program.sps:4: error: EXECUTE: EXECUTE is allowed only after the active dataset has been defined.
])
AT_CLEANUP
+
+dnl Tests for bug #39097, a bug when an INPUT PROGRAM used VECTOR, was
+dnl followed immediately by a call to proc_execute() (here via DATASET
+dnl COPY), and then the input was actually used.
+AT_SETUP([INPUT PROGRAM with VECTOR and EXECUTE])
+AT_DATA([input-program.sps], [dnl
+INPUT PROGRAM.
+VECTOR vec(5).
+LOOP #c = 1 to 10.
+ LOOP #v = 1 to 5.
+ COMPUTE vec(#v) = #v.
+ END LOOP.
+ END CASE.
+END LOOP.
+END FILE.
+END INPUT PROGRAM.
+DATASET COPY x.
+LIST.
+])
+AT_CHECK([pspp -O format=csv input-program.sps], [0], [dnl
+Table: Data List
+vec1,vec2,vec3,vec4,vec5
+1.00,2.00,3.00,4.00,5.00
+1.00,2.00,3.00,4.00,5.00
+1.00,2.00,3.00,4.00,5.00
+1.00,2.00,3.00,4.00,5.00
+1.00,2.00,3.00,4.00,5.00
+1.00,2.00,3.00,4.00,5.00
+1.00,2.00,3.00,4.00,5.00
+1.00,2.00,3.00,4.00,5.00
+1.00,2.00,3.00,4.00,5.00
+1.00,2.00,3.00,4.00,5.00
+])
+AT_CLEANUP