mbrtowc.c revision 102050
1102050Stjr/*- 2102050Stjr * Copyright (c) 2002 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 102050 2002-08-18 06:30:10Z tjr $"); 29102050Stjr 30102050Stjr#include <errno.h> 31102050Stjr#include <rune.h> 32102050Stjr#include <stdlib.h> 33102050Stjr#include <wchar.h> 34102050Stjr 35102050Stjrsize_t 36102050Stjrmbrtowc(wchar_t *__restrict pwc, const char *__restrict s, size_t n, 37102050Stjr mbstate_t *__restrict ps __unused) 38102050Stjr{ 39102050Stjr const char *e; 40102050Stjr rune_t r; 41102050Stjr 42102050Stjr if (s == NULL) { 43102050Stjr pwc = NULL; 44102050Stjr s = ""; 45102050Stjr n = 1; 46102050Stjr } 47102050Stjr 48102050Stjr if (*s == '\0') { 49102050Stjr if (pwc != NULL) 50102050Stjr *pwc = L'\0'; 51102050Stjr return (0); 52102050Stjr } 53102050Stjr 54102050Stjr if ((r = sgetrune(s, n, &e)) == _INVALID_RUNE) { 55102050Stjr /* 56102050Stjr * The design of sgetrune() doesn't give us any way to tell 57102050Stjr * between incomplete and invalid multibyte sequences. 58102050Stjr */ 59102050Stjr 60102050Stjr if (n >= (size_t)MB_CUR_MAX) { 61102050Stjr /* 62102050Stjr * If we have been supplied with at least MB_CUR_MAX 63102050Stjr * bytes and still cannot find a valid character, the 64102050Stjr * data must be invalid. 65102050Stjr */ 66102050Stjr errno = EILSEQ; 67102050Stjr return ((size_t)-1); 68102050Stjr } 69102050Stjr 70102050Stjr /* 71102050Stjr * .. otherwise, it's an incomplete character or an invalid 72102050Stjr * character we cannot detect yet. 73102050Stjr */ 74102050Stjr return ((size_t)-2); 75102050Stjr } 76102050Stjr 77102050Stjr if (pwc != NULL) 78102050Stjr *pwc = (wchar_t)r; 79102050Stjr 80102050Stjr return ((size_t)(e - s)); 81102050Stjr} 82