#include <stdarg.h>
#include <stdlib.h>
#include <libpspp/alloc.h>
+#include <libpspp/assertion.h>
#include <language/command.h>
#include <libpspp/message.h>
#include <language/line-buffer.h>
*/
\f
-/* Global variables. */
-
-extern const char *keywords[T_N_KEYWORDS + 1];
-
-
/* Current token. */
int token;
/* Pointer to next token in getl_buf. */
static char *prog;
-/* Nonzero only if this line ends with a terminal dot. */
-static int dot;
+/* True only if this line ends with a terminal dot. */
+static bool dot;
-/* Nonzero only if the last token returned was T_STOP. */
-static int eof;
+/* True only if the last token returned was T_STOP. */
+static bool eof;
/* If nonzero, next token returned by lex_get().
Used only in exceptional circumstances. */
HEX_STRING /* Hexadecimal digits. */
};
-static void convert_numeric_string_to_char_string (enum string_type);
static int parse_string (enum string_type);
#if DUMP_TOKENS
void
lex_init (void)
{
- ds_init (&tokstr, 64);
- ds_init (&put_tokstr, 64);
+ ds_init_empty (&tokstr);
+ ds_init_empty (&put_tokstr);
if (!lex_get_line ())
eof = true;
}
assert (put_token != 0);
token = put_token;
ds_assign_string (&tokstr, &put_tokstr);
- str_copy_trunc (tokid, sizeof tokid, ds_c_str (&tokstr));
+ str_copy_trunc (tokid, sizeof tokid, ds_cstr (&tokstr));
tokval = put_tokval;
put_token = 0;
}
}
else if (!lex_get_line ())
{
- eof = 1;
+ eof = true;
token = T_STOP;
#if DUMP_TOKENS
dump_token ();
negative numbers into two tokens. */
if (*prog == '-')
{
- ds_putc (&tokstr, *prog++);
+ ds_put_char (&tokstr, *prog++);
while (isspace ((unsigned char) *prog))
prog++;
/* Parse the number, copying it into tokstr. */
while (isdigit ((unsigned char) *prog))
- ds_putc (&tokstr, *prog++);
+ ds_put_char (&tokstr, *prog++);
if (*prog == '.')
{
- ds_putc (&tokstr, *prog++);
+ ds_put_char (&tokstr, *prog++);
while (isdigit ((unsigned char) *prog))
- ds_putc (&tokstr, *prog++);
+ ds_put_char (&tokstr, *prog++);
}
if (*prog == 'e' || *prog == 'E')
{
- ds_putc (&tokstr, *prog++);
+ ds_put_char (&tokstr, *prog++);
if (*prog == '+' || *prog == '-')
- ds_putc (&tokstr, *prog++);
+ ds_put_char (&tokstr, *prog++);
while (isdigit ((unsigned char) *prog))
- ds_putc (&tokstr, *prog++);
+ ds_put_char (&tokstr, *prog++);
}
/* Parse as floating point. */
- tokval = strtod (ds_c_str (&tokstr), &tail);
+ tokval = strtod (ds_cstr (&tokstr), &tail);
if (*tail)
{
msg (SE, _("%s does not form a valid number."),
- ds_c_str (&tokstr));
+ ds_cstr (&tokstr));
tokval = 0.0;
ds_clear (&tokstr);
- ds_putc (&tokstr, '0');
+ ds_put_char (&tokstr, '0');
}
break;
const char *start = prog;
prog = lex_skip_identifier (start);
- ds_concat (&tokstr, start, prog - start);
- str_copy_trunc (tokid, sizeof tokid, ds_c_str (&tokstr));
- return lex_id_to_token (ds_c_str (&tokstr), ds_length (&tokstr));
+ ds_put_substring (&tokstr, ss_buffer (start, prog - start));
+ str_copy_trunc (tokid, sizeof tokid, ds_cstr (&tokstr));
+ return lex_id_to_token (ds_cstr (&tokstr), ds_length (&tokstr));
}
/* Reports an error to the effect that subcommand SBC may only be
\f
/* Token matching functions. */
-/* If TOK is the current token, skips it and returns nonzero.
- Otherwise, returns zero. */
-int
+/* If TOK is the current token, skips it and returns true
+ Otherwise, returns false. */
+bool
lex_match (int t)
{
if (token == t)
{
lex_get ();
- return 1;
+ return true;
}
else
- return 0;
+ return false;
}
/* If the current token is the identifier S, skips it and returns
- nonzero. The identifier may be abbreviated to its first three
+ true. The identifier may be abbreviated to its first three
letters.
- Otherwise, returns zero. */
-int
+ Otherwise, returns false. */
+bool
lex_match_id (const char *s)
{
if (token == T_ID && lex_id_match (s, tokid))
{
lex_get ();
- return 1;
+ return true;
}
else
- return 0;
+ return false;
}
-/* If the current token is integer N, skips it and returns nonzero.
- Otherwise, returns zero. */
-int
+/* If the current token is integer N, skips it and returns true.
+ Otherwise, returns false. */
+bool
lex_match_int (int x)
{
if (lex_is_integer () && lex_integer () == x)
{
lex_get ();
- return 1;
+ return true;
}
else
- return 0;
+ return false;
}
\f
/* Forced matches. */
/* If this token is identifier S, fetches the next token and returns
nonzero.
Otherwise, reports an error and returns zero. */
-int
+bool
lex_force_match_id (const char *s)
{
if (token == T_ID && lex_id_match (s, tokid))
{
lex_get ();
- return 1;
+ return true;
}
else
{
lex_error (_("expecting `%s'"), s);
- return 0;
+ return false;
}
}
/* If the current token is T, skips the token. Otherwise, reports an
- error and returns from the current function with return value 0. */
-int
+ error and returns from the current function with return value false. */
+bool
lex_force_match (int t)
{
if (token == t)
{
lex_get ();
- return 1;
+ return true;
}
else
{
lex_error (_("expecting `%s'"), lex_token_name (t));
- return 0;
+ return false;
}
}
-/* If this token is a string, does nothing and returns nonzero.
- Otherwise, reports an error and returns zero. */
-int
+/* If this token is a string, does nothing and returns true.
+ Otherwise, reports an error and returns false. */
+bool
lex_force_string (void)
{
if (token == T_STRING)
- return 1;
+ return true;
else
{
lex_error (_("expecting string"));
- return 0;
+ return false;
}
}
-/* If this token is an integer, does nothing and returns nonzero.
- Otherwise, reports an error and returns zero. */
-int
+/* If this token is an integer, does nothing and returns true.
+ Otherwise, reports an error and returns false. */
+bool
lex_force_int (void)
{
if (lex_is_integer ())
- return 1;
+ return true;
else
{
lex_error (_("expecting integer"));
- return 0;
+ return false;
}
}
-/* If this token is a number, does nothing and returns nonzero.
- Otherwise, reports an error and returns zero. */
-int
+/* If this token is a number, does nothing and returns true.
+ Otherwise, reports an error and returns false. */
+bool
lex_force_num (void)
{
if (lex_is_number ())
- return 1;
+ return true;
else
{
lex_error (_("expecting number"));
- return 0;
+ return false;
}
}
-/* If this token is an identifier, does nothing and returns nonzero.
- Otherwise, reports an error and returns zero. */
-int
+/* If this token is an identifier, does nothing and returns true.
+ Otherwise, reports an error and returns false. */
+bool
lex_force_id (void)
{
if (token == T_ID)
- return 1;
+ return true;
else
{
lex_error (_("expecting identifier"));
- return 0;
+ return false;
}
}
/* Weird token functions. */
assert (lex_id_to_token (id, strlen (id)) == T_ID);
save_token ();
token = T_ID;
- ds_assign_c_str (&tokstr, id);
- str_copy_trunc (tokid, sizeof tokid, ds_c_str (&tokstr));
+ ds_assign_cstr (&tokstr, id);
+ str_copy_trunc (tokid, sizeof tokid, ds_cstr (&tokstr));
}
\f
/* Weird line processing functions. */
const char *
lex_entire_line (void)
{
- return ds_c_str (&getl_buf);
+ return ds_cstr (&getl_buf);
}
/* As lex_entire_line(), but only returns the part of the current line
lex_discard_line (void)
{
prog = ds_end (&getl_buf);
- dot = put_token = 0;
+ dot = false;
+ put_token = 0;
}
/* Sets the current position in the current line to P, which must be
in_comment = false;
quote = EOF;
- for (cp = ds_c_str (string); *cp; )
+ for (cp = ds_cstr (string); *cp; )
{
/* If we're not in a comment, check for quote marks. */
if (!in_comment)
return false;
strip_comments (line);
- ds_rtrim_spaces (line);
+ ds_rtrim (line, ss_cstr (CC_SPACES));
/* Check for and remove terminal dot. */
dot = (ds_chomp (line, get_endcmd ())
put_token = '.';
}
- prog = ds_c_str (line);
+ prog = ds_cstr (line);
return true;
}
return t;
}
- return _("<ERROR>");
+ NOT_REACHED ();
}
/* Returns an ASCII representation of the current token as a
case T_ID:
case T_POS_NUM:
case T_NEG_NUM:
- return xstrdup (ds_c_str (&tokstr));
+ return ds_xstrdup (&tokstr);
break;
case T_STRING:
int hexstring = 0;
char *sp, *dp;
- for (sp = ds_c_str (&tokstr); sp < ds_end (&tokstr); sp++)
+ for (sp = ds_cstr (&tokstr); sp < ds_end (&tokstr); sp++)
if (!isprint ((unsigned char) *sp))
{
hexstring = 1;
*dp++ = '\'';
if (!hexstring)
- for (sp = ds_c_str (&tokstr); *sp; )
+ for (sp = ds_cstr (&tokstr); *sp; )
{
if (*sp == '\'')
*dp++ = '\'';
*dp++ = (unsigned char) *sp++;
}
else
- for (sp = ds_c_str (&tokstr); sp < ds_end (&tokstr); sp++)
+ for (sp = ds_cstr (&tokstr); sp < ds_end (&tokstr); sp++)
{
*dp++ = (((unsigned char) *sp) >> 4)["0123456789ABCDEF"];
*dp++ = (((unsigned char) *sp) & 15)["0123456789ABCDEF"];
}
}
- assert (0);
+ NOT_REACHED ();
}
\f
/* Really weird functions. */
{
token = T_POS_NUM;
tokval = -tokval;
- ds_assign_substring (&tokstr, &tokstr, 1, SIZE_MAX);
+ ds_assign_substring (&tokstr, ds_substr (&tokstr, 1, SIZE_MAX));
save_token ();
token = '-';
}
void
lex_reset_eof (void)
{
- eof = 0;
+ eof = false;
}
/* Skip a COMMENT command. */
if (!lex_get_line ())
{
put_token = T_STOP;
- eof = 1;
+ eof = true;
return;
}
chars_per_byte = 2;
break;
default:
- abort ();
+ NOT_REACHED ();
}
byte_cnt = ds_length (&tokstr) / chars_per_byte;
"multiple of %d."),
base_name, ds_length (&tokstr), chars_per_byte);
- p = ds_c_str (&tokstr);
+ p = ds_cstr (&tokstr);
for (i = 0; i < byte_cnt; i++)
{
int value;
value = value * base + v;
}
- ds_c_str (&tokstr)[i] = (unsigned char) value;
+ ds_cstr (&tokstr)[i] = (unsigned char) value;
}
ds_truncate (&tokstr, byte_cnt);
static int
parse_string (enum string_type type)
{
+ if (type != CHARACTER_STRING)
+ prog++;
+
/* Accumulate the entire string, joining sections indicated by +
signs. */
for (;;)
break;
}
- ds_putc (&tokstr, *prog++);
+ ds_put_char (&tokstr, *prog++);
}
prog++;
ds_truncate (&tokstr, 255);
}
- {
- /* FIXME. */
- size_t i;
- int warned = 0;
-
- for (i = 0; i < ds_length (&tokstr); i++)
- if (ds_c_str (&tokstr)[i] == 0)
- {
- if (!warned)
- {
- msg (SE, _("Sorry, literal strings may not contain null "
- "characters. Replacing with spaces."));
- warned = 1;
- }
- ds_c_str (&tokstr)[i] = ' ';
- }
- }
-
return T_STRING;
}
\f
break;
case T_STRING:
- fprintf (stderr, "STRING\t\"%s\"\n", ds_c_str (&tokstr));
+ fprintf (stderr, "STRING\t\"%s\"\n", ds_cstr (&tokstr));
break;
case T_STOP: