| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: t_strtod.c,v 1.28 2012/03/18 07:00:51 jruoho Exp $ */ | | 1 | /* $NetBSD: t_strtod.c,v 1.29 2012/04/04 10:52:59 joerg Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2011 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 2011 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to The NetBSD Foundation | | 7 | * This code is derived from software contributed to The NetBSD Foundation |
8 | * by Jukka Ruohonen. | | 8 | * by Jukka Ruohonen. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
| @@ -22,27 +22,27 @@ | | | @@ -22,27 +22,27 @@ |
22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | | 22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
23 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | | 23 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | | 24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | 25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | 26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | 27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
29 | * POSSIBILITY OF SUCH DAMAGE. | | 29 | * POSSIBILITY OF SUCH DAMAGE. |
30 | */ | | 30 | */ |
31 | | | 31 | |
32 | /* Public domain, Otto Moerbeek <otto@drijf.net>, 2006. */ | | 32 | /* Public domain, Otto Moerbeek <otto@drijf.net>, 2006. */ |
33 | | | 33 | |
34 | #include <sys/cdefs.h> | | 34 | #include <sys/cdefs.h> |
35 | __RCSID("$NetBSD: t_strtod.c,v 1.28 2012/03/18 07:00:51 jruoho Exp $"); | | 35 | __RCSID("$NetBSD: t_strtod.c,v 1.29 2012/04/04 10:52:59 joerg Exp $"); |
36 | | | 36 | |
37 | #include <errno.h> | | 37 | #include <errno.h> |
38 | #include <math.h> | | 38 | #include <math.h> |
39 | #include <stdio.h> | | 39 | #include <stdio.h> |
40 | #include <stdlib.h> | | 40 | #include <stdlib.h> |
41 | #include <string.h> | | 41 | #include <string.h> |
42 | | | 42 | |
43 | #include <atf-c.h> | | 43 | #include <atf-c.h> |
44 | #include <atf-c/config.h> | | 44 | #include <atf-c/config.h> |
45 | | | 45 | |
46 | #if defined(__i386__) || defined(__amd64__) || defined(__sparc__) | | 46 | #if defined(__i386__) || defined(__amd64__) || defined(__sparc__) |
47 | #include <fenv.h> | | 47 | #include <fenv.h> |
48 | #endif | | 48 | #endif |
| @@ -82,159 +82,159 @@ ATF_TC_HEAD(strtod_hex, tc) | | | @@ -82,159 +82,159 @@ ATF_TC_HEAD(strtod_hex, tc) |
82 | atf_tc_set_md_var(tc, "descr", "A strtod(3) with hexadecimals"); | | 82 | atf_tc_set_md_var(tc, "descr", "A strtod(3) with hexadecimals"); |
83 | } | | 83 | } |
84 | | | 84 | |
85 | #ifdef __vax__ | | 85 | #ifdef __vax__ |
86 | #define SMALL_NUM 1.0e-38 | | 86 | #define SMALL_NUM 1.0e-38 |
87 | #else | | 87 | #else |
88 | #define SMALL_NUM 1.0e-40 | | 88 | #define SMALL_NUM 1.0e-40 |
89 | #endif | | 89 | #endif |
90 | | | 90 | |
91 | ATF_TC_BODY(strtod_hex, tc) | | 91 | ATF_TC_BODY(strtod_hex, tc) |
92 | { | | 92 | { |
93 | const char *str; | | 93 | const char *str; |
94 | char *end; | | 94 | char *end; |
95 | double d; | | 95 | volatile double d; |
96 | | | 96 | |
97 | str = "-0x0"; | | 97 | str = "-0x0"; |
98 | d = strtod(str, &end); /* -0.0 */ | | 98 | d = strtod(str, &end); /* -0.0 */ |
99 | | | 99 | |
100 | ATF_REQUIRE(end == str + 4); | | 100 | ATF_REQUIRE(end == str + 4); |
101 | ATF_REQUIRE(signbit(d) != 0); | | 101 | ATF_REQUIRE(signbit(d) != 0); |
102 | ATF_REQUIRE(fabs(d) < SMALL_NUM); | | 102 | ATF_REQUIRE(fabs(d) < SMALL_NUM); |
103 | | | 103 | |
104 | str = "-0x"; | | 104 | str = "-0x"; |
105 | d = strtod(str, &end); /* -0.0 */ | | 105 | d = strtod(str, &end); /* -0.0 */ |
106 | | | 106 | |
107 | ATF_REQUIRE(end == str + 2); | | 107 | ATF_REQUIRE(end == str + 2); |
108 | ATF_REQUIRE(signbit(d) != 0); | | 108 | ATF_REQUIRE(signbit(d) != 0); |
109 | ATF_REQUIRE(fabs(d) < SMALL_NUM); | | 109 | ATF_REQUIRE(fabs(d) < SMALL_NUM); |
110 | } | | 110 | } |
111 | | | 111 | |
112 | ATF_TC(strtod_inf); | | 112 | ATF_TC(strtod_inf); |
113 | ATF_TC_HEAD(strtod_inf, tc) | | 113 | ATF_TC_HEAD(strtod_inf, tc) |
114 | { | | 114 | { |
115 | atf_tc_set_md_var(tc, "descr", "A strtod(3) with INF (PR lib/33262)"); | | 115 | atf_tc_set_md_var(tc, "descr", "A strtod(3) with INF (PR lib/33262)"); |
116 | } | | 116 | } |
117 | | | 117 | |
118 | ATF_TC_BODY(strtod_inf, tc) | | 118 | ATF_TC_BODY(strtod_inf, tc) |
119 | { | | 119 | { |
120 | #ifndef __vax__ | | 120 | #ifndef __vax__ |
121 | for (size_t i = 0; i < __arraycount(inf_strings); i++) { | | 121 | for (size_t i = 0; i < __arraycount(inf_strings); i++) { |
122 | double d = strtod(inf_strings[i], NULL); | | 122 | volatile double d = strtod(inf_strings[i], NULL); |
123 | ATF_REQUIRE(isinf(d) != 0); | | 123 | ATF_REQUIRE(isinf(d) != 0); |
124 | } | | 124 | } |
125 | #else | | 125 | #else |
126 | atf_tc_skip("vax not supported"); | | 126 | atf_tc_skip("vax not supported"); |
127 | #endif | | 127 | #endif |
128 | } | | 128 | } |
129 | | | 129 | |
130 | ATF_TC(strtof_inf); | | 130 | ATF_TC(strtof_inf); |
131 | ATF_TC_HEAD(strtof_inf, tc) | | 131 | ATF_TC_HEAD(strtof_inf, tc) |
132 | { | | 132 | { |
133 | atf_tc_set_md_var(tc, "descr", "A strtof(3) with INF (PR lib/33262)"); | | 133 | atf_tc_set_md_var(tc, "descr", "A strtof(3) with INF (PR lib/33262)"); |
134 | } | | 134 | } |
135 | | | 135 | |
136 | ATF_TC_BODY(strtof_inf, tc) | | 136 | ATF_TC_BODY(strtof_inf, tc) |
137 | { | | 137 | { |
138 | #ifndef __vax__ | | 138 | #ifndef __vax__ |
139 | for (size_t i = 0; i < __arraycount(inf_strings); i++) { | | 139 | for (size_t i = 0; i < __arraycount(inf_strings); i++) { |
140 | float f = strtof(inf_strings[i], NULL); | | 140 | volatile float f = strtof(inf_strings[i], NULL); |
141 | ATF_REQUIRE(isinf(f) != 0); | | 141 | ATF_REQUIRE(isinf(f) != 0); |
142 | } | | 142 | } |
143 | #else | | 143 | #else |
144 | atf_tc_skip("vax not supported"); | | 144 | atf_tc_skip("vax not supported"); |
145 | #endif | | 145 | #endif |
146 | } | | 146 | } |
147 | | | 147 | |
148 | ATF_TC(strtold_inf); | | 148 | ATF_TC(strtold_inf); |
149 | ATF_TC_HEAD(strtold_inf, tc) | | 149 | ATF_TC_HEAD(strtold_inf, tc) |
150 | { | | 150 | { |
151 | atf_tc_set_md_var(tc, "descr", "A strtold(3) with INF (PR lib/33262)"); | | 151 | atf_tc_set_md_var(tc, "descr", "A strtold(3) with INF (PR lib/33262)"); |
152 | } | | 152 | } |
153 | | | 153 | |
154 | ATF_TC_BODY(strtold_inf, tc) | | 154 | ATF_TC_BODY(strtold_inf, tc) |
155 | { | | 155 | { |
156 | #ifndef __vax__ | | 156 | #ifndef __vax__ |
157 | # ifdef __HAVE_LONG_DOUBLE | | 157 | # ifdef __HAVE_LONG_DOUBLE |
158 | if (system("cpuctl identify 0 | grep -q QEMU") == 0) | | 158 | if (system("cpuctl identify 0 | grep -q QEMU") == 0) |
159 | atf_tc_expect_fail("PR misc/44767"); | | 159 | atf_tc_expect_fail("PR misc/44767"); |
160 | | | 160 | |
161 | for (size_t i = 0; i < __arraycount(inf_strings); i++) { | | 161 | for (size_t i = 0; i < __arraycount(inf_strings); i++) { |
162 | long double ld = strtold(inf_strings[i], NULL); | | 162 | volatile long double ld = strtold(inf_strings[i], NULL); |
163 | ATF_REQUIRE(isinf(ld) != 0); | | 163 | ATF_REQUIRE(isinf(ld) != 0); |
164 | } | | 164 | } |
165 | # else | | 165 | # else |
166 | atf_tc_skip("Requires long double support"); | | 166 | atf_tc_skip("Requires long double support"); |
167 | # endif | | 167 | # endif |
168 | #else | | 168 | #else |
169 | atf_tc_skip("vax not supported"); | | 169 | atf_tc_skip("vax not supported"); |
170 | #endif | | 170 | #endif |
171 | } | | 171 | } |
172 | | | 172 | |
173 | ATF_TC(strtod_nan); | | 173 | ATF_TC(strtod_nan); |
174 | ATF_TC_HEAD(strtod_nan, tc) | | 174 | ATF_TC_HEAD(strtod_nan, tc) |
175 | { | | 175 | { |
176 | atf_tc_set_md_var(tc, "descr", "A strtod(3) with NaN"); | | 176 | atf_tc_set_md_var(tc, "descr", "A strtod(3) with NaN"); |
177 | } | | 177 | } |
178 | | | 178 | |
179 | ATF_TC_BODY(strtod_nan, tc) | | 179 | ATF_TC_BODY(strtod_nan, tc) |
180 | { | | 180 | { |
181 | #ifndef __vax__ | | 181 | #ifndef __vax__ |
182 | char *end; | | 182 | char *end; |
183 | | | 183 | |
184 | double d = strtod(nan_string, &end); | | 184 | volatile double d = strtod(nan_string, &end); |
185 | ATF_REQUIRE(isnan(d) != 0); | | 185 | ATF_REQUIRE(isnan(d) != 0); |
186 | ATF_REQUIRE(strcmp(end, "y") == 0); | | 186 | ATF_REQUIRE(strcmp(end, "y") == 0); |
187 | #else | | 187 | #else |
188 | atf_tc_skip("vax not supported"); | | 188 | atf_tc_skip("vax not supported"); |
189 | #endif | | 189 | #endif |
190 | } | | 190 | } |
191 | | | 191 | |
192 | ATF_TC(strtof_nan); | | 192 | ATF_TC(strtof_nan); |
193 | ATF_TC_HEAD(strtof_nan, tc) | | 193 | ATF_TC_HEAD(strtof_nan, tc) |
194 | { | | 194 | { |
195 | atf_tc_set_md_var(tc, "descr", "A strtof(3) with NaN"); | | 195 | atf_tc_set_md_var(tc, "descr", "A strtof(3) with NaN"); |
196 | } | | 196 | } |
197 | | | 197 | |
198 | ATF_TC_BODY(strtof_nan, tc) | | 198 | ATF_TC_BODY(strtof_nan, tc) |
199 | { | | 199 | { |
200 | #ifndef __vax__ | | 200 | #ifndef __vax__ |
201 | char *end; | | 201 | char *end; |
202 | | | 202 | |
203 | float f = strtof(nan_string, &end); | | 203 | volatile float f = strtof(nan_string, &end); |
204 | ATF_REQUIRE(isnanf(f) != 0); | | 204 | ATF_REQUIRE(isnanf(f) != 0); |
205 | ATF_REQUIRE(strcmp(end, "y") == 0); | | 205 | ATF_REQUIRE(strcmp(end, "y") == 0); |
206 | #else | | 206 | #else |
207 | atf_tc_skip("vax not supported"); | | 207 | atf_tc_skip("vax not supported"); |
208 | #endif | | 208 | #endif |
209 | } | | 209 | } |
210 | | | 210 | |
211 | ATF_TC(strtold_nan); | | 211 | ATF_TC(strtold_nan); |
212 | ATF_TC_HEAD(strtold_nan, tc) | | 212 | ATF_TC_HEAD(strtold_nan, tc) |
213 | { | | 213 | { |
214 | atf_tc_set_md_var(tc, "descr", "A strtold(3) with NaN (PR lib/45020)"); | | 214 | atf_tc_set_md_var(tc, "descr", "A strtold(3) with NaN (PR lib/45020)"); |
215 | } | | 215 | } |
216 | | | 216 | |
217 | ATF_TC_BODY(strtold_nan, tc) | | 217 | ATF_TC_BODY(strtold_nan, tc) |
218 | { | | 218 | { |
219 | #ifndef __vax__ | | 219 | #ifndef __vax__ |
220 | # ifdef __HAVE_LONG_DOUBLE | | 220 | # ifdef __HAVE_LONG_DOUBLE |
221 | | | 221 | |
222 | char *end; | | 222 | char *end; |
223 | | | 223 | |
224 | if (system("cpuctl identify 0 | grep -q QEMU") == 0) | | 224 | if (system("cpuctl identify 0 | grep -q QEMU") == 0) |
225 | atf_tc_expect_fail("PR misc/44767"); | | 225 | atf_tc_expect_fail("PR misc/44767"); |
226 | | | 226 | |
227 | long double ld = strtold(nan_string, &end); | | 227 | volatile long double ld = strtold(nan_string, &end); |
228 | ATF_REQUIRE(isnan(ld) != 0); | | 228 | ATF_REQUIRE(isnan(ld) != 0); |
229 | ATF_REQUIRE(__isnanl(ld) != 0); | | 229 | ATF_REQUIRE(__isnanl(ld) != 0); |
230 | ATF_REQUIRE(strcmp(end, "y") == 0); | | 230 | ATF_REQUIRE(strcmp(end, "y") == 0); |
231 | # else | | 231 | # else |
232 | atf_tc_skip("Requires long double support"); | | 232 | atf_tc_skip("Requires long double support"); |
233 | # endif | | 233 | # endif |
234 | #else | | 234 | #else |
235 | atf_tc_skip("vax not supported"); | | 235 | atf_tc_skip("vax not supported"); |
236 | #endif | | 236 | #endif |
237 | } | | 237 | } |
238 | | | 238 | |
239 | ATF_TC(strtod_round); | | 239 | ATF_TC(strtod_round); |
240 | ATF_TC_HEAD(strtod_round, tc) | | 240 | ATF_TC_HEAD(strtod_round, tc) |
| @@ -245,31 +245,31 @@ ATF_TC_HEAD(strtod_round, tc) | | | @@ -245,31 +245,31 @@ ATF_TC_HEAD(strtod_round, tc) |
245 | ATF_TC_BODY(strtod_round, tc) | | 245 | ATF_TC_BODY(strtod_round, tc) |
246 | { | | 246 | { |
247 | #if defined(__i386__) || defined(__amd64__) || defined(__sparc__) | | 247 | #if defined(__i386__) || defined(__amd64__) || defined(__sparc__) |
248 | | | 248 | |
249 | /* | | 249 | /* |
250 | * Test that strtod(3) honors the current rounding mode. | | 250 | * Test that strtod(3) honors the current rounding mode. |
251 | * The used value is somewhere near 1 + DBL_EPSILON + FLT_EPSILON. | | 251 | * The used value is somewhere near 1 + DBL_EPSILON + FLT_EPSILON. |
252 | */ | | 252 | */ |
253 | const char *val = | | 253 | const char *val = |
254 | "1.00000011920928977282585492503130808472633361816406"; | | 254 | "1.00000011920928977282585492503130808472633361816406"; |
255 | | | 255 | |
256 | (void)fesetround(FE_UPWARD); | | 256 | (void)fesetround(FE_UPWARD); |
257 | | | 257 | |
258 | double d1 = strtod(val, NULL); | | 258 | volatile double d1 = strtod(val, NULL); |
259 | | | 259 | |
260 | (void)fesetround(FE_DOWNWARD); | | 260 | (void)fesetround(FE_DOWNWARD); |
261 | | | 261 | |
262 | double d2 = strtod(val, NULL); | | 262 | volatile double d2 = strtod(val, NULL); |
263 | | | 263 | |
264 | if (fabs(d1 - d2) > 0.0) | | 264 | if (fabs(d1 - d2) > 0.0) |
265 | return; | | 265 | return; |
266 | else { | | 266 | else { |
267 | atf_tc_expect_fail("PR misc/44767"); | | 267 | atf_tc_expect_fail("PR misc/44767"); |
268 | atf_tc_fail("strtod(3) did not honor fesetround(3)"); | | 268 | atf_tc_fail("strtod(3) did not honor fesetround(3)"); |
269 | } | | 269 | } |
270 | #else | | 270 | #else |
271 | atf_tc_skip("Requires one of i386, amd64 or sparc"); | | 271 | atf_tc_skip("Requires one of i386, amd64 or sparc"); |
272 | #endif | | 272 | #endif |
273 | } | | 273 | } |
274 | | | 274 | |
275 | ATF_TC(strtod_underflow); | | 275 | ATF_TC(strtod_underflow); |
| @@ -282,27 +282,27 @@ ATF_TC_BODY(strtod_underflow, tc) | | | @@ -282,27 +282,27 @@ ATF_TC_BODY(strtod_underflow, tc) |
282 | { | | 282 | { |
283 | | | 283 | |
284 | const char *tmp = | | 284 | const char *tmp = |
285 | "0.0000000000000000000000000000000000000000000000000000" | | 285 | "0.0000000000000000000000000000000000000000000000000000" |
286 | "000000000000000000000000000000000000000000000000000000" | | 286 | "000000000000000000000000000000000000000000000000000000" |
287 | "000000000000000000000000000000000000000000000000000000" | | 287 | "000000000000000000000000000000000000000000000000000000" |
288 | "000000000000000000000000000000000000000000000000000000" | | 288 | "000000000000000000000000000000000000000000000000000000" |
289 | "000000000000000000000000000000000000000000000000000000" | | 289 | "000000000000000000000000000000000000000000000000000000" |
290 | "000000000000000000000000000000000000000000000000000000" | | 290 | "000000000000000000000000000000000000000000000000000000" |
291 | "000000000000000000000000000000000000000000000000000000" | | 291 | "000000000000000000000000000000000000000000000000000000" |
292 | "000000000000000002"; | | 292 | "000000000000000002"; |
293 | | | 293 | |
294 | errno = 0; | | 294 | errno = 0; |
295 | double d = strtod(tmp, NULL); | | 295 | volatile double d = strtod(tmp, NULL); |
296 | | | 296 | |
297 | if (d != 0 || errno != ERANGE) | | 297 | if (d != 0 || errno != ERANGE) |
298 | atf_tc_fail("strtod(3) did not detect underflow"); | | 298 | atf_tc_fail("strtod(3) did not detect underflow"); |
299 | } | | 299 | } |
300 | | | 300 | |
301 | ATF_TP_ADD_TCS(tp) | | 301 | ATF_TP_ADD_TCS(tp) |
302 | { | | 302 | { |
303 | | | 303 | |
304 | ATF_TP_ADD_TC(tp, strtod_basic); | | 304 | ATF_TP_ADD_TC(tp, strtod_basic); |
305 | ATF_TP_ADD_TC(tp, strtod_hex); | | 305 | ATF_TP_ADD_TC(tp, strtod_hex); |
306 | ATF_TP_ADD_TC(tp, strtod_inf); | | 306 | ATF_TP_ADD_TC(tp, strtod_inf); |
307 | ATF_TP_ADD_TC(tp, strtof_inf); | | 307 | ATF_TP_ADD_TC(tp, strtof_inf); |
308 | ATF_TP_ADD_TC(tp, strtold_inf); | | 308 | ATF_TP_ADD_TC(tp, strtold_inf); |