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.
This commit is contained in:
Tim J. Robbins 2002-09-18 05:58:11 +00:00
parent 11142c6f54
commit 24990dfad0
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=103523
5 changed files with 61 additions and 25 deletions

View File

@ -29,8 +29,8 @@ __FBSDID("$FreeBSD$");
#include "namespace.h"
#include <errno.h>
#include <rune.h>
#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>
#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);
}

View File

@ -29,7 +29,6 @@ __FBSDID("$FreeBSD$");
#include "namespace.h"
#include <errno.h>
#include <rune.h>
#include <stdio.h>
#include <wchar.h>
#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';

View File

@ -29,8 +29,8 @@ __FBSDID("$FreeBSD$");
#include "namespace.h"
#include <errno.h>
#include <rune.h>
#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>
#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);
}

View File

@ -29,7 +29,6 @@ __FBSDID("$FreeBSD$");
#include "namespace.h"
#include <errno.h>
#include <rune.h>
#include <stdio.h>
#include <wchar.h>
#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);

View File

@ -29,8 +29,8 @@ __FBSDID("$FreeBSD$");
#include "namespace.h"
#include <errno.h>
#include <rune.h>
#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>
#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);
}