MATCH FILES, UPDATE, ADD FILES: Improve error messages.
[pspp] / src / language / stats / descriptives.c
index fdb454c2600af97bbffdb0a609d698d20885776c..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,14 +472,16 @@ 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;
 
+      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);
-      lex_error (lexer, _("expecting statistic name: reverting to default"));
     }
 
   return DSC_NONE;
@@ -722,15 +728,15 @@ static void
 setup_z_trns (struct dsc_proc *dsc, struct dataset *ds)
 {
   struct dsc_trns *t;
-  size_t cnt, i;
+  size_t n, i;
 
-  for (cnt = i = 0; i < dsc->n_vars; i++)
+  for (n = i = 0; i < dsc->n_vars; i++)
     if (dsc->vars[i].z_name != NULL)
-      cnt++;
+      n++;
 
   t = xmalloc (sizeof *t);
-  t->z_scores = xnmalloc (cnt, sizeof *t->z_scores);
-  t->n_z_scores = cnt;
+  t->z_scores = xnmalloc (n, sizeof *t->z_scores);
+  t->n_z_scores = n;
   t->missing_type = dsc->missing_type;
   t->exclude = dsc->exclude;
   if (t->missing_type == DSC_LISTWISE)
@@ -751,7 +757,7 @@ setup_z_trns (struct dsc_proc *dsc, struct dataset *ds)
   t->ok = true;
   dsc->z_writer = NULL;
 
-  for (cnt = i = 0; i < dsc->n_vars; i++)
+  for (n = i = 0; i < dsc->n_vars; i++)
     {
       struct dsc_var *dv = &dsc->vars[i];
       if (dv->z_name != NULL)
@@ -766,7 +772,7 @@ setup_z_trns (struct dsc_proc *dsc, struct dataset *ds)
           var_set_label (dst_var, label);
           free (label);
 
-          z = &t->z_scores[cnt++];
+          z = &t->z_scores[n++];
           z->src_var = dv->v;
           z->z_var = dst_var;
        }