MODIFY VARS: Fix bugs in REORDER and DROP subcommands, add tests.
authorBen Pfaff <blp@cs.stanford.edu>
Tue, 26 Feb 2019 04:30:03 +0000 (20:30 -0800)
committerBen Pfaff <blp@cs.stanford.edu>
Tue, 26 Feb 2019 04:30:03 +0000 (20:30 -0800)
Thanks to Nolan Void for reporting the bug.

doc/variables.texi
src/language/dictionary/modify-variables.c
tests/automake.mk
tests/language/dictionary/modify-variables.at [new file with mode: 0644]

index 7f6d89bee25767996f904f29fbc32dcb0c9c7366..587088ee78156ca5cd28233c37ea0ff7f8c6d79e 100644 (file)
@@ -275,8 +275,10 @@ same number of old and new variable names.  Each old variable is renamed to
 the corresponding new variable name.  Multiple parenthesized groups of
 variables may be specified.
 
 the corresponding new variable name.  Multiple parenthesized groups of
 variables may be specified.
 
-The @subcmd{DROP} subcommand deletes a specified list of variables from the
-active dataset.
+The @subcmd{DROP} subcommand deletes a specified list of variables
+from the active dataset.  @cmd{MODIFY VARS} may not be used to delete
+all variables from the dictionary; use @cmd{NEW FILE} to do that
+(@pxref{NEW FILE}).
 
 The @subcmd{KEEP} subcommand keeps the specified list of variables in the active
 dataset.  Any unlisted variables are deleted from the active dataset.
 
 The @subcmd{KEEP} subcommand keeps the specified list of variables in the active
 dataset.  Any unlisted variables are deleted from the active dataset.
index 90296b7bb09fbfb1867ff1bea15cd650b9c2dc54..98a588b15be47d1d7cbd889a044b0dba6796cc9e 100644 (file)
@@ -171,8 +171,12 @@ cmd_modify_vars (struct lexer *lexer, struct dataset *ds)
                      goto done;
                    }
                }
                      goto done;
                    }
                }
-             sort (&v[prev_nv], nv - prev_nv, sizeof *v,
-                    compare_variables_given_ordering, &ordering);
+
+              if (!ordering.positional)
+                sort (&v[prev_nv], nv - prev_nv, sizeof *v,
+                      compare_variables_given_ordering, &ordering);
+              else if (!ordering.forward)
+                reverse_array(&v[prev_nv], nv - prev_nv, sizeof *v);
            }
          while (lex_token (lexer) != T_SLASH
                  && lex_token (lexer) != T_ENDCMD);
            }
          while (lex_token (lexer) != T_SLASH
                  && lex_token (lexer) != T_ENDCMD);
@@ -303,6 +307,14 @@ cmd_modify_vars (struct lexer *lexer, struct dataset *ds)
            goto done;
           vm.drop_vars = drop_vars;
           vm.n_drop = n_drop;
            goto done;
           vm.drop_vars = drop_vars;
           vm.n_drop = n_drop;
