- else if (SYMBOLP (args[n]))
- {
- args[n] = SYMBOL_NAME (args[n]);
- if (STRING_MULTIBYTE (args[n]) && ! multibyte)
- {
- multibyte = 1;
- goto retry;
- }
- goto string;
- }
- else if (STRINGP (args[n]))
- {
- string:
- if (*format != 's' && *format != 'S')
- error ("Format specifier doesn't match argument type");
- /* In the case (PRECISION[N] > 0), THISSIZE may not need
- to be as large as is calculated here. Easy check for
- the case PRECISION = 0. */
- thissize = precision[n] ? CONVERTED_BYTE_SIZE (multibyte, args[n]) : 0;
- /* The precision also constrains how much of the argument
- string will finally appear (Bug#5710). */
- actual_width = lisp_string_width (args[n], -1, NULL, NULL);
- if (precision[n] != -1)
- actual_width = min (actual_width, precision[n]);
- }
- /* Would get MPV otherwise, since Lisp_Int's `point' to low memory. */
- else if (INTEGERP (args[n]) && *format != 's')
- {
- /* The following loop assumes the Lisp type indicates
- the proper way to pass the argument.
- So make sure we have a flonum if the argument should
- be a double. */
- if (*format == 'e' || *format == 'f' || *format == 'g')
- args[n] = Ffloat (args[n]);
- else
- if (*format != 'd' && *format != 'o' && *format != 'x'
- && *format != 'i' && *format != 'X' && *format != 'c')
- error ("Invalid format operation %%%c", *format);
-
- thissize = 30 + (precision[n] > 0 ? precision[n] : 0);
- if (*format == 'c')
- {
- if (! ASCII_CHAR_P (XINT (args[n]))
- /* Note: No one can remember why we have to treat
- the character 0 as a multibyte character here.
- But, until it causes a real problem, let's
- don't change it. */
- || XINT (args[n]) == 0)
- {
- if (! multibyte)
- {
- multibyte = 1;
- goto retry;
- }
- args[n] = Fchar_to_string (args[n]);
- thissize = SBYTES (args[n]);
- }
- }
- }
- else if (FLOATP (args[n]) && *format != 's')
- {
- if (! (*format == 'e' || *format == 'f' || *format == 'g'))
- {
- if (*format != 'd' && *format != 'o' && *format != 'x'
- && *format != 'i' && *format != 'X' && *format != 'c')
- error ("Invalid format operation %%%c", *format);
- /* This fails unnecessarily if args[n] is bigger than
- most-positive-fixnum but smaller than MAXINT.
- These cases are important because we sometimes use floats
- to represent such integer values (typically such values
- come from UIDs or PIDs). */
- /* args[n] = Ftruncate (args[n], Qnil); */
- }
-
- /* Note that we're using sprintf to print floats,
- so we have to take into account what that function
- prints. */
- /* Filter out flag value of -1. */
- thissize = (MAX_10_EXP + 100
- + (precision[n] > 0 ? precision[n] : 0));
- }
- else
- {
- /* Anything but a string, convert to a string using princ. */
- register Lisp_Object tem;
- tem = Fprin1_to_string (args[n], Qt);
- if (STRING_MULTIBYTE (tem) && ! multibyte)
- {
- multibyte = 1;
- goto retry;
- }
- args[n] = tem;
- goto string;
- }
-
- thissize += max (0, field_width - actual_width);
- total += thissize + 4;
- }
-
- abort_on_gc--;
-
- /* Now we can no longer jump to retry.
- TOTAL and LONGEST_FORMAT are known for certain. */
-
- this_format = (char *) alloca (longest_format + 1);
-
- /* Allocate the space for the result.
- Note that TOTAL is an overestimate. */
- SAFE_ALLOCA (buf, char *, total);
-
- p = buf;
- nchars = 0;
- n = 0;
-
- /* Scan the format and store result in BUF. */
- format = SSDATA (args[0]);
- format_start = format;
- end = format + SBYTES (args[0]);
- maybe_combine_byte = 0;
- while (format != end)
- {
- if (*format == '%')
- {
- int minlen;
- int negative = 0;
- char *this_format_start = format;
-