format: Cite variable names in messages reporting incompatible width.
authorBen Pfaff <blp@cs.stanford.edu>
Sat, 10 Sep 2022 18:12:33 +0000 (11:12 -0700)
committerBen Pfaff <blp@cs.stanford.edu>
Sat, 10 Sep 2022 18:14:04 +0000 (11:14 -0700)
src/data/format.c
src/data/format.h
src/data/por-file-reader.c
src/data/variable.c
src/language/data-io/print.c
src/language/dictionary/formats.c
src/output/spv/spv.c
tests/language/dictionary/formats.at

index 17afda6162b4f3bba021ebdad00660ff2fae25a9..8c1c467398e087bffde4d85decb8de9fb3db50ea 100644 (file)
@@ -518,9 +518,11 @@ fmt_check_type_compat (const struct fmt_spec *format, enum val_type var_type)
 
 /* Checks that FORMAT is appropriate for a variable of the given WIDTH and
    returns NULL if so.  Otherwise returns a malloc()'d error message that the
-   calelr must eventually free(). */
+   caller must eventually free().  VARNAME is optional and only used in the
+   error message. */
 char *
-fmt_check_width_compat__ (const struct fmt_spec *format, int width)
+fmt_check_width_compat__ (const struct fmt_spec *format, const char *varname,
+                          int width)
 {
   char *error = fmt_check_type_compat__ (format, val_type_from_width (width));
   if (error)
@@ -528,22 +530,31 @@ fmt_check_width_compat__ (const struct fmt_spec *format, int width)
 
   if (fmt_var_width (format) != width)
     {
-      char str[FMT_STRING_LEN_MAX + 1];
-      return xasprintf (_("String variable with width %d is not compatible "
-                          "with format %s."),
-                        width, fmt_to_string (format, str));
+      char format_str[FMT_STRING_LEN_MAX + 1];
+      fmt_to_string (format, format_str);
+
+      if (varname)
+        return xasprintf (_("String variable %s with width %d is not "
+                            "compatible with format %s."),
+                          varname, width, format_str);
+        else
+        return xasprintf (_("String variable with width %d is not compatible "
+                            "with format %s."),
+                          width, format_str);
     }
 
   return NULL;
 }
 
-/* Checks that FORMAT is appropriate for a variable of the given
-   WIDTH and returns true if so.  Otherwise returns false and
-   emits an error message. */
+/* Checks that FORMAT is appropriate for a variable of the given WIDTH and
+   returns true if so.  Otherwise returns false and emits an error message.
+   VARNAME is optional and only used in the error message. */
 bool
-fmt_check_width_compat (const struct fmt_spec *format, int width)
+fmt_check_width_compat (const struct fmt_spec *format, const char *varname,
+                        int width)
 {
-  return fmt_emit_and_free_error (fmt_check_width_compat__ (format, width));
+  return fmt_emit_and_free_error (fmt_check_width_compat__ (format, varname,
+                                                            width));
 }
 
 /* Returns the width corresponding to FORMAT.  The return value
@@ -1020,7 +1031,7 @@ fmt_from_u32 (uint32_t u32, int width, bool loose, struct fmt_spec *f)
         ok = fmt_check_output (f);
     }
   if (ok)
-    ok = fmt_check_width_compat (f, width);
+    ok = fmt_check_width_compat (f, NULL, width);
   msg_enable ();
 
   return ok;
index 8c54ba3a171448121cc0b4911b3146a21b34e510..5fe6c101f8a7a1cc9261aaa5431f578fb9e64962 100644 (file)
@@ -95,11 +95,13 @@ bool fmt_check (const struct fmt_spec *, enum fmt_use);
 bool fmt_check_input (const struct fmt_spec *);
 bool fmt_check_output (const struct fmt_spec *);
 bool fmt_check_type_compat (const struct fmt_spec *, enum val_type);
-bool fmt_check_width_compat (const struct fmt_spec *, int var_width);
+bool fmt_check_width_compat (const struct fmt_spec *, const char *varname,
+                             int var_width);
 
 char *fmt_check__ (const struct fmt_spec *, enum fmt_use);
 char *fmt_check_type_compat__ (const struct fmt_spec *, enum val_type);
-char *fmt_check_width_compat__ (const struct fmt_spec *, int var_width);
+char *fmt_check_width_compat__ (const struct fmt_spec *, const char *varname,
+                                int var_width);
 
 /* Working with formats. */
 int fmt_var_width (const struct fmt_spec *);
