summaryrefslogtreecommitdiff
path: root/lib/vasnprintf.c
diff options
context:
space:
mode:
authorStephen Kitt <skitt@debian.org>2016-05-27 10:11:04 +0200
committerManuel A. Fernandez Montecelo <manuel.montezelo@gmail.com>2016-05-27 14:28:33 +0100
commit752fd7247bc223bcea35bd89cf56d1c08ead9ba6 (patch)
treeb4a428f847a963738faaf24c8eff070fdb03a3a5 /lib/vasnprintf.c
parent9f7d4fa477ff2a51d7c932b13d57ac22dc033105 (diff)
parenta9a31b1de5776a3b08a82101a4fa711294f0dd1d (diff)
Imported Debian patch 0.9.6+really0.9.3-0.1debian/0.9.6+really0.9.3-0.1
Diffstat (limited to 'lib/vasnprintf.c')
-rw-r--r--lib/vasnprintf.c339
1 files changed, 153 insertions, 186 deletions
diff --git a/lib/vasnprintf.c b/lib/vasnprintf.c
index daea8164..daaec6ac 100644
--- a/lib/vasnprintf.c
+++ b/lib/vasnprintf.c
@@ -1,5 +1,5 @@
/* vsprintf with automatic memory allocation.
- Copyright (C) 1999, 2002-2015 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2002-2010 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
@@ -12,7 +12,8 @@
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
- with this program; if not, see <http://www.gnu.org/licenses/>. */
+ with this program; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
/* This file can be parametrized with the following macros:
VASNPRINTF The name of the function being defined.
@@ -87,8 +88,6 @@
/* Checked size_t computations. */
#include "xsize.h"
-#include "verify.h"
-
#if (NEED_PRINTF_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
# include <math.h>
# include "float+.h"
@@ -275,10 +274,10 @@ decimal_point_char (void)
{
const char *point;
/* Determine it in a multithread-safe way. We know nl_langinfo is
- multithread-safe on glibc systems and Mac OS X systems, but is not required
+ multithread-safe on glibc systems and MacOS X systems, but is not required
to be multithread-safe by POSIX. sprintf(), however, is multithread-safe.
localeconv() is rarely multithread-safe. */
-# if HAVE_NL_LANGINFO && (__GLIBC__ || defined __UCLIBC__ || (defined __APPLE__ && defined __MACH__))
+# if HAVE_NL_LANGINFO && (__GLIBC__ || (defined __APPLE__ && defined __MACH__))
point = nl_langinfo (RADIXCHAR);
# elif 1
char pointbuf[5];
@@ -323,11 +322,11 @@ is_infinite_or_zerol (long double x)
typedef unsigned int mp_limb_t;
# define GMP_LIMB_BITS 32
-verify (sizeof (mp_limb_t) * CHAR_BIT == GMP_LIMB_BITS);
+typedef int mp_limb_verify[2 * (sizeof (mp_limb_t) * CHAR_BIT == GMP_LIMB_BITS) - 1];
typedef unsigned long long mp_twolimb_t;
# define GMP_TWOLIMB_BITS 64
-verify (sizeof (mp_twolimb_t) * CHAR_BIT == GMP_TWOLIMB_BITS);
+typedef int mp_twolimb_verify[2 * (sizeof (mp_twolimb_t) * CHAR_BIT == GMP_TWOLIMB_BITS) - 1];
/* Representation of a bignum >= 0. */
typedef struct
@@ -552,61 +551,32 @@ divide (mpn_t a, mpn_t b, mpn_t *q)
size_t s;
{
mp_limb_t msd = b_ptr[b_len - 1]; /* = b[n-1], > 0 */
- /* Determine s = GMP_LIMB_BITS - integer_length (msd).
- Code copied from gnulib's integer_length.c. */
-# if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
- s = __builtin_clz (msd);
-# else
-# if defined DBL_EXPBIT0_WORD && defined DBL_EXPBIT0_BIT
- if (GMP_LIMB_BITS <= DBL_MANT_BIT)
+ s = 31;
+ if (msd >= 0x10000)
{
- /* Use 'double' operations.
- Assumes an IEEE 754 'double' implementation. */
-# define DBL_EXP_MASK ((DBL_MAX_EXP - DBL_MIN_EXP) | 7)
-# define DBL_EXP_BIAS (DBL_EXP_MASK / 2 - 1)
-# define NWORDS \
- ((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
- union { double value; unsigned int word[NWORDS]; } m;
-
- /* Use a single integer to floating-point conversion. */
- m.value = msd;
-
- s = GMP_LIMB_BITS
- - (((m.word[DBL_EXPBIT0_WORD] >> DBL_EXPBIT0_BIT) & DBL_EXP_MASK)
- - DBL_EXP_BIAS);
+ msd = msd >> 16;
+ s -= 16;
}
- else
-# undef NWORDS
-# endif
+ if (msd >= 0x100)
{
- s = 31;
- if (msd >= 0x10000)
- {
- msd = msd >> 16;
- s -= 16;
- }
- if (msd >= 0x100)
- {
- msd = msd >> 8;
- s -= 8;
- }
- if (msd >= 0x10)
- {
- msd = msd >> 4;
- s -= 4;
- }
- if (msd >= 0x4)
- {
- msd = msd >> 2;
- s -= 2;
- }
- if (msd >= 0x2)
- {
- msd = msd >> 1;
- s -= 1;
- }
+ msd = msd >> 8;
+ s -= 8;
+ }
+ if (msd >= 0x10)
+ {
+ msd = msd >> 4;
+ s -= 4;
+ }
+ if (msd >= 0x4)
+ {
+ msd = msd >> 2;
+ s -= 2;
+ }
+ if (msd >= 0x2)
+ {
+ msd = msd >> 1;
+ s -= 1;
}
-# endif
}
/* 0 <= s < GMP_LIMB_BITS.
Copy b, shifting it left by s bits. */
@@ -913,9 +883,9 @@ decode_long_double (long double x, int *ep, mpn_t *mp)
y = frexpl (x, &exp);
if (!(y >= 0.0L && y < 1.0L))
abort ();
- /* x = 2^exp * y = 2^(exp - LDBL_MANT_BIT) * (y * 2^LDBL_MANT_BIT), and the
+ /* x = 2^exp * y = 2^(exp - LDBL_MANT_BIT) * (y * LDBL_MANT_BIT), and the
latter is an integer. */
- /* Convert the mantissa (y * 2^LDBL_MANT_BIT) to a sequence of limbs.
+ /* Convert the mantissa (y * LDBL_MANT_BIT) to a sequence of limbs.
I'm not sure whether it's safe to cast a 'long double' value between
2^31 and 2^32 to 'unsigned int', therefore play safe and cast only
'long double' values between 0 and 2^16 (to 'unsigned int' or 'int',
@@ -963,11 +933,11 @@ decode_long_double (long double x, int *ep, mpn_t *mp)
abort ();
m.limbs[--i] = (hi << (GMP_LIMB_BITS / 2)) | lo;
}
-# if 0 /* On FreeBSD 6.1/x86, 'long double' numbers sometimes have excess
- precision. */
+#if 0 /* On FreeBSD 6.1/x86, 'long double' numbers sometimes have excess
+ precision. */
if (!(y == 0.0L))
abort ();
-# endif
+#endif
/* Normalise. */
while (m.nlimbs > 0 && m.limbs[m.nlimbs - 1] == 0)
m.nlimbs--;
@@ -1001,9 +971,9 @@ decode_double (double x, int *ep, mpn_t *mp)
y = frexp (x, &exp);
if (!(y >= 0.0 && y < 1.0))
abort ();
- /* x = 2^exp * y = 2^(exp - DBL_MANT_BIT) * (y * 2^DBL_MANT_BIT), and the
+ /* x = 2^exp * y = 2^(exp - DBL_MANT_BIT) * (y * DBL_MANT_BIT), and the
latter is an integer. */
- /* Convert the mantissa (y * 2^DBL_MANT_BIT) to a sequence of limbs.
+ /* Convert the mantissa (y * DBL_MANT_BIT) to a sequence of limbs.
I'm not sure whether it's safe to cast a 'double' value between
2^31 and 2^32 to 'unsigned int', therefore play safe and cast only
'double' values between 0 and 2^16 (to 'unsigned int' or 'int',
@@ -1530,7 +1500,7 @@ is_borderline (const char *digits, size_t precision)
/* Returns the number of TCHAR_T units needed as temporary space for the result
of sprintf or SNPRINTF of a single conversion directive. */
-static size_t
+static inline size_t
MAX_ROOM_NEEDED (const arguments *ap, size_t arg_index, FCHAR_T conversion,
arg_type type, int flags, size_t width, int has_precision,
size_t precision, int pad_ourselves)
@@ -1781,9 +1751,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
return NULL;
#define CLEANUP() \
- if (d.dir != d.direct_alloc_dir) \
- free (d.dir); \
- if (a.arg != a.direct_alloc_arg) \
+ free (d.dir); \
+ if (a.arg) \
free (a.arg);
if (PRINTF_FETCHARGS (args, &a) < 0)
@@ -1886,7 +1855,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
else
{
do
- result[length++] = *cp++;
+ result[length++] = (unsigned char) *cp++;
while (--n > 0);
}
}
@@ -1957,14 +1926,15 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
abort ();
arg = a.arg[dp->width_arg_index].a.a_int;
- width = arg;
if (arg < 0)
{
/* "A negative field width is taken as a '-' flag
followed by a positive field width." */
flags |= FLAG_LEFT;
- width = -width;
+ width = (unsigned int) (-arg);
}
+ else
+ width = arg;
}
else
{
@@ -2072,7 +2042,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
characters = 0;
}
- if (characters < width && !(dp->flags & FLAG_LEFT))
+ if (has_width && width > characters
+ && !(dp->flags & FLAG_LEFT))
{
size_t n = width - characters;
ENSURE_ALLOCATION (xsum (length, n));
@@ -2125,7 +2096,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
}
# endif
- if (characters < width && (dp->flags & FLAG_LEFT))
+ if (has_width && width > characters
+ && (dp->flags & FLAG_LEFT))
{
size_t n = width - characters;
ENSURE_ALLOCATION (xsum (length, n));
@@ -2198,7 +2170,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
characters = 0;
}
- if (characters < width && !(dp->flags & FLAG_LEFT))
+ if (has_width && width > characters
+ && !(dp->flags & FLAG_LEFT))
{
size_t n = width - characters;
ENSURE_ALLOCATION (xsum (length, n));
@@ -2251,7 +2224,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
}
# endif
- if (characters < width && (dp->flags & FLAG_LEFT))
+ if (has_width && width > characters
+ && (dp->flags & FLAG_LEFT))
{
size_t n = width - characters;
ENSURE_ALLOCATION (xsum (length, n));
@@ -2324,7 +2298,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
characters = 0;
}
- if (characters < width && !(dp->flags & FLAG_LEFT))
+ if (has_width && width > characters
+ && !(dp->flags & FLAG_LEFT))
{
size_t n = width - characters;
ENSURE_ALLOCATION (xsum (length, n));
@@ -2377,7 +2352,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
}
# endif
- if (characters < width && (dp->flags & FLAG_LEFT))
+ if (has_width && width > characters
+ && (dp->flags & FLAG_LEFT))
{
size_t n = width - characters;
ENSURE_ALLOCATION (xsum (length, n));
@@ -2428,14 +2404,15 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
abort ();
arg = a.arg[dp->width_arg_index].a.a_int;
- width = arg;
if (arg < 0)
{
/* "A negative field width is taken as a '-' flag
followed by a positive field width." */
flags |= FLAG_LEFT;
- width = -width;
+ width = (unsigned int) (-arg);
}
+ else
+ width = arg;
}
else
{
@@ -2565,7 +2542,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
characters = 0;
}
- if (characters < width && !(dp->flags & FLAG_LEFT))
+ if (has_width && width > characters
+ && !(dp->flags & FLAG_LEFT))
{
size_t n = width - characters;
ENSURE_ALLOCATION (xsum (length, n));
@@ -2626,7 +2604,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
}
}
- if (characters < width && (dp->flags & FLAG_LEFT))
+ if (has_width && width > characters
+ && (dp->flags & FLAG_LEFT))
{
size_t n = width - characters;
ENSURE_ALLOCATION (xsum (length, n));
@@ -2642,7 +2621,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
size_t characters;
# if !DCHAR_IS_TCHAR
/* This code assumes that TCHAR_T is 'char'. */
- verify (sizeof (TCHAR_T) == 1);
+ typedef int TCHAR_T_verify[2 * (sizeof (TCHAR_T) == 1) - 1];
TCHAR_T *tmpsrc;
DCHAR_T *tmpdst;
size_t tmpdst_len;
@@ -2803,7 +2782,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
if (has_width)
{
# if ENABLE_UNISTDIO
- /* Outside POSIX, it's preferable to compare the width
+ /* Outside POSIX, it's preferrable to compare the width
against the number of _characters_ of the converted
value. */
w = DCHAR_MBSNLEN (result + length, characters);
@@ -2817,7 +2796,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
/* w doesn't matter. */
w = 0;
- if (w < width && !(dp->flags & FLAG_LEFT))
+ if (has_width && width > w
+ && !(dp->flags & FLAG_LEFT))
{
size_t n = width - w;
ENSURE_ALLOCATION (xsum (length, n));
@@ -2900,7 +2880,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
length += tmpdst_len;
# endif
- if (w < width && (dp->flags & FLAG_LEFT))
+ if (has_width && width > w
+ && (dp->flags & FLAG_LEFT))
{
size_t n = width - w;
ENSURE_ALLOCATION (xsum (length, n));
@@ -2908,8 +2889,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
length += n;
}
}
-# endif
}
+# endif
#endif
#if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
else if ((dp->conversion == 'a' || dp->conversion == 'A')
@@ -2927,16 +2908,17 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
{
arg_type type = a.arg[dp->arg_index].type;
int flags = dp->flags;
+ int has_width;
size_t width;
int has_precision;
size_t precision;
size_t tmp_length;
- size_t count;
DCHAR_T tmpbuf[700];
DCHAR_T *tmp;
DCHAR_T *pad_ptr;
DCHAR_T *p;
+ has_width = 0;
width = 0;
if (dp->width_start != dp->width_end)
{
@@ -2947,14 +2929,15 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
abort ();
arg = a.arg[dp->width_arg_index].a.a_int;
- width = arg;
if (arg < 0)
{
/* "A negative field width is taken as a '-' flag
followed by a positive field width." */
flags |= FLAG_LEFT;
- width = -width;
+ width = (unsigned int) (-arg);
}
+ else
+ width = arg;
}
else
{
@@ -2964,6 +2947,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
width = xsum (xtimes (width, 10), *digitp++ - '0');
while (digitp != dp->width_end);
}
+ has_width = 1;
}
has_precision = 0;
@@ -3339,14 +3323,11 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
abort ();
# endif
}
-
/* The generated string now extends from tmp to p, with the
zero padding insertion point being at pad_ptr. */
- count = p - tmp;
-
- if (count < width)
+ if (has_width && p - tmp < width)
{
- size_t pad = width - count;
+ size_t pad = width - (p - tmp);
DCHAR_T *end = p + pad;
if (flags & FLAG_LEFT)
@@ -3379,26 +3360,28 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
p = end;
}
- count = p - tmp;
+ {
+ size_t count = p - tmp;
- if (count >= tmp_length)
- /* tmp_length was incorrectly calculated - fix the
- code above! */
- abort ();
+ if (count >= tmp_length)
+ /* tmp_length was incorrectly calculated - fix the
+ code above! */
+ abort ();
- /* Make room for the result. */
- if (count >= allocated - length)
- {
- size_t n = xsum (length, count);
+ /* Make room for the result. */
+ if (count >= allocated - length)
+ {
+ size_t n = xsum (length, count);
- ENSURE_ALLOCATION (n);
- }
+ ENSURE_ALLOCATION (n);
+ }
- /* Append the result. */
- memcpy (result + length, tmp, count * sizeof (DCHAR_T));
- if (tmp != tmpbuf)
- free (tmp);
- length += count;
+ /* Append the result. */
+ memcpy (result + length, tmp, count * sizeof (DCHAR_T));
+ if (tmp != tmpbuf)
+ free (tmp);
+ length += count;
+ }
}
#endif
#if (NEED_PRINTF_INFINITE_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
@@ -3432,8 +3415,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
arg_type type = a.arg[dp->arg_index].type;
# endif
int flags = dp->flags;
+ int has_width;
size_t width;
- size_t count;
int has_precision;
size_t precision;
size_t tmp_length;
@@ -3442,6 +3425,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
DCHAR_T *pad_ptr;
DCHAR_T *p;
+ has_width = 0;
width = 0;
if (dp->width_start != dp->width_end)
{
@@ -3452,14 +3436,15 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
abort ();
arg = a.arg[dp->width_arg_index].a.a_int;
- width = arg;
if (arg < 0)
{
/* "A negative field width is taken as a '-' flag
followed by a positive field width." */
flags |= FLAG_LEFT;
- width = -width;
+ width = (unsigned int) (-arg);
}
+ else
+ width = arg;
}
else
{
@@ -3469,6 +3454,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
width = xsum (xtimes (width, 10), *digitp++ - '0');
while (digitp != dp->width_end);
}
+ has_width = 1;
}
has_precision = 0;
@@ -3908,9 +3894,9 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
digits without trailing zeroes. */
if (exponent >= 0)
{
- size_t ecount = exponent + 1;
+ size_t count = exponent + 1;
/* Note: count <= precision = ndigits. */
- for (; ecount > 0; ecount--)
+ for (; count > 0; count--)
*p++ = digits[--ndigits];
if ((flags & FLAG_ALT) || ndigits > nzeroes)
{
@@ -3924,10 +3910,10 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
}
else
{
- size_t ecount = -exponent - 1;
+ size_t count = -exponent - 1;
*p++ = '0';
*p++ = decimal_point_char ();
- for (; ecount > 0; ecount--)
+ for (; count > 0; count--)
*p++ = '0';
while (ndigits > nzeroes)
{
@@ -4378,9 +4364,9 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
digits without trailing zeroes. */
if (exponent >= 0)
{
- size_t ecount = exponent + 1;
- /* Note: ecount <= precision = ndigits. */
- for (; ecount > 0; ecount--)
+ size_t count = exponent + 1;
+ /* Note: count <= precision = ndigits. */
+ for (; count > 0; count--)
*p++ = digits[--ndigits];
if ((flags & FLAG_ALT) || ndigits > nzeroes)
{
@@ -4394,10 +4380,10 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
}
else
{
- size_t ecount = -exponent - 1;
+ size_t count = -exponent - 1;
*p++ = '0';
*p++ = decimal_point_char ();
- for (; ecount > 0; ecount--)
+ for (; count > 0; count--)
*p++ = '0';
while (ndigits > nzeroes)
{
@@ -4525,11 +4511,9 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
/* The generated string now extends from tmp to p, with the
zero padding insertion point being at pad_ptr. */
- count = p - tmp;
-
- if (count < width)
+ if (has_width && p - tmp < width)
{
- size_t pad = width - count;
+ size_t pad = width - (p - tmp);
DCHAR_T *end = p + pad;
if (flags & FLAG_LEFT)
@@ -4562,36 +4546,36 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
p = end;
}
- count = p - tmp;
+ {
+ size_t count = p - tmp;
- if (count >= tmp_length)
- /* tmp_length was incorrectly calculated - fix the
- code above! */
- abort ();
+ if (count >= tmp_length)
+ /* tmp_length was incorrectly calculated - fix the
+ code above! */
+ abort ();
- /* Make room for the result. */
- if (count >= allocated - length)
- {
- size_t n = xsum (length, count);
+ /* Make room for the result. */
+ if (count >= allocated - length)
+ {
+ size_t n = xsum (length, count);
- ENSURE_ALLOCATION (n);
- }
+ ENSURE_ALLOCATION (n);
+ }
- /* Append the result. */
- memcpy (result + length, tmp, count * sizeof (DCHAR_T));
- if (tmp != tmpbuf)
- free (tmp);
- length += count;
+ /* Append the result. */
+ memcpy (result + length, tmp, count * sizeof (DCHAR_T));
+ if (tmp != tmpbuf)
+ free (tmp);
+ length += count;
+ }
}
#endif
else
{
arg_type type = a.arg[dp->arg_index].type;
int flags = dp->flags;
-#if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
- int has_width;
-#endif
#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
+ int has_width;
size_t width;
#endif
#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || NEED_PRINTF_UNBOUNDED_PRECISION
@@ -4613,17 +4597,14 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
TCHAR_T *fbp;
unsigned int prefix_count;
int prefixes[2] IF_LINT (= { 0 });
- int orig_errno;
#if !USE_SNPRINTF
size_t tmp_length;
TCHAR_T tmpbuf[700];
TCHAR_T *tmp;
#endif
-#if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
- has_width = 0;
-#endif
#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
+ has_width = 0;
width = 0;
if (dp->width_start != dp->width_end)
{
@@ -4634,14 +4615,15 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
abort ();
arg = a.arg[dp->width_arg_index].a.a_int;
- width = arg;
if (arg < 0)
{
/* "A negative field width is taken as a '-' flag
followed by a positive field width." */
flags |= FLAG_LEFT;
- width = -width;
+ width = (unsigned int) (-arg);
}
+ else
+ width = arg;
}
else
{
@@ -4651,9 +4633,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
width = xsum (xtimes (width, 10), *digitp++ - '0');
while (digitp != dp->width_end);
}
-#if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
has_width = 1;
-#endif
}
#endif
@@ -4771,10 +4751,6 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
*fbp++ = ' ';
if (flags & FLAG_ALT)
*fbp++ = '#';
-#if __GLIBC__ >= 2 && !defined __UCLIBC__
- if (flags & FLAG_LOCALIZED)
- *fbp++ = 'I';
-#endif
if (!pad_ourselves)
{
if (flags & FLAG_ZERO)
@@ -4793,7 +4769,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
{
const FCHAR_T *mp = dp->width_start;
do
- *fbp++ = *mp++;
+ *fbp++ = (unsigned char) *mp++;
while (--n > 0);
}
}
@@ -4814,7 +4790,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
{
const FCHAR_T *mp = dp->precision_start;
do
- *fbp++ = *mp++;
+ *fbp++ = (unsigned char) *mp++;
while (--n > 0);
}
}
@@ -4858,21 +4834,20 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
#endif
*fbp = dp->conversion;
#if USE_SNPRINTF
-# if !(((__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)) && !defined __UCLIBC__) || ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__))
+# if !(__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3) || ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__))
fbp[1] = '%';
fbp[2] = 'n';
fbp[3] = '\0';
# else
/* On glibc2 systems from glibc >= 2.3 - probably also older
- ones - we know that snprintf's return value conforms to
- ISO C 99: the tests gl_SNPRINTF_RETVAL_C99 and
- gl_SNPRINTF_TRUNCATION_C99 pass.
+ ones - we know that snprintf's returns value conforms to
+ ISO C 99: the gl_SNPRINTF_DIRECTIVE_N test passes.
Therefore we can avoid using %n in this situation.
On glibc2 systems from 2004-10-18 or newer, the use of %n
in format strings in writable memory may crash the program
(if compiled with _FORTIFY_SOURCE=2), so we should avoid it
in this situation. */
- /* On native Windows systems (such as mingw), we can avoid using
+ /* On native Win32 systems (such as mingw), we can avoid using
%n because:
- Although the gl_SNPRINTF_TRUNCATION_C99 test fails,
snprintf does not write more than the specified number
@@ -4881,7 +4856,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
- Although the gl_SNPRINTF_RETVAL_C99 test fails, snprintf
allows us to recognize the case of an insufficient
buffer size: it returns -1 in this case.
- On native Windows systems (such as mingw) where the OS is
+ On native Win32 systems (such as mingw) where the OS is
Windows Vista, the use of %n in format strings by default
crashes the program. See
<http://gcc.gnu.org/ml/gcc/2007-06/msg00122.html> and
@@ -4925,8 +4900,6 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
*(TCHAR_T *) (result + length) = '\0';
#endif
- orig_errno = errno;
-
for (;;)
{
int count = -1;
@@ -5141,8 +5114,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
size_t tmp_length =
MAX_ROOM_NEEDED (&a, dp->arg_index,
dp->conversion, type, flags,
- width,
- has_precision,
+ width, has_precision,
precision, pad_ourselves);
if (maxlen < tmp_length)
@@ -5179,21 +5151,18 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
/* SNPRINTF or sprintf failed. Save and use the errno
that it has set, if any. */
int saved_errno = errno;
- if (saved_errno == 0)
- {
- if (dp->conversion == 'c' || dp->conversion == 's')
- saved_errno = EILSEQ;
- else
- saved_errno = EINVAL;
- }
if (!(result == resultbuf || result == NULL))
free (result);
if (buf_malloced != NULL)
free (buf_malloced);
CLEANUP ();
-
- errno = saved_errno;
+ errno =
+ (saved_errno != 0
+ ? saved_errno
+ : (dp->conversion == 'c' || dp->conversion == 's'
+ ? EILSEQ
+ : EINVAL));
return NULL;
}
@@ -5315,7 +5284,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
DCHAR_T *tmpdst;
size_t tmpdst_len;
/* This code assumes that TCHAR_T is 'char'. */
- verify (sizeof (TCHAR_T) == 1);
+ typedef int TCHAR_T_verify
+ [2 * (sizeof (TCHAR_T) == 1) - 1];
# if USE_SNPRINTF
tmpsrc = (TCHAR_T *) (result + length);
# else
@@ -5382,7 +5352,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
tmpsrc += count;
tmpdst += count;
for (n = count; n > 0; n--)
- *--tmpdst = *--tmpsrc;
+ *--tmpdst = (unsigned char) *--tmpsrc;
}
}
#endif
@@ -5408,7 +5378,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
{
size_t w;
# if ENABLE_UNISTDIO
- /* Outside POSIX, it's preferable to compare the width
+ /* Outside POSIX, it's preferrable to compare the width
against the number of _characters_ of the converted
value. */
w = DCHAR_MBSNLEN (result + length, count);
@@ -5528,9 +5498,6 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
length += count;
break;
}
- errno = orig_errno;
-#undef pad_ourselves
-#undef prec_ourselves
}
}
}