1 /*
2 * Copyright © 2005-2020 Rich Felker
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <errno.h>
27
28 /* r = place to store result
29 * f = function call to test (or any expression)
30 * x = expected result
31 * m = message to print on failure (with formats for r & x)
32 **/
33
34 #pragma GCC diagnostic ignored "-Wpragmas"
35 #pragma GCC diagnostic ignored "-Wunknown-warning-option"
36 #pragma GCC diagnostic ignored "-Wformat-extra-args"
37 #pragma GCC diagnostic ignored "-Wformat"
38
39 #define TEST(r, f, x, m) ( \
40 msg = #f, ((r) = (f)) == (x) || \
41 (printf(__FILE__ ":%d: %s failed (" m ")\n", __LINE__, #f, r, x), err++, 0) )
42
43 #define TEST2(r, f, x, m) ( \
44 ((r) = (f)) == (x) || \
45 (printf(__FILE__ ":%d: %s failed (" m ")\n", __LINE__, msg, r, x), err++, 0) )
46
test_strtol(void)47 int test_strtol(void)
48 {
49 int i;
50 long l;
51 unsigned long ul;
52 long long ll;
53 unsigned long long ull;
54 char *msg="";
55 int err=0;
56 char *s, *c;
57
58 (void) ll;
59 (void) ull;
60 TEST(l, atol("2147483647"), 2147483647L, "max 32bit signed %ld != %ld");
61
62 TEST(l, strtol("2147483647", 0, 0), 2147483647L, "max 32bit signed %ld != %ld");
63 TEST(ul, strtoul("4294967295", 0, 0), 4294967295UL, "max 32bit unsigned %lu != %lu");
64
65 if (sizeof(long) == 4) {
66 errno = 0;
67 TEST(l, strtol(s="2147483648", &c, 0), 2147483647L, "uncaught overflow %ld != %ld");
68 TEST2(i, c-s, 10, "wrong final position %d != %d");
69 TEST2(i, errno, ERANGE, "missing errno %d != %d");
70 errno = 0;
71 TEST(l, strtol(s="-2147483649", &c, 0), -2147483647L-1, "uncaught overflow %ld != %ld");
72 TEST2(i, c-s, 11, "wrong final position %d != %d");
73 TEST2(i, errno, ERANGE, "missing errno %d != %d");
74 errno = 0;
75 TEST(ul, strtoul(s="4294967296", &c, 0), 4294967295UL, "uncaught overflow %lu != %lu");
76 TEST2(i, c-s, 10, "wrong final position %d != %d");
77 TEST2(i, errno, ERANGE, "missing errno %d != %d");
78 errno = 0;
79 TEST(ul, strtoul(s="-1", &c, 0), -1UL, "rejected negative %lu != %lu");
80 TEST2(i, c-s, 2, "wrong final position %d != %d");
81 TEST2(i, errno, 0, "spurious errno %d != %d");
82 errno = 0;
83 TEST(ul, strtoul(s="-2", &c, 0), -2UL, "rejected negative %lu != %lu");
84 TEST2(i, c-s, 2, "wrong final position %d != %d");
85 TEST2(i, errno, 0, "spurious errno %d != %d");
86 errno = 0;
87 TEST(ul, strtoul(s="-2147483648", &c, 0), -2147483648UL, "rejected negative %lu != %lu");
88 TEST2(i, c-s, 11, "wrong final position %d != %d");
89 TEST2(i, errno, 0, "spurious errno %d != %d");
90 errno = 0;
91 TEST(ul, strtoul(s="-2147483649", &c, 0), -2147483649UL, "rejected negative %lu != %lu");
92 TEST2(i, c-s, 11, "wrong final position %d != %d");
93 TEST2(i, errno, 0, "spurious errno %d != %d");
94 } else {
95 errno = 0;
96 TEST(l, strtol(s="9223372036854775808", &c, 0), 9223372036854775807L, "uncaught overflow %ld != %ld");
97 TEST2(i, c-s, 19, "wrong final position %d != %d");
98 TEST2(i, errno, ERANGE, "missing errno %d != %d");
99 errno = 0;
100 TEST(l, strtol(s="-9223372036854775809", &c, 0), -9223372036854775807L-1, "uncaught overflow %ld != %ld");
101 TEST2(i, c-s, 20, "wrong final position %d != %d");
102 TEST2(i, errno, ERANGE, "missing errno %d != %d");
103 errno = 0;
104 TEST(ul, strtoul(s="18446744073709551616", &c, 0), 18446744073709551615UL, "uncaught overflow %lu != %lu");
105 TEST2(i, c-s, 20, "wrong final position %d != %d");
106 TEST2(i, errno, ERANGE, "missing errno %d != %d");
107 errno = 0;
108 TEST(ul, strtoul(s="-1", &c, 0), -1UL, "rejected negative %lu != %lu");
109 TEST2(i, c-s, 2, "wrong final position %d != %d");
110 TEST2(i, errno, 0, "spurious errno %d != %d");
111 errno = 0;
112 TEST(ul, strtoul(s="-2", &c, 0), -2UL, "rejected negative %lu != %lu");
113 TEST2(i, c-s, 2, "wrong final position %d != %d");
114 TEST2(i, errno, 0, "spurious errno %d != %d");
115 errno = 0;
116 TEST(ul, strtoul(s="-9223372036854775808", &c, 0), -9223372036854775808UL, "rejected negative %lu != %lu");
117 TEST2(i, c-s, 20, "wrong final position %d != %d");
118 TEST2(i, errno, 0, "spurious errno %d != %d");
119 errno = 0;
120 TEST(ul, strtoul(s="-9223372036854775809", &c, 0), -9223372036854775809UL, "rejected negative %lu != %lu");
121 TEST2(i, c-s, 20, "wrong final position %d != %d");
122 TEST2(i, errno, 0, "spurious errno %d != %d");
123 }
124
125 TEST(l, strtol("z", 0, 36), 35, "%ld != %ld");
126 TEST(l, strtol("00010010001101000101011001111000", 0, 2), 0x12345678, "%ld != %ld");
127 TEST(l, strtol(s="0F5F", &c, 16), 0x0f5f, "%ld != %ld");
128
129 TEST(l, strtol(s="0xz", &c, 16), 0, "%ld != %ld");
130 TEST2(i, c-s, 1, "wrong final position %ld != %ld");
131
132 TEST(l, strtol(s="0x1234", &c, 16), 0x1234, "%ld != %ld");
133 TEST2(i, c-s, 6, "wrong final position %ld != %ld");
134
135 char delim_buf[6] = "09af:";
136
137 for (int j = 0; j < 256; j++) {
138 delim_buf[4] = j;
139 if (('0' <= j && j <= '9') ||
140 ('A' <= j && j <= 'F') ||
141 ('a' <= j && j <= 'f'))
142 {
143 long k;
144 if ('0' <= j && j <= '9')
145 k = j - '0';
146 else if ('A' <= j && j <= 'Z')
147 k = j - 'A' + 10;
148 else if ('a' <= j && j <= 'z')
149 k = j - 'a' + 10;
150 else
151 k = 0xffffffff;
152 TEST(l, strtol(s=delim_buf, &c, 16), 0x09af0 | k, "%ld != %ld");
153 TEST2(i, c-s, 5, "wrong final position %ld != %ld");
154 } else {
155 TEST(l, strtol(s=delim_buf, &c, 16), 0x09af, "%ld != %ld");
156 TEST2(i, c-s, 4, "wrong final position %ld != %ld");
157 }
158 }
159
160 errno = 0;
161 c = NULL;
162 TEST(l, strtol(s="123", &c, 37), 0, "%ld != %ld");
163 TEST2(i, c-s, 0, "wrong final position %d != %d");
164 TEST2(i, errno, EINVAL, "%d != %d");
165
166 TEST(l, strtol(s=" 15437", &c, 8), 015437, "%ld != %ld");
167 TEST2(i, c-s, 7, "wrong final position %d != %d");
168
169 TEST(l, strtol(s=" 1", &c, 0), 1, "%ld != %ld");
170 TEST2(i, c-s, 3, "wrong final position %d != %d");
171
172 return err;
173 }
174
175 #define TEST_NAME strtol
176 #include "testcase.h"
177