index 7f32d2cf8f359d4ebd9dd718e58410abeb134448..9ae6799ac45141ad4952ef3b21f14374051136b0 100644 (file)
@@ -640,7 +640,8 @@ convert_format (struct pfm_reader *r, const int portable_format[3],
 
   msg_disable ();
   ok = (fmt_check_output (&format)
-        && fmt_check_width_compat (&format, var_get_width (v)));
+        && fmt_check_width_compat (&format, var_get_name (v),
+                                   var_get_width (v)));
   msg_enable ();
 
   if (!ok)
index 87e7d07823f42271707000938d7501a24f562250..3c6bea271775d273034c637855c39fa5976869a2 100644 (file)
@@ -634,7 +634,7 @@ var_set_print_format_quiet (struct variable *v, const struct fmt_spec *print)
 {
   if (!fmt_equal (&v->print, print))
     {
-      assert (fmt_check_width_compat (print, v->width));
+      assert (fmt_check_width_compat (print, v->name, v->width));
       v->print = *print;
     }
 }
@@ -667,7 +667,7 @@ var_set_write_format_quiet (struct variable *v, const struct fmt_spec *write)
 {
   if (!fmt_equal (&v->write, write))
     {
-      assert (fmt_check_width_compat (write, v->width));
+      assert (fmt_check_width_compat (write, v->name, v->width));
       v->write = *write;
     }
 }
index 3b5f901b5342bfb4ab16028adbd8769b2980ca22..906730dce389b14bc9fcbdb2a1696055686dd0f1 100644 (file)
@@ -398,7 +398,8 @@ parse_variable_argument (struct lexer *lexer, const struct dictionary *dict,
         struct prt_out_spec *spec;
 
         var = vars[var_idx++];
-        if (!fmt_check_width_compat (f, var_get_width (var)))
+        if (!fmt_check_width_compat (f, var_get_name (var),
+                                     var_get_width (var)))
           return false;
 
         spec = pool_alloc (trns->pool, sizeof *spec);
index 817cdbd6d922cd03dc401a073214116cf8f9ec32..b2cc3a5c394d7f009750474f017c114fdae79393 100644 (file)
@@ -89,7 +89,7 @@ internal_cmd_formats (struct lexer *lexer, struct dataset *ds, int which)
        }
       if (!parse_format_specifier (lexer, &f)
           || !fmt_check_output (&f)
-          || !fmt_check_width_compat (&f, width))
+          || !fmt_check_width_compat (&f, var_get_name (v[0]), width))
        goto fail;
 
       if (!lex_match (lexer, T_RPAREN))
index 4547e967945a3c776cdcd97b9b9f6398de43694e..04aa6106459ecc6c668030fb7a5ce8c32880b9e4 100644 (file)
@@ -888,7 +888,7 @@ spv_decode_fmt_spec (uint32_t u32, struct fmt_spec *out)
   if (ok)
     {
       fmt_fix_output (out);
-      ok = fmt_check_width_compat (out, 0);
+      ok = fmt_check_width_compat (out, NULL, 0);
     }
   msg_enable ();
 
index 98019ae7e5871bca2ddf125211554508b926c429..93e135b10680dd812c22ce86ac61175992ede6be 100644 (file)
@@ -90,14 +90,14 @@ z,A3
     3 | FORMATS a y (F4).
       |           ^"
 
-formats.sps:4: error: FORMATS: String variable with width 1 is not compatible with format A2.
+formats.sps:4: error: FORMATS: String variable with width 1 is not compatible with format A2.
 
-formats.sps:5: error: FORMATS: String variable with width 2 is not compatible with format AHEX2.
+formats.sps:5: error: FORMATS: String variable with width 2 is not compatible with format AHEX2.
 
 "formats.sps:6.11: error: FORMATS: x and y are string variables with different widths.  All variables in this variable list must have the same width.  y will be omitted from the list.
     6 | FORMATS x y (A2).
       |           ^"
 
-formats.sps:6: error: FORMATS: String variable with width 1 is not compatible with format A2.
+formats.sps:6: error: FORMATS: String variable with width 1 is not compatible with format A2.
 ])
 AT_CLEANUP