public inbox for newlib-cvs@sourceware.org
help / color / mirror / Atom feed
* [newlib-cygwin/main] stdio: split byte- and wide-char-oriented low-level output functions
@ 2023-11-20 20:02 Corinna Vinschen
  0 siblings, 0 replies; only message in thread
From: Corinna Vinschen @ 2023-11-20 20:02 UTC (permalink / raw)
  To: newlib-cvs

https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=09119463a1445be498f8a6ce3834d462361c7dd3

commit 09119463a1445be498f8a6ce3834d462361c7dd3
Author:     Corinna Vinschen <corinna@vinschen.de>
AuthorDate: Mon Nov 20 20:46:14 2023 +0100
Commit:     Corinna Vinschen <corinna@vinschen.de>
CommitDate: Mon Nov 20 20:59:13 2023 +0100

    stdio: split byte- and wide-char-oriented low-level output functions
    
    Introduce function __swbufw_r and macros/inline-functions called
    __swputc_r.  Call these functions/macros exclusively from wide-char
    functions.
    
    This allows to set and test the stream orientation correctly even if
    output is only performed using byte-oriented macros from stdio.h.
    
    Signed-off-by: Corinna Vinschen <corinna@vinschen.de>

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 =
 @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@am__append_13 = \
@@ -1330,6 +1330,7 @@ am__objects_5 = 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 = 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.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@libc/stdio/$(DEPDIR)/libc_a-wbuf.Po@am__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.Po@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=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(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 $(CYGPATH_W) 'libc/stdio/wbuf.c'; else $(CYGPATH_W) '$(srcdir)/libc/stdio/wbuf.c'; fi`
 
+libc/stdio/libc_a-wbufw.o: libc/stdio/wbufw.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(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 libc/stdio/libc_a-wbufw.o `test -f 'libc/stdio/wbufw.c' || echo '$(srcdir)/'`libc/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='libc/stdio/wbufw.c' object='libc/stdio/libc_a-wbufw.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libc_a_CPPFLAGS) $(CPPFLAGS) $(libc_a_CFLAGS) $(CFLAGS) -c -o libc/stdio/libc_a-wbufw.o `test -f 'libc/stdio/wbufw.c' || echo '$(srcdir)/'`libc/stdio/wbufw.c
+
+libc/stdio/libc_a-wbufw.obj: libc/stdio/wbufw.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(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 libc/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='libc/stdio/wbufw.c' object='libc/stdio/libc_a-wbufw.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(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 $(CYGPATH_W) 'libc/stdio/wbufw.c'; else $(CYGPATH_W) '$(srcdir)/libc/stdio/wbufw.c'; fi`
+
 libc/stdio/libc_a-wsetup.o: libc/stdio/wsetup.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(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 libc/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-wsetup.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 += \
 	%D%/vsprintf.c \
 	%D%/vsscanf.c \
 	%D%/wbuf.c \
+	%D%/wbufw.c \
 	%D%/wsetup.c
 
 ## 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,
     }
 
   for (i = 0; i < len; i++)
-    if (__sputc_r (ptr, (unsigned char) buf[i], fp) == EOF)
+    if (__swputc_r (ptr, (unsigned char) buf[i], fp) == EOF)
       return WEOF;
 
   return (wint_t) wc;
@@ -169,10 +169,7 @@ _fputwc_r (struct _reent *ptr,
   wint_t r;
 
   _newlib_flockfile_start (fp);
-  if (ORIENT(fp, 1) != 1)
-    r = WEOF;
-  else
-    r = __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) == EOF)
+	  if (__swputc_r (ptr, buf[i], fp) == 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 = 0;
 
 #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) == 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) == 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) == 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 _reent *, void *,
 #define ORIENT(fp,ori) (-1)
 #endif
 
+/* 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 == '\n')
+	  __swputc_r (_ptr, '\r', _p);
+#endif
+	if (--_p->_w >= 0 || (_p->_w >= _p->_lbfsize && (char)_c != '\n'))
+		return (*_p->_p++ = _c);
+	else
+		return (__swbufw_r(_ptr, _c, _p));
+}
+#else
+#define       __swputc_raw_r(__ptr, __c, __p) \
+	(--(__p)->_w < 0 ? \
+		(__p)->_w >= (__p)->_lbfsize ? \
+			(*(__p)->_p = (__c)), *(__p)->_p != '\n' ? \
+				(int)*(__p)->_p++ : \
+				__swbufw_r(__ptr, '\n', __p) : \
+			__swbufw_r(__ptr, (int)(__c), __p) : \
+		(*(__p)->_p = (__c), (int)*(__p)->_p++))
+#ifdef __SCLE
+#define __swputc_r(__ptr, __c, __p) \
+        ((((__p)->_flags & __SCLE) && ((__c) == '\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!  */
 
 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 = (unsigned char) c;
 
-  ORIENT (fp, -1);
+  if (ORIENT (fp, -1) != -1)
+    return EOF;
 
   /*
    * 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[] = "%W% (Berkeley) %G%";
+#endif /* LIBC_SCCS and not lint */
+
+#include <_ansi.h>
+#include <stdio.h>
+#include <errno.h>
+#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 = fp->_lbfsize;
+  if (cantwrite (ptr, fp))
+    return EOF;
+  c = (unsigned char) c;
+
+  if (ORIENT (fp, 1) != 1)
+    return EOF;
+
+  n = fp->_p - fp->_bf._base;
+  if (n >= fp->_bf._size)
+    {
+      if (_fflush_r (ptr, fp))
+	return EOF;
+      n = 0;
+    }
+  fp->_w--;
+  *fp->_p++ = c;
+  if (++n == fp->_bf._size || (fp->_flags & __SLBF && c == '\n'))
+    if (_fflush_r (ptr, fp))
+      return EOF;
+  return c;
+}

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-11-20 20:02 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-11-20 20:02 [newlib-cygwin/main] stdio: split byte- and wide-char-oriented low-level output functions Corinna Vinschen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).