MATCH FILES, UPDATE, ADD FILES: Improve error messages.
[pspp] / src / language / stats / descriptives.c
index 160e45610f4057bd28a269d9c1b9a94eda47c073..ce4e19576b6f4835983d905405f4c0b5dfb68d86 100644 (file)
@@ -214,6 +214,7 @@ cmd_descriptives (struct lexer *lexer, struct dataset *ds)
   dsc->z_writer = NULL;
 
   /* Parse DESCRIPTIVES. */
+  int z_ofs = 0;
   while (lex_token (lexer) != T_ENDCMD)
     {
       if (lex_match_id (lexer, "MISSING"))
@@ -236,7 +237,10 @@ cmd_descriptives (struct lexer *lexer, struct dataset *ds)
             }
         }
       else if (lex_match_id (lexer, "SAVE"))
-        save_z_scores = 1;
+        {
+          save_z_scores = 1;
+          z_ofs = lex_ofs (lexer) - 1;
+        }
       else if (lex_match_id (lexer, "FORMAT"))
         {
           lex_match (lexer, T_EQUALS);
@@ -335,11 +339,9 @@ cmd_descriptives (struct lexer *lexer, struct dataset *ds)
 
               if (lex_match (lexer, T_LPAREN))
                 {
-                  if (lex_token (lexer) != T_ID)
-                    {
-                      lex_error (lexer, NULL);
-                      goto error;
-                    }
+                  if (!lex_force_id (lexer))
+                    goto error;
+                  z_ofs = lex_ofs (lexer);
                   if (try_name (dict, dsc, lex_tokcstr (lexer)))
                     {
                       struct dsc_var *dsc_var = &dsc->vars[dsc->n_vars - 1];
@@ -347,8 +349,9 @@ cmd_descriptives (struct lexer *lexer, struct dataset *ds)
                       n_zs++;
                     }
                   else
-                    msg (SE, _("Z-score variable name %s would be"
-                               " a duplicate variable name."), lex_tokcstr (lexer));
+                    lex_error (lexer, _("Z-score variable name %s would be "
+                                        "a duplicate variable name."),
+                               lex_tokcstr (lexer));
                   lex_get (lexer);
                   if (!lex_force_match (lexer, T_RPAREN))
                    goto error;
@@ -398,8 +401,9 @@ cmd_descriptives (struct lexer *lexer, struct dataset *ds)
          that) when TEMPORARY is in effect, but in the meantime this at least
          prevents a use-after-free error.  See bug #38786.  */
       if (proc_make_temporary_transformations_permanent (ds))
-        msg (SW, _("DESCRIPTIVES with Z scores ignores TEMPORARY.  "
-                   "Temporary transformations will be made permanent."));
+        lex_ofs_msg (lexer, SW, z_ofs, z_ofs,
+                     _("DESCRIPTIVES with Z scores ignores TEMPORARY.  "
+                       "Temporary transformations will be made permanent."));
 
       proto = caseproto_create ();
       for (i = 0; i < 1 + 2 * n_zs; i++)
@@ -468,13 +472,15 @@ match_statistic (struct lexer *lexer)
 {
   if (lex_token (lexer) == T_ID)
     {
-      enum dsc_statistic stat;
-
-      for (stat = 0; stat < DSC_N_STATS; stat++)
+      for (enum dsc_statistic stat = 0; stat < DSC_N_STATS; stat++)
         if (lex_match_id (lexer, dsc_info[stat].identifier))
          return stat;
 
-      lex_error (lexer, _("expecting statistic name: reverting to default"));
+      const char *stat_names[DSC_N_STATS];
+      for (enum dsc_statistic stat = 0; stat < DSC_N_STATS; stat++)
+        stat_names[stat] = dsc_info[stat].identifier;
+      lex_error_expecting_array (lexer, stat_names,
+                                 sizeof stat_names / sizeof *stat_names);
       lex_get (lexer);
     }