1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-08-07 06:43:00 +03:00
This commit is contained in:
Jakub Jelinek
2007-07-31 13:33:18 +00:00
parent d6220e9ee3
commit 32c075e1f0
448 changed files with 13841 additions and 10982 deletions

View File

@@ -1,4 +1,4 @@
# Copyright (C) 1991-2002,2003,2004,2005,2006 Free Software Foundation, Inc.
# Copyright (C) 1991-2006, 2007 Free Software Foundation, Inc.
# This file is part of the GNU C Library.
# The GNU C Library is free software; you can redistribute it and/or
@@ -54,7 +54,7 @@ tests := tstscanf test_rdwr test-popen tstgetln test-fseek \
tst-swprintf tst-fseek tst-fmemopen test-vfprintf tst-gets \
tst-perror tst-sprintf tst-rndseek tst-fdopen tst-fphex bug14 bug15 \
tst-popen tst-unlockedio tst-fmemopen2 tst-put-error tst-fgets \
tst-fwrite bug16
tst-fwrite bug16 bug17 tst-sprintf2
test-srcs = tst-unbputc tst-printf

View File

@@ -1,5 +1,5 @@
/* Internal function for converting integers to ASCII.
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2002, 2003, 2004
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2002, 2003, 2004, 2007
Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Torbjorn Granlund <tege@matematik.su.se>
@@ -269,6 +269,7 @@ _itoa (value, buflim, base, upper_case)
default:
{
char *bufend = buflim;
#if BITS_PER_MP_LIMB == 64
mp_limb_t base_multiplier = brec->base_multiplier;
if (brec->flag)
@@ -454,6 +455,8 @@ _itoa (value, buflim, base, upper_case)
}
while (n != 0);
#endif
if (buflim == bufend)
*--buflim = '0';
}
break;
}

31
stdio-common/bug17.c Normal file
View File

@@ -0,0 +1,31 @@
#include <stdio.h>
#include <string.h>
static int
do_test (void)
{
static const char expect[] = "0, 0, 0";
char buf[100];
int status = 0;
static const char fmt1[] = "%0d, %0ld, %0lld";
snprintf (buf, sizeof (buf), fmt1, 0, 0L, 0LL);
if (strcmp (buf, expect) != 0)
{
printf ("\"%s\": got \"%s\", expected \"%s\"\n", fmt1, buf, expect);
status = 1;
}
static const char fmt2[] = "%0u, %0lu, %0llu";
snprintf (buf, sizeof (buf), fmt2, 0u, 0uL, 0uLL);
if (strcmp (buf, expect) != 0)
{
printf ("\"%s\": got \"%s\", expected \"%s\"\n", fmt2, buf, expect);
status = 1;
}
return status;
}
#define TEST_FUNCTION do_test ()
#include "../test-skeleton.c"

View File

@@ -1,6 +1,5 @@
/* Floating point output for `printf'.
Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2006
Free Software Foundation, Inc.
Copyright (C) 1995-2003, 2006, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
@@ -793,7 +792,7 @@ ___printf_fp (FILE *fp,
else
{
/* This is a special case. We don't need a factor because the
numbers are in the range of 0.0 <= fp < 8.0. We simply
numbers are in the range of 1.0 <= |fp| < 8.0. We simply
shift it to the right place and divide it by 1.0 to get the
leading digit. (Of course this division is not really made.) */
assert (0 <= exponent && exponent < 3 &&
@@ -811,12 +810,14 @@ ___printf_fp (FILE *fp,
int chars_needed;
int expscale;
int intdig_max, intdig_no = 0;
int fracdig_min, fracdig_max, fracdig_no = 0;
int fracdig_min;
int fracdig_max;
int dig_max;
int significant;
int ngroups = 0;
char spec = _tolower (info->spec);
if (_tolower (info->spec) == 'e')
if (spec == 'e')
{
type = info->spec;
intdig_max = 1;
@@ -826,7 +827,7 @@ ___printf_fp (FILE *fp,
dig_max = INT_MAX; /* Unlimited. */
significant = 1; /* Does not matter here. */
}
else if (_tolower (info->spec) == 'f')
else if (spec == 'f')
{
type = 'f';
fracdig_min = fracdig_max = info->prec < 0 ? 6 : info->prec;
@@ -923,7 +924,9 @@ ___printf_fp (FILE *fp,
}
/* Generate the needed number of fractional digits. */
while (fracdig_no < fracdig_min
int fracdig_no = 0;
int added_zeros = 0;
while (fracdig_no < fracdig_min + added_zeros
|| (fracdig_no < fracdig_max && (fracsize > 1 || frac[0] != 0)))
{
++fracdig_no;
@@ -934,7 +937,7 @@ ___printf_fp (FILE *fp,
{
++fracdig_max;
if (fracdig_min > 0)
++fracdig_min;
++added_zeros;
}
}
@@ -971,11 +974,25 @@ ___printf_fp (FILE *fp,
{
/* Process fractional digits. Terminate if not rounded or
radix character is reached. */
int removed = 0;
while (*--wtp != decimalwc && *wtp == L'9')
*wtp = '0';
{
*wtp = L'0';
++removed;
}
if (removed == fracdig_min && added_zeros > 0)
--added_zeros;
if (*wtp != decimalwc)
/* Round up. */
(*wtp)++;
else if (__builtin_expect (spec == 'g' && type == 'f' && info->alt
&& wtp == wstartp + 1
&& wstartp[0] == L'0',
0))
/* This is a special case: the rounded number is 1.0,
the format is 'g' or 'G', and the alternative format
is selected. This means the result must be "1.". */
--added_zeros;
}
if (fracdig_no == 0 || *wtp == decimalwc)
@@ -997,6 +1014,12 @@ ___printf_fp (FILE *fp,
{
*wstartp = '1';
exponent += expsign == 0 ? 1 : -1;
/* The above exponent adjustment could lead to 1.0e-00,
e.g. for 0.999999999. Make sure exponent 0 always
uses + sign. */
if (exponent == 0)
expsign = 0;
}
else if (intdig_no == dig_max)
{
@@ -1042,7 +1065,7 @@ ___printf_fp (FILE *fp,
do_expo:
/* Now remove unnecessary '0' at the end of the string. */
while (fracdig_no > fracdig_min && *(wcp - 1) == L'0')
while (fracdig_no > fracdig_min + added_zeros && *(wcp - 1) == L'0')
{
--wcp;
--fracdig_no;
@@ -1060,26 +1083,46 @@ ___printf_fp (FILE *fp,
/* Write the exponent if it is needed. */
if (type != 'f')
{
*wcp++ = (wchar_t) type;
*wcp++ = expsign ? L'-' : L'+';
/* Find the magnitude of the exponent. */
expscale = 10;
while (expscale <= exponent)
expscale *= 10;
if (exponent < 10)
/* Exponent always has at least two digits. */
*wcp++ = L'0';
if (__builtin_expect (expsign != 0 && exponent == 4 && spec == 'g', 0))
{
/* This is another special case. The exponent of the number is
really smaller than -4, which requires the 'e'/'E' format.
But after rounding the number has an exponent of -4. */
assert (wcp >= wstartp + 1);
assert (wstartp[0] == L'1');
__wmemcpy (wstartp, L"0.0001", 6);
wstartp[1] = decimalwc;
if (wcp >= wstartp + 2)
{
wmemset (wstartp + 6, L'0', wcp - (wstartp + 2));
wcp += 4;
}
else
wcp += 5;
}
else
do
{
expscale /= 10;
*wcp++ = L'0' + (exponent / expscale);
exponent %= expscale;
}
while (expscale > 10);
*wcp++ = L'0' + exponent;
{
*wcp++ = (wchar_t) type;
*wcp++ = expsign ? L'-' : L'+';
/* Find the magnitude of the exponent. */
expscale = 10;
while (expscale <= exponent)
expscale *= 10;
if (exponent < 10)
/* Exponent always has at least two digits. */
*wcp++ = L'0';
else
do
{
expscale /= 10;
*wcp++ = L'0' + (exponent / expscale);
exponent %= expscale;
}
while (expscale > 10);
*wcp++ = L'0' + exponent;
}
}
/* Compute number of characters which must be filled with the padding

View File

@@ -1,5 +1,5 @@
/* Tests of *printf for very large strings.
Copyright (C) 2000, 2002, 2003 Free Software Foundation, Inc.
Copyright (C) 2000, 2002, 2003, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2000.
@@ -94,6 +94,7 @@ main (void)
fprintf (fp, "%.*s", 30000, large);
large[20000] = '\0';
fprintf (fp, large);
fprintf (fp, "%-1.300000000s", "hello");
if (fflush (fp) != 0 || ferror (fp) != 0 || fclose (fp) != 0)
{
@@ -108,11 +109,12 @@ main (void)
setlocale (LC_ALL, NULL));
exit (1);
}
else if (st.st_size != 99999)
else if (st.st_size != 50000 + 30000 + 19999 + 5)
{
printf ("file size incorrect for locale %s: %jd instead of %jd\n",
setlocale (LC_ALL, NULL),
(intmax_t) st.st_size, (intmax_t) 99999);
(intmax_t) st.st_size,
(intmax_t) 50000 + 30000 + 19999 + 5);
res = 1;
}
else

View File

@@ -4012,6 +4012,32 @@ sprint_double_type sprint_doubles[] =
{__LINE__, 16, "0x1.0p+4", "%.1a"},
{__LINE__, 16, "0x1.00000000000000000000p+4", "%.20a"},
{__LINE__, 4444.88888888, "4445", "%2.F"},
{__LINE__, 0.956, "1", "%.0g"},
{__LINE__, 1.0956, "1.", "%#.0g"},
{__LINE__, 0.956, "1.", "%#.0g"},
{__LINE__, 0.0956, "0.1", "%#.0g"},
{__LINE__, 0.00956, "0.01", "%#.0g"},
{__LINE__, 0.000956, "0.001", "%#.0g"},
{__LINE__, 0.000098, "0.0001", "%#.0g"},
{__LINE__, 0.0000996, "0.00010", "%#.2g"},
{__LINE__, 9.999999999999999e-05, "0.0001", "%g"},
{__LINE__, 1.0, "1.000000e+00", "%e"},
{__LINE__, .9999999999999999, "1.000000e+00", "%e"},
{__LINE__, 912.98, "913.0", "%#.4g"},
{__LINE__, 50.999999, "51.000", "%#.5g"},
{__LINE__, 0.956, "1", "%.1g"},
{__LINE__, 0.956, "1.", "%#.1g"},
{__LINE__, 0.996, "1", "%.2g"},
{__LINE__, 0.996, "1.0", "%#.2g"},
{__LINE__, 999.98, "1000", "%.4g"},
{__LINE__, 999.98, "1000.", "%#.4g"},
{__LINE__, 999.998, "1000", "%.5g"},
{__LINE__, 999.998, "1000.0", "%#.5g"},
{__LINE__, 999.9998, "1000", "%g"},
{__LINE__, 999.9998, "1000.00", "%#g"},
{__LINE__, 912.98, "913", "%.4g"},
{__LINE__, 50.999999, "51", "%.5g"},
{0 }
@@ -4023,13 +4049,8 @@ sprint_double_type sprint_doubles[] =
int required_precision = 13;
#if defined(__STDC__) || defined(__cplusplus)
static int
matches (register char *result, register const char *desired)
#else
int matches(result, desired)
register char *result; register const char *desired;
#endif
{
int digits_seen = 0;
for (;; result++, desired++) {
@@ -4080,7 +4101,7 @@ int main(int argc, char *argv[])
/* And one special test. */
{
const char ref[] = "1.7763568394002504646778106689453125e-15";
static const char ref[] = "1.7763568394002504646778106689453125e-15";
int i;
d = 1.0;
for (i = 1; i < 50; ++i)

View File

@@ -37,5 +37,26 @@ main (void)
free (dst);
}
if (sprintf (buf, "%1$d%3$.*2$s%4$d", 7, 67108863, "x", 8) != 3
|| strcmp (buf, "7x8") != 0)
{
printf ("sprintf (buf, \"%%1$d%%3$.*2$s%%4$d\", 7, 67108863, \"x\", 8) produced `%s' output", buf);
result = 1;
}
if (sprintf (buf, "%67108863.16\"%d", 7) != 14
|| strcmp (buf, "%67108863.16\"7") != 0)
{
printf ("sprintf (buf, \"%%67108863.16\\\"%%d\", 7) produced `%s' output", buf);
result = 1;
}
if (sprintf (buf, "%*\"%d", 0x3ffffff, 7) != 11
|| strcmp (buf, "%67108863\"7") != 0)
{
printf ("sprintf (buf, \"%%*\\\"%%d\", 0x3ffffff, 7) produced `%s' output", buf);
result = 1;
}
return result;
}

View File

@@ -0,0 +1,82 @@
#include <float.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
int
main (void)
{
volatile union { long double l; long long x[2]; } u, v;
char buf[64];
int result = 0;
#if LDBL_MANT_DIG == 106 || LDBL_MANT_DIG == 113
# define COMPARE_LDBL(u, v) \
((u).l == (v).l && (u).x[0] == (v).x[0] && (u).x[1] == (v).x[1])
#else
# define COMPARE_LDBL(u, v) ((u).l == (v).l)
#endif
#define TEST(val) \
do \
{ \
u.l = (val); \
snprintf (buf, sizeof buf, "%LaL", u.l); \
if (strcmp (buf, #val) != 0) \
{ \
printf ("Error on line %d: %s != %s\n", __LINE__, buf, #val); \
result = 1; \
} \
if (sscanf (#val, "%La", &v.l) != 1 || !COMPARE_LDBL (u, v)) \
{ \
printf ("Error sscanf on line %d: %La != %La\n", __LINE__, \
u.l, v.l); \
result = 1; \
} \
/* printf ("%s %La %016Lx %016Lx\n", #val, u.l, u.x[0], u.x[1]); */ \
} \
while (0)
#if LDBL_MANT_DIG >= 106
# if LDBL_MANT_DIG == 106
TEST (0x0.ffffffffffffp-1022L);
TEST (0x0.ffffffffffff1p-1022L);
TEST (0x0.fffffffffffffp-1022L);
# endif
TEST (0x1p-1022L);
TEST (0x1.0000000000001p-1022L);
TEST (0x1.00000000001e7p-1022L);
TEST (0x1.fffffffffffffp-1022L);
TEST (0x1p-1021L);
TEST (0x1.00000000000008p-1021L);
TEST (0x1.0000000000001p-1021L);
TEST (0x1.00000000000018p-1021L);
TEST (0x1.0000000000000f8p-1017L);
TEST (0x1.0000000000001p-1017L);
TEST (0x1.000000000000108p-1017L);
TEST (0x1.000000000000dcf8p-1013L);
TEST (0x1.000000000000ddp-1013L);
TEST (0x1.000000000000dd08p-1013L);
TEST (0x1.ffffffffffffffffffffffffffp-1L);
TEST (0x1.ffffffffffffffffffffffffff8p-1L);
TEST (0x1p+0L);
TEST (0x1.000000000000000000000000008p+0L);
TEST (0x1.00000000000000000000000001p+0L);
TEST (0x1.000000000000000000000000018p+0L);
TEST (0x1.23456789abcdef123456789abc8p+0L);
TEST (0x1.23456789abcde7123456789abc8p+0L);
TEST (0x1.23456789abcdef123456789abc8p+64L);
TEST (0x1.23456789abcde7123456789abc8p+64L);
TEST (0x1.123456789abcdef123456789p-969L);
# if LDBL_MANT_DIG == 106
TEST (-0x1.2d71957cc1263bbbeb1d365f1e8p-969L);
TEST (0x1.23456789abcdef0123456789abp-970L);
TEST (0x1.579bde02468acp-1001L);
TEST (0x0.abcdef0123456p-1022L);
TEST (0x1.abcdef0123456p-1022L);
TEST (0x1.abcdef012345678p-1014L);
TEST (0x1.abcdef0123456f8p-1014L);
# endif
#endif
return result;
}

View File

@@ -1,4 +1,4 @@
/* Copyright (C) 1991,92,96,97,98,99,2000,2001 Free Software Foundation, Inc.
/* Copyright (C) 1991,92,1996-2001,2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -272,7 +272,7 @@ main (int argc, char **argv)
res = sscanf ("0x1234", "%lf", &d);
printf ("res = %d, d = %f\n", res, d);
if (res != 0 || d != 123456.789)
if (res != 1 || d != 4660)
{
fputs ("test failed!\n", stdout);
result = 1;

View File

@@ -1,4 +1,4 @@
/* Copyright (C) 1991-2002, 2003, 2004, 2005, 2006
/* Copyright (C) 1991-2002, 2003, 2004, 2005, 2006, 2007
Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -1025,10 +1025,11 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
const char *mbs = (const char *) string; \
mbstate_t mbstate; \
\
len = prec != -1 ? (size_t) prec : strlen (mbs); \
len = prec != -1 ? __strnlen (mbs, (size_t) prec) : strlen (mbs); \
\
/* Allocate dynamically an array which definitely is long \
enough for the wide character version. */ \
enough for the wide character version. Each byte in the \
multi-byte string can produce at most one wide character. */ \
if (__libc_use_alloca (len * sizeof (wchar_t))) \
string = (CHAR_T *) alloca (len * sizeof (wchar_t)); \
else if ((string = (CHAR_T *) malloc (len * sizeof (wchar_t))) \
@@ -1159,19 +1160,26 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
else \
{ \
/* In case we have a multibyte character set the \
situation is more compilcated. We must not copy \
situation is more complicated. We must not copy \
bytes at the end which form an incomplete character. */\
wchar_t ignore[prec]; \
size_t ignore_size = (unsigned) prec > 1024 ? 1024 : prec;\
wchar_t ignore[ignore_size]; \
const char *str2 = string; \
mbstate_t ps; \
const char *strend = string + prec; \
if (strend < string) \
strend = (const char *) UINTPTR_MAX; \
\
mbstate_t ps; \
memset (&ps, '\0', sizeof (ps)); \
if (__mbsnrtowcs (ignore, &str2, prec, prec, &ps) \
== (size_t) -1) \
{ \
done = -1; \
goto all_done; \
} \
\
while (str2 != NULL && str2 < strend) \
if (__mbsnrtowcs (ignore, &str2, strend - str2, \
ignore_size, &ps) == (size_t) -1) \
{ \
done = -1; \
goto all_done; \
} \
\
if (str2 == NULL) \
len = strlen (string); \
else \
@@ -1618,6 +1626,8 @@ do_positional:
/* Just a counter. */
size_t cnt;
free (workstart);
workstart = NULL;
if (grouping == (const char *) -1)
{
@@ -1792,7 +1802,9 @@ do_positional:
int use_outdigits = specs[nspecs_done].info.i18n;
char pad = specs[nspecs_done].info.pad;
CHAR_T spec = specs[nspecs_done].info.spec;
CHAR_T *workstart = NULL;
workstart = NULL;
workend = &work_buffer[sizeof (work_buffer) / sizeof (CHAR_T)];
/* Fill in last information. */
if (specs[nspecs_done].width_arg != -1)
@@ -1888,8 +1900,7 @@ do_positional:
break;
}
if (__builtin_expect (workstart != NULL, 0))
free (workstart);
free (workstart);
workstart = NULL;
/* Write the following constant string. */
@@ -1917,7 +1928,7 @@ printf_unknown (FILE *s, const struct printf_info *info,
{
int done = 0;
CHAR_T work_buffer[MAX (info->width, info->spec) + 32];
CHAR_T work_buffer[MAX (sizeof (info->width), sizeof (info->prec)) * 3];
CHAR_T *const workend
= &work_buffer[sizeof (work_buffer) / sizeof (CHAR_T)];
register CHAR_T *w;

View File

@@ -1,5 +1,4 @@
/* Copyright (C) 1991-2002, 2003, 2004, 2005, 2006
Free Software Foundation, Inc.
/* Copyright (C) 1991-2006, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -1888,9 +1887,8 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
/* Have we read any character? If we try to read a number
in hexadecimal notation and we have read only the `0x'
prefix or no exponent this is an error. */
if (__builtin_expect (wpsize == 0
|| (is_hexa && (wpsize == 2 || ! got_e)), 0))
prefix this is an error. */
if (__builtin_expect (wpsize == 0 || (is_hexa && wpsize == 2), 0))
conv_error ();
scan_float: