variable-parser: Implement PV_NO_DUPLICATE.
authorBen Pfaff <blp@cs.stanford.edu>
Sat, 3 Apr 2010 04:26:52 +0000 (21:26 -0700)
committerBen Pfaff <blp@cs.stanford.edu>
Tue, 13 Apr 2010 05:33:01 +0000 (22:33 -0700)
Now that we have string_set, PV_NO_DUPLICATE is easy to implement, so
we might as well.

src/language/data-io/trim.c
src/language/dictionary/numeric.c
src/language/dictionary/rename-variables.c
src/language/lexer/variable-parser.c
src/language/stats/aggregate.c

index 7a14c996b8c6ea7cd1cc90ab0ec2399477a9b4da..921b9c655e9475b916a56823ff34f0fcf1d1d4bd 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2006, 2007, 2008 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2006, 2007, 2008, 2010 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
@@ -114,7 +114,8 @@ parse_dict_rename (struct lexer *lexer, struct dictionary *dict)
          msg (SE, _("`=' expected after variable list."));
          goto done;
        }
-      if (!parse_DATA_LIST_vars (lexer, &new_names, &nn, PV_APPEND | PV_NO_SCRATCH))
+      if (!parse_DATA_LIST_vars (lexer, &new_names, &nn,
+                                 PV_APPEND | PV_NO_SCRATCH | PV_NO_DUPLICATE))
        goto done;
       if (nn != nv)
        {
index 5fa77541b24791aa7d309e5500a6744d4d758b7a..41f3c79a67b8bcc3ea5b1194f770a93535f86713 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2006, 2010 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
@@ -49,7 +49,7 @@ cmd_numeric (struct lexer *lexer, struct dataset *ds)
         be used. */
       struct fmt_spec f;
 
-      if (!parse_DATA_LIST_vars (lexer, &v, &nv, PV_NONE))
+      if (!parse_DATA_LIST_vars (lexer, &v, &nv, PV_NO_DUPLICATE))
        return CMD_FAILURE;
 
       /* Get the optional format specification. */
@@ -127,7 +127,7 @@ cmd_string (struct lexer *lexer, struct dataset *ds)
 
   do
     {
-      if (!parse_DATA_LIST_vars (lexer, &v, &nv, PV_NONE))
+      if (!parse_DATA_LIST_vars (lexer, &v, &nv, PV_NO_DUPLICATE))
        return CMD_FAILURE;
 
       if (!lex_force_match (lexer, '(')
index 90117ff69ede1ea6a33b1cb7a4aa65761dbe0ba3..c175831d8dacb6c3d448ac2821a9d7362725e1b5 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 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
@@ -67,7 +67,8 @@ cmd_rename_variables (struct lexer *lexer, struct dataset *ds)
          msg (SE, _("`=' expected between lists of new and old variable names."));
          goto lossage;
        }
-      if (!parse_DATA_LIST_vars (lexer, &rename_new_names, &prev_nv_1, PV_APPEND))
+      if (!parse_DATA_LIST_vars (lexer, &rename_new_names, &prev_nv_1,
+                                 PV_APPEND | PV_NO_DUPLICATE))
        goto lossage;
       if (prev_nv_1 != rename_cnt)
        {
index c6a2d5378b112ecd2210d74bc904f054df893d6e..b9d67523eeda711ed52501425d8ff9fa99ed0c54 100644 (file)
@@ -34,6 +34,7 @@
 #include "libpspp/misc.h"
 #include "libpspp/pool.h"
 #include "libpspp/str.h"
+#include "libpspp/stringi-set.h"
 
 #include "gl/xalloc.h"
 
@@ -400,7 +401,8 @@ extract_num (char *s, char *r, int *n, int *d)
 /* 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 ***names, size_t *nnames, int pv_opts)
+parse_DATA_LIST_vars (struct lexer *lexer, char ***names,
+                      size_t *nnames, int pv_opts)
 {
   int n1, n2;
   int d1, d2;
@@ -408,16 +410,27 @@ parse_DATA_LIST_vars (struct lexer *lexer, char ***names, size_t *nnames, int pv
   size_t nvar, mvar;
   char name1[VAR_NAME_LEN + 1], name2[VAR_NAME_LEN + 1];
   char root1[VAR_NAME_LEN + 1], root2[VAR_NAME_LEN + 1];
+  struct stringi_set set;
   int success = 0;
 
   assert (names != NULL);
   assert (nnames != NULL);
   assert ((pv_opts & ~(PV_APPEND | PV_SINGLE
                        | PV_NO_SCRATCH | PV_NO_DUPLICATE)) == 0);
-  /* FIXME: PV_NO_DUPLICATE is not implemented. */
+  stringi_set_init (&set);
 
   if (pv_opts & PV_APPEND)
-    nvar = mvar = *nnames;
+    {
+      nvar = mvar = *nnames;
+
+      if (pv_opts & PV_NO_DUPLICATE)
+        {
+          size_t i;
+
+          for (i = 0; i < nvar; i++)
+            stringi_set_insert (&set, (*names)[i]);
+        }
+    }
   else
     {
       nvar = mvar = 0;
@@ -477,6 +490,13 @@ parse_DATA_LIST_vars (struct lexer *lexer, char ***names, size_t *nnames, int pv
            {
               char name[VAR_NAME_LEN + 1];
              sprintf (name, "%s%0*d", root1, d1, n);
+
+              if (pv_opts & PV_NO_DUPLICATE && !stringi_set_insert (&set, name))
+                {
+                  msg (SE, _("Variable %s appears twice in variable list."),
+                       name);
+                  goto fail;
+                }
              (*names)[nvar] = xstrdup (name);
              nvar++;
            }
@@ -501,6 +521,7 @@ parse_DATA_LIST_vars (struct lexer *lexer, char ***names, size_t *nnames, int pv
 
 fail:
   *nnames = nvar;
+  stringi_set_destroy (&set);
   if (!success)
     {
       int i;
index b54ebf6376bd1500c3f0e616703f84e2c07a1026..42f330d5d21a64b141a963b82ce1bbcae49a7c3e 100644 (file)
@@ -391,7 +391,8 @@ parse_aggregate_functions (struct lexer *lexer, const struct dictionary *dict,
          size_t n_dest_prev = n_dest;
 
          if (!parse_DATA_LIST_vars (lexer, &dest, &n_dest,
-                                     PV_APPEND | PV_SINGLE | PV_NO_SCRATCH))
+                                     (PV_APPEND | PV_SINGLE | PV_NO_SCRATCH
+                                      | PV_NO_DUPLICATE)))
            goto error;
 
          /* Assign empty labels. */