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