/* PSPP - a program for statistical analysis.
- Copyright (C) 2008 Free Software Foundation, Inc.
+ Copyright (C) 2008, 2010, 2011 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 <stdlib.h>
-#include <data/attributes.h>
-#include <data/dictionary.h>
-#include <data/procedure.h>
-#include <data/variable.h>
-#include <language/command.h>
-#include <language/lexer/lexer.h>
-#include <language/lexer/variable-parser.h>
-#include <libpspp/message.h>
+#include "data/attributes.h"
+#include "data/dictionary.h"
+#include "data/procedure.h"
+#include "data/variable.h"
+#include "language/command.h"
+#include "language/lexer/lexer.h"
+#include "language/lexer/variable-parser.h"
+#include "libpspp/message.h"
-#include "xalloc.h"
+#include "gl/xalloc.h"
#include "gettext.h"
#define _(msgid) gettext (msgid)
bool ok;
if (!lex_force_match_id (lexer, "VARIABLES")
- || !lex_force_match (lexer, '=')
+ || !lex_force_match (lexer, T_EQUALS)
|| !parse_variables (lexer, dataset_dict (ds), &vars, &n_vars,
PV_NONE))
return CMD_FAILURE;
if (!ok)
return CMD_FAILURE;
}
- while (lex_match (lexer, '/'));
+ while (lex_match (lexer, T_SLASH));
return lex_end_of_command (lexer);
}
match_subcommand (struct lexer *lexer, const char *keyword)
{
if (lex_token (lexer) == T_ID
- && lex_id_match (ss_cstr (lex_tokid (lexer)), ss_cstr (keyword))
- && lex_look_ahead (lexer) == '=')
+ && lex_id_match (lex_tokss (lexer), ss_cstr (keyword))
+ && lex_look_ahead (lexer) == T_EQUALS)
{
lex_get (lexer); /* Skip keyword. */
lex_get (lexer); /* Skip '='. */
return false;
}
-static bool
-parse_attribute_name (struct lexer *lexer, char name[VAR_NAME_LEN + 1],
- size_t *index)
+/* Parses an attribute name optionally followed by an index inside square
+ brackets. Returns the attribute name or NULL if there was a parse error.
+ Stores the index into *INDEX. */
+static char *
+parse_attribute_name (struct lexer *lexer, size_t *index)
{
+ char *name;
+
if (!lex_force_id (lexer))
- return false;
- strcpy (name, lex_tokid (lexer));
+ return NULL;
+ name = xstrdup (lex_tokcstr (lexer));
lex_get (lexer);
- if (lex_match (lexer, '['))
+ if (lex_match (lexer, T_LBRACK))
{
if (!lex_force_int (lexer))
- return false;
+ goto error;
if (lex_integer (lexer) < 1 || lex_integer (lexer) > 65535)
{
msg (SE, _("Attribute array index must be between 1 and 65535."));
- return false;
+ goto error;
}
*index = lex_integer (lexer);
lex_get (lexer);
- if (!lex_force_match (lexer, ']'))
- return false;
+ if (!lex_force_match (lexer, T_RBRACK))
+ goto error;
}
else
*index = 0;
- return true;
+ return name;
+
+error:
+ free (name);
+ return NULL;
}
static bool
add_attribute (struct lexer *lexer, struct attrset **sets, size_t n)
{
- char name[VAR_NAME_LEN + 1];
+ const char *value;
size_t index, i;
- char *value;
+ char *name;
- if (!parse_attribute_name (lexer, name, &index)
- || !lex_force_match (lexer, '(')
- || !lex_force_string (lexer))
+ name = parse_attribute_name (lexer, &index);
+ if (name == NULL)
return false;
- value = ds_cstr (lex_tokstr (lexer));
+ if (!lex_force_match (lexer, T_LPAREN) || !lex_force_string (lexer))
+ {
+ free (name);
+ return false;
+ }
+ value = lex_tokcstr (lexer);
for (i = 0; i < n; i++)
{
}
lex_get (lexer);
- return lex_force_match (lexer, ')');
+ free (name);
+ return lex_force_match (lexer, T_RPAREN);
}
static bool
delete_attribute (struct lexer *lexer, struct attrset **sets, size_t n)
{
- char name[VAR_NAME_LEN + 1];
size_t index, i;
+ char *name;
- if (!parse_attribute_name (lexer, name, &index))
+ name = parse_attribute_name (lexer, &index);
+ if (name == NULL)
return false;
for (i = 0; i < n; i++)
}
}
}
+
+ free (name);
return true;
}
command = DELETE;
else if (command == UNKNOWN)
{
- lex_error (lexer, _("expecting ATTRIBUTE= or DELETE="));
+ lex_error (lexer, _("expecting %s or %s"), "ATTRIBUTE=", "DELETE=");
return CMD_FAILURE;
}
: delete_attribute (lexer, sets, n)))
return CMD_FAILURE;
}
- while (lex_token (lexer) != '/' && lex_token (lexer) != '.');
+ while (lex_token (lexer) != T_SLASH && lex_token (lexer) != T_ENDCMD);
return CMD_SUCCESS;
}