vasnprintf.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918
  1. /* vsprintf with automatic memory allocation.
  2. Copyright (C) 1999, 2002-2006 Free Software Foundation, Inc.
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation; either version 2, or (at your option)
  6. any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License along
  12. with this program; if not, write to the Free Software Foundation,
  13. Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
  14. /* Tell glibc's <stdio.h> to provide a prototype for snprintf().
  15. This must come before <config.h> because <config.h> may include
  16. <features.h>, and once <features.h> has been included, it's too late. */
  17. #ifndef _GNU_SOURCE
  18. # define _GNU_SOURCE 1
  19. #endif
  20. #include <config.h>
  21. #ifndef IN_LIBINTL
  22. # include <alloca.h>
  23. #endif
  24. /* Specification. */
  25. #if WIDE_CHAR_VERSION
  26. # include "vasnwprintf.h"
  27. #else
  28. # include "vasnprintf.h"
  29. #endif
  30. #include <stdio.h> /* snprintf(), sprintf() */
  31. #include <stdlib.h> /* abort(), malloc(), realloc(), free() */
  32. #include <string.h> /* memcpy(), strlen() */
  33. #include <errno.h> /* errno */
  34. #include <limits.h> /* CHAR_BIT, INT_MAX */
  35. #include <float.h> /* DBL_MAX_EXP, LDBL_MAX_EXP */
  36. #if WIDE_CHAR_VERSION
  37. # include "wprintf-parse.h"
  38. #else
  39. # include "printf-parse.h"
  40. #endif
  41. #ifndef SIZE_MAX
  42. # define SIZE_MAX ((size_t) -1)
  43. #endif
  44. /* Some systems, like OSF/1 4.0 and Woe32, don't have EOVERFLOW. */
  45. #ifndef EOVERFLOW
  46. # define EOVERFLOW E2BIG
  47. #endif
  48. #ifdef HAVE_WCHAR_T
  49. # ifdef HAVE_WCSLEN
  50. # define local_wcslen wcslen
  51. # else
  52. /* Solaris 2.5.1 has wcslen() in a separate library libw.so. To avoid
  53. a dependency towards this library, here is a local substitute.
  54. Define this substitute only once, even if this file is included
  55. twice in the same compilation unit. */
  56. # ifndef local_wcslen_defined
  57. # define local_wcslen_defined 1
  58. static size_t
  59. local_wcslen (const wchar_t *s)
  60. {
  61. const wchar_t *ptr;
  62. for (ptr = s; *ptr != (wchar_t) 0; ptr++)
  63. ;
  64. return ptr - s;
  65. }
  66. # endif
  67. # endif
  68. #endif
  69. #if WIDE_CHAR_VERSION
  70. # define VASNPRINTF vasnwprintf
  71. # define CHAR_T wchar_t
  72. # define DIRECTIVE wchar_t_directive
  73. # define DIRECTIVES wchar_t_directives
  74. # define PRINTF_PARSE wprintf_parse
  75. # define USE_SNPRINTF 1
  76. # if HAVE_DECL__SNWPRINTF
  77. /* On Windows, the function swprintf() has a different signature than
  78. on Unix; we use the _snwprintf() function instead. */
  79. # define SNPRINTF _snwprintf
  80. # else
  81. /* Unix. */
  82. # define SNPRINTF swprintf
  83. # endif
  84. #else
  85. # define VASNPRINTF vasnprintf
  86. # define CHAR_T char
  87. # define DIRECTIVE char_directive
  88. # define DIRECTIVES char_directives
  89. # define PRINTF_PARSE printf_parse
  90. # define USE_SNPRINTF (HAVE_DECL__SNPRINTF || HAVE_SNPRINTF)
  91. # if HAVE_DECL__SNPRINTF
  92. /* Windows. */
  93. # define SNPRINTF _snprintf
  94. # else
  95. /* Unix. */
  96. # define SNPRINTF snprintf
  97. # endif
  98. #endif
  99. CHAR_T *
  100. VASNPRINTF (CHAR_T *resultbuf, size_t *lengthp, const CHAR_T *format, va_list args)
  101. {
  102. DIRECTIVES d;
  103. arguments a;
  104. if (PRINTF_PARSE (format, &d, &a) < 0)
  105. {
  106. errno = EINVAL;
  107. return NULL;
  108. }
  109. #define CLEANUP() \
  110. free (d.dir); \
  111. if (a.arg) \
  112. free (a.arg);
  113. if (printf_fetchargs (args, &a) < 0)
  114. {
  115. CLEANUP ();
  116. errno = EINVAL;
  117. return NULL;
  118. }
  119. {
  120. size_t buf_neededlength;
  121. CHAR_T *buf;
  122. CHAR_T *buf_malloced;
  123. const CHAR_T *cp;
  124. size_t i;
  125. DIRECTIVE *dp;
  126. /* Output string accumulator. */
  127. CHAR_T *result;
  128. size_t allocated;
  129. size_t length;
  130. /* Allocate a small buffer that will hold a directive passed to
  131. sprintf or snprintf. */
  132. buf_neededlength = 7 + d.max_width_length + d.max_precision_length + 6;
  133. #if HAVE_ALLOCA
  134. if (buf_neededlength < 4000 / sizeof (CHAR_T))
  135. {
  136. buf = (CHAR_T *) alloca (buf_neededlength * sizeof (CHAR_T));
  137. buf_malloced = NULL;
  138. }
  139. else
  140. #endif
  141. {
  142. if (SIZE_MAX / sizeof (CHAR_T) < buf_neededlength)
  143. goto out_of_memory_1;
  144. buf = (CHAR_T *) malloc (buf_neededlength * sizeof (CHAR_T));
  145. if (buf == NULL)
  146. goto out_of_memory_1;
  147. buf_malloced = buf;
  148. }
  149. if (resultbuf != NULL)
  150. {
  151. result = resultbuf;
  152. allocated = *lengthp;
  153. }
  154. else
  155. {
  156. result = NULL;
  157. allocated = 0;
  158. }
  159. length = 0;
  160. /* Invariants:
  161. result is either == resultbuf or == NULL or malloc-allocated.
  162. If length > 0, then result != NULL. */
  163. /* Ensures that allocated >= length + extra. Aborts through a jump to
  164. out_of_memory if size is too big. */
  165. #define ENSURE_ALLOCATION(extra) \
  166. { \
  167. size_t needed = length + (extra); \
  168. if (needed < length) \
  169. goto out_of_memory; \
  170. if (needed > allocated) \
  171. { \
  172. size_t memory_size; \
  173. CHAR_T *memory; \
  174. \
  175. allocated = (allocated > 0 ? 2 * allocated : 12); \
  176. if (needed > allocated) \
  177. allocated = needed; \
  178. if (SIZE_MAX / sizeof (CHAR_T) < allocated) \
  179. goto out_of_memory; \
  180. memory_size = allocated * sizeof (CHAR_T); \
  181. if (result == resultbuf || result == NULL) \
  182. memory = (CHAR_T *) malloc (memory_size); \
  183. else \
  184. memory = (CHAR_T *) realloc (result, memory_size); \
  185. if (memory == NULL) \
  186. goto out_of_memory; \
  187. if (result == resultbuf && length > 0) \
  188. memcpy (memory, result, length * sizeof (CHAR_T)); \
  189. result = memory; \
  190. } \
  191. }
  192. for (cp = format, i = 0, dp = &d.dir[0]; ; cp = dp->dir_end, i++, dp++)
  193. {
  194. if (cp != dp->dir_start)
  195. {
  196. size_t n = dp->dir_start - cp;
  197. ENSURE_ALLOCATION (n);
  198. memcpy (result + length, cp, n * sizeof (CHAR_T));
  199. length += n;
  200. }
  201. if (i == d.count)
  202. break;
  203. /* Execute a single directive. */
  204. if (dp->conversion == '%')
  205. {
  206. if (!(dp->arg_index == ARG_NONE))
  207. abort ();
  208. ENSURE_ALLOCATION (1);
  209. result[length] = '%';
  210. length += 1;
  211. }
  212. else
  213. {
  214. if (!(dp->arg_index != ARG_NONE))
  215. abort ();
  216. if (dp->conversion == 'n')
  217. {
  218. switch (a.arg[dp->arg_index].type)
  219. {
  220. case TYPE_COUNT_SCHAR_POINTER:
  221. *a.arg[dp->arg_index].a.a_count_schar_pointer = length;
  222. break;
  223. case TYPE_COUNT_SHORT_POINTER:
  224. *a.arg[dp->arg_index].a.a_count_short_pointer = length;
  225. break;
  226. case TYPE_COUNT_INT_POINTER:
  227. *a.arg[dp->arg_index].a.a_count_int_pointer = length;
  228. break;
  229. case TYPE_COUNT_LONGINT_POINTER:
  230. *a.arg[dp->arg_index].a.a_count_longint_pointer = length;
  231. break;
  232. #ifdef HAVE_LONG_LONG
  233. case TYPE_COUNT_LONGLONGINT_POINTER:
  234. *a.arg[dp->arg_index].a.a_count_longlongint_pointer = length;
  235. break;
  236. #endif
  237. default:
  238. abort ();
  239. }
  240. }
  241. else
  242. {
  243. arg_type type = a.arg[dp->arg_index].type;
  244. CHAR_T *p;
  245. unsigned int prefix_count;
  246. int prefixes[2];
  247. #if !USE_SNPRINTF
  248. size_t tmp_length;
  249. CHAR_T tmpbuf[700];
  250. CHAR_T *tmp;
  251. /* Allocate a temporary buffer of sufficient size for calling
  252. sprintf. */
  253. {
  254. size_t width;
  255. size_t precision;
  256. width = 0;
  257. if (dp->width_start != dp->width_end)
  258. {
  259. if (dp->width_arg_index != ARG_NONE)
  260. {
  261. int arg;
  262. if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
  263. abort ();
  264. arg = a.arg[dp->width_arg_index].a.a_int;
  265. width = (arg < 0 ? (unsigned int) (-arg) : arg);
  266. }
  267. else
  268. {
  269. const CHAR_T *digitp = dp->width_start;
  270. do
  271. {
  272. size_t w_tmp = width * 10 + (*digitp++ - '0');
  273. if (SIZE_MAX / 10 < width || w_tmp < width)
  274. goto out_of_memory;
  275. width = w_tmp;
  276. }
  277. while (digitp != dp->width_end);
  278. }
  279. }
  280. precision = 6;
  281. if (dp->precision_start != dp->precision_end)
  282. {
  283. if (dp->precision_arg_index != ARG_NONE)
  284. {
  285. int arg;
  286. if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
  287. abort ();
  288. arg = a.arg[dp->precision_arg_index].a.a_int;
  289. precision = (arg < 0 ? 0 : arg);
  290. }
  291. else
  292. {
  293. const CHAR_T *digitp = dp->precision_start + 1;
  294. precision = 0;
  295. while (digitp != dp->precision_end)
  296. {
  297. size_t p1 = 10 * precision + (*digitp++ - '0');
  298. precision = ((SIZE_MAX / 10 < precision
  299. || p1 < precision)
  300. ? SIZE_MAX : p1);
  301. }
  302. }
  303. }
  304. switch (dp->conversion)
  305. {
  306. case 'd': case 'i': case 'u':
  307. # ifdef HAVE_LONG_LONG
  308. if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
  309. tmp_length =
  310. (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
  311. * 0.30103 /* binary -> decimal */
  312. )
  313. + 1; /* turn floor into ceil */
  314. else
  315. # endif
  316. if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
  317. tmp_length =
  318. (unsigned int) (sizeof (unsigned long) * CHAR_BIT
  319. * 0.30103 /* binary -> decimal */
  320. )
  321. + 1; /* turn floor into ceil */
  322. else
  323. tmp_length =
  324. (unsigned int) (sizeof (unsigned int) * CHAR_BIT
  325. * 0.30103 /* binary -> decimal */
  326. )
  327. + 1; /* turn floor into ceil */
  328. if (tmp_length < precision)
  329. tmp_length = precision;
  330. /* Multiply by 2, as an estimate for FLAG_GROUP. */
  331. /* Add 1, to account for a leading sign. */
  332. tmp_length = (tmp_length < SIZE_MAX / 2
  333. ? 2 * tmp_length + 1
  334. : SIZE_MAX);
  335. break;
  336. case 'o':
  337. # ifdef HAVE_LONG_LONG
  338. if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
  339. tmp_length =
  340. (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
  341. * 0.333334 /* binary -> octal */
  342. )
  343. + 1; /* turn floor into ceil */
  344. else
  345. # endif
  346. if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
  347. tmp_length =
  348. (unsigned int) (sizeof (unsigned long) * CHAR_BIT
  349. * 0.333334 /* binary -> octal */
  350. )
  351. + 1; /* turn floor into ceil */
  352. else
  353. tmp_length =
  354. (unsigned int) (sizeof (unsigned int) * CHAR_BIT
  355. * 0.333334 /* binary -> octal */
  356. )
  357. + 1; /* turn floor into ceil */
  358. if (tmp_length < precision)
  359. tmp_length = precision;
  360. /* Add 1, to account for a leading sign. */
  361. tmp_length += (tmp_length < SIZE_MAX);
  362. break;
  363. case 'x': case 'X':
  364. # ifdef HAVE_LONG_LONG
  365. if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
  366. tmp_length =
  367. (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
  368. * 0.25 /* binary -> hexadecimal */
  369. )
  370. + 1; /* turn floor into ceil */
  371. else
  372. # endif
  373. if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
  374. tmp_length =
  375. (unsigned int) (sizeof (unsigned long) * CHAR_BIT
  376. * 0.25 /* binary -> hexadecimal */
  377. )
  378. + 1; /* turn floor into ceil */
  379. else
  380. tmp_length =
  381. (unsigned int) (sizeof (unsigned int) * CHAR_BIT
  382. * 0.25 /* binary -> hexadecimal */
  383. )
  384. + 1; /* turn floor into ceil */
  385. if (tmp_length < precision)
  386. tmp_length = precision;
  387. /* Add 2, to account for a leading sign or alternate form. */
  388. if (tmp_length <= SIZE_MAX / 2)
  389. tmp_length *= 2;
  390. break;
  391. case 'f': case 'F':
  392. # ifdef HAVE_LONG_DOUBLE
  393. if (type == TYPE_LONGDOUBLE)
  394. tmp_length =
  395. (unsigned int) (LDBL_MAX_EXP
  396. * 0.30103 /* binary -> decimal */
  397. * 2 /* estimate for FLAG_GROUP */
  398. )
  399. + 1 /* turn floor into ceil */
  400. + 10; /* sign, decimal point etc. */
  401. else
  402. # endif
  403. tmp_length =
  404. (unsigned int) (DBL_MAX_EXP
  405. * 0.30103 /* binary -> decimal */
  406. * 2 /* estimate for FLAG_GROUP */
  407. )
  408. + 1 /* turn floor into ceil */
  409. + 10; /* sign, decimal point etc. */
  410. tmp_length += precision;
  411. if (tmp_length < precision)
  412. goto out_of_memory;
  413. break;
  414. case 'e': case 'E': case 'g': case 'G':
  415. case 'a': case 'A':
  416. tmp_length =
  417. 12; /* sign, decimal point, exponent etc. */
  418. tmp_length += precision;
  419. if (tmp_length < precision)
  420. goto out_of_memory;
  421. break;
  422. case 'c':
  423. # if defined HAVE_WINT_T && !WIDE_CHAR_VERSION
  424. if (type == TYPE_WIDE_CHAR)
  425. tmp_length = MB_CUR_MAX;
  426. else
  427. # endif
  428. tmp_length = 1;
  429. break;
  430. case 's':
  431. # ifdef HAVE_WCHAR_T
  432. if (type == TYPE_WIDE_STRING)
  433. {
  434. tmp_length =
  435. local_wcslen (a.arg[dp->arg_index].a.a_wide_string);
  436. # if !WIDE_CHAR_VERSION
  437. if (SIZE_MAX / MB_CUR_MAX < tmp_length)
  438. goto out_of_memory;
  439. tmp_length *= MB_CUR_MAX;
  440. # endif
  441. }
  442. else
  443. # endif
  444. tmp_length = strlen (a.arg[dp->arg_index].a.a_string);
  445. break;
  446. case 'p':
  447. tmp_length =
  448. (unsigned int) (sizeof (void *) * CHAR_BIT
  449. * 0.25 /* binary -> hexadecimal */
  450. )
  451. + 1 /* turn floor into ceil */
  452. + 2; /* account for leading 0x */
  453. break;
  454. default:
  455. abort ();
  456. }
  457. if (tmp_length < width)
  458. tmp_length = width;
  459. tmp_length++; /* account for trailing NUL */
  460. if (!tmp_length)
  461. goto out_of_memory;
  462. }
  463. if (tmp_length <= sizeof (tmpbuf) / sizeof (CHAR_T))
  464. tmp = tmpbuf;
  465. else
  466. {
  467. if (SIZE_MAX / sizeof (CHAR_T) < tmp_length)
  468. /* Overflow, would lead to out of memory. */
  469. goto out_of_memory;
  470. tmp = (CHAR_T *) malloc (tmp_length * sizeof (CHAR_T));
  471. if (tmp == NULL)
  472. /* Out of memory. */
  473. goto out_of_memory;
  474. }
  475. #endif
  476. /* Construct the format string for calling snprintf or
  477. sprintf. */
  478. p = buf;
  479. *p++ = '%';
  480. if (dp->flags & FLAG_GROUP)
  481. *p++ = '\'';
  482. if (dp->flags & FLAG_LEFT)
  483. *p++ = '-';
  484. if (dp->flags & FLAG_SHOWSIGN)
  485. *p++ = '+';
  486. if (dp->flags & FLAG_SPACE)
  487. *p++ = ' ';
  488. if (dp->flags & FLAG_ALT)
  489. *p++ = '#';
  490. if (dp->flags & FLAG_ZERO)
  491. *p++ = '0';
  492. if (dp->width_start != dp->width_end)
  493. {
  494. size_t n = dp->width_end - dp->width_start;
  495. memcpy (p, dp->width_start, n * sizeof (CHAR_T));
  496. p += n;
  497. }
  498. if (dp->precision_start != dp->precision_end)
  499. {
  500. size_t n = dp->precision_end - dp->precision_start;
  501. memcpy (p, dp->precision_start, n * sizeof (CHAR_T));
  502. p += n;
  503. }
  504. switch (type)
  505. {
  506. #ifdef HAVE_LONG_LONG
  507. case TYPE_LONGLONGINT:
  508. case TYPE_ULONGLONGINT:
  509. *p++ = 'l';
  510. /*FALLTHROUGH*/
  511. #endif
  512. case TYPE_LONGINT:
  513. case TYPE_ULONGINT:
  514. #ifdef HAVE_WINT_T
  515. case TYPE_WIDE_CHAR:
  516. #endif
  517. #ifdef HAVE_WCHAR_T
  518. case TYPE_WIDE_STRING:
  519. #endif
  520. *p++ = 'l';
  521. break;
  522. #ifdef HAVE_LONG_DOUBLE
  523. case TYPE_LONGDOUBLE:
  524. *p++ = 'L';
  525. break;
  526. #endif
  527. default:
  528. break;
  529. }
  530. *p = dp->conversion;
  531. #if USE_SNPRINTF
  532. p[1] = '%';
  533. p[2] = 'n';
  534. p[3] = '\0';
  535. #else
  536. p[1] = '\0';
  537. #endif
  538. /* Construct the arguments for calling snprintf or sprintf. */
  539. prefix_count = 0;
  540. if (dp->width_arg_index != ARG_NONE)
  541. {
  542. if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
  543. abort ();
  544. prefixes[prefix_count++] = a.arg[dp->width_arg_index].a.a_int;
  545. }
  546. if (dp->precision_arg_index != ARG_NONE)
  547. {
  548. if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
  549. abort ();
  550. prefixes[prefix_count++] = a.arg[dp->precision_arg_index].a.a_int;
  551. }
  552. #if USE_SNPRINTF
  553. /* Prepare checking whether snprintf returns the count
  554. via %n. */
  555. ENSURE_ALLOCATION (1);
  556. result[length] = '\0';
  557. #endif
  558. for (;;)
  559. {
  560. size_t maxlen;
  561. int count;
  562. int retcount;
  563. maxlen = allocated - length;
  564. count = -1;
  565. retcount = 0;
  566. #if USE_SNPRINTF
  567. # define SNPRINTF_BUF(arg) \
  568. switch (prefix_count) \
  569. { \
  570. case 0: \
  571. retcount = SNPRINTF (result + length, maxlen, buf, \
  572. arg, &count); \
  573. break; \
  574. case 1: \
  575. retcount = SNPRINTF (result + length, maxlen, buf, \
  576. prefixes[0], arg, &count); \
  577. break; \
  578. case 2: \
  579. retcount = SNPRINTF (result + length, maxlen, buf, \
  580. prefixes[0], prefixes[1], arg, \
  581. &count); \
  582. break; \
  583. default: \
  584. abort (); \
  585. }
  586. #else
  587. # define SNPRINTF_BUF(arg) \
  588. switch (prefix_count) \
  589. { \
  590. case 0: \
  591. count = sprintf (tmp, buf, arg); \
  592. break; \
  593. case 1: \
  594. count = sprintf (tmp, buf, prefixes[0], arg); \
  595. break; \
  596. case 2: \
  597. count = sprintf (tmp, buf, prefixes[0], prefixes[1],\
  598. arg); \
  599. break; \
  600. default: \
  601. abort (); \
  602. }
  603. #endif
  604. switch (type)
  605. {
  606. case TYPE_SCHAR:
  607. {
  608. int arg = a.arg[dp->arg_index].a.a_schar;
  609. SNPRINTF_BUF (arg);
  610. }
  611. break;
  612. case TYPE_UCHAR:
  613. {
  614. unsigned int arg = a.arg[dp->arg_index].a.a_uchar;
  615. SNPRINTF_BUF (arg);
  616. }
  617. break;
  618. case TYPE_SHORT:
  619. {
  620. int arg = a.arg[dp->arg_index].a.a_short;
  621. SNPRINTF_BUF (arg);
  622. }
  623. break;
  624. case TYPE_USHORT:
  625. {
  626. unsigned int arg = a.arg[dp->arg_index].a.a_ushort;
  627. SNPRINTF_BUF (arg);
  628. }
  629. break;
  630. case TYPE_INT:
  631. {
  632. int arg = a.arg[dp->arg_index].a.a_int;
  633. SNPRINTF_BUF (arg);
  634. }
  635. break;
  636. case TYPE_UINT:
  637. {
  638. unsigned int arg = a.arg[dp->arg_index].a.a_uint;
  639. SNPRINTF_BUF (arg);
  640. }
  641. break;
  642. case TYPE_LONGINT:
  643. {
  644. long int arg = a.arg[dp->arg_index].a.a_longint;
  645. SNPRINTF_BUF (arg);
  646. }
  647. break;
  648. case TYPE_ULONGINT:
  649. {
  650. unsigned long int arg = a.arg[dp->arg_index].a.a_ulongint;
  651. SNPRINTF_BUF (arg);
  652. }
  653. break;
  654. #ifdef HAVE_LONG_LONG
  655. case TYPE_LONGLONGINT:
  656. {
  657. long long int arg = a.arg[dp->arg_index].a.a_longlongint;
  658. SNPRINTF_BUF (arg);
  659. }
  660. break;
  661. case TYPE_ULONGLONGINT:
  662. {
  663. unsigned long long int arg = a.arg[dp->arg_index].a.a_ulonglongint;
  664. SNPRINTF_BUF (arg);
  665. }
  666. break;
  667. #endif
  668. case TYPE_DOUBLE:
  669. {
  670. double arg = a.arg[dp->arg_index].a.a_double;
  671. SNPRINTF_BUF (arg);
  672. }
  673. break;
  674. #ifdef HAVE_LONG_DOUBLE
  675. case TYPE_LONGDOUBLE:
  676. {
  677. long double arg = a.arg[dp->arg_index].a.a_longdouble;
  678. SNPRINTF_BUF (arg);
  679. }
  680. break;
  681. #endif
  682. case TYPE_CHAR:
  683. {
  684. int arg = a.arg[dp->arg_index].a.a_char;
  685. SNPRINTF_BUF (arg);
  686. }
  687. break;
  688. #ifdef HAVE_WINT_T
  689. case TYPE_WIDE_CHAR:
  690. {
  691. wint_t arg = a.arg[dp->arg_index].a.a_wide_char;
  692. SNPRINTF_BUF (arg);
  693. }
  694. break;
  695. #endif
  696. case TYPE_STRING:
  697. {
  698. const char *arg = a.arg[dp->arg_index].a.a_string;
  699. SNPRINTF_BUF (arg);
  700. }
  701. break;
  702. #ifdef HAVE_WCHAR_T
  703. case TYPE_WIDE_STRING:
  704. {
  705. const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string;
  706. SNPRINTF_BUF (arg);
  707. }
  708. break;
  709. #endif
  710. case TYPE_POINTER:
  711. {
  712. void *arg = a.arg[dp->arg_index].a.a_pointer;
  713. SNPRINTF_BUF (arg);
  714. }
  715. break;
  716. default:
  717. abort ();
  718. }
  719. #if USE_SNPRINTF
  720. /* Portability: Not all implementations of snprintf()
  721. are ISO C 99 compliant. Determine the number of
  722. bytes that snprintf() has produced or would have
  723. produced. */
  724. if (count >= 0)
  725. {
  726. /* Verify that snprintf() has NUL-terminated its
  727. result. */
  728. if (count < maxlen && result[length + count] != '\0')
  729. abort ();
  730. /* Portability hack. */
  731. if (retcount > count)
  732. count = retcount;
  733. }
  734. else
  735. {
  736. /* snprintf() doesn't understand the '%n'
  737. directive. */
  738. if (p[1] != '\0')
  739. {
  740. /* Don't use the '%n' directive; instead, look
  741. at the snprintf() return value. */
  742. p[1] = '\0';
  743. continue;
  744. }
  745. else
  746. {
  747. /* Look at the snprintf() return value. */
  748. if (retcount < 0)
  749. {
  750. /* HP-UX 10.20 snprintf() is doubly deficient:
  751. It doesn't understand the '%n' directive,
  752. *and* it returns -1 (rather than the length
  753. that would have been required) when the
  754. buffer is too small. */
  755. size_t bigger_need =
  756. (allocated > 12 ? allocated : 12);
  757. ENSURE_ALLOCATION (bigger_need);
  758. continue;
  759. }
  760. else
  761. count = retcount;
  762. }
  763. }
  764. #endif
  765. /* Attempt to handle failure. */
  766. if (count < 0)
  767. {
  768. if (!(result == resultbuf || result == NULL))
  769. free (result);
  770. if (buf_malloced != NULL)
  771. free (buf_malloced);
  772. CLEANUP ();
  773. errno = EINVAL;
  774. return NULL;
  775. }
  776. #if !USE_SNPRINTF
  777. if (count >= tmp_length)
  778. /* tmp_length was incorrectly calculated - fix the
  779. code above! */
  780. abort ();
  781. #endif
  782. /* Make room for the result. */
  783. if (count >= maxlen)
  784. {
  785. /* Need at least count bytes. But allocate
  786. proportionally, to avoid looping eternally if
  787. snprintf() reports a too small count. */
  788. ENSURE_ALLOCATION (count < allocated
  789. ? allocated : count);
  790. #if USE_SNPRINTF
  791. continue;
  792. #endif
  793. }
  794. #if USE_SNPRINTF
  795. /* The snprintf() result did fit. */
  796. #else
  797. /* Append the sprintf() result. */
  798. memcpy (result + length, tmp, count * sizeof (CHAR_T));
  799. if (tmp != tmpbuf)
  800. free (tmp);
  801. #endif
  802. length += count;
  803. break;
  804. }
  805. }
  806. }
  807. }
  808. /* Add the final NUL. */
  809. ENSURE_ALLOCATION (1);
  810. result[length] = '\0';
  811. if (result != resultbuf && length + 1 < allocated)
  812. {
  813. /* Shrink the allocated memory if possible. */
  814. CHAR_T *memory;
  815. memory = (CHAR_T *) realloc (result, (length + 1) * sizeof (CHAR_T));
  816. if (memory != NULL)
  817. result = memory;
  818. }
  819. if (buf_malloced != NULL)
  820. free (buf_malloced);
  821. CLEANUP ();
  822. *lengthp = length;
  823. if (length > INT_MAX)
  824. goto length_overflow;
  825. return result;
  826. length_overflow:
  827. /* We could produce such a big string, but its length doesn't fit into
  828. an 'int'. POSIX says that snprintf() fails with errno = EOVERFLOW in
  829. this case. */
  830. if (result != resultbuf)
  831. free (result);
  832. errno = EOVERFLOW;
  833. return NULL;
  834. out_of_memory:
  835. if (!(result == resultbuf || result == NULL))
  836. free (result);
  837. if (buf_malloced != NULL)
  838. free (buf_malloced);
  839. out_of_memory_1:
  840. CLEANUP ();
  841. errno = ENOMEM;
  842. return NULL;
  843. }
  844. }
  845. #undef SNPRINTF
  846. #undef USE_SNPRINTF
  847. #undef PRINTF_PARSE
  848. #undef DIRECTIVES
  849. #undef DIRECTIVE
  850. #undef CHAR_T
  851. #undef VASNPRINTF