+
+ return error;
+}
+
+bool
+data_in_msg (struct substring input, const char *input_encoding,
+ enum fmt_type format, const struct fmt_settings *settings,
+ union value *output, int width, const char *output_encoding)
+{
+ char *error = data_in (input, input_encoding, format, settings,
+ output, width, output_encoding);
+ if (error != NULL)
+ {
+ msg (SW, _("Data is not valid as format %s: %s"),
+ fmt_name (format), error);
+ free (error);
+ return false;
+ }
+ else
+ return true;
+}
+
+static bool
+number_has_implied_decimals (const struct fmt_settings *settings,
+ const char *s, enum fmt_type type)
+{
+ int decimal = fmt_settings_get_style (settings, type)->decimal;
+ bool got_digit = false;
+ for (;;)
+ {
+ switch (*s)
+ {
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ got_digit = true;
+ break;
+
+ case '+': case '-':
+ if (got_digit)
+ return false;
+ break;
+
+ case 'e': case 'E': case 'd': case 'D':
+ return false;
+
+ case '.': case ',':
+ if (*s == decimal)
+ return false;
+ break;
+
+ case '\0':
+ return true;
+
+ default:
+ break;
+ }
+
+ s++;
+ }
+}
+
+static bool
+has_implied_decimals (struct substring input, const char *input_encoding,
+ enum fmt_type format,
+ const struct fmt_settings *settings)
+{
+ bool retval;
+ char *s;
+
+ switch (format)
+ {
+ case FMT_F:
+ case FMT_COMMA:
+ case FMT_DOT:
+ case FMT_DOLLAR:
+ case FMT_PCT:
+ case FMT_E:
+ case FMT_Z:
+ break;
+
+ case FMT_N:
+ case FMT_IB:
+ case FMT_PIB:
+ case FMT_P:
+ case FMT_PK:
+ return true;
+
+ default:
+ return false;
+ }
+
+ s = recode_string (C_ENCODING, input_encoding,
+ ss_data (input), ss_length (input));
+ retval = (format == FMT_Z
+ ? strchr (s, '.') == NULL
+ : number_has_implied_decimals (settings, s, format));
+ free (s);
+
+ return retval;