13d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes/* $OpenBSD: _wcstoul.h,v 1.1 2005/07/01 08:59:27 espie Exp $ */ 23d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes/* $NetBSD: _wcstoul.h,v 1.2 2003/08/07 16:43:03 agc Exp $ */ 33d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes 43d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes/* 53d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes * Copyright (c) 1990, 1993 63d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes * The Regents of the University of California. All rights reserved. 73d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes * 83d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes * Redistribution and use in source and binary forms, with or without 93d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes * modification, are permitted provided that the following conditions 103d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes * are met: 113d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes * 1. Redistributions of source code must retain the above copyright 123d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes * notice, this list of conditions and the following disclaimer. 133d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes * 2. Redistributions in binary form must reproduce the above copyright 143d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes * notice, this list of conditions and the following disclaimer in the 153d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes * documentation and/or other materials provided with the distribution. 163d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes * 3. Neither the name of the University nor the names of its contributors 173d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes * may be used to endorse or promote products derived from this software 183d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes * without specific prior written permission. 193d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes * 203d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 213d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 223d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 233d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 243d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 253d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 263d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 273d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 283d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 293d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 303d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes * SUCH DAMAGE. 313d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes * 323d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes * Original version ID: 333d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes * @(#)strtoul.c 8.1 (Berkeley) 6/4/93 343d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes * Citrus: xpg4dl/FreeBSD/lib/libc/locale/wcstoul.c,v 1.2 2001/09/21 16:11:41 yamt Exp 353d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes * NetBSD: wcstoul.c,v 1.1 2001/09/27 16:30:37 yamt Exp 363d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes */ 373d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes 383d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes/* 393d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes * function template for wcstoul, wcstoull and wcstoumax. 403d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes * 413d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes * parameters: 423d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes * FUNCNAME : function name 433d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes * uint_type : return type 443d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes * MAX_VALUE : upper limit of the return type 453d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes */ 463d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes 473d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughesuint_type 483d7a0d9b08ecab054b2dff8332507644de3690b0Elliott HughesFUNCNAME(const wchar_t *nptr, wchar_t **endptr, int base) 493d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes{ 503d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes const wchar_t *s; 513d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes uint_type acc, cutoff; 523d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes wint_t wc; 533d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes int i; 543d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes int neg, any, cutlim; 553d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes 563d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes if (base && (base < 2 || base > 36)) { 573d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes errno = EINVAL; 583d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes return 0; 593d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes } 603d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes 613d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes /* 623d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes * Skip white space and pick up leading +/- sign if any. 633d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes * If base is 0, allow 0x for hex and 0 for octal, else 643d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes * assume decimal; if base is already 16, allow 0x. 653d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes */ 663d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes s = nptr; 673d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes do { 683d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes wc = (wchar_t) *s++; 693d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes } while (iswspace(wc)); 703d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes if (wc == L'-') { 713d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes neg = 1; 723d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes wc = *s++; 733d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes } else { 743d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes neg = 0; 753d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes if (wc == L'+') 763d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes wc = *s++; 773d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes } 783d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes if ((base == 0 || base == 16) && 793d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes wc == L'0' && (*s == L'x' || *s == L'X')) { 803d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes wc = s[1]; 813d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes s += 2; 823d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes base = 16; 833d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes } 843d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes if (base == 0) 853d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes base = wc == L'0' ? 8 : 10; 863d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes 873d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes /* 883d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes * See strtoul for comments as to the logic used. 893d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes */ 903d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes cutoff = MAX_VALUE / (uint_type)base; 913d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes cutlim = (int)(MAX_VALUE % (uint_type)base); 923d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes for (acc = 0, any = 0;; wc = (wchar_t) *s++) { 933d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes i = wctoint(wc); 943d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes if (i == (wint_t)-1) 953d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes break; 963d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes if (i >= base) 973d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes break; 983d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes if (any < 0) 993d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes continue; 1003d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes if (acc > cutoff || (acc == cutoff && i > cutlim)) { 1013d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes any = -1; 1023d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes acc = MAX_VALUE; 1033d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes errno = ERANGE; 1043d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes } else { 1053d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes any = 1; 1063d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes acc *= (uint_type)base; 1073d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes acc += i; 1083d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes } 1093d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes } 1103d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes if (neg && any > 0) 1113d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes acc = -acc; 1123d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes if (endptr != 0) 1133d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes /* LINTED interface specification */ 1143d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes *endptr = (wchar_t *)(any ? s - 1 : nptr); 1153d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes return (acc); 1163d7a0d9b08ecab054b2dff8332507644de3690b0Elliott Hughes} 117