strtoull.c revision 1.1
11.1Sthorpej/* $NetBSD: strtoull.c,v 1.1 2006/10/08 03:14:55 thorpej Exp $ */ 21.1Sthorpej 31.1Sthorpej/* 41.1Sthorpej * Copyright (c) 1990, 1993 51.1Sthorpej * The Regents of the University of California. All rights reserved. 61.1Sthorpej * 71.1Sthorpej * Redistribution and use in source and binary forms, with or without 81.1Sthorpej * modification, are permitted provided that the following conditions 91.1Sthorpej * are met: 101.1Sthorpej * 1. Redistributions of source code must retain the above copyright 111.1Sthorpej * notice, this list of conditions and the following disclaimer. 121.1Sthorpej * 2. Redistributions in binary form must reproduce the above copyright 131.1Sthorpej * notice, this list of conditions and the following disclaimer in the 141.1Sthorpej * documentation and/or other materials provided with the distribution. 151.1Sthorpej * 3. Neither the name of the University nor the names of its contributors 161.1Sthorpej * may be used to endorse or promote products derived from this software 171.1Sthorpej * without specific prior written permission. 181.1Sthorpej * 191.1Sthorpej * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 201.1Sthorpej * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 211.1Sthorpej * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 221.1Sthorpej * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 231.1Sthorpej * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 241.1Sthorpej * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 251.1Sthorpej * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 261.1Sthorpej * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 271.1Sthorpej * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 281.1Sthorpej * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 291.1Sthorpej * SUCH DAMAGE. 301.1Sthorpej */ 311.1Sthorpej 321.1Sthorpej#if !defined(_KERNEL) && !defined(_STANDALONE) 331.1Sthorpej#include <sys/cdefs.h> 341.1Sthorpej#if defined(LIBC_SCCS) && !defined(lint) 351.1Sthorpej#if 0 361.1Sthorpejstatic char sccsid[] = "from: @(#)strtoul.c 8.1 (Berkeley) 6/4/93"; 371.1Sthorpej#else 381.1Sthorpej__RCSID("$NetBSD: strtoull.c,v 1.1 2006/10/08 03:14:55 thorpej Exp $"); 391.1Sthorpej#endif 401.1Sthorpej#endif /* LIBC_SCCS and not lint */ 411.1Sthorpej 421.1Sthorpej#include "namespace.h" 431.1Sthorpej#include <assert.h> 441.1Sthorpej#include <ctype.h> 451.1Sthorpej#include <errno.h> 461.1Sthorpej#include <limits.h> 471.1Sthorpej#include <stdlib.h> 481.1Sthorpej 491.1Sthorpej#ifdef __weak_alias 501.1Sthorpej__weak_alias(strtoull, _strtoull) 511.1Sthorpej#endif 521.1Sthorpej 531.1Sthorpej#else /* !_KERNEL && !_STANDALONE */ 541.1Sthorpej#include <sys/param.h> 551.1Sthorpej#include <lib/libkern/libkern.h> 561.1Sthorpej#define isspace(x) ((x) == ' ' || (x) == '\t' || (x) == '\n' || (x) == '\r') 571.1Sthorpej#define isdigit(x) ((x) >= '0' && (x) <= '9') 581.1Sthorpej#define isalpha(x) (((x) >= 'a' && (x) <= 'z') || ((x) >= 'A' && (x) <= 'Z')) 591.1Sthorpej#define toupper(x) ((x) & ~0x20) 601.1Sthorpej#endif 611.1Sthorpej 621.1Sthorpej/* 631.1Sthorpej * Convert a string to an unsigned long long integer. 641.1Sthorpej * 651.1Sthorpej * Ignores `locale' stuff. Assumes that the upper and lower case 661.1Sthorpej * alphabets and digits are each contiguous. 671.1Sthorpej */ 681.1Sthorpej/* LONGLONG */ 691.1Sthorpejunsigned long long int 701.1Sthorpejstrtoull(nptr, endptr, base) 711.1Sthorpej const char *nptr; 721.1Sthorpej char **endptr; 731.1Sthorpej int base; 741.1Sthorpej{ 751.1Sthorpej const char *s; 761.1Sthorpej /* LONGLONG */ 771.1Sthorpej unsigned long long int acc, cutoff; 781.1Sthorpej int c; 791.1Sthorpej int neg, any, cutlim; 801.1Sthorpej 811.1Sthorpej _DIAGASSERT(nptr != NULL); 821.1Sthorpej /* endptr may be NULL */ 831.1Sthorpej 841.1Sthorpej /* 851.1Sthorpej * See strtol for comments as to the logic used. 861.1Sthorpej */ 871.1Sthorpej s = nptr; 881.1Sthorpej do { 891.1Sthorpej c = (unsigned char) *s++; 901.1Sthorpej } while (isspace(c)); 911.1Sthorpej if (c == '-') { 921.1Sthorpej neg = 1; 931.1Sthorpej c = *s++; 941.1Sthorpej } else { 951.1Sthorpej neg = 0; 961.1Sthorpej if (c == '+') 971.1Sthorpej c = *s++; 981.1Sthorpej } 991.1Sthorpej if ((base == 0 || base == 16) && 1001.1Sthorpej c == '0' && (*s == 'x' || *s == 'X')) { 1011.1Sthorpej c = s[1]; 1021.1Sthorpej s += 2; 1031.1Sthorpej base = 16; 1041.1Sthorpej } 1051.1Sthorpej if (base == 0) 1061.1Sthorpej base = c == '0' ? 8 : 10; 1071.1Sthorpej 1081.1Sthorpej /* LONGLONG */ 1091.1Sthorpej cutoff = ULLONG_MAX / (unsigned long long int)base; 1101.1Sthorpej /* LONGLONG */ 1111.1Sthorpej cutlim = (int)(ULLONG_MAX % (unsigned long long int)base); 1121.1Sthorpej for (acc = 0, any = 0;; c = (unsigned char) *s++) { 1131.1Sthorpej if (isdigit(c)) 1141.1Sthorpej c -= '0'; 1151.1Sthorpej else if (isalpha(c)) { 1161.1Sthorpej#if defined(_KERNEL) || defined(_STANDALONE) 1171.1Sthorpej c = toupper(c) - 'A' + 10; 1181.1Sthorpej#else 1191.1Sthorpej c -= isupper(c) ? 'A' - 10 : 'a' - 10; 1201.1Sthorpej#endif 1211.1Sthorpej } else 1221.1Sthorpej break; 1231.1Sthorpej if (c >= base) 1241.1Sthorpej break; 1251.1Sthorpej if (any < 0) 1261.1Sthorpej continue; 1271.1Sthorpej if (acc > cutoff || (acc == cutoff && c > cutlim)) { 1281.1Sthorpej#if defined(_KERNEL) || defined(_STANDALONE) 1291.1Sthorpej if (endptr) 1301.1Sthorpej *endptr = __UNCONST(nptr); 1311.1Sthorpej return (ULLONG_MAX); 1321.1Sthorpej#else 1331.1Sthorpej any = -1; 1341.1Sthorpej acc = ULLONG_MAX; 1351.1Sthorpej errno = ERANGE; 1361.1Sthorpej#endif 1371.1Sthorpej } else { 1381.1Sthorpej any = 1; 1391.1Sthorpej /* LONGLONG */ 1401.1Sthorpej acc *= (unsigned long long int)base; 1411.1Sthorpej acc += c; 1421.1Sthorpej } 1431.1Sthorpej } 1441.1Sthorpej if (neg && any > 0) 1451.1Sthorpej acc = -acc; 1461.1Sthorpej if (endptr != 0) 1471.1Sthorpej *endptr = __UNCONST(any ? s - 1 : nptr); 1481.1Sthorpej return (acc); 1491.1Sthorpej} 150