fgetwc.c revision 132442
1101776Stjr/*- 2129583Stjr * Copyright (c) 2002-2004 Tim J. Robbins. 3101776Stjr * All rights reserved. 4101776Stjr * 5101776Stjr * Redistribution and use in source and binary forms, with or without 6101776Stjr * modification, are permitted provided that the following conditions 7101776Stjr * are met: 8101776Stjr * 1. Redistributions of source code must retain the above copyright 9101776Stjr * notice, this list of conditions and the following disclaimer. 10101776Stjr * 2. Redistributions in binary form must reproduce the above copyright 11101776Stjr * notice, this list of conditions and the following disclaimer in the 12101776Stjr * documentation and/or other materials provided with the distribution. 13101776Stjr * 14101776Stjr * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15101776Stjr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16101776Stjr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17101776Stjr * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18101776Stjr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19101776Stjr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20101776Stjr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21101776Stjr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22101776Stjr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23101776Stjr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24101776Stjr * SUCH DAMAGE. 25101776Stjr */ 26101776Stjr 27101776Stjr#include <sys/cdefs.h> 28101776Stjr__FBSDID("$FreeBSD: head/lib/libc/stdio/fgetwc.c 132442 2004-07-20 08:27:27Z tjr $"); 29101776Stjr 30101776Stjr#include "namespace.h" 31101776Stjr#include <errno.h> 32101776Stjr#include <stdio.h> 33103523Stjr#include <stdlib.h> 34101776Stjr#include <wchar.h> 35101776Stjr#include "un-namespace.h" 36101776Stjr#include "libc_private.h" 37101776Stjr#include "local.h" 38132442Stjr#include "mblocal.h" 39101776Stjr 40103676Stjr/* 41103676Stjr * MT-safe version. 42103676Stjr */ 43103676Stjrwint_t 44103676Stjrfgetwc(FILE *fp) 45103676Stjr{ 46103676Stjr wint_t r; 47103676Stjr 48103676Stjr FLOCKFILE(fp); 49103676Stjr ORIENT(fp, 1); 50103676Stjr r = __fgetwc(fp); 51103676Stjr FUNLOCKFILE(fp); 52103676Stjr 53103676Stjr return (r); 54103676Stjr} 55103676Stjr 56131880Stjr/* 57131880Stjr * Non-MT-safe version. 58131880Stjr */ 59131880Stjrwint_t 60131880Stjr__fgetwc(FILE *fp) 61103539Stjr{ 62103523Stjr wchar_t wc; 63129584Stjr size_t nconv; 64101776Stjr 65129584Stjr if (fp->_r <= 0 && __srefill(fp)) 66129584Stjr return (WEOF); 67131880Stjr if (MB_CUR_MAX == 1) { 68131880Stjr /* Fast path for single-byte encodings. */ 69131880Stjr wc = *fp->_p++; 70131880Stjr fp->_r--; 71131880Stjr return (wc); 72131880Stjr } 73129584Stjr do { 74132442Stjr nconv = __mbrtowc(&wc, fp->_p, fp->_r, &fp->_extra->mbstate); 75129584Stjr if (nconv == (size_t)-1) 76103523Stjr break; 77129584Stjr else if (nconv == (size_t)-2) 78129583Stjr continue; 79129584Stjr else if (nconv == 0) { 80129584Stjr /* 81129584Stjr * Assume that the only valid representation of 82129584Stjr * the null wide character is a single null byte. 83129584Stjr */ 84129584Stjr fp->_p++; 85129584Stjr fp->_r--; 86103523Stjr return (L'\0'); 87129584Stjr } else { 88129584Stjr fp->_p += nconv; 89129584Stjr fp->_r -= nconv; 90129583Stjr return (wc); 91129584Stjr } 92129584Stjr } while (__srefill(fp) == 0); 93129583Stjr fp->_flags |= __SERR; 94103523Stjr errno = EILSEQ; 95103523Stjr return (WEOF); 96101776Stjr} 97