]>
Commit | Line | Data |
---|---|---|
28f540f4 RM |
1 | /* My bet is this was written by Chris Torek. |
2 | I reformatted and ansidecl-ized it, and tweaked it a little. */ | |
3 | ||
28f540f4 RM |
4 | #include <ctype.h> |
5 | #include <stdio.h> | |
6 | #include <errno.h> | |
7 | #include <stdlib.h> | |
8 | #include <strings.h> | |
9 | ||
10 | struct ltest | |
11 | { | |
2c6fe0bd | 12 | const char *str; /* Convert this. */ |
28f540f4 RM |
13 | unsigned long int expect; /* To get this. */ |
14 | int base; /* Use this base. */ | |
15 | char left; /* With this left over. */ | |
16 | int err; /* And this in errno. */ | |
17 | }; | |
2c6fe0bd | 18 | static const struct ltest tests[] = |
28f540f4 | 19 | { |
b20e47cb | 20 | #if ~0UL == 0xffffffff |
28f540f4 RM |
21 | /* First, signed numbers. */ |
22 | { " -17", -17, 0, 0, 0 }, | |
23 | { " +0x123fg", 0x123f, 0, 'g', 0 }, | |
24 | { "2147483647", 2147483647, 0, 0, 0 }, | |
25 | { "2147483648", 2147483647, 0, 0, ERANGE }, | |
26 | { "214748364888", 2147483647, 0, 0, ERANGE }, | |
27 | { "2147483650", 2147483647, 0, 0, ERANGE }, | |
28 | { "-2147483649", -2147483648, 0, 0, ERANGE }, | |
29 | { "-2147483648", -2147483648, 0, 0, 0 }, | |
30 | { "0123", 0123, 0, 0, 0 }, | |
31 | { "0x1122334455z", 2147483647, 16, 'z', ERANGE }, | |
32 | { "0x0xc", 0, 0, 'x', 0 }, | |
33 | { "yz!", 34*36+35, 36, '!', 0 }, | |
34 | { NULL, 0, 0, 0, 0 }, | |
35 | ||
36 | /* Then unsigned. */ | |
37 | { " 0", 0, 0, 0, 0 }, | |
38 | { "0xffffffffg", 0xffffffff, 0, 'g', 0 }, | |
39 | { "0xf1f2f3f4f5", 0xffffffff, 0, 0, ERANGE }, | |
2c6fe0bd UD |
40 | { "-0x123456789", 0, 0, 0, EINVAL }, |
41 | { "-0xfedcba98", 0, 0, 0, EINVAL }, | |
28f540f4 | 42 | { NULL, 0, 0, 0, 0 }, |
b20e47cb RM |
43 | #else |
44 | /* assume 64 bit long... */ | |
45 | ||
46 | /* First, signed numbers. */ | |
47 | { " -17", -17, 0, 0, 0 }, | |
48 | { " +0x123fg", 0x123f, 0, 'g', 0 }, | |
49 | { "2147483647", 2147483647, 0, 0, 0 }, | |
50 | { "9223372036854775807", 9223372036854775807, 0, 0, 0 }, | |
51 | { "9223372036854775808", 9223372036854775807, 0, 0, ERANGE }, | |
52 | { "922337203685477580777", 9223372036854775807, 0, 0, ERANGE }, | |
53 | { "9223372036854775810", 9223372036854775807, 0, 0, ERANGE }, | |
54 | { "-2147483648", -2147483648, 0, 0, 0 }, | |
55 | { "-9223372036854775808", -9223372036854775808, 0, 0, 0 }, | |
56 | { "-9223372036854775809", -9223372036854775808, 0, 0, ERANGE }, | |
57 | { "0123", 0123, 0, 0, 0 }, | |
58 | { "0x112233445566778899z", 9223372036854775807, 16, 'z', ERANGE }, | |
59 | { "0x0xc", 0, 0, 'x', 0 }, | |
60 | { "yz!", 34*36+35, 36, '!', 0 }, | |
61 | { NULL, 0, 0, 0, 0 }, | |
62 | ||
63 | /* Then unsigned. */ | |
64 | { " 0", 0, 0, 0, 0 }, | |
65 | { "0xffffffffg", 0xffffffff, 0, 'g', 0 }, | |
66 | { "0xffffffffffffffffg", 0xffffffffffffffff, 0, 'g', 0 }, | |
67 | { "0xf1f2f3f4f5f6f7f8f9", 0xffffffffffffffff, 0, 0, ERANGE }, | |
f8b87ef0 | 68 | { "-0x123456789abcdef01", 0, 0, 0, EINVAL }, |
2c6fe0bd | 69 | { "-0xfedcba987654321", 0, 0, 0, EINVAL }, |
b20e47cb RM |
70 | { NULL, 0, 0, 0, 0 }, |
71 | #endif | |
28f540f4 RM |
72 | }; |
73 | ||
2c6fe0bd | 74 | static void expand __P ((char *dst, int c)); |
28f540f4 RM |
75 | |
76 | int | |
84384f5b | 77 | main (int argc, char ** argv) |
28f540f4 | 78 | { |
2c6fe0bd | 79 | register const struct ltest *lt; |
28f540f4 RM |
80 | char *ep; |
81 | int status = 0; | |
82 | ||
83 | for (lt = tests; lt->str != NULL; ++lt) | |
84 | { | |
85 | register long int l; | |
86 | ||
87 | errno = 0; | |
88 | l = strtol(lt->str, &ep, lt->base); | |
89 | printf("strtol(\"%s\", , %d) test %u", | |
90 | lt->str, lt->base, (unsigned int) (lt - tests)); | |
91 | if (l == (long int) lt->expect && *ep == lt->left && errno == lt->err) | |
92 | puts("\tOK"); | |
93 | else | |
94 | { | |
95 | puts("\tBAD"); | |
96 | if (l != (long int) lt->expect) | |
97 | printf(" returns %ld, expected %ld\n", | |
98 | l, (long int) lt->expect); | |
99 | if (lt->left != *ep) | |
100 | { | |
101 | char exp1[5], exp2[5]; | |
102 | expand(exp1, *ep); | |
103 | expand(exp2, lt->left); | |
104 | printf(" leaves '%s', expected '%s'\n", exp1, exp2); | |
105 | } | |
106 | if (errno != lt->err) | |
107 | printf(" errno %d (%s) instead of %d (%s)\n", | |
108 | errno, strerror(errno), lt->err, strerror(lt->err)); | |
109 | status = 1; | |
110 | } | |
111 | } | |
112 | ||
113 | for (++lt; lt->str != NULL; lt++) | |
114 | { | |
115 | register unsigned long int ul; | |
116 | ||
117 | errno = 0; | |
118 | ul = strtoul(lt->str, &ep, lt->base); | |
119 | printf("strtoul(\"%s\", , %d) test %u", | |
120 | lt->str, lt->base, (unsigned int) (lt - tests)); | |
121 | if (ul == lt->expect && *ep == lt->left && errno == lt->err) | |
122 | puts("\tOK"); | |
123 | else | |
124 | { | |
125 | puts("\tBAD"); | |
126 | if (ul != lt->expect) | |
127 | printf(" returns %lu, expected %lu\n", | |
128 | ul, lt->expect); | |
129 | if (lt->left != *ep) | |
130 | { | |
131 | char exp1[5], exp2[5]; | |
132 | expand(exp1, *ep); | |
133 | expand(exp2, lt->left); | |
134 | printf(" leaves '%s', expected '%s'\n", exp1, exp2); | |
135 | } | |
136 | if (errno != lt->err) | |
137 | printf(" errno %d (%s) instead of %d (%s)\n", | |
138 | errno, strerror(errno), lt->err, strerror(lt->err)); | |
139 | status = 1; | |
140 | } | |
141 | } | |
142 | ||
143 | exit(status ? EXIT_FAILURE : EXIT_SUCCESS); | |
144 | } | |
145 | ||
146 | static void | |
2c6fe0bd UD |
147 | expand (dst, c) |
148 | char *dst; | |
149 | int c; | |
28f540f4 RM |
150 | { |
151 | if (isprint(c)) | |
152 | { | |
153 | dst[0] = c; | |
154 | dst[1] = '\0'; | |
155 | } | |
156 | else | |
157 | (void) sprintf(dst, "%#.3o", (unsigned int) c); | |
158 | } |