summaryrefslogtreecommitdiff
path: root/src/lib/libc/stdlib/strtoull.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/lib/libc/stdlib/strtoull.c (renamed from src/lib/libc/stdlib/strtouq.c)68
1 files changed, 39 insertions, 29 deletions
diff --git a/src/lib/libc/stdlib/strtouq.c b/src/lib/libc/stdlib/strtoull.c
index cc647d8d28..a0ac9b381f 100644
--- a/src/lib/libc/stdlib/strtouq.c
+++ b/src/lib/libc/stdlib/strtoull.c
@@ -10,11 +10,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 13 * 3. Neither the name of the University nor the names of its contributors
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software 14 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 15 * without specific prior written permission.
20 * 16 *
@@ -32,40 +28,39 @@
32 */ 28 */
33 29
34#if defined(LIBC_SCCS) && !defined(lint) 30#if defined(LIBC_SCCS) && !defined(lint)
35static char sccsid[] = "@(#)strtouq.c 5.1 (Berkeley) 6/26/92"; 31static const char rcsid[] = "$OpenBSD: strtoull.c,v 1.2 2003/06/02 20:18:38 millert Exp $";
36#endif /* LIBC_SCCS and not lint */ 32#endif /* LIBC_SCCS and not lint */
37 33
38#include <sys/types.h> 34#include <sys/types.h>
39 35
40#include <limits.h>
41#include <errno.h>
42#include <ctype.h> 36#include <ctype.h>
37#include <errno.h>
38#include <limits.h>
43#include <stdlib.h> 39#include <stdlib.h>
44 40
45/* 41/*
46 * Convert a string to an unsigned quad integer. 42 * Convert a string to an unsigned long long.
47 * 43 *
48 * Ignores `locale' stuff. Assumes that the upper and lower case 44 * Ignores `locale' stuff. Assumes that the upper and lower case
49 * alphabets and digits are each contiguous. 45 * alphabets and digits are each contiguous.
50 */ 46 */
51u_quad_t 47unsigned long long
52strtouq(nptr, endptr, base) 48strtoull(nptr, endptr, base)
53 const char *nptr; 49 const char *nptr;
54 char **endptr; 50 char **endptr;
55 register int base; 51 int base;
56{ 52{
57 register const char *s = nptr; 53 const char *s;
58 register u_quad_t acc; 54 unsigned long long acc, cutoff;
59 register int c; 55 int c;
60 register u_quad_t qbase, cutoff; 56 int neg, any, cutlim;
61 register int neg, any, cutlim;
62 57
63 /* 58 /*
64 * See strtoq for comments as to the logic used. 59 * See strtoq for comments as to the logic used.
65 */ 60 */
66 s = nptr; 61 s = nptr;
67 do { 62 do {
68 c = *s++; 63 c = (unsigned char) *s++;
69 } while (isspace(c)); 64 } while (isspace(c));
70 if (c == '-') { 65 if (c == '-') {
71 neg = 1; 66 neg = 1;
@@ -83,10 +78,10 @@ strtouq(nptr, endptr, base)
83 } 78 }
84 if (base == 0) 79 if (base == 0)
85 base = c == '0' ? 8 : 10; 80 base = c == '0' ? 8 : 10;
86 qbase = (unsigned)base; 81
87 cutoff = (u_quad_t)UQUAD_MAX / qbase; 82 cutoff = ULLONG_MAX / (unsigned long long)base;
88 cutlim = (u_quad_t)UQUAD_MAX % qbase; 83 cutlim = ULLONG_MAX % (unsigned long long)base;
89 for (acc = 0, any = 0;; c = *s++) { 84 for (acc = 0, any = 0;; c = (unsigned char) *s++) {
90 if (isdigit(c)) 85 if (isdigit(c))
91 c -= '0'; 86 c -= '0';
92 else if (isalpha(c)) 87 else if (isalpha(c))
@@ -95,20 +90,35 @@ strtouq(nptr, endptr, base)
95 break; 90 break;
96 if (c >= base) 91 if (c >= base)
97 break; 92 break;
98 if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim) 93 if (any < 0)
94 continue;
95 if (acc > cutoff || (acc == cutoff && c > cutlim)) {
99 any = -1; 96 any = -1;
100 else { 97 acc = ULLONG_MAX;
98 errno = ERANGE;
99 } else {
101 any = 1; 100 any = 1;
102 acc *= qbase; 101 acc *= (unsigned long long)base;
103 acc += c; 102 acc += c;
104 } 103 }
105 } 104 }
106 if (any < 0) { 105 if (neg && any > 0)
107 acc = UQUAD_MAX;
108 errno = ERANGE;
109 } else if (neg)
110 acc = -acc; 106 acc = -acc;
111 if (endptr != 0) 107 if (endptr != 0)
112 *endptr = (char *) (any ? s - 1 : nptr); 108 *endptr = (char *) (any ? s - 1 : nptr);
113 return (acc); 109 return (acc);
114} 110}
111
112#ifdef __weak_alias
113__weak_alias(strtouq, strtoull);
114#else
115u_quad_t
116strtouq(nptr, endptr, base)
117 const char *nptr;
118 char **endptr;
119 int base;
120{
121
122 return ((u_quad_t)strtoull(nptr, endptr, base);
123}
124#endif