lexer: Reimplement for better testability and internationalization.
[pspp-builds.git] / src / language / dictionary / vector.c
index 3be0723f705d0da04534011c2a2e884d7728755a..a5e66df8c44a592fd8a0c5cb7c767c73943c0d05 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2010 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 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/format.h>
-#include <data/procedure.h>
-#include <data/dictionary.h>
-#include <data/variable.h>
-#include <language/command.h>
-#include <language/lexer/format-parser.h>
-#include <language/lexer/lexer.h>
-#include <language/lexer/variable-parser.h>
-#include <libpspp/assertion.h>
-#include <libpspp/message.h>
-#include <libpspp/misc.h>
-#include <libpspp/pool.h>
-#include <libpspp/str.h>
-
-#include "intprops.h"
-#include "xalloc.h"
+#include "data/format.h"
+#include "data/procedure.h"
+#include "data/dictionary.h"
+#include "data/variable.h"
+#include "language/command.h"
+#include "language/lexer/format-parser.h"
+#include "language/lexer/lexer.h"
+#include "language/lexer/variable-parser.h"
+#include "libpspp/assertion.h"
+#include "libpspp/message.h"
+#include "libpspp/misc.h"
+#include "libpspp/pool.h"
+#include "libpspp/str.h"
+
+#include "gl/intprops.h"
+#include "gl/xalloc.h"
 
 #include "gettext.h"
 #define _(msgid) gettext (msgid)
@@ -50,7 +50,8 @@ cmd_vector (struct lexer *lexer, struct dataset *ds)
       size_t vector_cnt, vector_cap;
 
       /* Get the name(s) of the new vector(s). */
-      if (!lex_force_id (lexer))
+      if (!lex_force_id (lexer)
+          || !dict_id_is_valid (dict, lex_tokcstr (lexer), true))
        return CMD_CASCADING_FAILURE;
 
       vectors = NULL;
@@ -151,26 +152,26 @@ cmd_vector (struct lexer *lexer, struct dataset *ds)
               goto fail;
             }
 
-         /* Check that none of the variables exist and that
-             their names are no more than VAR_NAME_LEN bytes
-             long. */
+         /* Check that none of the variables exist and that their names are
+             not excessively long. */
           for (i = 0; i < vector_cnt; i++)
            {
               int j;
              for (j = 0; j < var_cnt; j++)
                {
-                  char name[VAR_NAME_LEN + INT_STRLEN_BOUND (int) + 1];
-                 sprintf (name, "%s%d", vectors[i], j + 1);
-                  if (strlen (name) > VAR_NAME_LEN)
+                  char *name = xasprintf ("%s%d", vectors[i], j + 1);
+                  if (!dict_id_is_valid (dict, name, true))
                     {
-                      msg (SE, _("%s is too long for a variable name."), name);
+                      free (name);
                       goto fail;
                     }
                   if (dict_lookup_var (dict, name))
                    {
+                      free (name);
                      msg (SE, _("%s is an existing variable name."), name);
                      goto fail;
                    }
+                  free (name);
                }
            }
 
@@ -181,10 +182,10 @@ cmd_vector (struct lexer *lexer, struct dataset *ds)
               int j;
              for (j = 0; j < var_cnt; j++)
                {
-                  char name[VAR_NAME_LEN + 1];
-                 sprintf (name, "%s%d", vectors[i], j + 1);
+                  char *name = xasprintf ("%s%d", vectors[i], j + 1);
                  vars[j] = dict_create_var_assert (dict, name, 0);
                   var_set_both_formats (vars[j], &format);
+                  free (name);
                }
               dict_create_vector_assert (dict, vectors[i], vars, var_cnt);
            }
@@ -198,7 +199,7 @@ cmd_vector (struct lexer *lexer, struct dataset *ds)
   while (lex_match (lexer, T_SLASH));
 
   pool_destroy (pool);
-  return lex_end_of_command (lexer);
+  return CMD_SUCCESS;
 
 fail:
   pool_destroy (pool);