diff --git a/newlib/ChangeLog b/newlib/ChangeLog index 4fd0c791d..c2212f68e 100644 --- a/newlib/ChangeLog +++ b/newlib/ChangeLog @@ -1,3 +1,37 @@ +2009-03-06 Corinna Vinschen + + * libc/include/wchar.h (fwscanf, swscanf, vfwscanf, vswscanf, vwscanf, + wscanf): Declare. + (_fwscanf_r, _swscanf_r, _vfwscanf_r, _vswscanf_r, _vwscanf_r, + _wscanf_r): Declare. + * libc/stdio/Makefile.am: Add new wscanf files. + * libc/stdio/Makefile.in: Regenerate. + * libc/stdio/fwscanf.c: New file. + * libc/stdio/local.h (__svfwscanf_r, __ssvfwscanf_r, __svfiwscanf_r, + __ssvfiwscanf_r): Declare. + * libc/stdio/stdio.tex: Add new documentation references. + * libc/stdio/swscanf.c: New file. + * libc/stdio/vfwscanf.c: New file. + * libc/stdio/vswscanf.c: New file. + * libc/stdio/vwscanf.c: New file. + * libc/stdio/wscanf.c: New file. + + * libc/stdio/vfscanf.c (_sungetc_r): Make externaly available. Only + define if INTEGER_ONLY is defined. Declare otherwise. + (__ssrefill_r): Ditto. + (_sfread_r): Ditto. + + Remove static eofread/eofread1 functions and use __seofread + function instead, throughout. + * libc/stdio/local.h (__seofread): Declare. + * libc/stdio/stdio.c (__seofread): Define. + + * libc/stdio/fgetwc.c (__fgetwc): Fix compiler warning. + * libc/stdio/fgetws.c (_fgetws_r): Ditto. + * libc/stdio/fread.c (_fread_r): Ditto. + * libc/stdio/vfprintf.c: Ditto. + * libc/stdio/vswprintf.c: Ditto. + 2009-03-09 Brooks Moses * libc/machine/arm/arm_asm.h: Fix typo. @@ -29,7 +63,7 @@ * libc/include/stdio.h (__VALIST): Guard against multiple definition. * libc/include/wchar.h: Include stdarg.h. (__VALIST): Define conditionally. - (fwprintf, swprintf, vfwprintf, vswprintf, vwprintf, wprintf: Declare. + (fwprintf, swprintf, vfwprintf, vswprintf, vwprintf, wprintf): Declare. (_fwprintf_r, _swprintf_r, _vfwprintf_r, _vswprintf_r, _vwprintf_r, _wprintf_r): Declare. * libc/stdio/Makefile.am: Add new files. diff --git a/newlib/libc/include/wchar.h b/newlib/libc/include/wchar.h index bce08bac0..133af8c98 100644 --- a/newlib/libc/include/wchar.h +++ b/newlib/libc/include/wchar.h @@ -155,6 +155,20 @@ int _EXFUN(_vswprintf_r, (struct _reent *, wchar_t *, size_t, const wchar_t *, _ int _EXFUN(_vwprintf_r, (struct _reent *, const wchar_t *, __VALIST)); int _EXFUN(_wprintf_r, (struct _reent *, const wchar_t *, ...)); +int _EXFUN(fwscanf, (__FILE *, const wchar_t *, ...)); +int _EXFUN(swscanf, (const wchar_t *, const wchar_t *, ...)); +int _EXFUN(vfwscanf, (__FILE *, const wchar_t *, __VALIST)); +int _EXFUN(vswscanf, (const wchar_t *, const wchar_t *, __VALIST)); +int _EXFUN(vwscanf, (const wchar_t *, __VALIST)); +int _EXFUN(wscanf, (const wchar_t *, ...)); + +int _EXFUN(_fwscanf_r, (struct _reent *, __FILE *, const wchar_t *, ...)); +int _EXFUN(_swscanf_r, (struct _reent *, const wchar_t *, const wchar_t *, ...)); +int _EXFUN(_vfwscanf_r, (struct _reent *, __FILE *, const wchar_t *, __VALIST)); +int _EXFUN(_vswscanf_r, (struct _reent *, const wchar_t *, const wchar_t *, __VALIST)); +int _EXFUN(_vwscanf_r, (struct _reent *, const wchar_t *, __VALIST)); +int _EXFUN(_wscanf_r, (struct _reent *, const wchar_t *, ...)); + #define getwc(fp) fgetwc(fp) #define putwc(wc,fp) fputwc((wc), (fp)) #ifndef _REENT_ONLY diff --git a/newlib/libc/stdio/Makefile.am b/newlib/libc/stdio/Makefile.am index 23840bcee..b5895833e 100644 --- a/newlib/libc/stdio/Makefile.am +++ b/newlib/libc/stdio/Makefile.am @@ -126,18 +126,24 @@ ELIX_4_SOURCES = \ funopen.c \ fwide.c \ fwprintf.c \ + fwscanf.c \ getwc.c \ getwchar.c \ open_memstream.c \ putwc.c \ putwchar.c \ swprintf.c \ + swscanf.c \ ungetwc.c \ vasniprintf.c \ vasnprintf.c \ + vfwscanf.c \ vswprintf.c \ + vswscanf.c \ vwprintf.c \ - wprintf.c + vwscanf.c \ + wprintf.c \ + wscanf.c endif !ELIX_LEVEL_3 endif !ELIX_LEVEL_2 @@ -149,7 +155,9 @@ LIBADD_OBJS = \ $(lpfx)vfiprintf.$(oext) $(lpfx)vfprintf.$(oext) \ $(lpfx)vfscanf.$(oext) $(lpfx)vfiscanf.$(oext) \ $(lpfx)svfiwprintf.$(oext) $(lpfx)svfwprintf.$(oext) \ - $(lpfx)vfiwprintf.$(oext) $(lpfx)vfwprintf.$(oext) + $(lpfx)vfiwprintf.$(oext) $(lpfx)vfwprintf.$(oext) \ + $(lpfx)svfiwscanf.$(oext) $(lpfx)svfwscanf.$(oext) \ + $(lpfx)vfiwscanf.$(oext) $(lpfx)vfwscanf.$(oext) libstdio_la_LDFLAGS = -Xcompiler -nostdlib @@ -211,6 +219,18 @@ $(lpfx)svfscanf.$(oext): vfscanf.c $(lpfx)svfiscanf.$(oext): vfscanf.c $(LIB_COMPILE) -DINTEGER_ONLY -DSTRING_ONLY -c $(srcdir)/vfscanf.c -o $@ +$(lpfx)vfwscanf.$(oext): vfwscanf.c + $(LIB_COMPILE) -c $(srcdir)/vfwscanf.c -o $@ + +$(lpfx)vfiwscanf.$(oext): vfwscanf.c + $(LIB_COMPILE) -DINTEGER_ONLY -c $(srcdir)/vfwscanf.c -o $@ + +$(lpfx)svfwscanf.$(oext): vfwscanf.c + $(LIB_COMPILE) -DSTRING_ONLY -c $(srcdir)/vfwscanf.c -o $@ + +$(lpfx)svfiwscanf.$(oext): vfwscanf.c + $(LIB_COMPILE) -DINTEGER_ONLY -DSTRING_ONLY -c $(srcdir)/vfwscanf.c -o $@ + CHEWOUT_FILES = \ clearerr.def \ diprintf.def \ @@ -275,6 +295,7 @@ CHEWOUT_FILES = \ sprintf.def \ sscanf.def \ swprintf.def \ + swscanf.def \ tmpfile.def \ tmpnam.def \ ungetc.def \ @@ -282,6 +303,7 @@ CHEWOUT_FILES = \ vfprintf.def \ vfscanf.def \ vfwprintf.def \ + vfwscanf.def \ viprintf.def \ viscanf.def @@ -322,6 +344,7 @@ $(lpfx)fwalk.$(oext): local.h $(lpfx)fwide.$(oext): local.h $(lpfx)fwprintf.$(oext): local.h $(lpfx)fwrite.$(oext): local.h fvwrite.h +$(lpfx)fwscanf.$(oext): local.h $(lpfx)getwc.$(oext): local.h $(lpfx)getwchar.$(oext): local.h $(lpfx)iscanf.$(oext): local.h @@ -345,6 +368,7 @@ $(lpfx)svfiscanf.$(oext): local.h floatio.h $(lpfx)svfprintf.$(oext): local.h $(lpfx)svfscanf.$(oext): local.h floatio.h $(lpfx)swprintf.$(oext): local.h +$(lpfx)swscanf.$(oext): local.h $(lpfx)ungetc.$(oext): local.h $(lpfx)ungetwc.$(oext): local.h $(lpfx)vfiprintf.$(oext): local.h @@ -352,13 +376,17 @@ $(lpfx)vfiscanf.$(oext): local.h floatio.h $(lpfx)vfprintf.$(oext): local.h $(lpfx)vfscanf.$(oext): local.h floatio.h $(lpfx)vfwprintf.$(oext): local.h +$(lpfx)vfwscanf.$(oext): local.h $(lpfx)viscanf.$(oext): local.h $(lpfx)vscanf.$(oext): local.h $(lpfx)vsiscanf.$(oext): local.h $(lpfx)vsniprintf.$(oext): local.h $(lpfx)vsscanf.$(oext): local.h $(lpfx)vswprintf.$(oext): local.h +$(lpfx)vswscanf.$(oext): local.h $(lpfx)vwprintf.$(oext): local.h +$(lpfx)vwscanf.$(oext): local.h $(lpfx)wbuf.$(oext): local.h fvwrite.h $(lpfx)wprintf.$(oext): local.h +$(lpfx)wscanf.$(oext): local.h $(lpfx)wsetup.$(oext): local.h diff --git a/newlib/libc/stdio/Makefile.in b/newlib/libc/stdio/Makefile.in index a40e8af22..3dead2c65 100644 --- a/newlib/libc/stdio/Makefile.in +++ b/newlib/libc/stdio/Makefile.in @@ -38,6 +38,7 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ +LIBOBJDIR = DIST_COMMON = $(srcdir)/../../Makefile.shared $(srcdir)/Makefile.in \ $(srcdir)/Makefile.am subdir = stdio @@ -62,7 +63,9 @@ am__DEPENDENCIES_1 = $(lpfx)svfiprintf.$(oext) \ $(lpfx)vfprintf.$(oext) $(lpfx)vfscanf.$(oext) \ $(lpfx)vfiscanf.$(oext) $(lpfx)svfiwprintf.$(oext) \ $(lpfx)svfwprintf.$(oext) $(lpfx)vfiwprintf.$(oext) \ - $(lpfx)vfwprintf.$(oext) + $(lpfx)vfwprintf.$(oext) $(lpfx)svfiwscanf.$(oext) \ + $(lpfx)svfwscanf.$(oext) $(lpfx)vfiwscanf.$(oext) \ + $(lpfx)vfwscanf.$(oext) am__objects_1 = lib_a-clearerr.$(OBJEXT) lib_a-fclose.$(OBJEXT) \ lib_a-fdopen.$(OBJEXT) lib_a-feof.$(OBJEXT) \ lib_a-ferror.$(OBJEXT) lib_a-fflush.$(OBJEXT) \ @@ -126,18 +129,24 @@ 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-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-fwprintf.$(OBJEXT) \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-fwscanf.$(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-swprintf.$(OBJEXT) \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-swscanf.$(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) \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-vfwscanf.$(OBJEXT) \ @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-vswprintf.$(OBJEXT) \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-vswscanf.$(OBJEXT) \ @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-vwprintf.$(OBJEXT) \ -@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-wprintf.$(OBJEXT) +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-vwscanf.$(OBJEXT) \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-wprintf.$(OBJEXT) \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-wscanf.$(OBJEXT) @USE_LIBTOOL_FALSE@am_lib_a_OBJECTS = $(am__objects_1) \ @USE_LIBTOOL_FALSE@ $(am__objects_2) $(am__objects_3) lib_a_OBJECTS = $(am_lib_a_OBJECTS) @@ -173,19 +182,25 @@ 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@ 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@ fwprintf.c \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ fwprintf.lo \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ fwscanf.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@ swprintf.c \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ swprintf.lo \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ swscanf.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 \ -@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ vswprintf.c \ -@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ vwprintf.c \ -@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ wprintf.c +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ vfwscanf.lo \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ vswprintf.lo \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ vswscanf.lo \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ vwprintf.lo \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ vwscanf.lo \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ wprintf.lo \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ wscanf.lo @USE_LIBTOOL_TRUE@am_libstdio_la_OBJECTS = $(am__objects_4) \ @USE_LIBTOOL_TRUE@ $(am__objects_5) $(am__objects_6) libstdio_la_OBJECTS = $(am_libstdio_la_OBJECTS) @@ -314,20 +329,8 @@ STRIP = @STRIP@ USE_LIBTOOL_FALSE = @USE_LIBTOOL_FALSE@ USE_LIBTOOL_TRUE = @USE_LIBTOOL_TRUE@ VERSION = @VERSION@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_AS = @ac_ct_AS@ ac_ct_CC = @ac_ct_CC@ -ac_ct_DLLTOOL = @ac_ct_DLLTOOL@ -ac_ct_DSYMUTIL = @ac_ct_DSYMUTIL@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -ac_ct_LIPO = @ac_ct_LIPO@ -ac_ct_NMEDIT = @ac_ct_NMEDIT@ -ac_ct_OBJDUMP = @ac_ct_OBJDUMP@ -ac_ct_OTOOL = @ac_ct_OTOOL@ -ac_ct_OTOOL64 = @ac_ct_OTOOL64@ -ac_ct_RANLIB = @ac_ct_RANLIB@ -ac_ct_READELF = @ac_ct_READELF@ -ac_ct_STRIP = @ac_ct_STRIP@ aext = @aext@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ @@ -343,6 +346,9 @@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ exec_prefix = @exec_prefix@ extra_dir = @extra_dir@ host = @host@ @@ -350,12 +356,14 @@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ +htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ libm_machine_dir = @libm_machine_dir@ +localedir = @localedir@ localstatedir = @localstatedir@ lpfx = @lpfx@ lt_ECHO = @lt_ECHO@ @@ -365,8 +373,10 @@ mkdir_p = @mkdir_p@ newlib_basedir = @newlib_basedir@ oext = @oext@ oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ +psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ subdirs = @subdirs@ @@ -483,18 +493,24 @@ GENERAL_SOURCES = \ @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@ fwprintf.c \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ fwscanf.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@ swprintf.c \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ swscanf.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 \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ vfwscanf.c \ @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ vswprintf.c \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ vswscanf.c \ @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ vwprintf.c \ -@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ wprintf.c +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ vwscanf.c \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ wprintf.c \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ wscanf.c @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@ELIX_4_SOURCES = @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@ELIX_4_SOURCES = @@ -505,7 +521,9 @@ LIBADD_OBJS = \ $(lpfx)vfiprintf.$(oext) $(lpfx)vfprintf.$(oext) \ $(lpfx)vfscanf.$(oext) $(lpfx)vfiscanf.$(oext) \ $(lpfx)svfiwprintf.$(oext) $(lpfx)svfwprintf.$(oext) \ - $(lpfx)vfiwprintf.$(oext) $(lpfx)vfwprintf.$(oext) + $(lpfx)vfiwprintf.$(oext) $(lpfx)vfwprintf.$(oext) \ + $(lpfx)svfiwscanf.$(oext) $(lpfx)svfwscanf.$(oext) \ + $(lpfx)vfiwscanf.$(oext) $(lpfx)vfwscanf.$(oext) libstdio_la_LDFLAGS = -Xcompiler -nostdlib @USE_LIBTOOL_TRUE@noinst_LTLIBRARIES = libstdio.la @@ -585,6 +603,7 @@ CHEWOUT_FILES = \ sprintf.def \ sscanf.def \ swprintf.def \ + swscanf.def \ tmpfile.def \ tmpnam.def \ ungetc.def \ @@ -592,6 +611,7 @@ CHEWOUT_FILES = \ vfprintf.def \ vfscanf.def \ vfwprintf.def \ + vfwscanf.def \ viprintf.def \ viscanf.def @@ -1272,6 +1292,18 @@ lib_a-fwide.o: 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-fwprintf.o: fwprintf.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-fwprintf.o `test -f 'fwprintf.c' || echo '$(srcdir)/'`fwprintf.c + +lib_a-fwprintf.obj: fwprintf.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-fwprintf.obj `if test -f 'fwprintf.c'; then $(CYGPATH_W) 'fwprintf.c'; else $(CYGPATH_W) '$(srcdir)/fwprintf.c'; fi` + +lib_a-fwscanf.o: fwscanf.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-fwscanf.o `test -f 'fwscanf.c' || echo '$(srcdir)/'`fwscanf.c + +lib_a-fwscanf.obj: fwscanf.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-fwscanf.obj `if test -f 'fwscanf.c'; then $(CYGPATH_W) 'fwscanf.c'; else $(CYGPATH_W) '$(srcdir)/fwscanf.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 @@ -1302,6 +1334,18 @@ lib_a-putwchar.o: 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-swprintf.o: swprintf.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-swprintf.o `test -f 'swprintf.c' || echo '$(srcdir)/'`swprintf.c + +lib_a-swprintf.obj: swprintf.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-swprintf.obj `if test -f 'swprintf.c'; then $(CYGPATH_W) 'swprintf.c'; else $(CYGPATH_W) '$(srcdir)/swprintf.c'; fi` + +lib_a-swscanf.o: swscanf.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-swscanf.o `test -f 'swscanf.c' || echo '$(srcdir)/'`swscanf.c + +lib_a-swscanf.obj: swscanf.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-swscanf.obj `if test -f 'swscanf.c'; then $(CYGPATH_W) 'swscanf.c'; else $(CYGPATH_W) '$(srcdir)/swscanf.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 @@ -1320,17 +1364,11 @@ lib_a-vasnprintf.o: vasnprintf.c lib_a-vasnprintf.obj: vasnprintf.c $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-vasnprintf.obj `if test -f 'vasnprintf.c'; then $(CYGPATH_W) 'vasnprintf.c'; else $(CYGPATH_W) '$(srcdir)/vasnprintf.c'; fi` -lib_a-vwprintf.o: vwprintf.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-vwprintf.o `test -f 'vwprintf.c' || echo '$(srcdir)/'`vwprintf.c +lib_a-vfwscanf.o: vfwscanf.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-vfwscanf.o `test -f 'vfwscanf.c' || echo '$(srcdir)/'`vfwscanf.c -lib_a-vwprintf.obj: vwprintf.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-vwprintf.obj `if test -f 'vwprintf.c'; then $(CYGPATH_W) 'vwprintf.c'; else $(CYGPATH_W) '$(srcdir)/vwprintf.c'; fi` - -lib_a-swprintf.o: swprintf.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-swprintf.o `test -f 'swprintf.c' || echo '$(srcdir)/'`swprintf.c - -lib_a-swprintf.obj: swprintf.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-swprintf.obj `if test -f 'swprintf.c'; then $(CYGPATH_W) 'swprintf.c'; else $(CYGPATH_W) '$(srcdir)/swprintf.c'; fi` +lib_a-vfwscanf.obj: vfwscanf.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-vfwscanf.obj `if test -f 'vfwscanf.c'; then $(CYGPATH_W) 'vfwscanf.c'; else $(CYGPATH_W) '$(srcdir)/vfwscanf.c'; fi` lib_a-vswprintf.o: vswprintf.c $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-vswprintf.o `test -f 'vswprintf.c' || echo '$(srcdir)/'`vswprintf.c @@ -1338,17 +1376,35 @@ lib_a-vswprintf.o: vswprintf.c lib_a-vswprintf.obj: vswprintf.c $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-vswprintf.obj `if test -f 'vswprintf.c'; then $(CYGPATH_W) 'vswprintf.c'; else $(CYGPATH_W) '$(srcdir)/vswprintf.c'; fi` +lib_a-vswscanf.o: vswscanf.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-vswscanf.o `test -f 'vswscanf.c' || echo '$(srcdir)/'`vswscanf.c + +lib_a-vswscanf.obj: vswscanf.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-vswscanf.obj `if test -f 'vswscanf.c'; then $(CYGPATH_W) 'vswscanf.c'; else $(CYGPATH_W) '$(srcdir)/vswscanf.c'; fi` + +lib_a-vwprintf.o: vwprintf.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-vwprintf.o `test -f 'vwprintf.c' || echo '$(srcdir)/'`vwprintf.c + +lib_a-vwprintf.obj: vwprintf.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-vwprintf.obj `if test -f 'vwprintf.c'; then $(CYGPATH_W) 'vwprintf.c'; else $(CYGPATH_W) '$(srcdir)/vwprintf.c'; fi` + +lib_a-vwscanf.o: vwscanf.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-vwscanf.o `test -f 'vwscanf.c' || echo '$(srcdir)/'`vwscanf.c + +lib_a-vwscanf.obj: vwscanf.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-vwscanf.obj `if test -f 'vwscanf.c'; then $(CYGPATH_W) 'vwscanf.c'; else $(CYGPATH_W) '$(srcdir)/vwscanf.c'; fi` + lib_a-wprintf.o: wprintf.c $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-wprintf.o `test -f 'wprintf.c' || echo '$(srcdir)/'`wprintf.c lib_a-wprintf.obj: wprintf.c $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-wprintf.obj `if test -f 'wprintf.c'; then $(CYGPATH_W) 'wprintf.c'; else $(CYGPATH_W) '$(srcdir)/wprintf.c'; fi` -lib_a-fwprintf.o: fwprintf.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-fwprintf.o `test -f 'fwprintf.c' || echo '$(srcdir)/'`fwprintf.c +lib_a-wscanf.o: wscanf.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-wscanf.o `test -f 'wscanf.c' || echo '$(srcdir)/'`wscanf.c -lib_a-fwprintf.obj: fwprintf.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-fwprintf.obj `if test -f 'fwprintf.c'; then $(CYGPATH_W) 'fwprintf.c'; else $(CYGPATH_W) '$(srcdir)/fwprintf.c'; fi` +lib_a-wscanf.obj: wscanf.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-wscanf.obj `if test -f 'wscanf.c'; then $(CYGPATH_W) 'wscanf.c'; else $(CYGPATH_W) '$(srcdir)/wscanf.c'; fi` mostlyclean-libtool: -rm -f *.lo @@ -1357,7 +1413,7 @@ clean-libtool: -rm -rf .libs _libs distclean-libtool: - -rm -f libtool + -rm -f libtool config.lt uninstall-info-am: ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) @@ -1543,6 +1599,18 @@ $(lpfx)svfscanf.$(oext): vfscanf.c $(lpfx)svfiscanf.$(oext): vfscanf.c $(LIB_COMPILE) -DINTEGER_ONLY -DSTRING_ONLY -c $(srcdir)/vfscanf.c -o $@ +$(lpfx)vfwscanf.$(oext): vfwscanf.c + $(LIB_COMPILE) -c $(srcdir)/vfwscanf.c -o $@ + +$(lpfx)vfiwscanf.$(oext): vfwscanf.c + $(LIB_COMPILE) -DINTEGER_ONLY -c $(srcdir)/vfwscanf.c -o $@ + +$(lpfx)svfwscanf.$(oext): vfwscanf.c + $(LIB_COMPILE) -DSTRING_ONLY -c $(srcdir)/vfwscanf.c -o $@ + +$(lpfx)svfiwscanf.$(oext): vfwscanf.c + $(LIB_COMPILE) -DINTEGER_ONLY -DSTRING_ONLY -c $(srcdir)/vfwscanf.c -o $@ + .c.def: $(CHEW) < $< > $*.def 2> $*.ref touch stmp-def @@ -1572,6 +1640,7 @@ $(lpfx)fwalk.$(oext): local.h $(lpfx)fwide.$(oext): local.h $(lpfx)fwprintf.$(oext): local.h $(lpfx)fwrite.$(oext): local.h fvwrite.h +$(lpfx)fwscanf.$(oext): local.h $(lpfx)getwc.$(oext): local.h $(lpfx)getwchar.$(oext): local.h $(lpfx)iscanf.$(oext): local.h @@ -1595,6 +1664,7 @@ $(lpfx)svfiscanf.$(oext): local.h floatio.h $(lpfx)svfprintf.$(oext): local.h $(lpfx)svfscanf.$(oext): local.h floatio.h $(lpfx)swprintf.$(oext): local.h +$(lpfx)swscanf.$(oext): local.h $(lpfx)ungetc.$(oext): local.h $(lpfx)ungetwc.$(oext): local.h $(lpfx)vfiprintf.$(oext): local.h @@ -1602,15 +1672,19 @@ $(lpfx)vfiscanf.$(oext): local.h floatio.h $(lpfx)vfprintf.$(oext): local.h $(lpfx)vfscanf.$(oext): local.h floatio.h $(lpfx)vfwprintf.$(oext): local.h +$(lpfx)vfwscanf.$(oext): local.h $(lpfx)viscanf.$(oext): local.h $(lpfx)vscanf.$(oext): local.h $(lpfx)vsiscanf.$(oext): local.h $(lpfx)vsniprintf.$(oext): local.h $(lpfx)vsscanf.$(oext): local.h $(lpfx)vswprintf.$(oext): local.h +$(lpfx)vswscanf.$(oext): local.h $(lpfx)vwprintf.$(oext): local.h +$(lpfx)vwscanf.$(oext): local.h $(lpfx)wbuf.$(oext): local.h fvwrite.h $(lpfx)wprintf.$(oext): local.h +$(lpfx)wscanf.$(oext): local.h $(lpfx)wsetup.$(oext): local.h # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/newlib/libc/stdio/fgetwc.c b/newlib/libc/stdio/fgetwc.c index 0f7cf0fca..38a79bc7c 100644 --- a/newlib/libc/stdio/fgetwc.c +++ b/newlib/libc/stdio/fgetwc.c @@ -129,7 +129,7 @@ _DEFUN(__fgetwc, (ptr, fp), } do { - nconv = _mbrtowc_r (ptr, &wc, fp->_p, fp->_r, &fp->_mbstate); + nconv = _mbrtowc_r (ptr, &wc, (char *) fp->_p, fp->_r, &fp->_mbstate); if (nconv == (size_t)-1) break; else if (nconv == (size_t)-2) diff --git a/newlib/libc/stdio/fgetws.c b/newlib/libc/stdio/fgetws.c index 30e8ebbf2..2784f1513 100644 --- a/newlib/libc/stdio/fgetws.c +++ b/newlib/libc/stdio/fgetws.c @@ -108,7 +108,7 @@ _DEFUN(_fgetws_r, (ptr, ws, n, fp), wsp = ws; do { - src = fp->_p; + src = (char *) fp->_p; nl = memchr (fp->_p, '\n', fp->_r); nconv = _mbsrtowcs_r (ptr, wsp, &src, nl != NULL ? (nl - fp->_p + 1) : fp->_r, diff --git a/newlib/libc/stdio/fread.c b/newlib/libc/stdio/fread.c index 8919554b9..a39e9d85f 100644 --- a/newlib/libc/stdio/fread.c +++ b/newlib/libc/stdio/fread.c @@ -179,9 +179,9 @@ _DEFUN(_fread_r, (ptr, buf, size, count, fp), void * old_p = fp->_p; int old_size = fp->_bf._size; /* allow __refill to use user's buffer */ - fp->_bf._base = p; + fp->_bf._base = (unsigned char *) p; fp->_bf._size = resid; - fp->_p = p; + fp->_p = (unsigned char *) p; rc = __srefill_r (ptr, fp); /* restore fp buffering back to original state */ fp->_bf._base = old_base; diff --git a/newlib/libc/stdio/fwscanf.c b/newlib/libc/stdio/fwscanf.c new file mode 100644 index 000000000..8d5236edc --- /dev/null +++ b/newlib/libc/stdio/fwscanf.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include <_ansi.h> +#include +#include +#include +#include +#include "local.h" + +#ifndef _REENT_ONLY + +int +fwscanf (FILE *fp, _CONST wchar_t *fmt, ...) +{ + int ret; + va_list ap; + + va_start (ap, fmt); + ret = __svfwscanf_r (_REENT, fp, fmt, ap); + va_end (ap); + return ret; +} + +#endif /* !_REENT_ONLY */ + +int +_fwscanf_r (struct _reent *ptr, FILE *fp, _CONST wchar_t *fmt, ...) +{ + int ret; + va_list ap; + + va_start (ap, fmt); + ret = __svfwscanf_r (ptr, fp, fmt, ap); + va_end (ap); + return (ret); +} + diff --git a/newlib/libc/stdio/local.h b/newlib/libc/stdio/local.h index 1e1e042d2..7305bd58c 100644 --- a/newlib/libc/stdio/local.h +++ b/newlib/libc/stdio/local.h @@ -38,6 +38,10 @@ extern int _EXFUN(__svfscanf_r,(struct _reent *,FILE *, _CONST char *,va_list extern int _EXFUN(__ssvfscanf_r,(struct _reent *,FILE *, _CONST char *,va_list)); extern int _EXFUN(__svfiscanf_r,(struct _reent *,FILE *, _CONST char *,va_list)); extern int _EXFUN(__ssvfiscanf_r,(struct _reent *,FILE *, _CONST char *,va_list)); +extern int _EXFUN(__svfwscanf_r,(struct _reent *,FILE *, _CONST wchar_t *,va_list)); +extern int _EXFUN(__ssvfwscanf_r,(struct _reent *,FILE *, _CONST wchar_t *,va_list)); +extern int _EXFUN(__svfiwscanf_r,(struct _reent *,FILE *, _CONST wchar_t *,va_list)); +extern int _EXFUN(__ssvfiwscanf_r,(struct _reent *,FILE *, _CONST wchar_t *,va_list)); int _EXFUN(_svfprintf_r,(struct _reent *, FILE *, const char *, va_list) _ATTRIBUTE ((__format__ (__printf__, 3, 0)))); @@ -53,6 +57,8 @@ extern int _EXFUN(__sflags,(struct _reent *,_CONST char*, int*)); extern int _EXFUN(__srefill_r,(struct _reent *,FILE *)); extern _READ_WRITE_RETURN_TYPE _EXFUN(__sread,(struct _reent *, void *, char *, int)); +extern _READ_WRITE_RETURN_TYPE _EXFUN(__seofread,(struct _reent *, void *, + char *, int)); extern _READ_WRITE_RETURN_TYPE _EXFUN(__swrite,(struct _reent *, void *, const char *, int)); extern _fpos_t _EXFUN(__sseek,(struct _reent *, void *, _fpos_t, int)); diff --git a/newlib/libc/stdio/siscanf.c b/newlib/libc/stdio/siscanf.c index cbf434c39..a6a812670 100644 --- a/newlib/libc/stdio/siscanf.c +++ b/newlib/libc/stdio/siscanf.c @@ -113,18 +113,6 @@ Supporting OS subroutines required: <>, <>, <>, #endif #include "local.h" -/* | ARGSUSED */ -/*SUPPRESS 590*/ -static _READ_WRITE_RETURN_TYPE -_DEFUN(eofread, (ptr, cookie, buf, len), - struct _reent *ptr _AND - _PTR cookie _AND - char *buf _AND - int len) -{ - return 0; -} - #ifndef _REENT_ONLY #ifdef _HAVE_STDC @@ -147,7 +135,7 @@ siscanf(str, fmt, va_alist) f._flags = __SRD | __SSTR; f._bf._base = f._p = (unsigned char *) str; f._bf._size = f._r = strlen (str); - f._read = eofread; + f._read = __seofread; f._ub._base = NULL; f._lb._base = NULL; f._file = -1; /* No file. */ @@ -185,7 +173,7 @@ _siscanf_r(ptr, str, fmt, va_alist) f._flags = __SRD | __SSTR; f._bf._base = f._p = (unsigned char *) str; f._bf._size = f._r = strlen (str); - f._read = eofread; + f._read = __seofread; f._ub._base = NULL; f._lb._base = NULL; f._file = -1; /* No file. */ diff --git a/newlib/libc/stdio/sscanf.c b/newlib/libc/stdio/sscanf.c index 37cd7ca30..974ae812b 100644 --- a/newlib/libc/stdio/sscanf.c +++ b/newlib/libc/stdio/sscanf.c @@ -394,18 +394,6 @@ Supporting OS subroutines required: <>, <>, <>, #endif #include "local.h" -/* | ARGSUSED */ -/*SUPPRESS 590*/ -static _READ_WRITE_RETURN_TYPE -_DEFUN(eofread, (ptr, cookie, buf, len), - struct _reent *ptr _AND - _PTR cookie _AND - char *buf _AND - int len) -{ - return 0; -} - #ifndef _REENT_ONLY #ifdef _HAVE_STDC @@ -428,7 +416,7 @@ sscanf(str, fmt, va_alist) f._flags = __SRD | __SSTR; f._bf._base = f._p = (unsigned char *) str; f._bf._size = f._r = strlen (str); - f._read = eofread; + f._read = __seofread; f._ub._base = NULL; f._lb._base = NULL; f._file = -1; /* No file. */ @@ -466,7 +454,7 @@ _sscanf_r(ptr, str, fmt, va_alist) f._flags = __SRD | __SSTR; f._bf._base = f._p = (unsigned char *) str; f._bf._size = f._r = strlen (str); - f._read = eofread; + f._read = __seofread; f._ub._base = NULL; f._lb._base = NULL; f._file = -1; /* No file. */ diff --git a/newlib/libc/stdio/stdio.c b/newlib/libc/stdio/stdio.c index 3cf3ea728..31b787bf8 100644 --- a/newlib/libc/stdio/stdio.c +++ b/newlib/libc/stdio/stdio.c @@ -61,6 +61,17 @@ _DEFUN(__sread, (ptr, cookie, buf, n), return ret; } +/* Dummy function used in sscanf/swscanf. */ +_READ_WRITE_RETURN_TYPE +_DEFUN(__seofread, (ptr, cookie, buf, len), + struct _reent *_ptr _AND + _PTR cookie _AND + char *buf _AND + int len) +{ + return 0; +} + _READ_WRITE_RETURN_TYPE _DEFUN(__swrite, (ptr, cookie, buf, n), struct _reent *ptr _AND diff --git a/newlib/libc/stdio/stdio.tex b/newlib/libc/stdio/stdio.tex index b3a69fc1d..28feffbcc 100644 --- a/newlib/libc/stdio/stdio.tex +++ b/newlib/libc/stdio/stdio.tex @@ -85,6 +85,7 @@ structure. * sprintf:: Write formatted output * sscanf:: Scan and format input * swprintf:: Write formatted wide character output +* swscanf:: Scan and format wide character input * tmpfile:: Create a temporary file * tmpnam:: Generate name for a temporary file * ungetc:: Push data back into a stream @@ -92,6 +93,7 @@ structure. * vfprintf:: Format variable argument list * vfscanf:: Scan variable argument list * vfwprintf:: Format variable wide character argument list +* vfwscanf:: Scan and format argument list from wide character input * viprintf:: Format variable argument list (integer only) * viscanf:: Scan variable format list (integer only) @end menu @@ -279,6 +281,9 @@ structure. @page @include stdio/swprintf.def +@page +@include stdio/swscanf.def + @page @include stdio/tmpfile.def @@ -300,6 +305,9 @@ structure. @page @include stdio/vfwprintf.def +@page +@include stdio/vfwscanf.def + @page @include stdio/viprintf.def diff --git a/newlib/libc/stdio/swscanf.c b/newlib/libc/stdio/swscanf.c new file mode 100644 index 000000000..e4e251f95 --- /dev/null +++ b/newlib/libc/stdio/swscanf.c @@ -0,0 +1,417 @@ +/* + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +/* +FUNCTION +<>, <>, <>---scan and format wide character input + +INDEX + wscanf +INDEX + _wscanf_r +INDEX + fwscanf +INDEX + _fwscanf_r +INDEX + swscanf +INDEX + _swscanf_r + +ANSI_SYNOPSIS + #include + + int wscanf(const wchar_t *<[format]>, ...); + int fwscanf(FILE *<[fd]>, const wchar_t *<[format]>, ...); + int swscanf(const wchar_t *<[str]>, const wchar_t *<[format]>, ...); + + int _wscanf_r(struct _reent *<[ptr]>, const wchar_t *<[format]>, ...); + int _fwscanf_r(struct _reent *<[ptr]>, FILE *<[fd]>, + const wchar_t *<[format]>, ...); + int _swscanf_r(struct _reent *<[ptr]>, const wchar_t *<[str]>, + const wchar_t *<[format]>, ...); + + +TRAD_SYNOPSIS + #include + + int wscanf(<[format]> [, <[arg]>, ...]) + wchar_t *<[format]>; + + int fwscanf(<[fd]>, <[format]> [, <[arg]>, ...]); + FILE *<[fd]>; + wchar_t *<[format]>; + + int swscanf(<[str]>, <[format]> [, <[arg]>, ...]); + wchar_t *<[str]>; + wchar_t *<[format]>; + + int _wscanf_r(<[ptr]>, <[format]> [, <[arg]>, ...]) + struct _reent *<[ptr]>; + wchar_t *<[format]>; + + int _fwscanf_r(<[ptr]>, <[fd]>, <[format]> [, <[arg]>, ...]); + struct _reent *<[ptr]>; + FILE *<[fd]>; + wchar_t *<[format]>; + + int _swscanf_r(<[ptr]>, <[str]>, <[format]> [, <[arg]>, ...]); + struct _reent *<[ptr]>; + wchar_t *<[str]>; + wchar_t *<[format]>; + + +DESCRIPTION + <> scans a series of input fields from standard input, + one wide character at a time. Each field is interpreted according to + a format specifier passed to <> in the format string at + <<*<[format]>>>. <> stores the interpreted input from + each field at the address passed to it as the corresponding argument + following <[format]>. You must supply the same number of + format specifiers and address arguments as there are input fields. + + There must be sufficient address arguments for the given format + specifiers; if not the results are unpredictable and likely + disasterous. Excess address arguments are merely ignored. + + <> often produces unexpected results if the input diverges from + an expected pattern. Since the combination of <> or <> + followed by <> is safe and easy, that is the preferred way + to be certain that a program is synchronized with input at the end + of a line. + + <> and <> are identical to <>, other than the + source of input: <> reads from a file, and <> + from a string. + + The routines <<_wscanf_r>>, <<_fwscanf_r>>, and <<_swscanf_r>> are reentrant + versions of <>, <>, and <> that take an additional + first argument pointing to a reentrancy structure. + + The string at <<*<[format]>>> is a wide character sequence composed + of zero or more directives. Directives are composed of + one or more whitespace characters, non-whitespace characters, + and format specifications. + + Whitespace characters are blank (<< >>), tab (<<\t>>), or + newline (<<\n>>). + When <> encounters a whitespace character in the format string + it will read (but not store) all consecutive whitespace characters + up to the next non-whitespace character in the input. + + Non-whitespace characters are all other ASCII characters except the + percent sign (<<%>>). When <> encounters a non-whitespace + character in the format string it will read, but not store + a matching non-whitespace character. + + Format specifications tell <> to read and convert characters + from the input field into specific types of values, and store then + in the locations specified by the address arguments. + + Trailing whitespace is left unread unless explicitly + matched in the format string. + + The format specifiers must begin with a percent sign (<<%>>) + and have the following form: + +. %[*][<[width]>][<[size]>]<[type]> + + Each format specification begins with the percent character (<<%>>). + The other fields are: + o+ + o * + an optional marker; if present, it suppresses interpretation and + assignment of this input field. + + o <[width]> + an optional maximum field width: a decimal integer, + which controls the maximum number of characters that + will be read before converting the current input field. If the + input field has fewer than <[width]> characters, <> + reads all the characters in the field, and then + proceeds with the next field and its format specification. + + If a whitespace or a non-convertable wide character occurs + before <[width]> character are read, the characters up + to that character are read, converted, and stored. + Then <> proceeds to the next format specification. + + o size + <>, <>, <>, <>, <>, and <> are optional size + characters which override the default way that <> + interprets the data type of the corresponding argument. + + +.Modifier Type(s) +. hh d, i, o, u, x, n convert input to char, +. store in char object +. +. h d, i, o, u, x, n convert input to short, +. store in short object +. +. h e, f, c, s, p no effect +. +. j d, i, o, u, x, n convert input to intmax_t, +. store in intmax_t object +. +. j all others no effect +. +. l d, i, o, u, x, n convert input to long, +. store in long object +. +. l e, f, g convert input to double +. store in a double object +. +. l c, s, [ the input is stored in a wchar_t object +. +. l p no effect +. +. ll d, i, o, u, x, n convert to long long, +. store in long long +. +. L d, i, o, u, x, n convert to long long, +. store in long long +. +. L e, f, g, E, G convert to long double, +. store in long double +. +. L all others no effect +. +. t d, i, o, u, x, n convert input to ptrdiff_t, +. store in ptrdiff_t object +. +. t all others no effect +. +. z d, i, o, u, x, n convert input to size_t, +. store in size_t object +. +. z all others no effect +. + + + o <[type]> + + A character to specify what kind of conversion + <> performs. Here is a table of the conversion + characters: + + o+ + o % + No conversion is done; the percent character (<<%>>) is stored. + + o c + Scans one wide character. Corresponding <[arg]>: <<(char *arg)>>. + Otherwise, if an <> specifier is present, the corresponding + <[arg]> is a <<(wchar_t *arg)>>. + + o s + Reads a character string into the array supplied. + Corresponding <[arg]>: <<(char arg[])>>. + If an <> specifier is present, the corresponding <[arg]> is a <<(wchar_t *arg)>>. + + o [<[pattern]>] + Reads a non-empty character string into memory + starting at <[arg]>. This area must be large + enough to accept the sequence and a + terminating null character which will be added + automatically. (<[pattern]> is discussed in the paragraph following + this table). Corresponding <[arg]>: <<(char *arg)>>. + + o d + Reads a decimal integer into the corresponding <[arg]>: <<(int *arg)>>. + + o o + Reads an octal integer into the corresponding <[arg]>: <<(int *arg)>>. + + o u + Reads an unsigned decimal integer into the corresponding + <[arg]>: <<(unsigned int *arg)>>. + + o x,X + Read a hexadecimal integer into the corresponding <[arg]>: + <<(int *arg)>>. + + o e, f, g + Read a floating-point number into the corresponding <[arg]>: + <<(float *arg)>>. + + o E, F, G + Read a floating-point number into the corresponding <[arg]>: + <<(double *arg)>>. + + o i + Reads a decimal, octal or hexadecimal integer into the + corresponding <[arg]>: <<(int *arg)>>. + + o n + Stores the number of characters read in the corresponding + <[arg]>: <<(int *arg)>>. + + o p + Stores a scanned pointer. ANSI C leaves the details + to each implementation; this implementation treats + <<%p>> exactly the same as <<%U>>. Corresponding + <[arg]>: <<(void **arg)>>. + o- + + A <[pattern]> of characters surrounded by square brackets can be used + instead of the <> type character. <[pattern]> is a set of + characters which define a search set of possible characters making up + the <> input field. If the first character in the brackets is a + caret (<<^>>), the search set is inverted to include all ASCII characters + except those between the brackets. There is no range facility as is + defined in the corresponding non-wide character scanf functions. + Ranges are not part of the POSIX standard. + + Here are some <[pattern]> examples: + o+ + o %[abcd] + matches wide wide character strings containing only + <>, <>, <>, and <>. + + o %[^abcd] + matches wide character strings containing any characters except + <>, <>, <>, or <>. + + o %[A-DW-Z] + Note: No wide character ranges, so this expression matches wide + character strings containing <>, <<->>, <>, <>, <>. + + Floating point numbers (for field types <>, <>, <>, <>, + <>, <>) must correspond to the following general form: + +. [+/-] ddddd[.]ddd [E|e[+|-]ddd] + + where objects inclosed in square brackets are optional, and <> + represents decimal, octal, or hexadecimal digits. + o- + +RETURNS + <> returns the number of input fields successfully + scanned, converted and stored; the return value does + not include scanned fields which were not stored. + + If <> attempts to read at end-of-file, the return + value is <>. + + If no fields were stored, the return value is <<0>>. + + <> might stop scanning a particular field before + reaching the normal field end character, or may + terminate entirely. + + <> stops scanning and storing the current field + and moves to the next input field (if any) + in any of the following situations: + + O+ + o The assignment suppressing character (<<*>>) appears + after the <<%>> in the format specification; the current + input field is scanned but not stored. + + o <[width]> characters have been read (<[width]> is a + width specification, a positive decimal integer). + + o The next wide character read cannot be converted + under the the current format (for example, + if a <> is read when the format is decimal). + + o The next wide character in the input field does not appear + in the search set (or does appear in the inverted search set). + O- + + When <> stops scanning the current input field for one of + these reasons, the next character is considered unread and + used as the first character of the following input field, or the + first character in a subsequent read operation on the input. + + <> will terminate under the following circumstances: + + O+ + o The next wide character in the input field conflicts + with a corresponding non-whitespace character in the + format string. + + o The next wide character in the input field is <>. + + o The format string has been exhausted. + O- + + When the format string contains a wide character sequence that is + not part of a format specification, the same wide character + sequence must appear in the input; <> will + scan but not store the matched characters. If a + conflict occurs, the first conflicting wide character remains in the + input as if it had never been read. + +PORTABILITY +<> is C99, POSIX-1.2008. + +Supporting OS subroutines required: <>, <>, <>, +<>, <>, <>, <>. +*/ + +#include <_ansi.h> +#include +#include +#include +#include +#include "local.h" + +#ifndef _REENT_ONLY + +int +swscanf (_CONST wchar_t *str, _CONST wchar_t *fmt, ...) +{ + int ret; + va_list ap; + FILE f; + + f._flags = __SRD | __SSTR; + f._bf._base = f._p = (unsigned char *) str; + f._bf._size = f._r = wcslen (str) * sizeof (wchar_t); + f._read = __seofread; + f._ub._base = NULL; + f._lb._base = NULL; + f._file = -1; /* No file. */ + va_start (ap, fmt); + ret = __ssvfwscanf_r (_REENT, &f, fmt, ap); + va_end (ap); + return ret; +} + +#endif /* !_REENT_ONLY */ + +int +_swscanf_r (struct _reent *ptr, _CONST wchar_t *str, _CONST wchar_t *fmt, ...) +{ + int ret; + va_list ap; + FILE f; + + f._flags = __SRD | __SSTR; + f._bf._base = f._p = (unsigned char *) str; + f._bf._size = f._r = wcslen (str) * sizeof (wchar_t); + f._read = __seofread; + f._ub._base = NULL; + f._lb._base = NULL; + f._file = -1; /* No file. */ + va_start (ap, fmt); + ret = __ssvfwscanf_r (ptr, &f, fmt, ap); + va_end (ap); + return ret; +} diff --git a/newlib/libc/stdio/vfprintf.c b/newlib/libc/stdio/vfprintf.c index e81b068ee..3497bac80 100644 --- a/newlib/libc/stdio/vfprintf.c +++ b/newlib/libc/stdio/vfprintf.c @@ -278,7 +278,9 @@ err: uio->uio_iovcnt = 0; return EOF; } -#endif /* INTEGER_ONLY */ +#else /* !INTEGER_ONLY */ +int __ssprint_r (struct _reent *, FILE *, register struct __suio *); +#endif /* !INTEGER_ONLY */ #else /* !STRING_ONLY */ #ifdef INTEGER_ONLY @@ -322,7 +324,9 @@ out: uio->uio_iovcnt = 0; return (err); } -#endif /* INTEGER_ONLY */ +#else /* !INTEGER_ONLY */ +int __sprint_r (struct _reent *, FILE *, register struct __suio *); +#endif /* !INTEGER_ONLY */ /* * Helper function for `fprintf to unbuffered unix file': creates a diff --git a/newlib/libc/stdio/vfscanf.c b/newlib/libc/stdio/vfscanf.c index 8546088a8..b24c9fb84 100644 --- a/newlib/libc/stdio/vfscanf.c +++ b/newlib/libc/stdio/vfscanf.c @@ -293,11 +293,11 @@ _DEFUN(_VFSCANF_R, (data, fp, fmt, ap), } #endif /* !STRING_ONLY */ -#ifdef STRING_ONLY +#if defined (STRING_ONLY) && defined (INTEGER_ONLY) /* When dealing with the sscanf family, we don't want to use the * regular ungetc which will drag in file I/O items we don't need. * So, we create our own trimmed-down version. */ -static int +int _DEFUN(_sungetc_r, (data, fp, ch), struct _reent *data _AND int c _AND @@ -355,7 +355,7 @@ _DEFUN(_sungetc_r, (data, fp, ch), } /* String only version of __srefill_r for sscanf family. */ -static int +int _DEFUN(__ssrefill_r, (ptr, fp), struct _reent * ptr _AND register FILE * fp) @@ -381,7 +381,7 @@ _DEFUN(__ssrefill_r, (ptr, fp), return EOF; } -static size_t +size_t _DEFUN(_sfread_r, (ptr, buf, size, count, fp), struct _reent * ptr _AND _PTR buf _AND @@ -418,7 +418,11 @@ _DEFUN(_sfread_r, (ptr, buf, size, count, fp), fp->_p += resid; return count; } -#endif /* STRING_ONLY */ +#else /* !STRING_ONLY || !INTEGER_ONLY */ +int _EXFUN (_sungetc_r, (struct _reent *, int, register FILE *)); +int _EXFUN (__ssrefill_r, (struct _reent *, register FILE *)); +size_t _EXFUN (_sfread_r, (struct _reent *, _PTR buf, size_t, size_t, FILE *)); +#endif /* !STRING_ONLY || !INTEGER_ONLY */ int _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap), @@ -717,7 +721,7 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap), break; case '[': - fmt = __sccl (ccltab, fmt); + fmt = (u_char *) __sccl (ccltab, (unsigned char *) fmt); flags |= NOSKIP; c = CT_CCL; break; diff --git a/newlib/libc/stdio/vfwscanf.c b/newlib/libc/stdio/vfwscanf.c new file mode 100644 index 000000000..56df93247 --- /dev/null +++ b/newlib/libc/stdio/vfwscanf.c @@ -0,0 +1,1469 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +/* +FUNCTION +<>, <>, <>---scan and format argument list from wide character input + +INDEX + vfwscanf +INDEX + _vfwscanf +INDEX + vwscanf +INDEX + _vwscanf +INDEX + vswscanf +INDEX + _vswscanf + +ANSI_SYNOPSIS + #include + #include + int vwscanf(const wchar_t *<[fmt]>, va_list <[list]>); + int vfwscanf(FILE *<[fp]>, const wchar_t *<[fmt]>, va_list <[list]>); + int vswscanf(const wchar_t *<[str]>, const wchar_t *<[fmt]>, va_list <[list]>); + + int _vwscanf(struct _reent *<[reent]>, const wchar_t *<[fmt]>, + va_list <[list]>); + int _vfwscanf(struct _reent *<[reent]>, FILE *<[fp]>, const wchar_t *<[fmt]>, + va_list <[list]>); + int _vswscanf(struct _reent *<[reent]>, const wchar_t *<[str]>, + const wchar_t *<[fmt]>, va_list <[list]>); + +TRAD_SYNOPSIS + #include + #include + int vwscanf( <[fmt]>, <[ist]>) + wchar_t *<[fmt]>; + va_list <[list]>; + + int vfwscanf( <[fp]>, <[fmt]>, <[list]>) + FILE *<[fp]>; + wchar_t *<[fmt]>; + va_list <[list]>; + + int vswscanf( <[str]>, <[fmt]>, <[list]>) + wchar_t *<[str]>; + wchar_t *<[fmt]>; + va_list <[list]>; + + int _vwscanf( <[reent]>, <[fmt]>, <[ist]>) + struct _reent *<[reent]>; + wchar_t *<[fmt]>; + va_list <[list]>; + + int _vfwscanf( <[reent]>, <[fp]>, <[fmt]>, <[list]>) + struct _reent *<[reent]>; + FILE *<[fp]>; + wchar_t *<[fmt]>; + va_list <[list]>; + + int _vswscanf( <[reent]>, <[str]>, <[fmt]>, <[list]>) + struct _reent *<[reent]>; + wchar_t *<[str]>; + wchar_t *<[fmt]>; + va_list <[list]>; + +DESCRIPTION +<>, <>, and <> are (respectively) variants +of <>, <>, and <>. They differ only in +allowing their caller to pass the variable argument list as a +<> object (initialized by <>) rather than +directly accepting a variable number of arguments. + +RETURNS +The return values are consistent with the corresponding functions: +<> returns the number of input fields successfully scanned, +converted, and stored; the return value does not include scanned +fields which were not stored. + +If <> attempts to read at end-of-file, the return value +is <>. + +If no fields were stored, the return value is <<0>>. + +The routines <<_vwscanf>>, <<_vfwscanf>>, and <<_vswscanf>> are +reentrant versions which take an additional first parameter which points +to the reentrancy structure. + +PORTABILITY +C99, POSIX-1.2008 +*/ + +#include <_ansi.h> +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "local.h" + +#ifdef INTEGER_ONLY +#define VFWSCANF vfiwscanf +#define _VFWSCANF_R _vfiwscanf_r +#define __SVFWSCANF __svfiwscanf +#ifdef STRING_ONLY +# define __SVFWSCANF_R __ssvfiwscanf_r +#else +# define __SVFWSCANF_R __svfiwscanf_r +#endif +#else +#define VFWSCANF vfwscanf +#define _VFWSCANF_R _vfwscanf_r +#define __SVFWSCANF __svfwscanf +#ifdef STRING_ONLY +# define __SVFWSCANF_R __ssvfwscanf_r +#else +# define __SVFWSCANF_R __svfwscanf_r +#endif +#ifndef NO_FLOATING_POINT +#define FLOATING_POINT +#endif +#endif + +#ifdef STRING_ONLY +#undef _flockfile +#undef _funlockfile +#define _flockfile(x) {} +#define _funlockfile(x) {} +#define _ungetwc_r _sungetwc_r +#define __srefill_r __ssrefill_r +#define _fgetwc_r _sfgetwc_r +#endif + +#ifdef FLOATING_POINT +#include +#include + +/* Currently a test is made to see if long double processing is warranted. + This could be changed in the future should the _ldtoa_r code be + preferred over _dtoa_r. */ +#define _NO_LONGDBL +#if defined _WANT_IO_LONG_DOUBLE && (LDBL_MANT_DIG > DBL_MANT_DIG) +#undef _NO_LONGDBL +extern _LONG_DOUBLE _wcstold_r _PARAMS((wchar_t *s, wchar_t **sptr)); +#endif + +#include "floatio.h" + +#if ((MAXEXP+MAXFRACT+3) > MB_LEN_MAX) +# define BUF (MAXEXP+MAXFRACT+3) /* 3 = sign + decimal point + NUL */ +#else +# define BUF MB_LEN_MAX +#endif + +/* An upper bound for how long a long prints in decimal. 4 / 13 approximates + log (2). Add one char for roundoff compensation and one for the sign. */ +#define MAX_LONG_LEN ((CHAR_BIT * sizeof (long) - 1) * 4 / 13 + 2) +#else +#define BUF 40 +#endif + +#define _NO_LONGLONG +#if defined _WANT_IO_LONG_LONG \ + && (defined __GNUC__ || __STDC_VERSION__ >= 199901L) +# undef _NO_LONGLONG +#endif + +#define _NO_POS_ARGS +#ifdef _WANT_IO_POS_ARGS +# undef _NO_POS_ARGS +# ifdef NL_ARGMAX +# define MAX_POS_ARGS NL_ARGMAX +# else +# define MAX_POS_ARGS 32 +# endif + +static void * get_arg (int, va_list *, int *, void **); +#endif /* _WANT_IO_POS_ARGS */ + +/* + * Flags used during conversion. + */ + +#define LONG 0x01 /* l: long or double */ +#define LONGDBL 0x02 /* L/ll: long double or long long */ +#define SHORT 0x04 /* h: short */ +#define CHAR 0x08 /* hh: 8 bit integer */ +#define SUPPRESS 0x10 /* suppress assignment */ +#define POINTER 0x20 /* weird %p pointer (`fake hex') */ +#define NOSKIP 0x40 /* do not skip blanks */ + +/* + * The following are used in numeric conversions only: + * SIGNOK, NDIGITS, DPTOK, and EXPOK are for floating point; + * SIGNOK, NDIGITS, PFXOK, and NZDIGITS are for integral. + */ + +#define SIGNOK 0x80 /* +/- is (still) legal */ +#define NDIGITS 0x100 /* no digits detected */ + +#define DPTOK 0x200 /* (float) decimal point is still legal */ +#define EXPOK 0x400 /* (float) exponent (e+3, etc) still legal */ + +#define PFXOK 0x200 /* 0x prefix is (still) legal */ +#define NZDIGITS 0x400 /* no zero digits detected */ +#define HAVESIGN 0x10000 /* sign detected */ + +/* + * Conversion types. + */ + +#define CT_CHAR 0 /* %c conversion */ +#define CT_CCL 1 /* %[...] conversion */ +#define CT_STRING 2 /* %s conversion */ +#define CT_INT 3 /* integer, i.e., wcstol or wcstoul */ +#define CT_FLOAT 4 /* floating, i.e., wcstod */ + +#define INCCL(_c) \ + (cclcompl ? (wmemchr(ccls, (_c), ccle - ccls) == NULL) : \ + (wmemchr(ccls, (_c), ccle - ccls) != NULL)) + +/* + * vfwscanf + */ + +#ifndef STRING_ONLY + +#ifndef _REENT_ONLY + +int +_DEFUN(VFWSCANF, (fp, fmt, ap), + register FILE *fp _AND + _CONST wchar_t *fmt _AND + va_list ap) +{ + CHECK_INIT(_REENT, fp); + return __SVFWSCANF_R (_REENT, fp, fmt, ap); +} + +int +_DEFUN(__SVFWSCANF, (fp, fmt0, ap), + register FILE *fp _AND + wchar_t _CONST *fmt0 _AND + va_list ap) +{ + return __SVFWSCANF_R (_REENT, fp, fmt0, ap); +} + +#endif /* !_REENT_ONLY */ + +int +_DEFUN(_VFWSCANF_R, (data, fp, fmt, ap), + struct _reent *data _AND + register FILE *fp _AND + _CONST wchar_t *fmt _AND + va_list ap) +{ + CHECK_INIT(data, fp); + return __SVFWSCANF_R (data, fp, fmt, ap); +} +#endif /* !STRING_ONLY */ + +#ifdef STRING_ONLY +/* When dealing with the swscanf family, we don't want to use the + * regular ungetwc which will drag in file I/O items we don't need. + * So, we create our own trimmed-down version. */ +static wint_t +_DEFUN(_sungetwc_r, (data, fp, ch), + struct _reent *data _AND + wint_t wc _AND + register FILE *fp) +{ + if (wc == WEOF) + return (WEOF); + + /* After ungetc, we won't be at eof anymore */ + fp->_flags &= ~__SEOF; + + /* + * If we are in the middle of ungetwc'ing, just continue. + * This may require expanding the current ungetc buffer. + */ + + if (HASUB (fp)) + { + if (fp->_r >= fp->_ub._size && __submore (data, fp)) + { + return EOF; + } + fp->_p -= sizeof (wchar_t); + *fp->_p = (wchar_t) wc; + fp->_r += sizeof (wchar_t); + return wc; + } + + /* + * If we can handle this by simply backing up, do so, + * but never replace the original character. + * (This makes swscanf() work when scanning `const' data.) + */ + + if (fp->_bf._base != NULL && fp->_p > fp->_bf._base + && ((wchar_t *)fp->_p)[-1] == wc) + { + fp->_p -= sizeof (wchar_t); + fp->_r += sizeof (wchar_t); + return wc; + } + + /* + * Create an ungetc buffer. + * Initially, we will use the `reserve' buffer. + */ + + fp->_ur = fp->_r; + fp->_up = fp->_p; + fp->_ub._base = fp->_ubuf; + fp->_ub._size = sizeof (fp->_ubuf); + fp->_p = &fp->_ubuf[sizeof (fp->_ubuf) - sizeof (wchar_t)]; + *(wchar_t *) fp->_p = wc; + fp->_r = 2; + return wc; +} + +extern int __ssrefill_r _PARAMS ((struct _reent *ptr, register FILE * fp)); + +static size_t +_DEFUN(_sfgetwc_r, (ptr, fp), + struct _reent * ptr _AND + FILE * fp) +{ + wchar_t wc; + + if (fp->_r <= 0 && __ssrefill_r (ptr, fp)) + return (WEOF); + wc = *(wchar_t *) fp->_p; + fp->_p += sizeof (wchar_t); + fp->_r -= sizeof (wchar_t); + return (wc); +} +#endif /* STRING_ONLY */ + +int +_DEFUN(__SVFWSCANF_R, (rptr, fp, fmt0, ap), + struct _reent *rptr _AND + register FILE *fp _AND + wchar_t _CONST *fmt0 _AND + va_list ap) +{ + register wchar_t *fmt = (wchar_t *) fmt0; + register wint_t c; /* character from format, or conversion */ + register size_t width; /* field width, or 0 */ + register wchar_t *p = NULL; /* points into all kinds of strings */ + register int n; /* handy integer */ + register int flags; /* flags as defined above */ + register wchar_t *p0; /* saves original value of p when necessary */ + int nassigned; /* number of fields assigned */ + int nread; /* number of characters consumed from fp */ +#ifndef _NO_POS_ARGS + int N; /* arg number */ + int arg_index = 0; /* index into args processed directly */ + int numargs = 0; /* number of varargs read */ + void *args[MAX_POS_ARGS]; /* positional args read */ + int is_pos_arg; /* is current format positional? */ +#endif + int base = 0; /* base argument to wcstol/wcstoul */ + + mbstate_t mbs; /* value to keep track of multibyte state */ + + #define CCFN_PARAMS _PARAMS((struct _reent *, const wchar_t *, wchar_t **, int)) + unsigned long (*ccfn)CCFN_PARAMS=0; /* conversion function (wcstol/wcstoul) */ + wchar_t buf[BUF]; /* buffer for numeric conversions */ + const wchar_t *ccls; /* character class start */ + const wchar_t *ccle; /* character class end */ + int cclcompl = 0; /* ccl is complemented? */ + wint_t wi; /* handy wint_t */ + char *mbp = NULL; /* multibyte string pointer for %c %s %[ */ + size_t nconv; /* number of bytes in mb. conversion */ + char mbbuf[MB_LEN_MAX]; /* temporary mb. character buffer */ + + char *cp; + short *sp; + int *ip; +#ifdef FLOATING_POINT + float *flp; + _LONG_DOUBLE *ldp; + double *dp; +#endif + long *lp; +#ifndef _NO_LONGLONG + long long *llp; +#endif + + /* `basefix' is used to avoid `if' tests in the integer scanner */ + static _CONST short basefix[17] = + {10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; + + /* Macro to support positional arguments */ +#ifndef _NO_POS_ARGS +# define GET_ARG(n, ap, type) \ + ((type) (is_pos_arg \ + ? (n < numargs \ + ? args[n] \ + : get_arg (n, &ap, &numargs, args)) \ + : (arg_index++ < numargs \ + ? args[n] \ + : (numargs < MAX_POS_ARGS \ + ? args[numargs++] = va_arg (ap, void *) \ + : va_arg (ap, void *))))) +#else +# define GET_ARG(n, ap, type) (va_arg (ap, type)) +#endif + + __sfp_lock_acquire (); + _flockfile (fp); + + ORIENT (fp, 1); + + nassigned = 0; + nread = 0; + ccls = ccle = NULL; + for (;;) + { + c = *fmt++; + if (c == L'\0') + goto all_done; + if (iswspace (c)) + { + while ((c = _fgetwc_r (rptr, fp)) != WEOF && iswspace(c)) + ; + if (c != WEOF) + _ungetwc_r (rptr, c, fp); + continue; + } + if (c != L'%') + goto literal; + width = 0; + flags = 0; +#ifndef _NO_POS_ARGS + N = arg_index; + is_pos_arg = 0; +#endif + + /* + * switch on the format. continue if done; break once format + * type is derived. + */ + + again: + c = *fmt++; + + switch (c) + { + case L'%': + literal: + if ((wi = _fgetwc_r (rptr, fp)) == WEOF) + goto input_failure; + if (wi != c) + { + _ungetwc_r (rptr, wi, fp); + goto input_failure; + } + nread++; + continue; + + case L'*': + flags |= SUPPRESS; + goto again; + case L'l': +#if defined _WANT_IO_C99_FORMATS || !defined _NO_LONGLONG + if (*fmt == L'l') /* Check for 'll' = long long (SUSv3) */ + { + ++fmt; + flags |= LONGDBL; + } + else +#endif + flags |= LONG; + goto again; + case L'L': + flags |= LONGDBL; + goto again; + case L'h': +#ifdef _WANT_IO_C99_FORMATS + if (*fmt == 'h') /* Check for 'hh' = char int (SUSv3) */ + { + ++fmt; + flags |= CHAR; + } + else +#endif + flags |= SHORT; + goto again; +#ifdef _WANT_IO_C99_FORMATS + case L'j': /* intmax_t */ + if (sizeof (intmax_t) == sizeof (long)) + flags |= LONG; + else + flags |= LONGDBL; + goto again; + case L't': /* ptrdiff_t */ + if (sizeof (ptrdiff_t) < sizeof (int)) + /* POSIX states ptrdiff_t is 16 or more bits, as + is short. */ + flags |= SHORT; + else if (sizeof (ptrdiff_t) == sizeof (int)) + /* no flag needed */; + else if (sizeof (ptrdiff_t) <= sizeof (long)) + flags |= LONG; + else + /* POSIX states that at least one programming + environment must support ptrdiff_t no wider than + long, but that means other environments can + have ptrdiff_t as wide as long long. */ + flags |= LONGDBL; + goto again; + case L'z': /* size_t */ + if (sizeof (size_t) < sizeof (int)) + /* POSIX states size_t is 16 or more bits, as is short. */ + flags |= SHORT; + else if (sizeof (size_t) == sizeof (int)) + /* no flag needed */; + else if (sizeof (size_t) <= sizeof (long)) + flags |= LONG; + else + /* POSIX states that at least one programming + environment must support size_t no wider than + long, but that means other environments can + have size_t as wide as long long. */ + flags |= LONGDBL; + goto again; +#endif /* _WANT_IO_C99_FORMATS */ + + case L'0': + case L'1': + case L'2': + case L'3': + case L'4': + case L'5': + case L'6': + case L'7': + case L'8': + case L'9': + width = width * 10 + c - L'0'; + goto again; + +#ifndef _NO_POS_ARGS + case L'$': + if (width <= MAX_POS_ARGS) + { + N = width - 1; + is_pos_arg = 1; + width = 0; + goto again; + } + rptr->_errno = EINVAL; + goto input_failure; +#endif /* !_NO_POS_ARGS */ + + case L'd': + c = CT_INT; + ccfn = (unsigned long (*)CCFN_PARAMS)_wcstol_r; + base = 10; + break; + + case L'i': + c = CT_INT; + ccfn = (unsigned long (*)CCFN_PARAMS)_wcstol_r; + base = 0; + break; + + case L'o': + c = CT_INT; + ccfn = _wcstoul_r; + base = 8; + break; + + case L'u': + c = CT_INT; + ccfn = _wcstoul_r; + base = 10; + break; + + case L'X': + case L'x': + flags |= PFXOK; /* enable 0x prefixing */ + c = CT_INT; + ccfn = _wcstoul_r; + base = 16; + break; + +#ifdef FLOATING_POINT +# ifdef _WANT_IO_C99_FORMATS + case L'A': + case L'a': + case L'F': +# endif + case L'E': + case L'G': + case L'e': + case L'f': + case L'g': + c = CT_FLOAT; + break; +#endif + +#ifdef _WANT_IO_C99_FORMATS + case L'S': + flags |= LONG; + /* FALLTHROUGH */ +#endif + + case L's': + c = CT_STRING; + break; + + case L'[': + ccls = fmt; + if (*fmt == '^') + { + cclcompl = 1; + ++fmt; + } + else + cclcompl = 0; + if (*fmt == ']') + fmt++; + while (*fmt != '\0' && *fmt != ']') + fmt++; + ccle = fmt; + fmt++; + flags |= NOSKIP; + c = CT_CCL; + break; + +#ifdef _WANT_IO_C99_FORMATS + case 'C': + flags |= LONG; + /* FALLTHROUGH */ +#endif + + case 'c': + flags |= NOSKIP; + c = CT_CHAR; + break; + + case 'p': /* pointer format is like hex */ + flags |= POINTER | PFXOK; + c = CT_INT; + ccfn = _wcstoul_r; + base = 16; + break; + + case 'n': + if (flags & SUPPRESS) /* ??? */ + continue; +#ifdef _WANT_IO_C99_FORMATS + if (flags & CHAR) + { + cp = GET_ARG (N, ap, char *); + *cp = nread; + } + else +#endif + if (flags & SHORT) + { + sp = GET_ARG (N, ap, short *); + *sp = nread; + } + else if (flags & LONG) + { + lp = GET_ARG (N, ap, long *); + *lp = nread; + } +#ifndef _NO_LONGLONG + else if (flags & LONGDBL) + { + llp = GET_ARG (N, ap, long long*); + *llp = nread; + } +#endif + else + { + ip = GET_ARG (N, ap, int *); + *ip = nread; + } + continue; + + /* + * Disgusting backwards compatibility hacks. XXX + */ + case L'\0': /* compat */ + _funlockfile (fp); + __sfp_lock_release (); + return EOF; + + default: /* compat */ + goto match_failure; + } + + /* + * Consume leading white space, except for formats that + * suppress this. + */ + if ((flags & NOSKIP) == 0) + { + while ((wi = _fgetwc_r (rptr, fp)) != WEOF && iswspace (wi)) + nread++; + if (wi == WEOF) + goto input_failure; + _ungetwc_r (rptr, wi, fp); + } + + /* + * Do the conversion. + */ + switch (c) + { + + case CT_CHAR: + /* scan arbitrary characters (sets NOSKIP) */ + if (width == 0) + width = 1; + if (flags & LONG) + { + if (!(flags & SUPPRESS)) + p = va_arg(ap, wchar_t *); + n = 0; + while (width-- != 0 && (wi = _fgetwc_r (rptr, fp)) != WEOF) + { + if (!(flags & SUPPRESS)) + *p++ = (wchar_t) wi; + n++; + } + if (n == 0) + goto input_failure; + nread += n; + if (!(flags & SUPPRESS)) + nassigned++; + } + else + { + if (!(flags & SUPPRESS)) + mbp = va_arg(ap, char *); + n = 0; + memset ((_PTR)&mbs, '\0', sizeof (mbstate_t)); + while (width != 0 && (wi = _fgetwc_r (rptr, fp)) != WEOF) + { + if (width >= MB_CUR_MAX && !(flags & SUPPRESS)) + { + nconv = _wcrtomb_r (rptr, mbp, wi, &mbs); + if (nconv == (size_t) -1) + goto input_failure; + } + else + { + nconv = _wcrtomb_r (rptr, mbbuf, wi, &mbs); + if (nconv == (size_t) -1) + goto input_failure; + if (nconv > width) + { + _ungetwc_r (rptr, wi, fp); + break; + } + if (!(flags & SUPPRESS)) + memcpy(mbp, mbbuf, nconv); + } + if (!(flags & SUPPRESS)) + mbp += nconv; + width -= nconv; + n++; + } + if (n == 0) + goto input_failure; + nread += n; + if (!(flags & SUPPRESS)) + nassigned++; + } + break; + + case CT_CCL: + /* scan a (nonempty) character class (sets NOSKIP) */ + if (width == 0) + width = (size_t) ~0; /* `infinity' */ + /* take only those things in the class */ + if ((flags & SUPPRESS) && (flags & LONG)) + { + n = 0; + while ((wi = _fgetwc_r (rptr, fp)) != WEOF + && width-- != 0 && INCCL (wi)) + n++; + if (wi != WEOF) + _ungetwc_r (rptr, wi, fp); + if (n == 0) + goto match_failure; + } + else if (flags & LONG) + { + p0 = p = va_arg(ap, wchar_t *); + while ((wi = _fgetwc_r (rptr, fp)) != WEOF + && width-- != 0 && INCCL (wi)) + *p++ = (wchar_t) wi; + if (wi != WEOF) + _ungetwc_r (rptr, wi, fp); + n = p - p0; + if (n == 0) + goto match_failure; + } + else + { + if (!(flags & SUPPRESS)) + mbp = va_arg(ap, char *); + n = 0; + memset ((_PTR) &mbs, '\0', sizeof (mbstate_t)); + while ((wi = _fgetwc_r (rptr, fp)) != WEOF + && width-- != 0 && INCCL (wi)) + { + if (width >= MB_CUR_MAX && !(flags & SUPPRESS)) + { + nconv = _wcrtomb_r (rptr, mbp, wi, &mbs); + if (nconv == (size_t) -1) + goto input_failure; + } + else + { + nconv = wcrtomb(mbbuf, wi, &mbs); + if (nconv == (size_t) -1) + goto input_failure; + if (nconv > width) + break; + if (!(flags & SUPPRESS)) + memcpy(mbp, mbbuf, nconv); + } + if (!(flags & SUPPRESS)) + mbp += nconv; + width -= nconv; + n++; + } + if (wi != WEOF) + _ungetwc_r (rptr, wi, fp); + if (!(flags & SUPPRESS)) + { + *mbp = 0; + nassigned++; + } + } + nread += n; + break; + + case CT_STRING: + /* like CCL, but zero-length string OK, & no NOSKIP */ + if (width == 0) + width = (size_t)~0; + if ((flags & SUPPRESS) && (flags & LONG)) + { + while ((wi = _fgetwc_r (rptr, fp)) != WEOF + && width-- != 0 && !iswspace (wi)) + nread++; + if (wi != WEOF) + _ungetwc_r (rptr, wi, fp); + } + else if (flags & LONG) + { + p0 = p = va_arg(ap, wchar_t *); + while ((wi = _fgetwc_r (rptr, fp)) != WEOF + && width-- != 0 && !iswspace (wi)) + { + *p++ = (wchar_t) wi; + nread++; + } + if (wi != WEOF) + _ungetwc_r (rptr, wi, fp); + *p = '\0'; + nassigned++; + } + else + { + if (!(flags & SUPPRESS)) + mbp = va_arg(ap, char *); + memset ((_PTR) &mbs, '\0', sizeof (mbstate_t)); + while ((wi = _fgetwc_r (rptr, fp)) != WEOF + && width != 0 && !iswspace (wi)) + { + if (width >= MB_CUR_MAX && !(flags & SUPPRESS)) + { + nconv = wcrtomb(mbp, wi, &mbs); + if (nconv == (size_t)-1) + goto input_failure; + } + else + { + nconv = wcrtomb(mbbuf, wi, &mbs); + if (nconv == (size_t)-1) + goto input_failure; + if (nconv > width) + break; + if (!(flags & SUPPRESS)) + memcpy(mbp, mbbuf, nconv); + } + if (!(flags & SUPPRESS)) + mbp += nconv; + width -= nconv; + nread++; + } + if (wi != WEOF) + _ungetwc_r (rptr, wi, fp); + if (!(flags & SUPPRESS)) + { + *mbp = 0; + nassigned++; + } + } + continue; + + case CT_INT: + { + /* scan an integer as if by wcstol/wcstoul */ + if (width == 0 || width > sizeof (buf) / sizeof (*buf) - 1) + width = sizeof(buf) / sizeof (*buf) - 1; + flags |= SIGNOK | NDIGITS | NZDIGITS; + for (p = buf; width; width--) + { + c = _fgetwc_r (rptr, fp); + /* + * Switch on the character; `goto ok' if we + * accept it as a part of number. + */ + switch (c) + { + /* + * The digit 0 is always legal, but is special. + * For %i conversions, if no digits (zero or nonzero) + * have been scanned (only signs), we will have base==0. + * In that case, we should set it to 8 and enable 0x + * prefixing. Also, if we have not scanned zero digits + * before this, do not turn off prefixing (someone else + * will turn it off if we have scanned any nonzero digits). + */ + case L'0': + if (base == 0) + { + base = 8; + flags |= PFXOK; + } + if (flags & NZDIGITS) + flags &= ~(SIGNOK | NZDIGITS | NDIGITS); + else + flags &= ~(SIGNOK | PFXOK | NDIGITS); + goto ok; + + /* 1 through 7 always legal */ + case L'1': + case L'2': + case L'3': + case L'4': + case L'5': + case L'6': + case L'7': + base = basefix[base]; + flags &= ~(SIGNOK | PFXOK | NDIGITS); + goto ok; + + /* digits 8 and 9 ok iff decimal or hex */ + case L'8': + case L'9': + base = basefix[base]; + if (base <= 8) + break; /* not legal here */ + flags &= ~(SIGNOK | PFXOK | NDIGITS); + goto ok; + + /* letters ok iff hex */ + case L'A': + case L'B': + case L'C': + case L'D': + case L'E': + case L'F': + case L'a': + case L'b': + case L'c': + case L'd': + case L'e': + case L'f': + /* no need to fix base here */ + if (base <= 10) + break; /* not legal here */ + flags &= ~(SIGNOK | PFXOK | NDIGITS); + goto ok; + + /* sign ok only as first character */ + case L'+': + case L'-': + if (flags & SIGNOK) + { + flags &= ~SIGNOK; + flags |= HAVESIGN; + goto ok; + } + break; + + /* x ok iff flag still set & single 0 seen */ + case L'x': + case L'X': + if ((flags & PFXOK) && p == buf + 1 + !!(flags & HAVESIGN)) + { + base = 16;/* if %i */ + flags &= ~PFXOK; + goto ok; + } + break; + } + + /* + * If we got here, c is not a legal character + * for a number. Stop accumulating digits. + */ + if (c != WEOF) + _ungetwc_r (rptr, c, fp); + break; + ok: + /* + * c is legal: store it and look at the next. + */ + *p++ = (wchar_t) c; + } + /* + * If we had only a sign, it is no good; push back the sign. + * If the number ends in `x', it was [sign] '0' 'x', so push back + * the x and treat it as [sign] '0'. + * Use of ungetc here and below assumes ASCII encoding; we are only + * pushing back 7-bit characters, so casting to unsigned char is + * not necessary. + */ + if (flags & NDIGITS) + { + if (p > buf) + _ungetwc_r (rptr, *--p, fp); /* [-+xX] */ + goto match_failure; + } + c = p[-1]; + if (c == L'x' || c == L'X') + { + --p; + _ungetwc_r (rptr, c, fp); + } + if ((flags & SUPPRESS) == 0) + { + unsigned long res; + + *p = 0; + res = (*ccfn) (rptr, buf, (wchar_t **) NULL, base); + if (flags & POINTER) + { + void **vp = GET_ARG (N, ap, void **); +#ifndef _NO_LONGLONG + if (sizeof (uintptr_t) > sizeof (unsigned long)) + { + unsigned long long resll; + resll = _wcstoull_r (rptr, buf, (wchar_t **) NULL, base); + *vp = (void *) (uintptr_t) resll; + } + else +#endif /* !_NO_LONGLONG */ + *vp = (void *) (uintptr_t) res; + } +#ifdef _WANT_IO_C99_FORMATS + else if (flags & CHAR) + { + cp = GET_ARG (N, ap, char *); + *cp = res; + } +#endif + else if (flags & SHORT) + { + sp = GET_ARG (N, ap, short *); + *sp = res; + } + else if (flags & LONG) + { + lp = GET_ARG (N, ap, long *); + *lp = res; + } +#ifndef _NO_LONGLONG + else if (flags & LONGDBL) + { + unsigned long long resll; + if (ccfn == _wcstoul_r) + resll = _wcstoull_r (rptr, buf, (wchar_t **) NULL, base); + else + resll = _wcstoll_r (rptr, buf, (wchar_t **) NULL, base); + llp = GET_ARG (N, ap, long long*); + *llp = resll; + } +#endif + else + { + ip = GET_ARG (N, ap, int *); + *ip = res; + } + nassigned++; + } + nread += p - buf; + break; + } +#ifdef FLOATING_POINT + case CT_FLOAT: + { + /* scan a floating point number as if by wcstod */ + /* This code used to assume that the number of digits is reasonable. + However, ANSI / ISO C makes no such stipulation; we have to get + exact results even when there is an unreasonable amount of + leading zeroes. */ + long leading_zeroes = 0; + long zeroes, exp_adjust; + wchar_t *exp_start = NULL; + unsigned width_left = 0; + char nancount = 0; + char infcount = 0; +#ifdef hardway + if (width == 0 || width > sizeof (buf) - 1) +#else + /* size_t is unsigned, hence this optimisation */ + if (width - 1 > sizeof (buf) - 2) +#endif + { + width_left = width - (sizeof (buf) - 1); + width = sizeof (buf) - 1; + } + flags |= SIGNOK | NDIGITS | DPTOK | EXPOK; + zeroes = 0; + exp_adjust = 0; + for (p = buf; width; ) + { + c = _fgetwc_r (rptr, fp); + /* + * This code mimicks the integer conversion + * code, but is much simpler. + */ + switch (c) + { + case L'0': + if (flags & NDIGITS) + { + flags &= ~SIGNOK; + zeroes++; + if (width_left) + { + width_left--; + width++; + } + goto fskip; + } + /* Fall through. */ + case L'1': + case L'2': + case L'3': + case L'4': + case L'5': + case L'6': + case L'7': + case L'8': + case L'9': + if (nancount + infcount == 0) + { + flags &= ~(SIGNOK | NDIGITS); + goto fok; + } + break; + + case L'+': + case L'-': + if (flags & SIGNOK) + { + flags &= ~SIGNOK; + goto fok; + } + break; + case L'n': + case L'N': + if (nancount == 0 && zeroes == 0 + && (flags & (NDIGITS | DPTOK | EXPOK)) == + (NDIGITS | DPTOK | EXPOK)) + { + flags &= ~(SIGNOK | DPTOK | EXPOK | NDIGITS); + nancount = 1; + goto fok; + } + if (nancount == 2) + { + nancount = 3; + goto fok; + } + if (infcount == 1 || infcount == 4) + { + infcount++; + goto fok; + } + break; + case L'a': + case L'A': + if (nancount == 1) + { + nancount = 2; + goto fok; + } + break; + case L'i': + if (infcount == 0 && zeroes == 0 + && (flags & (NDIGITS | DPTOK | EXPOK)) == + (NDIGITS | DPTOK | EXPOK)) + { + flags &= ~(SIGNOK | DPTOK | EXPOK | NDIGITS); + infcount = 1; + goto fok; + } + if (infcount == 3 || infcount == 5) + { + infcount++; + goto fok; + } + break; + case L'f': + case L'F': + if (infcount == 2) + { + infcount = 3; + goto fok; + } + break; + case L't': + case L'T': + if (infcount == 6) + { + infcount = 7; + goto fok; + } + break; + case L'y': + case L'Y': + if (infcount == 7) + { + infcount = 8; + goto fok; + } + break; + case L'.': + if (flags & DPTOK) + { + flags &= ~(SIGNOK | DPTOK); + leading_zeroes = zeroes; + goto fok; + } + break; + case L'e': + case L'E': + /* no exponent without some digits */ + if ((flags & (NDIGITS | EXPOK)) == EXPOK + || ((flags & EXPOK) && zeroes)) + { + if (! (flags & DPTOK)) + { + exp_adjust = zeroes - leading_zeroes; + exp_start = p; + } + flags = + (flags & ~(EXPOK | DPTOK)) | + SIGNOK | NDIGITS; + zeroes = 0; + goto fok; + } + break; + } + if (c != WEOF) + _ungetwc_r (rptr, c, fp); + break; + fok: + *p++ = c; + fskip: + width--; + ++nread; + } + if (zeroes) + flags &= ~NDIGITS; + /* We may have a 'N' or possibly even [sign] 'N' 'a' as the + start of 'NaN', only to run out of chars before it was + complete (or having encountered a non-matching char). So + check here if we have an outstanding nancount, and if so + put back the chars we did swallow and treat as a failed + match. + + FIXME - we still don't handle NAN([0xdigits]). */ + if (nancount - 1U < 2U) /* nancount && nancount < 3 */ + { + /* Newlib's ungetc works even if we called __srefill in + the middle of a partial parse, but POSIX does not + guarantee that in all implementations of ungetc. */ + while (p > buf) + { + _ungetwc_r (rptr, *--p, fp); /* [-+nNaA] */ + --nread; + } + goto match_failure; + } + /* Likewise for 'inf' and 'infinity'. But be careful that + 'infinite' consumes only 3 characters, leaving the stream + at the second 'i'. */ + if (infcount - 1U < 7U) /* infcount && infcount < 8 */ + { + if (infcount >= 3) /* valid 'inf', but short of 'infinity' */ + while (infcount-- > 3) + { + _ungetwc_r (rptr, *--p, fp); /* [iInNtT] */ + --nread; + } + else + { + while (p > buf) + { + _ungetwc_r (rptr, *--p, fp); /* [-+iInN] */ + --nread; + } + goto match_failure; + } + } + /* + * If no digits, might be missing exponent digits + * (just give back the exponent) or might be missing + * regular digits, but had sign and/or decimal point. + */ + if (flags & NDIGITS) + { + if (flags & EXPOK) + { + /* no digits at all */ + while (p > buf) + { + _ungetwc_r (rptr, *--p, fp); /* [-+.] */ + --nread; + } + goto match_failure; + } + /* just a bad exponent (e and maybe sign) */ + c = *--p; + --nread; + if (c != L'e' && c != L'E') + { + _ungetwc_r (rptr, c, fp); /* [-+] */ + c = *--p; + --nread; + } + _ungetwc_r (rptr, c, fp); /* [eE] */ + } + if ((flags & SUPPRESS) == 0) + { + double res = 0; +#ifdef _NO_LONGDBL +#define QUAD_RES res; +#else /* !_NO_LONG_DBL */ + long double qres = 0; +#define QUAD_RES qres; +#endif /* !_NO_LONG_DBL */ + long new_exp = 0; + + *p = 0; + if ((flags & (DPTOK | EXPOK)) == EXPOK) + { + exp_adjust = zeroes - leading_zeroes; + new_exp = -exp_adjust; + exp_start = p; + } + else if (exp_adjust) + new_exp = _wcstol_r (rptr, (exp_start + 1), NULL, 10) - exp_adjust; + if (exp_adjust) + { + + /* If there might not be enough space for the new exponent, + truncate some trailing digits to make room. */ + if (exp_start >= buf + sizeof (buf) - MAX_LONG_LEN) + exp_start = buf + sizeof (buf) - MAX_LONG_LEN - 1; + swprintf (exp_start, MAX_LONG_LEN, L"e%ld", new_exp); + } + + /* FIXME: We don't have wcstold yet. */ +#if 0//ndef _NO_LONGDBL /* !_NO_LONGDBL */ + if (flags & LONGDBL) + qres = _wcstold_r (rptr, buf, NULL); + else +#endif + res = _wcstod_r (rptr, buf, NULL); + + if (flags & LONG) + { + dp = GET_ARG (N, ap, double *); + *dp = res; + } + else if (flags & LONGDBL) + { + ldp = GET_ARG (N, ap, _LONG_DOUBLE *); + *ldp = QUAD_RES; + } + else + { + flp = GET_ARG (N, ap, float *); + if (isnan (res)) + *flp = nanf (NULL); + else + *flp = res; + } + nassigned++; + } + break; + } +#endif /* FLOATING_POINT */ + } + } +input_failure: + /* On read failure, return EOF failure regardless of matches; errno + should have been set prior to here. On EOF failure (including + invalid format string), return EOF if no matches yet, else number + of matches made prior to failure. */ + _funlockfile (fp); + __sfp_lock_release (); + return nassigned && !(fp->_flags & __SERR) ? nassigned : EOF; +match_failure: +all_done: + /* Return number of matches, which can be 0 on match failure. */ + _funlockfile (fp); + __sfp_lock_release (); + return nassigned; +} + +#ifndef _NO_POS_ARGS +/* Process all intermediate arguments. Fortunately, with wscanf, all + intermediate arguments are sizeof(void*), so we don't need to scan + ahead in the format string. */ +static void * +get_arg (int n, va_list *ap, int *numargs_p, void **args) +{ + int numargs = *numargs_p; + while (n >= numargs) + args[numargs++] = va_arg (*ap, void *); + *numargs_p = numargs; + return args[n]; +} +#endif /* !_NO_POS_ARGS */ diff --git a/newlib/libc/stdio/vsiscanf.c b/newlib/libc/stdio/vsiscanf.c index c26171acf..01295995e 100644 --- a/newlib/libc/stdio/vsiscanf.c +++ b/newlib/libc/stdio/vsiscanf.c @@ -28,16 +28,6 @@ #endif #include "local.h" -static _READ_WRITE_RETURN_TYPE -_DEFUN(eofread1, (ptr, cookie, buf, len), - struct _reent *ptr _AND - _PTR cookie _AND - char *buf _AND - int len) -{ - return 0; -} - /* * vsiscanf */ @@ -67,7 +57,7 @@ _DEFUN(_vsiscanf_r, (ptr, str, fmt, ap), f._flags = __SRD | __SSTR; f._bf._base = f._p = (unsigned char *) str; f._bf._size = f._r = strlen (str); - f._read = eofread1; + f._read = __seofread; f._ub._base = NULL; f._lb._base = NULL; f._file = -1; /* No file. */ diff --git a/newlib/libc/stdio/vsscanf.c b/newlib/libc/stdio/vsscanf.c index 566823add..2b9aeaf5b 100644 --- a/newlib/libc/stdio/vsscanf.c +++ b/newlib/libc/stdio/vsscanf.c @@ -28,16 +28,6 @@ #endif #include "local.h" -static _READ_WRITE_RETURN_TYPE -_DEFUN(eofread1, (ptr, cookie, buf, len), - struct _reent *_ptr _AND - _PTR cookie _AND - char *buf _AND - int len) -{ - return 0; -} - /* * vsscanf */ @@ -67,7 +57,7 @@ _DEFUN(_vsscanf_r, (ptr, str, fmt, ap), f._flags = __SRD | __SSTR; f._bf._base = f._p = (unsigned char *) str; f._bf._size = f._r = strlen (str); - f._read = eofread1; + f._read = __seofread; f._ub._base = NULL; f._lb._base = NULL; f._file = -1; /* No file. */ diff --git a/newlib/libc/stdio/vswprintf.c b/newlib/libc/stdio/vswprintf.c index 5c70f1b92..aebb20a00 100644 --- a/newlib/libc/stdio/vswprintf.c +++ b/newlib/libc/stdio/vswprintf.c @@ -27,6 +27,7 @@ static char sccsid[] = "%W% (Berkeley) %G%"; #include #include #include +#include "local.h" int _DEFUN(_vswprintf_r, (ptr, str, size, fmt, ap), diff --git a/newlib/libc/stdio/vswscanf.c b/newlib/libc/stdio/vswscanf.c new file mode 100644 index 000000000..08108173a --- /dev/null +++ b/newlib/libc/stdio/vswscanf.c @@ -0,0 +1,60 @@ +/* + * Code created by modifying scanf.c which has following copyright. + * + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include <_ansi.h> +#include +#include +#include +#include +#ifdef _HAVE_STDC +#include +#else +#include +#endif +#include "local.h" + +/* + * vsscanf + */ + +#ifndef _REENT_ONLY + +int +vswscanf (_CONST wchar_t *str, _CONST wchar_t *fmt, va_list ap) +{ + return _vswscanf_r (_REENT, str, fmt, ap); +} + +#endif /* !_REENT_ONLY */ + +int +_vswscanf_r (struct _reent *ptr, _CONST wchar_t *str, _CONST wchar_t *fmt, + va_list ap) +{ + FILE f; + + f._flags = __SRD | __SSTR; + f._bf._base = f._p = (unsigned char *) str; + f._bf._size = f._r = wcslen (str) * sizeof (wchar_t); + f._read = __seofread; + f._ub._base = NULL; + f._lb._base = NULL; + f._file = -1; /* No file. */ + return __ssvfwscanf_r (ptr, &f, fmt, ap); +} diff --git a/newlib/libc/stdio/vwscanf.c b/newlib/libc/stdio/vwscanf.c new file mode 100644 index 000000000..3c60fbb73 --- /dev/null +++ b/newlib/libc/stdio/vwscanf.c @@ -0,0 +1,48 @@ +/*- + * Code created by modifying scanf.c which has following copyright. + * + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include <_ansi.h> +#include +#include +#include +#ifdef _HAVE_STDC +#include +#else +#include +#endif +#include "local.h" + +#ifndef _REENT_ONLY + +int +vwscanf (_CONST wchar_t *fmt, va_list ap) +{ + _REENT_SMALL_CHECK_INIT (_REENT); + return __svfwscanf_r (_REENT, _stdin_r (_REENT), fmt, ap); +} + +#endif /* !_REENT_ONLY */ + +int +_vwscanf_r (struct _reent *ptr, _CONST wchar_t *fmt, va_list ap) +{ + _REENT_SMALL_CHECK_INIT (ptr); + return __svfwscanf_r (ptr, _stdin_r (ptr), fmt, ap); +} + diff --git a/newlib/libc/stdio/wscanf.c b/newlib/libc/stdio/wscanf.c new file mode 100644 index 000000000..671727425 --- /dev/null +++ b/newlib/libc/stdio/wscanf.c @@ -0,0 +1,54 @@ +/* + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include <_ansi.h> +#include +#include +#include +#include +#include "local.h" + +#ifndef _REENT_ONLY + +int +wscanf(_CONST wchar_t *fmt, ...) +{ + int ret; + va_list ap; + + _REENT_SMALL_CHECK_INIT (_REENT); + va_start (ap, fmt); + ret = __svfwscanf_r (_REENT, _stdin_r (_REENT), fmt, ap); + va_end (ap); + return ret; +} + +#endif /* !_REENT_ONLY */ + +int +_wscanf_r(struct _reent *ptr, _CONST wchar_t *fmt, ...) +{ + int ret; + va_list ap; + + _REENT_SMALL_CHECK_INIT (ptr); + va_start (ap, fmt); + ret = __svfwscanf_r (ptr, _stdin_r (ptr), fmt, ap); + va_end (ap); + return (ret); +} +