/* PSPP - a program for statistical analysis.
- Copyright (C) 1997-9, 2000, 2009, 2010, 2011 Free Software Foundation, Inc.
+ Copyright (C) 1997-9, 2000, 2009, 2010, 2011, 2012 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 <stdbool.h>
#include <stdlib.h>
+#include "data/dataset.h"
#include "data/dictionary.h"
-#include "data/procedure.h"
#include "data/variable.h"
#include "language/lexer/lexer.h"
#include "libpspp/assertion.h"
#include "libpspp/cast.h"
#include "libpspp/hash-functions.h"
+#include "libpspp/i18n.h"
#include "libpspp/hmapx.h"
#include "libpspp/message.h"
#include "libpspp/misc.h"
#include "libpspp/str.h"
#include "libpspp/stringi-set.h"
+#include "math/interaction.h"
+
#include "gl/c-ctype.h"
#include "gl/xalloc.h"
/* Parses a list of variable names according to the DATA LIST version
of the TO convention. */
bool
-parse_DATA_LIST_vars (struct lexer *lexer, char ***namesp,
- size_t *n_varsp, int pv_opts)
+parse_DATA_LIST_vars (struct lexer *lexer, const struct dictionary *dict,
+ char ***namesp, size_t *n_varsp, int pv_opts)
{
char **names;
size_t n_vars;
do
{
- if (lex_token (lexer) != T_ID)
+ if (lex_token (lexer) != T_ID
+ || !dict_id_is_valid (dict, lex_tokcstr (lexer), true))
{
lex_error (lexer, "expecting variable name");
goto exit;
unsigned long int number;
lex_get (lexer);
- if (lex_token (lexer) != T_ID)
+ if (lex_token (lexer) != T_ID
+ || !dict_id_is_valid (dict, lex_tokcstr (lexer), true))
{
lex_error (lexer, "expecting variable name");
goto exit;
parse_DATA_LIST_vars(), except that all allocations are taken
from the given POOL. */
bool
-parse_DATA_LIST_vars_pool (struct lexer *lexer, struct pool *pool,
+parse_DATA_LIST_vars_pool (struct lexer *lexer, const struct dictionary *dict,
+ struct pool *pool,
char ***names, size_t *nnames, int pv_opts)
{
int retval;
re-free it later. */
assert (!(pv_opts & PV_APPEND));
- retval = parse_DATA_LIST_vars (lexer, names, nnames, pv_opts);
+ retval = parse_DATA_LIST_vars (lexer, dict, names, nnames, pv_opts);
if (retval)
register_vars_pool (pool, *names, *nnames);
return retval;
free (v);
*nnames += nv;
}
- else if (!parse_DATA_LIST_vars (lexer, names, nnames, PV_APPEND))
+ else if (!parse_DATA_LIST_vars (lexer, dict, names, nnames, PV_APPEND))
goto fail;
}
return 1;
{
assert (vs != NULL);
assert (name != NULL);
- assert (strlen (name) <= VAR_NAME_LEN);
return vs->lookup_var_idx (vs, name, idx);
}
struct hmapx_node *node;
struct variable **varp;
- HMAPX_FOR_EACH_WITH_HASH (varp, node, hash_case_string (name, 0),
+ HMAPX_FOR_EACH_WITH_HASH (varp, node, utf8_hash_case_string (name, 0),
&avs->vars_by_name)
- if (!strcasecmp (name, var_get_name (*varp)))
+ if (!utf8_strcasecmp (name, var_get_name (*varp)))
{
*idx = varp - avs->var;
return true;
return NULL;
}
hmapx_insert (&avs->vars_by_name, CONST_CAST (void *, &avs->var[i]),
- hash_case_string (name, 0));
+ utf8_hash_case_string (name, 0));
}
return vs;
}
+
+/* Match a variable.
+ If the match succeeds, the variable will be placed in VAR.
+ Returns true if successful */
+bool
+lex_match_variable (struct lexer *lexer, const struct dictionary *dict, const struct variable **var)
+{
+ if (lex_token (lexer) != T_ID)
+ return false;
+
+ *var = parse_variable_const (lexer, dict);
+
+ if ( *var == NULL)
+ return false;
+ return true;
+}
+
+/* An interaction is a variable followed by {*, BY} followed by an interaction */
+static bool
+parse_internal_interaction (struct lexer *lexer, const struct dictionary *dict, struct interaction **iact, struct interaction **it)
+{
+ const struct variable *v = NULL;
+ assert (iact);
+
+ switch (lex_next_token (lexer, 1))
+ {
+ case T_ENDCMD:
+ case T_SLASH:
+ case T_COMMA:
+ case T_ID:
+ case T_BY:
+ case T_ASTERISK:
+ break;
+ default:
+ return false;
+ break;
+ }
+
+ if (! lex_match_variable (lexer, dict, &v))
+ {
+ if (it)
+ interaction_destroy (*it);
+ *iact = NULL;
+ return false;
+ }
+
+ assert (v);
+
+ if ( *iact == NULL)
+ *iact = interaction_create (v);
+ else
+ interaction_add_variable (*iact, v);
+
+ if ( lex_match (lexer, T_ASTERISK) || lex_match (lexer, T_BY))
+ {
+ return parse_internal_interaction (lexer, dict, iact, iact);
+ }
+
+ return true;
+}
+
+bool
+parse_design_interaction (struct lexer *lexer, const struct dictionary *dict, struct interaction **iact)
+{
+ return parse_internal_interaction (lexer, dict, iact, NULL);
+}
+