Improve error messages for format specifiers.
[pspp] / src / language / stats / matrix.c
index 7c8d6519d18270b01d8b50c317d14e424c885351..7e9bd54658ff8db3a37b56cdba26ad6197f5d255 100644 (file)
@@ -6331,7 +6331,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;
         }
     }
@@ -6596,7 +6596,7 @@ matrix_read_parse (struct matrix_state *s)
 
   if (!read->c1)
     {
-      lex_sbc_missing ("FIELD");
+      lex_sbc_missing (s->lexer, "FIELD");
       goto error;
     }
 
@@ -6615,7 +6615,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;
         }
     }
@@ -7172,7 +7172,7 @@ matrix_write_parse (struct matrix_state *s)
 
   if (!write->c1)
     {
-      lex_sbc_missing ("FIELD");
+      lex_sbc_missing (s->lexer, "FIELD");
       goto error;
     }
 
@@ -7182,7 +7182,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;
         }
     }
@@ -7249,9 +7249,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))
     {
@@ -7896,7 +7925,7 @@ matrix_msave_parse (struct matrix_state *s)
     }
   if (!msave->rowtype)
     {
-      lex_sbc_missing ("TYPE");
+      lex_sbc_missing (s->lexer, "TYPE");
       goto error;
     }
 
@@ -7914,7 +7943,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,