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>
This commit is contained in:
parent
bc986b7ff6
commit
09119463a1
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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++;
|
||||
}
|
||||
|
|
|
@ -70,7 +70,28 @@ __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 */
|
||||
{
|
||||
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
|
||||
{
|
||||
|
@ -85,6 +106,7 @@ __sfvwrite_r (struct _reent *ptr,
|
|||
}
|
||||
}
|
||||
while (uio->uio_resid > 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue