/* PSPP - a program for statistical analysis.
- Copyright (C) 1997-9, 2000, 2006, 2009 Free Software Foundation, Inc.
+ Copyright (C) 1997-9, 2000, 2006, 2009, 2010 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 <libpspp/getl.h>
#include <libpspp/str.h>
#include <output/journal.h>
+#include <output/text-item.h>
#include "xalloc.h"
#define _(msgid) gettext (msgid)
#define N_(msgid) msgid
-
-#define DUMP_TOKENS 0
-
-
-
struct lexer
{
struct string line_buffer;
};
static int parse_string (struct lexer *, enum string_type);
-
-#if DUMP_TOKENS
-static void dump_token (struct lexer *);
-#endif
\f
/* Initialization. */
return;
}
- /* If a token was pushed ahead, return it. */
- if (lexer->put_token)
- {
- restore_token (lexer);
-#if DUMP_TOKENS
- dump_token (lexer);
-#endif
- return;
- }
+ /* If a token was pushed ahead, return it. */
+ if (lexer->put_token)
+ {
+ restore_token (lexer);
+ return;
+ }
- for (;;)
- {
- /* Skip whitespace. */
+ for (;;)
+ {
+ /* Skip whitespace. */
while (c_isspace ((unsigned char) *lexer->prog))
lexer->prog++;
{
lexer->dot = 0;
lexer->token = '.';
-#if DUMP_TOKENS
- dump_token (lexer);
-#endif
return;
}
else if (!lex_get_line (lexer))
{
lexer->prog = NULL;
lexer->token = T_STOP;
-#if DUMP_TOKENS
- dump_token (lexer);
-#endif
return;
}
if (lexer->put_token)
{
restore_token (lexer);
-#if DUMP_TOKENS
- dump_token (lexer);
-#endif
return;
}
}
else
{
unsigned char c = *lexer->prog++;
- if (c_isgraph (c))
- msg (SE, _("Bad character in input: `%c'."), c);
- else
- msg (SE, _("Bad character in input: `\\%o'."), c);
+ char *c_name = xasprintf (c_isgraph (c) ? "%c" : "\\%o", c);
+ msg (SE, _("Bad character in input: `%s'."), c_name);
+ free (c_name);
continue;
}
}
break;
}
-
-#if DUMP_TOKENS
- dump_token (lexer);
-#endif
}
/* Parses an identifier at the current position into tokid and
void
lex_error (struct lexer *lexer, const char *message, ...)
{
- char *token_rep;
- char where[128];
+ struct string s;
+
+ ds_init_empty (&s);
- token_rep = lex_token_representation (lexer);
if (lexer->token == T_STOP)
- strcpy (where, "end of file");
+ ds_put_cstr (&s, _("Syntax error at end of file"));
else if (lexer->token == '.')
- strcpy (where, "end of command");
+ ds_put_cstr (&s, _("Syntax error at end of command"));
else
- snprintf (where, sizeof where, "`%s'", token_rep);
- free (token_rep);
+ {
+ char *token_rep = lex_token_representation (lexer);
+ ds_put_format (&s, _("Syntax error at `%s'"), token_rep);
+ free (token_rep);
+ }
if (message)
{
- char buf[1024];
va_list args;
+ ds_put_cstr (&s, ": ");
+
va_start (args, message);
- vsnprintf (buf, 1024, message, args);
+ ds_put_vformat (&s, message, args);
va_end (args);
-
- msg (SE, _("Syntax error %s at %s."), buf, where);
}
- else
- msg (SE, _("Syntax error at %s."), where);
+
+ msg (SE, "%s.", ds_cstr (&s));
+ ds_destroy (&s);
}
/* Checks that we're at end of command.
}
}
-/* Reads a line, without performing any preprocessing.
- Sets *SYNTAX, if SYNTAX is non-null, to the line's syntax
- mode. */
+/* Reads a line, without performing any preprocessing. */
bool
lex_get_line_raw (struct lexer *lexer)
{
bool ok = getl_read_line (lexer->ss, &lexer->line_buffer);
- enum syntax_mode mode = lex_current_syntax_mode (lexer);
- journal_write (mode == GETL_BATCH, ds_cstr (&lexer->line_buffer));
-
+ if (ok)
+ {
+ const char *line = ds_cstr (&lexer->line_buffer);
+ text_item_submit (text_item_create (TEXT_ITEM_SYNTAX, line));
+ }
return ok;
}
if (type != CHARACTER_STRING)
convert_numeric_string_to_char_string (lexer, type);
- if (ds_length (&lexer->tokstr) > 255)
- {
- msg (SE, _("String exceeds 255 characters in length (%zu characters)."),
- ds_length (&lexer->tokstr));
- ds_truncate (&lexer->tokstr, 255);
- }
-
return T_STRING;
}
\f
-#if DUMP_TOKENS
-/* Reads one token from the lexer and writes a textual representation
- on stdout for debugging purposes. */
-static void
-dump_token (struct lexer *lexer)
-{
- {
- const char *curfn;
- int curln;
-
- curln = getl_source_location (lexer->ss);
- curfn = getl_source_name (lexer->ss);
- if (curfn)
- fprintf (stderr, "%s:%d\t", curfn, curln);
- }
-
- switch (lexer->token)
- {
- case T_ID:
- fprintf (stderr, "ID\t%s\n", lexer->tokid);
- break;
-
- case T_POS_NUM:
- case T_NEG_NUM:
- fprintf (stderr, "NUM\t%f\n", lexer->tokval);
- break;
-
- case T_STRING:
- fprintf (stderr, "STRING\t\"%s\"\n", ds_cstr (&lexer->tokstr));
- break;
-
- case T_STOP:
- fprintf (stderr, "STOP\n");
- break;
-
- case T_EXP:
- fprintf (stderr, "MISC\tEXP\"");
- break;
-
- case 0:
- fprintf (stderr, "MISC\tEOF\n");
- break;
-
- default:
- if (lex_is_keyword (lexer->token))
- fprintf (stderr, "KEYWORD\t%s\n", lex_token_name (lexer->token));
- else
- fprintf (stderr, "PUNCT\t%c\n", lexer->token);
- break;
- }
-}
-#endif /* DUMP_TOKENS */
-
-
/* Token Accessor Functions */
int