ENH: typo
[cmake.git] / Utilities / cmcurl / strtoofft.c
blob968fe70ce20e55f5baa9220414fc4b356f59129d
1 /***************************************************************************
2 * _ _ ____ _
3 * Project ___| | | | _ \| |
4 * / __| | | | |_) | |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
10 * This software is licensed as described in the file COPYING, which
11 * you should have received as part of this distribution. The terms
12 * are also available at http://curl.haxx.se/docs/copyright.html.
14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15 * copies of the Software, and permit persons to whom the Software is
16 * furnished to do so, under the terms of the COPYING file.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 * $Id: strtoofft.c,v 1.2 2007-03-15 19:22:13 andy Exp $
22 ***************************************************************************/
24 #include "setup.h"
25 #include "strtoofft.h"
28 * NOTE:
30 * In the ISO C standard (IEEE Std 1003.1), there is a strtoimax() function we
31 * could use in case strtoll() doesn't exist... See
32 * http://www.opengroup.org/onlinepubs/009695399/functions/strtoimax.html
35 #ifdef NEED_CURL_STRTOLL
36 #include <stdlib.h>
37 #include <ctype.h>
38 #include <errno.h>
40 static int get_char(char c, int base);
42 /**
43 * Emulated version of the strtoll function. This extracts a long long
44 * value from the given input string and returns it.
46 curl_off_t
47 curlx_strtoll(const char *nptr, char **endptr, int base)
49 char *end;
50 int is_negative = 0;
51 int overflow;
52 int i;
53 curl_off_t value = 0;
54 curl_off_t newval;
56 /* Skip leading whitespace. */
57 end = (char *)nptr;
58 while (ISSPACE(end[0])) {
59 end++;
62 /* Handle the sign, if any. */
63 if (end[0] == '-') {
64 is_negative = 1;
65 end++;
67 else if (end[0] == '+') {
68 end++;
70 else if (end[0] == '\0') {
71 /* We had nothing but perhaps some whitespace -- there was no number. */
72 if (endptr) {
73 *endptr = end;
75 return 0;
78 /* Handle special beginnings, if present and allowed. */
79 if (end[0] == '0' && end[1] == 'x') {
80 if (base == 16 || base == 0) {
81 end += 2;
82 base = 16;
85 else if (end[0] == '0') {
86 if (base == 8 || base == 0) {
87 end++;
88 base = 8;
92 /* Matching strtol, if the base is 0 and it doesn't look like
93 * the number is octal or hex, we assume it's base 10.
95 if (base == 0) {
96 base = 10;
99 /* Loop handling digits. */
100 value = 0;
101 overflow = 0;
102 for (i = get_char(end[0], base);
103 i != -1;
104 end++, i = get_char(end[0], base)) {
105 newval = base * value + i;
106 if (newval < value) {
107 /* We've overflowed. */
108 overflow = 1;
109 break;
111 else
112 value = newval;
115 if (!overflow) {
116 if (is_negative) {
117 /* Fix the sign. */
118 value *= -1;
121 else {
122 if (is_negative)
123 value = CURL_LLONG_MIN;
124 else
125 value = CURL_LLONG_MAX;
127 errno = ERANGE;
130 if (endptr)
131 *endptr = end;
133 return value;
137 * Returns the value of c in the given base, or -1 if c cannot
138 * be interpreted properly in that base (i.e., is out of range,
139 * is a null, etc.).
141 * @param c the character to interpret according to base
142 * @param base the base in which to interpret c
144 * @return the value of c in base, or -1 if c isn't in range
146 static int get_char(char c, int base)
148 int value = -1;
149 if (c <= '9' && c >= '0') {
150 value = c - '0';
152 else if (c <= 'Z' && c >= 'A') {
153 value = c - 'A' + 10;
155 else if (c <= 'z' && c >= 'a') {
156 value = c - 'a' + 10;
159 if (value >= base) {
160 value = -1;
163 return value;
165 #endif /* Only present if we need strtoll, but don't have it. */