Bug #38782.
Reported by John Darrington.
stops the flow of input data and passes out of the @cmd{INPUT PROGRAM}
structure.
+@cmd{INPUT PROGRAM} must contain at least one @cmd{DATA LIST} or
+@cmd{END FILE} command.
+
All this is very confusing. A few examples should help to clarify.
@c If you change this example, change the regression test1 in
/* PSPP - a program for statistical analysis.
- Copyright (C) 1997-9, 2000, 2009, 2010, 2011, 2012 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
static inline bool
cmd_result_is_valid (enum cmd_result result)
{
- return (result == CMD_SUCCESS || result == CMD_EOF || result == CMD_FINISH
- || (result >= CMD_PRIVATE_FIRST && result <= CMD_PRIVATE_LAST)
- || result == CMD_FAILURE || result == CMD_NOT_IMPLEMENTED
- || result == CMD_CASCADING_FAILURE);
+ switch (result)
+ {
+ case CMD_SUCCESS:
+ case CMD_EOF:
+ case CMD_FINISH:
+ case CMD_DATA_LIST:
+ case CMD_END_CASE:
+ case CMD_END_FILE:
+ case CMD_FAILURE:
+ case CMD_NOT_IMPLEMENTED:
+ case CMD_CASCADING_FAILURE:
+ return true;
+
+ default:
+ return false;
+ }
}
/* Returns true if RESULT indicates success,
/* PSPP - a program for statistical analysis.
- Copyright (C) 1997-9, 2000, 2006, 2010 Free Software Foundation, Inc.
+ Copyright (C) 1997-9, 2000, 2006, 2010, 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
CMD_EOF = 2, /* End of input. */
CMD_FINISH = 3, /* FINISH was executed. */
- /* Range of successful return values available for use
- by agreement between a command and the caller of
- cmd_parse(). */
- CMD_PRIVATE_FIRST = 4,
- CMD_PRIVATE_LAST = 127,
+ /* Successful return values returned by specific commands to let INPUT
+ PROGRAM function properly. */
+ CMD_DATA_LIST,
+ CMD_END_CASE,
+ CMD_END_FILE,
/* Various kinds of failures. */
CMD_FAILURE = -1, /* Not executed at all. */
/* PSPP - a program for statistical analysis.
- Copyright (C) 1997-9, 2000, 2006, 2007, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
+ Copyright (C) 1997-9, 2000, 2006, 2007, 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
fh_unref (fh);
free (encoding);
- return CMD_SUCCESS;
+ return CMD_DATA_LIST;
error:
data_parser_destroy (parser);
/* PSPP - a program for statistical analysis.
- Copyright (C) 1997-9, 2000, 2009, 2010, 2011, 2012 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 "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 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))
enum cmd_result result;
result = cmd_parse_in_state (lexer, ds, CMD_STATE_INPUT_PROGRAM);
- if (result == (enum cmd_result) CMD_END_CASE)
+ switch (result)
{
+ case CMD_DATA_LIST:
+ saw_DATA_LIST = true;
+ break;
+
+ case CMD_END_CASE:
emit_END_CASE (ds, inp);
saw_END_CASE = true;
- }
- else if (cmd_result_is_failure (result)
- && result != CMD_FAILURE
- && lex_get_error_mode (lexer) != LEX_ERROR_INTERACTIVE)
- {
- 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_INTERACTIVE)
+ {
+ 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);
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)
{
msg (SE, _("Input program did not create any variables."));
add_transformation (ds, end_file_trns_proc, NULL, NULL);
- return CMD_SUCCESS;
+ return CMD_END_FILE;
}
/* Executes an END FILE transformation. */
error: DESCRIPTIVES: Syntax error at end of input: expecting BEGIN.
])
AT_CLEANUP
+
+dnl Tests for bug #38782, an infinite loop processing an empty input program.
+AT_SETUP([INPUT PROGRAM infinite loop])
+AT_DATA([input-program.sps], [dnl
+INPUT PROGRAM.
+STRING firstname lastname (a24) / address (a80).
+END INPUT PROGRAM.
+EXECUTE.
+])
+AT_CHECK([pspp -O format=csv input-program.sps], [1], [dnl
+input-program.sps:3: error: Input program must contain DATA LIST or END FILE.
+
+input-program.sps:4: error: EXECUTE: EXECUTE is allowed only after the active dataset has been defined.
+])
+AT_CLEANUP