Don't have previous and next buffers deal with internal windows.
[bpt/emacs.git] / src / doprnt.c
CommitLineData
24f98398 1/* Output like sprintf to a buffer of specified size.
762b15be
EZ
2 Also takes args differently: pass one pointer to the end
3 of the format string in addition to the format string itself.
73b0cd50 4 Copyright (C) 1985, 2001-2011 Free Software Foundation, Inc.
24f98398
JA
5
6This file is part of GNU Emacs.
7
9ec0b715 8GNU Emacs is free software: you can redistribute it and/or modify
24f98398 9it under the terms of the GNU General Public License as published by
9ec0b715
GM
10the Free Software Foundation, either version 3 of the License, or
11(at your option) any later version.
24f98398
JA
12
13GNU Emacs is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
9ec0b715 19along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
24f98398 20
762b15be
EZ
21/* If you think about replacing this with some similar standard C function of
22 the printf family (such as vsnprintf), please note that this function
23 supports the following Emacs-specific features:
24
25 . For %c conversions, it produces a string with the multibyte representation
26 of the (`int') argument, suitable for display in an Emacs buffer.
27
28 . For %s and %c, when field width is specified (e.g., %25s), it accounts for
29 the diplay width of each character, according to char-width-table. That
30 is, it does not assume that each character takes one column on display.
31
32 . If the size of the buffer is not enough to produce the formatted string in
33 its entirety, it makes sure that truncation does not chop the last
34 character in the middle of its multibyte sequence, producing an invalid
35 sequence.
36
37 . It accepts a pointer to the end of the format string, so the format string
38 could include embedded null characters.
39
40 . It signals an error if the length of the formatted string is about to
41 overflow MOST_POSITIVE_FIXNUM, to avoid producing strings longer than what
42 Emacs can handle.
43
44 OTOH, this function supports only a small subset of the standard C formatted
45 output facilities. E.g., %u and %ll are not supported, and precision is
825cd63c
EZ
46 ignored %s and %c conversions. (See below for the detailed documentation of
47 what is supported.) However, this is okay, as this function is supposed to
48 be called from `error' and similar functions, and thus does not need to
49 support features beyond those in `Fformat', which is used by `error' on the
50 Lisp level. */
51
52/* This function supports the following %-sequences in the `format'
53 argument:
54
55 %s means print a string argument.
56 %S is silently treated as %s, for loose compatibility with `Fformat'.
57 %d means print a `signed int' argument in decimal.
825cd63c
EZ
58 %o means print an `unsigned int' argument in octal.
59 %x means print an `unsigned int' argument in hex.
60 %e means print a `double' argument in exponential notation.
61 %f means print a `double' argument in decimal-point notation.
62 %g means print a `double' argument in exponential notation
63 or in decimal-point notation, whichever uses fewer characters.
64 %c means print a `signed int' argument as a single character.
65 %% means produce a literal % character.
66
94dcfacf
EZ
67 A %-sequence may contain optional flag, width, and precision specifiers, and
68 a length modifier, as follows:
825cd63c 69
94dcfacf 70 %<flags><width><precision><length>character
825cd63c 71
b71a1728 72 where flags is [+ -0], width is [0-9]+, precision is .[0-9]+, and length
62f19c19
PE
73 is empty or l or the value of the pD or pI or pMd (sans "d") macros.
74 Also, %% in a format stands for a single % in the output. A % that
75 does not introduce a valid %-sequence causes undefined behavior.
825cd63c
EZ
76
77 The + flag character inserts a + before any positive number, while a space
94dcfacf
EZ
78 inserts a space before any positive number; these flags only affect %d, %o,
79 %x, %e, %f, and %g sequences. The - and 0 flags affect the width specifier,
80 as described below. For signed numerical arguments only, the ` ' (space)
81 flag causes the result to be prefixed with a space character if it does not
82 start with a sign (+ or -).
83
84 The l (lower-case letter ell) length modifier is a `long' data type
85 modifier: it is supported for %d, %o, and %x conversions of integral
54b8e3f7 86 arguments, must immediately precede the conversion specifier, and means that
94dcfacf 87 the respective argument is to be treated as `long int' or `unsigned long
62f19c19
PE
88 int'. Similarly, the value of the pD macro means to use ptrdiff_t,
89 the value of the pI macro means to use EMACS_INT or EMACS_UINT, the
90 value of the pMd etc. macros means to use intmax_t or uintmax_t,
91 and the empty length modifier means `int' or `unsigned int'.
825cd63c
EZ
92
93 The width specifier supplies a lower limit for the length of the printed
94 representation. The padding, if any, normally goes on the left, but it goes
95 on the right if the - flag is present. The padding character is normally a
96 space, but (for numerical arguments only) it is 0 if the 0 flag is present.
97 The - flag takes precedence over the 0 flag.
98
99 For %e, %f, and %g sequences, the number after the "." in the precision
100 specifier says how many decimal places to show; if zero, the decimal point
101 itself is omitted. For %s and %S, the precision specifier is ignored. */
24f98398 102
6d291527 103#include <config.h>
24f98398
JA
104#include <stdio.h>
105#include <ctype.h>
d7306fe6 106#include <setjmp.h>
be65c2f4 107#include <float.h>
48236137 108#include <unistd.h>
e6c3da20 109#include <limits.h>
e6c3da20 110
523e9291
RS
111#include "lisp.h"
112
a0ca925c
KH
113/* Since we use the macro CHAR_HEAD_P, we have to include this, but
114 don't have to include others because CHAR_HEAD_P does not contains
115 another macro. */
83be827a 116#include "character.h"
a0ca925c 117
92bc9a36
DN
118#ifndef DBL_MAX_10_EXP
119#define DBL_MAX_10_EXP 308 /* IEEE double */
120#endif
121
f4c730d3
RS
122/* Generate output from a format-spec FORMAT,
123 terminated at position FORMAT_END.
f40b429d 124 (*FORMAT_END is not part of the format, but must exist and be readable.)
f4c730d3 125 Output goes in BUFFER, which has room for BUFSIZE chars.
f40b429d
PE
126 BUFSIZE must be positive. If the output does not fit, truncate it
127 to fit and return BUFSIZE - 1; if this truncates a multibyte
128 sequence, store '\0' into the sequence's first byte.
825cd63c
EZ
129 Returns the number of bytes stored into BUFFER, excluding
130 the terminating null byte. Output is always null-terminated.
1513af9e
RS
131 String arguments are passed as C strings.
132 Integers are passed as C integers. */
f4c730d3 133
c2d1e36d
PE
134ptrdiff_t
135doprnt (char *buffer, ptrdiff_t bufsize, const char *format,
a8fe7202 136 const char *format_end, va_list ap)
24f98398 137{
a8fe7202 138 const char *fmt = format; /* Pointer into format string */
24f98398 139 register char *bufptr = buffer; /* Pointer into output buffer.. */
03383aaf 140
f4c730d3 141 /* Use this for sprintf unless we need something really big. */
be65c2f4 142 char tembuf[DBL_MAX_10_EXP + 100];
03383aaf 143
f4c730d3 144 /* Size of sprintf_buffer. */
c2d1e36d 145 ptrdiff_t size_allocated = sizeof (tembuf);
03383aaf 146
f4c730d3
RS
147 /* Buffer to use for sprintf. Either tembuf or same as BIG_BUFFER. */
148 char *sprintf_buffer = tembuf;
03383aaf 149
f4c730d3 150 /* Buffer we have got with malloc. */
e6c3da20 151 char *big_buffer = NULL;
03383aaf 152
e6c3da20 153 register size_t tem;
7469ef5d 154 char *string;
03383aaf
BF
155 char fixed_buffer[20]; /* Default buffer for small formatting. */
156 char *fmtcpy;
24f98398 157 int minlen;
7469ef5d 158 char charbuf[MAX_MULTIBYTE_LENGTH + 1]; /* Used for %c. */
825cd63c 159 USE_SAFE_ALLOCA;
24f98398
JA
160
161 if (format_end == 0)
162 format_end = format + strlen (format);
163
c2d1e36d 164 if (format_end - format < sizeof (fixed_buffer) - 1)
03383aaf
BF
165 fmtcpy = fixed_buffer;
166 else
825cd63c 167 SAFE_ALLOCA (fmtcpy, char *, format_end - format + 1);
03383aaf 168
24f98398 169 bufsize--;
03383aaf
BF
170
171 /* Loop until end of format string or buffer full. */
94dcfacf 172 while (fmt < format_end && bufsize > 0)
24f98398
JA
173 {
174 if (*fmt == '%') /* Check for a '%' character */
175 {
c2d1e36d 176 ptrdiff_t size_bound = 0;
e6c3da20 177 EMACS_INT width; /* Columns occupied by STRING on display. */
62f19c19
PE
178 enum {
179 pDlen = sizeof pD - 1,
180 pIlen = sizeof pI - 1,
181 pMlen = sizeof pMd - 2
182 };
183 enum {
184 no_modifier, long_modifier, pD_modifier, pI_modifier, pM_modifier
185 } length_modifier = no_modifier;
186 static char const modifier_len[] = { 0, 1, pDlen, pIlen, pMlen };
187 int maxmlen = max (max (1, pDlen), max (pIlen, pMlen));
188 int mlen;
f4c730d3 189
24f98398 190 fmt++;
d427b66a 191 /* Copy this one %-spec into fmtcpy. */
7469ef5d 192 string = fmtcpy;
24f98398 193 *string++ = '%';
94dcfacf 194 while (fmt < format_end)
24f98398
JA
195 {
196 *string++ = *fmt;
be65c2f4
PE
197 if ('0' <= *fmt && *fmt <= '9')
198 {
199 /* Get an idea of how much space we might need.
200 This might be a field width or a precision; e.g.
201 %1.1000f and %1000.1f both might need 1000+ bytes.
202 Parse the width or precision, checking for overflow. */
c2d1e36d 203 ptrdiff_t n = *fmt - '0';
ad5f9eea 204 while (fmt + 1 < format_end
94dcfacf 205 && '0' <= fmt[1] && fmt[1] <= '9')
be65c2f4 206 {
c2d1e36d 207 /* Avoid ptrdiff_t, size_t, and int overflow, as
ca2d6274
PE
208 many sprintfs mishandle widths greater than INT_MAX.
209 This test is simple but slightly conservative: e.g.,
210 (INT_MAX - INT_MAX % 10) is reported as an overflow
211 even when it's not. */
c2d1e36d 212 if (n >= min (INT_MAX, min (PTRDIFF_MAX, SIZE_MAX)) / 10)
be65c2f4 213 error ("Format width or precision too large");
26898943 214 n = n * 10 + fmt[1] - '0';
be65c2f4
PE
215 *string++ = *++fmt;
216 }
217
218 if (size_bound < n)
219 size_bound = n;
220 }
ad5f9eea
PE
221 else if (! (*fmt == '-' || *fmt == ' ' || *fmt == '.'
222 || *fmt == '+'))
24f98398
JA
223 break;
224 fmt++;
225 }
ad5f9eea 226
62f19c19
PE
227 /* Check for the length modifiers in textual length order, so
228 that longer modifiers override shorter ones. */
229 for (mlen = 1; mlen <= maxmlen; mlen++)
ad5f9eea 230 {
62f19c19
PE
231 if (format_end - fmt < mlen)
232 break;
233 if (mlen == 1 && *fmt == 'l')
234 length_modifier = long_modifier;
235 if (mlen == pDlen && memcmp (fmt, pD, pDlen) == 0)
236 length_modifier = pD_modifier;
237 if (mlen == pIlen && memcmp (fmt, pI, pIlen) == 0)
238 length_modifier = pI_modifier;
239 if (mlen == pMlen && memcmp (fmt, pMd, pMlen) == 0)
240 length_modifier = pM_modifier;
ad5f9eea 241 }
62f19c19
PE
242
243 mlen = modifier_len[length_modifier];
244 memcpy (string, fmt + 1, mlen);
245 string += mlen;
246 fmt += mlen;
24f98398 247 *string = 0;
03383aaf 248
be65c2f4
PE
249 /* Make the size bound large enough to handle floating point formats
250 with large numbers. */
c2d1e36d 251 if (size_bound > min (PTRDIFF_MAX, SIZE_MAX) - DBL_MAX_10_EXP - 50)
be65c2f4 252 error ("Format width or precision too large");
01769a73 253 size_bound += DBL_MAX_10_EXP + 50;
6e951728 254
f4c730d3
RS
255 /* Make sure we have that much. */
256 if (size_bound > size_allocated)
257 {
258 if (big_buffer)
94dcfacf
EZ
259 xfree (big_buffer);
260 big_buffer = (char *) xmalloc (size_bound);
f4c730d3
RS
261 sprintf_buffer = big_buffer;
262 size_allocated = size_bound;
263 }
24f98398
JA
264 minlen = 0;
265 switch (*fmt++)
266 {
267 default:
ad5f9eea 268 error ("Invalid format operation %s", fmtcpy);
24f98398
JA
269
270/* case 'b': */
e6c3da20 271 case 'l':
24f98398 272 case 'd':
62f19c19
PE
273 switch (length_modifier)
274 {
275 case no_modifier:
e810457d 276 {
62f19c19
PE
277 int v = va_arg (ap, int);
278 sprintf (sprintf_buffer, fmtcpy, v);
e810457d 279 }
62f19c19
PE
280 break;
281 case long_modifier:
e6c3da20 282 {
62f19c19
PE
283 long v = va_arg (ap, long);
284 sprintf (sprintf_buffer, fmtcpy, v);
e6c3da20 285 }
62f19c19
PE
286 break;
287 case pD_modifier:
288 signed_pD_modifier:
e6c3da20 289 {
62f19c19
PE
290 ptrdiff_t v = va_arg (ap, ptrdiff_t);
291 sprintf (sprintf_buffer, fmtcpy, v);
e6c3da20 292 }
62f19c19
PE
293 break;
294 case pI_modifier:
295 {
296 EMACS_INT v = va_arg (ap, EMACS_INT);
297 sprintf (sprintf_buffer, fmtcpy, v);
298 }
299 break;
300 case pM_modifier:
301 {
302 intmax_t v = va_arg (ap, intmax_t);
303 sprintf (sprintf_buffer, fmtcpy, v);
304 }
305 break;
306 }
307 /* Now copy into final output, truncating as necessary. */
308 string = sprintf_buffer;
309 goto doit;
e6c3da20 310
24f98398
JA
311 case 'o':
312 case 'x':
62f19c19
PE
313 switch (length_modifier)
314 {
315 case no_modifier:
e810457d 316 {
62f19c19
PE
317 unsigned v = va_arg (ap, unsigned);
318 sprintf (sprintf_buffer, fmtcpy, v);
e810457d 319 }
62f19c19
PE
320 break;
321 case long_modifier:
e6c3da20 322 {
62f19c19
PE
323 unsigned long v = va_arg (ap, unsigned long);
324 sprintf (sprintf_buffer, fmtcpy, v);
e6c3da20 325 }
62f19c19
PE
326 break;
327 case pD_modifier:
328 goto signed_pD_modifier;
329 case pI_modifier:
e6c3da20 330 {
62f19c19
PE
331 EMACS_UINT v = va_arg (ap, EMACS_UINT);
332 sprintf (sprintf_buffer, fmtcpy, v);
e6c3da20 333 }
62f19c19
PE
334 break;
335 case pM_modifier:
336 {
337 uintmax_t v = va_arg (ap, uintmax_t);
338 sprintf (sprintf_buffer, fmtcpy, v);
339 }
340 break;
341 }
342 /* Now copy into final output, truncating as necessary. */
343 string = sprintf_buffer;
344 goto doit;
24f98398 345
f4c730d3
RS
346 case 'f':
347 case 'e':
348 case 'g':
349 {
6a8033e1
KR
350 double d = va_arg(ap, double);
351 sprintf (sprintf_buffer, fmtcpy, d);
e6c3da20 352 /* Now copy into final output, truncating as necessary. */
7469ef5d 353 string = sprintf_buffer;
f4c730d3
RS
354 goto doit;
355 }
356
24f98398
JA
357 case 'S':
358 string[-1] = 's';
359 case 's':
24f98398
JA
360 if (fmtcpy[1] != 's')
361 minlen = atoi (&fmtcpy[1]);
7469ef5d 362 string = va_arg (ap, char *);
e267324c 363 tem = strlen (string);
c9d624c6 364 if (STRING_BYTES_BOUND < tem)
e6c3da20 365 error ("String for %%s or %%S format is too long");
a0ca925c 366 width = strwidth (string, tem);
1513af9e
RS
367 goto doit1;
368
24f98398
JA
369 /* Copy string into final output, truncating if no room. */
370 doit:
a0ca925c 371 /* Coming here means STRING contains ASCII only. */
e6c3da20 372 tem = strlen (string);
c9d624c6 373 if (STRING_BYTES_BOUND < tem)
e6c3da20
EZ
374 error ("Format width or precision too large");
375 width = tem;
35a65fce 376 doit1:
a0ca925c
KH
377 /* We have already calculated:
378 TEM -- length of STRING,
379 WIDTH -- columns occupied by STRING when displayed, and
380 MINLEN -- minimum columns of the output. */
24f98398
JA
381 if (minlen > 0)
382 {
a0ca925c 383 while (minlen > width && bufsize > 0)
24f98398
JA
384 {
385 *bufptr++ = ' ';
386 bufsize--;
387 minlen--;
388 }
389 minlen = 0;
390 }
391 if (tem > bufsize)
a0ca925c
KH
392 {
393 /* Truncate the string at character boundary. */
394 tem = bufsize;
a50545d9 395 while (!CHAR_HEAD_P (string[tem - 1])) tem--;
afda1437
EZ
396 /* If the multibyte sequence of this character is
397 too long for the space we have left in the
398 buffer, truncate before it. */
399 if (tem > 0
400 && BYTES_BY_CHAR_HEAD (string[tem - 1]) > bufsize)
401 tem--;
402 if (tem > 0)
403 memcpy (bufptr, string, tem);
404 bufptr[tem] = 0;
405 /* Trigger exit from the loop, but make sure we
406 return to the caller a value which will indicate
407 that the buffer was too small. */
408 bufptr += bufsize;
409 bufsize = 0;
410 continue;
a0ca925c
KH
411 }
412 else
72af86bd 413 memcpy (bufptr, string, tem);
24f98398
JA
414 bufptr += tem;
415 bufsize -= tem;
416 if (minlen < 0)
417 {
a0ca925c 418 while (minlen < - width && bufsize > 0)
24f98398
JA
419 {
420 *bufptr++ = ' ';
421 bufsize--;
422 minlen++;
423 }
424 minlen = 0;
425 }
426 continue;
427
428 case 'c':
6a8033e1 429 {
e6c3da20
EZ
430 int chr = va_arg(ap, int);
431 tem = CHAR_STRING (chr, (unsigned char *) charbuf);
6a8033e1
KR
432 string = charbuf;
433 string[tem] = 0;
434 width = strwidth (string, tem);
435 if (fmtcpy[1] != 'c')
436 minlen = atoi (&fmtcpy[1]);
437 goto doit1;
438 }
24f98398
JA
439
440 case '%':
441 fmt--; /* Drop thru and this % will be treated as normal */
442 }
443 }
a0ca925c
KH
444
445 {
446 /* Just some character; Copy it if the whole multi-byte form
447 fit in the buffer. */
448 char *save_bufptr = bufptr;
449
450 do { *bufptr++ = *fmt++; }
94dcfacf 451 while (fmt < format_end && --bufsize > 0 && !CHAR_HEAD_P (*fmt));
a50545d9 452 if (!CHAR_HEAD_P (*fmt))
a0ca925c 453 {
d178f871
EZ
454 /* Truncate, but return value that will signal to caller
455 that the buffer was too small. */
456 *save_bufptr = 0;
a0ca925c
KH
457 break;
458 }
459 }
24f98398
JA
460 };
461
f4c730d3 462 /* If we had to malloc something, free it. */
70fdbb46 463 xfree (big_buffer);
f4c730d3 464
e6c3da20 465 *bufptr = 0; /* Make sure our string ends with a '\0' */
825cd63c
EZ
466
467 SAFE_FREE ();
24f98398
JA
468 return bufptr - buffer;
469}
62f19c19
PE
470
471/* Format to an unbounded buffer BUF. This is like sprintf, except it
472 is not limited to returning an 'int' so it doesn't have a silly 2
473 GiB limit on typical 64-bit hosts. However, it is limited to the
474 Emacs-style formats that doprnt supports.
475
476 Return the number of bytes put into BUF, excluding the terminating
477 '\0'. */
478ptrdiff_t
479esprintf (char *buf, char const *format, ...)
480{
481 ptrdiff_t nbytes;
482 va_list ap;
483 va_start (ap, format);
484 nbytes = doprnt (buf, TYPE_MAXIMUM (ptrdiff_t), format, 0, ap);
485 va_end (ap);
486 return nbytes;
487}
488
62f19c19
PE
489/* Format to buffer *BUF of positive size *BUFSIZE, reallocating *BUF
490 and updating *BUFSIZE if the buffer is too small, and otherwise
491 behaving line esprintf. When reallocating, free *BUF unless it is
492 equal to NONHEAPBUF, and if BUFSIZE_MAX is nonnegative then signal
493 memory exhaustion instead of growing the buffer size past
494 BUFSIZE_MAX. */
495ptrdiff_t
496exprintf (char **buf, ptrdiff_t *bufsize,
497 char const *nonheapbuf, ptrdiff_t bufsize_max,
498 char const *format, ...)
499{
500 ptrdiff_t nbytes;
501 va_list ap;
502 va_start (ap, format);
503 nbytes = evxprintf (buf, bufsize, nonheapbuf, bufsize_max, format, ap);
504 va_end (ap);
505 return nbytes;
506}
507
508/* Act like exprintf, except take a va_list. */
509ptrdiff_t
510evxprintf (char **buf, ptrdiff_t *bufsize,
511 char const *nonheapbuf, ptrdiff_t bufsize_max,
512 char const *format, va_list ap)
513{
514 for (;;)
515 {
516 ptrdiff_t nbytes;
517 va_list ap_copy;
518 va_copy (ap_copy, ap);
519 nbytes = doprnt (*buf, *bufsize, format, 0, ap_copy);
520 va_end (ap_copy);
521 if (nbytes < *bufsize - 1)
522 return nbytes;
523 if (*buf != nonheapbuf)
524 xfree (*buf);
525 *buf = xpalloc (NULL, bufsize, 1, bufsize_max, 1);
526 }
527}