X-Git-Url: https://git.saurik.com/apple/libc.git/blobdiff_plain/9385eb3d10ebe5eb398c52040ec3dbfba9b0cdcf..34e8f8296870d0e8695f90e1a54240a589d41312:/stdio/FreeBSD/fgetws.c diff --git a/stdio/FreeBSD/fgetws.c b/stdio/FreeBSD/fgetws.c index d818f62..be180c9 100644 --- a/stdio/FreeBSD/fgetws.c +++ b/stdio/FreeBSD/fgetws.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2002 Tim J. Robbins. + * Copyright (c) 2002-2004 Tim J. Robbins. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,21 +25,25 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/fgetws.c,v 1.4 2002/09/20 13:25:40 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/fgetws.c,v 1.6 2004/10/03 15:48:32 stefanf Exp $"); #include "namespace.h" #include #include +#include #include #include "un-namespace.h" #include "libc_private.h" #include "local.h" +#include "mblocal.h" wchar_t * fgetws(wchar_t * __restrict ws, int n, FILE * __restrict fp) { wchar_t *wsp; - wint_t wc; + size_t nconv; + const char *src; + unsigned char *nl; FLOCKFILE(fp); ORIENT(fp, 1); @@ -49,21 +53,42 @@ fgetws(wchar_t * __restrict ws, int n, FILE * __restrict fp) goto error; } + if (fp->_r <= 0 && __srefill(fp)) + /* EOF */ + goto error; wsp = ws; - while (n-- > 1) { - /* XXX Inefficient */ - if ((wc = __fgetwc(fp)) == WEOF && errno == EILSEQ) + do { + src = fp->_p; + nl = memchr(fp->_p, '\n', fp->_r); + nconv = __mbsnrtowcs(wsp, &src, + nl != NULL ? (nl - fp->_p + 1) : fp->_r, + n - 1, &fp->_extra->mbstate); + if (nconv == (size_t)-1) + /* Conversion error */ goto error; - if (wc == WEOF) { - if (wsp == ws) - /* EOF/error, no characters read yet. */ - goto error; - break; + if (src == NULL) { + /* + * We hit a null byte. Increment the character count, + * since mbsnrtowcs()'s return value doesn't include + * the terminating null, then resume conversion + * after the null. + */ + nconv++; + src = memchr(fp->_p, '\0', fp->_r); + src++; } - *wsp++ = (wchar_t)wc; - if (wc == L'\n') - break; - } + fp->_r -= (unsigned char *)src - fp->_p; + fp->_p = (unsigned char *)src; + n -= nconv; + wsp += nconv; + } while (wsp[-1] != L'\n' && n > 1 && (fp->_r > 0 || + __srefill(fp) == 0)); + if (wsp == ws) + /* EOF */ + goto error; + if (!__mbsinit(&fp->_extra->mbstate)) + /* Incomplete character */ + goto error; *wsp++ = L'\0'; FUNLOCKFILE(fp);