Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/newlib
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2023-11-20 22:46:14 +0300
committerCorinna Vinschen <corinna@vinschen.de>2023-11-20 22:59:13 +0300
commit09119463a1445be498f8a6ce3834d462361c7dd3 (patch)
treead5e3e893c9ec6b07b032ee9c3768ba509e402c9 /newlib
parentbc986b7ff668aa98372fc4e885307339e7ab3f51 (diff)
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>
Diffstat (limited to 'newlib')
-rw-r--r--newlib/Makefile.in20
-rw-r--r--newlib/libc/stdio/Makefile.inc1
-rw-r--r--newlib/libc/stdio/fputwc.c7
-rw-r--r--newlib/libc/stdio/fputws.c2
-rw-r--r--newlib/libc/stdio/fvwrite.c48
-rw-r--r--newlib/libc/stdio/local.h33
-rw-r--r--newlib/libc/stdio/wbuf.c3
-rw-r--r--newlib/libc/stdio/wbufw.c66
8 files changed, 159 insertions, 21 deletions
diff --git a/newlib/Makefile.in b/newlib/Makefile.in
index ff2f88ff7..644e595c9 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 0780e5c60..e25680212 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 ef2be1048..8430446de 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 a9ac9d6d7..d6963837b 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 fc7995103..add48ba99 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 3b86cf19a..63c0618f1 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 247490303..2e742e255 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 000000000..01639df69
--- /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;
+}