diff --git a/newlib/ChangeLog b/newlib/ChangeLog index 2e3c94ccb..39f1557c2 100644 --- a/newlib/ChangeLog +++ b/newlib/ChangeLog @@ -1,3 +1,51 @@ +2008-12-10 Corinna Vinschen + + Implement basic wide char stdio functionality, based on FreeBSD. + * libc/include/stdio.h (__SORD): Define. + (__SWID): Define. + * libc/include/wchar.h: Add declarations for new wide char functions. + (getwc): Define as macro. + (getwchar): Ditto. + (putwc): Ditto. + (putwchar): Ditto. + * libc/include/sys/reent.h (struct __sFILE): Add _mbstate member. + (struct __sFILE64): Ditto. + * libc/stdio/Makefile.am (ELIX_4_SOURCES): Add fgetwc.c, fgetws.c, + fputwc.c, fputws.c, fwide.c, getwc.c, getwchar.c, putwc.c, putwchar.c + and ungetwc.c. + (CHEWOUT_FILES): Add fgetwc.def, fgetws.def, fputwc.def, fputws.def, + fwide.def, getwc.def, getwchar.def, putwc.def, putwchar.def and + ungetwc.def. + Add header dependency rules for the new files. + * libc/stdio/Makefile.in: Regenerate. + * libc/stdio/fgetwc.c: New file, implementing fgetwc and _fgetwc_r. + * libc/stdio/fgetws.c: New file, implementing fgetws and _fgetws_r. + * libc/stdio/findfp.c (std): Initialize FILE's _mbstate member. + (__sfmoreglue): Ditto. + * libc/stdio/fputs.c (_fputs_r): Set stream orientation. + * libc/stdio/fputwc.c: New file, implementing fputwc and _fputwc_r. + * libc/stdio/fputws.c: New file, implementing fputws and _fputws_r. + * libc/stdio/fread.c (_fread_r): Set stream orientation. + * libc/stdio/freopen.c (_freopen_r): Reset stream orientation. Reset + _mbstate. + * libc/stdio/fseek.c (_fseek_r): Reset _mbstate. + * libc/stdio/fwide.c: New file, implementing fwide and _fwide_r. + * libc/stdio/fwrite.c (_fwrite_r): Set stream orientation. + * libc/stdio/getwc.c: New file, implementing getwc and _getwc_r. + * libc/stdio/getwchar.c: New file, implementing getwchar and + _getwchar_r. + * libc/stdio/local.h (ORIENT): New macro. + * libc/stdio/puts.c (_puts_r): Set stream orientation. + * libc/stdio/putwc.c: New file, implementing putwc and _putwc_r. + * libc/stdio/putwchar.c: New file, implementing putwchar and + _putwchar_r. + * libc/stdio/refill.c (__srefill_r): Set stream orientation. + * libc/stdio/stdio.tex: Add documentation for new functions. + * libc/stdio/ungetc.c (_ungetc_r): Set stream orientation. + * libc/stdio/ungetwc.c: New file, implementing ungetwc and _ungetwc_r. + * libc/stdio/vfscanf.c (__SVFSCANF_R): Set stream orientation. + * libc/stdio/wbuf.c (__swbuf_r): Ditto. + 2008-12-10 Joseph Myers * libc/include/stdint.h (INT32_MIN, INT32_MAX, UINT32_MAX, diff --git a/newlib/libc/include/stdio.h b/newlib/libc/include/stdio.h index b62bc851f..95bceed34 100644 --- a/newlib/libc/include/stdio.h +++ b/newlib/libc/include/stdio.h @@ -78,11 +78,15 @@ typedef _fpos64_t fpos64_t; #define __SOPT 0x0400 /* do fseek() optimisation */ #define __SNPT 0x0800 /* do not do fseek() optimisation */ #define __SOFF 0x1000 /* set iff _offset is in fact correct */ +#define __SORD 0x2000 /* true => stream orientation (byte/wide) decided */ #if defined(__CYGWIN__) # define __SCLE 0x4000 /* convert line endings CR/LF <-> NL */ #endif #define __SL64 0x8000 /* is 64-bit offset large file */ +/* _flags2 flags */ +#define __SWID 0x2000 /* true => stream orientation wide, false => byte, only valid if __SORD in _flags is true */ + /* * The following three definitions are for ANSI C, which took them * from System V, which stupidly took internal interface macros and diff --git a/newlib/libc/include/sys/reent.h b/newlib/libc/include/sys/reent.h index b5d5c7da5..55fb9ff2a 100644 --- a/newlib/libc/include/sys/reent.h +++ b/newlib/libc/include/sys/reent.h @@ -212,6 +212,7 @@ struct __sFILE { #ifndef __SINGLE_THREAD__ _flock_t _lock; /* for thread-safety locking */ #endif + _mbstate_t _mbstate; /* for wide char stdio functions. */ int _flags2; /* for future use */ }; @@ -265,6 +266,7 @@ struct __sFILE64 { #ifndef __SINGLE_THREAD__ _flock_t _lock; /* for thread-safety locking */ #endif + _mbstate_t _mbstate; /* for wide char stdio functions. */ }; typedef struct __sFILE64 __FILE; #else diff --git a/newlib/libc/include/wchar.h b/newlib/libc/include/wchar.h index d132f730e..d5b63e95e 100644 --- a/newlib/libc/include/wchar.h +++ b/newlib/libc/include/wchar.h @@ -91,6 +91,38 @@ long long _EXFUN(_wcstoll_r, (struct _reent *, const wchar_t *, wchar_t **, int) unsigned long _EXFUN(_wcstoul_r, (struct _reent *, const wchar_t *, wchar_t **, int)); unsigned long long _EXFUN(_wcstoull_r, (struct _reent *, const wchar_t *, wchar_t **, int)); +wint_t _EXFUN(fgetwc, (__FILE *)); +wchar_t *_EXFUN(fgetws, (wchar_t *, int, __FILE *)); +wint_t _EXFUN(fputwc, (wchar_t, __FILE *)); +int _EXFUN(fputws, (const wchar_t *, __FILE *)); +int _EXFUN (fwide, (__FILE *, int)); +wint_t _EXFUN (getwc, (__FILE *)); +wint_t _EXFUN (getwchar, (void)); +wint_t _EXFUN(putwc, (wchar_t, __FILE *)); +wint_t _EXFUN(putwchar, (wchar_t)); +wint_t _EXFUN (ungetwc, (wint_t wc, __FILE *)); + +wint_t _EXFUN(_fgetwc_r, (struct _reent *, __FILE *)); +wchar_t *_EXFUN(_fgetws_r, (struct _reent *, wchar_t *, int, __FILE *)); +wint_t _EXFUN(_fputwc_r, (struct _reent *, wchar_t, __FILE *)); +int _EXFUN(_fputws_r, (struct _reent *, const wchar_t *, __FILE *)); +int _EXFUN (_fwide_r, (struct _reent *, __FILE *, int)); +wint_t _EXFUN (_getwc_r, (struct _reent *, __FILE *)); +wint_t _EXFUN (_getwchar_r, (struct _reent *ptr)); +wint_t _EXFUN(_putwc_r, (struct _reent *, wchar_t, __FILE *)); +wint_t _EXFUN(_putwchar_r, (struct _reent *, wchar_t)); +wint_t _EXFUN (_ungetwc_r, (struct _reent *, wint_t wc, __FILE *)); + +#define getwc(fp) fgetwc(fp) +#define putwc(wc,fp) fputwc((wc), (fp)) +#ifndef _REENT_ONLY +#define getwchar() fgetwc(_REENT->_stdin) +#define putwchar(wc) fputwc((wc), _REENT->_stdout) +#else +#define getwchar() fgetwc(_impure_ptr->_stdin) +#define putwchar(wc) fputwc((wc), _impure_ptr->_stdout) +#endif + _END_STD_C #endif /* _WCHAR_H_ */ diff --git a/newlib/libc/stdio/Makefile.am b/newlib/libc/stdio/Makefile.am index b50b87188..c7111e2c8 100644 --- a/newlib/libc/stdio/Makefile.am +++ b/newlib/libc/stdio/Makefile.am @@ -117,10 +117,20 @@ ELIX_4_SOURCES = \ asnprintf.c \ diprintf.c \ dprintf.c \ + fgetwc.c \ + fgetws.c \ fmemopen.c \ fopencookie.c \ + fputwc.c \ + fputws.c \ funopen.c \ + fwide.c \ + getwc.c \ + getwchar.c \ open_memstream.c \ + putwc.c \ + putwchar.c \ + ungetwc.c \ vasniprintf.c \ vasnprintf.c endif !ELIX_LEVEL_3 @@ -194,18 +204,23 @@ CHEWOUT_FILES = \ fgetc.def \ fgetpos.def \ fgets.def \ + fgetwc.def \ + fgetws.def \ fileno.def \ fmemopen.def \ fopen.def \ fopencookie.def \ fputc.def \ fputs.def \ + fputwc.def \ + fputws.def \ fread.def \ freopen.def \ fseek.def \ fsetpos.def \ ftell.def \ funopen.def \ + fwide.def \ fwrite.def \ getc.def \ getc_u.def \ @@ -215,6 +230,8 @@ CHEWOUT_FILES = \ getline.def \ gets.def \ getw.def \ + getwc.def \ + getwchar.def \ mktemp.def \ open_memstream.def \ perror.def \ @@ -224,6 +241,8 @@ CHEWOUT_FILES = \ putchar_u.def \ puts.def \ putw.def \ + putwc.def \ + putwchar.def \ remove.def \ rename.def \ rewind.def \ @@ -238,6 +257,7 @@ CHEWOUT_FILES = \ tmpfile.def \ tmpnam.def \ ungetc.def \ + ungetwc.def \ vfprintf.def \ vfscanf.def \ viprintf.def \ @@ -261,11 +281,15 @@ CLEANFILES = $(CHEWOUT_FILES) *.ref $(lpfx)fclose.$(oext): local.h $(lpfx)fdopen.$(oext): local.h $(lpfx)fflush.$(oext): local.h +$(lpfx)fgetwc.$(oext): local.h +$(lpfx)fgetws.$(oext): local.h $(lpfx)findfp.$(oext): local.h $(lpfx)fmemopen.$(oext): local.h $(lpfx)fopen.$(oext): local.h $(lpfx)fopencookie.$(oext): local.h $(lpfx)fputs.$(oext): fvwrite.h +$(lpfx)fputwc.$(oext): local.h +$(lpfx)fputws.$(oext): local.h fvwrite.h $(lpfx)fread.$(oext): local.h $(lpfx)freopen.$(oext): local.h $(lpfx)fseek.$(oext): local.h @@ -273,11 +297,16 @@ $(lpfx)ftell.$(oext): local.h $(lpfx)funopen.$(oext): local.h $(lpfx)fvwrite.$(oext): local.h fvwrite.h $(lpfx)fwalk.$(oext): local.h +$(lpfx)fwide.$(oext): local.h +$(lpfx)getwc.$(oext): local.h +$(lpfx)getwchar.$(oext): local.h $(lpfx)fwrite.$(oext): local.h fvwrite.h $(lpfx)iscanf.$(oext): local.h $(lpfx)makebuf.$(oext): local.h $(lpfx)open_memstream.$(oext): local.h $(lpfx)puts.$(oext): fvwrite.h +$(lpfx)putwc.$(oext): local.h +$(lpfx)putwchar.$(oext): local.h $(lpfx)refill.$(oext): local.h $(lpfx)scanf.$(oext): local.h $(lpfx)setbuf.$(oext): local.h @@ -293,6 +322,7 @@ $(lpfx)svfiscanf.$(oext): local.h floatio.h $(lpfx)svfprintf.$(oext): local.h $(lpfx)svfscanf.$(oext): local.h floatio.h $(lpfx)ungetc.$(oext): local.h +$(lpfx)ungetwc.$(oext): local.h $(lpfx)vfiprintf.$(oext): local.h $(lpfx)vfprintf.$(oext): local.h $(lpfx)vfiscanf.$(oext): local.h floatio.h diff --git a/newlib/libc/stdio/Makefile.in b/newlib/libc/stdio/Makefile.in index 5eba57beb..7beaa0ab3 100644 --- a/newlib/libc/stdio/Makefile.in +++ b/newlib/libc/stdio/Makefile.in @@ -115,10 +115,20 @@ am__objects_1 = lib_a-clearerr.$(OBJEXT) lib_a-fclose.$(OBJEXT) \ @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-asnprintf.$(OBJEXT) \ @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-diprintf.$(OBJEXT) \ @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-dprintf.$(OBJEXT) \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-fgetwc.$(OBJEXT) \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-fgetws.$(OBJEXT) \ @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-fmemopen.$(OBJEXT) \ @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-fopencookie.$(OBJEXT) \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-fputwc.$(OBJEXT) \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-fputws.$(OBJEXT) \ @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-funopen.$(OBJEXT) \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-fwide.$(OBJEXT) \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-getwc.$(OBJEXT) \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-getwchar.$(OBJEXT) \ @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-open_memstream.$(OBJEXT) \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-putwc.$(OBJEXT) \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-putwchar.$(OBJEXT) \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-ungetwc.$(OBJEXT) \ @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-vasniprintf.$(OBJEXT) \ @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-vasnprintf.$(OBJEXT) @USE_LIBTOOL_FALSE@am_lib_a_OBJECTS = $(am__objects_1) \ @@ -148,10 +158,20 @@ am__objects_4 = clearerr.lo fclose.lo fdopen.lo feof.lo ferror.lo \ @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ asnprintf.lo \ @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ diprintf.lo \ @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ dprintf.lo \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ fgetwc.lo \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ fgetws.lo \ @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ fmemopen.lo \ @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ fopencookie.lo \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ fputwc.lo \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ fputws.lo \ @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ funopen.lo \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ fwide.lo \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ getwc.lo \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ getwchar.lo \ @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ open_memstream.lo \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ putwc.lo \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ putwchar.lo \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ ungetwc.lo \ @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ vasniprintf.lo \ @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ vasnprintf.lo @USE_LIBTOOL_TRUE@am_libstdio_la_OBJECTS = $(am__objects_4) \ @@ -442,10 +462,20 @@ GENERAL_SOURCES = \ @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ asnprintf.c \ @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ diprintf.c \ @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ dprintf.c \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ fgetwc.c \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ fgetws.c \ @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ fmemopen.c \ @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ fopencookie.c \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ fputwc.c \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ fputws.c \ @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ funopen.c \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ fwide.c \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ getwc.c \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ getwchar.c \ @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ open_memstream.c \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ putwc.c \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ putwchar.c \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ ungetwc.c \ @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ vasniprintf.c \ @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ vasnprintf.c @@ -485,18 +515,23 @@ CHEWOUT_FILES = \ fgetc.def \ fgetpos.def \ fgets.def \ + fgetwc.def \ + fgetws.def \ fileno.def \ fmemopen.def \ fopen.def \ fopencookie.def \ fputc.def \ fputs.def \ + fputwc.def \ + fputws.def \ fread.def \ freopen.def \ fseek.def \ fsetpos.def \ ftell.def \ funopen.def \ + fwide.def \ fwrite.def \ getc.def \ getc_u.def \ @@ -506,6 +541,8 @@ CHEWOUT_FILES = \ getline.def \ gets.def \ getw.def \ + getwc.def \ + getwchar.def \ mktemp.def \ open_memstream.def \ perror.def \ @@ -515,6 +552,8 @@ CHEWOUT_FILES = \ putchar_u.def \ puts.def \ putw.def \ + putwc.def \ + putwchar.def \ remove.def \ rename.def \ rewind.def \ @@ -529,6 +568,7 @@ CHEWOUT_FILES = \ tmpfile.def \ tmpnam.def \ ungetc.def \ + ungetwc.def \ vfprintf.def \ vfscanf.def \ viprintf.def \ @@ -1163,6 +1203,18 @@ lib_a-dprintf.o: dprintf.c lib_a-dprintf.obj: dprintf.c $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-dprintf.obj `if test -f 'dprintf.c'; then $(CYGPATH_W) 'dprintf.c'; else $(CYGPATH_W) '$(srcdir)/dprintf.c'; fi` +lib_a-fgetwc.o: fgetwc.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-fgetwc.o `test -f 'fgetwc.c' || echo '$(srcdir)/'`fgetwc.c + +lib_a-fgetwc.obj: fgetwc.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-fgetwc.obj `if test -f 'fgetwc.c'; then $(CYGPATH_W) 'fgetwc.c'; else $(CYGPATH_W) '$(srcdir)/fgetwc.c'; fi` + +lib_a-fgetws.o: fgetws.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-fgetws.o `test -f 'fgetws.c' || echo '$(srcdir)/'`fgetws.c + +lib_a-fgetws.obj: fgetws.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-fgetws.obj `if test -f 'fgetws.c'; then $(CYGPATH_W) 'fgetws.c'; else $(CYGPATH_W) '$(srcdir)/fgetws.c'; fi` + lib_a-fmemopen.o: fmemopen.c $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-fmemopen.o `test -f 'fmemopen.c' || echo '$(srcdir)/'`fmemopen.c @@ -1175,18 +1227,66 @@ lib_a-fopencookie.o: fopencookie.c lib_a-fopencookie.obj: fopencookie.c $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-fopencookie.obj `if test -f 'fopencookie.c'; then $(CYGPATH_W) 'fopencookie.c'; else $(CYGPATH_W) '$(srcdir)/fopencookie.c'; fi` +lib_a-fputwc.o: fputwc.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-fputwc.o `test -f 'fputwc.c' || echo '$(srcdir)/'`fputwc.c + +lib_a-fputwc.obj: fputwc.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-fputwc.obj `if test -f 'fputwc.c'; then $(CYGPATH_W) 'fputwc.c'; else $(CYGPATH_W) '$(srcdir)/fputwc.c'; fi` + +lib_a-fputws.o: fputws.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-fputws.o `test -f 'fputws.c' || echo '$(srcdir)/'`fputws.c + +lib_a-fputws.obj: fputws.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-fputws.obj `if test -f 'fputws.c'; then $(CYGPATH_W) 'fputws.c'; else $(CYGPATH_W) '$(srcdir)/fputws.c'; fi` + lib_a-funopen.o: funopen.c $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-funopen.o `test -f 'funopen.c' || echo '$(srcdir)/'`funopen.c lib_a-funopen.obj: funopen.c $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-funopen.obj `if test -f 'funopen.c'; then $(CYGPATH_W) 'funopen.c'; else $(CYGPATH_W) '$(srcdir)/funopen.c'; fi` +lib_a-fwide.o: fwide.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-fwide.o `test -f 'fwide.c' || echo '$(srcdir)/'`fwide.c + +lib_a-fwide.obj: fwide.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-fwide.obj `if test -f 'fwide.c'; then $(CYGPATH_W) 'fwide.c'; else $(CYGPATH_W) '$(srcdir)/fwide.c'; fi` + +lib_a-getwc.o: getwc.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-getwc.o `test -f 'getwc.c' || echo '$(srcdir)/'`getwc.c + +lib_a-getwc.obj: getwc.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-getwc.obj `if test -f 'getwc.c'; then $(CYGPATH_W) 'getwc.c'; else $(CYGPATH_W) '$(srcdir)/getwc.c'; fi` + +lib_a-getwchar.o: getwchar.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-getwchar.o `test -f 'getwchar.c' || echo '$(srcdir)/'`getwchar.c + +lib_a-getwchar.obj: getwchar.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-getwchar.obj `if test -f 'getwchar.c'; then $(CYGPATH_W) 'getwchar.c'; else $(CYGPATH_W) '$(srcdir)/getwchar.c'; fi` + lib_a-open_memstream.o: open_memstream.c $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-open_memstream.o `test -f 'open_memstream.c' || echo '$(srcdir)/'`open_memstream.c lib_a-open_memstream.obj: open_memstream.c $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-open_memstream.obj `if test -f 'open_memstream.c'; then $(CYGPATH_W) 'open_memstream.c'; else $(CYGPATH_W) '$(srcdir)/open_memstream.c'; fi` +lib_a-putwc.o: putwc.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-putwc.o `test -f 'putwc.c' || echo '$(srcdir)/'`putwc.c + +lib_a-putwc.obj: putwc.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-putwc.obj `if test -f 'putwc.c'; then $(CYGPATH_W) 'putwc.c'; else $(CYGPATH_W) '$(srcdir)/putwc.c'; fi` + +lib_a-putwchar.o: putwchar.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-putwchar.o `test -f 'putwchar.c' || echo '$(srcdir)/'`putwchar.c + +lib_a-putwchar.obj: putwchar.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-putwchar.obj `if test -f 'putwchar.c'; then $(CYGPATH_W) 'putwchar.c'; else $(CYGPATH_W) '$(srcdir)/putwchar.c'; fi` + +lib_a-ungetwc.o: ungetwc.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-ungetwc.o `test -f 'ungetwc.c' || echo '$(srcdir)/'`ungetwc.c + +lib_a-ungetwc.obj: ungetwc.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-ungetwc.obj `if test -f 'ungetwc.c'; then $(CYGPATH_W) 'ungetwc.c'; else $(CYGPATH_W) '$(srcdir)/ungetwc.c'; fi` + lib_a-vasniprintf.o: vasniprintf.c $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-vasniprintf.o `test -f 'vasniprintf.c' || echo '$(srcdir)/'`vasniprintf.c @@ -1390,11 +1490,15 @@ doc: $(CHEWOUT_FILES) $(lpfx)fclose.$(oext): local.h $(lpfx)fdopen.$(oext): local.h $(lpfx)fflush.$(oext): local.h +$(lpfx)fgetwc.$(oext): local.h +$(lpfx)fgetws.$(oext): local.h $(lpfx)findfp.$(oext): local.h $(lpfx)fmemopen.$(oext): local.h $(lpfx)fopen.$(oext): local.h $(lpfx)fopencookie.$(oext): local.h $(lpfx)fputs.$(oext): fvwrite.h +$(lpfx)fputwc.$(oext): local.h +$(lpfx)fputws.$(oext): local.h fvwrite.h $(lpfx)fread.$(oext): local.h $(lpfx)freopen.$(oext): local.h $(lpfx)fseek.$(oext): local.h @@ -1402,11 +1506,16 @@ $(lpfx)ftell.$(oext): local.h $(lpfx)funopen.$(oext): local.h $(lpfx)fvwrite.$(oext): local.h fvwrite.h $(lpfx)fwalk.$(oext): local.h +$(lpfx)fwide.$(oext): local.h +$(lpfx)getwc.$(oext): local.h +$(lpfx)getwchar.$(oext): local.h $(lpfx)fwrite.$(oext): local.h fvwrite.h $(lpfx)iscanf.$(oext): local.h $(lpfx)makebuf.$(oext): local.h $(lpfx)open_memstream.$(oext): local.h $(lpfx)puts.$(oext): fvwrite.h +$(lpfx)putwc.$(oext): local.h +$(lpfx)putwchar.$(oext): local.h $(lpfx)refill.$(oext): local.h $(lpfx)scanf.$(oext): local.h $(lpfx)setbuf.$(oext): local.h @@ -1422,6 +1531,7 @@ $(lpfx)svfiscanf.$(oext): local.h floatio.h $(lpfx)svfprintf.$(oext): local.h $(lpfx)svfscanf.$(oext): local.h floatio.h $(lpfx)ungetc.$(oext): local.h +$(lpfx)ungetwc.$(oext): local.h $(lpfx)vfiprintf.$(oext): local.h $(lpfx)vfprintf.$(oext): local.h $(lpfx)vfiscanf.$(oext): local.h floatio.h diff --git a/newlib/libc/stdio/fgetwc.c b/newlib/libc/stdio/fgetwc.c new file mode 100644 index 000000000..0f7cf0fca --- /dev/null +++ b/newlib/libc/stdio/fgetwc.c @@ -0,0 +1,180 @@ +/*- + * Copyright (c) 2002-2004 Tim J. Robbins. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* +FUNCTION +<>, <>---get a wide character from a file or stream + +INDEX + fgetwc +INDEX + _fgetwc_r +INDEX + getwc +INDEX + _getwc_r + +ANSI_SYNOPSIS + #include + #include + wint_t fgetwc(FILE *<[fp]>); + + #include + #include + wint_t _fgetwc_r(struct _reent *<[ptr]>, FILE *<[fp]>); + + #include + #include + wint_t getwc(FILE *<[fp]>); + + #include + #include + wint_t _getwc_r(struct _reent *<[ptr]>, FILE *<[fp]>); + +TRAD_SYNOPSIS + #include + #include + wint_t fgetwc(<[fp]>) + FILE *<[fp]>; + + #include + #include + wint_t _fgetwc_r(<[ptr]>, <[fp]>) + struct _reent *<[ptr]>; + FILE *<[fp]>; + + #include + #include + wint_t getwc(<[fp]>) + FILE *<[fp]>; + + #include + #include + wint_t _getwc_r(<[ptr]>, <[fp]>) + struct _reent *<[ptr]>; + FILE *<[fp]>; + +DESCRIPTION +Use <> to get the next wide character from the file or stream +identified by <[fp]>. As a side effect, <> advances the file's +current position indicator. + +The <> function or macro functions identically to <>. It +may be implemented as a macro, and may evaluate its argument more than +once. There is no reason ever to use it. + +<<_fgetwc_r>> and <<_getwc_r>> are simply reentrant versions of +<> and <> that are passed the additional reentrant +structure pointer argument: <[ptr]>. + +RETURNS +The next wide character cast to <>), unless there is no more data, +or the host system reports a read error; in either of these situations, +<> and <> return <>. + +You can distinguish the two situations that cause an <> result by +using the <> and <> functions. + +PORTABILITY +C99, POSIX.1-2001 +*/ + +#include <_ansi.h> +#include +#include +#include +#include +#include +#include "local.h" + +static wint_t +_DEFUN(__fgetwc, (ptr, fp), + struct _reent *ptr _AND + register FILE *fp) +{ + wchar_t wc; + size_t nconv; + + if (fp->_r <= 0 && __srefill_r (ptr, fp)) + return (WEOF); + if (MB_CUR_MAX == 1) + { + /* Fast path for single-byte encodings. */ + wc = *fp->_p++; + fp->_r--; + return (wc); + } + do + { + nconv = _mbrtowc_r (ptr, &wc, fp->_p, fp->_r, &fp->_mbstate); + if (nconv == (size_t)-1) + break; + else if (nconv == (size_t)-2) + continue; + else if (nconv == 0) + { + /* + * Assume that the only valid representation of + * the null wide character is a single null byte. + */ + fp->_p++; + fp->_r--; + return (L'\0'); + } + else + { + fp->_p += nconv; + fp->_r -= nconv; + return (wc); + } + } + while (__srefill_r(ptr, fp) == 0); + fp->_flags |= __SERR; + errno = EILSEQ; + return (WEOF); +} + +wint_t +_DEFUN(_fgetwc_r, (ptr, fp), + struct _reent *ptr _AND + register FILE *fp) +{ + wint_t r; + + _flockfile (fp); + ORIENT(fp, 1); + r = __fgetwc (ptr, fp); + _funlockfile (fp); + return r; +} + +wint_t +_DEFUN(fgetwc, (fp), + FILE *fp) +{ + CHECK_INIT(_REENT, fp); + return _fgetwc_r (_REENT, fp); +} diff --git a/newlib/libc/stdio/fgetws.c b/newlib/libc/stdio/fgetws.c new file mode 100644 index 000000000..30e8ebbf2 --- /dev/null +++ b/newlib/libc/stdio/fgetws.c @@ -0,0 +1,161 @@ +/*- + * Copyright (c) 2002-2004 Tim J. Robbins. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* +FUNCTION +<>---get wide character string from a file or stream + +INDEX + fgetws +INDEX + _fgetws_r + +ANSI_SYNOPSIS + #include + wchar_t *fgetws(wchar_t *<[ws]>, int <[n]>, FILE *<[fp]>); + + #include + wchar_t *_fgetws_r(struct _reent *<[ptr]>, wchar_t *<[ws]>, int <[n]>, FILE *<[fp]>); + +TRAD_SYNOPSIS + #include + wchar_t *fgetws(<[ws]>,<[n]>,<[fp]>) + wchar_t *<[ws]>; + int <[n]>; + FILE *<[fp]>; + + #include + wchar_t *_fgetws_r(<[ptr]>, <[ws]>,<[n]>,<[fp]>) + struct _reent *<[ptr]>; + wchar_t *<[ws]>; + int <[n]>; + FILE *<[fp]>; + +DESCRIPTION +Reads at most <[n-1]> wide characters from <[fp]> until a newline +is found. The wide characters including to the newline are stored +in <[ws]>. The buffer is terminated with a 0. + +The <<_fgetws_r>> function is simply the reentrant version of +<> and is passed an additional reentrancy structure +pointer: <[ptr]>. + +RETURNS +<> returns the buffer passed to it, with the data +filled in. If end of file occurs with some data already +accumulated, the data is returned with no other indication. If +no data are read, NULL is returned instead. + +PORTABILITY +C99, POSIX.1-2001 +*/ + +#include <_ansi.h> +#include +#include +#include +#include +#include +#include "local.h" + +wchar_t * +_DEFUN(_fgetws_r, (ptr, ws, n, fp), + struct _reent *ptr _AND + wchar_t * ws _AND + int n _AND + FILE * fp) +{ + wchar_t *wsp; + size_t nconv; + const char *src; + unsigned char *nl; + + _flockfile (fp); + ORIENT (fp, 1); + + if (n <= 0) + { + errno = EINVAL; + goto error; + } + + if (fp->_r <= 0 && __srefill_r (ptr, fp)) + /* EOF */ + goto error; + wsp = ws; + do + { + src = fp->_p; + nl = memchr (fp->_p, '\n', fp->_r); + nconv = _mbsrtowcs_r (ptr, wsp, &src, + nl != NULL ? (nl - fp->_p + 1) : fp->_r, + &fp->_mbstate); + if (nconv == (size_t) -1) + /* Conversion error */ + goto error; + if (src == NULL) + { + /* + * We hit a null byte. Increment the character count, + * since mbsnrtowcs()'s return value doesn't include + * the terminating null, then resume conversion + * after the null. + */ + nconv++; + src = memchr (fp->_p, '\0', fp->_r); + src++; + } + fp->_r -= (unsigned char *) src - fp->_p; + fp->_p = (unsigned char *) src; + n -= nconv; + wsp += nconv; + } + while (wsp[-1] != L'\n' && n > 1 && (fp->_r > 0 + || __srefill_r (ptr, fp) == 0)); + if (wsp == ws) + /* EOF */ + goto error; + if (!mbsinit (&fp->_mbstate)) + /* Incomplete character */ + goto error; + *wsp++ = L'\0'; + _funlockfile (fp); + return ws; + +error: + _funlockfile (fp); + return NULL; +} + +wchar_t * +_DEFUN(fgetws, (ws, n, fp), + wchar_t *ws _AND + int n _AND + FILE *fp) +{ + CHECK_INIT (_REENT, fp); + return _fgetws_r (_REENT, ws, n, fp); +} diff --git a/newlib/libc/stdio/findfp.c b/newlib/libc/stdio/findfp.c index 0de2a7f23..570fd457e 100644 --- a/newlib/libc/stdio/findfp.c +++ b/newlib/libc/stdio/findfp.c @@ -51,6 +51,7 @@ _DEFUN(std, (ptr, flags, file, data), ptr->_bf._base = 0; ptr->_bf._size = 0; ptr->_lbfsize = 0; + memset (&ptr->_mbstate, 0, sizeof (_mbstate_t)); ptr->_cookie = ptr; ptr->_read = __sread; #ifndef __LARGE64_FILES @@ -139,6 +140,7 @@ found: fp->_bf._base = NULL; /* no buffer */ fp->_bf._size = 0; fp->_lbfsize = 0; /* not line buffered */ + memset (&fp->_mbstate, 0, sizeof (_mbstate_t)); /* fp->_cookie = ; */ /* caller sets cookie, _read/_write etc */ fp->_ub._base = NULL; /* no ungetc buffer */ fp->_ub._size = 0; diff --git a/newlib/libc/stdio/fputs.c b/newlib/libc/stdio/fputs.c index 24a108b15..a32dea4e2 100644 --- a/newlib/libc/stdio/fputs.c +++ b/newlib/libc/stdio/fputs.c @@ -89,6 +89,7 @@ _DEFUN(_fputs_r, (ptr, s, fp), CHECK_INIT(ptr, fp); _flockfile (fp); + ORIENT (fp, -1); result = __sfvwrite_r (ptr, fp, &uio); _funlockfile (fp); return result; diff --git a/newlib/libc/stdio/fputwc.c b/newlib/libc/stdio/fputwc.c new file mode 100644 index 000000000..ef10a8eba --- /dev/null +++ b/newlib/libc/stdio/fputwc.c @@ -0,0 +1,177 @@ +/*- + * Copyright (c) 2002-2004 Tim J. Robbins. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* +FUNCTION +<>, <>---write a wide character on a stream or file + +INDEX + fputwc +INDEX + _fputwc_r +INDEX + putwc +INDEX + _putwc_r + +ANSI_SYNOPSIS + #include + #include + wint_t fputwc(wchar_t <[wc]>, FILE *<[fp]>); + + #include + #include + wint_t _fputwc_r(struct _rent *<[ptr]>, wchar_t <[wc]>, FILE *<[fp]>); + + #include + #include + wint_t putwc(wchar_t <[wc]>, FILE *<[fp]>); + + #include + #include + wint_t _putwc_r(struct _rent *<[ptr]>, wchar_t <[wc]>, FILE *<[fp]>); + +TRAD_SYNOPSIS + #include + #include + wint_t fputwc(<[wc]>, <[fp]>) + wchar_t <[wc]>; + FILE *<[fp]>; + + #include + #include + wint_t _fputwc_r(<[ptr]>, <[wc]>, <[fp]>) + struct _reent *<[ptr]>; + wchar_t <[wc]>; + FILE *<[fp]>; + + #include + #include + wint_t putwc(<[wc]>, <[fp]>) + wchar_t <[wc]>; + FILE *<[fp]>; + + #include + #include + wint_t _putwc_r(<[ptr]>, <[wc]>, <[fp]>) + struct _reent *<[ptr]>; + wchar_t <[wc]>; + FILE *<[fp]>; + +DESCRIPTION +<> writes the wide character argument <[wc]> to the file or +stream identified by <[fp]>. + +If the file was opened with append mode (or if the stream cannot +support positioning), then the new wide character goes at the end of the +file or stream. Otherwise, the new wide character is written at the +current value of the position indicator, and the position indicator +oadvances by one. + +The <> function or macro functions identically to <>. It +may be implemented as a macro, and may evaluate its argument more than +once. There is no reason ever to use it. + +The <<_fputwc_r>> and <<_putwc_r>> functions are simply reentrant versions +of <> and <> that take an additional reentrant structure +argument: <[ptr]>. + +RETURNS +If successful, <> and <> return their argument <[wc]>. +If an error intervenes, the result is <>. You can use +`<)>>' to query for errors. + +PORTABILITY +C99, POSIX.1-2001 +*/ + +#include <_ansi.h> +#include +#include +#include +#include +#include +#include +#include "local.h" + +static wint_t +_DEFUN(__fputwc, (ptr, wc, fp), + struct _reent *ptr _AND + wchar_t wc _AND + FILE *fp) +{ + char buf[MB_LEN_MAX]; + size_t i, len; + + if (MB_CUR_MAX == 1 && wc > 0 && wc <= UCHAR_MAX) + { + /* + * Assume single-byte locale with no special encoding. + * A more careful test would be to check + * _CurrentRuneLocale->encoding. + */ + *buf = (unsigned char)wc; + len = 1; + } + else + { + if ((len = _wcrtomb_r (ptr, buf, wc, &fp->_mbstate)) == (size_t) -1) + { + fp->_flags |= __SERR; + return WEOF; + } + } + + for (i = 0; i < len; i++) + if (__sputc_r (ptr, (unsigned char) buf[i], fp) == EOF) + return WEOF; + + return (wint_t) wc; +} + +wint_t +_DEFUN(_fputwc_r, (ptr, wc, fp), + struct _reent *ptr _AND + wchar_t wc _AND + FILE *fp) +{ + wint_t r; + + _flockfile (fp); + ORIENT(fp, 1); + r = __fputwc(ptr, wc, fp); + _funlockfile (fp); + return r; +} + +wint_t +_DEFUN(fputwc, (wc, fp), + wchar_t wc _AND + FILE *fp) +{ + CHECK_INIT(_REENT, fp); + return _fputwc_r (_REENT, wc, fp); +} diff --git a/newlib/libc/stdio/fputws.c b/newlib/libc/stdio/fputws.c new file mode 100644 index 000000000..596081806 --- /dev/null +++ b/newlib/libc/stdio/fputws.c @@ -0,0 +1,122 @@ +/*- + * Copyright (c) 2002-2004 Tim J. Robbins. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* +FUNCTION +<>---write a wide character string in a file or stream + +INDEX + fputws +INDEX + _fputws_r + +ANSI_SYNOPSIS + #include + int fputws(const wchar_t *<[ws]>, FILE *<[fp]>); + + #include + int _fputws_r(struct _reent *<[ptr]>, const wchar_t *<[ws]>, FILE *<[fp]>); + +TRAD_SYNOPSIS + #include + int fputws(<[ws]>, <[fp]>) + wchar_t *<[ws]>; + FILE *<[fp]>; + + #include + int _fputws_r(<[ptr]>, <[ws]>, <[fp]>) + struct _reent *<[ptr]>; + wchar_t *<[ws]>; + FILE *<[fp]>; + +DESCRIPTION +<> writes the wide character string at <[ws]> (but without the +trailing null) to the file or stream identified by <[fp]>. + +<<_fputws_r>> is simply the reentrant version of <> that takes +an additional reentrant struct pointer argument: <[ptr]>. + +RETURNS +If successful, the result is a non-negative integer; otherwise, the result +is <<-1>> to indicate an error. + +PORTABILITY +C99, POSIX.1-2001 +*/ + +#include <_ansi.h> +#include +#include +#include +#include +#include +#include "fvwrite.h" +#include "local.h" + +int +_DEFUN(_fputws_r, (ptr, ws, fp), + struct _reent *ptr _AND + const wchar_t *ws _AND + FILE *fp) +{ + size_t nbytes; + char buf[BUFSIZ]; + struct __suio uio; + struct __siov iov; + + _flockfile (fp); + ORIENT (fp, 1); + if (cantwrite (ptr, fp) != 0) + goto error; + uio.uio_iov = &iov; + uio.uio_iovcnt = 1; + iov.iov_base = buf; + do + { + nbytes = _wcsrtombs_r(ptr, buf, &ws, sizeof (buf), &fp->_mbstate); + if (nbytes == (size_t) -1) + goto error; + iov.iov_len = uio.uio_resid = nbytes; + if (__sfvwrite_r(ptr, fp, &uio) != 0) + goto error; + } + while (ws != NULL); + _funlockfile (fp); + return (0); + +error: + _funlockfile(fp); + return (-1); +} + +int +_DEFUN(fputws, (ws, fp), + const wchar_t *ws _AND + FILE *fp) +{ + CHECK_INIT (_REENT, fp); + return _fputws_r (_REENT, ws, fp); +} diff --git a/newlib/libc/stdio/fread.c b/newlib/libc/stdio/fread.c index 8c0697c5c..15b48bb8b 100644 --- a/newlib/libc/stdio/fread.c +++ b/newlib/libc/stdio/fread.c @@ -147,6 +147,7 @@ _DEFUN(_fread_r, (ptr, buf, size, count, fp), CHECK_INIT(ptr, fp); _flockfile (fp); + ORIENT (fp, -1); if (fp->_r < 0) fp->_r = 0; total = resid; diff --git a/newlib/libc/stdio/freopen.c b/newlib/libc/stdio/freopen.c index 2a0d36247..0d2563b0b 100644 --- a/newlib/libc/stdio/freopen.c +++ b/newlib/libc/stdio/freopen.c @@ -201,6 +201,9 @@ _DEFUN(_freopen_r, (ptr, file, mode, fp), if (HASLB (fp)) FREELB (ptr, fp); fp->_lb._size = 0; + fp->_flags & ~__SORD; + fp->_flags2 = 0; + memset (&fp->_mbstate, 0, sizeof (_mbstate_t)); if (f < 0) { /* did not get it after all */ diff --git a/newlib/libc/stdio/fseek.c b/newlib/libc/stdio/fseek.c index 06c66654e..d7f8ab83f 100644 --- a/newlib/libc/stdio/fseek.c +++ b/newlib/libc/stdio/fseek.c @@ -316,6 +316,7 @@ _DEFUN(_fseek_r, (ptr, fp, offset, whence), if (HASUB (fp)) FREEUB (ptr, fp); fp->_flags &= ~__SEOF; + memset (&fp->_mbstate, 0, sizeof (_mbstate_t)); _funlockfile (fp); return 0; } @@ -345,6 +346,7 @@ _DEFUN(_fseek_r, (ptr, fp, offset, whence), fp->_p += n; fp->_r -= n; } + memset (&fp->_mbstate, 0, sizeof (_mbstate_t)); _funlockfile (fp); return 0; @@ -374,6 +376,7 @@ dumb: optimization is then allowed if no subsequent flush is performed. */ fp->_flags &= ~__SNPT; + memset (&fp->_mbstate, 0, sizeof (_mbstate_t)); _funlockfile (fp); return 0; } diff --git a/newlib/libc/stdio/fwide.c b/newlib/libc/stdio/fwide.c new file mode 100644 index 000000000..b81327ada --- /dev/null +++ b/newlib/libc/stdio/fwide.c @@ -0,0 +1,88 @@ +/* +FUNCTION +<>---set and determine the orientation of a FILE stream + +INDEX + fwide +INDEX + _fwide_r + +ANSI_SYNOPSIS + #include + int fwide(FILE *<[fp]>, int <[mode]>) + + int _fwide_r(struct _reent *<[ptr]>, FILE *<[fp]>, int <[mode]>) + +TRAD_SYNOPSIS + #include + int fwide(<[fp]>, <[mode]>) + FILE *<[fp]>; + int <[mode]>; + + int fwide(<[ptr]>, <[fp]>, <[mode]>) + struct _reent *<[ptr]>; + FILE *<[fp]>; + int <[mode]>; + +DESCRIPTION +When <[mode]> is zero, the <> function determines the current +orientation of <[fp]>. It returns a value > 0 if <[fp]> is +wide-character oriented, i.e. if wide character I/O is permitted but +char I/O is disallowed. It returns a value < 0 if <[fp]> is byte +oriented, i.e. if char I/O is permitted but wide character I/O is +disallowed. It returns zero if <[fp]> has no orientation yet; in +this case the next I/O operation might change the orientation (to byte +oriented if it is a char I/O operation, or to wide-character oriented +if it is a wide character I/O operation). + +Once a stream has an orientation, it cannot be changed and persists +until the stream is closed, unless the stream is re-opened with freopen, +which removes the orientation of the stream. + +When <[mode]> is non-zero, the <> function first attempts to set +<[fp]>'s orientation (to wide-character oriented if <[mode]> > 0, or to +byte oriented if <[mode]> < 0). It then returns a value denoting the +current orientation, as above. + +RETURNS +The <> function returns <[fp]>'s orientation, after possibly +changing it. A return value > 0 means wide-character oriented. A return +value < 0 means byte oriented. A return value of zero means undecided. + +PORTABILITY +C99, POSIX.1-2001. + +*/ + +#include <_ansi.h> +#include "local.h" + +int +_DEFUN(_fwide_r, (ptr, fp, mode), + struct _reent *ptr _AND + FILE *fp _AND + int mode) +{ + int ret; + + CHECK_INIT(ptr, fp); + + _flockfile (fp); + if (mode != 0) { + ORIENT (fp, mode); + } + if (!(fp->_flags & __SORD)) + ret = 0; + else + ret = (fp->_flags2 & __SWID) ? 1 : -1; + _funlockfile (fp); + return ret; +} + +int +_DEFUN(fwide, (fp, mode), + FILE *fp _AND + int mode) +{ + return _fwide_r (_REENT, fp, mode); +} diff --git a/newlib/libc/stdio/fwrite.c b/newlib/libc/stdio/fwrite.c index 3443d95d1..ce77c8dc1 100644 --- a/newlib/libc/stdio/fwrite.c +++ b/newlib/libc/stdio/fwrite.c @@ -120,6 +120,7 @@ _DEFUN(_fwrite_r, (ptr, buf, size, count, fp), CHECK_INIT(ptr, fp); _flockfile (fp); + ORIENT (fp, -1); if (__sfvwrite_r (ptr, fp, &uio) == 0) { _funlockfile (fp); diff --git a/newlib/libc/stdio/getwc.c b/newlib/libc/stdio/getwc.c new file mode 100644 index 000000000..6d88fa869 --- /dev/null +++ b/newlib/libc/stdio/getwc.c @@ -0,0 +1,52 @@ +/*- + * Copyright (c) 2002 Tim J. Robbins. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <_ansi.h> +#include +#include +#include +#include "local.h" + +#undef getwc + +wint_t +_DEFUN(_getwc_r, (ptr, fp), + struct _reent *ptr _AND + FILE *fp) +{ + return _fgetwc_r (ptr, fp); +} + +/* + * Synonym for fgetwc(). The only difference is that getwc(), if it is a + * macro, may evaluate `fp' more than once. + */ +wint_t +_DEFUN(getwc, (fp), + FILE *fp) +{ + return fgetwc(fp); +} diff --git a/newlib/libc/stdio/getwchar.c b/newlib/libc/stdio/getwchar.c new file mode 100644 index 000000000..c55bf1b83 --- /dev/null +++ b/newlib/libc/stdio/getwchar.c @@ -0,0 +1,93 @@ +/*- + * Copyright (c) 2002 Tim J. Robbins. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* +FUNCTION +<>---read a wide character from standard input + +INDEX + getwchar +INDEX + _getwchar_r + +ANSI_SYNOPSIS + #include + wint_t getwchar(void); + + wint_t _getwchar_r(struct _reent *<[reent]>); + +TRAD_SYNOPSIS + #include + wint_t getwchar(); + + wint_t _getwchar_r(<[reent]>) + char * <[reent]>; + +DESCRIPTION +<> function or macro is the wide character equivalent of +the <> function. You can use <> to get the next +wide character from the standard input stream. As a side effect, +<> advances the standard input's current position indicator. + +The alternate function <<_getwchar_r>> is a reentrant version. The +extra argument <[reent]> is a pointer to a reentrancy structure. + +RETURNS +The next wide character cast to <>), unless there is no more +data, or the host system reports a read error; in either of these +situations, <> returns <>. + +You can distinguish the two situations that cause an <> result by +using `<>' and `<>'. + +PORTABILITY +C99 +*/ + +#include <_ansi.h> +#include +#include +#include +#include "local.h" + +#undef getwchar + +wint_t +_DEFUN (_getwchar_r, (ptr), + struct _reent *ptr) +{ + return _fgetwc_r (ptr, stdin); +} + +/* + * Synonym for fgetwc(stdin). + */ +wint_t +_DEFUN_VOID (getwchar) +{ + _REENT_SMALL_CHECK_INIT (_REENT); + return fgetwc (stdin); +} diff --git a/newlib/libc/stdio/local.h b/newlib/libc/stdio/local.h index 71d579ee0..8b1516f01 100644 --- a/newlib/libc/stdio/local.h +++ b/newlib/libc/stdio/local.h @@ -123,6 +123,24 @@ extern _READ_WRITE_RETURN_TYPE _EXFUN(__swrite64,(struct _reent *, void *, #define FREELB(ptr, fp) { _free_r(ptr,(char *)(fp)->_lb._base); \ (fp)->_lb._base = NULL; } +/* + * Set the orientation for a stream. If o > 0, the stream has wide- + * orientation. If o < 0, the stream has byte-orientation. + */ +#define ORIENT(fp,ori) \ + do \ + { \ + if (!((fp)->_flags & __SORD)) \ + { \ + (fp)->_flags |= __SORD; \ + if (ori > 0) \ + (fp)->_flags2 |= __SWID; \ + else \ + (fp)->_flags2 &= ~__SWID; \ + } \ + } \ + while (0) + /* WARNING: _dcvt is defined in the stdlib directory, not here! */ char *_EXFUN(_dcvt,(struct _reent *, char *, double, int, int, char, int)); diff --git a/newlib/libc/stdio/puts.c b/newlib/libc/stdio/puts.c index e6c4d2e14..66291cd13 100644 --- a/newlib/libc/stdio/puts.c +++ b/newlib/libc/stdio/puts.c @@ -89,8 +89,8 @@ _DEFUN(_puts_r, (ptr, s), uio.uio_resid = c + 1; uio.uio_iov = &iov[0]; uio.uio_iovcnt = 2; - _REENT_SMALL_CHECK_INIT (ptr); + ORIENT (stdout, -1); return (__sfvwrite_r (ptr, _stdout_r (ptr), &uio) ? EOF : '\n'); } diff --git a/newlib/libc/stdio/putwc.c b/newlib/libc/stdio/putwc.c new file mode 100644 index 000000000..9a84f35fb --- /dev/null +++ b/newlib/libc/stdio/putwc.c @@ -0,0 +1,53 @@ +/*- + * Copyright (c) 2002 Tim J. Robbins. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <_ansi.h> +#include +#include +#include +#include "local.h" + +#undef putwc + +wint_t +_DEFUN(_putwc_r, (ptr, wc, fp), + struct _reent *ptr _AND + wchar_t wc _AND + FILE *fp) +{ + return _fputwc_r (ptr, wc, fp); +} +/* + * Synonym for fputwc(). The only difference is that putwc(), if it is a + * macro, may evaluate `fp' more than once. + */ +wint_t +_DEFUN(putwc, (wc, fp), + wchar_t wc _AND + FILE *fp) +{ + return fputwc (wc, fp); +} diff --git a/newlib/libc/stdio/putwchar.c b/newlib/libc/stdio/putwchar.c new file mode 100644 index 000000000..12c9f09cc --- /dev/null +++ b/newlib/libc/stdio/putwchar.c @@ -0,0 +1,92 @@ +/*- + * Copyright (c) 2002 Tim J. Robbins. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* +FUNCTION +<>---write a wide character to standard output + +INDEX + putwchar +INDEX + _putwchar_r + +ANSI_SYNOPSIS + #include + wint_t putwchar(wchar_t <[wc]>); + + wint_t _putwchar_r(struct _reent *<[reent]>, wchar_t <[wc]>); + +TRAD_SYNOPSIS + #include + wint_t putwchar(<[wc]>) + wchar_t <[wc]>; + + wint_t _putwchar_r(<[reent]>, <[wc]>) + struct _reent *<[reent]>; + wchar_t <[wc]>; + +DESCRIPTION +The <> function or macro is the wide-character equivalent of +the <> function. It writes the wide character wc to stdout. + +The alternate function <<_putwchar_r>> is a reentrant version. The +extra argument <[reent]> is a pointer to a reentrancy structure. + +RETURNS +If successful, <> returns its argument <[wc]>. If an error +intervenes, the result is <>. You can use `<>' to +query for errors. + +PORTABILITY +C99 +*/ + +#include <_ansi.h> +#include +#include +#include +#include "local.h" + +#undef putwchar + +wint_t +_DEFUN(_putwchar_r, (ptr, wc), + struct _reent *ptr _AND + wchar_t wc) +{ + return _fputwc_r (ptr, wc, stdout); +} + +/* + * Synonym for fputwc(wc, stdout). + */ +wint_t +_DEFUN(putwchar, (wc), + wchar_t wc) +{ + _REENT_SMALL_CHECK_INIT (_REENT); + return fputwc (wc, stdout); +} diff --git a/newlib/libc/stdio/refill.c b/newlib/libc/stdio/refill.c index 9e76e668a..27266ce70 100644 --- a/newlib/libc/stdio/refill.c +++ b/newlib/libc/stdio/refill.c @@ -45,6 +45,8 @@ _DEFUN(__srefill_r, (ptr, fp), CHECK_INIT (ptr, fp); + ORIENT (fp, -1); + fp->_r = 0; /* largely a convenience for callers */ #ifndef __CYGWIN__ diff --git a/newlib/libc/stdio/stdio.tex b/newlib/libc/stdio/stdio.tex index 582f43e37..b738b9278 100644 --- a/newlib/libc/stdio/stdio.tex +++ b/newlib/libc/stdio/stdio.tex @@ -36,18 +36,23 @@ structure. * fgetc:: Get a character from a file or stream * fgetpos:: Record position in a stream or file * fgets:: Get character string from a file or stream +* fgetwc:: Get a wide character from a file or stream +* fgetws:: Get a wide character string from a file or stream * fileno:: Get file descriptor associated with stream * fmemopen:: Open a stream around a fixed-length buffer * fopen:: Open a file * fopencookie:: Open a stream with custom callbacks * fputc:: Write a character on a stream or file * fputs:: Write a character string in a file or stream +* fputwc:: Write a wide character to a file or stream +* fputws:: Write a wide character string to a file or stream * fread:: Read array elements from a file * freopen:: Open a file using an existing file descriptor * fseek:: Set file position * fsetpos:: Restore position of a stream or file * ftell:: Return position in a stream or file * funopen:: Open a stream with custom callbacks +* fwide:: Set and determine the orientation of a FILE stream * fwrite:: Write array elements from memory to a file or stream * getc:: Get a character from a file or stream (macro) * getc_unlocked:: Get a character from a file or stream (macro) @@ -57,6 +62,8 @@ structure. * getline:: Get character string from a file or stream * gets:: Get character string from standard input (obsolete) * getw:: Get a word (int) from a file or stream +* getwc:: Get a wide character from a file or stream +* getwchar:: Get a wide character from standard input * mktemp:: Generate unused file name * open_memstream:: Open a write stream around an arbitrary-length buffer * perror:: Print an error message on standard error @@ -66,6 +73,8 @@ structure. * putchar_unlocked:: Write a character on standard output (macro) * puts:: Write a character string on standard output * putw:: Write a word (int) to a file or stream +* putwc:: Write a wide character to a file or stream +* putwchar:: Write a wide character to standard output * remove:: Delete a file's name * rename:: Rename a file * rewind:: Reinitialize a file or stream @@ -80,6 +89,7 @@ structure. * tmpfile:: Create a temporary file * tmpnam:: Generate name for a temporary file * ungetc:: Push data back into a stream +* ungetwc:: Push wide character data back into a stream * vfprintf:: Format variable argument list * vfscanf:: Scan variable argument list * viprintf:: Format variable argument list (integer only) @@ -122,6 +132,12 @@ structure. @page @include stdio/fgets.def +@page +@include stdio/fgetwc.def + +@page +@include stdio/fgetws.def + @page @include stdio/fileno.def @@ -140,6 +156,12 @@ structure. @page @include stdio/fputs.def +@page +@include stdio/fputwc.def + +@page +@include stdio/fputws.def + @page @include stdio/fread.def @@ -158,6 +180,9 @@ structure. @page @include stdio/funopen.def +@page +@include stdio/fwide.def + @page @include stdio/fwrite.def @@ -185,6 +210,9 @@ structure. @page @include stdio/getw.def +@page +@include stdio/getwchar.def + @page @include stdio/mktemp.def @@ -212,6 +240,9 @@ structure. @page @include stdio/putw.def +@page +@include stdio/putwchar.def + @page @include stdio/remove.def @@ -254,6 +285,9 @@ structure. @page @include stdio/ungetc.def +@page +@include stdio/ungetwc.def + @page @include stdio/vfprintf.def diff --git a/newlib/libc/stdio/ungetc.c b/newlib/libc/stdio/ungetc.c index d65cddab6..0339a3d0c 100644 --- a/newlib/libc/stdio/ungetc.c +++ b/newlib/libc/stdio/ungetc.c @@ -127,6 +127,8 @@ _DEFUN(_ungetc_r, (rptr, c, fp), _flockfile (fp); + ORIENT (fp, -1); + /* After ungetc, we won't be at eof anymore */ fp->_flags &= ~__SEOF; diff --git a/newlib/libc/stdio/ungetwc.c b/newlib/libc/stdio/ungetwc.c new file mode 100644 index 000000000..234d2f7ef --- /dev/null +++ b/newlib/libc/stdio/ungetwc.c @@ -0,0 +1,115 @@ +/*- + * Copyright (c) 2002-2004 Tim J. Robbins. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* +FUNCTION +<>---push wide character data back into a stream + +INDEX + ungetwc +INDEX + _ungetwc_r + +ANSI_SYNOPSIS + #include + #include + wint_t ungetwc(wint_t <[wc]>, FILE *<[stream]>); + + wint_t _ungetwc_r(struct _reent *<[reent]>, wint_t <[wc]>, FILE *<[stream]>); + +DESCRIPTION +<> is used to return wide characters back to <[stream]> to be +read again. If <[wc]> is WEOF, the stream is unchanged. Otherwise, the +wide character <[wc]> is put back on the stream, and subsequent reads will see +the wide chars pushed back in reverse order. Pushed wide chars are lost if the +stream is repositioned, such as by <>, <>, or +<>. + +The underlying file is not changed, but it is possible to push back +something different than what was originally read. Ungetting a +character will clear the end-of-stream marker, and decrement the file +position indicator. Pushing back beyond the beginning of a file gives +unspecified behavior. + +The alternate function <<_ungetwc_r>> is a reentrant version. The +extra argument <[reent]> is a pointer to a reentrancy structure. + +RETURNS +The wide character pushed back, or <> on error. + +PORTABILITY +C99 +*/ + +#include <_ansi.h> +#include +#include +#include +#include +#include +#include +#include "local.h" + +wint_t +_DEFUN(_ungetwc_r, (ptr, wc, fp), + struct _reent *ptr _AND + wint_t wc _AND + register FILE *fp) +{ + char buf[MB_LEN_MAX]; + size_t len; + + _flockfile (fp); + ORIENT (fp, 1); + if (wc == WEOF) + wc = WEOF; + else if ((len = _wcrtomb_r(ptr, buf, wc, &fp->_mbstate)) == (size_t)-1) + { + fp->_flags |= __SERR; + wc = WEOF; + } + else + while (len-- != 0) + if (_ungetc_r(ptr, (unsigned char)buf[len], fp) == EOF) + { + wc = WEOF; + break; + } + _funlockfile (fp); + return wc; +} + +/* + * MT-safe version. + */ +wint_t +_DEFUN(ungetwc, (wint_t wc, FILE *fp), + wint_t wc _AND + FILE *fp) +{ + CHECK_INIT (_REENT, fp); + return _ungetwc_r (_REENT, wc, fp); +} diff --git a/newlib/libc/stdio/vfprintf.c b/newlib/libc/stdio/vfprintf.c index 32fc202d5..ac1d919b8 100644 --- a/newlib/libc/stdio/vfprintf.c +++ b/newlib/libc/stdio/vfprintf.c @@ -637,6 +637,8 @@ _DEFUN(_VFPRINTF_R, (data, fp, fmt0, ap), CHECK_INIT (data, fp); _flockfile (fp); + ORIENT(fp, -1); + /* sorry, fprintf(read_only_file, "") returns EOF, not 0 */ if (cantwrite (data, fp)) { _funlockfile (fp); diff --git a/newlib/libc/stdio/vfscanf.c b/newlib/libc/stdio/vfscanf.c index 0b5e9750b..cad50988f 100644 --- a/newlib/libc/stdio/vfscanf.c +++ b/newlib/libc/stdio/vfscanf.c @@ -492,6 +492,8 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap), _flockfile (fp); + ORIENT (fp, -1); + nassigned = 0; nread = 0; for (;;) diff --git a/newlib/libc/stdio/wbuf.c b/newlib/libc/stdio/wbuf.c index bd7f15d9b..33457f0d0 100644 --- a/newlib/libc/stdio/wbuf.c +++ b/newlib/libc/stdio/wbuf.c @@ -61,6 +61,8 @@ _DEFUN(__swbuf_r, (ptr, c, fp), } c = (unsigned char) c; + ORIENT (fp, -1); + /* * If it is completely full, flush it out. Then, in any case, * stuff c into the buffer. If this causes the buffer to fill