43 |
/* Common formats. */ |
/* Common formats. */ |
44 |
const struct fmt_spec f8_2 = {FMT_F, 8, 2}; |
const struct fmt_spec f8_2 = {FMT_F, 8, 2}; |
45 |
|
|
|
/* Parses the alphabetic prefix of the current token as a format |
|
|
specifier name. Returns the corresponding format specifier |
|
|
type if successful, or -1 on failure. If ALLOW_XT is zero, |
|
|
then X and T format specifiers are not allowed. If CP is |
|
|
nonzero, then *CP is set to the first non-alphabetic character |
|
|
in the current token on success or to a null pointer on |
|
|
failure. */ |
|
|
int |
|
|
parse_format_specifier_name (const char **cp, enum fmt_parse_flags flags) |
|
|
{ |
|
|
char *sp, *ep; |
|
|
int idx; |
|
|
|
|
|
sp = ep = ds_c_str (&tokstr); |
|
|
while (isalpha ((unsigned char) *ep)) |
|
|
ep++; |
|
|
|
|
|
if (sp != ep) |
|
|
{ |
|
|
/* Find format. */ |
|
|
for (idx = 0; idx < FMT_NUMBER_OF_FORMATS; idx++) |
|
|
if (strlen (formats[idx].name) == ep - sp |
|
|
&& !buf_compare_case (formats[idx].name, sp, ep - sp)) |
|
|
break; |
|
|
|
|
|
/* Check format. */ |
|
|
if (idx < FMT_NUMBER_OF_FORMATS) |
|
|
{ |
|
|
if (!(flags & FMTP_ALLOW_XT) && (idx == FMT_T || idx == FMT_X)) |
|
|
{ |
|
|
if (!(flags & FMTP_SUPPRESS_ERRORS)) |
|
|
msg (SE, _("X and T format specifiers not allowed here.")); |
|
|
idx = -1; |
|
|
} |
|
|
} |
|
|
else |
|
|
{ |
|
|
/* No match. */ |
|
|
if (!(flags & FMTP_SUPPRESS_ERRORS)) |
|
|
msg (SE, _("%.*s is not a valid data format."), |
|
|
(int) (ep - sp), ds_c_str (&tokstr)); |
|
|
idx = -1; |
|
|
} |
|
|
} |
|
|
else |
|
|
{ |
|
|
lex_error ("expecting data format"); |
|
|
idx = -1; |
|
|
} |
|
|
|
|
|
if (cp != NULL) |
|
|
{ |
|
|
if (idx != -1) |
|
|
*cp = ep; |
|
|
else |
|
|
*cp = NULL; |
|
|
} |
|
|
|
|
|
return idx; |
|
|
} |
|
|
|
|
46 |
/* Converts F to its string representation (for instance, "F8.2") and |
/* Converts F to its string representation (for instance, "F8.2") and |
47 |
returns a pointer to a static buffer containing that string. */ |
returns a pointer to a static buffer containing that string. */ |
48 |
char * |
char * |
300 |
assert (check_output_specifier (output, 0)); |
assert (check_output_specifier (output, 0)); |
301 |
} |
} |
302 |
|
|
|
/* Parses a format specifier from the token stream and returns |
|
|
nonzero only if successful. Emits an error message on |
|
|
failure. Allows X and T format specifiers only if ALLOW_XT is |
|
|
nonzero. The caller should call check_input_specifier() or |
|
|
check_output_specifier() on the parsed format as |
|
|
necessary. */ |
|
|
int |
|
|
parse_format_specifier (struct fmt_spec *input, enum fmt_parse_flags flags) |
|
|
{ |
|
|
struct fmt_spec spec; |
|
|
struct fmt_desc *f; |
|
|
const char *cp; |
|
|
char *cp2; |
|
|
int type, w, d; |
|
|
|
|
|
if (token != T_ID) |
|
|
{ |
|
|
if (!(flags & FMTP_SUPPRESS_ERRORS)) |
|
|
msg (SE, _("Format specifier expected.")); |
|
|
return 0; |
|
|
} |
|
|
type = parse_format_specifier_name (&cp, flags); |
|
|
if (type == -1) |
|
|
return 0; |
|
|
f = &formats[type]; |
|
|
|
|
|
w = strtol (cp, &cp2, 10); |
|
|
if (cp2 == cp && type != FMT_X) |
|
|
{ |
|
|
if (!(flags & FMTP_SUPPRESS_ERRORS)) |
|
|
msg (SE, _("Data format %s does not specify a width."), |
|
|
ds_c_str (&tokstr)); |
|
|
return 0; |
|
|
} |
|
|
|
|
|
cp = cp2; |
|
|
if (f->n_args > 1 && *cp == '.') |
|
|
{ |
|
|
cp++; |
|
|
d = strtol (cp, &cp2, 10); |
|
|
cp = cp2; |
|
|
} |
|
|
else |
|
|
d = 0; |
|
|
|
|
|
if (*cp) |
|
|
{ |
|
|
if (!(flags & FMTP_SUPPRESS_ERRORS)) |
|
|
msg (SE, _("Data format %s is not valid."), ds_c_str (&tokstr)); |
|
|
return 0; |
|
|
} |
|
|
lex_get (); |
|
|
|
|
|
spec.type = type; |
|
|
spec.w = w; |
|
|
spec.d = d; |
|
|
*input = spec; |
|
|
|
|
|
return 1; |
|
|
} |
|
|
|
|
303 |
/* Returns the width corresponding to the format specifier. The |
/* Returns the width corresponding to the format specifier. The |
304 |
return value is the value of the `width' member of a `struct |
return value is the value of the `width' member of a `struct |
305 |
variable' for such an input format. */ |
variable' for such an input format. */ |