strtoll.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. /*-
  2. * Copyright (c) 2014 The Regents of the University of California.
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. * 3. [rescinded 22 July 1999]
  14. * 4. Neither the name of the University nor the names of its contributors
  15. * may be used to endorse or promote products derived from this software
  16. * without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  19. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  20. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  21. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  22. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  23. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  24. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  25. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  26. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  27. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  28. * SUCH DAMAGE.
  29. */
  30. /*
  31. @deftypefn Supplemental {long long int} strtoll (const char *@var{string}, @
  32. char **@var{endptr}, int @var{base})
  33. @deftypefnx Supplemental {unsigned long long int} strtoul (@
  34. const char *@var{string}, char **@var{endptr}, int @var{base})
  35. The @code{strtoll} function converts the string in @var{string} to a
  36. long long integer value according to the given @var{base}, which must be
  37. between 2 and 36 inclusive, or be the special value 0. If @var{base}
  38. is 0, @code{strtoll} will look for the prefixes @code{0} and @code{0x}
  39. to indicate bases 8 and 16, respectively, else default to base 10.
  40. When the base is 16 (either explicitly or implicitly), a prefix of
  41. @code{0x} is allowed. The handling of @var{endptr} is as that of
  42. @code{strtod} above. The @code{strtoull} function is the same, except
  43. that the converted value is unsigned.
  44. @end deftypefn
  45. */
  46. #ifdef HAVE_CONFIG_H
  47. #include "config.h"
  48. #endif
  49. #ifdef HAVE_LIMITS_H
  50. #include <limits.h>
  51. #endif
  52. #ifdef HAVE_SYS_PARAM_H
  53. #include <sys/param.h>
  54. #endif
  55. #include <errno.h>
  56. #ifdef NEED_DECLARATION_ERRNO
  57. extern int errno;
  58. #endif
  59. #include "safe-ctype.h"
  60. #ifdef HAVE_LONG_LONG
  61. __extension__
  62. typedef unsigned long long ullong_type;
  63. __extension__
  64. typedef long long llong_type;
  65. /* FIXME: It'd be nice to configure around these, but the include files are too
  66. painful. These macros should at least be more portable than hardwired hex
  67. constants. */
  68. #ifndef ULLONG_MAX
  69. #define ULLONG_MAX (~(ullong_type)0) /* 0xFFFFFFFFFFFFFFFF */
  70. #endif
  71. #ifndef LLONG_MAX
  72. #define LLONG_MAX ((llong_type)(ULLONG_MAX >> 1)) /* 0x7FFFFFFFFFFFFFFF */
  73. #endif
  74. #ifndef LLONG_MIN
  75. #define LLONG_MIN (~LLONG_MAX) /* 0x8000000000000000 */
  76. #endif
  77. /*
  78. * Convert a string to a long long integer.
  79. *
  80. * Ignores `locale' stuff. Assumes that the upper and lower case
  81. * alphabets and digits are each contiguous.
  82. */
  83. llong_type
  84. strtoll(const char *nptr, char **endptr, register int base)
  85. {
  86. register const char *s = nptr;
  87. register ullong_type acc;
  88. register int c;
  89. register ullong_type cutoff;
  90. register int neg = 0, any, cutlim;
  91. /*
  92. * Skip white space and pick up leading +/- sign if any.
  93. * If base is 0, allow 0x for hex and 0 for octal, else
  94. * assume decimal; if base is already 16, allow 0x.
  95. */
  96. do {
  97. c = *s++;
  98. } while (ISSPACE(c));
  99. if (c == '-') {
  100. neg = 1;
  101. c = *s++;
  102. } else if (c == '+')
  103. c = *s++;
  104. if ((base == 0 || base == 16) &&
  105. c == '0' && (*s == 'x' || *s == 'X')) {
  106. c = s[1];
  107. s += 2;
  108. base = 16;
  109. }
  110. if (base == 0)
  111. base = c == '0' ? 8 : 10;
  112. /*
  113. * Compute the cutoff value between legal numbers and illegal
  114. * numbers. That is the largest legal value, divided by the
  115. * base. An input number that is greater than this value, if
  116. * followed by a legal input character, is too big. One that
  117. * is equal to this value may be valid or not; the limit
  118. * between valid and invalid numbers is then based on the last
  119. * digit. For instance, if the range for longs is
  120. * [-2147483648..2147483647] and the input base is 10,
  121. * cutoff will be set to 214748364 and cutlim to either
  122. * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
  123. * a value > 214748364, or equal but the next digit is > 7 (or 8),
  124. * the number is too big, and we will return a range error.
  125. *
  126. * Set any if any `digits' consumed; make it negative to indicate
  127. * overflow.
  128. */
  129. cutoff = neg ? -(ullong_type)LLONG_MIN : LLONG_MAX;
  130. cutlim = cutoff % (ullong_type)base;
  131. cutoff /= (ullong_type)base;
  132. for (acc = 0, any = 0;; c = *s++) {
  133. if (ISDIGIT(c))
  134. c -= '0';
  135. else if (ISALPHA(c))
  136. c -= ISUPPER(c) ? 'A' - 10 : 'a' - 10;
  137. else
  138. break;
  139. if (c >= base)
  140. break;
  141. if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
  142. any = -1;
  143. else {
  144. any = 1;
  145. acc *= base;
  146. acc += c;
  147. }
  148. }
  149. if (any < 0) {
  150. acc = neg ? LLONG_MIN : LLONG_MAX;
  151. errno = ERANGE;
  152. } else if (neg)
  153. acc = -acc;
  154. if (endptr != 0)
  155. *endptr = (char *) (any ? s - 1 : nptr);
  156. return (acc);
  157. }
  158. #endif /* ifdef HAVE_LONG_LONG */