os/persistentdata/persistentstorage/sqlite3api/TEST/TCL/tcldistribution/compat/strtoull.c
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/persistentdata/persistentstorage/sqlite3api/TEST/TCL/tcldistribution/compat/strtoull.c Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,261 @@
1.4 +/*
1.5 + * strtoull.c --
1.6 + *
1.7 + * Source code for the "strtoull" library procedure.
1.8 + *
1.9 + * Copyright (c) 1988 The Regents of the University of California.
1.10 + * Copyright (c) 1994 Sun Microsystems, Inc.
1.11 + *
1.12 + * See the file "license.terms" for information on usage and redistribution
1.13 + * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
1.14 + *
1.15 + * RCS: @(#) $Id: strtoull.c,v 1.5 2002/02/24 02:53:25 dgp Exp $
1.16 + */
1.17 +
1.18 +#include "tcl.h"
1.19 +#include "tclPort.h"
1.20 +#include <ctype.h>
1.21 +
1.22 +/*
1.23 + * The table below is used to convert from ASCII digits to a
1.24 + * numerical equivalent. It maps from '0' through 'z' to integers
1.25 + * (100 for non-digit characters).
1.26 + */
1.27 +
1.28 +static char cvtIn[] = {
1.29 + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* '0' - '9' */
1.30 + 100, 100, 100, 100, 100, 100, 100, /* punctuation */
1.31 + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, /* 'A' - 'Z' */
1.32 + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
1.33 + 30, 31, 32, 33, 34, 35,
1.34 + 100, 100, 100, 100, 100, 100, /* punctuation */
1.35 + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, /* 'a' - 'z' */
1.36 + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
1.37 + 30, 31, 32, 33, 34, 35};
1.38 +
1.39 +
1.40 +/*
1.41 + *----------------------------------------------------------------------
1.42 + *
1.43 + * strtoull --
1.44 + *
1.45 + * Convert an ASCII string into an integer.
1.46 + *
1.47 + * Results:
1.48 + * The return value is the integer equivalent of string. If endPtr
1.49 + * is non-NULL, then *endPtr is filled in with the character
1.50 + * after the last one that was part of the integer. If string
1.51 + * doesn't contain a valid integer value, then zero is returned
1.52 + * and *endPtr is set to string.
1.53 + *
1.54 + * Side effects:
1.55 + * None.
1.56 + *
1.57 + *----------------------------------------------------------------------
1.58 + */
1.59 +
1.60 +#if TCL_WIDE_INT_IS_LONG
1.61 +unsigned long long
1.62 +#else
1.63 +Tcl_WideUInt
1.64 +#endif
1.65 +strtoull(string, endPtr, base)
1.66 + CONST char *string; /* String of ASCII digits, possibly
1.67 + * preceded by white space. For bases
1.68 + * greater than 10, either lower- or
1.69 + * upper-case digits may be used.
1.70 + */
1.71 + char **endPtr; /* Where to store address of terminating
1.72 + * character, or NULL. */
1.73 + int base; /* Base for conversion. Must be less
1.74 + * than 37. If 0, then the base is chosen
1.75 + * from the leading characters of string:
1.76 + * "0x" means hex, "0" means octal, anything
1.77 + * else means decimal.
1.78 + */
1.79 +{
1.80 + register CONST char *p;
1.81 + register Tcl_WideUInt result = 0;
1.82 + register unsigned digit;
1.83 + register Tcl_WideUInt shifted;
1.84 + int anyDigits = 0, negative = 0;
1.85 +
1.86 + /*
1.87 + * Skip any leading blanks.
1.88 + */
1.89 +
1.90 + p = string;
1.91 + while (isspace(UCHAR(*p))) { /* INTL: locale-dependent */
1.92 + p += 1;
1.93 + }
1.94 +
1.95 + /*
1.96 + * Check for a sign.
1.97 + */
1.98 +
1.99 + if (*p == '-') {
1.100 + p += 1;
1.101 + negative = 1;
1.102 + } else {
1.103 + if (*p == '+') {
1.104 + p += 1;
1.105 + }
1.106 + }
1.107 +
1.108 + /*
1.109 + * If no base was provided, pick one from the leading characters
1.110 + * of the string.
1.111 + */
1.112 +
1.113 + if (base == 0) {
1.114 + if (*p == '0') {
1.115 + p += 1;
1.116 + if (*p == 'x' || *p == 'X') {
1.117 + p += 1;
1.118 + base = 16;
1.119 + } else {
1.120 +
1.121 + /*
1.122 + * Must set anyDigits here, otherwise "0" produces a
1.123 + * "no digits" error.
1.124 + */
1.125 +
1.126 + anyDigits = 1;
1.127 + base = 8;
1.128 + }
1.129 + } else {
1.130 + base = 10;
1.131 + }
1.132 + } else if (base == 16) {
1.133 +
1.134 + /*
1.135 + * Skip a leading "0x" from hex numbers.
1.136 + */
1.137 +
1.138 + if ((p[0] == '0') && (p[1] == 'x' || *p == 'X')) {
1.139 + p += 2;
1.140 + }
1.141 + }
1.142 +
1.143 + /*
1.144 + * Sorry this code is so messy, but speed seems important. Do
1.145 + * different things for base 8, 10, 16, and other.
1.146 + */
1.147 +
1.148 + if (base == 8) {
1.149 + for ( ; ; p += 1) {
1.150 + digit = *p - '0';
1.151 + if (digit > 7) {
1.152 + break;
1.153 + }
1.154 + shifted = result << 3;
1.155 + if ((shifted >> 3) != result) {
1.156 + goto overflow;
1.157 + }
1.158 + result = shifted + digit;
1.159 + if ( result < shifted ) {
1.160 + goto overflow;
1.161 + }
1.162 + anyDigits = 1;
1.163 + }
1.164 + } else if (base == 10) {
1.165 + for ( ; ; p += 1) {
1.166 + digit = *p - '0';
1.167 + if (digit > 9) {
1.168 + break;
1.169 + }
1.170 + shifted = 10 * result;
1.171 + if ((shifted / 10) != result) {
1.172 + goto overflow;
1.173 + }
1.174 + result = shifted + digit;
1.175 + if ( result < shifted ) {
1.176 + goto overflow;
1.177 + }
1.178 + anyDigits = 1;
1.179 + }
1.180 + } else if (base == 16) {
1.181 + for ( ; ; p += 1) {
1.182 + digit = *p - '0';
1.183 + if (digit > ('z' - '0')) {
1.184 + break;
1.185 + }
1.186 + digit = cvtIn[digit];
1.187 + if (digit > 15) {
1.188 + break;
1.189 + }
1.190 + shifted = result << 4;
1.191 + if ((shifted >> 4) != result) {
1.192 + goto overflow;
1.193 + }
1.194 + result = shifted + digit;
1.195 + if ( result < shifted ) {
1.196 + goto overflow;
1.197 + }
1.198 + anyDigits = 1;
1.199 + }
1.200 + } else if ( base >= 2 && base <= 36 ) {
1.201 + for ( ; ; p += 1) {
1.202 + digit = *p - '0';
1.203 + if (digit > ('z' - '0')) {
1.204 + break;
1.205 + }
1.206 + digit = cvtIn[digit];
1.207 + if (digit >= (unsigned) base) {
1.208 + break;
1.209 + }
1.210 + shifted = result * base;
1.211 + if ((shifted/base) != result) {
1.212 + goto overflow;
1.213 + }
1.214 + result = shifted + digit;
1.215 + if ( result < shifted ) {
1.216 + goto overflow;
1.217 + }
1.218 + anyDigits = 1;
1.219 + }
1.220 + }
1.221 +
1.222 + /*
1.223 + * Negate if we found a '-' earlier.
1.224 + */
1.225 +
1.226 + if (negative) {
1.227 + result = (Tcl_WideUInt)(-((Tcl_WideInt)result));
1.228 + }
1.229 +
1.230 + /*
1.231 + * See if there were any digits at all.
1.232 + */
1.233 +
1.234 + if (!anyDigits) {
1.235 + p = string;
1.236 + }
1.237 +
1.238 + if (endPtr != 0) {
1.239 + *endPtr = (char *) p;
1.240 + }
1.241 +
1.242 + return result;
1.243 +
1.244 + /*
1.245 + * On overflow generate the right output
1.246 + */
1.247 +
1.248 + overflow:
1.249 + errno = ERANGE;
1.250 + if (endPtr != 0) {
1.251 + for ( ; ; p += 1) {
1.252 + digit = *p - '0';
1.253 + if (digit > ('z' - '0')) {
1.254 + break;
1.255 + }
1.256 + digit = cvtIn[digit];
1.257 + if (digit >= (unsigned) base) {
1.258 + break;
1.259 + }
1.260 + }
1.261 + *endPtr = (char *) p;
1.262 + }
1.263 + return (Tcl_WideUInt)Tcl_LongAsWide(-1);
1.264 +}