The LEX_ERROR_INTERACTIVE error handling mode really only makes sense for
reading from a terminal, where we know we're getting one line at a time
and not partial lines. Unfortunately LEX_ERROR_INTERACTIVE was the default
and it was getting used as such in the GUI for reading from syntax files.
This meant that if there was an error in the GUI then the current buffer
(which might be any arbitrary chunk of syntax) was being discarded, which
caused terrible confusion.
This commit changes the default to LEX_ERROR_CONTINUE, which works
in a reasonable fashion regardless of the input source. It also renames
LEX_ERROR_INTERACTIVE to LEX_ERROR_TERMINAL to make it clear that that's
the only reasonable use.
Reported by Thambu David <thambu@cmcvellore.ac.in>, archived at:
http://lists.gnu.org/archive/html/pspp-users/2013-08/msg00019.html
- * Notable bug fixes:
-
- - System files written by IBM SPSS 21 are now read without warnings.
-
* PSPPIRE graphical user interface improvements:
- Syntax windows now parse syntax in "auto" mode, which in practice
should mean that both "batch" and "interactive" syntax now works,
instead of just "interactive" syntax.
* PSPPIRE graphical user interface improvements:
- Syntax windows now parse syntax in "auto" mode, which in practice
should mean that both "batch" and "interactive" syntax now works,
instead of just "interactive" syntax.
+ * Notable bug fixes:
+
+ - System files written by IBM SPSS 21 are now read without warnings.
+
+ - PSPPIRE should now more gracefully handle syntax files that contain
+ errors.
+
Changes from 0.6.2 to 0.8.0:
* New commands:
Changes from 0.6.2 to 0.8.0:
* New commands:
default:
if (cmd_result_is_failure (result)
default:
if (cmd_result_is_failure (result)
- && lex_get_error_mode (lexer) != LEX_ERROR_INTERACTIVE)
+ && lex_get_error_mode (lexer) != LEX_ERROR_TERMINAL)
{
if (result == CMD_EOF)
msg (SE, _("Unexpected end-of-file within INPUT PROGRAM."));
{
if (result == CMD_EOF)
msg (SE, _("Unexpected end-of-file within INPUT PROGRAM."));
{
reader->class = class;
reader->syntax = LEX_SYNTAX_AUTO;
{
reader->class = class;
reader->syntax = LEX_SYNTAX_AUTO;
- reader->error = LEX_ERROR_INTERACTIVE;
+ reader->error = LEX_ERROR_CONTINUE;
reader->file_name = NULL;
reader->line_number = 0;
}
reader->file_name = NULL;
reader->line_number = 0;
}
}
/* Returns the error mode for the syntax file from which the current drawn is
}
/* Returns the error mode for the syntax file from which the current drawn is
- drawn. Returns LEX_ERROR_INTERACTIVE for a T_STOP token or if the command's
+ drawn. Returns LEX_ERROR_TERMINAL for a T_STOP token or if the command's
source does not have line numbers.
There is no version of this function that takes an N argument because
source does not have line numbers.
There is no version of this function that takes an N argument because
lex_get_error_mode (const struct lexer *lexer)
{
struct lex_source *src = lex_source__ (lexer);
lex_get_error_mode (const struct lexer *lexer)
{
struct lex_source *src = lex_source__ (lexer);
- return src == NULL ? LEX_ERROR_INTERACTIVE : src->reader->error;
+ return src == NULL ? LEX_ERROR_TERMINAL : src->reader->error;
}
/* If the source that LEXER is currently reading has error mode
}
/* If the source that LEXER is currently reading has error mode
- LEX_ERROR_INTERACTIVE, discards all buffered input and tokens, so that the
- next token to be read comes directly from whatever is next read from the
- stream.
+ LEX_ERROR_TERMINAL, discards all buffered input and tokens, so that the next
+ token to be read comes directly from whatever is next read from the stream.
It makes sense to call this function after encountering an error in a
command entered on the console, because usually the user would prefer not to
It makes sense to call this function after encountering an error in a
command entered on the console, because usually the user would prefer not to
lex_interactive_reset (struct lexer *lexer)
{
struct lex_source *src = lex_source__ (lexer);
lex_interactive_reset (struct lexer *lexer)
{
struct lex_source *src = lex_source__ (lexer);
- if (src != NULL && src->reader->error == LEX_ERROR_INTERACTIVE)
+ if (src != NULL && src->reader->error == LEX_ERROR_TERMINAL)
{
src->head = src->tail = 0;
src->journal_pos = src->seg_pos = src->line_pos = 0;
{
src->head = src->tail = 0;
src->journal_pos = src->seg_pos = src->line_pos = 0;
}
/* Discards all lookahead tokens in LEXER, then discards all input sources
}
/* Discards all lookahead tokens in LEXER, then discards all input sources
- until it encounters one with error mode LEX_ERROR_INTERACTIVE or until it
+ until it encounters one with error mode LEX_ERROR_TERMINAL or until it
runs out of input sources. */
void
lex_discard_noninteractive (struct lexer *lexer)
runs out of input sources. */
void
lex_discard_noninteractive (struct lexer *lexer)
while (!deque_is_empty (&src->deque))
lex_source_pop__ (src);
while (!deque_is_empty (&src->deque))
lex_source_pop__ (src);
- for (; src != NULL && src->reader->error != LEX_ERROR_INTERACTIVE;
+ for (; src != NULL && src->reader->error != LEX_ERROR_TERMINAL;
src = lex_source__ (lexer))
lex_source_destroy (src);
}
src = lex_source__ (lexer))
lex_source_destroy (src);
}
/* PSPP - a program for statistical analysis.
/* PSPP - a program for statistical analysis.
- Copyright (C) 1997-9, 2000, 2010, 2011 Free Software Foundation, Inc.
+ Copyright (C) 1997-9, 2000, 2010, 2011, 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
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
/* Handling of errors. */
enum lex_error_mode
{
/* Handling of errors. */
enum lex_error_mode
{
- LEX_ERROR_INTERACTIVE, /* Always continue to next command. */
+ LEX_ERROR_TERMINAL, /* Discard input line and continue reading. */
LEX_ERROR_CONTINUE, /* Continue to next command, except for
cascading failures. */
LEX_ERROR_STOP /* Stop processing. */
LEX_ERROR_CONTINUE, /* Continue to next command, except for
cascading failures. */
LEX_ERROR_STOP /* Stop processing. */
lex_discard_noninteractive (lexer);
}
else if (result == CMD_CASCADING_FAILURE
lex_discard_noninteractive (lexer);
}
else if (result == CMD_CASCADING_FAILURE
- && lex_get_error_mode (lexer) != LEX_ERROR_INTERACTIVE)
+ && lex_get_error_mode (lexer) != LEX_ERROR_TERMINAL)
{
msg (SE, _("Stopping syntax file processing here to avoid "
"a cascade of dependent command failures."));
{
msg (SE, _("Stopping syntax file processing here to avoid "
"a cascade of dependent command failures."));
r = xzalloc (sizeof *r);
r->reader.class = &terminal_reader_class;
r->reader.syntax = LEX_SYNTAX_INTERACTIVE;
r = xzalloc (sizeof *r);
r->reader.class = &terminal_reader_class;
r->reader.syntax = LEX_SYNTAX_INTERACTIVE;
- r->reader.error = LEX_ERROR_INTERACTIVE;
+ r->reader.error = LEX_ERROR_TERMINAL;
r->reader.file_name = NULL;
r->s = ss_empty ();
r->offset = 0;
r->reader.file_name = NULL;
r->s = ss_empty ();
r->offset = 0;