diff options
46 files changed, 1677 insertions, 67 deletions
@@ -1,7 +1,129 @@ +2007-09-17 Jakub Jelinek <jakub@redhat.com> + + * include/stdio.h (__isoc99_fscanf, __isoc99_scanf, + __isoc99_sscanf, __isoc99_vscanf): New prototypes. + (__isoc99_vsscanf, __isoc99_vfscanf): New prototypes, add + libc_hidden_proto. + * include/wchar.h (__isoc99_fwscanf, __isoc99_wscanf, + __isoc99_swscanf, __isoc99_vwscanf): New prototypes. + (__isoc99_vswscanf, __isoc99_vfwscanf): New prototypes, + add libc_hidden_proto. + * libio/stdio.h (fscanf, scanf, sscanf, vfscanf, vscanf, + vsscanf): Redirect to __isoc99_* if strict ISO C99 or POSIX + conformance requested. + * wcsmbs/wchar.h (fwscanf, wscanf, swscanf, vfwscanf, vwscanf, + vswscanf): Redirect to __isoc99_* if strict ISO C99 or POSIX + conformance requested. + * libio/bits/stdio-ldbl.h (fscanf, scanf, sscanf, vfscanf, vscanf, + vsscanf): Redirect to __nldbl___isoc99_* if strict ISO C99 or POSIX + conformance requested. + * wcsmbs/bits/wchar-ldbl.h (fwscanf, wscanf, swscanf, vfwscanf, + vwscanf, vswscanf): Redirect to __nldbl___isoc99_* if strict + ISO C99 or POSIX conformance requested. + * stdio-common/Versions (libc): Export __isoc99_scanf@@GLIBC_2.7, + __isoc99_vscanf@@GLIBC_2.7, __isoc99_fscanf@@GLIBC_2.7, + __isoc99_vfscanf@@GLIBC_2.7, __isoc99_sscanf@@GLIBC_2.7 + and __isoc99_vsscanf@@GLIBC_2.7. + * stdio-common/Makefile (routines): Add isoc99_scanf, isoc99_vscanf, + isoc99_fscanf, isoc99_vfscanf, isoc99_sscanf and isoc99_vsscanf. + (tests): Add scanf14. + (CFLAGS-vfprintf.c, CFLAGS-fprintf.c, CFLAGS-printf.c, + CFLAGS-vfwprintf.c, CFLAGS-vfscanf.c, CFLAGS-vfwscanf.c, + CFLAGS-fscanf.c, CFLAGS-scanf.c, CFLAGS-isoc99_vfscanf.c, + CFLAGS-isoc99_vscanf.c, CFLAGS-isoc99_fscanf.c, + CFLAGS-isoc99_scanf.c): Add $(exceptions). + (CFLAGS-scanf15.c): Add various -I paths to prevent the compiler + from using internal headers. + * wcsmbs/Versions (libc): Export __isoc99_wscanf@@GLIBC_2.7, + __isoc99_vwscanf@@GLIBC_2.7, __isoc99_fwscanf@@GLIBC_2.7, + __isoc99_vfwscanf@@GLIBC_2.7, __isoc99_swscanf@@GLIBC_2.7 + and __isoc99_vswscanf@@GLIBC_2.7. + * wcsmbs/Makefile (routines): Add isoc99_wscanf, isoc99_vwscanf, + isoc99_fwscanf, isoc99_vfwscanf, isoc99_swscanf and isoc99_vswscanf. + (CFLAGS-isoc99_wscanf.c, CFLAGS-isoc99_fwscanf.c, + CFLAGS-isoc99_vwscanf.c, CFLAGS-isoc99_vfwscanf.c): Add $(exceptions). + (CPPFLAGS): Add -D_IO_MTSAFE_IO if needed. + * stdio-common/isoc99_scanf.c: New file. + * stdio-common/isoc99_vsscanf.c: New file. + * stdio-common/isoc99_vscanf.c: New file. + * stdio-common/isoc99_vfscanf.c: New file. + * stdio-common/isoc99_fscanf.c: New file. + * stdio-common/isoc99_sscanf.c: New file. + * wcsmbs/isoc99_fwscanf.c: New file. + * wcsmbs/isoc99_vswscanf.c: New file. + * wcsmbs/isoc99_swscanf.c: New file. + * wcsmbs/isoc99_wscanf.c: New file. + * wcsmbs/isoc99_vwscanf.c: New file. + * wcsmbs/isoc99_vfwscanf.c: New file. + * libio/libio.h (_IO_FLAGS2_SCANF_STD): Define. + * libio/libioP.h (_IO_acquire_lock_clear_flags2_fct): Also + clear _IO_FLAGS2_SCANF_STD bit from _flags2. + * stdio-common/vfscanf.c (_IO_vfscanf_internal): Don't + handle %as, %aS and %a[ if _IO_FLAGS2_SCANF_STD is set in _flags2. + * stdio-common/scanf14.c: New test. + * stdio-common/scanf15.c: New test. + * sysdeps/ieee754/ldbl-opt/Makefile (libnldbl-calls): Add + isoc99_scanf, isoc99_fscanf, isoc99_sscanf, + isoc99_vscanf, isoc99_vfscanf, isoc99_vsscanf, + isoc99_wscanf, isoc99_fwscanf, isoc99_swscanf, + isoc99_vwscanf, isoc99_vfwscanf and isoc99_vswscanf. + * sysdeps/ieee754/ldbl-opt/Versions (libc): Export + __nldbl___isoc99_scanf@@GLIBC_2.7, + __nldbl___isoc99_fscanf@@GLIBC_2.7, + __nldbl___isoc99_sscanf@@GLIBC_2.7, + __nldbl___isoc99_vscanf@@GLIBC_2.7, + __nldbl___isoc99_vfscanf@@GLIBC_2.7, + __nldbl___isoc99_vsscanf@@GLIBC_2.7, + __nldbl___isoc99_wscanf@@GLIBC_2.7, + __nldbl___isoc99_fwscanf@@GLIBC_2.7, + __nldbl___isoc99_swscanf@@GLIBC_2.7, + __nldbl___isoc99_vwscanf@@GLIBC_2.7, + __nldbl___isoc99_vfwscanf@@GLIBC_2.7 + and __nldbl___isoc99_vswscanf@@GLIBC_2.7. + * sysdeps/ieee754/ldbl-opt/nldbl-compat.h (__isoc99_scanf, + __isoc99_fscanf, __isoc99_sscanf, __isoc99_vscanf, + __isoc99_vfscanf, __isoc99_vsscanf, __isoc99_wscanf, + __isoc99_fwscanf, __isoc99_swscanf, __isoc99_vwscanf, + __isoc99_vfwscanf, __isoc99_vswscanf): Add NLDBL_DECL. + * sysdeps/ieee754/ldbl-opt/nldbl-compat.c + (__nldbl___isoc99_scanf, __nldbl___isoc99_fscanf, + __nldbl___isoc99_sscanf, __nldbl___isoc99_vscanf, + __nldbl___isoc99_vfscanf, __nldbl___isoc99_vsscanf, + __nldbl___isoc99_wscanf, __nldbl___isoc99_fwscanf, + __nldbl___isoc99_swscanf, __nldbl___isoc99_vwscanf, + __nldbl___isoc99_vfwscanf, __nldbl___isoc99_vswscanf): New + functions. + * sysdeps/ieee754/ldbl-opt/nldbl-isoc99_vfscanf.c: New file. + * sysdeps/ieee754/ldbl-opt/nldbl-isoc99_swscanf.c: New file. + * sysdeps/ieee754/ldbl-opt/nldbl-isoc99_vwscanf.c: New file. + * sysdeps/ieee754/ldbl-opt/nldbl-isoc99_wscanf.c: New file. + * sysdeps/ieee754/ldbl-opt/nldbl-isoc99_scanf.c: New file. + * sysdeps/ieee754/ldbl-opt/nldbl-isoc99_sscanf.c: New file. + * sysdeps/ieee754/ldbl-opt/nldbl-isoc99_vsscanf.c: New file. + * sysdeps/ieee754/ldbl-opt/nldbl-isoc99_fwscanf.c: New file. + * sysdeps/ieee754/ldbl-opt/nldbl-isoc99_vfwscanf.c: New file. + * sysdeps/ieee754/ldbl-opt/nldbl-isoc99_vswscanf.c: New file. + * sysdeps/ieee754/ldbl-opt/nldbl-isoc99_vscanf.c: New file. + * sysdeps/ieee754/ldbl-opt/nldbl-isoc99_fscanf.c: New file. + + * stdio-common/Makefile (tests): Add scanf13. + (scanf13-ENV): New. + * stdio-common/vfscanf.c (_IO_vfscanf_internal): Handle + m modifier followed by l. + (STRING_ARG): Add width argument. + (_IO_vfscanf_internal) <case L_('c')>: Handle %mc. + <case L_('C')>: Handle %mlc and %mC. + <case L_('s'), case L_('S'), case L_('[')>: Adjust STRING_ARG + arguments. + * stdio-common/scanf13.c: New test. + + * libio/libioP.h (_IO_acquire_lock_clear_flags2_fct): Clear + the _IO_FLAGS2_FORTIFY bit from _flags2 rather than _flags. + 2007-09-18 Ulrich Drepper <drepper@redhat.com> * sysdeps/unix/sysv/linux/i386/bits/fcntl.h: Correct return value - type __THROW marker of splice, vmsplice, and tee. + type and __THROW marker of splice, vmsplice, and tee. * sysdeps/unix/sysv/linux/ia64/bits/fcntl.h: Likewise. * sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h: Likewise. * sysdeps/unix/sysv/linux/s390/bits/fcntl.h: Likewise. diff --git a/include/stdio.h b/include/stdio.h index 4b30e6a359..084c02ea1e 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -43,6 +43,22 @@ extern char *__fgets_unlocked_chk (char *buf, size_t size, int n, FILE *fp); extern char *__fgets_chk (char *buf, size_t size, int n, FILE *fp); #endif +extern int __isoc99_fscanf (FILE *__restrict __stream, + __const char *__restrict __format, ...) __wur; +extern int __isoc99_scanf (__const char *__restrict __format, ...) __wur; +extern int __isoc99_sscanf (__const char *__restrict __s, + __const char *__restrict __format, ...) __THROW; +extern int __isoc99_vfscanf (FILE *__restrict __s, + __const char *__restrict __format, + _G_va_list __arg) __wur; +extern int __isoc99_vscanf (__const char *__restrict __format, + _G_va_list __arg) __wur; +extern int __isoc99_vsscanf (__const char *__restrict __s, + __const char *__restrict __format, + _G_va_list __arg) __THROW; +libc_hidden_proto (__isoc99_vsscanf) +libc_hidden_proto (__isoc99_vfscanf) + /* Prototypes for compatibility functions. */ extern FILE *__new_tmpfile (void); extern FILE *__old_tmpfile (void); diff --git a/include/wchar.h b/include/wchar.h index 7651f6de29..bca847731d 100644 --- a/include/wchar.h +++ b/include/wchar.h @@ -166,6 +166,23 @@ libc_hidden_proto (__vfwprintf_chk) libc_hidden_proto (__vswprintf_chk) #endif +extern int __isoc99_fwscanf (__FILE *__restrict __stream, + __const wchar_t *__restrict __format, ...); +extern int __isoc99_wscanf (__const wchar_t *__restrict __format, ...); +extern int __isoc99_swscanf (__const wchar_t *__restrict __s, + __const wchar_t *__restrict __format, ...) + __THROW; +extern int __isoc99_vfwscanf (__FILE *__restrict __s, + __const wchar_t *__restrict __format, + __gnuc_va_list __arg); +extern int __isoc99_vwscanf (__const wchar_t *__restrict __format, + __gnuc_va_list __arg); +extern int __isoc99_vswscanf (__const wchar_t *__restrict __s, + __const wchar_t *__restrict __format, + __gnuc_va_list __arg) __THROW; +libc_hidden_proto (__isoc99_vswscanf) +libc_hidden_proto (__isoc99_vfwscanf) + /* Internal functions. */ extern size_t __mbsrtowcs_l (wchar_t *dst, const char **src, size_t len, mbstate_t *ps, __locale_t l) attribute_hidden; diff --git a/inet/tst-network.c b/inet/tst-network.c index 564a366a44..5491740e37 100644 --- a/inet/tst-network.c +++ b/inet/tst-network.c @@ -34,7 +34,10 @@ struct {"1.0", 0x100}, {"1", 0x1}, {"192.168.0.0", 0xC0A80000}, + {"0", 0}, + {"0x0", 0}, /* Now some invalid addresses. */ + {"0x", INADDR_NONE}, {"141.30.225.2800", INADDR_NONE}, {"141.76.1.1.1", INADDR_NONE}, {"141.76.1.11.", INADDR_NONE}, diff --git a/libio/bits/stdio-ldbl.h b/libio/bits/stdio-ldbl.h index b6ec7f3c92..c93e6c48fb 100644 --- a/libio/bits/stdio-ldbl.h +++ b/libio/bits/stdio-ldbl.h @@ -28,9 +28,17 @@ __LDBL_REDIR_DECL (sprintf) __LDBL_REDIR_DECL (vfprintf) __LDBL_REDIR_DECL (vprintf) __LDBL_REDIR_DECL (vsprintf) +#if defined __USE_ISOC99 && !defined __USE_GNU \ + && !defined __REDIRECT \ + && (defined __STRICT_ANSI__ || defined __USE_XOPEN2K) +__LDBL_REDIR1_DECL (fscanf, __nldbl___isoc99_fscanf) +__LDBL_REDIR1_DECL (scanf, __nldbl___isoc99_scanf) +__LDBL_REDIR1_DECL (sscanf, __nldbl___isoc99_sscanf) +#else __LDBL_REDIR_DECL (fscanf) __LDBL_REDIR_DECL (scanf) __LDBL_REDIR_DECL (sscanf) +#endif __END_NAMESPACE_STD #if defined __USE_BSD || defined __USE_ISOC99 || defined __USE_UNIX98 @@ -42,9 +50,16 @@ __END_NAMESPACE_C99 #ifdef __USE_ISOC99 __BEGIN_NAMESPACE_C99 +# if !defined __USE_GNU && !defined __REDIRECT \ + && (defined __STRICT_ANSI__ || defined __USE_XOPEN2K) +__LDBL_REDIR1_DECL (vfscanf, __nldbl___isoc99_vfscanf) +__LDBL_REDIR1_DECL (vscanf, __nldbl___isoc99_vscanf) +__LDBL_REDIR1_DECL (vsscanf, __nldbl___isoc99_vsscanf) +# else __LDBL_REDIR_DECL (vfscanf) __LDBL_REDIR_DECL (vsscanf) __LDBL_REDIR_DECL (vscanf) +# endif __END_NAMESPACE_C99 #endif diff --git a/libio/libio.h b/libio/libio.h index a807883856..643812f72b 100644 --- a/libio/libio.h +++ b/libio/libio.h @@ -143,6 +143,9 @@ # define _IO_FLAGS2_FORTIFY 4 #endif #define _IO_FLAGS2_USER_WBUF 8 +#ifdef _LIBC +# define _IO_FLAGS2_SCANF_STD 16 +#endif /* These are "formatting flags" matching the iostream fmtflags enum values. */ #define _IO_SKIPWS 01 diff --git a/libio/libioP.h b/libio/libioP.h index b99b81743f..854f049291 100644 --- a/libio/libioP.h +++ b/libio/libioP.h @@ -974,7 +974,7 @@ __attribute__ ((__always_inline__)) _IO_acquire_lock_clear_flags2_fct (_IO_FILE **p) { _IO_FILE *fp = *p; - fp->_flags &= ~_IO_FLAGS2_FORTIFY; + fp->_flags2 &= ~(_IO_FLAGS2_FORTIFY | _IO_FLAGS2_SCANF_STD); if ((fp->_flags & _IO_USER_LOCK) == 0) _IO_funlockfile (fp); } diff --git a/libio/stdio.h b/libio/stdio.h index c1ba9b2235..47c6cb0a90 100644 --- a/libio/stdio.h +++ b/libio/stdio.h @@ -410,6 +410,34 @@ extern int scanf (__const char *__restrict __format, ...) __wur; /* Read formatted input from S. */ extern int sscanf (__const char *__restrict __s, __const char *__restrict __format, ...) __THROW; + +#if defined __USE_ISOC99 && !defined __USE_GNU \ + && (!defined __LDBL_COMPAT || !defined __REDIRECT) \ + && (defined __STRICT_ANSI__ || defined __USE_XOPEN2K) +# ifdef __REDIRECT +/* For strict ISO C99 or POSIX compliance disallow %as, %aS and %a[ + GNU extension which conflicts with valid %a followed by letter + s, S or [. */ +extern int __REDIRECT (fscanf, (FILE *__restrict __stream, + __const char *__restrict __format, ...), + __isoc99_fscanf) __wur; +extern int __REDIRECT (scanf, (__const char *__restrict __format, ...), + __isoc99_scanf) __wur; +extern int __REDIRECT (sscanf, (__const char *__restrict __s, + __const char *__restrict __format, ...), + __isoc99_sscanf) __THROW; +# else +extern int __isoc99_fscanf (FILE *__restrict __stream, + __const char *__restrict __format, ...) __wur; +extern int __isoc99_scanf (__const char *__restrict __format, ...) __wur; +extern int __isoc99_sscanf (__const char *__restrict __s, + __const char *__restrict __format, ...) __THROW; +# define fscanf __isoc99_fscanf +# define scanf __isoc99_scanf +# define sscanf __isoc99_sscanf +# endif +#endif + __END_NAMESPACE_STD #ifdef __USE_ISOC99 @@ -433,6 +461,42 @@ extern int vscanf (__const char *__restrict __format, _G_va_list __arg) extern int vsscanf (__const char *__restrict __s, __const char *__restrict __format, _G_va_list __arg) __THROW __attribute__ ((__format__ (__scanf__, 2, 0))); + +# if !defined __USE_GNU \ + && (!defined __LDBL_COMPAT || !defined __REDIRECT) \ + && (defined __STRICT_ANSI__ || defined __USE_XOPEN2K) +# ifdef __REDIRECT +/* For strict ISO C99 or POSIX compliance disallow %as, %aS and %a[ + GNU extension which conflicts with valid %a followed by letter + s, S or [. */ +extern int __REDIRECT (vfscanf, + (FILE *__restrict __s, + __const char *__restrict __format, _G_va_list __arg), + __isoc99_vfscanf) + __attribute__ ((__format__ (__scanf__, 2, 0))) __wur; +extern int __REDIRECT (vscanf, (__const char *__restrict __format, + _G_va_list __arg), __isoc99_vfscanf) + __attribute__ ((__format__ (__scanf__, 1, 0))) __wur; +extern int __REDIRECT (vsscanf, + (__const char *__restrict __s, + __const char *__restrict __format, _G_va_list __arg), + __isoc99_vsscanf) + __THROW __attribute__ ((__format__ (__scanf__, 2, 0))); +# else +extern int __isoc99_vfscanf (FILE *__restrict __s, + __const char *__restrict __format, + _G_va_list __arg) __wur; +extern int __isoc99_vscanf (__const char *__restrict __format, + _G_va_list __arg) __wur; +extern int __isoc99_vsscanf (__const char *__restrict __s, + __const char *__restrict __format, + _G_va_list __arg) __THROW; +# define vfscanf __isoc99_vfscanf +# define vscanf __isoc99_vsscanf +# define vsscanf __isoc99_vsscanf +# endif +# endif + __END_NAMESPACE_C99 #endif /* Use ISO C9x. */ diff --git a/stdio-common/Makefile b/stdio-common/Makefile index 84aebf4945..f87ac560aa 100644 --- a/stdio-common/Makefile +++ b/stdio-common/Makefile @@ -34,7 +34,9 @@ routines := \ tmpfile tmpfile64 tmpnam tmpnam_r tempnam tempname \ getline getw putw \ remove rename renameat \ - flockfile ftrylockfile funlockfile + flockfile ftrylockfile funlockfile \ + isoc99_scanf isoc99_vscanf isoc99_fscanf isoc99_vfscanf isoc99_sscanf \ + isoc99_vsscanf install-others = $(inst_includedir)/bits/stdio_lim.h @@ -55,7 +57,7 @@ tests := tstscanf test_rdwr test-popen tstgetln test-fseek \ 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 bug17 tst-swscanf tst-sprintf2 bug18 bug18a \ - bug19 bug19a tst-popen2 + bug19 bug19a tst-popen2 scanf13 scanf14 scanf15 test-srcs = tst-unbputc tst-printf @@ -91,14 +93,34 @@ CFLAGS-tempname.c = -fexceptions CFLAGS-psignal.c = -fexceptions CFLAGS-vprintf.c = -fexceptions CFLAGS-cuserid.c = -fexceptions + +CFLAGS-vfprintf.c += $(exceptions) +CFLAGS-fprintf.c += $(exceptions) +CFLAGS-printf.c += $(exceptions) +CFLAGS-vfwprintf.c += $(exceptions) +CFLAGS-vfscanf.c += $(exceptions) +CFLAGS-vfwscanf.c += $(exceptions) +CFLAGS-fscanf.c += $(exceptions) +CFLAGS-scanf.c += $(exceptions) +CFLAGS-isoc99_vfscanf.c += $(exceptions) +CFLAGS-isoc99_vscanf.c += $(exceptions) +CFLAGS-isoc99_fscanf.c += $(exceptions) +CFLAGS-isoc99_scanf.c += $(exceptions) CFLAGS-errlist.c = $(fno-unit-at-a-time) CFLAGS-siglist.c = $(fno-unit-at-a-time) +# The following is a hack since we must compile scanf15.c without any +# GNU extension. The latter are needed, though, when internal headers +# are used. So made sure we see the installed headers first. +CFLAGS-scanf15.c = -I../libio -I../stdlib -I../wcsmbs -I../time -I../string \ + -I../wctype + # We know the test has a format string problem. CFLAGS-tst-sprintf.c = -Wno-format tst-sscanf-ENV = LOCPATH=$(common-objpfx)localedata tst-swprintf-ENV = LOCPATH=$(common-objpfx)localedata test-vfprintf-ENV = LOCPATH=$(common-objpfx)localedata +scanf13-ENV = LOCPATH=$(common-objpfx)localedata bug14-ENV = LOCPATH=$(common-objpfx)localedata bug15-ENV = LOCPATH=$(common-objpfx)localedata diff --git a/stdio-common/Versions b/stdio-common/Versions index 2f64429346..1501fa2ffd 100644 --- a/stdio-common/Versions +++ b/stdio-common/Versions @@ -49,6 +49,10 @@ libc { GLIBC_2.4 { renameat; } + GLIBC_2.7 { + __isoc99_scanf; __isoc99_vscanf; __isoc99_fscanf; __isoc99_vfscanf; + __isoc99_sscanf; __isoc99_vsscanf; + } GLIBC_PRIVATE { # global variables _itoa_lower_digits; diff --git a/stdio-common/isoc99_fscanf.c b/stdio-common/isoc99_fscanf.c new file mode 100644 index 0000000000..5b8c16e788 --- /dev/null +++ b/stdio-common/isoc99_fscanf.c @@ -0,0 +1,40 @@ +/* Copyright (C) 1991, 1997, 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 + 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 <libioP.h> +#include <stdarg.h> +#include <stdio.h> + +/* Read formatted input from STREAM according to the format string FORMAT. */ +/* VARARGS2 */ +int +__isoc99_fscanf (FILE *stream, const char *format, ...) +{ + va_list arg; + int done; + + _IO_acquire_lock_clear_flags2 (stream); + stream->_flags2 |= _IO_FLAGS2_SCANF_STD; + + va_start (arg, format); + done = INTUSE(_IO_vfscanf) (stream, format, arg, NULL); + va_end (arg); + + _IO_release_lock (stream); + return done; +} diff --git a/stdio-common/isoc99_scanf.c b/stdio-common/isoc99_scanf.c new file mode 100644 index 0000000000..a90fe7018c --- /dev/null +++ b/stdio-common/isoc99_scanf.c @@ -0,0 +1,42 @@ +/* Copyright (C) 1991, 1995, 1996, 1997, 2002, 2004, 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 + 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 <stdarg.h> +#include <stdio.h> +#include <libioP.h> + + +/* Read formatted input from stdin according to the format string FORMAT. */ +/* VARARGS1 */ +int +__isoc99_scanf (const char *format, ...) +{ + va_list arg; + int done; + + _IO_acquire_lock_clear_flags2 (stdin); + stdin->_flags2 |= _IO_FLAGS2_SCANF_STD; + + va_start (arg, format); + done = INTUSE(_IO_vfscanf) (stdin, format, arg, NULL); + va_end (arg); + + _IO_release_lock (stdin); + return done; +} diff --git a/stdio-common/isoc99_sscanf.c b/stdio-common/isoc99_sscanf.c new file mode 100644 index 0000000000..9500ccb464 --- /dev/null +++ b/stdio-common/isoc99_sscanf.c @@ -0,0 +1,37 @@ +/* Copyright (C) 1991, 1995, 1996, 1998, 2002, 2003, 2004, 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 + 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 <stdarg.h> +#include <stdio.h> +#include <libioP.h> + +/* Read formatted input from S, according to the format string FORMAT. */ +/* VARARGS2 */ +int +__isoc99_sscanf (const char *s, const char *format, ...) +{ + va_list arg; + int done; + + va_start (arg, format); + done = __isoc99_vsscanf (s, format, arg); + va_end (arg); + + return done; +} diff --git a/stdio-common/isoc99_vfscanf.c b/stdio-common/isoc99_vfscanf.c new file mode 100644 index 0000000000..10b04c3bc7 --- /dev/null +++ b/stdio-common/isoc99_vfscanf.c @@ -0,0 +1,35 @@ +/* Copyright (C) 1991, 1997, 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 + 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 <libioP.h> +#include <stdio.h> + +/* Read formatted input from STREAM according to the format string FORMAT. */ +/* VARARGS2 */ +int +__isoc99_vfscanf (FILE *stream, const char *format, _IO_va_list args) +{ + int done; + + _IO_acquire_lock_clear_flags2 (stream); + stream->_flags2 |= _IO_FLAGS2_SCANF_STD; + done = INTUSE(_IO_vfscanf) (stream, format, args, NULL); + _IO_release_lock (stream); + return done; +} +libc_hidden_def (__isoc99_vfscanf) diff --git a/stdio-common/isoc99_vscanf.c b/stdio-common/isoc99_vscanf.c new file mode 100644 index 0000000000..f7858f042b --- /dev/null +++ b/stdio-common/isoc99_vscanf.c @@ -0,0 +1,34 @@ +/* Copyright (C) 1991, 1997, 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 + 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 <libioP.h> +#include <stdio.h> + +/* Read formatted input from STDIN according to the format string FORMAT. */ +/* VARARGS2 */ +int +__isoc99_vscanf (const char *format, _IO_va_list args) +{ + int done; + + _IO_acquire_lock_clear_flags2 (stdin); + stdin->_flags2 |= _IO_FLAGS2_SCANF_STD; + done = INTUSE(_IO_vfscanf) (stdin, format, args, NULL); + _IO_release_lock (stdin); + return done; +} diff --git a/stdio-common/isoc99_vsscanf.c b/stdio-common/isoc99_vsscanf.c new file mode 100644 index 0000000000..f10919c79a --- /dev/null +++ b/stdio-common/isoc99_vsscanf.c @@ -0,0 +1,47 @@ +/* Copyright (C) 1993, 1997-2003, 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 + 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. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include <libioP.h> +#include <stdio.h> +#include "../libio/strfile.h" + +int +__isoc99_vsscanf (const char *string, const char *format, _IO_va_list args) +{ + int ret; + _IO_strfile sf; +#ifdef _IO_MTSAFE_IO + sf._sbf._f._lock = NULL; +#endif + _IO_no_init (&sf._sbf._f, _IO_USER_LOCK, -1, NULL, NULL); + _IO_JUMPS ((struct _IO_FILE_plus *) &sf._sbf) = &_IO_str_jumps; + _IO_str_init_static_internal (&sf, (char*)string, 0, NULL); + sf._sbf._f._flags2 |= _IO_FLAGS2_SCANF_STD; + ret = INTUSE(_IO_vfscanf) ((_IO_FILE *) &sf._sbf, format, args, NULL); + return ret; +} +libc_hidden_def (__isoc99_vsscanf) diff --git a/stdio-common/scanf13.c b/stdio-common/scanf13.c new file mode 100644 index 0000000000..e53cde29c7 --- /dev/null +++ b/stdio-common/scanf13.c @@ -0,0 +1,187 @@ +#include <locale.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <wchar.h> + +int +main (void) +{ + char *sp1, *sp2, *sp3, *sp4; + wchar_t *lsp1, *lsp2, *lsp3, *lsp4; + int result = 0; + char buf[2048+64]; + wchar_t wbuf[2048+64]; + size_t i; + +#define FAIL() \ + do { \ + result = 1; \ + printf ("test at line %d failed\n", __LINE__); \ + } while (0) + + setlocale (LC_ALL, "de_DE.UTF-8"); + if (sscanf ("A \xc3\x84-\t\t\xc3\x84-abcdefbcd\t\xc3\x84-B", + "A%ms%10ms%4m[bcd]%4mcB", &sp1, &sp2, &sp3, &sp4) != 4) + FAIL (); + else + { + if (strcmp (sp1, "\xc3\x84-") != 0) + FAIL (); + free (sp1); + if (strcmp (sp2, "\xc3\x84-abcdefb") != 0) + FAIL (); + free (sp2); + if (strcmp (sp3, "cd") != 0) + FAIL (); + free (sp3); + if (memcmp (sp4, "\t\xc3\x84-", 4) != 0) + FAIL (); + free (sp4); + } + + if (sscanf ("A \xc3\x84-\t\t\xc3\x84-abcdefbcd\t\xc3\x84-BB", + "A%mS%10mls%4ml[bcd]%4mCB", &lsp1, &lsp2, &lsp3, &lsp4) != 4) + FAIL (); + else + { + if (wcscmp (lsp1, L"\xc4-") != 0) + FAIL (); + free (lsp1); + if (wcscmp (lsp2, L"\xc4-abcdefbc") != 0) + FAIL (); + free (lsp2); + if (wcscmp (lsp3, L"d") != 0) + FAIL (); + free (lsp3); + if (memcmp (lsp4, L"\t\xc4-B", 4 * sizeof (wchar_t)) != 0) + FAIL (); + free (lsp4); + } + + memset (buf, '/', sizeof (buf)); + buf[0] = '\t'; + buf[1] = ' '; + buf[2] = 0xc3; + buf[3] = 0x84; + buf[2048] = 0xc3; + buf[2049] = 0x84; + buf[2058] = '\t'; + buf[2059] = 'a'; + if (sscanf (buf, "%ms%mc", &sp1, &sp2) != 2) + FAIL (); + else + { + if (sp1[0] != '\xc3' || sp1[1] != '\x84' + || sp1[2046] != '\xc3' || sp1[2047] != '\x84' + || sp1[2056] != '\0') + FAIL (); + sp1[2046] = '/'; + sp1[2047] = '/'; + for (i = 2; i < 2056; i++) + if (sp1[i] != '/') + FAIL (); + free (sp1); + if (sp2[0] != '\t') + FAIL (); + free (sp2); + } + if (sscanf (buf, "%2048ms%mc", &sp3, &sp4) != 2) + FAIL (); + else + { + if (sp3[0] != '\xc3' || sp3[1] != '\x84' + || sp3[2046] != '\xc3' || sp3[2047] != '\x84' + || sp3[2048] != '\0') + FAIL (); + for (i = 2; i < 2046; i++) + if (sp3[i] != '/') + FAIL (); + free (sp3); + if (sp4[0] != '/') + FAIL (); + free (sp4); + } + if (sscanf (buf, "%4mc%1500m[dr/]%548m[abc/d]%3mc", &sp1, &sp2, &sp3, &sp4) + != 4) + FAIL (); + else + { + if (memcmp (sp1, "\t \xc3\x84", 4) != 0) + FAIL (); + free (sp1); + for (i = 0; i < 1500; i++) + if (sp2[i] != '/') + FAIL (); + if (sp2[1500] != '\0') + FAIL (); + free (sp2); + for (i = 0; i < 544; i++) + if (sp3[i] != '/') + FAIL (); + if (sp3[544] != '\0') + FAIL (); + free (sp3); + if (memcmp (sp4, "\xc3\x84/", 3) != 0) + FAIL (); + free (sp4); + } + if (sscanf (buf, "%mS%mC", &lsp1, &lsp2) != 2) + FAIL (); + else + { + if (lsp1[0] != L'\xc4' || lsp1[2045] != L'\xc4' + || lsp1[2054] != L'\0') + FAIL (); + lsp1[2045] = L'/'; + for (i = 1; i < 2054; i++) + if (lsp1[i] != L'/') + FAIL (); + free (lsp1); + if (lsp2[0] != L'\t') + FAIL (); + free (lsp2); + } + if (sscanf (buf, "%2048mls%mlc", &lsp3, &lsp4) != 2) + FAIL (); + else + { + if (lsp3[0] != L'\xc4' || lsp3[2045] != L'\xc4' + || lsp3[2048] != L'\0') + FAIL (); + lsp3[2045] = L'/'; + for (i = 1; i < 2048; i++) + if (lsp3[i] != L'/') + FAIL (); + free (lsp3); + if (lsp4[0] != L'/') + FAIL (); + free (lsp4); + } + if (sscanf (buf, "%4mC%1500ml[dr/]%548ml[abc/d]%3mlc", + &lsp1, &lsp2, &lsp3, &lsp4) != 4) + FAIL (); + else + { + if (memcmp (lsp1, L"\t \xc4/", 4 * sizeof (wchar_t)) != 0) + FAIL (); + free (lsp1); + for (i = 0; i < 1500; i++) + if (lsp2[i] != L'/') + FAIL (); + if (lsp2[1500] != L'\0') + FAIL (); + free (lsp2); + for (i = 0; i < 543; i++) + if (lsp3[i] != L'/') + FAIL (); + if (lsp3[543] != L'\0') + FAIL (); + free (lsp3); + if (memcmp (lsp4, L"\xc4//", 3 * sizeof (wchar_t)) != 0) + FAIL (); + free (lsp4); + } + + return result; +} diff --git a/stdio-common/scanf14.c b/stdio-common/scanf14.c new file mode 100644 index 0000000000..387ceba4bb --- /dev/null +++ b/stdio-common/scanf14.c @@ -0,0 +1,63 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <wchar.h> + +#define FAIL() \ + do { \ + result = 1; \ + printf ("test at line %d failed\n", __LINE__); \ + } while (0) + +int +main (void) +{ + wchar_t *lsp; + char *sp; + float f; + double d; + char c[8]; + int result = 0; + + if (sscanf (" 0.25s x", "%e%3c", &f, c) != 2) + FAIL (); + else if (f != 0.25 || memcmp (c, "s x", 3) != 0) + FAIL (); + if (sscanf (" 1.25s x", "%as%2c", &sp, c) != 2) + FAIL (); + else + { + if (strcmp (sp, "1.25s") != 0 || memcmp (c, " x", 2) != 0) + FAIL (); + memset (sp, 'x', sizeof "1.25s"); + free (sp); + } + if (sscanf (" 2.25s x", "%las%2c", &d, c) != 2) + FAIL (); + else if (d != 2.25 || memcmp (c, " x", 2) != 0) + FAIL (); + if (sscanf (" 3.25S x", "%4aS%3c", &lsp, c) != 2) + FAIL (); + else + { + if (wcscmp (lsp, L"3.25") != 0 || memcmp (c, "S x", 3) != 0) + FAIL (); + memset (lsp, 'x', sizeof L"3.25"); + free (lsp); + } + if (sscanf ("4.25[0-9.] x", "%a[0-9.]%8c", &sp, c) != 2) + FAIL (); + else + { + if (strcmp (sp, "4.25") != 0 || memcmp (c, "[0-9.] x", 8) != 0) + FAIL (); + memset (sp, 'x', sizeof "4.25"); + free (sp); + } + if (sscanf ("5.25[0-9.] x", "%la[0-9.]%2c", &d, c) != 2) + FAIL (); + else if (d != 5.25 || memcmp (c, " x", 2) != 0) + FAIL (); + + return result; +} diff --git a/stdio-common/scanf15.c b/stdio-common/scanf15.c new file mode 100644 index 0000000000..cc8aa2e6a6 --- /dev/null +++ b/stdio-common/scanf15.c @@ -0,0 +1,54 @@ +#undef _GNU_SOURCE +#define _XOPEN_SOURCE 600 +/* The following macro definitions are a hack. They word around disabling + the GNU extension while still using a few internal headers. */ +#define u_char unsigned char +#define u_short unsigned short +#define u_int unsigned int +#define u_long unsigned long +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <wchar.h> + +#define FAIL() \ + do { \ + result = 1; \ + printf ("test at line %d failed\n", __LINE__); \ + } while (0) + +int +main (void) +{ + float f; + double d; + char c[8]; + int result = 0; + + if (sscanf (" 0.25s x", "%e%3c", &f, c) != 2) + FAIL (); + else if (f != 0.25 || memcmp (c, "s x", 3) != 0) + FAIL (); + if (sscanf (" 1.25s x", "%as%2c", &f, c) != 2) + FAIL (); + else if (f != 1.25 || memcmp (c, " x", 2) != 0) + FAIL (); + if (sscanf (" 2.25s x", "%las%2c", &d, c) != 2) + FAIL (); + else if (d != 2.25 || memcmp (c, " x", 2) != 0) + FAIL (); + if (sscanf (" 3.25S x", "%4aS%2c", &f, c) != 2) + FAIL (); + else if (f != 3.25 || memcmp (c, " x", 2) != 0) + FAIL (); + if (sscanf (" 4.25[0-9.] x", "%a[0-9.]%2c", &f, c) != 2) + FAIL (); + else if (f != 4.25 || memcmp (c, " x", 2) != 0) + FAIL (); + if (sscanf (" 5.25[0-9.] x", "%la[0-9.]%2c", &d, c) != 2) + FAIL (); + else if (d != 5.25 || memcmp (c, " x", 2) != 0) + FAIL (); + + return result; +} diff --git a/stdio-common/vfscanf.c b/stdio-common/vfscanf.c index ddf9a5ea31..e4728d00c9 100644 --- a/stdio-common/vfscanf.c +++ b/stdio-common/vfscanf.c @@ -514,13 +514,25 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr, --f; break; } + /* In __isoc99_*scanf %as, %aS and %a[ extension is not + supported at all. */ + if (s->_flags2 & _IO_FLAGS2_SCANF_STD) + { + --f; + break; + } /* String conversions (%s, %[) take a `char **' arg and fill it in with a malloc'd pointer. */ flags |= GNU_MALLOC; break; - case L_('m'): - flags |= POSIX_MALLOC; - break; + case L_('m'): + flags |= POSIX_MALLOC; + if (*f == L_('l')) + { + ++f; + flags |= LONG; + } + break; case L_('z'): if (need_longlong && sizeof (size_t) > sizeof (unsigned long int)) flags |= LONGDBL; @@ -635,20 +647,46 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr, case L_('c'): /* Match characters. */ if ((flags & LONG) == 0) { - if (!(flags & SUPPRESS)) - { - str = ARG (char *); - if (str == NULL) - conv_error (); - } + if (width == -1) + width = 1; + +#define STRING_ARG(Str, Type, Width) \ + do if (!(flags & SUPPRESS)) \ + { \ + if (flags & MALLOC) \ + { \ + /* The string is to be stored in a malloc'd buffer. */ \ + /* For %mS using char ** is actually wrong, but \ + shouldn't make a difference on any arch glibc \ + supports and would unnecessarily complicate \ + things. */ \ + strptr = ARG (char **); \ + if (strptr == NULL) \ + conv_error (); \ + /* Allocate an initial buffer. */ \ + strsize = Width; \ + *strptr = (char *) malloc (strsize * sizeof (Type)); \ + Str = (Type *) *strptr; \ + if (Str != NULL) \ + add_ptr_to_free (strptr); \ + else if (flags & POSIX_MALLOC) \ + goto reteof; \ + } \ + else \ + Str = ARG (Type *); \ + if (Str == NULL) \ + conv_error (); \ + } while (0) +#ifdef COMPILE_WSCANF + STRING_ARG (str, char, 100); +#else + STRING_ARG (str, char, (width > 1024 ? 1024 : width)); +#endif c = inchar (); if (__builtin_expect (c == EOF, 0)) input_error (); - if (width == -1) - width = 1; - #ifdef COMPILE_WSCANF /* We have to convert the wide character(s) into multibyte characters and store the result. */ @@ -658,6 +696,38 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr, { size_t n; + if (!(flags & SUPPRESS) && (flags & POSIX_MALLOC) + && str + MB_CUR_MAX >= *strptr + strsize) + { + /* We have to enlarge the buffer if the `m' flag + was given. */ + size_t strleng = str - *strptr; + char *newstr; + + newstr = (char *) realloc (*strptr, strsize * 2); + if (newstr == NULL) + { + /* Can't allocate that much. Last-ditch effort. */ + newstr = (char *) realloc (*strptr, + strleng + MB_CUR_MAX); + if (newstr == NULL) + /* c can't have `a' flag, only `m'. */ + goto reteof; + else + { + *strptr = newstr; + str = newstr + strleng; + strsize = strleng + MB_CUR_MAX; + } + } + else + { + *strptr = newstr; + str = newstr + strleng; + strsize *= 2; + } + } + n = __wcrtomb (!(flags & SUPPRESS) ? str : NULL, c, &state); if (__builtin_expect (n == (size_t) -1, 0)) /* No valid wide character. */ @@ -672,7 +742,40 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr, if (!(flags & SUPPRESS)) { do - *str++ = c; + { + if ((flags & MALLOC) + && (char *) str == *strptr + strsize) + { + /* Enlarge the buffer. */ + size_t newsize + = strsize + + (strsize >= width ? width - 1 : strsize); + + str = (char *) realloc (*strptr, newsize); + if (str == NULL) + { + /* Can't allocate that much. Last-ditch + effort. */ + str = (char *) realloc (*strptr, strsize + 1); + if (str == NULL) + /* c can't have `a' flag, only `m'. */ + goto reteof; + else + { + *strptr = (char *) str; + str += strsize; + ++strsize; + } + } + else + { + *strptr = (char *) str; + str += strsize; + strsize = newsize; + } + } + *str++ = c; + } while (--width > 0 && inchar () != EOF); } else @@ -680,18 +783,25 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr, #endif if (!(flags & SUPPRESS)) - ++done; + { + if ((flags & MALLOC) && str - *strptr != strsize) + { + char *cp = (char *) realloc (*strptr, str - *strptr); + if (cp != NULL) + *strptr = cp; + } + strptr = NULL; + ++done; + } break; } /* FALLTHROUGH */ case L_('C'): - if (!(flags & SUPPRESS)) - { - wstr = ARG (wchar_t *); - if (wstr == NULL) - conv_error (); - } + if (width == -1) + width = 1; + + STRING_ARG (wstr, wchar_t, (width > 1024 ? 1024 : width)); c = inchar (); if (__builtin_expect (c == EOF, 0)) @@ -702,7 +812,40 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr, if (!(flags & SUPPRESS)) { do - *wstr++ = c; + { + if ((flags & MALLOC) + && wstr == (wchar_t *) *strptr + strsize) + { + size_t newsize + = strsize + (strsize > width ? width - 1 : strsize); + /* Enlarge the buffer. */ + wstr = (wchar_t *) realloc (*strptr, + newsize * sizeof (wchar_t)); + if (wstr == NULL) + { + /* Can't allocate that much. Last-ditch effort. */ + wstr = (wchar_t *) realloc (*strptr, + (strsize + 1) + * sizeof (wchar_t)); + if (wstr == NULL) + /* C or lc can't have `a' flag, only `m' flag. */ + goto reteof; + else + { + *strptr = (char *) wstr; + wstr += strsize; + ++strsize; + } + } + else + { + *strptr = (char *) wstr; + wstr += strsize; + strsize = newsize; + } + } + *wstr++ = c; + } while (--width > 0 && inchar () != EOF); } else @@ -721,6 +864,38 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr, /* This is what we present the mbrtowc function first. */ buf[0] = c; + if (!(flags & SUPPRESS) && (flags & MALLOC) + && wstr == (wchar_t *) *strptr + strsize) + { + size_t newsize + = strsize + (strsize > width ? width - 1 : strsize); + /* Enlarge the buffer. */ + wstr = (wchar_t *) realloc (*strptr, + newsize * sizeof (wchar_t)); + if (wstr == NULL) + { + /* Can't allocate that much. Last-ditch effort. */ + wstr = (wchar_t *) realloc (*strptr, + ((strsize + 1) + * sizeof (wchar_t))); + if (wstr == NULL) + /* C or lc can't have `a' flag, only `m' flag. */ + goto reteof; + else + { + *strptr = (char *) wstr; + wstr += strsize; + ++strsize; + } + } + else + { + *strptr = (char *) wstr; + wstr += strsize; + strsize = newsize; + } + } + while (1) { size_t n; @@ -754,41 +929,27 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr, #endif if (!(flags & SUPPRESS)) - ++done; + { + if ((flags & MALLOC) && wstr - (wchar_t *) *strptr != strsize) + { + wchar_t *cp = (wchar_t *) realloc (*strptr, + ((wstr + - (wchar_t *) *strptr) + * sizeof (wchar_t))); + if (cp != NULL) + *strptr = (char *) cp; + } + strptr = NULL; + + ++done; + } break; case L_('s'): /* Read a string. */ if (!(flags & LONG)) { -#define STRING_ARG(Str, Type) \ - do if (!(flags & SUPPRESS)) \ - { \ - if (flags & MALLOC) \ - { \ - /* The string is to be stored in a malloc'd buffer. */ \ - /* For %mS using char ** is actually wrong, but \ - shouldn't make a difference on any arch glibc \ - supports and would unnecessarily complicate \ - things. */ \ - strptr = ARG (char **); \ - if (strptr == NULL) \ - conv_error (); \ - /* Allocate an initial buffer. */ \ - strsize = 100; \ - *strptr = (char *) malloc (strsize * sizeof (Type)); \ - Str = (Type *) *strptr; \ - if (Str != NULL) \ - add_ptr_to_free (strptr); \ - else if (flags & POSIX_MALLOC) \ - goto reteof; \ - } \ - else \ - Str = ARG (Type *); \ - if (Str == NULL) \ - conv_error (); \ - } while (0) - STRING_ARG (str, char); + STRING_ARG (str, char, 100); c = inchar (); if (__builtin_expect (c == EOF, 0)) @@ -816,8 +977,8 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr, if (!(flags & SUPPRESS) && (flags & MALLOC) && str + MB_CUR_MAX >= *strptr + strsize) { - /* We have to enlarge the buffer if the `a' flag - was given. */ + /* We have to enlarge the buffer if the `a' or `m' + flag was given. */ size_t strleng = str - *strptr; char *newstr; @@ -969,7 +1130,7 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr, #endif /* Wide character string. */ - STRING_ARG (wstr, wchar_t); + STRING_ARG (wstr, wchar_t, 100); c = inchar (); if (__builtin_expect (c == EOF, 0)) @@ -1002,7 +1163,7 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr, if (wstr == NULL) { /* Can't allocate that much. Last-ditch - effort. */ + effort. */ wstr = (wchar_t *) realloc (*strptr, (strsize + 1) * sizeof (wchar_t)); @@ -2120,9 +2281,9 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr, case L_('['): /* Character class. */ if (flags & LONG) - STRING_ARG (wstr, wchar_t); + STRING_ARG (wstr, wchar_t, 100); else - STRING_ARG (str, char); + STRING_ARG (str, char, 100); if (*f == L_('^')) { diff --git a/sysdeps/ieee754/ldbl-opt/Makefile b/sysdeps/ieee754/ldbl-opt/Makefile index 7f7bc3ce33..ce2d2d5d1d 100644 --- a/sysdeps/ieee754/ldbl-opt/Makefile +++ b/sysdeps/ieee754/ldbl-opt/Makefile @@ -35,7 +35,11 @@ libnldbl-calls = asprintf dprintf fprintf fscanf fwprintf fwscanf iovfscanf \ jn yn ilogb remquo lrint lround llrint llround nexttowardf \ nexttoward conj cacos cacosh casin catan catanh ccos ccosh \ casinh cexp clog cproj csin csinh csqrt ctan ctanh cpow \ - cabs carg cimag creal clog10 + cabs carg cimag creal clog10 \ + isoc99_scanf isoc99_fscanf isoc99_sscanf \ + isoc99_vscanf isoc99_vfscanf isoc99_vsscanf \ + isoc99_wscanf isoc99_fwscanf isoc99_swscanf \ + isoc99_vwscanf isoc99_vfwscanf isoc99_vswscanf libnldbl-routines = $(libnldbl-calls:%=nldbl-%) libnldbl-inhibit-o = $(object-suffixes) libnldbl-static-only-routines = $(libnldbl-routines) diff --git a/sysdeps/ieee754/ldbl-opt/Versions b/sysdeps/ieee754/ldbl-opt/Versions index d22b18ec89..74fb3383ab 100644 --- a/sysdeps/ieee754/ldbl-opt/Versions +++ b/sysdeps/ieee754/ldbl-opt/Versions @@ -65,6 +65,14 @@ libc { __nldbl___swprintf_chk; __nldbl___vswprintf_chk; __nldbl___fwprintf_chk; __nldbl___wprintf_chk; __nldbl___vfwprintf_chk; __nldbl___vwprintf_chk; } + GLIBC_2.7 { + __nldbl___isoc99_scanf; __nldbl___isoc99_fscanf; + __nldbl___isoc99_sscanf; __nldbl___isoc99_vscanf; + __nldbl___isoc99_vfscanf; __nldbl___isoc99_vsscanf; + __nldbl___isoc99_wscanf; __nldbl___isoc99_fwscanf; + __nldbl___isoc99_swscanf; __nldbl___isoc99_vwscanf; + __nldbl___isoc99_vfwscanf; __nldbl___isoc99_vswscanf; + } } libm { NLDBL_VERSION { diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-compat.c b/sysdeps/ieee754/ldbl-opt/nldbl-compat.c index f82c5f60bb..b87f3bc476 100644 --- a/sysdeps/ieee754/ldbl-opt/nldbl-compat.c +++ b/sysdeps/ieee754/ldbl-opt/nldbl-compat.c @@ -1,5 +1,5 @@ /* *printf* family compatibility routines for IEEE double as long double - Copyright (C) 2006 Free Software Foundation, Inc. + Copyright (C) 2006, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Jakub Jelinek <jakub@cygnus.com>, 2006. @@ -50,6 +50,10 @@ libc_hidden_proto (__nldbl___vsprintf_chk) libc_hidden_proto (__nldbl___vswprintf_chk) libc_hidden_proto (__nldbl___vstrfmon) libc_hidden_proto (__nldbl___vstrfmon_l) +libc_hidden_proto (__nldbl___isoc99_vsscanf) +libc_hidden_proto (__nldbl___isoc99_vfscanf) +libc_hidden_proto (__nldbl___isoc99_vswscanf) +libc_hidden_proto (__nldbl___isoc99_vfwscanf) static void __nldbl_cleanup (void *arg) @@ -782,6 +786,153 @@ __nldbl_vsyslog (int pri, const char *fmt, va_list ap) __nldbl___vsyslog_chk (pri, -1, fmt, ap); } +int +attribute_compat_text_section +__nldbl___isoc99_vfscanf (FILE *s, const char *fmt, va_list ap) +{ + int res; + set_no_long_double (); + res = __isoc99_vfscanf (s, fmt, ap); + clear_no_long_double (); + return res; +} +libc_hidden_def (__nldbl___isoc99_vfscanf) + +int +attribute_compat_text_section +__nldbl___isoc99_sscanf (const char *s, const char *fmt, ...) +{ + va_list arg; + int done; + + va_start (arg, fmt); + done = __nldbl___isoc99_vsscanf (s, fmt, arg); + va_end (arg); + + return done; +} + +int +attribute_compat_text_section +__nldbl___isoc99_vsscanf (const char *string, const char *fmt, va_list ap) +{ + int res; + __no_long_double = 1; + res = __isoc99_vsscanf (string, fmt, ap); + __no_long_double = 0; + return res; +} +libc_hidden_def (__nldbl___isoc99_vsscanf) + +int +attribute_compat_text_section +__nldbl___isoc99_vscanf (const char *fmt, va_list ap) +{ + return __nldbl___isoc99_vfscanf (stdin, fmt, ap); +} + +int +attribute_compat_text_section +__nldbl___isoc99_fscanf (FILE *stream, const char *fmt, ...) +{ + va_list arg; + int done; + + va_start (arg, fmt); + done = __nldbl___isoc99_vfscanf (stream, fmt, arg); + va_end (arg); + + return done; +} + +int +attribute_compat_text_section +__nldbl___isoc99_scanf (const char *fmt, ...) +{ + va_list arg; + int done; + + va_start (arg, fmt); + done = __nldbl___isoc99_vfscanf (stdin, fmt, arg); + va_end (arg); + + return done; +} + +int +attribute_compat_text_section +__nldbl___isoc99_vfwscanf (FILE *s, const wchar_t *fmt, va_list ap) +{ + int res; + set_no_long_double (); + res = __isoc99_vfwscanf (s, fmt, ap); + clear_no_long_double (); + return res; +} +libc_hidden_def (__nldbl___isoc99_vfwscanf) + +int +attribute_compat_text_section +__nldbl___isoc99_swscanf (const wchar_t *s, const wchar_t *fmt, ...) +{ + va_list arg; + int done; + + va_start (arg, fmt); + done = __nldbl___isoc99_vswscanf (s, fmt, arg); + va_end (arg); + + return done; +} + +int +attribute_compat_text_section +__nldbl___isoc99_vswscanf (const wchar_t *string, const wchar_t *fmt, + va_list ap) +{ + int res; + __no_long_double = 1; + res = __isoc99_vswscanf (string, fmt, ap); + __no_long_double = 0; + return res; +} +libc_hidden_def (__nldbl___isoc99_vswscanf) + +int +attribute_compat_text_section +__nldbl___isoc99_vwscanf (const wchar_t *fmt, va_list ap) +{ + return __nldbl___isoc99_vfwscanf (stdin, fmt, ap); +} + +int +attribute_compat_text_section +__nldbl___isoc99_fwscanf (FILE *stream, const wchar_t *fmt, ...) +{ + va_list arg; + int done; + + va_start (arg, fmt); + done = __nldbl___isoc99_vfwscanf (stream, fmt, arg); + va_end (arg); + + return done; +} + +int +attribute_compat_text_section +__nldbl___isoc99_wscanf (const wchar_t *fmt, ...) +{ + va_list arg; + int done; + + va_start (arg, fmt); + done = __nldbl___isoc99_vfwscanf (stdin, fmt, arg); + va_end (arg); + + return done; +} + #if LONG_DOUBLE_COMPAT(libc, GLIBC_2_0) compat_symbol (libc, __nldbl__IO_printf, _IO_printf, GLIBC_2_0); compat_symbol (libc, __nldbl__IO_sprintf, _IO_sprintf, GLIBC_2_0); diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-compat.h b/sysdeps/ieee754/ldbl-opt/nldbl-compat.h index c0461000f0..c7824583d6 100644 --- a/sysdeps/ieee754/ldbl-opt/nldbl-compat.h +++ b/sysdeps/ieee754/ldbl-opt/nldbl-compat.h @@ -1,5 +1,5 @@ /* Prototypes for compatibility double == long double entry points. - Copyright (C) 2006 Free Software Foundation, Inc. + Copyright (C) 2006, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Jakub Jelinek <jakub@cygnus.com>, 2006. @@ -61,6 +61,18 @@ NLDBL_DECL (qecvt); NLDBL_DECL (qfcvt); NLDBL_DECL (qgcvt); NLDBL_DECL (__vstrfmon_l); +NLDBL_DECL (__isoc99_scanf); +NLDBL_DECL (__isoc99_fscanf); +NLDBL_DECL (__isoc99_sscanf); +NLDBL_DECL (__isoc99_vscanf); +NLDBL_DECL (__isoc99_vfscanf); +NLDBL_DECL (__isoc99_vsscanf); +NLDBL_DECL (__isoc99_wscanf); +NLDBL_DECL (__isoc99_fwscanf); +NLDBL_DECL (__isoc99_swscanf); +NLDBL_DECL (__isoc99_vwscanf); +NLDBL_DECL (__isoc99_vfwscanf); +NLDBL_DECL (__isoc99_vswscanf); /* This one does not exist in the normal interface, only __nldbl___vstrfmon really exists. */ diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-isoc99_fscanf.c b/sysdeps/ieee754/ldbl-opt/nldbl-isoc99_fscanf.c new file mode 100644 index 0000000000..1d736668a4 --- /dev/null +++ b/sysdeps/ieee754/ldbl-opt/nldbl-isoc99_fscanf.c @@ -0,0 +1,15 @@ +#include "nldbl-compat.h" + +int +attribute_hidden +__isoc99_fscanf (FILE *stream, const char *fmt, ...) +{ + va_list arg; + int done; + + va_start (arg, fmt); + done = __nldbl___isoc99_vfscanf (stream, fmt, arg); + va_end (arg); + + return done; +} diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-isoc99_fwscanf.c b/sysdeps/ieee754/ldbl-opt/nldbl-isoc99_fwscanf.c new file mode 100644 index 0000000000..dbea1512cf --- /dev/null +++ b/sysdeps/ieee754/ldbl-opt/nldbl-isoc99_fwscanf.c @@ -0,0 +1,15 @@ +#include "nldbl-compat.h" + +int +attribute_hidden +__isoc99_fwscanf (FILE *stream, const wchar_t *fmt, ...) +{ + va_list arg; + int done; + + va_start (arg, fmt); + done = __nldbl___isoc99_vfwscanf (stream, fmt, arg); + va_end (arg); + + return done; +} diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-isoc99_scanf.c b/sysdeps/ieee754/ldbl-opt/nldbl-isoc99_scanf.c new file mode 100644 index 0000000000..ec2ec53291 --- /dev/null +++ b/sysdeps/ieee754/ldbl-opt/nldbl-isoc99_scanf.c @@ -0,0 +1,15 @@ +#include "nldbl-compat.h" + +int +attribute_hidden +__isoc99_scanf (const char *fmt, ...) +{ + va_list arg; + int done; + + va_start (arg, fmt); + done = __nldbl___isoc99_vfscanf (stdin, fmt, arg); + va_end (arg); + + return done; +} diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-isoc99_sscanf.c b/sysdeps/ieee754/ldbl-opt/nldbl-isoc99_sscanf.c new file mode 100644 index 0000000000..52e1bd5d2a --- /dev/null +++ b/sysdeps/ieee754/ldbl-opt/nldbl-isoc99_sscanf.c @@ -0,0 +1,15 @@ +#include "nldbl-compat.h" + +int +attribute_hidden +__isoc99_sscanf (const char *s, const char *fmt, ...) +{ + va_list arg; + int done; + + va_start (arg, fmt); + done = __nldbl___isoc99_vsscanf (s, fmt, arg); + va_end (arg); + + return done; +} diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-isoc99_swscanf.c b/sysdeps/ieee754/ldbl-opt/nldbl-isoc99_swscanf.c new file mode 100644 index 0000000000..927d024923 --- /dev/null +++ b/sysdeps/ieee754/ldbl-opt/nldbl-isoc99_swscanf.c @@ -0,0 +1,15 @@ +#include "nldbl-compat.h" + +int +attribute_hidden +__isoc99_swscanf (const wchar_t *s, const wchar_t *fmt, ...) +{ + va_list arg; + int done; + + va_start (arg, fmt); + done = __nldbl___isoc99_vswscanf (s, fmt, arg); + va_end (arg); + + return done; +} diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-isoc99_vfscanf.c b/sysdeps/ieee754/ldbl-opt/nldbl-isoc99_vfscanf.c new file mode 100644 index 0000000000..55556c375c --- /dev/null +++ b/sysdeps/ieee754/ldbl-opt/nldbl-isoc99_vfscanf.c @@ -0,0 +1,8 @@ +#include "nldbl-compat.h" + +int +attribute_hidden +__isoc99_vfscanf (FILE *s, const char *fmt, va_list ap) +{ + return __nldbl___isoc99_vfscanf (s, fmt, ap); +} diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-isoc99_vfwscanf.c b/sysdeps/ieee754/ldbl-opt/nldbl-isoc99_vfwscanf.c new file mode 100644 index 0000000000..4fd54cb176 --- /dev/null +++ b/sysdeps/ieee754/ldbl-opt/nldbl-isoc99_vfwscanf.c @@ -0,0 +1,8 @@ +#include "nldbl-compat.h" + +int +attribute_hidden +__isoc99_vfwscanf (FILE *s, const wchar_t *fmt, va_list ap) +{ + return __nldbl___isoc99_vfwscanf (s, fmt, ap); +} diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-isoc99_vscanf.c b/sysdeps/ieee754/ldbl-opt/nldbl-isoc99_vscanf.c new file mode 100644 index 0000000000..6284c9339b --- /dev/null +++ b/sysdeps/ieee754/ldbl-opt/nldbl-isoc99_vscanf.c @@ -0,0 +1,8 @@ +#include "nldbl-compat.h" + +int +attribute_hidden +__isoc99_vscanf (const char *fmt, va_list ap) +{ + return __nldbl___isoc99_vfscanf (stdin, fmt, ap); +} diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-isoc99_vsscanf.c b/sysdeps/ieee754/ldbl-opt/nldbl-isoc99_vsscanf.c new file mode 100644 index 0000000000..0c19032b15 --- /dev/null +++ b/sysdeps/ieee754/ldbl-opt/nldbl-isoc99_vsscanf.c @@ -0,0 +1,8 @@ +#include "nldbl-compat.h" + +int +attribute_hidden +__isoc99_vsscanf (const char *string, const char *fmt, va_list ap) +{ + return __nldbl___isoc99_vsscanf (string, fmt, ap); +} diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-isoc99_vswscanf.c b/sysdeps/ieee754/ldbl-opt/nldbl-isoc99_vswscanf.c new file mode 100644 index 0000000000..5f34221b62 --- /dev/null +++ b/sysdeps/ieee754/ldbl-opt/nldbl-isoc99_vswscanf.c @@ -0,0 +1,8 @@ +#include "nldbl-compat.h" + +int +attribute_hidden +__isoc99_vswscanf (const wchar_t *string, const wchar_t *fmt, va_list ap) +{ + return __nldbl___isoc99_vswscanf (string, fmt, ap); +} diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-isoc99_vwscanf.c b/sysdeps/ieee754/ldbl-opt/nldbl-isoc99_vwscanf.c new file mode 100644 index 0000000000..a8a76ff54b --- /dev/null +++ b/sysdeps/ieee754/ldbl-opt/nldbl-isoc99_vwscanf.c @@ -0,0 +1,8 @@ +#include "nldbl-compat.h" + +int +attribute_hidden +__isoc99_vwscanf (const wchar_t *fmt, va_list ap) +{ + return __nldbl___isoc99_vfwscanf (stdin, fmt, ap); +} diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-isoc99_wscanf.c b/sysdeps/ieee754/ldbl-opt/nldbl-isoc99_wscanf.c new file mode 100644 index 0000000000..fc2f6f8598 --- /dev/null +++ b/sysdeps/ieee754/ldbl-opt/nldbl-isoc99_wscanf.c @@ -0,0 +1,15 @@ +#include "nldbl-compat.h" + +int +attribute_hidden +__isoc99_wscanf (const wchar_t *fmt, ...) +{ + va_list arg; + int done; + + va_start (arg, fmt); + done = __nldbl___isoc99_vfwscanf (stdin, fmt, arg); + va_end (arg); + + return done; +} diff --git a/wcsmbs/Makefile b/wcsmbs/Makefile index 7a289a8dc7..4afbc4cac4 100644 --- a/wcsmbs/Makefile +++ b/wcsmbs/Makefile @@ -1,4 +1,4 @@ -# Copyright (C) 1995-2000,2002,2003,2004,2005,2006 +# Copyright (C) 1995-2000,2002,2003,2004,2005,2006,2007 # Free Software Foundation, Inc. # This file is part of the GNU C Library. @@ -38,7 +38,9 @@ routines := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \ wcwidth wcswidth \ wcscoll_l wcsxfrm_l \ wcscasecmp wcsncase wcscasecmp_l wcsncase_l \ - wcsmbsload mbsrtowcs_l + wcsmbsload mbsrtowcs_l \ + isoc99_wscanf isoc99_vwscanf isoc99_fwscanf isoc99_vfwscanf \ + isoc99_swscanf isoc99_vswscanf tests := tst-wcstof wcsmbs-tst1 tst-wcsnlen tst-btowc tst-mbrtowc \ tst-wcrtomb tst-wcpncpy tst-mbsrtowcs tst-wchar-h tst-mbrtowc2 @@ -65,6 +67,14 @@ CFLAGS-wcstold_l.c = $(strtox-CFLAGS) CFLAGS-wcstof_l.c = $(strtox-CFLAGS) CFLAGS-tst-wchar-h.c = -D_FORTIFY_SOURCE=2 +CFLAGS-isoc99_wscanf.c += $(exceptions) +CFLAGS-isoc99_fwscanf.c += $(exceptions) +CFLAGS-isoc99_vwscanf.c += $(exceptions) +CFLAGS-isoc99_vfwscanf.c += $(exceptions) +ifneq (,$(filter %REENTRANT, $(defines))) +CPPFLAGS += -D_IO_MTSAFE_IO +endif + # We need to find the default version of strtold_l in stdlib. CPPFLAGS-wcstold_l.c = -I../stdlib diff --git a/wcsmbs/Versions b/wcsmbs/Versions index 6f2e72eb2a..b6dfa85a40 100644 --- a/wcsmbs/Versions +++ b/wcsmbs/Versions @@ -24,4 +24,8 @@ libc { # w* wcschrnul; wmempcpy; } + GLIBC_2.7 { + __isoc99_wscanf; __isoc99_vwscanf; __isoc99_fwscanf; __isoc99_vfwscanf; + __isoc99_swscanf; __isoc99_vswscanf; + } } diff --git a/wcsmbs/bits/wchar-ldbl.h b/wcsmbs/bits/wchar-ldbl.h index f398aecc65..80a6a684ab 100644 --- a/wcsmbs/bits/wchar-ldbl.h +++ b/wcsmbs/bits/wchar-ldbl.h @@ -21,7 +21,7 @@ # error "Never include <bits/wchar-ldbl.h> directly; use <wchar.h> instead." #endif -#if defined __USE_ISOC99 || defined __USE_UNIX98 +#if defined __USE_ISOC95 || defined __USE_UNIX98 __BEGIN_NAMESPACE_C99 __LDBL_REDIR_DECL (fwprintf); __LDBL_REDIR_DECL (wprintf); @@ -29,18 +29,33 @@ __LDBL_REDIR_DECL (swprintf); __LDBL_REDIR_DECL (vfwprintf); __LDBL_REDIR_DECL (vwprintf); __LDBL_REDIR_DECL (vswprintf); +# if defined __USE_ISOC99 && !defined __USE_GNU \ + && !defined __REDIRECT \ + && (defined __STRICT_ANSI__ || defined __USE_XOPEN2K) +__LDBL_REDIR1_DECL (fwscanf, __nldbl___isoc99_fwscanf) +__LDBL_REDIR1_DECL (wscanf, __nldbl___isoc99_wscanf) +__LDBL_REDIR1_DECL (swscanf, __nldbl___isoc99_swscanf) +# else __LDBL_REDIR_DECL (fwscanf); __LDBL_REDIR_DECL (wscanf); __LDBL_REDIR_DECL (swscanf); +# endif __END_NAMESPACE_C99 #endif #ifdef __USE_ISOC99 __BEGIN_NAMESPACE_C99 __LDBL_REDIR1_DECL (wcstold, wcstod); +# if !defined __USE_GNU && !defined __REDIRECT \ + && (defined __STRICT_ANSI__ || defined __USE_XOPEN2K) +__LDBL_REDIR1_DECL (vfwscanf, __nldbl___isoc99_vfwscanf) +__LDBL_REDIR1_DECL (vwscanf, __nldbl___isoc99_vwscanf) +__LDBL_REDIR1_DECL (vswscanf, __nldbl___isoc99_vswscanf) +# else __LDBL_REDIR_DECL (vfwscanf); __LDBL_REDIR_DECL (vwscanf); __LDBL_REDIR_DECL (vswscanf); +# endif __END_NAMESPACE_C99 #endif diff --git a/wcsmbs/isoc99_fwscanf.c b/wcsmbs/isoc99_fwscanf.c new file mode 100644 index 0000000000..ce12ad8f90 --- /dev/null +++ b/wcsmbs/isoc99_fwscanf.c @@ -0,0 +1,41 @@ +/* Copyright (C) 1991, 1997, 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 + 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 <libioP.h> +#include <stdarg.h> +#include <stdio.h> +#include <wchar.h> + +/* Read formatted input from STREAM according to the format string FORMAT. */ +/* VARARGS2 */ +int +__isoc99_fwscanf (FILE *stream, const wchar_t *format, ...) +{ + va_list arg; + int done; + + _IO_acquire_lock_clear_flags2 (stream); + stream->_flags2 |= _IO_FLAGS2_SCANF_STD; + + va_start (arg, format); + done = _IO_vfwscanf (stream, format, arg, NULL); + va_end (arg); + + _IO_release_lock (stream); + return done; +} diff --git a/wcsmbs/isoc99_swscanf.c b/wcsmbs/isoc99_swscanf.c new file mode 100644 index 0000000000..fed05eff35 --- /dev/null +++ b/wcsmbs/isoc99_swscanf.c @@ -0,0 +1,38 @@ +/* Copyright (C) 1991, 1995, 1996, 1998, 2002, 2003, 2004, 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 + 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 <stdarg.h> +#include <stdio.h> +#include <libioP.h> +#include <wchar.h> + +/* Read formatted input from S, according to the format string FORMAT. */ +/* VARARGS2 */ +int +__isoc99_swscanf (const wchar_t *s, const wchar_t *format, ...) +{ + va_list arg; + int done; + + va_start (arg, format); + done = __isoc99_vswscanf (s, format, arg); + va_end (arg); + + return done; +} diff --git a/wcsmbs/isoc99_vfwscanf.c b/wcsmbs/isoc99_vfwscanf.c new file mode 100644 index 0000000000..7564503e88 --- /dev/null +++ b/wcsmbs/isoc99_vfwscanf.c @@ -0,0 +1,36 @@ +/* Copyright (C) 1991, 1997, 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 + 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 <libioP.h> +#include <stdio.h> +#include <wchar.h> + +/* Read formatted input from STREAM according to the format string FORMAT. */ +/* VARARGS2 */ +int +__isoc99_vfwscanf (FILE *stream, const wchar_t *format, _IO_va_list args) +{ + int done; + + _IO_acquire_lock_clear_flags2 (stream); + stream->_flags2 |= _IO_FLAGS2_SCANF_STD; + done = _IO_vfwscanf (stream, format, args, NULL); + _IO_release_lock (stream); + return done; +} +libc_hidden_def (__isoc99_vfwscanf) diff --git a/wcsmbs/isoc99_vswscanf.c b/wcsmbs/isoc99_vswscanf.c new file mode 100644 index 0000000000..4d7081e43d --- /dev/null +++ b/wcsmbs/isoc99_vswscanf.c @@ -0,0 +1,49 @@ +/* Copyright (C) 1993, 1997-2003, 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 + 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. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include <libioP.h> +#include <wchar.h> +#include "../libio/strfile.h" + +int +__isoc99_vswscanf (const wchar_t *string, const wchar_t *format, + _IO_va_list args) +{ + int ret; + _IO_strfile sf; + struct _IO_wide_data wd; +#ifdef _IO_MTSAFE_IO + sf._sbf._f._lock = NULL; +#endif + _IO_no_init (&sf._sbf._f, _IO_USER_LOCK, 0, &wd, &_IO_wstr_jumps); + _IO_fwide (&sf._sbf._f, 1); + _IO_wstr_init_static (&sf._sbf._f, (wchar_t *)string, 0, NULL); + sf._sbf._f._flags2 |= _IO_FLAGS2_SCANF_STD; + ret = _IO_vfwscanf ((_IO_FILE *) &sf._sbf, format, args, NULL); + return ret; +} +libc_hidden_def (__isoc99_vswscanf) diff --git a/wcsmbs/isoc99_vwscanf.c b/wcsmbs/isoc99_vwscanf.c new file mode 100644 index 0000000000..8a0b345f05 --- /dev/null +++ b/wcsmbs/isoc99_vwscanf.c @@ -0,0 +1,35 @@ +/* Copyright (C) 1991, 1997, 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 + 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 <libioP.h> +#include <stdio.h> +#include <wchar.h> + +/* Read formatted input from STDIN according to the format string FORMAT. */ +/* VARARGS2 */ +int +__isoc99_vwscanf (const wchar_t *format, _IO_va_list args) +{ + int done; + + _IO_acquire_lock_clear_flags2 (stdin); + stdin->_flags2 |= _IO_FLAGS2_SCANF_STD; + done = _IO_vfwscanf (stdin, format, args, NULL); + _IO_release_lock (stdin); + return done; +} diff --git a/wcsmbs/isoc99_wscanf.c b/wcsmbs/isoc99_wscanf.c new file mode 100644 index 0000000000..581e05fefb --- /dev/null +++ b/wcsmbs/isoc99_wscanf.c @@ -0,0 +1,43 @@ +/* Copyright (C) 1991, 1995, 1996, 1997, 2002, 2004, 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 + 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 <stdarg.h> +#include <stdio.h> +#include <libioP.h> +#include <wchar.h> + + +/* Read formatted input from stdin according to the format string FORMAT. */ +/* VARARGS1 */ +int +__isoc99_wscanf (const wchar_t *format, ...) +{ + va_list arg; + int done; + + _IO_acquire_lock_clear_flags2 (stdin); + stdin->_flags2 |= _IO_FLAGS2_SCANF_STD; + + va_start (arg, format); + done = _IO_vfwscanf (stdin, format, arg, NULL); + va_end (arg); + + _IO_release_lock (stdin); + return done; +} diff --git a/wcsmbs/wchar.h b/wcsmbs/wchar.h index 8deaddab97..e8448c86d9 100644 --- a/wcsmbs/wchar.h +++ b/wcsmbs/wchar.h @@ -587,12 +587,42 @@ extern int swscanf (__const wchar_t *__restrict __s, __const wchar_t *__restrict __format, ...) __THROW /* __attribute__ ((__format__ (__wscanf__, 2, 3))) */; +# if defined __USE_ISOC99 && !defined __USE_GNU \ + && (!defined __LDBL_COMPAT || !defined __REDIRECT) \ + && (defined __STRICT_ANSI__ || defined __USE_XOPEN2K) +# ifdef __REDIRECT +/* For strict ISO C99 or POSIX compliance disallow %as, %aS and %a[ + GNU extension which conflicts with valid %a followed by letter + s, S or [. */ +extern int __REDIRECT (fwscanf, (__FILE *__restrict __stream, + __const wchar_t *__restrict __format, ...), + __isoc99_fwscanf) + /* __attribute__ ((__format__ (__wscanf__, 2, 3))) */; +extern int __REDIRECT (wscanf, (__const wchar_t *__restrict __format, ...), + __isoc99_wscanf) + /* __attribute__ ((__format__ (__wscanf__, 1, 2))) */; +extern int __REDIRECT (swscanf, (__const wchar_t *__restrict __s, + __const wchar_t *__restrict __format, ...), + __isoc99_swscanf) + __THROW /* __attribute__ ((__format__ (__wscanf__, 2, 3))) */; +# else +extern int __isoc99_fwscanf (__FILE *__restrict __stream, + __const wchar_t *__restrict __format, ...); +extern int __isoc99_wscanf (__const wchar_t *__restrict __format, ...); +extern int __isoc99_swscanf (__const wchar_t *__restrict __s, + __const wchar_t *__restrict __format, ...) + __THROW; +# define fwscanf __isoc99_fwscanf +# define wscanf __isoc99_wscanf +# define swscanf __isoc99_swscanf +# endif +# endif + __END_NAMESPACE_C99 #endif /* Use ISO C95, C99 and Unix98. */ #ifdef __USE_ISOC99 __BEGIN_NAMESPACE_C99 - /* Read formatted input from S into argument list ARG. This function is a possible cancellation point and therefore not @@ -614,6 +644,36 @@ extern int vswscanf (__const wchar_t *__restrict __s, __gnuc_va_list __arg) __THROW /* __attribute__ ((__format__ (__wscanf__, 2, 0))) */; +# if !defined __USE_GNU \ + && (!defined __LDBL_COMPAT || !defined __REDIRECT) \ + && (defined __STRICT_ANSI__ || defined __USE_XOPEN2K) +# ifdef __REDIRECT +extern int __REDIRECT (vfwscanf, (__FILE *__restrict __s, + __const wchar_t *__restrict __format, + __gnuc_va_list __arg), __isoc99_vfwscanf) + /* __attribute__ ((__format__ (__wscanf__, 2, 0))) */; +extern int __REDIRECT (vwscanf, (__const wchar_t *__restrict __format, + __gnuc_va_list __arg), __isoc99_vwscanf) + /* __attribute__ ((__format__ (__wscanf__, 1, 0))) */; +extern int __REDIRECT (vswscanf, (__const wchar_t *__restrict __s, + __const wchar_t *__restrict __format, + __gnuc_va_list __arg), __isoc99_vswscanf) + __THROW /* __attribute__ ((__format__ (__wscanf__, 2, 0))) */; +# else +extern int __isoc99_vfwscanf (__FILE *__restrict __s, + __const wchar_t *__restrict __format, + __gnuc_va_list __arg); +extern int __isoc99_vwscanf (__const wchar_t *__restrict __format, + __gnuc_va_list __arg); +extern int __isoc99_vswscanf (__const wchar_t *__restrict __s, + __const wchar_t *__restrict __format, + __gnuc_va_list __arg) __THROW; +# define vfwscanf __isoc99_vfwscanf +# define vwscanf __isoc99_vwscanf +# define vswscanf __isoc99_vswscanf +# endif +# endif + __END_NAMESPACE_C99 #endif /* Use ISO C99. */ |