From e74101e4eff767325553039def89de70b70f36d3 Mon Sep 17 00:00:00 2001 From: "Tim J. Robbins" Date: Tue, 13 Aug 2002 09:30:41 +0000 Subject: Basic support for wide character I/O: getwc(), fgetwc(), getwchar(), putwc(), fputwc(), putwchar(), ungetwc(), fwide(). --- lib/libc/stdio/Makefile.inc | 27 ++++++---- lib/libc/stdio/asprintf.c | 3 ++ lib/libc/stdio/fgetc.c | 1 + lib/libc/stdio/fgets.c | 1 + lib/libc/stdio/fgetwc.c | 56 ++++++++++++++++++++ lib/libc/stdio/fgetws.3 | 122 ++++++++++++++++++++++++++++++++++++++++++++ lib/libc/stdio/fgetws.c | 70 +++++++++++++++++++++++++ lib/libc/stdio/findfp.c | 6 +++ lib/libc/stdio/fputc.c | 2 + lib/libc/stdio/fputs.c | 2 + lib/libc/stdio/fputwc.c | 46 +++++++++++++++++ lib/libc/stdio/fputws.3 | 89 ++++++++++++++++++++++++++++++++ lib/libc/stdio/fputws.c | 51 ++++++++++++++++++ lib/libc/stdio/fread.c | 1 + lib/libc/stdio/fwide.c | 51 ++++++++++++++++++ lib/libc/stdio/fwrite.c | 1 + lib/libc/stdio/getc.c | 1 + lib/libc/stdio/getchar.c | 2 + lib/libc/stdio/gets.c | 2 + lib/libc/stdio/getwc.c | 48 +++++++++++++++++ lib/libc/stdio/getwchar.c | 47 +++++++++++++++++ lib/libc/stdio/local.h | 31 +++++++++++ lib/libc/stdio/putc.c | 2 + lib/libc/stdio/putchar.c | 2 + lib/libc/stdio/putwc.c | 48 +++++++++++++++++ lib/libc/stdio/putwchar.c | 47 +++++++++++++++++ lib/libc/stdio/refill.c | 2 + lib/libc/stdio/snprintf.c | 3 ++ lib/libc/stdio/sprintf.c | 3 ++ lib/libc/stdio/stdio.3 | 24 +++++++-- lib/libc/stdio/ungetc.c | 3 ++ lib/libc/stdio/ungetwc.c | 46 +++++++++++++++++ lib/libc/stdio/vasprintf.c | 3 ++ lib/libc/stdio/vfprintf.c | 1 + lib/libc/stdio/vfscanf.c | 2 + lib/libc/stdio/vsnprintf.c | 3 ++ lib/libc/stdio/vsprintf.c | 3 ++ lib/libc/stdio/vsscanf.c | 4 ++ lib/libc/stdio/wbuf.c | 2 + 39 files changed, 846 insertions(+), 12 deletions(-) create mode 100644 lib/libc/stdio/fgetwc.c create mode 100644 lib/libc/stdio/fgetws.3 create mode 100644 lib/libc/stdio/fgetws.c create mode 100644 lib/libc/stdio/fputwc.c create mode 100644 lib/libc/stdio/fputws.3 create mode 100644 lib/libc/stdio/fputws.c create mode 100644 lib/libc/stdio/fwide.c create mode 100644 lib/libc/stdio/getwc.c create mode 100644 lib/libc/stdio/getwchar.c create mode 100644 lib/libc/stdio/putwc.c create mode 100644 lib/libc/stdio/putwchar.c create mode 100644 lib/libc/stdio/ungetwc.c (limited to 'lib') diff --git a/lib/libc/stdio/Makefile.inc b/lib/libc/stdio/Makefile.inc index f4a9f329cb9e..15c61761ade4 100644 --- a/lib/libc/stdio/Makefile.inc +++ b/lib/libc/stdio/Makefile.inc @@ -6,20 +6,27 @@ SRCS+= _flock_stub.c \ asprintf.c clrerr.c fclose.c fdopen.c feof.c ferror.c fflush.c \ - fgetc.c fgetln.c fgetpos.c fgets.c fileno.c findfp.c flags.c fopen.c \ - fprintf.c fpurge.c fputc.c fputs.c fread.c freopen.c fscanf.c \ - fseek.c fsetpos.c ftell.c funopen.c fvwrite.c fwalk.c fwrite.c \ - getc.c getchar.c gets.c getw.c makebuf.c mktemp.c perror.c \ - printf.c putc.c putchar.c puts.c putw.c refill.c remove.c rewind.c \ + fgetc.c fgetln.c fgetpos.c fgets.c fgetwc.c fgetws.c fileno.c findfp.c \ + flags.c fopen.c \ + fprintf.c fpurge.c fputc.c fputs.c fputwc.c fputws.c fread.c freopen.c \ + fscanf.c \ + fseek.c fsetpos.c ftell.c funopen.c fvwrite.c fwalk.c fwide.c fwrite.c \ + getc.c getchar.c gets.c getw.c getwc.c getwchar.c makebuf.c mktemp.c \ + perror.c \ + printf.c putc.c putchar.c puts.c putw.c putwc.c putwchar.c refill.c \ + remove.c rewind.c \ rget.c scanf.c setbuf.c setbuffer.c setvbuf.c snprintf.c sprintf.c \ - sscanf.c stdio.c tempnam.c tmpfile.c tmpnam.c ungetc.c vasprintf.c \ + sscanf.c stdio.c tempnam.c tmpfile.c tmpnam.c ungetc.c ungetwc.c \ + vasprintf.c \ vfprintf.c vfscanf.c vprintf.c vscanf.c vsnprintf.c vsprintf.c \ vsscanf.c wbuf.c wsetup.c .if ${LIB} == "c" -MAN+= fclose.3 ferror.3 fflush.3 fgetln.3 fgets.3 fopen.3 fputs.3 \ - fread.3 fseek.3 funopen.3 getc.3 mktemp.3 printf.3 putc.3 remove.3 \ - scanf.3 setbuf.3 stdio.3 tmpnam.3 ungetc.3 +MAN+= fclose.3 ferror.3 fflush.3 fgetln.3 fgets.3 fgetws.3 fopen.3 fputs.3 \ + fputws.3 \ + fread.3 fseek.3 funopen.3 fwide.3 getc.3 getwc.3 mktemp.3 printf.3 \ + putc.3 putwc.3 remove.3 \ + scanf.3 setbuf.3 stdio.3 tmpnam.3 ungetc.3 ungetwc.3 MLINKS+=ferror.3 clearerr.3 ferror.3 feof.3 ferror.3 fileno.3 MLINKS+=fflush.3 fpurge.3 @@ -31,6 +38,7 @@ MLINKS+=fseek.3 fgetpos.3 fseek.3 fseeko.3 fseek.3 fsetpos.3 fseek.3 ftell.3 \ fseek.3 ftello.3 fseek.3 rewind.3 MLINKS+=funopen.3 fropen.3 funopen.3 fwopen.3 MLINKS+=getc.3 fgetc.3 getc.3 getchar.3 getc.3 getw.3 +MLINKS+=getwc.3 fgetwc.3 getwc.3 getwchar.3 MLINKS+=mktemp.3 mkdtemp.3 mktemp.3 mkstemp.3 mktemp.3 mkstemps.3 MLINKS+=printf.3 asprintf.3 printf.3 fprintf.3 \ printf.3 snprintf.3 printf.3 sprintf.3 \ @@ -38,6 +46,7 @@ MLINKS+=printf.3 asprintf.3 printf.3 fprintf.3 \ printf.3 vfprintf.3 printf.3 vprintf.3 printf.3 vsnprintf.3 \ printf.3 vsprintf.3 MLINKS+=putc.3 fputc.3 putc.3 putchar.3 putc.3 putw.3 +MLINKS+=putwc.3 fputwc.3 putwc.3 putwchar.3 MLINKS+=scanf.3 fscanf.3 scanf.3 sscanf.3 scanf.3 vfscanf.3 scanf.3 vscanf.3 \ scanf.3 vsscanf.3 MLINKS+=setbuf.3 setbuffer.3 setbuf.3 setlinebuf.3 setbuf.3 setvbuf.3 diff --git a/lib/libc/stdio/asprintf.c b/lib/libc/stdio/asprintf.c index 57116e6a91df..1eddf57de830 100644 --- a/lib/libc/stdio/asprintf.c +++ b/lib/libc/stdio/asprintf.c @@ -43,6 +43,7 @@ asprintf(char **str, char const *fmt, ...) int ret; va_list ap; FILE f; + struct __sFILEX ext; va_start(ap, fmt); f._file = -1; @@ -54,6 +55,8 @@ asprintf(char **str, char const *fmt, ...) return (-1); } f._bf._size = f._w = 127; /* Leave room for the NULL */ + f._extra = &ext; + INITEXTRA(&f); ret = __vfprintf(&f, fmt, ap); /* Use unlocked __vfprintf */ *f._p = '\0'; va_end(ap); diff --git a/lib/libc/stdio/fgetc.c b/lib/libc/stdio/fgetc.c index 9aba285c11c5..3469fda79d1c 100644 --- a/lib/libc/stdio/fgetc.c +++ b/lib/libc/stdio/fgetc.c @@ -52,6 +52,7 @@ fgetc(fp) { int retval; FLOCKFILE(fp); + ORIENT(fp, -1); retval = __sgetc(fp); FUNLOCKFILE(fp); return (retval); diff --git a/lib/libc/stdio/fgets.c b/lib/libc/stdio/fgets.c index 9148686e44ad..bb4ea4c70223 100644 --- a/lib/libc/stdio/fgets.c +++ b/lib/libc/stdio/fgets.c @@ -66,6 +66,7 @@ fgets(buf, n, fp) return (NULL); FLOCKFILE(fp); + ORIENT(fp, -1); s = buf; n--; /* leave space for NUL */ while (n != 0) { diff --git a/lib/libc/stdio/fgetwc.c b/lib/libc/stdio/fgetwc.c new file mode 100644 index 000000000000..7278dadd6b5b --- /dev/null +++ b/lib/libc/stdio/fgetwc.c @@ -0,0 +1,56 @@ +/*- + * Copyright (c) 2002 Tim J. Robbins. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include "namespace.h" +#include +#include +#include +#include +#include "un-namespace.h" +#include "libc_private.h" +#include "local.h" + +wint_t +fgetwc(FILE *fp) +{ + wint_t wc; + long r; + + ORIENTLOCK(fp, 1); + + if ((r = fgetrune(fp)) == _INVALID_RUNE) { + wc = WEOF; + errno = EILSEQ; + } else if (r == EOF) + wc = WEOF; + else + wc = (wint_t)r; + + return (wc); +} diff --git a/lib/libc/stdio/fgetws.3 b/lib/libc/stdio/fgetws.3 new file mode 100644 index 000000000000..5ccd4fe5e323 --- /dev/null +++ b/lib/libc/stdio/fgetws.3 @@ -0,0 +1,122 @@ +.\" Copyright (c) 1990, 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" Chris Torek and the American National Standards Committee X3, +.\" on Information Processing Systems. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" @(#)fgets.3 8.1 (Berkeley) 6/4/93 +.\" FreeBSD: src/lib/libc/stdio/fgets.3,v 1.16 2002/05/31 05:01:17 archie Exp +.\" $FreeBSD$ +.\" +.Dd August 6, 2002 +.Dt FGETWS 3 +.Os +.Sh NAME +.Nm fgetws +.Nd get a line of wide characters from a stream +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdio.h +.In wchar.h +.Ft "wchar_t *" +.Fn fgetws "wchar_t *restrict ws" "int n" "FILE *restrict fp" +.Sh DESCRIPTION +The +.Fn fgetws +function +reads at most one less than the number of characters specified by +.Fa n +from the given +.Fa fp +and stores them in the wide character string +.Fa ws . +Reading stops when a newline character is found, +at end-of-file or error. +The newline, if any, is retained. +If any characters are read and there is no error, a +.Ql \e0 +character is appended to end the string. +.Sh RETURN VALUES +Upon successful completion, +.Fn fgetws +returns +.Fa ws . +If end-of-file occurs before any characters are read, +.Fn fgetws +returns +.Dv NULL +and the buffer contents remain unchanged. +If an error occurs, +.Fn fgetws +returns +.Dv NULL +and the buffer contents are indeterminate. +The +.Fn fgetws +function +does not distinguish between end-of-file and error, and callers must use +.Xr feof 3 +and +.Xr ferror 3 +to determine which occurred. +.Sh ERRORS +.Bl -tag -width Er +.It Bq Er EBADF +The given +.Fa fp +argument is not a readable stream. +.It Bq Er EILSEQ +The data obtained from the input stream does not form a valid +multibyte character. +.El +.Pp +The function +.Fn fgetws +may also fail and set +.Va errno +for any of the errors specified for the routines +.Xr fflush 3 , +.Xr fstat 2 , +.Xr read 2 , +or +.Xr malloc 3 . +.Sh SEE ALSO +.Xr feof 3 , +.Xr ferror 3 , +.Xr fgets 3 +.Sh STANDARDS +The +.Fn fgetws +function +conforms to +.St -p1003.1-2001 . diff --git a/lib/libc/stdio/fgetws.c b/lib/libc/stdio/fgetws.c new file mode 100644 index 000000000000..2cfd4e3cfa71 --- /dev/null +++ b/lib/libc/stdio/fgetws.c @@ -0,0 +1,70 @@ +/*- + * Copyright (c) 2002 Tim J. Robbins. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include "namespace.h" +#include +#include +#include +#include +#include "un-namespace.h" +#include "libc_private.h" +#include "local.h" + +wchar_t * +fgetws(wchar_t *__restrict ws, int n, FILE *__restrict fp) +{ + wchar_t *wsp; + long r; + + ORIENTLOCK(fp, 1); + + if (n <= 0) + return (NULL); + + wsp = ws; + while (n-- > 1) { + /* XXX Inefficient */ + if ((r = fgetrune(fp)) == _INVALID_RUNE) { + errno = EILSEQ; + return (NULL); + } + if (r == EOF) { + if (wsp == ws) + /* EOF/error, no characters read yet. */ + return (NULL); + break; + } + *wsp++ = (wchar_t)r; + if (r == L'\n') + break; + } + *wsp++ = L'\0'; + + return (ws); +} diff --git a/lib/libc/stdio/findfp.c b/lib/libc/stdio/findfp.c index 8b7517ab7cd8..40a2a048eb64 100644 --- a/lib/libc/stdio/findfp.c +++ b/lib/libc/stdio/findfp.c @@ -176,6 +176,12 @@ found: fp->_lb._base = NULL; /* no line buffer */ fp->_lb._size = 0; /* fp->_lock = NULL; */ /* once set always set (reused) */ + fp->_extra->orientation = 0; +#ifdef notdef + /* Stateful encoding/decoding is not yet supported. */ + memset(&fp->_extra->wstate, 0, sizeof(mbstate_t)); + memset(&fp->_extra->rstate, 0, sizeof(mbstate_t)); +#endif return (fp); } diff --git a/lib/libc/stdio/fputc.c b/lib/libc/stdio/fputc.c index d5023650ded2..0fe538d52283 100644 --- a/lib/libc/stdio/fputc.c +++ b/lib/libc/stdio/fputc.c @@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include "un-namespace.h" +#include "local.h" #include "libc_private.h" int @@ -52,6 +53,7 @@ fputc(c, fp) { int retval; FLOCKFILE(fp); + ORIENT(fp, -1); retval = putc(c, fp); FUNLOCKFILE(fp); return (retval); diff --git a/lib/libc/stdio/fputs.c b/lib/libc/stdio/fputs.c index c885c174f5c7..e209659dd553 100644 --- a/lib/libc/stdio/fputs.c +++ b/lib/libc/stdio/fputs.c @@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$"); #include "un-namespace.h" #include "fvwrite.h" #include "libc_private.h" +#include "local.h" /* * Write the given string to the given file. @@ -64,6 +65,7 @@ fputs(s, fp) uio.uio_iov = &iov; uio.uio_iovcnt = 1; FLOCKFILE(fp); + ORIENT(fp, -1); retval = __sfvwrite(fp, &uio); FUNLOCKFILE(fp); return (retval); diff --git a/lib/libc/stdio/fputwc.c b/lib/libc/stdio/fputwc.c new file mode 100644 index 000000000000..ae19cd62a8eb --- /dev/null +++ b/lib/libc/stdio/fputwc.c @@ -0,0 +1,46 @@ +/*- + * Copyright (c) 2002 Tim J. Robbins. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include "namespace.h" +#include +#include +#include +#include +#include "un-namespace.h" +#include "libc_private.h" +#include "local.h" + +wint_t +fputwc(wchar_t wc, FILE *fp) +{ + + ORIENTLOCK(fp, 1); + + return (fputrune((rune_t)wc, fp) != EOF ? (wint_t)wc : WEOF); +} diff --git a/lib/libc/stdio/fputws.3 b/lib/libc/stdio/fputws.3 new file mode 100644 index 000000000000..e9908e617d9f --- /dev/null +++ b/lib/libc/stdio/fputws.3 @@ -0,0 +1,89 @@ +.\" Copyright (c) 1990, 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" Chris Torek and the American National Standards Committee X3, +.\" on Information Processing Systems. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" @(#)fputs.3 8.1 (Berkeley) 6/4/93 +.\" FreeBSD: src/lib/libc/stdio/fputs.3,v 1.8 2001/10/01 16:08:59 ru Exp +.\" $FreeBSD$ +.\" +.Dd August 6, 2002 +.Dt FPUTWS 3 +.Os +.Sh NAME +.Nm fputws +.Nd output a line of wide characters to a stream +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdio.h +.In wchar.h +.Ft int +.Fn fputws "const wchar_t *restrict ws" "FILE *restrict fp" +.Sh DESCRIPTION +The +.Fn fputws +function writes the wide character string pointed to by +.Fa ws +to the stream pointed to by +.Fa fp . +.Sh RETURN VALUES +The +.Fn fputws +function +returns 0 on success and -1 on error. +.Sh ERRORS +.Bl -tag -width Er +.It Bq Er EBADF +The +.Fa fp +argument supplied +is not a writable stream. +.El +.Pp +The +.Fn fputws +function may also fail and set +.Va errno +for any of the errors specified for the routine +.Xr write 2 . +.Sh SEE ALSO +.Xr ferror 3 , +.Xr fputs 3 , +.Xr putwc 3 , +.Xr stdio 3 +.Sh STANDARDS +The +.Fn fputws +function conforms to +.St -p1003.1-2001 . diff --git a/lib/libc/stdio/fputws.c b/lib/libc/stdio/fputws.c new file mode 100644 index 000000000000..3cf529985ccc --- /dev/null +++ b/lib/libc/stdio/fputws.c @@ -0,0 +1,51 @@ +/*- + * Copyright (c) 2002 Tim J. Robbins. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include "namespace.h" +#include +#include +#include +#include +#include "un-namespace.h" +#include "libc_private.h" +#include "local.h" + +int +fputws(const wchar_t *__restrict ws, FILE *__restrict fp) +{ + + ORIENTLOCK(fp, 1); + + /* XXX Inefficient */ + while (*ws != '\0') + if (fputrune((rune_t)*ws++, fp) == EOF) + return (-1); + + return (0); +} diff --git a/lib/libc/stdio/fread.c b/lib/libc/stdio/fread.c index a437fc721193..39c1a8c36db4 100644 --- a/lib/libc/stdio/fread.c +++ b/lib/libc/stdio/fread.c @@ -66,6 +66,7 @@ fread(buf, size, count, fp) if ((resid = count * size) == 0) return (0); FLOCKFILE(fp); + ORIENT(fp, -1); if (fp->_r < 0) fp->_r = 0; total = resid; diff --git a/lib/libc/stdio/fwide.c b/lib/libc/stdio/fwide.c new file mode 100644 index 000000000000..70309f56daa1 --- /dev/null +++ b/lib/libc/stdio/fwide.c @@ -0,0 +1,51 @@ +/*- + * Copyright (c) 2002 Tim J. Robbins. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include "namespace.h" +#include +#include +#include +#include "un-namespace.h" +#include "libc_private.h" +#include "local.h" + +int +fwide(FILE *fp, int mode) +{ + int m; + + FLOCKFILE(fp); + /* Only change the orientation if the stream is not oriented yet. */ + if (mode != 0 && fp->_extra->orientation == 0) + fp->_extra->orientation = mode > 0 ? 1 : -1; + m = fp->_extra->orientation; + FUNLOCKFILE(fp); + + return (m); +} diff --git a/lib/libc/stdio/fwrite.c b/lib/libc/stdio/fwrite.c index 0687714de7c8..445baecb7da4 100644 --- a/lib/libc/stdio/fwrite.c +++ b/lib/libc/stdio/fwrite.c @@ -67,6 +67,7 @@ fwrite(buf, size, count, fp) uio.uio_iovcnt = 1; FLOCKFILE(fp); + ORIENT(fp, -1); /* * The usual case is success (__sfvwrite returns 0); * skip the divide if this happens, since divides are diff --git a/lib/libc/stdio/getc.c b/lib/libc/stdio/getc.c index 49b4c97b2f7a..8fb30576f658 100644 --- a/lib/libc/stdio/getc.c +++ b/lib/libc/stdio/getc.c @@ -51,6 +51,7 @@ getc(FILE *fp) { int retval; FLOCKFILE(fp); + ORIENT(fp, -1); retval = __sgetc(fp); FUNLOCKFILE(fp); return (retval); diff --git a/lib/libc/stdio/getchar.c b/lib/libc/stdio/getchar.c index e68c52f84cdd..5aa8024b607e 100644 --- a/lib/libc/stdio/getchar.c +++ b/lib/libc/stdio/getchar.c @@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include "un-namespace.h" +#include "local.h" #include "libc_private.h" #undef getchar @@ -55,6 +56,7 @@ getchar() { int retval; FLOCKFILE(stdin); + ORIENT(stdin, -1); retval = getc(stdin); FUNLOCKFILE(stdin); return (retval); diff --git a/lib/libc/stdio/gets.c b/lib/libc/stdio/gets.c index 384cb412d250..932b828629f1 100644 --- a/lib/libc/stdio/gets.c +++ b/lib/libc/stdio/gets.c @@ -58,6 +58,8 @@ gets(buf) static char w[] = "warning: this program uses gets(), which is unsafe.\n"; + /* Orientation set by getchar(). */ + if (!warned) { (void) _write(STDERR_FILENO, w, sizeof(w) - 1); warned = 1; diff --git a/lib/libc/stdio/getwc.c b/lib/libc/stdio/getwc.c new file mode 100644 index 000000000000..ac1a763cd467 --- /dev/null +++ b/lib/libc/stdio/getwc.c @@ -0,0 +1,48 @@ +/*- + * Copyright (c) 2002 Tim J. Robbins. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include "namespace.h" +#include +#include +#include "un-namespace.h" +#include "libc_private.h" +#include "local.h" + +/* + * Synonym for fgetwc(). The only difference is that getwc(), if it is a + * macro, may evaluate `fp' more than once. Function call overhead is not + * an issue here: wchar.h #define's getwc to fgetwc. + */ +#undef getwc +wint_t +getwc(FILE *fp) +{ + + return (fgetwc(fp)); +} diff --git a/lib/libc/stdio/getwchar.c b/lib/libc/stdio/getwchar.c new file mode 100644 index 000000000000..25c15b0eb0f0 --- /dev/null +++ b/lib/libc/stdio/getwchar.c @@ -0,0 +1,47 @@ +/*- + * Copyright (c) 2002 Tim J. Robbins. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include "namespace.h" +#include +#include +#include "un-namespace.h" +#include "libc_private.h" +#include "local.h" + +/* + * Synonym for fgetwc(stdin). Function call overhead is not an issue here: + * wchar.h #define's getwchar() to fgetwc(stdin). + */ +#undef getwchar +wint_t +getwchar(void) +{ + + return (fgetwc(stdin)); +} diff --git a/lib/libc/stdio/local.h b/lib/libc/stdio/local.h index 5b2e23ee1b64..4d8926a766cc 100644 --- a/lib/libc/stdio/local.h +++ b/lib/libc/stdio/local.h @@ -39,6 +39,8 @@ #include /* for off_t */ #include +#include +#include /* * Information local to this implementation of stdio, @@ -78,6 +80,16 @@ struct __sFILEX { pthread_mutex_t fl_mutex; /* used for MT-safety */ pthread_t fl_owner; /* current owner */ int fl_count; /* recursive lock count */ + int orientation; /* orientation for fwide() */ +#ifdef notdef + /* + * XXX These are not used yet -- they will be used to store the + * multibyte conversion state for writing and reading when + * stateful encodings are supported by the locale framework. + */ + mbstate_t wstate; /* write conversion state */ + mbstate_t rstate; /* read conversion state */ +#endif }; /* @@ -113,4 +125,23 @@ struct __sFILEX { (fp)->_extra->fl_mutex = PTHREAD_MUTEX_INITIALIZER; \ (fp)->_extra->fl_owner = NULL; \ (fp)->_extra->fl_count = 0; \ + (fp)->_extra->orientation = 0; \ + /* memset(&(fp)->_extra->wstate, 0, sizeof(mbstate_t)); */ \ + /* memset(&(fp)->_extra->rstate, 0, sizeof(mbstate_t)); */ \ } + +/* + * Set the orientation for a stream. If o > 0, the stream has wide- + * orientation. If o < 0, the stream has byte-orientation. + */ +#define ORIENT(fp, o) do { \ + if ((fp)->_extra->orientation == 0) \ + (fp)->_extra->orientation = (o); \ +} while (0) +#ifdef FLOCKFILE +#define ORIENTLOCK(fp, o) do { \ + FLOCKFILE(fp); \ + ORIENT(fp, o); \ + FUNLOCKFILE(fp); \ +} while (0) +#endif diff --git a/lib/libc/stdio/putc.c b/lib/libc/stdio/putc.c index feec00316931..95a9cac5b5d2 100644 --- a/lib/libc/stdio/putc.c +++ b/lib/libc/stdio/putc.c @@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include "un-namespace.h" +#include "local.h" #include "libc_private.h" /* @@ -60,6 +61,7 @@ putc(c, fp) { int retval; FLOCKFILE(fp); + ORIENT(fp, -1); retval = __sputc(c, fp); FUNLOCKFILE(fp); return (retval); diff --git a/lib/libc/stdio/putchar.c b/lib/libc/stdio/putchar.c index 8f961169c29a..5a775ece1c58 100644 --- a/lib/libc/stdio/putchar.c +++ b/lib/libc/stdio/putchar.c @@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include "un-namespace.h" +#include "local.h" #include "libc_private.h" /* @@ -64,6 +65,7 @@ putchar(c) FILE *so = stdout; FLOCKFILE(so); + ORIENT(so, -1); retval = __sputc(c, so); FUNLOCKFILE(so); return (retval); diff --git a/lib/libc/stdio/putwc.c b/lib/libc/stdio/putwc.c new file mode 100644 index 000000000000..1607fd856564 --- /dev/null +++ b/lib/libc/stdio/putwc.c @@ -0,0 +1,48 @@ +/*- + * Copyright (c) 2002 Tim J. Robbins. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include "namespace.h" +#include +#include +#include "un-namespace.h" +#include "libc_private.h" +#include "local.h" + +/* + * Synonym for fputwc(). The only difference is that putwc(), if it is a + * macro, may evaluate `fp' more than once. Function call overhead is not + * an issue here: wchar.h #define's putwc to fputwc. + */ +#undef putwc +wint_t +putwc(wchar_t wc, FILE *fp) +{ + + return (fputwc(wc, fp)); +} diff --git a/lib/libc/stdio/putwchar.c b/lib/libc/stdio/putwchar.c new file mode 100644 index 000000000000..35ae489af97f --- /dev/null +++ b/lib/libc/stdio/putwchar.c @@ -0,0 +1,47 @@ +/*- + * Copyright (c) 2002 Tim J. Robbins. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include "namespace.h" +#include +#include +#include "un-namespace.h" +#include "libc_private.h" +#include "local.h" + +/* + * Synonym for fputwc(wc, stdout). Function call overhead is not an issue here: + * wchar.h #define's putwchar(wc) to fgetwc(wc, stdout). + */ +#undef putwchar +wint_t +putwchar(wchar_t wc) +{ + + return (fputwc(wc, stdout)); +} diff --git a/lib/libc/stdio/refill.c b/lib/libc/stdio/refill.c index a1e4e30a2e48..b76bb701aca0 100644 --- a/lib/libc/stdio/refill.c +++ b/lib/libc/stdio/refill.c @@ -76,6 +76,8 @@ __srefill(FILE *fp) if (!__sdidinit) __sinit(); + ORIENT(fp, -1); + fp->_r = 0; /* largely a convenience for callers */ /* SysV does not make this test; take it out for compatibility */ diff --git a/lib/libc/stdio/snprintf.c b/lib/libc/stdio/snprintf.c index e3e71f227bd3..e4cc7fcfea4e 100644 --- a/lib/libc/stdio/snprintf.c +++ b/lib/libc/stdio/snprintf.c @@ -53,6 +53,7 @@ snprintf(char *str, size_t n, char const *fmt, ...) int ret; va_list ap; FILE f; + struct __sFILEX ext; on = n; if (n != 0) @@ -64,6 +65,8 @@ snprintf(char *str, size_t n, char const *fmt, ...) f._flags = __SWR | __SSTR; f._bf._base = f._p = (unsigned char *)str; f._bf._size = f._w = n; + f._extra = &ext; + INITEXTRA(&f); ret = __vfprintf(&f, fmt, ap); if (on > 0) *f._p = '\0'; diff --git a/lib/libc/stdio/sprintf.c b/lib/libc/stdio/sprintf.c index 7b81c1f8638e..e2511d64f8b3 100644 --- a/lib/libc/stdio/sprintf.c +++ b/lib/libc/stdio/sprintf.c @@ -51,11 +51,14 @@ sprintf(char *str, char const *fmt, ...) int ret; va_list ap; FILE f; + struct __sFILEX ext; f._file = -1; f._flags = __SWR | __SSTR; f._bf._base = f._p = (unsigned char *)str; f._bf._size = f._w = INT_MAX; + f._extra = &ext; + INITEXTRA(&f); va_start(ap, fmt); ret = __vfprintf(&f, fmt, ap); va_end(ap); diff --git a/lib/libc/stdio/stdio.3 b/lib/libc/stdio/stdio.3 index 0c2c20b0dfb2..4561a980360c 100644 --- a/lib/libc/stdio/stdio.3 +++ b/lib/libc/stdio/stdio.3 @@ -32,7 +32,7 @@ .\" @(#)stdio.3 8.7 (Berkeley) 4/19/94 .\" $FreeBSD$ .\" -.Dd April 19, 1994 +.Dd August 11, 2002 .Dt STDIO 3 .Os .Sh NAME @@ -194,8 +194,12 @@ without first removing their current definitions with .Dv fwopen , .Dv getc , .Dv getchar , +.Dv getwc , +.Dv getwchar , .Dv putc , .Dv putchar , +.Dv putwc , +.Dv putwchar , .Dv stderr , .Dv stdin , .Dv stdout , @@ -207,9 +211,13 @@ Function versions of the macro functions .Fn fileno , .Fn getc , .Fn getchar , +.Fn getwc , +.Fn getwchar , .Fn putc , +.Fn putchar , +.Fn putwc and -.Fn putchar +.Fn putwchar exist and will be used if the macro definitions are explicitly removed. .Sh SEE ALSO @@ -225,7 +233,7 @@ library and system functions, especially The .Nm library conforms to -.St -isoC . +.St -isoC-99 . .Sh LIST OF FUNCTIONS .Bl -column "Description" .It Sy "Function Description" @@ -240,12 +248,16 @@ library conforms to .It "fgetln get a line from a stream" .It "fgetpos reposition a stream" .It "fgets get a line from a stream" +.It "fgetwc get next wide character from input stream" +.It "fgetws get a line of wide characters from a stream" .It "fileno check and reset stream status" .It "fopen stream open functions" .It "fprintf formatted output conversion" .It "fpurge flush a stream" .It "fputc output a character or word to a stream" .It "fputs output a line to a stream" +.It "fputwc output a wide character to a stream" +.It "fputws output a line of wide characters to a stream" .It "fread binary stream input/output" .It "freopen stream open functions" .It "fropen open a stream" @@ -254,12 +266,15 @@ library conforms to .It "fsetpos reposition a stream" .It "ftell reposition a stream" .It "funopen open a stream" +.It "fwide set/get orientation of stream" .It "fwopen open a stream" .It "fwrite binary stream input/output" .It "getc get next character or word from input stream" .It "getchar get next character or word from input stream" .It "gets get a line from a stream" .It "getw get next character or word from input stream" +.It "getwc get next wide character from input stream" +.It "getwchar get next wide character from input stream" .It "mkdtemp create unique temporary file" .It "mkstemp create unique temporary file" .It "mktemp create unique temporary file" @@ -269,6 +284,8 @@ library conforms to .It "putchar output a character or word to a stream" .It "puts output a line to a stream" .It "putw output a character or word to a stream" +.It "putwc output a wide character to a stream" +.It "putwchar output a wide character to a stream" .It "remove remove directory entry" .It "rewind reposition a stream" .It "scanf input format conversion" @@ -286,6 +303,7 @@ library conforms to .It "tmpfile temporary file routines" .It "tmpnam temporary file routines" .It "ungetc un-get character from input stream" +.It "ungetwc un-get wide character from input stream" .It "vasprintf formatted output conversion" .It "vfprintf formatted output conversion" .It "vfscanf input format conversion" diff --git a/lib/libc/stdio/ungetc.c b/lib/libc/stdio/ungetc.c index 9273d07803aa..cb38e9eaa4a0 100644 --- a/lib/libc/stdio/ungetc.c +++ b/lib/libc/stdio/ungetc.c @@ -112,6 +112,9 @@ ungetc(int c, FILE *fp) int __ungetc(int c, FILE *fp) { + + ORIENT(fp, -1); + if (c == EOF) return (EOF); if ((fp->_flags & __SRD) == 0) { diff --git a/lib/libc/stdio/ungetwc.c b/lib/libc/stdio/ungetwc.c new file mode 100644 index 000000000000..2a509865ffc9 --- /dev/null +++ b/lib/libc/stdio/ungetwc.c @@ -0,0 +1,46 @@ +/*- + * Copyright (c) 2002 Tim J. Robbins. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include "namespace.h" +#include +#include +#include +#include +#include "un-namespace.h" +#include "libc_private.h" +#include "local.h" + +wint_t +ungetwc(wint_t wc, FILE *fp) +{ + + ORIENTLOCK(fp, 1); + + return (fungetrune((rune_t)wc, fp) == EOF ? WEOF : wc); +} diff --git a/lib/libc/stdio/vasprintf.c b/lib/libc/stdio/vasprintf.c index bed79eb72ccd..498e7bbefd6c 100644 --- a/lib/libc/stdio/vasprintf.c +++ b/lib/libc/stdio/vasprintf.c @@ -43,6 +43,7 @@ vasprintf(str, fmt, ap) { int ret; FILE f; + struct __sFILEX ext; f._file = -1; f._flags = __SWR | __SSTR | __SALC; @@ -53,6 +54,8 @@ vasprintf(str, fmt, ap) return (-1); } f._bf._size = f._w = 127; /* Leave room for the NULL */ + f._extra = &ext; + INITEXTRA(&f); ret = __vfprintf(&f, fmt, ap); *f._p = '\0'; f._bf._base = reallocf(f._bf._base, f._bf._size + 1); diff --git a/lib/libc/stdio/vfprintf.c b/lib/libc/stdio/vfprintf.c index 55fc82c2e87e..b158bc09323e 100644 --- a/lib/libc/stdio/vfprintf.c +++ b/lib/libc/stdio/vfprintf.c @@ -151,6 +151,7 @@ __sbprintf(FILE *fp, const char *fmt, va_list ap) fake._file = fp->_file; fake._cookie = fp->_cookie; fake._write = fp->_write; + fake._extra = fp->_extra; /* set up the buffer */ fake._bf._base = fake._p = buf; diff --git a/lib/libc/stdio/vfscanf.c b/lib/libc/stdio/vfscanf.c index e329eed699ee..47334d5c4cc9 100644 --- a/lib/libc/stdio/vfscanf.c +++ b/lib/libc/stdio/vfscanf.c @@ -145,6 +145,8 @@ __svfscanf(FILE *fp, const char *fmt0, va_list ap) char decimal_point = localeconv()->decimal_point[0]; #endif + ORIENT(fp, -1); + nassigned = 0; nconversions = 0; nread = 0; diff --git a/lib/libc/stdio/vsnprintf.c b/lib/libc/stdio/vsnprintf.c index cb0e15a80ad6..18b5e5c0537b 100644 --- a/lib/libc/stdio/vsnprintf.c +++ b/lib/libc/stdio/vsnprintf.c @@ -54,6 +54,7 @@ vsnprintf(str, n, fmt, ap) size_t on; int ret; FILE f; + struct __sFILEX ext; on = n; if (n != 0) @@ -64,6 +65,8 @@ vsnprintf(str, n, fmt, ap) f._flags = __SWR | __SSTR; f._bf._base = f._p = (unsigned char *)str; f._bf._size = f._w = n; + f._extra = &ext; + INITEXTRA(&f); ret = __vfprintf(&f, fmt, ap); if (on > 0) *f._p = '\0'; diff --git a/lib/libc/stdio/vsprintf.c b/lib/libc/stdio/vsprintf.c index a3eebb39b0a9..3f92fcdb0227 100644 --- a/lib/libc/stdio/vsprintf.c +++ b/lib/libc/stdio/vsprintf.c @@ -52,11 +52,14 @@ vsprintf(str, fmt, ap) { int ret; FILE f; + struct __sFILEX ext; f._file = -1; f._flags = __SWR | __SSTR; f._bf._base = f._p = (unsigned char *)str; f._bf._size = f._w = INT_MAX; + f._extra = &ext; + INITEXTRA(&f); ret = __vfprintf(&f, fmt, ap); *f._p = 0; return (ret); diff --git a/lib/libc/stdio/vsscanf.c b/lib/libc/stdio/vsscanf.c index 6841fc48fbf5..58778f661ae3 100644 --- a/lib/libc/stdio/vsscanf.c +++ b/lib/libc/stdio/vsscanf.c @@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include "local.h" static int eofread(void *, char *, int); @@ -64,6 +65,7 @@ vsscanf(str, fmt, ap) _BSD_VA_LIST_ ap; { FILE f; + struct __sFILEX ext; f._file = -1; f._flags = __SRD; @@ -72,5 +74,7 @@ vsscanf(str, fmt, ap) f._read = eofread; f._ub._base = NULL; f._lb._base = NULL; + f._extra = &ext; + INITEXTRA(&f); return (__svfscanf(&f, fmt, ap)); } diff --git a/lib/libc/stdio/wbuf.c b/lib/libc/stdio/wbuf.c index 9f4f0965eb90..80945d822571 100644 --- a/lib/libc/stdio/wbuf.c +++ b/lib/libc/stdio/wbuf.c @@ -69,6 +69,8 @@ __swbuf(c, fp) return (EOF); c = (unsigned char)c; + ORIENT(fp, -1); + /* * If it is completely full, flush it out. Then, in any case, * stuff c into the buffer. If this causes the buffer to fill -- cgit v1.2.3