From deab9deadc372fe1a367aef2e78c0d8f2885bf23 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Tue, 17 Oct 1995 00:41:39 +0000 Subject: * Makefile (subdirs): Replace stdio with stdio-common and $(stdio). * configure.in: Grok arg --enable-libio. ($stdio = libio): Define USE_IN_LIBIO. * config.h.in (USE_IN_LIBIO): Add #undef. * config.make.in (stdio): New variable, set by configure. * Makeconfig (stdio): New variable. * stdio.h [USE_IN_LIBIO]: Include libio/stdio.h instead of stdio/stdio.h. * stdio-common/Makefile: New file. * stdio/Makefile: Half the contents moved to stdio-common/Makefile. * stdio/_itoa.c: Moved to stdio-common. * stdio/_itoa.h: Moved to stdio-common. * stdio/asprintf.c: Moved to stdio-common. * stdio/bug1.c: Moved to stdio-common. * stdio/bug1.input: Moved to stdio-common. * stdio/bug2.c: Moved to stdio-common. * stdio/bug3.c: Moved to stdio-common. * stdio/bug4.c: Moved to stdio-common. * stdio/bug5.c: Moved to stdio-common. * stdio/bug6.c: Moved to stdio-common. * stdio/bug6.input: Moved to stdio-common. * stdio/bug7.c: Moved to stdio-common. * stdio/dprintf.c: Moved to stdio-common. * stdio/errnobug.c: Moved to stdio-common. * stdio/getline.c: Moved to stdio-common. * stdio/getw.c: Moved to stdio-common. * stdio/perror.c: Moved to stdio-common. * stdio/printf-parse.h: Moved to stdio-common. * stdio/printf-prs.c: Moved to stdio-common. * stdio/printf.c: Moved to stdio-common. * stdio/printf.h: Moved to stdio-common. * stdio/printf_fp.c: Moved to stdio-common. * stdio/psignal.c: Moved to stdio-common. * stdio/putw.c: Moved to stdio-common. * stdio/reg-printf.c: Moved to stdio-common. * stdio/scanf.c: Moved to stdio-common. * stdio/snprintf.c: Moved to stdio-common. * stdio/sprintf.c: Moved to stdio-common. * stdio/sscanf.c: Moved to stdio-common. * stdio/tempnam.c: Moved to stdio-common. * stdio/temptest.c: Moved to stdio-common. * stdio/test-fseek.c: Moved to stdio-common. * stdio/test-fwrite.c: Moved to stdio-common. * stdio/test-popen.c: Moved to stdio-common. * stdio/test_rdwr.c: Moved to stdio-common. * stdio/tmpfile.c: Moved to stdio-common. * stdio/tmpnam.c: Moved to stdio-common. * stdio/tst-fileno.c: Moved to stdio-common. * stdio/tst-printf.c: Moved to stdio-common. * stdio/tstgetln.c: Moved to stdio-common. * stdio/tstgetln.input: Moved to stdio-common. * stdio/tstscanf.c: Moved to stdio-common. * stdio/tstscanf.input: Moved to stdio-common. * stdio/vfprintf.c: Moved to stdio-common. * stdio/vfscanf.c: Moved to stdio-common. * stdio/vprintf.c: Moved to stdio-common. * stdio/xbug.c: Moved to stdio-common. * sysdeps/generic/Makefile (siglist.c rules): Do this in subdir stdio-common instead of stdio. * sysdeps/unix/Makefile (errlist.c rules): Likewise. * stdio-common/asprintf.c [USE_IN_LIBIO]: Call libio primitive function. * stdio-common/dprintf.c: Likewise. * stdio-common/printf.c: Likewise. * stdio-common/scanf.c: Likewise. * stdio-common/snprintf.c: Likewise. * stdio-common/sprintf.c: Likewise. * stdio-common/sscanf.c: Likewise. * stdio-common/vprintf.c: Likewise. * Makerules: Include $(+depfiles) directly instead of generating depend-$(subdir). (depend-$(subdir)): Target removed. (common-clean): Don't remove depend-$(subdir). --- ChangeLog | 75 ++++ Makeconfig | 6 + Makefile | 8 +- Makerules | 16 +- config.h.in | 4 + config.make.in | 1 + configure.in | 8 + stdio-common/Makefile | 47 +++ stdio-common/_itoa.c | 418 +++++++++++++++++++ stdio-common/_itoa.h | 32 ++ stdio-common/asprintf.c | 42 ++ stdio-common/bug1.c | 28 ++ stdio-common/bug1.input | 1 + stdio-common/bug2.c | 12 + stdio-common/bug3.c | 52 +++ stdio-common/bug4.c | 50 +++ stdio-common/bug5.c | 60 +++ stdio-common/bug6.c | 27 ++ stdio-common/bug6.input | 1 + stdio-common/bug7.c | 53 +++ stdio-common/dprintf.c | 41 ++ stdio-common/errnobug.c | 60 +++ stdio-common/fprintf.c | 38 ++ stdio-common/fscanf.c | 38 ++ stdio-common/getline.c | 33 ++ stdio-common/getw.c | 33 ++ stdio-common/perror.c | 42 ++ stdio-common/printf-parse.h | 388 +++++++++++++++++ stdio-common/printf-prs.c | 72 ++++ stdio-common/printf.c | 40 ++ stdio-common/printf.h | 124 ++++++ stdio-common/printf_fp.c | 990 ++++++++++++++++++++++++++++++++++++++++++++ stdio-common/psignal.c | 49 +++ stdio-common/putw.c | 31 ++ stdio-common/reg-printf.c | 47 +++ stdio-common/scanf.c | 40 ++ stdio-common/snprintf.c | 43 ++ stdio-common/sprintf.c | 41 ++ stdio-common/sscanf.c | 41 ++ stdio-common/tempnam.c | 50 +++ stdio-common/temptest.c | 31 ++ stdio-common/test-fseek.c | 67 +++ stdio-common/test-fwrite.c | 68 +++ stdio-common/test-popen.c | 67 +++ stdio-common/test_rdwr.c | 130 ++++++ stdio-common/tmpfile.c | 43 ++ stdio-common/tmpnam.c | 42 ++ stdio-common/tst-fileno.c | 37 ++ stdio-common/tst-printf.c | 298 +++++++++++++ stdio-common/tstgetln.c | 46 ++ stdio-common/tstgetln.input | 3 + stdio-common/tstscanf.c | 100 +++++ stdio-common/tstscanf.input | 7 + stdio-common/vasprintf.c | 86 ++++ stdio-common/vdprintf.c | 51 +++ stdio-common/vfprintf.c | 858 ++++++++++++++++++++++++++++++++++++++ stdio-common/vfscanf.c | 624 ++++++++++++++++++++++++++++ stdio-common/vprintf.c | 37 ++ stdio-common/vscanf.c | 32 ++ stdio-common/vsnprintf.c | 56 +++ stdio-common/vsprintf.c | 50 +++ stdio-common/vsscanf.c | 58 +++ stdio-common/xbug.c | 63 +++ stdio.h | 4 + stdio/Makefile | 26 +- stdio/_itoa.c | 418 ------------------- stdio/_itoa.h | 32 -- stdio/asprintf.c | 39 -- stdio/bug1.c | 28 -- stdio/bug1.input | 1 - stdio/bug2.c | 12 - stdio/bug3.c | 52 --- stdio/bug4.c | 50 --- stdio/bug5.c | 60 --- stdio/bug6.c | 27 -- stdio/bug6.input | 1 - stdio/bug7.c | 53 --- stdio/dprintf.c | 37 -- stdio/errnobug.c | 60 --- stdio/fprintf.c | 38 -- stdio/fscanf.c | 38 -- stdio/getline.c | 33 -- stdio/getw.c | 33 -- stdio/perror.c | 42 -- stdio/printf-parse.h | 388 ----------------- stdio/printf-prs.c | 72 ---- stdio/printf.c | 37 -- stdio/printf.h | 124 ------ stdio/printf_fp.c | 990 -------------------------------------------- stdio/psignal.c | 49 --- stdio/putw.c | 31 -- stdio/reg-printf.c | 47 --- stdio/scanf.c | 37 -- stdio/snprintf.c | 39 -- stdio/sprintf.c | 37 -- stdio/sscanf.c | 37 -- stdio/tempnam.c | 50 --- stdio/temptest.c | 31 -- stdio/test-fseek.c | 67 --- stdio/test-fwrite.c | 68 --- stdio/test-popen.c | 67 --- stdio/test_rdwr.c | 130 ------ stdio/tmpfile.c | 43 -- stdio/tmpnam.c | 42 -- stdio/tst-fileno.c | 37 -- stdio/tst-printf.c | 298 ------------- stdio/tstgetln.c | 46 -- stdio/tstgetln.input | 3 - stdio/tstscanf.c | 100 ----- stdio/tstscanf.input | 7 - stdio/vasprintf.c | 86 ---- stdio/vdprintf.c | 51 --- stdio/vfprintf.c | 858 -------------------------------------- stdio/vfscanf.c | 624 ---------------------------- stdio/vprintf.c | 33 -- stdio/vscanf.c | 32 -- stdio/vsnprintf.c | 56 --- stdio/vsprintf.c | 50 --- stdio/vsscanf.c | 58 --- stdio/xbug.c | 63 --- sysdeps/generic/Makefile | 4 +- 121 files changed, 6030 insertions(+), 5882 deletions(-) create mode 100644 stdio-common/Makefile create mode 100644 stdio-common/_itoa.c create mode 100644 stdio-common/_itoa.h create mode 100644 stdio-common/asprintf.c create mode 100644 stdio-common/bug1.c create mode 100644 stdio-common/bug1.input create mode 100644 stdio-common/bug2.c create mode 100644 stdio-common/bug3.c create mode 100644 stdio-common/bug4.c create mode 100644 stdio-common/bug5.c create mode 100644 stdio-common/bug6.c create mode 100644 stdio-common/bug6.input create mode 100644 stdio-common/bug7.c create mode 100644 stdio-common/dprintf.c create mode 100644 stdio-common/errnobug.c create mode 100644 stdio-common/fprintf.c create mode 100644 stdio-common/fscanf.c create mode 100644 stdio-common/getline.c create mode 100644 stdio-common/getw.c create mode 100644 stdio-common/perror.c create mode 100644 stdio-common/printf-parse.h create mode 100644 stdio-common/printf-prs.c create mode 100644 stdio-common/printf.c create mode 100644 stdio-common/printf.h create mode 100644 stdio-common/printf_fp.c create mode 100644 stdio-common/psignal.c create mode 100644 stdio-common/putw.c create mode 100644 stdio-common/reg-printf.c create mode 100644 stdio-common/scanf.c create mode 100644 stdio-common/snprintf.c create mode 100644 stdio-common/sprintf.c create mode 100644 stdio-common/sscanf.c create mode 100644 stdio-common/tempnam.c create mode 100644 stdio-common/temptest.c create mode 100644 stdio-common/test-fseek.c create mode 100644 stdio-common/test-fwrite.c create mode 100644 stdio-common/test-popen.c create mode 100644 stdio-common/test_rdwr.c create mode 100644 stdio-common/tmpfile.c create mode 100644 stdio-common/tmpnam.c create mode 100644 stdio-common/tst-fileno.c create mode 100644 stdio-common/tst-printf.c create mode 100644 stdio-common/tstgetln.c create mode 100644 stdio-common/tstgetln.input create mode 100644 stdio-common/tstscanf.c create mode 100644 stdio-common/tstscanf.input create mode 100644 stdio-common/vasprintf.c create mode 100644 stdio-common/vdprintf.c create mode 100644 stdio-common/vfprintf.c create mode 100644 stdio-common/vfscanf.c create mode 100644 stdio-common/vprintf.c create mode 100644 stdio-common/vscanf.c create mode 100644 stdio-common/vsnprintf.c create mode 100644 stdio-common/vsprintf.c create mode 100644 stdio-common/vsscanf.c create mode 100644 stdio-common/xbug.c delete mode 100644 stdio/_itoa.c delete mode 100644 stdio/_itoa.h delete mode 100644 stdio/asprintf.c delete mode 100644 stdio/bug1.c delete mode 100644 stdio/bug1.input delete mode 100644 stdio/bug2.c delete mode 100644 stdio/bug3.c delete mode 100644 stdio/bug4.c delete mode 100644 stdio/bug5.c delete mode 100644 stdio/bug6.c delete mode 100644 stdio/bug6.input delete mode 100644 stdio/bug7.c delete mode 100644 stdio/dprintf.c delete mode 100644 stdio/errnobug.c delete mode 100644 stdio/fprintf.c delete mode 100644 stdio/fscanf.c delete mode 100644 stdio/getline.c delete mode 100644 stdio/getw.c delete mode 100644 stdio/perror.c delete mode 100644 stdio/printf-parse.h delete mode 100644 stdio/printf-prs.c delete mode 100644 stdio/printf.c delete mode 100644 stdio/printf.h delete mode 100644 stdio/printf_fp.c delete mode 100644 stdio/psignal.c delete mode 100644 stdio/putw.c delete mode 100644 stdio/reg-printf.c delete mode 100644 stdio/scanf.c delete mode 100644 stdio/snprintf.c delete mode 100644 stdio/sprintf.c delete mode 100644 stdio/sscanf.c delete mode 100644 stdio/tempnam.c delete mode 100644 stdio/temptest.c delete mode 100644 stdio/test-fseek.c delete mode 100644 stdio/test-fwrite.c delete mode 100644 stdio/test-popen.c delete mode 100644 stdio/test_rdwr.c delete mode 100644 stdio/tmpfile.c delete mode 100644 stdio/tmpnam.c delete mode 100644 stdio/tst-fileno.c delete mode 100644 stdio/tst-printf.c delete mode 100644 stdio/tstgetln.c delete mode 100644 stdio/tstgetln.input delete mode 100644 stdio/tstscanf.c delete mode 100644 stdio/tstscanf.input delete mode 100644 stdio/vasprintf.c delete mode 100644 stdio/vdprintf.c delete mode 100644 stdio/vfprintf.c delete mode 100644 stdio/vfscanf.c delete mode 100644 stdio/vprintf.c delete mode 100644 stdio/vscanf.c delete mode 100644 stdio/vsnprintf.c delete mode 100644 stdio/vsprintf.c delete mode 100644 stdio/vsscanf.c delete mode 100644 stdio/xbug.c diff --git a/ChangeLog b/ChangeLog index 610def7e75..5e0887b88a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,80 @@ Mon Oct 16 03:22:37 1995 Roland McGrath + * Makefile (subdirs): Replace stdio with stdio-common and $(stdio). + * configure.in: Grok arg --enable-libio. + ($stdio = libio): Define USE_IN_LIBIO. + * config.h.in (USE_IN_LIBIO): Add #undef. + * config.make.in (stdio): New variable, set by configure. + * Makeconfig (stdio): New variable. + * stdio.h [USE_IN_LIBIO]: Include libio/stdio.h instead of + stdio/stdio.h. + * stdio-common/Makefile: New file. + * stdio/Makefile: Half the contents moved to stdio-common/Makefile. + * stdio/_itoa.c: Moved to stdio-common. + * stdio/_itoa.h: Moved to stdio-common. + * stdio/asprintf.c: Moved to stdio-common. + * stdio/bug1.c: Moved to stdio-common. + * stdio/bug1.input: Moved to stdio-common. + * stdio/bug2.c: Moved to stdio-common. + * stdio/bug3.c: Moved to stdio-common. + * stdio/bug4.c: Moved to stdio-common. + * stdio/bug5.c: Moved to stdio-common. + * stdio/bug6.c: Moved to stdio-common. + * stdio/bug6.input: Moved to stdio-common. + * stdio/bug7.c: Moved to stdio-common. + * stdio/dprintf.c: Moved to stdio-common. + * stdio/errnobug.c: Moved to stdio-common. + * stdio/getline.c: Moved to stdio-common. + * stdio/getw.c: Moved to stdio-common. + * stdio/perror.c: Moved to stdio-common. + * stdio/printf-parse.h: Moved to stdio-common. + * stdio/printf-prs.c: Moved to stdio-common. + * stdio/printf.c: Moved to stdio-common. + * stdio/printf.h: Moved to stdio-common. + * stdio/printf_fp.c: Moved to stdio-common. + * stdio/psignal.c: Moved to stdio-common. + * stdio/putw.c: Moved to stdio-common. + * stdio/reg-printf.c: Moved to stdio-common. + * stdio/scanf.c: Moved to stdio-common. + * stdio/snprintf.c: Moved to stdio-common. + * stdio/sprintf.c: Moved to stdio-common. + * stdio/sscanf.c: Moved to stdio-common. + * stdio/tempnam.c: Moved to stdio-common. + * stdio/temptest.c: Moved to stdio-common. + * stdio/test-fseek.c: Moved to stdio-common. + * stdio/test-fwrite.c: Moved to stdio-common. + * stdio/test-popen.c: Moved to stdio-common. + * stdio/test_rdwr.c: Moved to stdio-common. + * stdio/tmpfile.c: Moved to stdio-common. + * stdio/tmpnam.c: Moved to stdio-common. + * stdio/tst-fileno.c: Moved to stdio-common. + * stdio/tst-printf.c: Moved to stdio-common. + * stdio/tstgetln.c: Moved to stdio-common. + * stdio/tstgetln.input: Moved to stdio-common. + * stdio/tstscanf.c: Moved to stdio-common. + * stdio/tstscanf.input: Moved to stdio-common. + * stdio/vfprintf.c: Moved to stdio-common. + * stdio/vfscanf.c: Moved to stdio-common. + * stdio/vprintf.c: Moved to stdio-common. + * stdio/xbug.c: Moved to stdio-common. + * sysdeps/generic/Makefile (siglist.c rules): Do this in subdir + stdio-common instead of stdio. + * sysdeps/unix/Makefile (errlist.c rules): Likewise. + * stdio-common/asprintf.c [USE_IN_LIBIO]: Call libio primitive + function. + * stdio-common/dprintf.c: Likewise. + * stdio-common/printf.c: Likewise. + * stdio-common/scanf.c: Likewise. + * stdio-common/snprintf.c: Likewise. + * stdio-common/sprintf.c: Likewise. + * stdio-common/sscanf.c: Likewise. + * stdio-common/vprintf.c: Likewise. + + * Makerules: Include $(+depfiles) directly instead of generating + depend-$(subdir). + (depend-$(subdir)): Target removed. + (common-clean): Don't remove depend-$(subdir). + * sysdeps/unix/sysv/linux/Makefile (rtld-installed-name): New variable. (config-LDFLAGS): Variable removed. diff --git a/Makeconfig b/Makeconfig index d21d7114e0..cbb2db0102 100644 --- a/Makeconfig +++ b/Makeconfig @@ -114,6 +114,12 @@ export sysdep_dir := $(sysdep_dir) #### +# Set this to either `stdio' or `libio', to compile in either GNU stdio +# or GNU libio. +ifndef stdio +stdio = stdio +endif + # Common prefix for machine-independent installation directories. ifeq ($(origin prefix),undefined) # ifndef would override explicit empty value. prefix = /usr/local diff --git a/Makefile b/Makefile index f3d5e1c2f2..f1aae8ed0b 100644 --- a/Makefile +++ b/Makefile @@ -51,10 +51,10 @@ sysdep-subdirs := $(subst $(\n), ,$(sysdep-subdirs)) endif # These are the subdirectories containing the library source. -subdirs := csu assert ctype locale intl math setjmp signal stdio stdlib \ - malloc string time dirent grp pwd posix io termios resource \ - misc socket sysvipc gmon gnulib $(wildcard crypt) manual \ - $(sysdep-subdirs) elf +subdirs = csu assert ctype locale intl math setjmp signal stdlib \ + stdio-common $(stdio) malloc string time dirent grp pwd \ + posix io termios resource misc socket sysvipc gmon gnulib \ + $(wildcard crypt) manual $(sysdep-subdirs) elf export subdirs := $(subdirs) # Benign, useless in GNU make before 3.63. # The mach and hurd subdirectories have many generated header files which diff --git a/Makerules b/Makerules index 56f8cc89e6..ac1ac39b48 100644 --- a/Makerules +++ b/Makerules @@ -301,19 +301,10 @@ endif $(filter-out $(addsuffix .d,$(omit-deps)),\ $(+depfiles))) -$(objpfx)depend-$(subdir): Makefile ifdef +depfiles - for file in $(+depfiles:$(objpfx)%=%); do \ - echo "include \$$(objpfx)$$file"; \ - done > $@-tmp - mv -f $@-tmp $@ -else - cp /dev/null $@ -endif - ifneq ($(no_deps),t) -# Include the generated dependencies of the sources in this directory. -include $(objpfx)depend-$(subdir) +include $(+depfiles) +endif endif # Maximize efficiency by minimizing the number of rules. @@ -623,8 +614,7 @@ endef # Also remove the dependencies and generated source files. common-clean: common-mostlyclean - -rm -f $(objpfx)depend-$(subdir) $(+depfiles) - -rm -f $(addprefix $(objpfx),$(generated)) + -rm -f $(addprefix $(objpfx),$(generated)) $(+depfiles) # Produce a file `stub-$(subdir)' which contains `#define __stub_FUNCTION' # for each function which is a stub. We grovel over all the .d files diff --git a/config.h.in b/config.h.in index 800fe15720..485f86170f 100644 --- a/config.h.in +++ b/config.h.in @@ -30,6 +30,10 @@ #define HAVE_WEAK_SYMBOLS #endif #endif + +/* Define to use GNU libio instead of GNU stdio. + This is defined by configure under --enable-libio. */ +#undef USE_IN_LIBIO /* */ /* These symbols might be defined by some sysdeps configures. */ diff --git a/config.make.in b/config.make.in index 69d4fcbdea..2af925da48 100644 --- a/config.make.in +++ b/config.make.in @@ -24,6 +24,7 @@ gnu-ld = @gnu_ld@ build-shared = @shared@ build-profile = @profile@ build-omitfp = @omitfp@ +stdio = @stdio@ # Build tools. CC = @CC@ diff --git a/configure.in b/configure.in index e7d4ecbb39..239e7fd874 100644 --- a/configure.in +++ b/configure.in @@ -40,6 +40,11 @@ AC_ARG_WITH(weak-symbols, dnl --with-weak-symbols if weak symbols are available in as and ld, weak=$withval, weak=no) +AC_ARG_ENABLE(libio, dnl +[ --enable-libio build in GNU libio instead of GNU stdio], + stdio=libio, stdio=stdio) +AC_SUBST(stdio) + dnl Arguments to enable or disable building the shared, profiled, and dnl -fomit-frame-pointer libraries. AC_ARG_ENABLE(shared, dnl @@ -485,6 +490,9 @@ fi AC_SUBST(profile) AC_SUBST(omitfp) +if test $stdio = libio; then + AC_DEFINE(USE_IN_LIBIO) +fi if test "`(cd $srcdir; pwd)`" = "`pwd`"; then config_makefile= diff --git a/stdio-common/Makefile b/stdio-common/Makefile new file mode 100644 index 0000000000..6ca6c7d1d3 --- /dev/null +++ b/stdio-common/Makefile @@ -0,0 +1,47 @@ +# Copyright (C) 1991, 1992, 1993, 1994, 1995 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 Library General Public License as +# published by the Free Software Foundation; either version 2 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 +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +# +# Specific makefile for stdio-common. +# +subdir := stdio-common + +headers := stdio_lim.h printf.h + +routines := \ + ctermid cuserid \ + vfprintf vprintf printf_fp reg-printf printf-prs _itoa \ + vsnprintf vsprintf vasprintf \ + fprintf printf snprintf sprintf asprintf \ + dprintf vdprintf \ + vfscanf vscanf vsscanf \ + fscanf scanf sscanf \ + perror psignal \ + tmpfile tmpnam tempnam tempname \ + getline getw putw \ + remove rename +aux := errlist siglist +distribute := _itoa.h printf-parse.h + +tests := tst-printf tstscanf test_rdwr test-popen tstgetln test-fseek \ + temptest tst-fileno test-fwrite \ + xbug errnobug \ + bug1 bug2 bug3 bug4 bug5 bug6 bug7 + + +include ../Rules diff --git a/stdio-common/_itoa.c b/stdio-common/_itoa.c new file mode 100644 index 0000000000..caa8179624 --- /dev/null +++ b/stdio-common/_itoa.c @@ -0,0 +1,418 @@ +/* Internal function for converting integers to ASCII. +Copyright (C) 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. +Contributed by Torbjorn Granlund +and Ulrich Drepper . + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include +#include "../stdlib/gmp.h" +#include "../stdlib/gmp-impl.h" +#include "../stdlib/longlong.h" + +#include "_itoa.h" + + +/* Canonize environment. For some architectures not all values might + be defined in the GMP header files. */ +#ifndef UMUL_TIME +# define UMUL_TIME 1 +#endif +#ifndef UDIV_TIME +# define UDIV_TIME 1 +#endif + +/* Control memory layout. */ +#ifdef PACK +# undef PACK +# define PACK __attribute__ ((packed)) +#else +# define PACK +#endif + + +/* Declare local types. */ +struct base_table_t +{ +#if (UDIV_TIME > 2 * UMUL_TIME) + mp_limb base_multiplier; +#endif + char flag; + char post_shift; +#if BITS_PER_MP_LIMB == 32 + struct + { + char normalization_steps; + char ndigits; + mp_limb base PACK; +#if UDIV_TIME > 2 * UMUL_TIME + mp_limb base_ninv PACK; +#endif + } big; +#endif +}; + +/* To reduce the memory needed we include some fields of the tables + only confitionally. */ +#if BITS_PER_MP_LIMB == 32 +# if UDIV_TIME > 2 * UMUL_TIME +# define SEL1(X) X, +# define SEL2(X) ,X +# else +# define SEL1(X) +# define SEL2(X) +# endif +#endif + + +/* Local variables. */ +static const struct base_table_t base_table[] = +{ +#if BITS_PER_MP_LIMB == 64 + /* 2 */ {0ul, 1, 1}, + /* 3 */ {0xaaaaaaaaaaaaaaabul, 0, 1}, + /* 4 */ {0ul, 1, 2}, + /* 5 */ {0xcccccccccccccccdul, 0, 2}, + /* 6 */ {0xaaaaaaaaaaaaaaabul, 0, 2}, + /* 7 */ {0x2492492492492493ul, 1, 3}, + /* 8 */ {0ul, 1, 3}, + /* 9 */ {0xe38e38e38e38e38ful, 0, 3}, + /* 10 */ {0xcccccccccccccccdul, 0, 3}, + /* 11 */ {0x2e8ba2e8ba2e8ba3ul, 0, 1}, + /* 12 */ {0xaaaaaaaaaaaaaaabul, 0, 3}, + /* 13 */ {0x4ec4ec4ec4ec4ec5ul, 0, 2}, + /* 14 */ {0x2492492492492493ul, 1, 4}, + /* 15 */ {0x8888888888888889ul, 0, 3}, + /* 16 */ {0ul, 1, 4}, + /* 17 */ {0xf0f0f0f0f0f0f0f1ul, 0, 4}, + /* 18 */ {0xe38e38e38e38e38ful, 0, 4}, + /* 19 */ {0xd79435e50d79435ful, 0, 4}, + /* 20 */ {0xcccccccccccccccdul, 0, 4}, + /* 21 */ {0x8618618618618619ul, 1, 5}, + /* 22 */ {0x2e8ba2e8ba2e8ba3ul, 0, 2}, + /* 23 */ {0x642c8590b21642c9ul, 1, 5}, + /* 24 */ {0xaaaaaaaaaaaaaaabul, 0, 4}, + /* 25 */ {0x47ae147ae147ae15ul, 1, 5}, + /* 26 */ {0x4ec4ec4ec4ec4ec5ul, 0, 3}, + /* 27 */ {0x97b425ed097b425ful, 0, 4}, + /* 28 */ {0x2492492492492493ul, 1, 5}, + /* 29 */ {0x1a7b9611a7b9611bul, 1, 5}, + /* 30 */ {0x8888888888888889ul, 0, 4}, + /* 31 */ {0x0842108421084211ul, 1, 5}, + /* 32 */ {0ul, 1, 5}, + /* 33 */ {0x0f83e0f83e0f83e1ul, 0, 1}, + /* 34 */ {0xf0f0f0f0f0f0f0f1ul, 0, 5}, + /* 35 */ {0xea0ea0ea0ea0ea0ful, 0, 5}, + /* 36 */ {0xe38e38e38e38e38ful, 0, 5} +#endif +#if BITS_PER_MP_LIMB == 32 + /* 2 */ {SEL1(0ul) 1, 1, {0, 31, 0x80000000ul SEL2(0xfffffffful)}}, + /* 3 */ {SEL1(0xaaaaaaabul) 0, 1, {0, 20, 0xcfd41b91ul SEL2(0x3b563c24ul)}}, + /* 4 */ {SEL1(0ul) 1, 2, {1, 15, 0x40000000ul SEL2(0xfffffffful)}}, + /* 5 */ {SEL1(0xcccccccdul) 0, 2, {1, 13, 0x48c27395ul SEL2(0xc25c2684ul)}}, + /* 6 */ {SEL1(0xaaaaaaabul) 0, 2, {0, 12, 0x81bf1000ul SEL2(0xf91bd1b6ul)}}, + /* 7 */ {SEL1(0x24924925ul) 1, 3, {1, 11, 0x75db9c97ul SEL2(0x1607a2cbul)}}, + /* 8 */ {SEL1(0ul) 1, 3, {1, 10, 0x40000000ul SEL2(0xfffffffful)}}, + /* 9 */ {SEL1(0x38e38e39ul) 0, 1, {0, 10, 0xcfd41b91ul SEL2(0x3b563c24ul)}}, + /* 10 */ {SEL1(0xcccccccdul) 0, 3, {2, 9, 0x3b9aca00ul SEL2(0x12e0be82ul)}}, + /* 11 */ {SEL1(0xba2e8ba3ul) 0, 3, {0, 9, 0x8c8b6d2bul SEL2(0xd24cde04ul)}}, + /* 12 */ {SEL1(0xaaaaaaabul) 0, 3, {3, 8, 0x19a10000ul SEL2(0x3fa39ab5ul)}}, + /* 13 */ {SEL1(0x4ec4ec4ful) 0, 2, {2, 8, 0x309f1021ul SEL2(0x50f8ac5ful)}}, + /* 14 */ {SEL1(0x24924925ul) 1, 4, {1, 8, 0x57f6c100ul SEL2(0x74843b1eul)}}, + /* 15 */ {SEL1(0x88888889ul) 0, 3, {0, 8, 0x98c29b81ul SEL2(0xad0326c2ul)}}, + /* 16 */ {SEL1(0ul) 1, 4, {3, 7, 0x10000000ul SEL2(0xfffffffful)}}, + /* 17 */ {SEL1(0xf0f0f0f1ul) 0, 4, {3, 7, 0x18754571ul SEL2(0x4ef0b6bdul)}}, + /* 18 */ {SEL1(0x38e38e39ul) 0, 2, {2, 7, 0x247dbc80ul SEL2(0xc0fc48a1ul)}}, + /* 19 */ {SEL1(0xaf286bcbul) 1, 5, {2, 7, 0x3547667bul SEL2(0x33838942ul)}}, + /* 20 */ {SEL1(0xcccccccdul) 0, 4, {1, 7, 0x4c4b4000ul SEL2(0xad7f29abul)}}, + /* 21 */ {SEL1(0x86186187ul) 1, 5, {1, 7, 0x6b5a6e1dul SEL2(0x313c3d15ul)}}, + /* 22 */ {SEL1(0xba2e8ba3ul) 0, 4, {0, 7, 0x94ace180ul SEL2(0xb8cca9e0ul)}}, + /* 23 */ {SEL1(0xb21642c9ul) 0, 4, {0, 7, 0xcaf18367ul SEL2(0x42ed6de9ul)}}, + /* 24 */ {SEL1(0xaaaaaaabul) 0, 4, {4, 6, 0x0b640000ul SEL2(0x67980e0bul)}}, + /* 25 */ {SEL1(0x51eb851ful) 0, 3, {4, 6, 0x0e8d4a51ul SEL2(0x19799812ul)}}, + /* 26 */ {SEL1(0x4ec4ec4ful) 0, 3, {3, 6, 0x1269ae40ul SEL2(0xbce85396ul)}}, + /* 27 */ {SEL1(0x2f684bdbul) 1, 5, {3, 6, 0x17179149ul SEL2(0x62c103a9ul)}}, + /* 28 */ {SEL1(0x24924925ul) 1, 5, {3, 6, 0x1cb91000ul SEL2(0x1d353d43ul)}}, + /* 29 */ {SEL1(0x8d3dcb09ul) 0, 4, {2, 6, 0x23744899ul SEL2(0xce1deceaul)}}, + /* 30 */ {SEL1(0x88888889ul) 0, 4, {2, 6, 0x2b73a840ul SEL2(0x790fc511ul)}}, + /* 31 */ {SEL1(0x08421085ul) 1, 5, {2, 6, 0x34e63b41ul SEL2(0x35b865a0ul)}}, + /* 32 */ {SEL1(0ul) 1, 5, {1, 6, 0x40000000ul SEL2(0xfffffffful)}}, + /* 33 */ {SEL1(0x3e0f83e1ul) 0, 3, {1, 6, 0x4cfa3cc1ul SEL2(0xa9aed1b3ul)}}, + /* 34 */ {SEL1(0xf0f0f0f1ul) 0, 5, {1, 6, 0x5c13d840ul SEL2(0x63dfc229ul)}}, + /* 35 */ {SEL1(0xd41d41d5ul) 1, 6, {1, 6, 0x6d91b519ul SEL2(0x2b0fee30ul)}}, + /* 36 */ {SEL1(0x38e38e39ul) 0, 3, {0, 6, 0x81bf1000ul SEL2(0xf91bd1b6ul)}} +#endif +}; + +/* Lower-case digits. */ +static const char _itoa_lower_digits[] + = "0123456789abcdefghijklmnopqrstuvwxyz"; +/* Upper-case digits. */ +static const char _itoa_upper_digits[] + = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + + +char * +_itoa (value, buflim, base, upper_case) + unsigned long long int value; + char *buflim; + unsigned int base; + int upper_case; +{ + const char *digits = upper_case ? _itoa_upper_digits : _itoa_lower_digits; + char *bp = buflim; + const struct base_table_t *brec = &base_table[base - 2]; + + switch (base) + { +#define RUN_2N(BITS) \ + do \ + { \ + /* `unsigned long long int' always has 64 bits. */ \ + mp_limb work_hi = value >> (64 - BITS_PER_MP_LIMB); \ + \ + if (BITS_PER_MP_LIMB == 32) \ + if (work_hi != 0) \ + { \ + mp_limb work_lo; \ + int cnt; \ + \ + work_lo = value & 0xfffffffful; \ + for (cnt = BITS_PER_MP_LIMB / BITS; cnt > 0; --cnt) \ + { \ + *--bp = digits[work_lo & ((1ul << BITS) - 1)]; \ + work_lo >>= BITS; \ + } \ + if (BITS_PER_MP_LIMB % BITS != 0) \ + { \ + work_lo |= ((work_hi \ + & ((1 << BITS - BITS_PER_MP_LIMB % BITS) \ + - 1)) \ + << BITS_PER_MP_LIMB % BITS); \ + *--bp = digits[work_lo]; \ + work_hi >>= BITS - BITS_PER_MP_LIMB % BITS; \ + } \ + } \ + else \ + work_hi = value & 0xfffffffful; \ + do \ + { \ + *--bp = digits[work_hi & ((1 << BITS) - 1)]; \ + work_hi >>= BITS; \ + } \ + while (work_hi != 0); \ + } \ + while (0) + case 8: + RUN_2N (3); + break; + + case 16: + RUN_2N (4); + break; + + default: + { +#if BITS_PER_MP_LIMB == 64 + mp_limb base_multiplier = brec->base_multiplier; + if (brec->flag) + while (value != 0) + { + mp_limb quo, rem, x, dummy; + + umul_ppmm (x, dummy, value, base_multiplier); + quo = (x + ((value - x) >> 1)) >> (brec->post_shift - 1); + rem = value - quo * base; + *--bp = digits[rem]; + value = quo; + } + else + while (value != 0) + { + mp_limb quo, rem, x, dummy; + + umul_ppmm (x, dummy, value, base_multiplier); + quo = x >> brec->post_shift; + rem = value - quo * base; + *--bp = digits[rem]; + value = quo; + } +#endif +#if BITS_PER_MP_LIMB == 32 + mp_limb t[3]; + int n; + + /* First convert x0 to 1-3 words in base s->big.base. + Optimize for frequent cases of 32 bit numbers. */ + if ((mp_limb) (value >> 32) >= 1) + { + int big_normalization_steps = brec->big.normalization_steps; + mp_limb big_base_norm = brec->big.base << big_normalization_steps; + + if ((mp_limb) (value >> 32) >= brec->big.base) + { + mp_limb x1hi, x1lo, r; + /* If you want to optimize this, take advantage of + that the quotient in the first udiv_qrnnd will + always be very small. It might be faster just to + subtract in a tight loop. */ + +#if UDIV_TIME > 2 * UMUL_TIME + mp_limb x, xh, xl; + + if (big_normalization_steps == 0) + xh = 0; + else + xh = (mp_limb) (value >> 64 - big_normalization_steps); + xl = (mp_limb) (value >> 32 - big_normalization_steps); + udiv_qrnnd_preinv (x1hi, r, xh, xl, big_base_norm, + brec->big.base_ninv); + + xl = ((mp_limb) value) << big_normalization_steps; + udiv_qrnnd_preinv (x1lo, x, r, xl, big_base_norm, + big_normalization_steps); + t[2] = x >> big_normalization_steps; + + if (big_normalization_steps == 0) + xh = x1hi; + else + xh = ((x1hi << big_normalization_steps) + | (x1lo >> 32 - big_normalization_steps)); + xl = x1lo << big_normalization_steps; + udiv_qrnnd_preinv (t[0], x, xh, xl, big_base_norm, + big_normalization_steps); + t[1] = x >> big_normalization_steps; +#elif UDIV_NEEDS_NORMALIZATION + mp_limb x, xh, xl; + + if (big_normalization_steps == 0) + xh = 0; + else + xh = (mp_limb) (value >> 64 - big_normalization_steps); + xl = (mp_limb) (value >> 32 - big_normalization_steps); + udiv_qrnnd (x1hi, r, xh, xl, big_base_norm); + + xl = ((mp_limb) value) << big_normalization_steps; + udiv_qrnnd (x1lo, x, r, xl, big_base_norm); + t[2] = x >> big_normalization_steps; + + if (big_normalization_steps == 0) + xh = x1hi; + else + xh = ((x1hi << big_normalization_steps) + | (x1lo >> 32 - big_normalization_steps)); + xl = x1lo << big_normalization_steps; + udiv_qrnnd (t[0], x, xh, xl, big_base_norm); + t[1] = x >> big_normalization_steps; +#else + udiv_qrnnd (x1hi, r, 0, (mp_limb) (value >> 32), + brec->big.base); + udiv_qrnnd (x1lo, t[2], r, (mp_limb) value, brec->big.base); + udiv_qrnnd (t[0], t[1], x1hi, x1lo, brec->big.base); +#endif + n = 3; + } + else + { +#if (UDIV_TIME > 2 * UMUL_TIME) + mp_limb x; + + value <<= brec->big.normalization_steps; + udiv_qrnnd_preinv (t[0], x, (mp_limb) (value >> 32), + (mp_limb) value, big_base_norm, + brec->big.base_ninv); + t[1] = x >> brec->big.normalization_steps; +#elif UDIV_NEEDS_NORMALIZATION + mp_limb x; + + value <<= big_normalization_steps; + udiv_qrnnd (t[0], x, (mp_limb) (value >> 32), + (mp_limb) value, big_base_norm); + t[1] = x >> big_normalization_steps; +#else + udiv_qrnnd (t[0], t[1], (mp_limb) (value >> 32), + (mp_limb) value, brec->big.base); +#endif + n = 2; + } + } + else + { + t[0] = value; + n = 1; + } + + /* Convert the 1-3 words in t[], word by word, to ASCII. */ + do + { + mp_limb ti = t[--n]; + int ndig_for_this_limb = 0; + +#if UDIV_TIME > 2 * UMUL_TIME + mp_limb base_multiplier = brec->base_multiplier; + if (brec->flag) + while (ti != 0) + { + mp_limb quo, rem, x, dummy; + + umul_ppmm (x, dummy, ti, base_multiplier); + quo = (x + ((ti - x) >> 1)) >> (brec->post_shift - 1); + rem = ti - quo * base; + *--bp = digits[rem]; + ti = quo; + ++ndig_for_this_limb; + } + else + while (ti != 0) + { + mp_limb quo, rem, x, dummy; + + umul_ppmm (x, dummy, ti, base_multiplier); + quo = x >> brec->post_shift; + rem = ti - quo * base; + *--bp = digits[rem]; + ti = quo; + ++ndig_for_this_limb; + } +#else + while (ti != 0) + { + mp_limb quo, rem; + + quo = ti / base; + rem = ti % base; + *--bp = digits[rem]; + ti = quo; + ++ndig_for_this_limb; + } +#endif + /* If this wasn't the most significant word, pad with zeros. */ + if (n != 0) + while (ndig_for_this_limb < brec->big.ndigits) + { + *--bp = '0'; + ++ndig_for_this_limb; + } + } + while (n != 0); +#endif + } + break; + } + + return bp; +} diff --git a/stdio-common/_itoa.h b/stdio-common/_itoa.h new file mode 100644 index 0000000000..ab3d1d1d3a --- /dev/null +++ b/stdio-common/_itoa.h @@ -0,0 +1,32 @@ +/* Internal function for converting integers to ASCII. +Copyright (C) 1994, 1995 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 Library General Public License as +published by the Free Software Foundation; either version 2 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _ITOA_H +#define _ITOA_H +#include + +/* Convert VALUE into ASCII in base BASE (2..36). + Write backwards starting the character just before BUFLIM. + Return the address of the first (left-to-right) character in the number. + Use upper case letters iff UPPER_CASE is nonzero. */ + +extern char *_itoa __P ((unsigned long long int value, char *buflim, + unsigned int base, int upper_case)); + +#endif /* itoa.h */ diff --git a/stdio-common/asprintf.c b/stdio-common/asprintf.c new file mode 100644 index 0000000000..85ab7b1041 --- /dev/null +++ b/stdio-common/asprintf.c @@ -0,0 +1,42 @@ +/* Copyright (C) 1991, 1995 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 Library General Public License as +published by the Free Software Foundation; either version 2 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include +#include + +#ifdef USE_IN_LIBIO +# define vasprintf _IO_vasprintf +#endif + +/* Write formatted output from FORMAT to a string which is + allocated with malloc and stored in *STRING_PTR. */ +/* VARARGS2 */ +int +asprintf (string_ptr, format) + char **string_ptr; + const char *format; +{ + va_list arg; + int done; + + va_start (arg, format); + done = vasprintf (string_ptr, format, arg); + va_end (arg); + + return done; +} diff --git a/stdio-common/bug1.c b/stdio-common/bug1.c new file mode 100644 index 0000000000..755bc4231b --- /dev/null +++ b/stdio-common/bug1.c @@ -0,0 +1,28 @@ +#include +#include +#include + +int +DEFUN_VOID(main) +{ + char *bp; + size_t size; + FILE *stream; + int lose = 0; + + stream = open_memstream (&bp, &size); + fprintf (stream, "hello"); + fflush (stream); + printf ("buf = %s, size = %d\n", bp, size); + lose |= size != 5; + lose |= strncmp (bp, "hello", size); + fprintf (stream, ", world"); + fclose (stream); + printf ("buf = %s, size = %d\n", bp, size); + lose |= size != 12; + lose |= strncmp (bp, "hello, world", 12); + + puts (lose ? "Test FAILED!" : "Test succeeded."); + + return lose; +} diff --git a/stdio-common/bug1.input b/stdio-common/bug1.input new file mode 100644 index 0000000000..5595fa46c0 --- /dev/null +++ b/stdio-common/bug1.input @@ -0,0 +1 @@ +95 diff --git a/stdio-common/bug2.c b/stdio-common/bug2.c new file mode 100644 index 0000000000..2b34c890bf --- /dev/null +++ b/stdio-common/bug2.c @@ -0,0 +1,12 @@ +#include +#include + +int +DEFUN_VOID(main) +{ + int i; + puts ("This should print \"wow = I\" for I from 0 to 39 inclusive."); + for (i = 0; i < 40; i++) + printf ("%s = %d\n", "wow", i); + return 0; +} diff --git a/stdio-common/bug3.c b/stdio-common/bug3.c new file mode 100644 index 0000000000..1684720b9f --- /dev/null +++ b/stdio-common/bug3.c @@ -0,0 +1,52 @@ +#include +#include +#include + +int +DEFUN_VOID(main) +{ + FILE *f; + int i; + + f = fopen("/tmp/bugtest", "w+"); + for (i=0; i<9000; i++) + putc ('x', f); + fseek (f, 8180L, 0); + fwrite ("Where does this text go?", 1, 24, f); + fflush (f); + + rewind (f); + for (i=0; i<9000; i++) + { + int j; + + if ((j = getc(f)) != 'x') + { + if (i != 8180) + { + printf ("Test FAILED!"); + return 1; + } + else + { + char buf[25]; + + buf[0] = j; + fread (buf + 1, 1, 23, f); + buf[24] = '\0'; + if (strcmp (buf, "Where does this text go?") != 0) + { + printf ("%s\nTest FAILED!\n", buf); + return 1; + } + i += 23; + } + } + } + + fclose(f); + + puts ("Test succeeded."); + + return 0; +} diff --git a/stdio-common/bug4.c b/stdio-common/bug4.c new file mode 100644 index 0000000000..00abf3c502 --- /dev/null +++ b/stdio-common/bug4.c @@ -0,0 +1,50 @@ +#ifdef _LIBC +#include +#endif +#include +#include +#include + +int stdio_block_read = 1, stdio_block_write = 1; + +int +DEFUN(main, (argc, argv), + int argc AND char **argv) +{ + FILE *f; + int i; + char buffer[31]; + + while ((i = getopt (argc, argv, "rw")) != EOF) + switch (i) + { + case 'r': + stdio_block_read = 0; + break; + case 'w': + stdio_block_write = 0; + break; + } + + f = fopen("/tmp/bugtest", "w+"); + for (i=0; i<9000; i++) { + putc('x', f); + } + fseek(f, 8180L, 0); + fwrite("Where does this text come from?", 1, 31, f); + fseek(f, 8180L, 0); + fread(buffer, 1, 31, f); + fwrite(buffer, 1, 31, stdout); + fclose(f); + + if (!memcmp (buffer, "Where does this text come from?", 31)) + { + puts ("\nTest succeeded."); + return 0; + } + else + { + puts ("\nTest FAILED!"); + return 1; + } +} diff --git a/stdio-common/bug5.c b/stdio-common/bug5.c new file mode 100644 index 0000000000..18f069ae29 --- /dev/null +++ b/stdio-common/bug5.c @@ -0,0 +1,60 @@ +/* If stdio is working correctly, after this is run infile and outfile + will have the same contents. If the bug (found in GNU C library 0.3) + exhibits itself, outfile will be missing the 2nd through 1023rd + characters. */ + +#include +#include +#include +#include + +static char buf[8192]; + +int +DEFUN_VOID(main) +{ + FILE *in; + FILE *out; + static char inname[] = "/tmp/bug5.in"; + static char outname[] = "/tmp/bug5.out"; + int i; + + /* Create a test file. */ + in = fopen (inname, "w+"); + if (in == NULL) + { + perror (inname); + return 1; + } + for (i = 0; i < 1000; ++i) + fprintf (in, "%d\n", i); + + out = fopen (outname, "w"); + if (out == NULL) + { + perror (outname); + return 1; + } + if (fseek (in, 0L, SEEK_SET) != 0) + abort (); + putc (getc (in), out); + i = fread (buf, 1, sizeof (buf), in); + if (i == 0) + { + perror ("fread"); + return 1; + } + if (fwrite (buf, 1, i, out) != i) + { + perror ("fwrite"); + return 1; + } + fclose (in); + fclose (out); + + puts ("There should be no further output from this test."); + fflush (stdout); + execlp ("cmp", "cmp", inname, outname, (char *) NULL); + perror ("execlp: cmp"); + exit (1); +} diff --git a/stdio-common/bug6.c b/stdio-common/bug6.c new file mode 100644 index 0000000000..4a37ab2584 --- /dev/null +++ b/stdio-common/bug6.c @@ -0,0 +1,27 @@ +#include +#include + +int +DEFUN_VOID(main) +{ + char buf[80]; + int i; + int lost = 0; + + scanf ("%2s", buf); + lost |= (buf[0] != 'X' || buf[1] != 'Y' || buf[2] != '\0'); + if (lost) + puts ("test of %2s failed."); + scanf (" "); + scanf ("%d", &i); + lost |= (i != 1234); + if (lost) + puts ("test of %d failed."); + scanf ("%c", buf); + lost |= (buf[0] != 'L'); + if (lost) + puts ("test of %c failed.\n"); + + puts (lost ? "Test FAILED!" : "Test succeeded."); + return lost; +} diff --git a/stdio-common/bug6.input b/stdio-common/bug6.input new file mode 100644 index 0000000000..d996e399c3 --- /dev/null +++ b/stdio-common/bug6.input @@ -0,0 +1 @@ +XY 1234L diff --git a/stdio-common/bug7.c b/stdio-common/bug7.c new file mode 100644 index 0000000000..af06f8d6a5 --- /dev/null +++ b/stdio-common/bug7.c @@ -0,0 +1,53 @@ +/* Regression test for fseek and freopen bugs. */ + +#include + +int +main () +{ + int lose = 0; + char filename[] = "/tmp/foo"; + FILE *fp; + + fp = fopen (filename, "w+"); + fprintf (fp, "Hello world!\n"); + fflush (fp); + fseek (fp, 5L, SEEK_SET); + if (fseek (fp, -1L, SEEK_CUR) < 0) + { + printf ("seek failed\n"); + lose = 1; + } + fclose (fp); + remove (filename); + + { + FILE *file1; + FILE *file2; + char filename1[] = "/tmp/foo"; + char filename2[] = "/tmp/bar"; + int ch; + + file1 = fopen (filename1, "w"); + fclose (file1); + + file2 = fopen (filename2, "w"); + fputc ('x', file2); + fclose (file2); + + file1 = fopen (filename1, "r"); + file2 = freopen (filename2, "r", file1); + if ((ch = fgetc (file2)) != 'x') + { + printf ("wrong character in reopened file, value = %d\n", ch); + lose = 1; + } + fclose (file1); + fclose (file2); + remove (filename1); + remove (filename2); + } + + puts (lose ? "Test FAILED!" : "Test succeeded."); + return lose; +} diff --git a/stdio-common/dprintf.c b/stdio-common/dprintf.c new file mode 100644 index 0000000000..5746d49841 --- /dev/null +++ b/stdio-common/dprintf.c @@ -0,0 +1,41 @@ +/* Copyright (C) 1991, 1995 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 Library General Public License as +published by the Free Software Foundation; either version 2 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include +#include + +#ifdef USE_IN_LIBIO +# define vdprintf _IO_vdprintf +#endif + +/* Write formatted output to D, according to the format string FORMAT. */ +/* VARARGS2 */ +int +dprintf (d, format) + int d; + const char *format; +{ + va_list arg; + int done; + + va_start (arg, format); + done = vdprintf (d, format, arg); + va_end (arg); + + return done; +} diff --git a/stdio-common/errnobug.c b/stdio-common/errnobug.c new file mode 100644 index 0000000000..cf17be30a2 --- /dev/null +++ b/stdio-common/errnobug.c @@ -0,0 +1,60 @@ +/* Regression test for reported old bug that errno is clobbered + by the first successful output to a stream on an unseekable object. +Copyright (C) 1995 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 Library General Public License as +published by the Free Software Foundation; either version 2 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include +#include +#include + +int +main (void) +{ + int fd[2]; + FILE *f; + + /* Get a stream that cannot seek. */ + + if (pipe (fd)) + { + perror ("pipe"); + return 1; + } + f = fdopen (fd[1], "w"); + if (f == NULL) + { + perror ("fdopen"); + return 1; + } + + errno = 0; + if (fputs ("fnord", f)) + { + perror ("fputs"); + return 1; + } + + if (errno) + { + perror ("errno gratuitously set -- TEST FAILED"); + return 1; + } + + puts ("Test succeeded."); + return 0; +} diff --git a/stdio-common/fprintf.c b/stdio-common/fprintf.c new file mode 100644 index 0000000000..bc6d1003b7 --- /dev/null +++ b/stdio-common/fprintf.c @@ -0,0 +1,38 @@ +/* Copyright (C) 1991 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 Library General Public License as +published by the Free Software Foundation; either version 2 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include +#include +#include + + +/* Write formatted output to STREAM from the format string FORMAT. */ +/* VARARGS2 */ +int +DEFUN(fprintf, (stream, format), + FILE *stream AND CONST char *format DOTS) +{ + va_list arg; + int done; + + va_start(arg, format); + done = vfprintf(stream, format, arg); + va_end(arg); + + return done; +} diff --git a/stdio-common/fscanf.c b/stdio-common/fscanf.c new file mode 100644 index 0000000000..cbe0103368 --- /dev/null +++ b/stdio-common/fscanf.c @@ -0,0 +1,38 @@ +/* Copyright (C) 1991 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 Library General Public License as +published by the Free Software Foundation; either version 2 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include +#include +#include + + +/* Read formatted input from STREAM according to the format string FORMAT. */ +/* VARARGS2 */ +int +DEFUN(fscanf, (stream, format), + FILE *stream AND CONST char *format DOTS) +{ + va_list arg; + int done; + + va_start(arg, format); + done = __vfscanf(stream, format, arg); + va_end(arg); + + return done; +} diff --git a/stdio-common/getline.c b/stdio-common/getline.c new file mode 100644 index 0000000000..1a2f975c75 --- /dev/null +++ b/stdio-common/getline.c @@ -0,0 +1,33 @@ +/* Copyright (C) 1991, 1992, 1995 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 Library General Public License as +published by the Free Software Foundation; either version 2 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include +#include +#include + +#undef __getline + +/* Like getdelim, but always looks for a newline. */ +ssize_t +DEFUN(__getline, (lineptr, n, stream), + char **lineptr AND size_t *n AND FILE *stream) +{ + return __getdelim (lineptr, n, '\n', stream); +} + +weak_alias (__getline, getline) diff --git a/stdio-common/getw.c b/stdio-common/getw.c new file mode 100644 index 0000000000..45d4d8875d --- /dev/null +++ b/stdio-common/getw.c @@ -0,0 +1,33 @@ +/* Copyright (C) 1991 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 Library General Public License as +published by the Free Software Foundation; either version 2 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include +#include + + +/* Read a word (int) from STREAM. */ +int +DEFUN(getw, (stream), FILE *stream) +{ + int w; + + /* Is there a better way? */ + if (fread((PTR) &w, sizeof(w), 1, stream) != 1) + return(EOF); + return(w); +} diff --git a/stdio-common/perror.c b/stdio-common/perror.c new file mode 100644 index 0000000000..1054acaa7d --- /dev/null +++ b/stdio-common/perror.c @@ -0,0 +1,42 @@ +/* Copyright (C) 1991, 1992, 1993 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 Library General Public License as +published by the Free Software Foundation; either version 2 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include +#include +#include + +extern char *_strerror_internal __P ((int, char *buf, size_t)); + +/* Print a line on stderr consisting of the text in S, a colon, a space, + a message describing the meaning of the contents of `errno' and a newline. + If S is NULL or "", the colon and space are omitted. */ +void +DEFUN(perror, (s), register CONST char *s) +{ + char buf[1024]; + int errnum = errno; + CONST char *colon; + + if (s == NULL || *s == '\0') + s = colon = ""; + else + colon = ": "; + + (void) fprintf (stderr, "%s%s%s\n", + s, colon, _strerror_internal (errnum, buf, sizeof buf)); +} diff --git a/stdio-common/printf-parse.h b/stdio-common/printf-parse.h new file mode 100644 index 0000000000..0f6e9e287b --- /dev/null +++ b/stdio-common/printf-parse.h @@ -0,0 +1,388 @@ +/* Internal header for parsing printf format strings. +Copyright (C) 1995 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 +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include +#include +#include +#include + +#define NDEBUG 1 +#include + +#define MAX(a,b) ({typeof(a) _a = (a); typeof(b) _b = (b); \ + _a > _b ? _a : _b; }) +#define MIN(a,b) ({typeof(a) _a = (a); typeof(b) _b = (b); \ + _a < _b ? _a : _b; }) + +struct printf_spec + { + /* Information parsed from the format spec. */ + struct printf_info info; + + /* Pointers into the format string for the end of this format + spec and the next (or to the end of the string if no more). */ + const char *end_of_fmt, *next_fmt; + + /* Position of arguments for precision and width, or -1 if `info' has + the constant value. */ + int prec_arg, width_arg; + + int data_arg; /* Position of data argument. */ + int data_arg_type; /* Type of first argument. */ + /* Number of arguments consumed by this format specifier. */ + size_t ndata_args; + }; + + +/* The various kinds off arguments that can be passed to printf. */ +union printf_arg + { + unsigned char pa_char; + short int pa_short_int; + int pa_int; + long int pa_long_int; + long long int pa_long_long_int; + unsigned short int pa_u_short_int; + unsigned int pa_u_int; + unsigned long int pa_u_long_int; + unsigned long long int pa_u_long_long_int; + float pa_float; + double pa_double; + long double pa_long_double; + const char *pa_string; + void *pa_pointer; + }; + + +/* Read a simple integer from a string and update the string pointer. + It is assumed that the first character is a digit. */ +static inline unsigned int +read_int (const char * *pstr) +{ + unsigned int retval = **pstr - '0'; + + while (isdigit (*++(*pstr))) + { + retval *= 10; + retval += **pstr - '0'; + } + + return retval; +} + + + +/* Find the next spec in FORMAT, or the end of the string. Returns + a pointer into FORMAT, to a '%' or a '\0'. */ +static inline const char * +find_spec (const char *format) +{ + while (*format != '\0' && *format != '%') + { + int len; + + if (isascii (*format) || (len = mblen (format, MB_CUR_MAX)) <= 0) + ++format; + else + format += len; + } + return format; +} + + +/* This is defined in reg-printf.c. */ +extern printf_arginfo_function **__printf_arginfo_table; + + +/* FORMAT must point to a '%' at the beginning of a spec. Fills in *SPEC + with the parsed details. POSN is the number of arguments already + consumed. At most MAXTYPES - POSN types are filled in TYPES. Return + the number of args consumed by this spec; *MAX_REF_ARG is updated so it + remains the highest argument index used. */ +static inline size_t +parse_one_spec (const char *format, size_t posn, struct printf_spec *spec, + size_t *max_ref_arg) +{ + unsigned int n; + size_t nargs = 0; + + /* Skip the '%'. */ + ++format; + + /* Clear information structure. */ + spec->data_arg = -1; + spec->info.alt = 0; + spec->info.space = 0; + spec->info.left = 0; + spec->info.showsign = 0; + spec->info.group = 0; + spec->info.pad = ' '; + + /* Test for positional argument. */ + if (isdigit (*format)) + { + const char *begin = format; + + n = read_int (&format); + + if (n > 0 && *format == '$') + /* Is positional parameter. */ + { + ++format; /* Skip the '$'. */ + spec->data_arg = n - 1; + *max_ref_arg = MAX (*max_ref_arg, n); + } + else + /* Oops; that was actually the width and/or 0 padding flag. + Step back and read it again. */ + format = begin; + } + + /* Check for spec modifiers. */ + while (*format == ' ' || *format == '+' || *format == '-' || + *format == '#' || *format == '0' || *format == '\'') + switch (*format++) + { + case ' ': + /* Output a space in place of a sign, when there is no sign. */ + spec->info.space = 1; + break; + case '+': + /* Always output + or - for numbers. */ + spec->info.showsign = 1; + break; + case '-': + /* Left-justify things. */ + spec->info.left = 1; + break; + case '#': + /* Use the "alternate form": + Hex has 0x or 0X, FP always has a decimal point. */ + spec->info.alt = 1; + break; + case '0': + /* Pad with 0s. */ + spec->info.pad = '0'; + break; + case '\'': + /* Show grouping in numbers if the locale information + indicates any. */ + spec->info.group = 1; + break; + } + if (spec->info.left) + spec->info.pad = ' '; + + /* Get the field width. */ + spec->width_arg = -1; + spec->info.width = 0; + if (*format == '*') + { + /* The field width is given in an argument. + A negative field width indicates left justification. */ + const char *begin = ++format; + + if (isdigit (*format)) + { + /* The width argument might be found in a positional parameter. */ + n = read_int (&format); + + if (n > 0 && *format == '$') + { + spec->width_arg = n - 1; + *max_ref_arg = MAX (*max_ref_arg, n); + ++format; /* Skip '$'. */ + } + } + + if (spec->width_arg < 0) + { + /* Not in a positional parameter. Consume one argument. */ + spec->width_arg = posn++; + ++nargs; + format = begin; /* Step back and reread. */ + } + } + else if (isdigit (*format)) + /* Constant width specification. */ + spec->info.width = read_int (&format); + + /* Get the precision. */ + spec->prec_arg = -1; + /* -1 means none given; 0 means explicit 0. */ + spec->info.prec = -1; + if (*format == '.') + { + ++format; + if (*format == '*') + { + /* The precision is given in an argument. */ + const char *begin = ++format; + + if (isdigit (*format)) + { + n = read_int (&format); + + if (n > 0 && *format == '$') + { + spec->prec_arg = n - 1; + *max_ref_arg = MAX (*max_ref_arg, n); + ++format; + } + } + + if (spec->prec_arg < 0) + { + /* Not in a positional parameter. */ + spec->prec_arg = posn++; + ++nargs; + format = begin; + } + } + else if (isdigit (*format)) + spec->info.prec = read_int (&format); + else + /* "%.?" is treated like "%.0?". */ + spec->info.prec = 0; + + /* If there was a precision specified, ignore the 0 flag and always + pad with spaces. */ + spec->info.pad = ' '; + } + + /* Check for type modifiers. */ +#define is_longlong is_long_double + spec->info.is_long_double = 0; + spec->info.is_short = 0; + spec->info.is_long = 0; + + while (*format == 'h' || *format == 'l' || *format == 'L' || + *format == 'Z' || *format == 'q') + switch (*format++) + { + case 'h': + /* int's are short int's. */ + spec->info.is_short = 1; + break; + case 'l': + if (spec->info.is_long) + /* A double `l' is equivalent to an `L'. */ + spec->info.is_longlong = 1; + else + /* int's are long int's. */ + spec->info.is_long = 1; + break; + case 'L': + /* double's are long double's, and int's are long long int's. */ + spec->info.is_long_double = 1; + break; + case 'Z': + /* int's are size_t's. */ + assert (sizeof(size_t) <= sizeof(unsigned long long int)); + spec->info.is_longlong = sizeof(size_t) > sizeof(unsigned long int); + spec->info.is_long = sizeof(size_t) > sizeof(unsigned int); + break; + case 'q': + /* 4.4 uses this for long long. */ + spec->info.is_longlong = 1; + break; + } + + /* Get the format specification. */ + spec->info.spec = *format++; + if (__printf_arginfo_table != NULL && + __printf_arginfo_table[spec->info.spec] != NULL) + /* We don't try to get the types for all arguments if the format + uses more than one. The normal case is covered though. */ + spec->ndata_args = (*__printf_arginfo_table[spec->info.spec]) + (&spec->info, 1, &spec->data_arg_type); + else + { + /* Find the data argument types of a built-in spec. */ + spec->ndata_args = 1; + + switch (spec->info.spec) + { + case 'i': + case 'd': + case 'u': + case 'o': + case 'X': + case 'x': + if (spec->info.is_longlong) + spec->data_arg_type = PA_INT|PA_FLAG_LONG_LONG; + else if (spec->info.is_long) + spec->data_arg_type = PA_INT|PA_FLAG_LONG; + else if (spec->info.is_short) + spec->data_arg_type = PA_INT|PA_FLAG_SHORT; + else + spec->data_arg_type = PA_INT; + break; + case 'e': + case 'E': + case 'f': + case 'g': + case 'G': + if (spec->info.is_long_double) + spec->data_arg_type =