MODIFY VARS: Remove.
authorBen Pfaff <blp@cs.stanford.edu>
Sun, 18 Sep 2022 19:33:03 +0000 (12:33 -0700)
committerBen Pfaff <blp@cs.stanford.edu>
Sun, 18 Sep 2022 19:33:03 +0000 (12:33 -0700)
NEWS
doc/variables.texi
src/language/command.def
src/language/dictionary/automake.mk
src/language/dictionary/modify-variables.c [deleted file]
tests/automake.mk
tests/language/dictionary/modify-variables.at [deleted file]

diff --git a/NEWS b/NEWS
index aa8e337cdaea2b169c5d0c733aa43278cc6bec9e..46973b48cf283268b6c1855011303797c0cd937c 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -17,6 +17,8 @@ Changes after 1.6.2:
 
    - Break variables are now optional.
 
+ * Removed the MODIFY VARS command, which is not in SPSS.
+
  * Building from a Git repository, which previously required GIMP, now
    requires rsvg-convert from librsvg2 instead.
 
index ab6f83daea2d91c815ebc42e5edd106dafd827d1..6a033db42bffedbf227f9184c8942bfda84c681d 100644 (file)
@@ -21,7 +21,6 @@ There are several utility commands for examining and adjusting variables.
 * DISPLAY::                     Display information about the active dataset.
 * NUMERIC::                     Create new numeric variables.
 * STRING::                      Create new string variables.
-* MODIFY VARS::                 Rename, reorder, and drop variables.
 * RENAME VARIABLES::            Rename variables.
 * SORT VARIABLES::              Reorder variables.
 * DELETE VARIABLES::            Delete variables.
@@ -169,55 +168,6 @@ STRING lastname (A24).
 STRING address (A80).
 @end example
 
-@node MODIFY VARS
-@section MODIFY VARS
-@vindex MODIFY VARS
-
-You can use @cmd{MODIFY VARS} to reorder, rename, or delete variables.
-
-@display
-MODIFY VARS
-        /REORDER=@{FORWARD,BACKWARD@} @{POSITIONAL,ALPHA@} (@var{var_list})@dots{}
-        /RENAME=(@var{old_names}=@var{new_names})@dots{}
-        /@{DROP,KEEP@}=@var{var_list}
-        /MAP
-@end display
-
-At least one subcommand must be specified, and no subcommand may be
-specified more than once.  @subcmd{DROP} and @subcmd{KEEP} may not both
-be specified.
-
-The @subcmd{REORDER} subcommand changes the order of variables in the active
-dataset.  Specify one or more lists of variable names in parentheses.  By
-default, each list of variables is rearranged into the specified order.
-To put the variables into the reverse of the specified order, put
-keyword @subcmd{BACKWARD} before the parentheses.  To put them into alphabetical
-order in the dictionary, specify keyword @subcmd{ALPHA} before the parentheses.
-@subcmd{BACKWARD} and @subcmd{ALPHA} may also be combined.
-
-To rename variables in the active dataset, specify @subcmd{RENAME}, an equals sign
-(@samp{=}), and lists of the old variable names and new variable names
-separated by another equals sign within parentheses.  There must be the
-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 @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.
-
-@subcmd{MAP} is currently ignored.
-
-If either @subcmd{DROP} or @subcmd{KEEP} is specified, the data is read;
-otherwise it is not.
-
-@cmd{MODIFY VARS} may not be specified following @cmd{TEMPORARY}
-(@pxref{TEMPORARY}).
-
 @node RENAME VARIABLES
 @section RENAME VARIABLES
 @vindex RENAME VARIABLES
index 6db5e74e2e60b54bfe28603f9fc833c03a2166b3..9549fca4b151f361c4cb09fb649299337a975e12 100644 (file)
@@ -130,7 +130,6 @@ DEF_CMD (S_DATA, 0, "GRAPH", cmd_graph)
 DEF_CMD (S_DATA, 0, "LIST", cmd_list)
 DEF_CMD (S_DATA, 0, "LOGISTIC REGRESSION", cmd_logistic)
 DEF_CMD (S_DATA, 0, "MEANS", cmd_means)
