From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2155) id 13DD03858C74; Mon, 20 Nov 2023 20:02:06 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 13DD03858C74 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1700510526; bh=wmMXFx/fD9ZBN85dG7HlmqvhwXcVru4VkhzPeqDlQbI=; h=From:To:Subject:Date:From; b=VQD/DQZ/cuD0l2lCXgqTE9kKwwsYV7YRUEOpYRw/9MYUkmuuVrlDmb+wfl314owan VGcfu7MoENVdiAcf5ozT+k2lrjuH1cuBstmSOGtA7iMgXQXTZqmQcSBqImzaKHPsoj 1ci9qLZGjpzhdj1vkxu0lk603G/ZajcwGgi/FpDs= Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Corinna Vinschen To: newlib-cvs@sourceware.org Subject: [newlib-cygwin/main] stdio: split byte- and wide-char-oriented low-level output functions X-Act-Checkin: newlib-cygwin X-Git-Author: Corinna Vinschen X-Git-Refname: refs/heads/main X-Git-Oldrev: bc986b7ff668aa98372fc4e885307339e7ab3f51 X-Git-Newrev: 09119463a1445be498f8a6ce3834d462361c7dd3 Message-Id: <20231120200206.13DD03858C74@sourceware.org> Date: Mon, 20 Nov 2023 20:02:06 +0000 (GMT) List-Id: https://sourceware.org/git/gitweb.cgi?p=3Dnewlib-cygwin.git;h=3D09119463a14= 45be498f8a6ce3834d462361c7dd3 commit 09119463a1445be498f8a6ce3834d462361c7dd3 Author: Corinna Vinschen AuthorDate: Mon Nov 20 20:46:14 2023 +0100 Commit: Corinna Vinschen CommitDate: Mon Nov 20 20:59:13 2023 +0100 stdio: split byte- and wide-char-oriented low-level output functions =20 Introduce function __swbufw_r and macros/inline-functions called __swputc_r. Call these functions/macros exclusively from wide-char functions. =20 This allows to set and test the stream orientation correctly even if output is only performed using byte-oriented macros from stdio.h. =20 Signed-off-by: Corinna Vinschen Diff: --- newlib/Makefile.in | 20 ++++++++++++- newlib/libc/stdio/Makefile.inc | 1 + newlib/libc/stdio/fputwc.c | 7 ++--- newlib/libc/stdio/fputws.c | 2 +- newlib/libc/stdio/fvwrite.c | 48 +++++++++++++++++++++--------- newlib/libc/stdio/local.h | 33 +++++++++++++++++++++ newlib/libc/stdio/wbuf.c | 3 +- newlib/libc/stdio/wbufw.c | 66 ++++++++++++++++++++++++++++++++++++++= ++++ 8 files changed, 159 insertions(+), 21 deletions(-) diff --git a/newlib/Makefile.in b/newlib/Makefile.in index ff2f88ff756e..644e595c90a3 100644 --- a/newlib/Makefile.in +++ b/newlib/Makefile.in @@ -292,7 +292,7 @@ check_PROGRAMS =3D @HAVE_STDIO_DIR_TRUE@ libc/stdio/vsnprintf.c \ @HAVE_STDIO_DIR_TRUE@ libc/stdio/vsprintf.c \ @HAVE_STDIO_DIR_TRUE@ libc/stdio/vsscanf.c libc/stdio/wbuf.c \ -@HAVE_STDIO_DIR_TRUE@ libc/stdio/wsetup.c \ +@HAVE_STDIO_DIR_TRUE@ libc/stdio/wbufw.c libc/stdio/wsetup.c \ @HAVE_STDIO_DIR_TRUE@ $(libc_stdio_ELIX_2_SOURCES) \ @HAVE_STDIO_DIR_TRUE@ $(libc_stdio_ELIX_4_SOURCES) @ELIX_LEVEL_1_FALSE@@HAVE_STDIO_DIR_TRUE@@NEWLIB_NANO_FORMATTED_IO_FALSE@a= m__append_13 =3D \ @@ -1330,6 +1330,7 @@ am__objects_5 =3D libc/stdlib/libc_a-rpmatch.$(OBJEXT= ) \ @HAVE_STDIO_DIR_TRUE@ libc/stdio/libc_a-vsprintf.$(OBJEXT) \ @HAVE_STDIO_DIR_TRUE@ libc/stdio/libc_a-vsscanf.$(OBJEXT) \ @HAVE_STDIO_DIR_TRUE@ libc/stdio/libc_a-wbuf.$(OBJEXT) \ +@HAVE_STDIO_DIR_TRUE@ libc/stdio/libc_a-wbufw.$(OBJEXT) \ @HAVE_STDIO_DIR_TRUE@ libc/stdio/libc_a-wsetup.$(OBJEXT) \ @HAVE_STDIO_DIR_TRUE@ $(am__objects_13) $(am__objects_15) @ELIX_LEVEL_1_FALSE@@HAVE_STDIO64_DIR_TRUE@am__objects_17 =3D libc/stdio64= /libc_a-fdopen64.$(OBJEXT) \ @@ -6126,6 +6127,8 @@ libc/stdio/libc_a-vsscanf.$(OBJEXT): libc/stdio/$(am_= _dirstamp) \ libc/stdio/$(DEPDIR)/$(am__dirstamp) libc/stdio/libc_a-wbuf.$(OBJEXT): libc/stdio/$(am__dirstamp) \ libc/stdio/$(DEPDIR)/$(am__dirstamp) +libc/stdio/libc_a-wbufw.$(OBJEXT): libc/stdio/$(am__dirstamp) \ + libc/stdio/$(DEPDIR)/$(am__dirstamp) libc/stdio/libc_a-wsetup.$(OBJEXT): libc/stdio/$(am__dirstamp) \ libc/stdio/$(DEPDIR)/$(am__dirstamp) libc/stdio/libc_a-asprintf.$(OBJEXT): libc/stdio/$(am__dirstamp) \ @@ -13509,6 +13512,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@libc/stdio/$(DEPDIR)/libc_a-vwprintf.= Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@libc/stdio/$(DEPDIR)/libc_a-vwscanf.P= o@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@libc/stdio/$(DEPDIR)/libc_a-wbuf.Po@a= m__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@libc/stdio/$(DEPDIR)/libc_a-wbufw.Po@= am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@libc/stdio/$(DEPDIR)/libc_a-wprintf.P= o@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@libc/stdio/$(DEPDIR)/libc_a-wscanf.Po= @am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@libc/stdio/$(DEPDIR)/libc_a-wsetup.Po= @am__quote@ @@ -25124,6 +25128,20 @@ libc/stdio/libc_a-wbuf.obj: libc/stdio/wbuf.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=3D$(DEPDIR) $(CCDEPMODE) $(depcom= p) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDE= S) $(INCLUDES) $(libc_a_CPPFLAGS) $(CPPFLAGS) $(libc_a_CFLAGS) $(CFLAGS) -c= -o libc/stdio/libc_a-wbuf.obj `if test -f 'libc/stdio/wbuf.c'; then $(CYGP= ATH_W) 'libc/stdio/wbuf.c'; else $(CYGPATH_W) '$(srcdir)/libc/stdio/wbuf.c'= ; fi` =20 +libc/stdio/libc_a-wbufw.o: libc/stdio/wbufw.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDE= S) $(libc_a_CPPFLAGS) $(CPPFLAGS) $(libc_a_CFLAGS) $(CFLAGS) -MT libc/stdio= /libc_a-wbufw.o -MD -MP -MF libc/stdio/$(DEPDIR)/libc_a-wbufw.Tpo -c -o lib= c/stdio/libc_a-wbufw.o `test -f 'libc/stdio/wbufw.c' || echo '$(srcdir)/'`l= ibc/stdio/wbufw.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libc/stdio/$(DEPDIR)/libc_a-wbufw= .Tpo libc/stdio/$(DEPDIR)/libc_a-wbufw.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source=3D'libc/stdio/wbufw.c' = object=3D'libc/stdio/libc_a-wbufw.o' libtool=3Dno @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=3D$(DEPDIR) $(CCDEPMODE) $(depcom= p) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDE= S) $(INCLUDES) $(libc_a_CPPFLAGS) $(CPPFLAGS) $(libc_a_CFLAGS) $(CFLAGS) -c= -o libc/stdio/libc_a-wbufw.o `test -f 'libc/stdio/wbufw.c' || echo '$(srcd= ir)/'`libc/stdio/wbufw.c + +libc/stdio/libc_a-wbufw.obj: libc/stdio/wbufw.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDE= S) $(libc_a_CPPFLAGS) $(CPPFLAGS) $(libc_a_CFLAGS) $(CFLAGS) -MT libc/stdio= /libc_a-wbufw.obj -MD -MP -MF libc/stdio/$(DEPDIR)/libc_a-wbufw.Tpo -c -o l= ibc/stdio/libc_a-wbufw.obj `if test -f 'libc/stdio/wbufw.c'; then $(CYGPATH= _W) 'libc/stdio/wbufw.c'; else $(CYGPATH_W) '$(srcdir)/libc/stdio/wbufw.c';= fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libc/stdio/$(DEPDIR)/libc_a-wbufw= .Tpo libc/stdio/$(DEPDIR)/libc_a-wbufw.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source=3D'libc/stdio/wbufw.c' = object=3D'libc/stdio/libc_a-wbufw.obj' libtool=3Dno @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=3D$(DEPDIR) $(CCDEPMODE) $(depcom= p) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDE= S) $(INCLUDES) $(libc_a_CPPFLAGS) $(CPPFLAGS) $(libc_a_CFLAGS) $(CFLAGS) -c= -o libc/stdio/libc_a-wbufw.obj `if test -f 'libc/stdio/wbufw.c'; then $(CY= GPATH_W) 'libc/stdio/wbufw.c'; else $(CYGPATH_W) '$(srcdir)/libc/stdio/wbuf= w.c'; fi` + libc/stdio/libc_a-wsetup.o: libc/stdio/wsetup.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDE= S) $(libc_a_CPPFLAGS) $(CPPFLAGS) $(libc_a_CFLAGS) $(CFLAGS) -MT libc/stdio= /libc_a-wsetup.o -MD -MP -MF libc/stdio/$(DEPDIR)/libc_a-wsetup.Tpo -c -o l= ibc/stdio/libc_a-wsetup.o `test -f 'libc/stdio/wsetup.c' || echo '$(srcdir)= /'`libc/stdio/wsetup.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libc/stdio/$(DEPDIR)/libc_a-wsetu= p.Tpo libc/stdio/$(DEPDIR)/libc_a-wsetup.Po diff --git a/newlib/libc/stdio/Makefile.inc b/newlib/libc/stdio/Makefile.inc index 0780e5c602b9..e25680212a39 100644 --- a/newlib/libc/stdio/Makefile.inc +++ b/newlib/libc/stdio/Makefile.inc @@ -117,6 +117,7 @@ libc_a_SOURCES +=3D \ %D%/vsprintf.c \ %D%/vsscanf.c \ %D%/wbuf.c \ + %D%/wbufw.c \ %D%/wsetup.c =20 ## The following are EL/IX level 2 interfaces diff --git a/newlib/libc/stdio/fputwc.c b/newlib/libc/stdio/fputwc.c index ef2be10483eb..8430446dea40 100644 --- a/newlib/libc/stdio/fputwc.c +++ b/newlib/libc/stdio/fputwc.c @@ -155,7 +155,7 @@ __fputwc (struct _reent *ptr, } =20 for (i =3D 0; i < len; i++) - if (__sputc_r (ptr, (unsigned char) buf[i], fp) =3D=3D EOF) + if (__swputc_r (ptr, (unsigned char) buf[i], fp) =3D=3D EOF) return WEOF; =20 return (wint_t) wc; @@ -169,10 +169,7 @@ _fputwc_r (struct _reent *ptr, wint_t r; =20 _newlib_flockfile_start (fp); - if (ORIENT(fp, 1) !=3D 1) - r =3D WEOF; - else - r =3D __fputwc(ptr, wc, fp); + __fputwc(ptr, wc, fp); _newlib_flockfile_end (fp); return r; } diff --git a/newlib/libc/stdio/fputws.c b/newlib/libc/stdio/fputws.c index a9ac9d6d72c6..d6963837b4c7 100644 --- a/newlib/libc/stdio/fputws.c +++ b/newlib/libc/stdio/fputws.c @@ -143,7 +143,7 @@ error: goto error; while (i < nbytes) { - if (__sputc_r (ptr, buf[i], fp) =3D=3D EOF) + if (__swputc_r (ptr, buf[i], fp) =3D=3D EOF) goto error; i++; } diff --git a/newlib/libc/stdio/fvwrite.c b/newlib/libc/stdio/fvwrite.c index fc79951032ad..add48ba99c41 100644 --- a/newlib/libc/stdio/fvwrite.c +++ b/newlib/libc/stdio/fvwrite.c @@ -70,21 +70,43 @@ __sfvwrite_r (struct _reent *ptr, len =3D 0; =20 #ifdef __SCLE + /* This only affects Cygwin, so calling __sputc_r *and* __swputc_r + * from here doesn't matter. + */ if (fp->_flags & __SCLE) /* text mode */ { - do - { - GETIOV (;); - while (len > 0) - { - if (__sputc_r (ptr, *p, fp) =3D=3D EOF) - return EOF; - p++; - len--; - uio->uio_resid--; - } - } - while (uio->uio_resid > 0); + if (fp->_flags2 & __SWID) + { + do + { + GETIOV (;); + while (len > 0) + { + if (__swputc_r (ptr, *p, fp) =3D=3D EOF) + return EOF; + p++; + len--; + uio->uio_resid--; + } + } + while (uio->uio_resid > 0); + } + else + { + do + { + GETIOV (;); + while (len > 0) + { + if (__sputc_r (ptr, *p, fp) =3D=3D EOF) + return EOF; + p++; + len--; + uio->uio_resid--; + } + } + while (uio->uio_resid > 0); + } return 0; } #endif diff --git a/newlib/libc/stdio/local.h b/newlib/libc/stdio/local.h index 3b86cf19aa1c..63c0618f1baf 100644 --- a/newlib/libc/stdio/local.h +++ b/newlib/libc/stdio/local.h @@ -251,6 +251,39 @@ extern _READ_WRITE_RETURN_TYPE __swrite64 (struct _ree= nt *, void *, #define ORIENT(fp,ori) (-1) #endif =20 +/* Same thing as the functions in stdio.h, but these are to be called + from inside the wide-char functions. */ +int __swbufw_r (struct _reent *, int, FILE *); +#ifdef __GNUC__ +_ELIDABLE_INLINE int __swputc_r(struct _reent *_ptr, int _c, FILE *_p) { +#ifdef __SCLE + if ((_p->_flags & __SCLE) && _c =3D=3D '\n') + __swputc_r (_ptr, '\r', _p); +#endif + if (--_p->_w >=3D 0 || (_p->_w >=3D _p->_lbfsize && (char)_c !=3D '\n')) + return (*_p->_p++ =3D _c); + else + return (__swbufw_r(_ptr, _c, _p)); +} +#else +#define __swputc_raw_r(__ptr, __c, __p) \ + (--(__p)->_w < 0 ? \ + (__p)->_w >=3D (__p)->_lbfsize ? \ + (*(__p)->_p =3D (__c)), *(__p)->_p !=3D '\n' ? \ + (int)*(__p)->_p++ : \ + __swbufw_r(__ptr, '\n', __p) : \ + __swbufw_r(__ptr, (int)(__c), __p) : \ + (*(__p)->_p =3D (__c), (int)*(__p)->_p++)) +#ifdef __SCLE +#define __swputc_r(__ptr, __c, __p) \ + ((((__p)->_flags & __SCLE) && ((__c) =3D=3D '\n')) \ + ? __swputc_raw_r(__ptr, '\r', (__p)) : 0 , \ + __swputc_raw_r((__ptr), (__c), (__p))) +#else +#define __swputc_r(__ptr, __c, __p) __swputc_raw_r(__ptr, __c, __p) +#endif +#endif + /* WARNING: _dcvt is defined in the stdlib directory, not here! */ =20 char *_dcvt (struct _reent *, char *, double, int, int, char, int); diff --git a/newlib/libc/stdio/wbuf.c b/newlib/libc/stdio/wbuf.c index 24749030376d..2e742e255b02 100644 --- a/newlib/libc/stdio/wbuf.c +++ b/newlib/libc/stdio/wbuf.c @@ -56,7 +56,8 @@ __swbuf_r (struct _reent *ptr, return EOF; c =3D (unsigned char) c; =20 - ORIENT (fp, -1); + if (ORIENT (fp, -1) !=3D -1) + return EOF; =20 /* * If it is completely full, flush it out. Then, in any case, diff --git a/newlib/libc/stdio/wbufw.c b/newlib/libc/stdio/wbufw.c new file mode 100644 index 000000000000..01639df696ce --- /dev/null +++ b/newlib/libc/stdio/wbufw.c @@ -0,0 +1,66 @@ +/* + * 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, + * and/or 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. + */ +/* No user fns here. Pesch 15apr92. */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] =3D "%W% (Berkeley) %G%"; +#endif /* LIBC_SCCS and not lint */ + +#include <_ansi.h> +#include +#include +#include "local.h" +#include "fvwrite.h" + +/* + * Note that this is the same function as __swbuf_r, just to be called + * from wide-char functions! + * + * The only difference is that we set and test the orientation differently. + */ + +int +__swbufw_r (struct _reent *ptr, + register int c, + register FILE *fp) +{ + register int n; + + CHECK_INIT (ptr, fp); + + fp->_w =3D fp->_lbfsize; + if (cantwrite (ptr, fp)) + return EOF; + c =3D (unsigned char) c; + + if (ORIENT (fp, 1) !=3D 1) + return EOF; + + n =3D fp->_p - fp->_bf._base; + if (n >=3D fp->_bf._size) + { + if (_fflush_r (ptr, fp)) + return EOF; + n =3D 0; + } + fp->_w--; + *fp->_p++ =3D c; + if (++n =3D=3D fp->_bf._size || (fp->_flags & __SLBF && c =3D=3D '\n')) + if (_fflush_r (ptr, fp)) + return EOF; + return c; +}