From 5bb288ec923336fc582dae1b5ee61a4965037b5f Mon Sep 17 00:00:00 2001 From: tjr Date: Wed, 18 Sep 2002 05:58:11 +0000 Subject: Reimplement the functionality of fgetrune(), fputrune(), and fungetrune() here in terms of mbrtowc(), wcrtomb(), and the single-byte I/O functions. The rune I/O functions are about to become deprecated in favour of the ones provided by ISO C90 Amd. 1 and C99. --- lib/libc/stdio/fgetwc.c | 38 +++++++++++++++++++++++++++----------- lib/libc/stdio/fgetws.c | 13 +++++-------- lib/libc/stdio/fputwc.c | 15 +++++++++++++-- lib/libc/stdio/fputws.c | 3 +-- lib/libc/stdio/ungetwc.c | 17 +++++++++++++++-- 5 files changed, 61 insertions(+), 25 deletions(-) (limited to 'lib/libc/stdio') diff --git a/lib/libc/stdio/fgetwc.c b/lib/libc/stdio/fgetwc.c index 7278dad..c726caf 100644 --- a/lib/libc/stdio/fgetwc.c +++ b/lib/libc/stdio/fgetwc.c @@ -29,8 +29,8 @@ __FBSDID("$FreeBSD$"); #include "namespace.h" #include -#include #include +#include #include #include "un-namespace.h" #include "libc_private.h" @@ -39,18 +39,34 @@ __FBSDID("$FreeBSD$"); wint_t fgetwc(FILE *fp) { - wint_t wc; - long r; + char buf[MB_LEN_MAX]; + mbstate_t mbs; + size_t n, nconv; + int c; + wchar_t wc; ORIENTLOCK(fp, 1); - if ((r = fgetrune(fp)) == _INVALID_RUNE) { - wc = WEOF; - errno = EILSEQ; - } else if (r == EOF) - wc = WEOF; - else - wc = (wint_t)r; + n = 0; + while (n < MB_CUR_MAX) { + if ((c = fgetc(fp)) == EOF) { + if (n == 0) + return (WEOF); + break; + } + buf[n++] = (char)c; + memset(&mbs, 0, sizeof(mbs)); + nconv = mbrtowc(&wc, buf, n, &mbs); + if (nconv == n) + return (wc); + else if (nconv == 0) + return (L'\0'); + else if (nconv == (size_t)-2 || nconv == (size_t)-1) + break; + } - return (wc); + while (n-- != 0) + ungetc((unsigned char)buf[n], fp); + errno = EILSEQ; + return (WEOF); } diff --git a/lib/libc/stdio/fgetws.c b/lib/libc/stdio/fgetws.c index 9d456a1..d39b082 100644 --- a/lib/libc/stdio/fgetws.c +++ b/lib/libc/stdio/fgetws.c @@ -29,7 +29,6 @@ __FBSDID("$FreeBSD$"); #include "namespace.h" #include -#include #include #include #include "un-namespace.h" @@ -40,7 +39,7 @@ wchar_t * fgetws(wchar_t * __restrict ws, int n, FILE * __restrict fp) { wchar_t *wsp; - long r; + wint_t wc; ORIENTLOCK(fp, 1); @@ -50,18 +49,16 @@ fgetws(wchar_t * __restrict ws, int n, FILE * __restrict fp) wsp = ws; while (n-- > 1) { /* XXX Inefficient */ - if ((r = fgetrune(fp)) == _INVALID_RUNE) { - errno = EILSEQ; + if ((wc = fgetwc(fp)) == WEOF && errno == EILSEQ) return (NULL); - } - if (r == EOF) { + if (wc == WEOF) { if (wsp == ws) /* EOF/error, no characters read yet. */ return (NULL); break; } - *wsp++ = (wchar_t)r; - if (r == L'\n') + *wsp++ = (wchar_t)wc; + if (wc == L'\n') break; } *wsp++ = L'\0'; diff --git a/lib/libc/stdio/fputwc.c b/lib/libc/stdio/fputwc.c index ae19cd6..c12581c 100644 --- a/lib/libc/stdio/fputwc.c +++ b/lib/libc/stdio/fputwc.c @@ -29,8 +29,8 @@ __FBSDID("$FreeBSD$"); #include "namespace.h" #include -#include #include +#include #include #include "un-namespace.h" #include "libc_private.h" @@ -39,8 +39,19 @@ __FBSDID("$FreeBSD$"); wint_t fputwc(wchar_t wc, FILE *fp) { + char buf[MB_LEN_MAX]; + mbstate_t mbs; + size_t i, len; ORIENTLOCK(fp, 1); - return (fputrune((rune_t)wc, fp) != EOF ? (wint_t)wc : WEOF); + memset(&mbs, 0, sizeof(mbs)); + if ((len = wcrtomb(buf, wc, &mbs)) == (size_t)-1) + return (WEOF); + + for (i = 0; i < len; i++) + if (fputc((unsigned char)buf[i], fp) == EOF) + return (WEOF); + + return ((wint_t)wc); } diff --git a/lib/libc/stdio/fputws.c b/lib/libc/stdio/fputws.c index 312d02a..254b4f9 100644 --- a/lib/libc/stdio/fputws.c +++ b/lib/libc/stdio/fputws.c @@ -29,7 +29,6 @@ __FBSDID("$FreeBSD$"); #include "namespace.h" #include -#include #include #include #include "un-namespace.h" @@ -44,7 +43,7 @@ fputws(const wchar_t * __restrict ws, FILE * __restrict fp) /* XXX Inefficient */ while (*ws != '\0') - if (fputrune((rune_t)*ws++, fp) == EOF) + if (fputwc(*ws++, fp) == WEOF) return (-1); return (0); diff --git a/lib/libc/stdio/ungetwc.c b/lib/libc/stdio/ungetwc.c index 2a50986..0783fa9 100644 --- a/lib/libc/stdio/ungetwc.c +++ b/lib/libc/stdio/ungetwc.c @@ -29,8 +29,8 @@ __FBSDID("$FreeBSD$"); #include "namespace.h" #include -#include #include +#include #include #include "un-namespace.h" #include "libc_private.h" @@ -39,8 +39,21 @@ __FBSDID("$FreeBSD$"); wint_t ungetwc(wint_t wc, FILE *fp) { + char buf[MB_LEN_MAX]; + mbstate_t mbs; + size_t len; ORIENTLOCK(fp, 1); - return (fungetrune((rune_t)wc, fp) == EOF ? WEOF : wc); + if (wc == WEOF) + return (WEOF); + + memset(&mbs, 0, sizeof(mbs)); + if ((len = wcrtomb(buf, wc, &mbs)) == (size_t)-1) + return (WEOF); + while (len-- != 0) + if (ungetc((unsigned char)buf[len], fp) == EOF) + return (WEOF); + + return (wc); } -- cgit v1.1