-DEF_CMD (S_DATA, 0, "MODIFY VARS", cmd_modify_vars)
 DEF_CMD (S_DATA, 0, "NPAR TESTS", cmd_npar_tests)
 DEF_CMD (S_DATA, 0, "ONEWAY", cmd_oneway)
 DEF_CMD (S_DATA, 0, "PEARSON CORRELATIONS", cmd_correlation)
index 93a1decbf27c1588915c4de5380880c9e0b22518..87553045b38843fbfe2a0efe75f10689d0ba77a6 100644 (file)
@@ -22,7 +22,6 @@ language_dictionary_sources = \
  src/language/dictionary/delete-variables.c \
  src/language/dictionary/formats.c \
  src/language/dictionary/missing-values.c \
- src/language/dictionary/modify-variables.c \
  src/language/dictionary/mrsets.c \
  src/language/dictionary/numeric.c \
  src/language/dictionary/rename-variables.c \
diff --git a/src/language/dictionary/modify-variables.c b/src/language/dictionary/modify-variables.c
deleted file mode 100644 (file)
index e23d6a4..0000000
+++ /dev/null
@@ -1,546 +0,0 @@
-/* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2010, 2011, 2012 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
-   the Free Software Foundation, either version 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
-
-#include <config.h>
-
-#include <stdlib.h>
-
-#include "data/dataset.h"
-#include "data/dictionary.h"
-#include "data/variable.h"
-#include "language/command.h"
-#include "language/lexer/lexer.h"
-#include "language/lexer/variable-parser.h"
-#include "libpspp/array.h"
-#include "libpspp/assertion.h"
-#include "libpspp/compiler.h"
-#include "libpspp/i18n.h"
-#include "libpspp/message.h"
-#include "libpspp/misc.h"
-#include "libpspp/str.h"
-
-#include "gl/xalloc.h"
-
-#include "gettext.h"
-#define _(msgid) gettext (msgid)
-
-/* These control the ordering produced by
-   compare_variables_given_ordering(). */
-struct ordering
-  {
-    bool forward;              /* true=FORWARD, false=BACKWARD. */
-    bool positional;           /* true=POSITIONAL, false=ALPHA. */
-  };
-
-/* Increasing order of variable index. */
-static struct ordering forward_positional_ordering = {1, 1};
-
-static int compare_variables_given_ordering (const void *, const void *,
-                                             const void *ordering);
-
-/* Explains how to modify the variables in a dictionary. */
-struct var_modification
-  {
-    /* New variable ordering. */
-    struct variable **reorder_vars;
-    size_t n_reorder;
-
-    /* DROP/KEEP information. */
-    struct variable **drop_vars;
-    size_t n_drop;
-
-    /* New variable names. */
-    struct variable **rename_vars;
-    char **new_names;
-    size_t n_rename;
-  };
-
-static bool rearrange_dict (struct dictionary *d,
-                           const struct var_modification *vm);
-
-/* Performs MODIFY VARS command. */
-int
-cmd_modify_vars (struct lexer *lexer, struct dataset *ds)
-{
-  if (proc_make_temporary_transformations_permanent (ds))
-    lex_ofs_error (lexer, 0, lex_ofs (lexer) - 1,
-                   _("%s may not be used after %s.  "
-                     "Temporary transformations will be made permanent."),
-                   "MODIFY VARS", "TEMPORARY");
-
-  /* Bits indicated whether we've already encountered a subcommand of this
-     type. */
-  unsigned int already_encountered = 0;
-
-  /* Return code. */
-  int ret_code = CMD_CASCADING_FAILURE;
-
-  /* What we are going to do to the active dataset. */
-  struct var_modification vm =
-    {
-      .reorder_vars = NULL,
-      .n_reorder = 0,
-      .rename_vars = NULL,
-      .new_names = NULL,
-      .n_rename = 0,
-      .drop_vars = NULL,
-      .n_drop = 0,
-    };
-
-  /* Parse each subcommand. */
-  lex_match (lexer, T_SLASH);
-  for (;;)
-    {
-      if (lex_match_id (lexer, "REORDER"))
-       {
-         if (already_encountered & 1)
-           {
-              lex_sbc_only_once (lexer, "REORDER");
-             goto done;
-           }
-         already_encountered |= 1;
-
-         struct variable **v = NULL;
-         size_t nv = 0;
-
-         lex_match (lexer, T_EQUALS);
-         do
-           {
-              struct ordering ordering;
-             size_t prev_nv = nv;
-
-             ordering.forward = ordering.positional = true;
-              for (;;)
-                {
-                  if (lex_match_id (lexer, "FORWARD"))
-                    ordering.forward = true;
-                  else if (lex_match_id (lexer, "BACKWARD"))
-                    ordering.forward = false;
-                  else if (lex_match_id (lexer, "POSITIONAL"))
-                    ordering.positional = true;
-                  else if (lex_match_id (lexer, "ALPHA"))
-                    ordering.positional = false;
-                  else
-                    break;
-                }
-
-             if (lex_match (lexer, T_ALL)
-                  || lex_token (lexer) == T_SLASH
-                  || lex_token (lexer) == T_ENDCMD)
-               {
-                 if (prev_nv != 0)
-                   {
-                     msg (SE, _("Cannot specify ALL after specifying a set "
-                          "of variables."));
-                     goto done;
-                   }
-                 dict_get_vars_mutable (dataset_dict (ds), &v, &nv,
-                                         DC_SYSTEM);
-               }
-             else
-               {
-                 if (!lex_match (lexer, T_LPAREN))
-                   {
-                      lex_error_expecting (lexer, "`('");
-                     free (v);
-                     goto done;
-                   }
-                 if (!parse_variables (lexer, dataset_dict (ds), &v, &nv,
-                                       PV_APPEND | PV_NO_DUPLICATE))
-                   {
-                     free (v);
-                     goto done;
-                   }
-                 if (!lex_match (lexer, T_RPAREN))
-                   {
-                      lex_error_expecting (lexer, "`)'");
-                     free (v);
-                     goto done;
-                   }
-               }
-
-              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);
-
-         vm.reorder_vars = v;
-          vm.n_reorder = nv;
-       }
-      else if (lex_match_id (lexer, "RENAME"))
-       {
-         if (already_encountered & 2)
-           {
-              lex_sbc_only_once (lexer, "RENAME");
-             goto done;
-           }
-         already_encountered |= 2;
-
-         lex_match (lexer, T_EQUALS);
-         do
-           {
-             size_t prev_nv_1 = vm.n_rename;
-             size_t prev_nv_2 = vm.n_rename;
-
-             if (!lex_match (lexer, T_LPAREN))
-               {
-                  lex_error_expecting (lexer, "`('");
-                 goto done;
-               }
-             if (!parse_variables (lexer, dataset_dict (ds),
-                                   &vm.rename_vars, &vm.n_rename,
-                                   PV_APPEND | PV_NO_DUPLICATE))
-               goto done;
-             if (!lex_match (lexer, T_EQUALS))
-               {
-                  lex_error_expecting (lexer, "`='");
-                 goto done;
-               }
-
-             if (!parse_DATA_LIST_vars (lexer, dataset_dict (ds),
-                                         &vm.new_names, &prev_nv_1, PV_APPEND))
-               goto done;
-             if (prev_nv_1 != vm.n_rename)
-               {
-                 msg (SE, _("Differing number of variables in old name list "
-                             "(%zu) and in new name list (%zu)."),
-                      vm.n_rename - prev_nv_2, prev_nv_1 - prev_nv_2);
-                 for (size_t i = 0; i < prev_nv_1; i++)
-                   free (vm.new_names[i]);
-                 free (vm.new_names);
-                 vm.new_names = NULL;
-                 goto done;
-               }
-             if (!lex_match (lexer, T_RPAREN))
-               {
-                  lex_error_expecting (lexer, "`)'");
-                 goto done;
-               }
-           }
-         while (lex_token (lexer) != T_ENDCMD
-                 && lex_token (lexer) != T_SLASH);
-       }
-      else if (lex_match_id (lexer, "KEEP"))
-       {
-         if (already_encountered & 4)
-           {
-             lex_next_error (lexer, -1, -1,
-                              _("%s subcommand may be given at most once.  "
-                                "It may not be given in conjunction with the "
-                                "%s subcommand."),
-                              "KEEP", "DROP");
-             goto done;
-           }
-         already_encountered |= 4;
-
-         struct variable **keep_vars, **drop_vars;
-         size_t n_keep, n_drop;
-         lex_match (lexer, T_EQUALS);
-         if (!parse_variables (lexer, dataset_dict (ds),
-                                &keep_vars, &n_keep, PV_NONE))
-           goto done;
-
-         /* Transform the list of variables to keep into a list of
-            variables to drop.  First sort the keep list, then figure
-            out which variables are missing. */
-         sort (keep_vars, n_keep, sizeof *keep_vars,
-                compare_variables_given_ordering,
-                &forward_positional_ordering);
-
-          struct variable **all_vars;
-          size_t n_all;
-          dict_get_vars_mutable (dataset_dict (ds), &all_vars, &n_all, 0);
-          assert (n_all >= n_keep);
-
-          n_drop = n_all - n_keep;
-          drop_vars = xnmalloc (n_drop, sizeof *keep_vars);
-          if (set_difference (all_vars, n_all,
-                              keep_vars, n_keep,
-                              sizeof *all_vars,
-                              drop_vars,
-                              compare_variables_given_ordering,
-                              &forward_positional_ordering)
-              != n_drop)
-            NOT_REACHED ();
-
-          free (keep_vars);
-          free (all_vars);
-
-          vm.drop_vars = drop_vars;
-          vm.n_drop = n_drop;
-       }
-      else if (lex_match_id (lexer, "DROP"))
-       {
-         struct variable **drop_vars;
-         size_t n_drop;
-
-         if (already_encountered & 4)
-           {
-             lex_next_error (lexer, -1, -1,
-                              _("%s subcommand may be given at most once.  "
-                                "It may not be given in conjunction with the "
-                                "%s subcommand."),
-                  "DROP", "KEEP"
-               );
-             goto done;
-           }
-         already_encountered |= 4;
-
-          int start_ofs = lex_ofs (lexer) - 1;
-         lex_match (lexer, T_EQUALS);
-         if (!parse_variables (lexer, dataset_dict (ds),
-                                &drop_vars, &n_drop, PV_NONE))
-           goto done;
-          int end_ofs = lex_ofs (lexer) - 1;
-          vm.drop_vars = drop_vars;
-          vm.n_drop = n_drop;
-
-          if (n_drop == dict_get_n_vars (dataset_dict (ds)))
-            {
-              lex_ofs_error (lexer, start_ofs, end_ofs,
-                             _("%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"))
-       {
-          struct dictionary *temp = dict_clone (dataset_dict (ds));
-          int success = rearrange_dict (temp, &vm);
-          if (success)
-            {
-              /* FIXME: display new dictionary. */
-            }
-          dict_unref (temp);
-       }
-      else
-       {
-          lex_error_expecting (lexer, "REORDER", "RENAME", "KEEP",
-                               "DROP", "MAP");
-         goto done;
-       }
-
-      if (lex_token (lexer) == T_ENDCMD)
-       break;
-      if (lex_token (lexer) != T_SLASH)
-       {
-          lex_error_expecting (lexer, "`/'", "`.'");
-         goto done;
-       }
-      lex_get (lexer);
-    }
-
-  if (already_encountered & (1 | 4))
-    {
-      /* Read the data. */
-      if (!proc_execute (ds))
-        goto done;
-    }
-
-  if (!rearrange_dict (dataset_dict (ds), &vm))
-    goto done;
-
-  ret_code = CMD_SUCCESS;
-
-done:
-  free (vm.reorder_vars);
-  free (vm.rename_vars);
-  if (vm.new_names)
-    for (size_t i = 0; i < vm.n_rename; i++)
-      free (vm.new_names[i]);
-  free (vm.new_names);
-  free (vm.drop_vars);
-  return ret_code;
-}
-
-/* Compares A and B according to the settings in ORDERING, returning a
-   strcmp()-type result. */
-static int
-compare_variables_given_ordering (const void *a_, const void *b_,
-                                  const void *ordering_)
-{
-  struct variable *const *pa = a_;
-  struct variable *const *pb = b_;
-  const struct variable *a = *pa;
-  const struct variable *b = *pb;
-  const struct ordering *ordering = ordering_;
-
-  int result;
-  if (ordering->positional)
-    {
-      size_t a_index = var_get_dict_index (a);
-      size_t b_index = var_get_dict_index (b);
-      result = a_index < b_index ? -1 : a_index > b_index;
-    }
-  else
-    result = utf8_strcasecmp (var_get_name (a), var_get_name (b));
-  if (!ordering->forward)
-    result = -result;
-  return result;
-}
-
-/* Pairs a variable with a new name. */
-struct var_renaming
-  {
-    struct variable *var;
-    const char *new_name;
-  };
-
-/* A algo_compare_func that compares new_name members in struct var_renaming
-   structures A and B. */
-static int
-compare_var_renaming_by_new_name (const void *a_, const void *b_,
-                                  const void *aux UNUSED)
-{
-  const struct var_renaming *a = a_;
-  const struct var_renaming *b = b_;
-
-  return utf8_strcasecmp (a->new_name, b->new_name);
-}
-
-/* Returns true if performing VM on dictionary D would not cause problems such
-   as duplicate variable names.  Returns false otherwise, and issues an error
-   message. */
-static bool
-validate_var_modification (const struct dictionary *d,
-                           const struct var_modification *vm)
-{
-  /* Variable reordering can't be a problem, so we don't simulate
-     it.  Variable renaming can cause duplicate names, but
-     dropping variables can eliminate them, so we simulate both
-     of those. */
-
-  /* All variables, in index order. */
-  struct variable **all_vars;
-  size_t n_all;
-  dict_get_vars_mutable (d, &all_vars, &n_all, 0);
-
-  /* Drop variables, in index order. */
-  size_t n_drop = vm->n_drop;
-  struct variable **drop_vars = xnmalloc (n_drop, sizeof *drop_vars);
-  memcpy (drop_vars, vm->drop_vars, n_drop * sizeof *drop_vars);
-  sort (drop_vars, n_drop, sizeof *drop_vars,
-        compare_variables_given_ordering, &forward_positional_ordering);
-
-  /* Keep variables, in index order. */
-  assert (n_all >= n_drop);
-  size_t n_keep = n_all - n_drop;
-  struct variable **keep_vars = xnmalloc (n_keep, sizeof *keep_vars);
-  if (set_difference (all_vars, n_all,
-                      drop_vars, n_drop,
-                      sizeof *all_vars,
-                      keep_vars,
-                      compare_variables_given_ordering,
-                      &forward_positional_ordering) != n_keep)
-    NOT_REACHED ();
-
-  /* Copy variables into var_renaming array. */
-  struct var_renaming *var_renaming = xnmalloc (n_keep, sizeof *var_renaming);
-  for (size_t i = 0; i < n_keep; i++)
-    {
-      var_renaming[i].var = keep_vars[i];
-      var_renaming[i].new_name = var_get_name (keep_vars[i]);
-    }
-
-  /* Rename variables in var_renaming array. */
-  for (size_t i = 0; i < vm->n_rename; i++)
-    {
-      struct variable *const *kv;
-      struct var_renaming *vr;
-
-      /* Get the var_renaming element. */
-      kv = binary_search (keep_vars, n_keep, sizeof *keep_vars,
-                          &vm->rename_vars[i],
-                          compare_variables_given_ordering,
-                          &forward_positional_ordering);
-      if (kv == NULL)
-        continue;
-      vr = var_renaming + (kv - keep_vars);
-
-      vr->new_name = vm->new_names[i];
-    }
-
-  /* Sort var_renaming array by new names and check for duplicates. */
-  sort (var_renaming, n_keep, sizeof *var_renaming,
-        compare_var_renaming_by_new_name, NULL);
-  bool ok = !adjacent_find_equal (var_renaming, n_keep, sizeof *var_renaming,
-                                  compare_var_renaming_by_new_name, NULL);
-
-  /* Clean up. */
-  free (all_vars);
-  free (keep_vars);
-  free (drop_vars);
-  free (var_renaming);
-
-  return ok;
-}
-
-/* Reorders, removes, and renames variables in dictionary D according to VM.
-   Returns true if successful, false if there would have been duplicate
-   variable names if the modifications had been carried out.  In the latter
-   case, the dictionary is not modified. */
-static bool
-rearrange_dict (struct dictionary *d, const struct var_modification *vm)
-{
-  /* Check whether the modifications will cause duplicate names. */
-  if (!validate_var_modification (d, vm))
-    return false;
-
-  /* Record the old names of variables to rename.  After variables are deleted,
-     we can't depend on the variables to still exist, but we can still look
-     them up by name. */
-  char **rename_old_names = xnmalloc (vm->n_rename, sizeof *rename_old_names);
-  for (size_t i = 0; i < vm->n_rename; i++)
-    rename_old_names[i] = xstrdup (var_get_name (vm->rename_vars[i]));
-
-  /* Reorder and delete variables. */
-  dict_reorder_vars (d, vm->reorder_vars, vm->n_reorder);
-  dict_delete_vars (d, vm->drop_vars, vm->n_drop);
-
-  /* Compose lists of variables to rename and their new names. */
-  struct variable **rename_vars = xnmalloc (vm->n_rename, sizeof *rename_vars);
-  char **rename_new_names = xnmalloc (vm->n_rename, sizeof *rename_new_names);
-  size_t n_rename = 0;
-  for (size_t i = 0; i < vm->n_rename; i++)
-    {
-      struct variable *var = dict_lookup_var (d, rename_old_names[i]);
-      if (var == NULL)
-        continue;
-
-      rename_vars[n_rename] = var;
-      rename_new_names[n_rename] = vm->new_names[i];
-      n_rename++;
-    }
-
-  /* Do renaming. */
-  if (dict_rename_vars (d, rename_vars, rename_new_names, n_rename,
-                        NULL) == 0)
-    NOT_REACHED ();
-
-  /* Clean up. */
-  for (size_t i = 0; i < vm->n_rename; i++)
-    free (rename_old_names[i]);
-  free (rename_old_names);
-  free (rename_vars);
-  free (rename_new_names);
-
-  return true;
-}
index 095ed03579ab3c280702c1d761f8b678c0e5dbb6..e1889532e0959c31a59e91270c2b6af702b756d1 100644 (file)
@@ -378,7 +378,6 @@ TESTSUITE_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 \
diff --git a/tests/language/dictionary/modify-variables.at b/tests/language/dictionary/modify-variables.at
deleted file mode 100644 (file)
index be79d74..0000000
+++ /dev/null
@@ -1,255 +0,0 @@
-dnl PSPP - a program for statistical analysis.
-dnl Copyright (C) 2017, 2020 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.14-16.19: error: MODIFY VARS: MODIFY VARS may not be used to delete all variables from the active dataset dictionary.  Use NEW FILE instead.
-   16 | MODIFY VARS /DROP y.
-      |              ^~~~~~"
-
-modify-variables.sps:17: error: Stopping syntax file processing here to avoid a cascade of dependent command failures.
-])
-AT_CLEANUP
-
-AT_SETUP([MODIFY VARS crash])
-AT_DATA([modify-variables.sps], [dnl
-DATA LIST notable LIST /a b c (F2.0).
-BEGIN DATA.
-1 2 3
-END DATA.
-
-MODIFY VARS /RENAME (a 4 c = one two three).
-])
-
-AT_CHECK([pspp -O format=csv modify-variables.sps], [1], [ignore])
-
-AT_CLEANUP