1542bd65fSTim J. Robbins /*- 2542bd65fSTim J. Robbins * Copyright (c) 2002, 2003 Tim J. Robbins 3542bd65fSTim J. Robbins * All rights reserved. 4542bd65fSTim J. Robbins * 5542bd65fSTim J. Robbins * Redistribution and use in source and binary forms, with or without 6542bd65fSTim J. Robbins * modification, are permitted provided that the following conditions 7542bd65fSTim J. Robbins * are met: 8542bd65fSTim J. Robbins * 1. Redistributions of source code must retain the above copyright 9542bd65fSTim J. Robbins * notice, this list of conditions and the following disclaimer. 10542bd65fSTim J. Robbins * 2. Redistributions in binary form must reproduce the above copyright 11542bd65fSTim J. Robbins * notice, this list of conditions and the following disclaimer in the 12542bd65fSTim J. Robbins * documentation and/or other materials provided with the distribution. 13542bd65fSTim J. Robbins * 14542bd65fSTim J. Robbins * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15542bd65fSTim J. Robbins * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16542bd65fSTim J. Robbins * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17542bd65fSTim J. Robbins * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18542bd65fSTim J. Robbins * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19542bd65fSTim J. Robbins * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20542bd65fSTim J. Robbins * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21542bd65fSTim J. Robbins * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22542bd65fSTim J. Robbins * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23542bd65fSTim J. Robbins * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24542bd65fSTim J. Robbins * SUCH DAMAGE. 25542bd65fSTim J. Robbins */ 26542bd65fSTim J. Robbins 27542bd65fSTim J. Robbins #include <sys/cdefs.h> 28542bd65fSTim J. Robbins __FBSDID("$FreeBSD$"); 29542bd65fSTim J. Robbins 30542bd65fSTim J. Robbins #include <stdlib.h> 31542bd65fSTim J. Robbins #include <wchar.h> 32542bd65fSTim J. Robbins #include <wctype.h> 33542bd65fSTim J. Robbins 34542bd65fSTim J. Robbins /* 35542bd65fSTim J. Robbins * See wcstod() for comments as to the logic used. 36542bd65fSTim J. Robbins */ 37542bd65fSTim J. Robbins long double 38542bd65fSTim J. Robbins wcstold(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr) 39542bd65fSTim J. Robbins { 40542bd65fSTim J. Robbins static const mbstate_t initial; 41542bd65fSTim J. Robbins mbstate_t state; 42542bd65fSTim J. Robbins long double val; 43542bd65fSTim J. Robbins char *buf, *end, *p; 44542bd65fSTim J. Robbins const wchar_t *wcp; 45542bd65fSTim J. Robbins size_t clen, len; 46542bd65fSTim J. Robbins 47542bd65fSTim J. Robbins while (iswspace(*nptr)) 48542bd65fSTim J. Robbins nptr++; 49542bd65fSTim J. Robbins 50542bd65fSTim J. Robbins state = initial; 51542bd65fSTim J. Robbins wcp = nptr; 52542bd65fSTim J. Robbins if ((len = wcsrtombs(NULL, &wcp, 0, &state)) == (size_t)-1) { 53542bd65fSTim J. Robbins if (endptr != NULL) 54542bd65fSTim J. Robbins *endptr = (wchar_t *)nptr; 55542bd65fSTim J. Robbins return (0.0); 56542bd65fSTim J. Robbins } 57542bd65fSTim J. Robbins if ((buf = malloc(len + 1)) == NULL) 58542bd65fSTim J. Robbins return (0.0); 59542bd65fSTim J. Robbins state = initial; 60542bd65fSTim J. Robbins wcsrtombs(buf, &wcp, len + 1, &state); 61542bd65fSTim J. Robbins 62542bd65fSTim J. Robbins val = strtold(buf, &end); 63542bd65fSTim J. Robbins 64542bd65fSTim J. Robbins if (endptr != NULL) { 65542bd65fSTim J. Robbins #if 1 /* Fast, assume 1:1 WC:MBS mapping. */ 66542bd65fSTim J. Robbins *endptr = (wchar_t *)nptr + (end - buf); 67542bd65fSTim J. Robbins (void)clen; 68542bd65fSTim J. Robbins (void)p; 69542bd65fSTim J. Robbins #else /* Slow, conservative approach. */ 70542bd65fSTim J. Robbins state = initial; 71542bd65fSTim J. Robbins *endptr = (wchar_t *)nptr; 72542bd65fSTim J. Robbins p = buf; 73542bd65fSTim J. Robbins while (p < end && 74542bd65fSTim J. Robbins (clen = mbrlen(p, end - p, &state)) > 0) { 75542bd65fSTim J. Robbins p += clen; 76542bd65fSTim J. Robbins (*endptr)++; 77542bd65fSTim J. Robbins } 78542bd65fSTim J. Robbins #endif 79542bd65fSTim J. Robbins } 80542bd65fSTim J. Robbins 81542bd65fSTim J. Robbins free(buf); 82542bd65fSTim J. Robbins 83542bd65fSTim J. Robbins return (val); 84542bd65fSTim J. Robbins } 85