mbrtowc.c revision 121845
1102050Stjr/*- 2121845Stjr * Copyright (c) 2002, 2003 Tim J. Robbins. 3102050Stjr * All rights reserved. 4102050Stjr * 5102050Stjr * Redistribution and use in source and binary forms, with or without 6102050Stjr * modification, are permitted provided that the following conditions 7102050Stjr * are met: 8102050Stjr * 1. Redistributions of source code must retain the above copyright 9102050Stjr * notice, this list of conditions and the following disclaimer. 10102050Stjr * 2. Redistributions in binary form must reproduce the above copyright 11102050Stjr * notice, this list of conditions and the following disclaimer in the 12102050Stjr * documentation and/or other materials provided with the distribution. 13102050Stjr * 14102050Stjr * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15102050Stjr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16102050Stjr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17102050Stjr * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18102050Stjr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19102050Stjr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20102050Stjr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21102050Stjr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22102050Stjr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23102050Stjr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24102050Stjr * SUCH DAMAGE. 25102050Stjr */ 26102050Stjr 27102050Stjr#include <sys/cdefs.h> 28102050Stjr__FBSDID("$FreeBSD: head/lib/libc/locale/mbrtowc.c 121845 2003-11-01 05:13:13Z tjr $"); 29102050Stjr 30102050Stjr#include <errno.h> 31102050Stjr#include <rune.h> 32102050Stjr#include <stdlib.h> 33102050Stjr#include <wchar.h> 34102050Stjr 35121845Stjrextern size_t (*__mbrtowc)(wchar_t * __restrict, const char * __restrict, 36121845Stjr size_t, mbstate_t * __restrict); 37121845Stjr 38102050Stjrsize_t 39121845Stjrmbrtowc(wchar_t * __restrict pwc, const char * __restrict s, 40121845Stjr size_t n, mbstate_t * __restrict ps) 41102050Stjr{ 42121845Stjr 43121845Stjr return (__mbrtowc(pwc, s, n, ps)); 44121845Stjr} 45121845Stjr 46121845Stjr/* 47121845Stjr * Emulate the ISO C mbrtowc() function in terms of the deprecated 48121845Stjr * 4.4BSD sgetrune() function. 49121845Stjr */ 50121845Stjrsize_t 51121845Stjr__emulated_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, 52121845Stjr size_t n, mbstate_t * __restrict ps __unused) 53121845Stjr{ 54102050Stjr const char *e; 55102050Stjr rune_t r; 56102050Stjr 57102050Stjr if (s == NULL) { 58102050Stjr pwc = NULL; 59102050Stjr s = ""; 60102050Stjr n = 1; 61102050Stjr } 62102050Stjr 63102050Stjr if ((r = sgetrune(s, n, &e)) == _INVALID_RUNE) { 64102050Stjr /* 65102050Stjr * The design of sgetrune() doesn't give us any way to tell 66102050Stjr * between incomplete and invalid multibyte sequences. 67102050Stjr */ 68102050Stjr 69102050Stjr if (n >= (size_t)MB_CUR_MAX) { 70102050Stjr /* 71102050Stjr * If we have been supplied with at least MB_CUR_MAX 72102050Stjr * bytes and still cannot find a valid character, the 73102050Stjr * data must be invalid. 74102050Stjr */ 75102050Stjr errno = EILSEQ; 76102050Stjr return ((size_t)-1); 77102050Stjr } 78102050Stjr 79102050Stjr /* 80102050Stjr * .. otherwise, it's an incomplete character or an invalid 81102050Stjr * character we cannot detect yet. 82102050Stjr */ 83102050Stjr return ((size_t)-2); 84102050Stjr } 85102050Stjr 86102050Stjr if (pwc != NULL) 87102050Stjr *pwc = (wchar_t)r; 88102050Stjr 89106725Stjr return (r != 0 ? (size_t)(e - s) : 0); 90102050Stjr} 91