CORRELATIONS: Improve error messages and coding style.
[pspp] / src / language / stats / matrix.c
index ba6a1402074926f8aefc84e4aadd86b0c6729c8c..69c6323ef48152076b9c953bf2b4aaea13f2dc27 100644 (file)
@@ -6135,10 +6135,15 @@ save_file_open (struct save_file *sf, gsl_matrix *m,
           for (size_t i = 0; i < nv.size; i++)
             {
               char *name = trimmed_string (gsl_vector_get (&nv, i));
-              if (dict_id_is_valid (dict, name, true))
+              char *error = dict_id_is_valid__ (dict, name);
+              if (!error)
                 string_array_append_nocopy (&names, name);
               else
-                ok = false;
+                {
+                  msg_at (SE, save_location, "%s", error);
+                  free (error);
+                  ok = false;
+                }
             }
         }
       gsl_matrix_free (nm);
@@ -6260,6 +6265,8 @@ matrix_save_parse (struct matrix_state *s)
   if (!save->expression)
     goto error;
 
+  int names_start = 0;
+  int names_end = 0;
   while (lex_match (s->lexer, T_SLASH))
     {
       if (lex_match_id (s->lexer, "OUTFILE"))
@@ -6297,7 +6304,9 @@ matrix_save_parse (struct matrix_state *s)
         {
           lex_match (s->lexer, T_EQUALS);
           matrix_expr_destroy (names);
+          names_start = lex_ofs (s->lexer);
           names = matrix_parse_exp (s);
+          names_end = lex_ofs (s->lexer) - 1;
           if (!names)
             goto error;
         }
@@ -6326,7 +6335,7 @@ matrix_save_parse (struct matrix_state *s)
         fh = fh_ref (s->prev_save_file);
       else
         {
-          lex_sbc_missing ("OUTFILE");
+          lex_sbc_missing (s->lexer, "OUTFILE");
           goto error;
         }
     }
@@ -6335,7 +6344,8 @@ matrix_save_parse (struct matrix_state *s)
 
   if (variables.n && names)
     {
-      msg (SW, _("VARIABLES and NAMES both specified; ignoring NAMES."));
+      lex_ofs_msg (s->lexer, SW, names_start, names_end,
+                   _("Ignoring NAMES because VARIABLES was also specified."));
       matrix_expr_destroy (names);
       names = NULL;
     }
@@ -6591,7 +6601,7 @@ matrix_read_parse (struct matrix_state *s)
 
   if (!read->c1)
     {
-      lex_sbc_missing ("FIELD");
+      lex_sbc_missing (s->lexer, "FIELD");
       goto error;
     }
 
@@ -6610,7 +6620,7 @@ matrix_read_parse (struct matrix_state *s)
         fh = fh_ref (s->prev_read_file);
       else
         {
-          lex_sbc_missing ("FILE");
+          lex_sbc_missing (s->lexer, "FILE");
           goto error;
         }
     }
@@ -7167,7 +7177,7 @@ matrix_write_parse (struct matrix_state *s)
 
   if (!write->c1)
     {
-      lex_sbc_missing ("FIELD");
+      lex_sbc_missing (s->lexer, "FIELD");
       goto error;
     }
 
@@ -7177,7 +7187,7 @@ matrix_write_parse (struct matrix_state *s)
         fh = fh_ref (s->prev_write_file);
       else
         {
-          lex_sbc_missing ("OUTFILE");
+          lex_sbc_missing (s->lexer, "OUTFILE");
           goto error;
         }
     }
@@ -7244,9 +7254,38 @@ matrix_write_parse (struct matrix_state *s)
       write->format = xmalloc (sizeof *write->format);
       *write->format = (struct fmt_spec) { .type = format, .w = w };
 
-      if (!fmt_check_output (write->format))
-        goto error;
-    };
+      char *error = fmt_check_output__ (write->format);
+      if (error)
+        {
+          msg (SE, "%s", error);
+          free (error);
+
+          if (has_format)
+            lex_ofs_msg (s->lexer, SN, format_ofs, format_ofs,
+                         _("This syntax specifies format %s."),
+                         fmt_name (format));
+
+          if (repetitions)
+            {
+              lex_ofs_msg (s->lexer, SN, format_ofs, format_ofs,
+                           ngettext ("This syntax specifies %d repetition.",
+                                     "This syntax specifies %d repetitions.",
+                                     repetitions),
+                           repetitions);
+              lex_ofs_msg (s->lexer, SN, record_width_start, record_width_end,
+                           _("This syntax designates record width %d, "
+                             "which divided by %d repetitions implies "
+                             "field width %d."),
+                           record_width, repetitions, w);
+            }
+
+          if (by)
+            lex_ofs_msg (s->lexer, SN, by_ofs, by_ofs,
+                         _("This syntax specifies field width %d."), by);
+
+          goto error;
+        }
+    }
 
   if (write->format && fmt_var_width (write->format) > sizeof (double))
     {
@@ -7891,7 +7930,7 @@ matrix_msave_parse (struct matrix_state *s)
     }
   if (!msave->rowtype)
     {
-      lex_sbc_missing ("TYPE");
+      lex_sbc_missing (s->lexer, "TYPE");
       goto error;
     }
 
@@ -7909,7 +7948,7 @@ matrix_msave_parse (struct matrix_state *s)
         }
       if (!common->outfile)
         {
-          lex_sbc_missing ("OUTFILE");
+          lex_sbc_missing (s->lexer, "OUTFILE");
           goto error;
         }
       common->location = lex_ofs_location (s->lexer, start_ofs,