15e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann/*- 25e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann * Copyright (c) 1992, 1993 35e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann * The Regents of the University of California. All rights reserved. 45e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann * 55e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann * Redistribution and use in source and binary forms, with or without 65e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann * modification, are permitted provided that the following conditions 75e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann * are met: 85e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann * 1. Redistributions of source code must retain the above copyright 95e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann * notice, this list of conditions and the following disclaimer. 105e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann * 2. Redistributions in binary form must reproduce the above copyright 115e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann * notice, this list of conditions and the following disclaimer in the 125e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann * documentation and/or other materials provided with the distribution. 135e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann * 4. Neither the name of the University nor the names of its contributors 145e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann * may be used to endorse or promote products derived from this software 155e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann * without specific prior written permission. 165e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann * 175e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 185e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 195e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 205e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 215e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 225e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 235e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 245e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 255e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 265e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 275e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann * SUCH DAMAGE. 285e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann */ 295e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann 305e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann 315e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann#include <limits.h> 325e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann#ifdef HAVE_ERRNO_H 335e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann#include <errno.h> 345e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann#endif 355e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann#include <stdlib.h> 365e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann#ifdef DBUS_WINCE 375e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann#include <windows.h> 385e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann#endif 395e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann 405e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann#ifndef isspace 415e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann#define isspace(c) ((c) == ' ' || (c) == '\t' || (c) == '\r' || (c) == '\n') 425e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann#endif 435e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann 445e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann/* Minimum and maximum values a `signed long long int' can hold. */ 455e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann#ifndef LLONG_MAX 465e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann# define LLONG_MAX 9223372036854775807LL 475e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann#endif 485e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann 495e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann#ifndef LLONG_MIN 505e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann# define LLONG_MIN (-LLONG_MAX - 1LL) 515e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann#endif 525e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann/* Maximum value an `unsigned long long int' can hold. (Minimum is 0.) */ 535e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann#ifndef ULLONG_MAX 545e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann# define ULLONG_MAX 18446744073709551615ULL 555e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann#endif 565e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann 575e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann/* 585e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann * Convert a string to an unsigned long long integer. 595e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann * 605e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann * Assumes that the upper and lower case 615e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann * alphabets and digits are each contiguous. 625e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann */ 635e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmannunsigned long long strtoull (const char *, char **, int); 645e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann 655e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmannunsigned long long 665e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmannstrtoull(const char * nptr, char ** endptr, int base) 675e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann{ 685e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann const char *s; 695e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann unsigned long long acc; 705e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann char c; 715e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann unsigned long long cutoff; 725e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann int neg, any, cutlim; 735e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann 745e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann /* 755e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann * See strtoq for comments as to the logic used. 765e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann */ 775e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann s = nptr; 785e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann do { 795e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann c = *s++; 805e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann } while (isspace((unsigned char)c)); 815e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann if (c == '-') { 825e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann neg = 1; 835e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann c = *s++; 845e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann } else { 855e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann neg = 0; 865e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann if (c == '+') 875e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann c = *s++; 885e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann } 895e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann if ((base == 0 || base == 16) && 905e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann c == '0' && (*s == 'x' || *s == 'X') && 915e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann ((s[1] >= '0' && s[1] <= '9') || 925e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann (s[1] >= 'A' && s[1] <= 'F') || 935e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann (s[1] >= 'a' && s[1] <= 'f'))) { 945e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann c = s[1]; 955e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann s += 2; 965e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann base = 16; 975e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann } 985e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann if (base == 0) 995e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann base = c == '0' ? 8 : 10; 1005e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann acc = any = 0; 1015e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann if (base < 2 || base > 36) 1025e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann goto noconv; 1035e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann 1045e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann cutoff = ULLONG_MAX / base; 1055e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann cutlim = ULLONG_MAX % base; 1065e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann for ( ; ; c = *s++) { 1075e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann if (c >= '0' && c <= '9') 1085e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann c -= '0'; 1095e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann else if (c >= 'A' && c <= 'Z') 1105e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann c -= 'A' - 10; 1115e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann else if (c >= 'a' && c <= 'z') 1125e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann c -= 'a' - 10; 1135e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann else 1145e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann break; 1155e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann if (c >= base) 1165e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann break; 1175e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) 1185e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann any = -1; 1195e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann else { 1205e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann any = 1; 1215e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann acc *= base; 1225e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann acc += c; 1235e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann } 1245e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann } 1255e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann if (any < 0) { 1265e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann acc = ULLONG_MAX; 1275e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann#ifdef DBUS_WINCE 1285e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann SetLastError (ERROR_ARITHMETIC_OVERFLOW); 1295e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann#else 1305e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann errno = ERANGE; 1315e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann#endif 1325e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann } else if (!any) { 1335e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmannnoconv: 1345e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann#ifdef DBUS_WINCE 1355e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann SetLastError (ERROR_INVALID_PARAMETER); 1365e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann#else 1375e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann errno = EINVAL; 1385e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann#endif 1395e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann } else if (neg) 1405e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann acc = -acc; 1415e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann if (endptr != NULL) 1425e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann *endptr = (char *)(any ? s - 1 : nptr); 1435e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann return (acc); 1445e4ef80e098c950fa394092060eb311babbe7035Marcus Brinkmann} 145