VECTOR: Eliminate VAR_NAME_LEN limit for variable names.
[pspp-builds.git] / src / language / dictionary / vector.c
index a623a349e2442a1b7bd23a714a9ccf2bd4861ef5..8eb7ef16f17bce3ca77f119d85d342fc4fa22afe 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000 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
@@ -26,7 +26,6 @@
 #include <language/lexer/format-parser.h>
 #include <language/lexer/lexer.h>
 #include <language/lexer/variable-parser.h>
-#include <libpspp/alloc.h>
 #include <libpspp/assertion.h>
 #include <libpspp/message.h>
 #include <libpspp/misc.h>
@@ -34,6 +33,7 @@
 #include <libpspp/str.h>
 
 #include "intprops.h"
+#include "xalloc.h"
 
 #include "gettext.h"
 #define _(msgid) gettext (msgid)
@@ -59,33 +59,33 @@ cmd_vector (struct lexer *lexer, struct dataset *ds)
        {
           size_t i;
 
-         if (dict_lookup_vector (dict, lex_tokid (lexer)))
+         if (dict_lookup_vector (dict, lex_tokcstr (lexer)))
            {
              msg (SE, _("A vector named %s already exists."),
-                   lex_tokid (lexer));
+                   lex_tokcstr (lexer));
              goto fail;
            }
 
           for (i = 0; i < vector_cnt; i++)
-            if (!strcasecmp (vectors[i], lex_tokid (lexer)))
+            if (!strcasecmp (vectors[i], lex_tokcstr (lexer)))
              {
                msg (SE, _("Vector name %s is given twice."),
-                     lex_tokid (lexer));
+                     lex_tokcstr (lexer));
                goto fail;
              }
 
           if (vector_cnt == vector_cap)
             vectors = pool_2nrealloc (pool,
                                        vectors, &vector_cap, sizeof *vectors);
-          vectors[vector_cnt++] = xstrdup (lex_tokid (lexer));
+          vectors[vector_cnt++] = pool_strdup (pool, lex_tokcstr (lexer));
 
          lex_get (lexer);
-         lex_match (lexer, ',');
+         lex_match (lexer, T_COMMA);
        }
 
       /* Now that we have the names it's time to check for the short
          or long forms. */
-      if (lex_match (lexer, '='))
+      if (lex_match (lexer, T_EQUALS))
        {
          /* Long form. */
           struct variable **v;
@@ -104,7 +104,7 @@ cmd_vector (struct lexer *lexer, struct dataset *ds)
 
           dict_create_vector (dict, vectors[0], v, nv);
        }
-      else if (lex_match (lexer, '('))
+      else if (lex_match (lexer, T_LPAREN))
        {
           /* Short form. */
           struct fmt_spec format;
@@ -118,7 +118,7 @@ cmd_vector (struct lexer *lexer, struct dataset *ds)
           var_cnt = 0;
           format = fmt_for_output (FMT_F, 8, 2);
           seen_format = false;
-          while (!lex_match (lexer, ')'))
+          while (!lex_match (lexer, T_RPAREN))
             {
               if (lex_is_integer (lexer) && var_cnt == 0)
                 {
@@ -135,7 +135,7 @@ cmd_vector (struct lexer *lexer, struct dataset *ds)
                   seen_format = true;
                   if (!parse_format_specifier (lexer, &format)
                       || !fmt_check_output (&format)
-                      || !fmt_check_type_compat (&format, VAR_NUMERIC))
+                      || !fmt_check_type_compat (&format, VAL_NUMERIC))
                     goto fail;
                 }
               else
@@ -143,7 +143,7 @@ cmd_vector (struct lexer *lexer, struct dataset *ds)
                   lex_error (lexer, NULL);
                   goto fail;
                 }
-              lex_match (lexer, ',');
+              lex_match (lexer, T_COMMA);
             }
           if (var_cnt == 0)
             {
@@ -152,25 +152,27 @@ cmd_vector (struct lexer *lexer, struct dataset *ds)
             }
 
          /* Check that none of the variables exist and that
-             their names are no more than LONG_NAME_LEN bytes
+             their names are no more than VAR_NAME_LEN bytes
              long. */
           for (i = 0; i < vector_cnt; i++)
            {
               int j;
              for (j = 0; j < var_cnt; j++)
                {
-                  char name[LONG_NAME_LEN + INT_STRLEN_BOUND (int) + 1];
-                 sprintf (name, "%s%d", vectors[i], j + 1);
-                  if (strlen (name) > LONG_NAME_LEN)
+                  char *name = xasprintf ("%s%d", vectors[i], j + 1);
+                  if (strlen (name) > VAR_NAME_LEN)
                     {
+                      free (name);
                       msg (SE, _("%s is too long for a variable name."), 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 +183,10 @@ cmd_vector (struct lexer *lexer, struct dataset *ds)
               int j;
              for (j = 0; j < var_cnt; j++)
                {
-                  char name[LONG_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);
            }
@@ -195,7 +197,7 @@ cmd_vector (struct lexer *lexer, struct dataset *ds)
          goto fail;
        }
     }
-  while (lex_match (lexer, '/'));
+  while (lex_match (lexer, T_SLASH));
 
   pool_destroy (pool);
   return lex_end_of_command (lexer);