X-Git-Url: https://git.saurik.com/apple/libc.git/blobdiff_plain/9385eb3d10ebe5eb398c52040ec3dbfba9b0cdcf..6465356a983ac139f81d3b7913cdb548477c346c:/stdio/FreeBSD/fgetwc.c diff --git a/stdio/FreeBSD/fgetwc.c b/stdio/FreeBSD/fgetwc.c index 0fc8f1d..ead24c3 100644 --- a/stdio/FreeBSD/fgetwc.c +++ b/stdio/FreeBSD/fgetwc.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,7 +25,9 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/fgetwc.c,v 1.6 2002/10/16 12:09:43 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/stdio/fgetwc.c,v 1.13 2008/04/17 22:17:53 jhb Exp $"); + +#include "xlocale_private.h" #include "namespace.h" #include @@ -35,75 +37,78 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/fgetwc.c,v 1.6 2002/10/16 12:09:43 tjr Ex #include "un-namespace.h" #include "libc_private.h" #include "local.h" - -static __inline wint_t __fgetwc_nbf(FILE *); +#include "mblocal.h" /* - * Non-MT-safe version. + * MT-safe version. */ wint_t -__fgetwc(FILE *fp) +fgetwc(FILE *fp) { - wint_t wc; + wint_t r; - if (MB_CUR_MAX == 1) { - /* - * Assume we're using a single-byte locale. A safer test - * might be to check _CurrentRuneLocale->encoding. - */ - wc = (wint_t)__sgetc(fp); - } else - wc = __fgetwc_nbf(fp); + FLOCKFILE(fp); + ORIENT(fp, 1); + r = __fgetwc(fp, __current_locale()); + FUNLOCKFILE(fp); - return (wc); + return (r); } -/* - * MT-safe version. - */ wint_t -fgetwc(FILE *fp) +fgetwc_l(FILE *fp, locale_t loc) { wint_t r; + NORMALIZE_LOCALE(loc); FLOCKFILE(fp); ORIENT(fp, 1); - r = __fgetwc(fp); + r = __fgetwc(fp, loc); FUNLOCKFILE(fp); return (r); } -static __inline wint_t -__fgetwc_nbf(FILE *fp) +/* + * Non-MT-safe version. + */ +wint_t +__fgetwc(FILE *fp, locale_t loc) { - char buf[MB_LEN_MAX]; - mbstate_t mbs; - size_t n, nconv; - int c; wchar_t wc; + size_t nconv; + struct __xlocale_st_runelocale *xrl = loc->__lc_ctype; + size_t (*__mbrtowc)(wchar_t * __restrict, const char * __restrict, size_t, mbstate_t * __restrict, locale_t) = xrl->__mbrtowc; - n = 0; - while (n < MB_CUR_MAX) { - if ((c = __sgetc(fp)) == EOF) { - if (n == 0) - return (WEOF); + if (fp->_r <= 0 && __srefill(fp)) + return (WEOF); + if (xrl->__mb_cur_max == 1) { + /* Fast path for single-byte encodings. */ + wc = *fp->_p++; + fp->_r--; + return (wc); + } + do { + nconv = __mbrtowc(&wc, fp->_p, fp->_r, &fp->_mbstate, loc); + if (nconv == (size_t)-1) 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) + else if (nconv == (size_t)-2) + continue; + else if (nconv == 0) { + /* + * Assume that the only valid representation of + * the null wide character is a single null byte. + */ + fp->_p++; + fp->_r--; return (L'\0'); - else if (nconv == (size_t)-1) - break; - } - - while (n-- != 0) - __ungetc((unsigned char)buf[n], fp); - errno = EILSEQ; + } else { + fp->_p += nconv; + fp->_r -= nconv; + return (wc); + } + } while (__srefill(fp) == 0); fp->_flags |= __SERR; + errno = EILSEQ; return (WEOF); }