(format "%s" @var{arbitrary-string})
@end example
- If @var{string} contains more than one format specification and none
-of the format specifications contain an explicit field number, the
-format specifications correspond to successive values from
-@var{objects}. Thus, the first format specification in @var{string}
-uses the first such value, the second format specification uses the
-second such value, and so on. Any extra format specifications (those
-for which there are no corresponding values) cause an error. Any
-extra values to be formatted are ignored.
-
Certain format specifications require values of particular types. If
you supply a value that doesn't fit the requirements, an error is
signaled.
@end group
@end example
+ By default, format specifications correspond to successive values from
+@var{objects}. Thus, the first format specification in @var{string}
+uses the first such value, the second format specification uses the
+second such value, and so on. Any extra format specifications (those
+for which there are no corresponding values) cause an error. Any
+extra values to be formatted are ignored.
+
@cindex field numbers in format spec
- A specification can have a @dfn{field number}, which is a decimal
-number after the initial @samp{%}, followed by a literal dollar sign
-@samp{$}. If you provide a field number, then the argument to be
-printed corresponds to the given field number instead of the next
-argument. Field numbers start at 1.
+ A format specification can have a @dfn{field number}, which is a
+decimal number immediately after the initial @samp{%}, followed by a
+literal dollar sign @samp{$}. It causes the format specification to
+convert the argument with the given number instead of the next
+argument. Argument 1 is the argument just after the format.
-You can mix specifications with and without field numbers. A
+ You can mix specifications with and without field numbers. A
specification without a field number that follows a specification with
a field number will convert the argument after the one specified by
the field number:
@example
-(format "First argument %2$s, then %s, then %1$s" 1 2 3)
- @result{} "First argument 2, then 3, then 1"
-@end example
-
-You can't use field numbers in a @samp{%%} specification.
-
-@cindex field width
-@cindex padding
- A specification can have a @dfn{width}, which is a decimal number
-between the @samp{%} and the specification character. If the printed
-representation of the object contains fewer characters than this
-width, @code{format} extends it with padding. The width specifier is
-ignored for the @samp{%%} specification. Any padding introduced by
-the width specifier normally consists of spaces inserted on the left:
-
-@example
-(format "%5d is padded on the left with spaces" 123)
- @result{} " 123 is padded on the left with spaces"
-@end example
-
-@noindent
-If the width is too small, @code{format} does not truncate the
-object's printed representation. Thus, you can use a width to specify
-a minimum spacing between columns with no risk of losing information.
-In the following two examples, @samp{%7s} specifies a minimum width
-of 7. In the first case, the string inserted in place of @samp{%7s}
-has only 3 letters, and needs 4 blank spaces as padding. In the
-second case, the string @code{"specification"} is 13 letters wide but
-is not truncated.
-
-@example
-@group
-(format "The word '%7s' has %d letters in it."
- "foo" (length "foo"))
- @result{} "The word ' foo' has 3 letters in it."
-(format "The word '%7s' has %d letters in it."
- "specification" (length "specification"))
- @result{} "The word 'specification' has 13 letters in it."
-@end group
+(format "Argument %2$s, then %s, then %1$s" "x" "y" "z")
+ @result{} "Argument y, then z, then x"
@end example
-If you want to use both a field number and a width, place the field
-number before the width. For example, in @samp{%2$7s}, @samp{2} is
-the field number and @samp{7} is the width.
-
@cindex flags in format specifications
- After the @samp{%} and before the optional width specifier, you can
-also put certain @dfn{flag characters}. The flag characters need to
-come directly after a potential field number.
+ After the @samp{%} and any field number, you can put certain
+@dfn{flag characters}.
The flag @samp{+} inserts a plus sign before a positive number, so
that it always has a sign. A space character as flag inserts a space
These specification characters accept the @samp{0} flag, but still pad
with @emph{spaces}.
- The flag @samp{-} causes the padding inserted by the width
-specifier, if any, to be inserted on the right rather than the left.
+ The flag @samp{-} causes any padding inserted by the width,
+if specified, to be inserted on the right rather than the left.
If both @samp{-} and @samp{0} are present, the @samp{0} flag is
ignored.
@end group
@end example
+@cindex field width
+@cindex padding
+ A specification can have a @dfn{width}, which is a decimal number
+that appears after any field number and flags. If the printed
+representation of the object contains fewer characters than this
+width, @code{format} extends it with padding. The width is
+ignored for the @samp{%%} specification. Any padding introduced by
+the width normally consists of spaces inserted on the left:
+
+@example
+(format "%5d is padded on the left with spaces" 123)
+ @result{} " 123 is padded on the left with spaces"
+@end example
+
+@noindent
+If the width is too small, @code{format} does not truncate the
+object's printed representation. Thus, you can use a width to specify
+a minimum spacing between columns with no risk of losing information.
+In the following two examples, @samp{%7s} specifies a minimum width
+of 7. In the first case, the string inserted in place of @samp{%7s}
+has only 3 letters, and needs 4 blank spaces as padding. In the
+second case, the string @code{"specification"} is 13 letters wide but
+is not truncated.
+
+@example
+@group
+(format "The word '%7s' has %d letters in it."
+ "foo" (length "foo"))
+ @result{} "The word ' foo' has 3 letters in it."
+(format "The word '%7s' has %d letters in it."
+ "specification" (length "specification"))
+ @result{} "The word 'specification' has 13 letters in it."
+@end group
+@end example
+
@cindex precision in format specifications
All the specification characters allow an optional @dfn{precision}
-before the character (after the width, if present). The precision is
+after the field number, flags and width, if present. The precision is
a decimal-point @samp{.} followed by a digit-string. For the
floating-point specifications (@samp{%e} and @samp{%f}), the
precision specifies how many digits following the decimal point to
field-width ::= [0-9]+
precision ::= '.' [0-9]*
- If a field-number is specified, it specifies the argument
- number to substitute. Otherwise, the next argument is
- taken.
+ If present, a field-number specifies the argument number
+ to substitute. Otherwise, the next argument is taken.
If a field-width is specified, it specifies to which width
the output should be padded with blanks, if the output
digits to print after the '.' for floats, or the max.
number of chars to print from a string. */
- char *field_end;
- uintmax_t raw_field = strtoumax (format, &field_end, 10);
- bool has_field = false;
- if (c_isdigit (*format) && *field_end == '$')
- {
- if (raw_field < 1 || raw_field >= PTRDIFF_MAX)
- {
- /* doprnt doesn't support %.*s, so we need to copy
- the field number string. */
- ptrdiff_t length = field_end - format;
- eassert (length > 0);
- eassert (length < PTRDIFF_MAX);
- char *field = SAFE_ALLOCA (length + 1);
- memcpy (field, format, length);
- field[length] = '\0';
- error ("Invalid field number `%s'", field);
- }
- has_field = true;
- /* n is incremented below. */
- n = raw_field - 1;
- format = field_end + 1;
- }
+ uintmax_t num;
+ char *num_end;
+ if (c_isdigit (*format))
+ {
+ num = strtoumax (format, &num_end, 10);
+ if (*num_end == '$')
+ {
+ if (num == 0)
+ error ("Invalid format field number 0");
+ n = min (num, PTRDIFF_MAX);
+ n--;
+ format = num_end + 1;
+ }
+ }
bool minus_flag = false;
bool plus_flag = false;
space_flag &= ! plus_flag;
zero_flag &= ! minus_flag;
- char *num_end;
- uintmax_t raw_field_width = strtoumax (format, &num_end, 10);
- if (max_bufsize <= raw_field_width)
+ num = strtoumax (format, &num_end, 10);
+ if (max_bufsize <= num)
string_overflow ();
- ptrdiff_t field_width = raw_field_width;
+ ptrdiff_t field_width = num;
bool precision_given = *num_end == '.';
uintmax_t precision = (precision_given
memset (&discarded[format0 - format_start], 1,
format - format0 - (conversion == '%'));
if (conversion == '%')
- {
- if (has_field)
- /* FIXME: `error' doesn't appear to support `%%'. */
- error ("Field number specified together with `%c' conversion",
- '%');
- goto copy_char;
- }
+ goto copy_char;
++n;
if (! (n < nargs))