psppire: Deal properly with inverted variable selections.
[pspp] / src / language / dictionary / modify-variables.c
index 90296b7bb09fbfb1867ff1bea15cd650b9c2dc54..a1fe6d75df294244fe11bc168c0120e2c77f57bd 100644 (file)
@@ -26,7 +26,6 @@
 #include "language/lexer/variable-parser.h"
 #include "libpspp/array.h"
 #include "libpspp/assertion.h"
-#include "libpspp/bit-vector.h"
 #include "libpspp/compiler.h"
 #include "libpspp/i18n.h"
 #include "libpspp/message.h"
@@ -154,7 +153,7 @@ cmd_modify_vars (struct lexer *lexer, struct dataset *ds)
                {
                  if (!lex_match (lexer, T_LPAREN))
                    {
-                      lex_error_expecting (lexer, "`('", NULL_SENTINEL);
+                      lex_error_expecting (lexer, "`('");
                      free (v);
                      goto done;
                    }
@@ -166,13 +165,17 @@ cmd_modify_vars (struct lexer *lexer, struct dataset *ds)
                    }
                  if (!lex_match (lexer, T_RPAREN))
                    {
-                      lex_error_expecting (lexer, "`)'", NULL_SENTINEL);
+                      lex_error_expecting (lexer, "`)'");
                      free (v);
                      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);
@@ -197,7 +200,7 @@ cmd_modify_vars (struct lexer *lexer, struct dataset *ds)
 
              if (!lex_match (lexer, T_LPAREN))
                {
-                  lex_error_expecting (lexer, "`('", NULL_SENTINEL);
+                  lex_error_expecting (lexer, "`('");
                  goto done;
                }
              if (!parse_variables (lexer, dataset_dict (ds),
@@ -206,7 +209,7 @@ cmd_modify_vars (struct lexer *lexer, struct dataset *ds)
                goto done;
              if (!lex_match (lexer, T_EQUALS))
                {
-                  lex_error_expecting (lexer, "`='", NULL_SENTINEL);
+                  lex_error_expecting (lexer, "`='");
                  goto done;
                }
 
@@ -226,7 +229,7 @@ cmd_modify_vars (struct lexer *lexer, struct dataset *ds)
                }
              if (!lex_match (lexer, T_RPAREN))
                {
-                  lex_error_expecting (lexer, "`)'", NULL_SENTINEL);
+                  lex_error_expecting (lexer, "`)'");
                  goto done;
                }
            }
@@ -303,6 +306,14 @@ cmd_modify_vars (struct lexer *lexer, struct dataset *ds)
            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"))
        {
@@ -328,7 +339,7 @@ cmd_modify_vars (struct lexer *lexer, struct dataset *ds)
        break;
       if (lex_token (lexer) != T_SLASH)
        {
-          lex_error_expecting (lexer, "`/'", "`.'", NULL_SENTINEL);
+          lex_error_expecting (lexer, "`/'", "`.'");
          goto done;
        }
       lex_get (lexer);