+
+          if (n_drop == dict_get_var_cnt (dataset_dict (ds)))
+            {
+              msg (SE, _("%s may not be used to delete all variables "
+                         "from the active dataset dictionary.  "
+                         "Use %s instead."), "MODIFY VARS", "NEW FILE");
+              goto done;
+            }
        }
       else if (lex_match_id (lexer, "MAP"))
        {
        }
       else if (lex_match_id (lexer, "MAP"))
        {
index 50525848f0f4ca66b3cea3c439d1d1466a76361e..3af1e2a278a16fc976e4a7683d5737ab76329ee5 100644 (file)
@@ -336,6 +336,7 @@ TESTSUITE_AT = \
        tests/language/dictionary/formats.at \
        tests/language/dictionary/missing-values.at \
        tests/language/dictionary/mrsets.at \
        tests/language/dictionary/formats.at \
        tests/language/dictionary/missing-values.at \
        tests/language/dictionary/mrsets.at \
+       tests/language/dictionary/modify-variables.at \
        tests/language/dictionary/rename-variables.at \
        tests/language/dictionary/sort-variables.at \
        tests/language/dictionary/split-file.at \
        tests/language/dictionary/rename-variables.at \
        tests/language/dictionary/sort-variables.at \
        tests/language/dictionary/split-file.at \
diff --git a/tests/language/dictionary/modify-variables.at b/tests/language/dictionary/modify-variables.at
new file mode 100644 (file)
index 0000000..818bf5f
--- /dev/null
@@ -0,0 +1,239 @@
+dnl PSPP - a program for statistical analysis.
+dnl Copyright (C) 2017 Free Software Foundation, Inc.
+dnl 
+dnl This program is free software: you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation, either version 3 of the License, or
+dnl (at your option) any later version.
+dnl 
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+dnl GNU General Public License for more details.
+dnl 
+dnl You should have received a copy of the GNU General Public License
+dnl along with this program.  If not, see <http://www.gnu.org/licenses/>.
+dnl
+AT_BANNER([MODIFY VARS])
+
+AT_SETUP([MODIFY VARS /REORDER])
+AT_KEYWORDS([REORDER])
+AT_DATA([modify-variables.sps], [dnl
+DATA LIST LIST /a b c x y z (F2.0).
+BEGIN DATA.
+1 2 3 4 5 6
+END DATA.
+
+MODIFY VARS /REORDER (z y x).
+DISPLAY INDEX.
+MODIFY VARS /REORDER (c b a).
+DISPLAY INDEX.
+
+MODIFY VARS /REORDER BACKWARD (z y x).
+DISPLAY INDEX.
+MODIFY VARS /REORDER BACKWARD (c b a).
+DISPLAY INDEX.
+
+MODIFY VARS /REORDER BACKWARD ALPHA (ALL).
+DISPLAY INDEX.
+MODIFY VARS /REORDER ALPHA (ALL).
+DISPLAY INDEX.
+])
+AT_CHECK([pspp -O format=csv modify-variables.sps], [0], [dnl
+Table: Reading free-form data from INLINE.
+Variable,Format
+a,F2.0
+b,F2.0
+c,F2.0
+x,F2.0
+y,F2.0
+z,F2.0
+
+Table: Variables
+Name,Position
+z,1
+y,2
+x,3
+a,4
+b,5
+c,6
+
+Table: Variables
+Name,Position
+c,1
+b,2
+a,3
+z,4
+y,5
+x,6
+
+Table: Variables
+Name,Position
+x,1
+y,2
+z,3
+c,4
+b,5
+a,6
+
+Table: Variables
+Name,Position
+a,1
+b,2
+c,3
+x,4
+y,5
+z,6
+
+Table: Variables
+Name,Position
+z,1
+y,2
+x,3
+c,4
+b,5
+a,6
+
+Table: Variables
+Name,Position
+a,1
+b,2
+c,3
+x,4
+y,5
+z,6
+])
+AT_CLEANUP
+
+AT_SETUP([MODIFY VARS /RENAME])
+AT_KEYWORDS([RENAME])
+AT_DATA([modify-variables.sps], [dnl
+DATA LIST LIST /a b c x y z (F2.0).
+BEGIN DATA.
+1 2 3 4 5 6
+END DATA.
+
+MODIFY VARS /RENAME (a b c = one two three).
+DISPLAY INDEX.
+MODIFY VARS /RENAME (one two three = a b c).
+DISPLAY INDEX.
+MODIFY VARS /RENAME (a = a).
+DISPLAY INDEX.
+MODIFY VARS /RENAME (a b c = b c a).
+DISPLAY INDEX.
+])
+AT_CHECK([pspp -O format=csv modify-variables.sps], [0], [dnl
+Table: Reading free-form data from INLINE.
+Variable,Format
+a,F2.0
+b,F2.0
+c,F2.0
+x,F2.0
+y,F2.0
+z,F2.0
+
+Table: Variables
+Name,Position
+one,1
+two,2
+three,3
+x,4
+y,5
+z,6
+
+Table: Variables
+Name,Position
+a,1
+b,2
+c,3
+x,4
+y,5
+z,6
+
+Table: Variables
+Name,Position
+a,1
+b,2
+c,3
+x,4
+y,5
+z,6
+
+Table: Variables
+Name,Position
+b,1
+c,2
+a,3
+x,4
+y,5
+z,6
+])
+AT_CLEANUP
+
+AT_SETUP([MODIFY VARS /DROP and /KEEP])
+AT_KEYWORDS([DROP KEEP])
+AT_DATA([modify-variables.sps], [dnl
+DATA LIST LIST /a b c x y z (F2.0).
+BEGIN DATA.
+1 2 3 4 5 6
+END DATA.
+
+MODIFY VARS /DROP a.
+DISPLAY INDEX.
+MODIFY VARS /KEEP ALL.
+DISPLAY INDEX.
+MODIFY VARS /KEEP c TO y.
+DISPLAY INDEX.
+MODIFY VARS /DROP x.
+DISPLAY INDEX.
+MODIFY VARS /KEEP y.
+DISPLAY INDEX.
+MODIFY VARS /DROP y.
+DISPLAY INDEX.
+])
+AT_CHECK([pspp -O format=csv modify-variables.sps], [1], [dnl
+Table: Reading free-form data from INLINE.
+Variable,Format
+a,F2.0
+b,F2.0
+c,F2.0
+x,F2.0
+y,F2.0
+z,F2.0
+
+Table: Variables
+Name,Position
+b,1
+c,2
+x,3
+y,4
+z,5
+
+Table: Variables
+Name,Position
+b,1
+c,2
+x,3
+y,4
+z,5
+
+Table: Variables
+Name,Position
+c,1
+x,2
+y,3
+
+Table: Variables
+Name,Position
+c,1
+y,2
+
+Table: Variables
+Name,Position
+y,1
+
+modify-variables.sps:16: error: MODIFY VARS: MODIFY VARS may not be used to delete all variables from the active dataset dictionary.  Use NEW FILE instead.
+
+modify-variables.sps:17: error: Stopping syntax file processing here to avoid a cascade of dependent command failures.
+])
+AT_CLEANUP