From 0ecb606cb6cf65de1d9fc8a919bceb4be476c602 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 12 Jul 2007 18:26:36 +0000 Subject: 2.5-18.1 --- stdio-common/Makefile | 11 +- stdio-common/Versions | 5 +- stdio-common/_itoa.c | 5 +- stdio-common/asprintf.c | 12 +- stdio-common/bits/printf-ldbl.h | 24 ++ stdio-common/bug16.c | 43 ++++ stdio-common/bug17.c | 31 +++ stdio-common/ctermid.c | 36 +++ stdio-common/cuserid.c | 35 +++ stdio-common/dprintf.c | 9 +- stdio-common/errlist.c | 37 +++ stdio-common/flockfile.c | 30 +++ stdio-common/fprintf.c | 10 +- stdio-common/fscanf.c | 6 +- stdio-common/ftrylockfile.c | 31 +++ stdio-common/funlockfile.c | 30 +++ stdio-common/fxprintf.c | 56 +++++ stdio-common/perror.c | 7 +- stdio-common/printf-parsemb.c | 5 +- stdio-common/printf-prs.c | 7 +- stdio-common/printf.c | 8 +- stdio-common/printf.h | 6 +- stdio-common/printf_fp.c | 139 +++++++---- stdio-common/printf_fphex.c | 493 ++++++++++++++++++++++++++++++++++++++++ stdio-common/printf_size.c | 6 +- stdio-common/psignal.c | 25 +- stdio-common/remove.c | 33 +++ stdio-common/rename.c | 41 ++++ stdio-common/renameat.c | 50 ++++ stdio-common/scanf.c | 5 +- stdio-common/siglist.c | 38 ++++ stdio-common/snprintf.c | 8 +- stdio-common/sprintf.c | 12 +- stdio-common/sscanf.c | 12 +- stdio-common/tempname.c | 59 +++++ stdio-common/test-vfprintf.c | 8 +- stdio-common/tfformat.c | 18 +- stdio-common/tmpfile.c | 66 ++++++ stdio-common/tmpfile64.c | 3 + stdio-common/tst-fgets.c | 20 ++ stdio-common/tst-fmemopen2.c | 68 ++++++ stdio-common/tst-fwrite.c | 70 ++++++ stdio-common/tst-printf.c | 11 +- stdio-common/tst-printf.sh | 14 +- stdio-common/tst-put-error.c | 33 +++ stdio-common/tst-sprintf.c | 21 ++ stdio-common/tst-sprintf2.c | 82 +++++++ stdio-common/tstdiomisc.c | 12 +- stdio-common/tstscanf.c | 4 +- stdio-common/vfprintf.c | 113 +++++---- stdio-common/vfscanf.c | 183 ++++++++------- stdio-common/vprintf.c | 9 +- 52 files changed, 1835 insertions(+), 265 deletions(-) create mode 100644 stdio-common/bits/printf-ldbl.h create mode 100644 stdio-common/bug16.c create mode 100644 stdio-common/bug17.c create mode 100644 stdio-common/ctermid.c create mode 100644 stdio-common/cuserid.c create mode 100644 stdio-common/errlist.c create mode 100644 stdio-common/flockfile.c create mode 100644 stdio-common/ftrylockfile.c create mode 100644 stdio-common/funlockfile.c create mode 100644 stdio-common/fxprintf.c create mode 100644 stdio-common/printf_fphex.c create mode 100644 stdio-common/remove.c create mode 100644 stdio-common/rename.c create mode 100644 stdio-common/renameat.c create mode 100644 stdio-common/siglist.c create mode 100644 stdio-common/tempname.c create mode 100644 stdio-common/tmpfile.c create mode 100644 stdio-common/tmpfile64.c create mode 100644 stdio-common/tst-fgets.c create mode 100644 stdio-common/tst-fmemopen2.c create mode 100644 stdio-common/tst-fwrite.c create mode 100644 stdio-common/tst-put-error.c create mode 100644 stdio-common/tst-sprintf2.c (limited to 'stdio-common') diff --git a/stdio-common/Makefile b/stdio-common/Makefile index 3a66f1d021..7bd368bdca 100644 --- a/stdio-common/Makefile +++ b/stdio-common/Makefile @@ -1,4 +1,4 @@ -# Copyright (C) 1991-2002, 2003, 2004 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 @@ -21,7 +21,7 @@ # subdir := stdio-common -headers := printf.h stdio_ext.h +headers := stdio_ext.h printf.h bits/printf-ldbl.h routines := \ ctermid cuserid \ @@ -33,14 +33,14 @@ routines := \ perror psignal \ tmpfile tmpfile64 tmpnam tmpnam_r tempnam tempname \ getline getw putw \ - remove rename \ + remove rename renameat \ flockfile ftrylockfile funlockfile install-others = $(inst_includedir)/bits/stdio_lim.h include ../Makeconfig -aux := errlist siglist printf-parsemb printf-parsewc +aux := errlist siglist printf-parsemb printf-parsewc fxprintf distribute := _itoa.h _itowa.h _i18n_number.h \ printf-parse.h stdio_lim.h.in tst-unbputc.sh tst-printf.sh @@ -53,7 +53,8 @@ tests := tstscanf test_rdwr test-popen tstgetln test-fseek \ scanf11 scanf12 tst-tmpnam tst-cookie tst-obprintf tst-sscanf \ 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-popen tst-unlockedio tst-fmemopen2 tst-put-error tst-fgets \ + tst-fwrite bug16 bug17 tst-sprintf2 test-srcs = tst-unbputc tst-printf diff --git a/stdio-common/Versions b/stdio-common/Versions index 1dbce1a124..2f64429346 100644 --- a/stdio-common/Versions +++ b/stdio-common/Versions @@ -37,7 +37,7 @@ libc { tempnam; tmpfile; tmpnam; tmpnam_r; # v* - vfprintf; vfscanf; vprintf; + vfprintf; vfscanf; vprintf; } GLIBC_2.1 { # p* @@ -46,6 +46,9 @@ libc { # t* tmpfile; tmpfile64; } + GLIBC_2.4 { + renameat; + } GLIBC_PRIVATE { # global variables _itoa_lower_digits; diff --git a/stdio-common/_itoa.c b/stdio-common/_itoa.c index f61b23fceb..285fde2ab9 100644 --- a/stdio-common/_itoa.c +++ b/stdio-common/_itoa.c @@ -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 @@ -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; } diff --git a/stdio-common/asprintf.c b/stdio-common/asprintf.c index 2c466d28d5..66e766ebfb 100644 --- a/stdio-common/asprintf.c +++ b/stdio-common/asprintf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991, 1995, 1997, 1998, 2002, 2004 +/* Copyright (C) 1991, 1995, 1997, 1998, 2002, 2004, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -20,7 +20,7 @@ #include #include -#include +#include #define vasprintf(s, f, a) _IO_vasprintf (s, f, a) #undef __asprintf @@ -28,7 +28,7 @@ allocated with malloc and stored in *STRING_PTR. */ /* VARARGS2 */ int -__asprintf (char **string_ptr, const char *format, ...) +___asprintf (char **string_ptr, const char *format, ...) { va_list arg; int done; @@ -39,5 +39,7 @@ __asprintf (char **string_ptr, const char *format, ...) return done; } -INTDEF(__asprintf) -weak_alias (__asprintf, asprintf) +INTDEF2(___asprintf, __asprintf) + +ldbl_strong_alias (___asprintf, __asprintf) +ldbl_weak_alias (___asprintf, asprintf) diff --git a/stdio-common/bits/printf-ldbl.h b/stdio-common/bits/printf-ldbl.h new file mode 100644 index 0000000000..cbdc3f1cbc --- /dev/null +++ b/stdio-common/bits/printf-ldbl.h @@ -0,0 +1,24 @@ +/* -mlong-double-64 compatibility mode for functions. + Copyright (C) 2006 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 + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef _PRINTF_H +# error "Never include directly; use instead." +#endif + +__LDBL_REDIR_DECL (printf_size) diff --git a/stdio-common/bug16.c b/stdio-common/bug16.c new file mode 100644 index 0000000000..84269f3b6d --- /dev/null +++ b/stdio-common/bug16.c @@ -0,0 +1,43 @@ +#include +#include + +struct +{ + long double val; + const char str[4][7]; +} tests[] = +{ + { 0x0.FFFFp+0L, { "0X1P+0", "0X2P-1", "0X4P-2", "0X8P-3" } }, + { 0x0.FFFFp+1L, { "0X1P+1", "0X2P+0", "0X4P-1", "0X8P-2" } }, + { 0x0.FFFFp+2L, { "0X1P+2", "0X2P+1", "0X4P+0", "0X8P-1" } }, + { 0x0.FFFFp+3L, { "0X1P+3", "0X2P+2", "0X4P+1", "0X8P+0" } } +}; + +static int +do_test (void) +{ + char buf[100]; + int ret = 0; + + for (size_t i = 0; i < sizeof (tests) / sizeof (tests[0]); ++i) + { + snprintf (buf, sizeof (buf), "%.0LA", tests[i].val); + + size_t j; + for (j = 0; j < 4; ++j) + if (strcmp (buf, tests[i].str[j]) == 0) + break; + + if (j == 4) + { + printf ("%zd: got \"%s\", expected \"%s\" or equivalent\n", + i, buf, tests[i].str[0]); + ret = 1; + } + } + + return ret; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/stdio-common/bug17.c b/stdio-common/bug17.c new file mode 100644 index 0000000000..2ef398674b --- /dev/null +++ b/stdio-common/bug17.c @@ -0,0 +1,31 @@ +#include +#include + +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" diff --git a/stdio-common/ctermid.c b/stdio-common/ctermid.c new file mode 100644 index 0000000000..e4d94eada2 --- /dev/null +++ b/stdio-common/ctermid.c @@ -0,0 +1,36 @@ +/* Copyright (C) 1991, 1995, 1996, 1997 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 + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include + + +/* Return the name of the controlling terminal. + If S is not NULL, the name is copied into it (it should be at + least L_ctermid bytes long), otherwise a static buffer is used. */ +char * +ctermid (s) + char *s; +{ + __set_errno (ENOSYS); + return NULL; +} + + +stub_warning (ctermid) +#include diff --git a/stdio-common/cuserid.c b/stdio-common/cuserid.c new file mode 100644 index 0000000000..826972f4de --- /dev/null +++ b/stdio-common/cuserid.c @@ -0,0 +1,35 @@ +/* Copyright (C) 1991, 1995, 1996, 1997 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 + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include + +/* Return the username of the caller. + If S is not NULL, it points to a buffer of at least L_cuserid bytes + into which the name is copied; otherwise, a static buffer is used. */ +char * +cuserid (s) + char *s; +{ + __set_errno (ENOSYS); + return NULL; +} + + +stub_warning (cuserid) +#include diff --git a/stdio-common/dprintf.c b/stdio-common/dprintf.c index b362e5fa71..6d00e10a63 100644 --- a/stdio-common/dprintf.c +++ b/stdio-common/dprintf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991,95,97,98,2002,2004 Free Software Foundation, Inc. +/* Copyright (C) 1991,95,97,98,2002,2004,2006 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 @@ -19,13 +19,13 @@ #include #include -#include +#include #define vdprintf(d, f, a) _IO_vdprintf (d, f, a) /* Write formatted output to D, according to the format string FORMAT. */ /* VARARGS2 */ int -dprintf (int d, const char *format, ...) +__dprintf (int d, const char *format, ...) { va_list arg; int done; @@ -36,4 +36,5 @@ dprintf (int d, const char *format, ...) return done; } -libc_hidden_def (dprintf) +ldbl_hidden_def (__dprintf, dprintf) +ldbl_strong_alias (__dprintf, dprintf) diff --git a/stdio-common/errlist.c b/stdio-common/errlist.c new file mode 100644 index 0000000000..6a834fc329 --- /dev/null +++ b/stdio-common/errlist.c @@ -0,0 +1,37 @@ +/* Copyright (C) 1991, 1994, 1997, 2005 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 + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + + +const char *const _sys_errlist[] = + { + "Error 0", /* 0 */ + "Argument out of function's domain", /* 1 = EDOM */ + "Result out of range", /* 2 = ERANGE */ + "Operation not implemented", /* 3 = ENOSYS */ + "Invalid argument", /* 4 = EINVAL */ + "Illegal seek", /* 5 = ESPIPE */ + "Bad file descriptor", /* 6 = EBADF */ + "Cannot allocate memory", /* 7 = ENOMEM */ + "Permission denied", /* 8 = EACCES */ + "Too many open files in system", /* 9 = ENFILE */ + "Too many open files", /* 10 = EMFILE */ + }; + +const int _sys_nerr = sizeof (_sys_errlist) / sizeof (_sys_errlist[0]); diff --git a/stdio-common/flockfile.c b/stdio-common/flockfile.c new file mode 100644 index 0000000000..571930ee54 --- /dev/null +++ b/stdio-common/flockfile.c @@ -0,0 +1,30 @@ +/* Lock I/O stream. Singlethreaded version. + Copyright (C) 1996, 1997, 2000, 2002 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 + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + +#undef _IO_flockfile + +void +__flockfile (FILE *stream) +{ + /* Do nothing. Using this version does not do any locking. */ +} +weak_alias (__flockfile, flockfile); +weak_alias (__flockfile, _IO_flockfile) diff --git a/stdio-common/fprintf.c b/stdio-common/fprintf.c index 0b99fc8994..689e80f466 100644 --- a/stdio-common/fprintf.c +++ b/stdio-common/fprintf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991,97,2002,2004 Free Software Foundation, Inc. +/* Copyright (C) 1991, 1997, 2002, 2004, 2006 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 @@ -18,12 +18,13 @@ #include #include +#include /* Write formatted output to STREAM from the format string FORMAT. */ /* VARARGS2 */ int -fprintf (FILE *stream, const char *format, ...) +__fprintf (FILE *stream, const char *format, ...) { va_list arg; int done; @@ -34,9 +35,10 @@ fprintf (FILE *stream, const char *format, ...) return done; } -libc_hidden_def (fprintf) +ldbl_hidden_def (__fprintf, fprintf) +ldbl_strong_alias (__fprintf, fprintf) /* We define the function with the real name here. But deep down in libio the original function _IO_fprintf is also needed. So make an alias. */ -weak_alias (fprintf, _IO_fprintf) +ldbl_weak_alias (__fprintf, _IO_fprintf) diff --git a/stdio-common/fscanf.c b/stdio-common/fscanf.c index 58a66eaf30..a6b60162cf 100644 --- a/stdio-common/fscanf.c +++ b/stdio-common/fscanf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991, 1997 Free Software Foundation, Inc. +/* Copyright (C) 1991, 1997, 2006 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 @@ -16,13 +16,14 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +#include #include #include /* Read formatted input from STREAM according to the format string FORMAT. */ /* VARARGS2 */ int -fscanf (FILE *stream, const char *format, ...) +__fscanf (FILE *stream, const char *format, ...) { va_list arg; int done; @@ -33,3 +34,4 @@ fscanf (FILE *stream, const char *format, ...) return done; } +ldbl_strong_alias (__fscanf, fscanf) diff --git a/stdio-common/ftrylockfile.c b/stdio-common/ftrylockfile.c new file mode 100644 index 0000000000..7bd3e9b53b --- /dev/null +++ b/stdio-common/ftrylockfile.c @@ -0,0 +1,31 @@ +/* Try locking I/O stream. Singlethreaded version. + Copyright (C) 1996, 1997, 2000, 2002 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 + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + +#undef _IO_ftrylockfile + +int +__ftrylockfile (FILE *stream) +{ + /* Do nothing. Using this version does not do any locking. */ + return 1; +} +weak_alias (__ftrylockfile, ftrylockfile); +weak_alias (__ftrylockfile, _IO_ftrylockfile) diff --git a/stdio-common/funlockfile.c b/stdio-common/funlockfile.c new file mode 100644 index 0000000000..902d29478d --- /dev/null +++ b/stdio-common/funlockfile.c @@ -0,0 +1,30 @@ +/* Unlock I/O stream. Singlethreaded version. + Copyright (C) 1996, 1997, 2000, 2002 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 + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + +#undef _IO_funlockfile + +void +__funlockfile (FILE *stream) +{ + /* Do nothing. Using this version does not do any locking. */ +} +weak_alias (__funlockfile, _IO_funlockfile) +weak_alias (__funlockfile, funlockfile); diff --git a/stdio-common/fxprintf.c b/stdio-common/fxprintf.c new file mode 100644 index 0000000000..f6ba0ca558 --- /dev/null +++ b/stdio-common/fxprintf.c @@ -0,0 +1,56 @@ +/* Copyright (C) 2005 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper . + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include +#include +#include +#include +#include +#include + + +int +__fxprintf (FILE *fp, const char *fmt, ...) +{ + if (fp == NULL) + fp = stderr; + + va_list ap; + va_start (ap, fmt); + + int res; + if (_IO_fwide (fp, 0) > 0) + { + size_t len = strlen (fmt) + 1; + wchar_t wfmt[len]; + for (size_t i = 0; i < len; ++i) + { + assert (isascii (fmt[i])); + wfmt[i] = fmt[i]; + } + res = __vfwprintf (fp, wfmt, ap); + } + else + res = INTUSE(_IO_vfprintf) (fp, fmt, ap); + + va_end (ap); + + return res; +} diff --git a/stdio-common/perror.c b/stdio-common/perror.c index f0751375b5..3ee61520f4 100644 --- a/stdio-common/perror.c +++ b/stdio-common/perror.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991-1993,1997,1998,2000-2004 Free Software Foundation, Inc. +/* Copyright (C) 1991-1993,1997,1998,2000-2005 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 @@ -37,10 +37,7 @@ perror_internal (FILE *fp, const char *s, int errnum) errstring = __strerror_r (errnum, buf, sizeof buf); - if (_IO_fwide (fp, 0) > 0) - (void) __fwprintf (fp, L"%s%s%s\n", s, colon, errstring); - else - (void) fprintf (fp, "%s%s%s\n", s, colon, errstring); + (void) __fxprintf (fp, "%s%s%s\n", s, colon, errstring); } diff --git a/stdio-common/printf-parsemb.c b/stdio-common/printf-parsemb.c index c55b97060c..2f21fc6365 100644 --- a/stdio-common/printf-parsemb.c +++ b/stdio-common/printf-parsemb.c @@ -1,5 +1,5 @@ /* Helper functions for parsing printf format strings. - Copyright (C) 1995-2000, 2002, 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 1995-2000,2002,2003,2004,2006 Free Software Foundation, Inc. This file is part of th GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -64,7 +64,8 @@ __find_specmb (const UCHAR_T *format, mbstate_t *ps) /* Remove any hints of a wrong encoding. */ ps->__count = 0; - if (! isascii (*format) && (len = __mbrlen (format, MB_CUR_MAX, ps)) > 0) + if (! isascii (*format) + && (len = __mbrlen ((const CHAR_T *) format, MB_CUR_MAX, ps)) > 0) format += len; else ++format; diff --git a/stdio-common/printf-prs.c b/stdio-common/printf-prs.c index f3b27d6712..015b01f1ed 100644 --- a/stdio-common/printf-prs.c +++ b/stdio-common/printf-prs.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991, 1992, 1995, 1996, 1999, 2000, 2002, 2003, 2004 +/* Copyright (C) 1991, 1992, 1995, 1996, 1999, 2000, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -67,15 +67,16 @@ parse_printf_format (fmt, n, argtypes) size_t max_ref_arg; /* Highest index used in a positional arg. */ struct printf_spec spec; mbstate_t mbstate; + const unsigned char *f = (const unsigned char *) fmt; nargs = 0; max_ref_arg = 0; /* Search for format specifications. */ - for (fmt = __find_specmb (fmt, &mbstate); *fmt != '\0'; fmt = spec.next_fmt) + for (f = __find_specmb (f, &mbstate); *f != '\0'; f = spec.next_fmt) { /* Parse this spec. */ - nargs += __parse_one_specmb (fmt, nargs, &spec, &max_ref_arg, &mbstate); + nargs += __parse_one_specmb (f, nargs, &spec, &max_ref_arg, &mbstate); /* If the width is determined by an argument this is an int. */ if (spec.width_arg != -1 && (size_t) spec.width_arg < n) diff --git a/stdio-common/printf.c b/stdio-common/printf.c index e28c5837e5..4c8f3a2a0c 100644 --- a/stdio-common/printf.c +++ b/stdio-common/printf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991, 1995, 1996, 1997, 2001, 2004 +/* Copyright (C) 1991, 1995, 1996, 1997, 2001, 2004, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -17,6 +17,7 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +#include #include #include @@ -25,7 +26,7 @@ /* Write formatted output to stdout from the format string FORMAT. */ /* VARARGS1 */ int -printf (const char *format, ...) +__printf (const char *format, ...) { va_list arg; int done; @@ -38,5 +39,6 @@ printf (const char *format, ...) } #undef _IO_printf +ldbl_strong_alias (__printf, printf); /* This is for libg++. */ -strong_alias (printf, _IO_printf); +ldbl_strong_alias (__printf, _IO_printf); diff --git a/stdio-common/printf.h b/stdio-common/printf.h index c16569b59b..360cdcce1d 100644 --- a/stdio-common/printf.h +++ b/stdio-common/printf.h @@ -1,4 +1,5 @@ -/* Copyright (C) 1991-1993,1995-1999,2000,2001 Free Software Foundation, Inc. +/* Copyright (C) 1991-1993,1995-1999,2000,2001,2006 + 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 @@ -139,6 +140,9 @@ extern int printf_size_info (__const struct printf_info *__restrict __info, size_t __n, int *__restrict __argtypes) __THROW; +#ifdef __LDBL_COMPAT +# include +#endif __END_DECLS diff --git a/stdio-common/printf_fp.c b/stdio-common/printf_fp.c index ed225e05a6..c7a381a69d 100644 --- a/stdio-common/printf_fp.c +++ b/stdio-common/printf_fp.c @@ -1,5 +1,5 @@ /* Floating point output for `printf'. - Copyright (C) 1995-1999,2000,2001,2002,2003 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 , 1995. @@ -71,7 +71,11 @@ { \ register const int outc = (ch); \ if (putc (outc, fp) == EOF) \ - return -1; \ + { \ + if (buffer_malloced) \ + free (wbuffer); \ + return -1; \ + } \ ++done; \ } while (0) @@ -82,7 +86,11 @@ if (len > 20) \ { \ if (PUT (fp, wide ? (const char *) wptr : ptr, outlen) != outlen) \ - return -1; \ + { \ + if (buffer_malloced) \ + free (wbuffer); \ + return -1; \ + } \ ptr += outlen; \ done += outlen; \ } \ @@ -101,7 +109,11 @@ do \ { \ if (PAD (fp, ch, len) != len) \ - return -1; \ + { \ + if (buffer_malloced) \ + free (wbuffer); \ + return -1; \ + } \ done += len; \ } \ while (0) @@ -138,9 +150,9 @@ static wchar_t *group_number (wchar_t *buf, wchar_t *bufend, int -__printf_fp (FILE *fp, - const struct printf_info *info, - const void *const *args) +___printf_fp (FILE *fp, + const struct printf_info *info, + const void *const *args) { /* The floating-point value to output. */ union @@ -199,6 +211,11 @@ __printf_fp (FILE *fp, /* Nonzero if this is output on a wide character stream. */ int wide = info->wide; + /* Buffer in which we produce the output. */ + wchar_t *wbuffer = NULL; + /* Flag whether wbuffer is malloc'ed or not. */ + int buffer_malloced = 0; + auto wchar_t hack_digit (void); wchar_t hack_digit (void) @@ -775,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 && @@ -789,17 +806,18 @@ __printf_fp (FILE *fp, { int width = info->width; - wchar_t *wbuffer, *wstartp, *wcp; - int buffer_malloced; + wchar_t *wstartp, *wcp; 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; @@ -809,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; @@ -906,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; @@ -917,7 +937,7 @@ __printf_fp (FILE *fp, { ++fracdig_max; if (fracdig_min > 0) - ++fracdig_min; + ++added_zeros; } } @@ -954,11 +974,23 @@ __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, + 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) @@ -980,6 +1012,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) { @@ -1025,7 +1063,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; @@ -1043,26 +1081,46 @@ __printf_fp (FILE *fp, /* Write the exponent if it is needed. */ if (type != 'f') { - *wcp++ = (wchar_t) type; - *wcp++ = expsign ? L'-' : L'+'; + 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 + { + *wcp++ = (wchar_t) type; + *wcp++ = expsign ? L'-' : L'+'; - /* Find the magnitude of the exponent. */ - expscale = 10; - while (expscale <= exponent) - expscale *= 10; + /* 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; + 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 @@ -1108,8 +1166,12 @@ __printf_fp (FILE *fp, buffer = (char *) malloc (2 + chars_needed + decimal_len + ngroups * thousands_sep_len); if (buffer == NULL) - /* Signal an error to the caller. */ - return -1; + { + /* Signal an error to the caller. */ + if (buffer_malloced) + free (wbuffer); + return -1; + } } else buffer = (char *) alloca (2 + chars_needed + decimal_len @@ -1153,7 +1215,8 @@ __printf_fp (FILE *fp, } return done; } -libc_hidden_def (__printf_fp) +ldbl_hidden_def (___printf_fp, __printf_fp) +ldbl_strong_alias (___printf_fp, __printf_fp) /* Return the number of extra grouping characters that will be inserted into a number with INTDIG_MAX integer digits. */ diff --git a/stdio-common/printf_fphex.c b/stdio-common/printf_fphex.c new file mode 100644 index 0000000000..4e30d94c61 --- /dev/null +++ b/stdio-common/printf_fphex.c @@ -0,0 +1,493 @@ +/* Print floating point number in hexadecimal notation according to ISO C99. + Copyright (C) 1997-2002,2004,2006 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "_itoa.h" +#include "_itowa.h" +#include + +/* #define NDEBUG 1*/ /* Undefine this for debugging assertions. */ +#include + +/* This defines make it possible to use the same code for GNU C library and + the GNU I/O library. */ +#ifdef USE_IN_LIBIO +# include +# define PUT(f, s, n) _IO_sputn (f, s, n) +# define PAD(f, c, n) (wide ? _IO_wpadn (f, c, n) : INTUSE(_IO_padn) (f, c, n)) +/* We use this file GNU C library and GNU I/O library. So make + names equal. */ +# undef putc +# define putc(c, f) (wide \ + ? (int)_IO_putwc_unlocked (c, f) : _IO_putc_unlocked (c, f)) +# define size_t _IO_size_t +# define FILE _IO_FILE +#else /* ! USE_IN_LIBIO */ +# define PUT(f, s, n) fwrite (s, 1, n, f) +# define PAD(f, c, n) __printf_pad (f, c, n) +ssize_t __printf_pad (FILE *, char pad, int n) __THROW; /* In vfprintf.c. */ +#endif /* USE_IN_LIBIO */ + +/* Macros for doing the actual output. */ + +#define outchar(ch) \ + do \ + { \ + register const int outc = (ch); \ + if (putc (outc, fp) == EOF) \ + return -1; \ + ++done; \ + } while (0) + +#define PRINT(ptr, wptr, len) \ + do \ + { \ + register size_t outlen = (len); \ + if (wide) \ + while (outlen-- > 0) \ + outchar (*wptr++); \ + else \ + while (outlen-- > 0) \ + outchar (*ptr++); \ + } while (0) + +#define PADN(ch, len) \ + do \ + { \ + if (PAD (fp, ch, len) != len) \ + return -1; \ + done += len; \ + } \ + while (0) + +#ifndef MIN +# define MIN(a,b) ((a)<(b)?(a):(b)) +#endif + + +int +__printf_fphex (FILE *fp, + const struct printf_info *info, + const void *const *args) +{ + /* The floating-point value to output. */ + union + { + union ieee754_double dbl; + union ieee854_long_double ldbl; + } + fpnum; + + /* Locale-dependent representation of decimal point. */ + const char *decimal; + wchar_t decimalwc; + + /* "NaN" or "Inf" for the special cases. */ + const char *special = NULL; + const wchar_t *wspecial = NULL; + + /* Buffer for the generated number string for the mantissa. The + maximal size for the mantissa is 128 bits. */ + char numbuf[32]; + char *numstr; + char *numend; + wchar_t wnumbuf[32]; + wchar_t *wnumstr; + wchar_t *wnumend; + int negative; + + /* The maximal exponent of two in decimal notation has 5 digits. */ + char expbuf[5]; + char *expstr; + wchar_t wexpbuf[5]; + wchar_t *wexpstr; + int expnegative; + int exponent; + + /* Non-zero is mantissa is zero. */ + int zero_mantissa; + + /* The leading digit before the decimal point. */ + char leading; + + /* Precision. */ + int precision = info->prec; + + /* Width. */ + int width = info->width; + + /* Number of characters written. */ + int done = 0; + + /* Nonzero if this is output on a wide character stream. */ + int wide = info->wide; + + + /* Figure out the decimal point character. */ + if (info->extra == 0) + { + decimal = _NL_CURRENT (LC_NUMERIC, DECIMAL_POINT); + decimalwc = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_DECIMAL_POINT_WC); + } + else + { + decimal = _NL_CURRENT (LC_MONETARY, MON_DECIMAL_POINT); + decimalwc = _NL_CURRENT_WORD (LC_MONETARY, + _NL_MONETARY_DECIMAL_POINT_WC); + } + /* The decimal point character must never be zero. */ + assert (*decimal != '\0' && decimalwc != L'\0'); + + + /* Fetch the argument value. */ +#ifndef __NO_LONG_DOUBLE_MATH + if (info->is_long_double && sizeof (long double) > sizeof (double)) + { + fpnum.ldbl.d = *(const long double *) args[0]; + + /* Check for special values: not a number or infinity. */ + if (__isnanl (fpnum.ldbl.d)) + { + if (isupper (info->spec)) + { + special = "NAN"; + wspecial = L"NAN"; + } + else + { + special = "nan"; + wspecial = L"nan"; + } + negative = 0; + } + else + { + if (__isinfl (fpnum.ldbl.d)) + { + if (isupper (info->spec)) + { + special = "INF"; + wspecial = L"INF"; + } + else + { + special = "inf"; + wspecial = L"inf"; + } + } + + negative = signbit (fpnum.ldbl.d); + } + } + else +#endif /* no long double */ + { + fpnum.dbl.d = *(const double *) args[0]; + + /* Check for special values: not a number or infinity. */ + if (__isnan (fpnum.dbl.d)) + { + if (isupper (info->spec)) + { + special = "NAN"; + wspecial = L"NAN"; + } + else + { + special = "nan"; + wspecial = L"nan"; + } + negative = 0; + } + else + { + if (__isinf (fpnum.dbl.d)) + { + if (isupper (info->spec)) + { + special = "INF"; + wspecial = L"INF"; + } + else + { + special = "inf"; + wspecial = L"inf"; + } + } + + negative = signbit (fpnum.dbl.d); + } + } + + if (special) + { + int width = info->width; + + if (negative || info->showsign || info->space) + --width; + width -= 3; + + if (!info->left && width > 0) + PADN (' ', width); + + if (negative) + outchar ('-'); + else if (info->showsign) + outchar ('+'); + else if (info->space) + outchar (' '); + + PRINT (special, wspecial, 3); + + if (info->left && width > 0) + PADN (' ', width); + + return done; + } + + if (info->is_long_double == 0 || sizeof (double) == sizeof (long double)) + { + /* We have 52 bits of mantissa plus one implicit digit. Since + 52 bits are representable without rest using hexadecimal + digits we use only the implicit digits for the number before + the decimal point. */ + unsigned long long int num; + + num = (((unsigned long long int) fpnum.dbl.ieee.mantissa0) << 32 + | fpnum.dbl.ieee.mantissa1); + + zero_mantissa = num == 0; + + if (sizeof (unsigned long int) > 6) + { + wnumstr = _itowa_word (num, wnumbuf + (sizeof wnumbuf) / sizeof (wchar_t), 16, + info->spec == 'A'); + numstr = _itoa_word (num, numbuf + sizeof numbuf, 16, + info->spec == 'A'); + } + else + { + wnumstr = _itowa (num, wnumbuf + sizeof wnumbuf / sizeof (wchar_t), 16, + info->spec == 'A'); + numstr = _itoa (num, numbuf + sizeof numbuf, 16, + info->spec == 'A'); + } + + /* Fill with zeroes. */ + while (wnumstr > wnumbuf + (sizeof wnumbuf - 52) / sizeof (wchar_t)) + { + *--wnumstr = L'0'; + *--numstr = '0'; + } + + leading = fpnum.dbl.ieee.exponent == 0 ? '0' : '1'; + + exponent = fpnum.dbl.ieee.exponent; + + if (exponent == 0) + { + if (zero_mantissa) + expnegative = 0; + else + { + /* This is a denormalized number. */ + expnegative = 1; + exponent = IEEE754_DOUBLE_BIAS - 1; + } + } + else if (exponent >= IEEE754_DOUBLE_BIAS) + { + expnegative = 0; + exponent -= IEEE754_DOUBLE_BIAS; + } + else + { + expnegative = 1; + exponent = -(exponent - IEEE754_DOUBLE_BIAS); + } + } +#ifdef PRINT_FPHEX_LONG_DOUBLE + else + PRINT_FPHEX_LONG_DOUBLE; +#endif + + /* Look for trailing zeroes. */ + if (! zero_mantissa) + { + wnumend = &wnumbuf[sizeof wnumbuf / sizeof wnumbuf[0]]; + numend = &numbuf[sizeof numbuf / sizeof numbuf[0]]; + while (wnumend[-1] == L'0') + { + --wnumend; + --numend; + } + + if (precision == -1) + precision = numend - numstr; + else if (precision < numend - numstr + && (numstr[precision] > '8' + || (('A' < '0' || 'a' < '0') + && numstr[precision] < '0') + || (numstr[precision] == '8' + && (precision + 1 < numend - numstr + /* Round to even. */ + || (precision > 0 + && ((numstr[precision - 1] & 1) + ^ (isdigit (numstr[precision - 1]) == 0))) + || (precision == 0 + && ((leading & 1) + ^ (isdigit (leading) == 0))))))) + { + /* Round up. */ + int cnt = precision; + while (--cnt >= 0) + { + char ch = numstr[cnt]; + /* We assume that the digits and the letters are ordered + like in ASCII. This is true for the rest of GNU, too. */ + if (ch == '9') + { + wnumstr[cnt] = (wchar_t) info->spec; + numstr[cnt] = info->spec; /* This is tricky, + think about it! */ + break; + } + else if (tolower (ch) < 'f') + { + ++numstr[cnt]; + ++wnumstr[cnt]; + break; + } + else + { + numstr[cnt] = '0'; + wnumstr[cnt] = L'0'; + } + } + if (cnt < 0) + { + /* The mantissa so far was fff...f Now increment the + leading digit. Here it is again possible that we + get an overflow. */ + if (leading == '9') + leading = info->spec; + else if (tolower (leading) < 'f') + ++leading; + else + { + leading = '1'; + if (expnegative) + { + exponent -= 4; + if (exponent <= 0) + { + exponent = -exponent; + expnegative = 0; + } + } + else + exponent += 4; + } + } + } + } + else + { + if (precision == -1) + precision = 0; + numend = numstr; + wnumend = wnumstr; + } + + /* Now we can compute the exponent string. */ + expstr = _itoa_word (exponent, expbuf + sizeof expbuf, 10, 0); + wexpstr = _itowa_word (exponent, + wexpbuf + sizeof wexpbuf / sizeof (wchar_t), 10, 0); + + /* Now we have all information to compute the size. */ + width -= ((negative || info->showsign || info->space) + /* Sign. */ + + 2 + 1 + 0 + precision + 1 + 1 + /* 0x h . hhh P ExpoSign. */ + + ((expbuf + sizeof expbuf) - expstr)); + /* Exponent. */ + + /* Count the decimal point. + A special case when the mantissa or the precision is zero and the `#' + is not given. In this case we must not print the decimal point. */ + if (precision > 0 || info->alt) + width -= wide ? 1 : strlen (decimal); + + if (!info->left && info->pad != '0' && width > 0) + PADN (' ', width); + + if (negative) + outchar ('-'); + else if (info->showsign) + outchar ('+'); + else if (info->space) + outchar (' '); + + outchar ('0'); + if ('X' - 'A' == 'x' - 'a') + outchar (info->spec + ('x' - 'a')); + else + outchar (info->spec == 'A' ? 'X' : 'x'); + + if (!info->left && info->pad == '0' && width > 0) + PADN ('0', width); + + outchar (leading); + + if (precision > 0 || info->alt) + { + const wchar_t *wtmp = &decimalwc; + PRINT (decimal, wtmp, wide ? 1 : strlen (decimal)); + } + + if (precision > 0) + { + ssize_t tofill = precision - (numend - numstr); + PRINT (numstr, wnumstr, MIN (numend - numstr, precision)); + if (tofill > 0) + PADN ('0', tofill); + } + + if ('P' - 'A' == 'p' - 'a') + outchar (info->spec + ('p' - 'a')); + else + outchar (info->spec == 'A' ? 'P' : 'p'); + + outchar (expnegative ? '-' : '+'); + + PRINT (expstr, wexpstr, (expbuf + sizeof expbuf) - expstr); + + if (info->left && info->pad != '0' && width > 0) + PADN (info->pad, width); + + return done; +} diff --git a/stdio-common/printf_size.c b/stdio-common/printf_size.c index 32f262ead0..957de2f571 100644 --- a/stdio-common/printf_size.c +++ b/stdio-common/printf_size.c @@ -1,5 +1,5 @@ /* Print size value using units for orders of magnitude. - Copyright (C) 1997-2002, 2004 Free Software Foundation, Inc. + Copyright (C) 1997-2002, 2004, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1997. Based on a proposal by Larry McVoy . @@ -86,7 +86,8 @@ extern int __printf_fp (FILE *fp, const struct printf_info *info, int -printf_size (FILE *fp, const struct printf_info *info, const void *const *args) +__printf_size (FILE *fp, const struct printf_info *info, + const void *const *args) { /* Units for the both formats. */ #define BINARY_UNITS " kmgtpezy" @@ -233,6 +234,7 @@ printf_size (FILE *fp, const struct printf_info *info, const void *const *args) return done; } +ldbl_strong_alias (__printf_size, printf_size); /* This is the function used by `vfprintf' to determine number and type of the arguments. */ diff --git a/stdio-common/psignal.c b/stdio-common/psignal.c index 2e6588c692..98049a5871 100644 --- a/stdio-common/psignal.c +++ b/stdio-common/psignal.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991, 1992, 1995, 1996, 1997, 2001, 2002, 2004 +/* Copyright (C) 1991, 1992, 1995, 1996, 1997, 2001, 2002, 2004, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -24,10 +24,6 @@ #include -#ifndef HAVE_GNU_LD -#define _sys_siglist sys_siglist -#endif - /* Defined in sys_siglist.c. */ extern const char *const _sys_siglist[]; extern const char *const _sys_siglist_internal[] attribute_hidden; @@ -47,29 +43,16 @@ psignal (int sig, const char *s) colon = ": "; if (sig >= 0 && sig < NSIG && (desc = INTUSE(_sys_siglist)[sig]) != NULL) - { - if (_IO_fwide (stderr, 0) > 0) - (void) __fwprintf (stderr, L"%s%s%s\n", s, colon, _(desc)); - else - (void) fprintf (stderr, "%s%s%s\n", s, colon, _(desc)); - } + (void) __fxprintf (NULL, "%s%s%s\n", s, colon, _(desc)); else { char *buf; if (__asprintf (&buf, _("%s%sUnknown signal %d\n"), s, colon, sig) < 0) - { - if (_IO_fwide (stderr, 0) > 0) - (void) __fwprintf (stderr, L"%s%s%s\n", s, colon, _("Unknown signal")); - else - (void) fprintf (stderr, "%s%s%s\n", s, colon, _("Unknown signal")); - } + (void) __fxprintf (NULL, "%s%s%s\n", s, colon, _("Unknown signal")); else { - if (_IO_fwide (stderr, 0) > 0) - (void) __fwprintf (stderr, L"%s", buf); - else - (void) fputs (buf, stderr); + (void) __fxprintf (NULL, "%s", buf); free (buf); } diff --git a/stdio-common/remove.c b/stdio-common/remove.c new file mode 100644 index 0000000000..5dc0e9edf0 --- /dev/null +++ b/stdio-common/remove.c @@ -0,0 +1,33 @@ +/* ANSI C `remove' function to delete a file or directory. Stub version. + Copyright (C) 1995,96,97,2002 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 + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include + +int +remove (file) + const char *file; +{ + __set_errno (ENOSYS); + return -1; +} +libc_hidden_def (remove) + +stub_warning (remove) +#include diff --git a/stdio-common/rename.c b/stdio-common/rename.c new file mode 100644 index 0000000000..b7d8392179 --- /dev/null +++ b/stdio-common/rename.c @@ -0,0 +1,41 @@ +/* Copyright (C) 1991, 1995, 1996, 1997 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 + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include + + +/* Rename the file OLD to NEW. */ +int +rename (old, new) + const char *old; + const char *new; +{ + if (old == NULL || new == NULL) + { + __set_errno (EINVAL); + return -1; + } + + __set_errno (ENOSYS); + return -1; +} + + +stub_warning (rename) +#include diff --git a/stdio-common/renameat.c b/stdio-common/renameat.c new file mode 100644 index 0000000000..1261da88a4 --- /dev/null +++ b/stdio-common/renameat.c @@ -0,0 +1,50 @@ +/* Copyright (C) 2005, 2006 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 + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include +#include + + +/* Rename the file OLD relative to OLDFD to NEW relative to NEWFD. */ +int +renameat (oldfd, old, newfd, new) + int oldfd; + const char *old; + int newfd; + const char *new; +{ + if ((oldfd < 0 && oldfd != AT_FDCWD) || (newfd < 0 && newfd != AT_FDCWD)) + { + __set_errno (EBADF); + return -1; + } + + if (old == NULL || new == NULL) + { + __set_errno (EINVAL); + return -1; + } + + __set_errno (ENOSYS); + return -1; +} + + +stub_warning (renameat) +#include diff --git a/stdio-common/scanf.c b/stdio-common/scanf.c index 62c9959651..d4a4daf726 100644 --- a/stdio-common/scanf.c +++ b/stdio-common/scanf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991, 1995, 1996, 1997, 2002, 2004 +/* Copyright (C) 1991, 1995, 1996, 1997, 2002, 2004, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -26,7 +26,7 @@ /* Read formatted input from stdin according to the format string FORMAT. */ /* VARARGS1 */ int -scanf (const char *format, ...) +__scanf (const char *format, ...) { va_list arg; int done; @@ -37,3 +37,4 @@ scanf (const char *format, ...) return done; } +ldbl_strong_alias (__scanf, scanf) diff --git a/stdio-common/siglist.c b/stdio-common/siglist.c new file mode 100644 index 0000000000..80847cd491 --- /dev/null +++ b/stdio-common/siglist.c @@ -0,0 +1,38 @@ +/* Define list of all signal numbers and their names. + Copyright (C) 1997, 1998, 1999, 2002 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 + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include +#include + +const char *const _sys_siglist[NSIG] = +{ +#define init_sig(sig, abbrev, desc) [sig] = desc, +#include +#undef init_sig +}; +strong_alias (_sys_siglist, _sys_siglist_internal) + + +const char *const _sys_sigabbrev[NSIG] = +{ +#define init_sig(sig, abbrev, desc) [sig] = abbrev, +#include +#undef init_sig +}; diff --git a/stdio-common/snprintf.c b/stdio-common/snprintf.c index ce392f0096..00d2082350 100644 --- a/stdio-common/snprintf.c +++ b/stdio-common/snprintf.c @@ -1,4 +1,5 @@ -/* Copyright (C) 1991, 1995, 1997, 1998, 2004 Free Software Foundation, Inc. +/* Copyright (C) 1991, 1995, 1997, 1998, 2004, 2006 + 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 @@ -18,8 +19,7 @@ #include #include - -#include +#include #define __vsnprintf(s, l, f, a) _IO_vsnprintf (s, l, f, a) /* Write formatted output into S, according to the format @@ -37,4 +37,4 @@ __snprintf (char *s, size_t maxlen, const char *format, ...) return done; } -weak_alias (__snprintf, snprintf) +ldbl_weak_alias (__snprintf, snprintf) diff --git a/stdio-common/sprintf.c b/stdio-common/sprintf.c index 249fcb0dde..7f564d5635 100644 --- a/stdio-common/sprintf.c +++ b/stdio-common/sprintf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991, 1995, 1997, 1998, 2002, 2004 +/* Copyright (C) 1991, 1995, 1997, 1998, 2002, 2004, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -19,13 +19,13 @@ #include #include -#include +#include #define vsprintf(s, f, a) INTUSE(_IO_vsprintf) (s, f, a) /* Write formatted output into S, according to the format string FORMAT. */ /* VARARGS2 */ int -sprintf (char *s, const char *format, ...) +__sprintf (char *s, const char *format, ...) { va_list arg; int done; @@ -36,6 +36,6 @@ sprintf (char *s, const char *format, ...) return done; } -libc_hidden_def (sprintf) - -strong_alias(sprintf, _IO_sprintf) +ldbl_hidden_def (__sprintf, sprintf) +ldbl_strong_alias (__sprintf, sprintf) +ldbl_strong_alias (__sprintf, _IO_sprintf) diff --git a/stdio-common/sscanf.c b/stdio-common/sscanf.c index b36976710b..384a6977dc 100644 --- a/stdio-common/sscanf.c +++ b/stdio-common/sscanf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991, 1995, 1996, 1998, 2002, 2003, 2004 +/* Copyright (C) 1991, 1995, 1996, 1998, 2002, 2003, 2004, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -19,13 +19,13 @@ #include #include -#include +#include #define __vsscanf(s, f, a) _IO_vsscanf (s, f, a) /* Read formatted input from S, according to the format string FORMAT. */ /* VARARGS2 */ int -sscanf (const char *s, const char *format, ...) +__sscanf (const char *s, const char *format, ...) { va_list arg; int done; @@ -36,8 +36,8 @@ sscanf (const char *s, const char *format, ...) return done; } -libc_hidden_def (sscanf) - +ldbl_hidden_def (__sscanf, sscanf) +ldbl_strong_alias (__sscanf, sscanf) #undef _IO_sscanf /* This is for libg++. */ -strong_alias (sscanf, _IO_sscanf) +ldbl_strong_alias (__sscanf, _IO_sscanf) diff --git a/stdio-common/tempname.c b/stdio-common/tempname.c new file mode 100644 index 0000000000..60c94d6409 --- /dev/null +++ b/stdio-common/tempname.c @@ -0,0 +1,59 @@ +/* Copyright (C) 1991, 92, 93, 95-98, 99 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 + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#define __need_size_t +#include +#include +#include + +/* Perform the "SVID path search malarkey" on DIR and PFX. Write a + template suitable for use in __gen_tempname into TMPL, bounded + by TMPL_LEN. */ +int +__path_search (tmpl, tmpl_len, dir, pfx, try_tmpdir) + char *tmpl; + size_t tmpl_len; + const char *dir; + const char *pfx; + int try_tmpdir; +{ + __set_errno (ENOSYS); + return -1; +} +stub_warning (__path_search) + +/* Generate a (hopefully) unique temporary filename + in DIR (if applicable), using template TMPL. + KIND determines what to do with that name. It may be one of: + __GT_FILE: create a file and return a read-write fd. + __GT_BIGFILE: same, but use open64() (or equivalent). + __GT_DIR: create a directory. + __GT_NOCREATE: just find a name not currently in use. + */ + +int +__gen_tempname (tmpl, kind) + char *tmpl; + int kind; +{ + __set_errno (ENOSYS); + return -1; +} + +stub_warning (__gen_tempname) +#include diff --git a/stdio-common/test-vfprintf.c b/stdio-common/test-vfprintf.c index a683eac779..342ac471da 100644 --- a/stdio-common/test-vfprintf.c +++ b/stdio-common/test-vfprintf.c @@ -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 , 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, (