Assorted improvements to diagnostics.
[pspp] / src / language / dictionary / modify-variables.c
index 98a588b15be47d1d7cbd889a044b0dba6796cc9e..e23d6a418dea7c34ae61d08532d681fc94aada67 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"
@@ -77,9 +76,10 @@ int
 cmd_modify_vars (struct lexer *lexer, struct dataset *ds)
 {
   if (proc_make_temporary_transformations_permanent (ds))
-    msg (SE, _("%s may not be used after %s.  "
-               "Temporary transformations will be made permanent."),
-         "MODIFY VARS", "TEMPORARY");
+    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. */
@@ -108,7 +108,7 @@ cmd_modify_vars (struct lexer *lexer, struct dataset *ds)
        {
          if (already_encountered & 1)
            {
-              lex_sbc_only_once ("REORDER");
+              lex_sbc_only_once (lexer, "REORDER");
              goto done;
            }
          already_encountered |= 1;
@@ -154,7 +154,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,7 +166,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, "`)'");
                      free (v);
                      goto done;
                    }
@@ -188,7 +188,7 @@ cmd_modify_vars (struct lexer *lexer, struct dataset *ds)
        {
          if (already_encountered & 2)
            {
-              lex_sbc_only_once ("RENAME");
+              lex_sbc_only_once (lexer, "RENAME");
              goto done;
            }
          already_encountered |= 2;
@@ -201,7 +201,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),
@@ -210,7 +210,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;
                }
 
@@ -230,7 +230,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;
                }
            }
@@ -241,10 +241,11 @@ cmd_modify_vars (struct lexer *lexer, struct dataset *ds)
        {
          if (already_encountered & 4)
            {
-             msg (SE,
-                   _("%s subcommand may be given at most once.  It may "
-                     "not be given in conjunction with the %s subcommand."),
-                  "KEEP", "DROP");
+             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;
@@ -292,27 +293,31 @@ cmd_modify_vars (struct lexer *lexer, struct dataset *ds)
 
          if (already_encountered & 4)
            {
-             msg (SE, _("%s subcommand may be given at most once.  It may "
-                         "not be given in conjunction with the %s "
-                         "subcommand."),
+             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_var_cnt (dataset_dict (ds)))
+          if (n_drop == dict_get_n_vars (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");
+              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;
             }
        }
@@ -328,11 +333,8 @@ cmd_modify_vars (struct lexer *lexer, struct dataset *ds)
        }
       else
        {
-         if (lex_token (lexer) == T_ID)
-           msg (SE, _("Unrecognized subcommand name `%s'."),
-                 lex_tokcstr (lexer));
-         else
-           msg (SE, _("Subcommand name expected."));
+          lex_error_expecting (lexer, "REORDER", "RENAME", "KEEP",
+                               "DROP", "MAP");
          goto done;
        }
 
@@ -340,7 +342,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);
@@ -361,8 +363,9 @@ cmd_modify_vars (struct lexer *lexer, struct dataset *ds)
 done:
   free (vm.reorder_vars);
   free (vm.rename_vars);
-  for (size_t i = 0; i < vm.n_rename; i++)
-    free (vm.new_names[i]);
+  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;