00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef _GNU_SOURCE
00022 # define _GNU_SOURCE 1
00023 #endif
00024
00025 #ifdef HAVE_CONFIG_H
00026 # include <config.h>
00027 #endif
00028 #ifndef IN_LIBINTL
00029 # include <alloca.h>
00030 #endif
00031
00032
00033 #if WIDE_CHAR_VERSION
00034 # include "vasnwprintf.h"
00035 #else
00036 # include "vasnprintf.h"
00037 #endif
00038
00039 #include <stdio.h>
00040 #include <stdlib.h>
00041 #include <string.h>
00042 #include <errno.h>
00043 #include <limits.h>
00044 #include <float.h>
00045 #if WIDE_CHAR_VERSION
00046 # include "wprintf-parse.h"
00047 #else
00048 # include "printf-parse.h"
00049 #endif
00050
00051
00052 #include "xsize.h"
00053
00054
00055 #ifndef EOVERFLOW
00056 # define EOVERFLOW E2BIG
00057 #endif
00058
00059 #ifdef HAVE_WCHAR_T
00060 # ifdef HAVE_WCSLEN
00061 # define local_wcslen wcslen
00062 # else
00063
00064
00065
00066
00067 # ifndef local_wcslen_defined
00068 # define local_wcslen_defined 1
00069 static size_t
00070 local_wcslen (const wchar_t *s)
00071 {
00072 const wchar_t *ptr;
00073
00074 for (ptr = s; *ptr != (wchar_t) 0; ptr++)
00075 ;
00076 return ptr - s;
00077 }
00078 # endif
00079 # endif
00080 #endif
00081
00082 #if WIDE_CHAR_VERSION
00083 # define VASNPRINTF vasnwprintf
00084 # define CHAR_T wchar_t
00085 # define DIRECTIVE wchar_t_directive
00086 # define DIRECTIVES wchar_t_directives
00087 # define PRINTF_PARSE wprintf_parse
00088 # define USE_SNPRINTF 1
00089 # if HAVE_DECL__SNWPRINTF
00090
00091
00092 # define SNPRINTF _snwprintf
00093 # else
00094
00095 # define SNPRINTF swprintf
00096 # endif
00097 #else
00098 # define VASNPRINTF vasnprintf
00099 # define CHAR_T char
00100 # define DIRECTIVE char_directive
00101 # define DIRECTIVES char_directives
00102 # define PRINTF_PARSE printf_parse
00103 # define USE_SNPRINTF (HAVE_DECL__SNPRINTF || HAVE_SNPRINTF)
00104 # if HAVE_DECL__SNPRINTF
00105
00106 # define SNPRINTF _snprintf
00107 # else
00108
00109 # define SNPRINTF snprintf
00110 # endif
00111 #endif
00112
00113 CHAR_T *
00114 VASNPRINTF (CHAR_T *resultbuf, size_t *lengthp, const CHAR_T *format, va_list args)
00115 {
00116 DIRECTIVES d;
00117 arguments a;
00118
00119 if (PRINTF_PARSE (format, &d, &a) < 0)
00120 {
00121 errno = EINVAL;
00122 return NULL;
00123 }
00124
00125 #define CLEANUP() \
00126 free (d.dir); \
00127 if (a.arg) \
00128 free (a.arg);
00129
00130 if (printf_fetchargs (args, &a) < 0)
00131 {
00132 CLEANUP ();
00133 errno = EINVAL;
00134 return NULL;
00135 }
00136
00137 {
00138 size_t buf_neededlength;
00139 CHAR_T *buf;
00140 CHAR_T *buf_malloced;
00141 const CHAR_T *cp;
00142 size_t i;
00143 DIRECTIVE *dp;
00144
00145 CHAR_T *result;
00146 size_t allocated;
00147 size_t length;
00148
00149
00150
00151 buf_neededlength =
00152 xsum4 (7, d.max_width_length, d.max_precision_length, 6);
00153 #if HAVE_ALLOCA
00154 if (buf_neededlength < 4000 / sizeof (CHAR_T))
00155 {
00156 buf = (CHAR_T *) alloca (buf_neededlength * sizeof (CHAR_T));
00157 buf_malloced = NULL;
00158 }
00159 else
00160 #endif
00161 {
00162 size_t buf_memsize = xtimes (buf_neededlength, sizeof (CHAR_T));
00163 if (size_overflow_p (buf_memsize))
00164 goto out_of_memory_1;
00165 buf = (CHAR_T *) malloc (buf_memsize);
00166 if (buf == NULL)
00167 goto out_of_memory_1;
00168 buf_malloced = buf;
00169 }
00170
00171 if (resultbuf != NULL)
00172 {
00173 result = resultbuf;
00174 allocated = *lengthp;
00175 }
00176 else
00177 {
00178 result = NULL;
00179 allocated = 0;
00180 }
00181 length = 0;
00182
00183
00184
00185
00186
00187
00188 #define ENSURE_ALLOCATION(needed) \
00189 if ((needed) > allocated) \
00190 { \
00191 size_t memory_size; \
00192 CHAR_T *memory; \
00193 \
00194 allocated = (allocated > 0 ? xtimes (allocated, 2) : 12); \
00195 if ((needed) > allocated) \
00196 allocated = (needed); \
00197 memory_size = xtimes (allocated, sizeof (CHAR_T)); \
00198 if (size_overflow_p (memory_size)) \
00199 goto out_of_memory; \
00200 if (result == resultbuf || result == NULL) \
00201 memory = (CHAR_T *) malloc (memory_size); \
00202 else \
00203 memory = (CHAR_T *) realloc (result, memory_size); \
00204 if (memory == NULL) \
00205 goto out_of_memory; \
00206 if (result == resultbuf && length > 0) \
00207 memcpy (memory, result, length * sizeof (CHAR_T)); \
00208 result = memory; \
00209 }
00210
00211 for (cp = format, i = 0, dp = &d.dir[0]; ; cp = dp->dir_end, i++, dp++)
00212 {
00213 if (cp != dp->dir_start)
00214 {
00215 size_t n = dp->dir_start - cp;
00216 size_t augmented_length = xsum (length, n);
00217
00218 ENSURE_ALLOCATION (augmented_length);
00219 memcpy (result + length, cp, n * sizeof (CHAR_T));
00220 length = augmented_length;
00221 }
00222 if (i == d.count)
00223 break;
00224
00225
00226 if (dp->conversion == '%')
00227 {
00228 size_t augmented_length;
00229
00230 if (!(dp->arg_index == ARG_NONE))
00231 abort ();
00232 augmented_length = xsum (length, 1);
00233 ENSURE_ALLOCATION (augmented_length);
00234 result[length] = '%';
00235 length = augmented_length;
00236 }
00237 else
00238 {
00239 if (!(dp->arg_index != ARG_NONE))
00240 abort ();
00241
00242 if (dp->conversion == 'n')
00243 {
00244 switch (a.arg[dp->arg_index].type)
00245 {
00246 case TYPE_COUNT_SCHAR_POINTER:
00247 *a.arg[dp->arg_index].a.a_count_schar_pointer = length;
00248 break;
00249 case TYPE_COUNT_SHORT_POINTER:
00250 *a.arg[dp->arg_index].a.a_count_short_pointer = length;
00251 break;
00252 case TYPE_COUNT_INT_POINTER:
00253 *a.arg[dp->arg_index].a.a_count_int_pointer = length;
00254 break;
00255 case TYPE_COUNT_LONGINT_POINTER:
00256 *a.arg[dp->arg_index].a.a_count_longint_pointer = length;
00257 break;
00258 #ifdef HAVE_LONG_LONG
00259 case TYPE_COUNT_LONGLONGINT_POINTER:
00260 *a.arg[dp->arg_index].a.a_count_longlongint_pointer = length;
00261 break;
00262 #endif
00263 default:
00264 abort ();
00265 }
00266 }
00267 else
00268 {
00269 arg_type type = a.arg[dp->arg_index].type;
00270 CHAR_T *p;
00271 unsigned int prefix_count;
00272 int prefixes[2];
00273 #if !USE_SNPRINTF
00274 size_t tmp_length;
00275 CHAR_T tmpbuf[700];
00276 CHAR_T *tmp;
00277
00278
00279
00280 {
00281 size_t width;
00282 size_t precision;
00283
00284 width = 0;
00285 if (dp->width_start != dp->width_end)
00286 {
00287 if (dp->width_arg_index != ARG_NONE)
00288 {
00289 int arg;
00290
00291 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
00292 abort ();
00293 arg = a.arg[dp->width_arg_index].a.a_int;
00294 width = (arg < 0 ? (unsigned int) (-arg) : arg);
00295 }
00296 else
00297 {
00298 const CHAR_T *digitp = dp->width_start;
00299
00300 do
00301 width = xsum (xtimes (width, 10), *digitp++ - '0');
00302 while (digitp != dp->width_end);
00303 }
00304 }
00305
00306 precision = 6;
00307 if (dp->precision_start != dp->precision_end)
00308 {
00309 if (dp->precision_arg_index != ARG_NONE)
00310 {
00311 int arg;
00312
00313 if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
00314 abort ();
00315 arg = a.arg[dp->precision_arg_index].a.a_int;
00316 precision = (arg < 0 ? 0 : arg);
00317 }
00318 else
00319 {
00320 const CHAR_T *digitp = dp->precision_start + 1;
00321
00322 precision = 0;
00323 while (digitp != dp->precision_end)
00324 precision = xsum (xtimes (precision, 10), *digitp++ - '0');
00325 }
00326 }
00327
00328 switch (dp->conversion)
00329 {
00330
00331 case 'd': case 'i': case 'u':
00332 # ifdef HAVE_LONG_LONG
00333 if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
00334 tmp_length =
00335 (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
00336 * 0.30103
00337 * 2
00338 )
00339 + 1
00340 + 1;
00341 else
00342 # endif
00343 if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
00344 tmp_length =
00345 (unsigned int) (sizeof (unsigned long) * CHAR_BIT
00346 * 0.30103
00347 * 2
00348 )
00349 + 1
00350 + 1;
00351 else
00352 tmp_length =
00353 (unsigned int) (sizeof (unsigned int) * CHAR_BIT
00354 * 0.30103
00355 * 2
00356 )
00357 + 1
00358 + 1;
00359 break;
00360
00361 case 'o':
00362 # ifdef HAVE_LONG_LONG
00363 if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
00364 tmp_length =
00365 (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
00366 * 0.333334
00367 )
00368 + 1
00369 + 1;
00370 else
00371 # endif
00372 if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
00373 tmp_length =
00374 (unsigned int) (sizeof (unsigned long) * CHAR_BIT
00375 * 0.333334
00376 )
00377 + 1
00378 + 1;
00379 else
00380 tmp_length =
00381 (unsigned int) (sizeof (unsigned int) * CHAR_BIT
00382 * 0.333334
00383 )
00384 + 1
00385 + 1;
00386 break;
00387
00388 case 'x': case 'X':
00389 # ifdef HAVE_LONG_LONG
00390 if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
00391 tmp_length =
00392 (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
00393 * 0.25
00394 )
00395 + 1
00396 + 2;
00397 else
00398 # endif
00399 if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
00400 tmp_length =
00401 (unsigned int) (sizeof (unsigned long) * CHAR_BIT
00402 * 0.25
00403 )
00404 + 1
00405 + 2;
00406 else
00407 tmp_length =
00408 (unsigned int) (sizeof (unsigned int) * CHAR_BIT
00409 * 0.25
00410 )
00411 + 1
00412 + 2;
00413 break;
00414
00415 case 'f': case 'F':
00416 # ifdef HAVE_LONG_DOUBLE
00417 if (type == TYPE_LONGDOUBLE)
00418 tmp_length =
00419 (unsigned int) (LDBL_MAX_EXP
00420 * 0.30103
00421 * 2
00422 )
00423 + 1
00424 + 10;
00425 else
00426 # endif
00427 tmp_length =
00428 (unsigned int) (DBL_MAX_EXP
00429 * 0.30103
00430 * 2
00431 )
00432 + 1
00433 + 10;
00434 tmp_length = xsum (tmp_length, precision);
00435 break;
00436
00437 case 'e': case 'E': case 'g': case 'G':
00438 case 'a': case 'A':
00439 tmp_length =
00440 12;
00441 tmp_length = xsum (tmp_length, precision);
00442 break;
00443
00444 case 'c':
00445 # if defined HAVE_WINT_T && !WIDE_CHAR_VERSION
00446 if (type == TYPE_WIDE_CHAR)
00447 tmp_length = MB_CUR_MAX;
00448 else
00449 # endif
00450 tmp_length = 1;
00451 break;
00452
00453 case 's':
00454 # ifdef HAVE_WCHAR_T
00455 if (type == TYPE_WIDE_STRING)
00456 {
00457 tmp_length =
00458 local_wcslen (a.arg[dp->arg_index].a.a_wide_string);
00459
00460 # if !WIDE_CHAR_VERSION
00461 tmp_length = xtimes (tmp_length, MB_CUR_MAX);
00462 # endif
00463 }
00464 else
00465 # endif
00466 tmp_length = strlen (a.arg[dp->arg_index].a.a_string);
00467 break;
00468
00469 case 'p':
00470 tmp_length =
00471 (unsigned int) (sizeof (void *) * CHAR_BIT
00472 * 0.25
00473 )
00474 + 1
00475 + 2;
00476 break;
00477
00478 default:
00479 abort ();
00480 }
00481
00482 if (tmp_length < width)
00483 tmp_length = width;
00484
00485 tmp_length = xsum (tmp_length, 1);
00486 }
00487
00488 if (tmp_length <= sizeof (tmpbuf) / sizeof (CHAR_T))
00489 tmp = tmpbuf;
00490 else
00491 {
00492 size_t tmp_memsize = xtimes (tmp_length, sizeof (CHAR_T));
00493
00494 if (size_overflow_p (tmp_memsize))
00495
00496 goto out_of_memory;
00497 tmp = (CHAR_T *) malloc (tmp_memsize);
00498 if (tmp == NULL)
00499
00500 goto out_of_memory;
00501 }
00502 #endif
00503
00504
00505
00506 p = buf;
00507 *p++ = '%';
00508 if (dp->flags & FLAG_GROUP)
00509 *p++ = '\'';
00510 if (dp->flags & FLAG_LEFT)
00511 *p++ = '-';
00512 if (dp->flags & FLAG_SHOWSIGN)
00513 *p++ = '+';
00514 if (dp->flags & FLAG_SPACE)
00515 *p++ = ' ';
00516 if (dp->flags & FLAG_ALT)
00517 *p++ = '#';
00518 if (dp->flags & FLAG_ZERO)
00519 *p++ = '0';
00520 if (dp->width_start != dp->width_end)
00521 {
00522 size_t n = dp->width_end - dp->width_start;
00523 memcpy (p, dp->width_start, n * sizeof (CHAR_T));
00524 p += n;
00525 }
00526 if (dp->precision_start != dp->precision_end)
00527 {
00528 size_t n = dp->precision_end - dp->precision_start;
00529 memcpy (p, dp->precision_start, n * sizeof (CHAR_T));
00530 p += n;
00531 }
00532
00533 switch (type)
00534 {
00535 #ifdef HAVE_LONG_LONG
00536 case TYPE_LONGLONGINT:
00537 case TYPE_ULONGLONGINT:
00538 *p++ = 'l';
00539
00540 #endif
00541 case TYPE_LONGINT:
00542 case TYPE_ULONGINT:
00543 #ifdef HAVE_WINT_T
00544 case TYPE_WIDE_CHAR:
00545 #endif
00546 #ifdef HAVE_WCHAR_T
00547 case TYPE_WIDE_STRING:
00548 #endif
00549 *p++ = 'l';
00550 break;
00551 #ifdef HAVE_LONG_DOUBLE
00552 case TYPE_LONGDOUBLE:
00553 *p++ = 'L';
00554 break;
00555 #endif
00556 default:
00557 break;
00558 }
00559 *p = dp->conversion;
00560 #if USE_SNPRINTF
00561 p[1] = '%';
00562 p[2] = 'n';
00563 p[3] = '\0';
00564 #else
00565 p[1] = '\0';
00566 #endif
00567
00568
00569 prefix_count = 0;
00570 if (dp->width_arg_index != ARG_NONE)
00571 {
00572 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
00573 abort ();
00574 prefixes[prefix_count++] = a.arg[dp->width_arg_index].a.a_int;
00575 }
00576 if (dp->precision_arg_index != ARG_NONE)
00577 {
00578 if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
00579 abort ();
00580 prefixes[prefix_count++] = a.arg[dp->precision_arg_index].a.a_int;
00581 }
00582
00583 #if USE_SNPRINTF
00584
00585
00586 ENSURE_ALLOCATION (xsum (length, 1));
00587 result[length] = '\0';
00588 #endif
00589
00590 for (;;)
00591 {
00592 size_t maxlen;
00593 int count;
00594 int retcount;
00595
00596 maxlen = allocated - length;
00597 count = -1;
00598 retcount = 0;
00599
00600 #if USE_SNPRINTF
00601 # define SNPRINTF_BUF(arg) \
00602 switch (prefix_count) \
00603 { \
00604 case 0: \
00605 retcount = SNPRINTF (result + length, maxlen, buf, \
00606 arg, &count); \
00607 break; \
00608 case 1: \
00609 retcount = SNPRINTF (result + length, maxlen, buf, \
00610 prefixes[0], arg, &count); \
00611 break; \
00612 case 2: \
00613 retcount = SNPRINTF (result + length, maxlen, buf, \
00614 prefixes[0], prefixes[1], arg, \
00615 &count); \
00616 break; \
00617 default: \
00618 abort (); \
00619 }
00620 #else
00621 # define SNPRINTF_BUF(arg) \
00622 switch (prefix_count) \
00623 { \
00624 case 0: \
00625 count = sprintf (tmp, buf, arg); \
00626 break; \
00627 case 1: \
00628 count = sprintf (tmp, buf, prefixes[0], arg); \
00629 break; \
00630 case 2: \
00631 count = sprintf (tmp, buf, prefixes[0], prefixes[1],\
00632 arg); \
00633 break; \
00634 default: \
00635 abort (); \
00636 }
00637 #endif
00638
00639 switch (type)
00640 {
00641 case TYPE_SCHAR:
00642 {
00643 int arg = a.arg[dp->arg_index].a.a_schar;
00644 SNPRINTF_BUF (arg);
00645 }
00646 break;
00647 case TYPE_UCHAR:
00648 {
00649 unsigned int arg = a.arg[dp->arg_index].a.a_uchar;
00650 SNPRINTF_BUF (arg);
00651 }
00652 break;
00653 case TYPE_SHORT:
00654 {
00655 int arg = a.arg[dp->arg_index].a.a_short;
00656 SNPRINTF_BUF (arg);
00657 }
00658 break;
00659 case TYPE_USHORT:
00660 {
00661 unsigned int arg = a.arg[dp->arg_index].a.a_ushort;
00662 SNPRINTF_BUF (arg);
00663 }
00664 break;
00665 case TYPE_INT:
00666 {
00667 int arg = a.arg[dp->arg_index].a.a_int;
00668 SNPRINTF_BUF (arg);
00669 }
00670 break;
00671 case TYPE_UINT:
00672 {
00673 unsigned int arg = a.arg[dp->arg_index].a.a_uint;
00674 SNPRINTF_BUF (arg);
00675 }
00676 break;
00677 case TYPE_LONGINT:
00678 {
00679 long int arg = a.arg[dp->arg_index].a.a_longint;
00680 SNPRINTF_BUF (arg);
00681 }
00682 break;
00683 case TYPE_ULONGINT:
00684 {
00685 unsigned long int arg = a.arg[dp->arg_index].a.a_ulongint;
00686 SNPRINTF_BUF (arg);
00687 }
00688 break;
00689 #ifdef HAVE_LONG_LONG
00690 case TYPE_LONGLONGINT:
00691 {
00692 long long int arg = a.arg[dp->arg_index].a.a_longlongint;
00693 SNPRINTF_BUF (arg);
00694 }
00695 break;
00696 case TYPE_ULONGLONGINT:
00697 {
00698 unsigned long long int arg = a.arg[dp->arg_index].a.a_ulonglongint;
00699 SNPRINTF_BUF (arg);
00700 }
00701 break;
00702 #endif
00703 case TYPE_DOUBLE:
00704 {
00705 double arg = a.arg[dp->arg_index].a.a_double;
00706 SNPRINTF_BUF (arg);
00707 }
00708 break;
00709 #ifdef HAVE_LONG_DOUBLE
00710 case TYPE_LONGDOUBLE:
00711 {
00712 long double arg = a.arg[dp->arg_index].a.a_longdouble;
00713 SNPRINTF_BUF (arg);
00714 }
00715 break;
00716 #endif
00717 case TYPE_CHAR:
00718 {
00719 int arg = a.arg[dp->arg_index].a.a_char;
00720 SNPRINTF_BUF (arg);
00721 }
00722 break;
00723 #ifdef HAVE_WINT_T
00724 case TYPE_WIDE_CHAR:
00725 {
00726 wint_t arg = a.arg[dp->arg_index].a.a_wide_char;
00727 SNPRINTF_BUF (arg);
00728 }
00729 break;
00730 #endif
00731 case TYPE_STRING:
00732 {
00733 const char *arg = a.arg[dp->arg_index].a.a_string;
00734 SNPRINTF_BUF (arg);
00735 }
00736 break;
00737 #ifdef HAVE_WCHAR_T
00738 case TYPE_WIDE_STRING:
00739 {
00740 const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string;
00741 SNPRINTF_BUF (arg);
00742 }
00743 break;
00744 #endif
00745 case TYPE_POINTER:
00746 {
00747 void *arg = a.arg[dp->arg_index].a.a_pointer;
00748 SNPRINTF_BUF (arg);
00749 }
00750 break;
00751 default:
00752 abort ();
00753 }
00754
00755 #if USE_SNPRINTF
00756
00757
00758
00759
00760 if (count >= 0)
00761 {
00762
00763
00764 if (count < maxlen && result[length + count] != '\0')
00765 abort ();
00766
00767 if (retcount > count)
00768 count = retcount;
00769 }
00770 else
00771 {
00772
00773
00774 if (p[1] != '\0')
00775 {
00776
00777
00778 p[1] = '\0';
00779 continue;
00780 }
00781 else
00782 {
00783
00784 if (retcount < 0)
00785 {
00786
00787
00788
00789
00790
00791 size_t bigger_need =
00792 xsum (xtimes (allocated, 2), 12);
00793 ENSURE_ALLOCATION (bigger_need);
00794 continue;
00795 }
00796 else
00797 count = retcount;
00798 }
00799 }
00800 #endif
00801
00802
00803 if (count < 0)
00804 {
00805 if (!(result == resultbuf || result == NULL))
00806 free (result);
00807 if (buf_malloced != NULL)
00808 free (buf_malloced);
00809 CLEANUP ();
00810 errno = EINVAL;
00811 return NULL;
00812 }
00813
00814 #if !USE_SNPRINTF
00815 if (count >= tmp_length)
00816
00817
00818 abort ();
00819 #endif
00820
00821
00822 if (count >= maxlen)
00823 {
00824
00825
00826
00827 size_t n =
00828 xmax (xsum (length, count), xtimes (allocated, 2));
00829
00830 ENSURE_ALLOCATION (n);
00831 #if USE_SNPRINTF
00832 continue;
00833 #endif
00834 }
00835
00836 #if USE_SNPRINTF
00837
00838 #else
00839
00840 memcpy (result + length, tmp, count * sizeof (CHAR_T));
00841 if (tmp != tmpbuf)
00842 free (tmp);
00843 #endif
00844
00845 length += count;
00846 break;
00847 }
00848 }
00849 }
00850 }
00851
00852
00853 ENSURE_ALLOCATION (xsum (length, 1));
00854 result[length] = '\0';
00855
00856 if (result != resultbuf && length + 1 < allocated)
00857 {
00858
00859 CHAR_T *memory;
00860
00861 memory = (CHAR_T *) realloc (result, (length + 1) * sizeof (CHAR_T));
00862 if (memory != NULL)
00863 result = memory;
00864 }
00865
00866 if (buf_malloced != NULL)
00867 free (buf_malloced);
00868 CLEANUP ();
00869 *lengthp = length;
00870 if (length > INT_MAX)
00871 goto length_overflow;
00872 return result;
00873
00874 length_overflow:
00875
00876
00877
00878 if (result != resultbuf)
00879 free (result);
00880 errno = EOVERFLOW;
00881 return NULL;
00882
00883 out_of_memory:
00884 if (!(result == resultbuf || result == NULL))
00885 free (result);
00886 if (buf_malloced != NULL)
00887 free (buf_malloced);
00888 out_of_memory_1:
00889 CLEANUP ();
00890 errno = ENOMEM;
00891 return NULL;
00892 }
00893 }
00894
00895 #undef SNPRINTF
00896 #undef USE_SNPRINTF
00897 #undef PRINTF_PARSE
00898 #undef DIRECTIVES
00899 #undef DIRECTIVE
00900 #undef CHAR_T
00901 #undef VASNPRINTF