strtoofft.c
Go to the documentation of this file.
00001 /***************************************************************************
00002  *                                  _   _ ____  _
00003  *  Project                     ___| | | |  _ \| |
00004  *                             / __| | | | |_) | |
00005  *                            | (__| |_| |  _ <| |___
00006  *                             \___|\___/|_| \_\_____|
00007  *
00008  * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
00009  *
00010  * This software is licensed as described in the file COPYING, which
00011  * you should have received as part of this distribution. The terms
00012  * are also available at https://curl.haxx.se/docs/copyright.html.
00013  *
00014  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
00015  * copies of the Software, and permit persons to whom the Software is
00016  * furnished to do so, under the terms of the COPYING file.
00017  *
00018  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
00019  * KIND, either express or implied.
00020  *
00021  ***************************************************************************/
00022 
00023 #include "curl_setup.h"
00024 
00025 #include "strtoofft.h"
00026 
00027 /*
00028  * NOTE:
00029  *
00030  * In the ISO C standard (IEEE Std 1003.1), there is a strtoimax() function we
00031  * could use in case strtoll() doesn't exist...  See
00032  * http://www.opengroup.org/onlinepubs/009695399/functions/strtoimax.html
00033  */
00034 
00035 #ifdef NEED_CURL_STRTOLL
00036 
00037 /* Range tests can be used for alphanum decoding if characters are consecutive,
00038    like in ASCII. Else an array is scanned. Determine this condition now. */
00039 
00040 #if('9' - '0') != 9 || ('Z' - 'A') != 25 || ('z' - 'a') != 25
00041 
00042 #define NO_RANGE_TEST
00043 
00044 static const char valchars[] =
00045             "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
00046 #endif
00047 
00048 static int get_char(char c, int base);
00049 
00054 curl_off_t
00055 curlx_strtoll(const char *nptr, char **endptr, int base)
00056 {
00057   char *end;
00058   int is_negative = 0;
00059   int overflow;
00060   int i;
00061   curl_off_t value = 0;
00062   curl_off_t newval;
00063 
00064   /* Skip leading whitespace. */
00065   end = (char *)nptr;
00066   while(ISSPACE(end[0])) {
00067     end++;
00068   }
00069 
00070   /* Handle the sign, if any. */
00071   if(end[0] == '-') {
00072     is_negative = 1;
00073     end++;
00074   }
00075   else if(end[0] == '+') {
00076     end++;
00077   }
00078   else if(end[0] == '\0') {
00079     /* We had nothing but perhaps some whitespace -- there was no number. */
00080     if(endptr) {
00081       *endptr = end;
00082     }
00083     return 0;
00084   }
00085 
00086   /* Handle special beginnings, if present and allowed. */
00087   if(end[0] == '0' && end[1] == 'x') {
00088     if(base == 16 || base == 0) {
00089       end += 2;
00090       base = 16;
00091     }
00092   }
00093   else if(end[0] == '0') {
00094     if(base == 8 || base == 0) {
00095       end++;
00096       base = 8;
00097     }
00098   }
00099 
00100   /* Matching strtol, if the base is 0 and it doesn't look like
00101    * the number is octal or hex, we assume it's base 10.
00102    */
00103   if(base == 0) {
00104     base = 10;
00105   }
00106 
00107   /* Loop handling digits. */
00108   value = 0;
00109   overflow = 0;
00110   for(i = get_char(end[0], base);
00111       i != -1;
00112       end++, i = get_char(end[0], base)) {
00113     newval = base * value + i;
00114     if(newval < value) {
00115       /* We've overflowed. */
00116       overflow = 1;
00117       break;
00118     }
00119     else
00120       value = newval;
00121   }
00122 
00123   if(!overflow) {
00124     if(is_negative) {
00125       /* Fix the sign. */
00126       value *= -1;
00127     }
00128   }
00129   else {
00130     if(is_negative)
00131       value = CURL_OFF_T_MIN;
00132     else
00133       value = CURL_OFF_T_MAX;
00134 
00135     SET_ERRNO(ERANGE);
00136   }
00137 
00138   if(endptr)
00139     *endptr = end;
00140 
00141   return value;
00142 }
00143 
00154 static int get_char(char c, int base)
00155 {
00156 #ifndef NO_RANGE_TEST
00157   int value = -1;
00158   if(c <= '9' && c >= '0') {
00159     value = c - '0';
00160   }
00161   else if(c <= 'Z' && c >= 'A') {
00162     value = c - 'A' + 10;
00163   }
00164   else if(c <= 'z' && c >= 'a') {
00165     value = c - 'a' + 10;
00166   }
00167 #else
00168   const char *cp;
00169   int value;
00170 
00171   cp = memchr(valchars, c, 10 + 26 + 26);
00172 
00173   if(!cp)
00174     return -1;
00175 
00176   value = cp - valchars;
00177 
00178   if(value >= 10 + 26)
00179     value -= 26;                /* Lowercase. */
00180 #endif
00181 
00182   if(value >= base) {
00183     value = -1;
00184   }
00185 
00186   return value;
00187 }
00188 #endif  /* Only present if we need strtoll, but don't have it. */


rc_visard_driver
Author(s): Heiko Hirschmueller , Christian Emmerich , Felix Ruess
autogenerated on Thu Jun 6 2019 20:43:06