strtoull.c revision 87023
1198090Srdivacky/*- 2198090Srdivacky * Copyright (c) 1992, 1993 3198090Srdivacky * The Regents of the University of California. All rights reserved. 4198090Srdivacky * 5198090Srdivacky * Redistribution and use in source and binary forms, with or without 6198090Srdivacky * modification, are permitted provided that the following conditions 7198090Srdivacky * are met: 8198090Srdivacky * 1. Redistributions of source code must retain the above copyright 9198090Srdivacky * notice, this list of conditions and the following disclaimer. 10198090Srdivacky * 2. Redistributions in binary form must reproduce the above copyright 11198090Srdivacky * notice, this list of conditions and the following disclaimer in the 12198090Srdivacky * documentation and/or other materials provided with the distribution. 13198090Srdivacky * 3. All advertising materials mentioning features or use of this software 14198090Srdivacky * must display the following acknowledgement: 15198090Srdivacky * This product includes software developed by the University of 16198090Srdivacky * California, Berkeley and its contributors. 17198090Srdivacky * 4. Neither the name of the University nor the names of its contributors 18198090Srdivacky * may be used to endorse or promote products derived from this software 19198090Srdivacky * without specific prior written permission. 20198090Srdivacky * 21198090Srdivacky * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22198090Srdivacky * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23198090Srdivacky * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24198090Srdivacky * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25198090Srdivacky * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26198090Srdivacky * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27198090Srdivacky * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28198090Srdivacky * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29198090Srdivacky * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30198090Srdivacky * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31198090Srdivacky * SUCH DAMAGE. 32198090Srdivacky * 33198090Srdivacky * $FreeBSD: head/lib/libc/stdlib/strtoull.c 87023 2001-11-28 02:35:35Z fenner $ 34198090Srdivacky */ 35198090Srdivacky 36198090Srdivacky#if defined(LIBC_SCCS) && !defined(lint) 37198090Srdivackystatic char sccsid[] = "@(#)strtouq.c 8.1 (Berkeley) 6/4/93"; 38198090Srdivacky#endif /* LIBC_SCCS and not lint */ 39198090Srdivacky 40198090Srdivacky#include <limits.h> 41198090Srdivacky#include <errno.h> 42198090Srdivacky#include <ctype.h> 43198090Srdivacky#include <stdlib.h> 44198090Srdivacky 45198090Srdivacky/* 46198090Srdivacky * Convert a string to an unsigned long long integer. 47198090Srdivacky * 48198090Srdivacky * Assumes that the upper and lower case 49198090Srdivacky * alphabets and digits are each contiguous. 50198090Srdivacky */ 51198090Srdivackyunsigned long long 52198090Srdivackystrtoull(nptr, endptr, base) 53198090Srdivacky const char *nptr; 54198090Srdivacky char **endptr; 55198090Srdivacky int base; 56198090Srdivacky{ 57198090Srdivacky const char *s; 58198090Srdivacky unsigned long long acc; 59198090Srdivacky unsigned char c; 60198090Srdivacky unsigned long long cutoff; 61198090Srdivacky int neg, any, cutlim; 62198090Srdivacky 63198090Srdivacky /* 64198090Srdivacky * See strtoq for comments as to the logic used. 65198090Srdivacky */ 66198090Srdivacky s = nptr; 67198090Srdivacky do { 68198090Srdivacky c = *s++; 69198090Srdivacky } while (isspace(c)); 70198090Srdivacky if (c == '-') { 71198090Srdivacky neg = 1; 72198090Srdivacky c = *s++; 73198090Srdivacky } else { 74198090Srdivacky neg = 0; 75198090Srdivacky if (c == '+') 76198090Srdivacky c = *s++; 77198090Srdivacky } 78198090Srdivacky if ((base == 0 || base == 16) && 79198090Srdivacky c == '0' && (*s == 'x' || *s == 'X')) { 80198090Srdivacky c = s[1]; 81198090Srdivacky s += 2; 82198090Srdivacky base = 16; 83198090Srdivacky } 84198090Srdivacky if (base == 0) 85198090Srdivacky base = c == '0' ? 8 : 10; 86198090Srdivacky acc = any = 0; 87198090Srdivacky if (base < 2 || base > 36) 88198090Srdivacky goto noconv; 89198090Srdivacky 90198090Srdivacky cutoff = ULLONG_MAX / base; 91198090Srdivacky cutlim = ULLONG_MAX % base; 92198090Srdivacky for ( ; ; c = *s++) { 93198090Srdivacky if (isxdigit(c)) 94198090Srdivacky c = digittoint(c); 95198090Srdivacky else if (isascii(c) && isalpha(c)) 96198090Srdivacky c -= isupper(c) ? 'A' - 10 : 'a' - 10; 97198090Srdivacky else 98198090Srdivacky break; 99198090Srdivacky if (c >= base) 100198090Srdivacky break; 101198090Srdivacky if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) 102198090Srdivacky any = -1; 103198090Srdivacky else { 104198090Srdivacky any = 1; 105198090Srdivacky acc *= base; 106198090Srdivacky acc += c; 107198090Srdivacky } 108198090Srdivacky } 109198090Srdivacky if (any < 0) { 110198090Srdivacky acc = ULLONG_MAX; 111198090Srdivacky errno = ERANGE; 112198090Srdivacky } else if (!any) { 113198090Srdivackynoconv: 114198090Srdivacky errno = EINVAL; 115198090Srdivacky } else if (neg) 116198090Srdivacky acc = -acc; 117198090Srdivacky if (endptr != NULL) 118198090Srdivacky *endptr = (char *)(any ? s - 1 : nptr); 119198090Srdivacky return (acc); 120198090Srdivacky} 121198090Srdivacky