fgetwc.c revision 103676
1101776Stjr/*- 2101776Stjr * Copyright (c) 2002 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 103676 2002-09-20 13:20:41Z 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" 38101776Stjr 39103539Stjrstatic __inline wint_t __fgetwc_nbf(FILE *); 40103539Stjr 41103676Stjr/* 42103676Stjr * Non-MT-safe version. 43103676Stjr */ 44101776Stjrwint_t 45103676Stjr__fgetwc(FILE *fp) 46101776Stjr{ 47103539Stjr wint_t wc; 48103539Stjr 49103539Stjr if (MB_CUR_MAX == 1) { 50103539Stjr /* 51103539Stjr * Assume we're using a single-byte locale. A safer test 52103539Stjr * might be to check _CurrentRuneLocale->encoding. 53103539Stjr */ 54103539Stjr wc = (wint_t)__sgetc(fp); 55103539Stjr } else 56103539Stjr wc = __fgetwc_nbf(fp); 57103539Stjr 58103539Stjr return (wc); 59103539Stjr} 60103539Stjr 61103676Stjr/* 62103676Stjr * MT-safe version. 63103676Stjr */ 64103676Stjrwint_t 65103676Stjrfgetwc(FILE *fp) 66103676Stjr{ 67103676Stjr wint_t r; 68103676Stjr 69103676Stjr FLOCKFILE(fp); 70103676Stjr ORIENT(fp, 1); 71103676Stjr r = __fgetwc(fp); 72103676Stjr FUNLOCKFILE(fp); 73103676Stjr 74103676Stjr return (r); 75103676Stjr} 76103676Stjr 77103539Stjrstatic __inline wint_t 78103539Stjr__fgetwc_nbf(FILE *fp) 79103539Stjr{ 80103523Stjr char buf[MB_LEN_MAX]; 81103523Stjr mbstate_t mbs; 82103523Stjr size_t n, nconv; 83103523Stjr int c; 84103523Stjr wchar_t wc; 85101776Stjr 86103523Stjr n = 0; 87103523Stjr while (n < MB_CUR_MAX) { 88103539Stjr if ((c = __sgetc(fp)) == EOF) { 89103523Stjr if (n == 0) 90103523Stjr return (WEOF); 91103523Stjr break; 92103523Stjr } 93103523Stjr buf[n++] = (char)c; 94103523Stjr memset(&mbs, 0, sizeof(mbs)); 95103523Stjr nconv = mbrtowc(&wc, buf, n, &mbs); 96103523Stjr if (nconv == n) 97103523Stjr return (wc); 98103523Stjr else if (nconv == 0) 99103523Stjr return (L'\0'); 100103538Stjr else if (nconv == (size_t)-1) 101103523Stjr break; 102103523Stjr } 103101776Stjr 104103523Stjr while (n-- != 0) 105103676Stjr __ungetc((unsigned char)buf[n], fp); 106103523Stjr errno = EILSEQ; 107103523Stjr return (WEOF); 108101776Stjr} 109