Add sysdeps/ieee754/soft-fp.
[glibc.git] / stdio-common / tst-sscanf.c
blob9ccd86e7b0d368fcaf8cb4e2135f2ddfbd0a5d37
1 /* Copyright (C) 2000-2017 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Jakub Jelinek <jakub@redhat.com>, 2000.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
19 #include <array_length.h>
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <locale.h>
24 #ifndef CHAR
25 # define CHAR char
26 # define L(str) str
27 # define SSCANF sscanf
28 #endif
30 const CHAR *str_double[] =
32 L("-.10000E+020.20000E+020.25000E+010.40000E+010.50000E+010.12500E+01"),
33 L("0.10000E+020.20000E+020.25000E+010.40000E+010.50000E+010.12500E+01"),
34 L("-1234567E0198765432E0912345678901987654321091234567890198765432109"),
35 L("-0.1000E+020.20000E+020.25000E+010.40000E+010.50000E+010.12500E+01")
38 const double val_double[] =
40 -.10000E+02, 0.20000E+02, 0.25000E+01, 0.40000E+01, 0.50000E+01, 0.12500E+01,
41 0.10000E+02, 0.20000E+02, 0.25000E+01, 0.40000E+01, 0.50000E+01, 0.12500E+01,
42 -1234567E01, 98765432E09, 12345678901.0, 98765432109.0, 12345678901.0,
43 98765432109.0,
44 -0.1000E+02, 0.20000E+02, 0.25000E+01, 0.40000E+01, 0.50000E+01, 0.12500E+01
47 const CHAR *str_long[] =
49 L("-12345678987654321123456789987654321123456789987654321"),
50 L("-12345678987654321123456789987654321123456789987654321"),
51 L("-12,345,678987,654,321123,456,789987,654,321123,456,789987,654,321"),
52 L("-12,345,678987,654,321123,456,789987,654,321123,456,789987,654,321")
55 const CHAR *fmt_long[] =
57 L("%9ld%9ld%9ld%9ld%9ld%9ld"),
58 L("%I9ld%I9ld%I9ld%I9ld%I9ld%I9ld"),
59 L("%'11ld%'11ld%'11ld%'11ld%'11ld%'11ld"),
60 L("%I'11ld%I'11ld%I'11ld%I'11ld%I'11ld%I'11ld")
63 const long int val_long[] =
65 -12345678, 987654321, 123456789, 987654321, 123456789, 987654321
68 struct test
70 const CHAR *str;
71 const CHAR *fmt;
72 int retval;
73 } int_tests[] =
75 { L("foo\n"), L("foo\nbar"), -1 },
76 { L("foo\n"), L("foo bar"), -1 },
77 { L("foo\n"), L("foo %d"), -1 },
78 { L("foo\n"), L("foo\n%d"), -1 },
79 { L("foon"), L("foonbar"), -1 },
80 { L("foon"), L("foon%d"), -1 },
81 { L("foo "), L("foo bar"), -1 },
82 { L("foo "), L("foo %d"), -1 },
83 { L("foo\t"), L("foo\tbar"), -1 },
84 { L("foo\t"), L("foo bar"), -1 },
85 { L("foo\t"), L("foo %d"), -1 },
86 { L("foo\t"), L("foo\t%d"), -1 },
87 { L("foo"), L("foo"), 0 },
88 { L("foon"), L("foo bar"), 0 },
89 { L("foon"), L("foo %d"), 0 },
90 { L("foo "), L("fooxbar"), 0 },
91 { L("foo "), L("foox%d"), 0 },
92 { L("foo bar"), L("foon"), 0 },
93 { L("foo bar"), L("foo bar"), 0 },
94 { L("foo bar"), L("foo %d"), 0 },
95 { L("foo bar"), L("foon%d"), 0 },
96 { L("foo (nil)"), L("foo %p"), 1},
97 { L("foo (nil)"), L("foo %4p"), 0},
98 { L("foo "), L("foo %n"), 0 },
99 { L("foo%bar1"), L("foo%%bar%d"), 1 },
100 /* Some OSes skip whitespace here while others don't. */
101 { L("foo \t %bar1"), L("foo%%bar%d"), 1 }
104 struct test double_tests[] =
106 { L("-1"), L("%1g"), 0 },
107 { L("-.1"), L("%2g"), 0 },
108 { L("-inf"), L("%3g"), 0 },
109 { L("+0"), L("%1g"), },
110 { L("-0x1p0"), L("%2g"), 1 },
111 { L("-..1"), L("%g"), 0 },
112 { L("-inf"), L("%g"), 1 }
115 struct test2
117 const CHAR *str;
118 const CHAR *fmt;
119 int retval;
120 char residual;
121 } double_tests2[] =
123 { L("0e+0"), L("%g%c"), 1, 0 },
124 { L("0xe+0"), L("%g%c"), 2, '+' },
125 { L("0x.e+0"), L("%g%c"), 2, '+' },
128 static int
129 do_test (void)
131 double d[6];
132 long l[6];
133 int i, j;
134 int tst_locale;
135 int result = 0;
137 tst_locale = 1;
138 if (tst_locale)
139 if (setlocale (LC_ALL, "en_US.ISO-8859-1") == NULL)
141 puts ("Failed to set en_US locale, skipping locale related tests");
142 tst_locale = 0;
145 for (i = 0; i < 4; ++i)
147 if (SSCANF (str_double[i], L("%11lf%11lf%11lf%11lf%11lf%11lf"),
148 &d[0], &d[1], &d[2], &d[3], &d[4], &d[5]) != 6)
150 printf ("Double sscanf test %d wrong number of "
151 "assigned inputs\n", i);
152 result = 1;
154 else
155 for (j = 0; j < 6; ++j)
156 if (d[j] != val_double[6 * i + j])
158 printf ("Double sscanf test %d failed (%g instead of %g)\n",
159 i, d[j], val_double[6 * i + j]);
160 result = 1;
161 break;
165 for (i = 0; i < 4; ++i)
167 if (SSCANF (str_long[i], fmt_long[i],
168 &l[0], &l[1], &l[2], &l[3], &l[4], &l[5]) != 6)
170 printf ("Integer sscanf test %d wrong number of "
171 "assigned inputs\n", i);
172 result = 1;
174 else
175 for (j = 0; j < 6; ++j)
176 if (l[j] != val_long[j])
178 printf ("Integer sscanf test %d failed (%ld instead %ld)\n",
179 i, l[j], val_long[j]);
180 result = 1;
181 break;
184 if (! tst_locale)
185 break;
188 for (i = 0; i < array_length (int_tests); ++i)
190 long dummy;
191 int ret;
193 if ((ret = SSCANF (int_tests[i].str, int_tests[i].fmt,
194 &dummy)) != int_tests[i].retval)
196 printf ("int_tests[%d] returned %d != %d\n",
197 i, ret, int_tests[i].retval);
198 result = 1;
202 for (i = 0; i < array_length (double_tests); ++i)
204 double dummy;
205 int ret;
207 if ((ret = SSCANF (double_tests[i].str, double_tests[i].fmt,
208 &dummy)) != double_tests[i].retval)
210 printf ("double_tests[%d] returned %d != %d\n",
211 i, ret, double_tests[i].retval);
212 result = 1;
216 for (i = 0; i < array_length (double_tests2); ++i)
218 double dummy;
219 int ret;
220 char c = 0;
222 if ((ret = SSCANF (double_tests2[i].str, double_tests2[i].fmt,
223 &dummy, &c)) != double_tests2[i].retval)
225 printf ("double_tests2[%d] returned %d != %d\n",
226 i, ret, double_tests2[i].retval);
227 result = 1;
229 else if (ret == 2 && c != double_tests2[i].residual)
231 printf ("double_tests2[%d] stopped at '%c' != '%c'\n",
232 i, c, double_tests2[i].residual);
233 result = 1;
237 /* BZ #16618
238 The test will segfault during SSCANF if the buffer overflow
239 is not fixed. The size of `s` is such that it forces the use
240 of malloc internally and this triggers the incorrect computation.
241 Thus the value for SIZE is arbitrariy high enough that malloc
242 is used. */
244 #define SIZE 131072
245 CHAR *s = malloc ((SIZE + 1) * sizeof (*s));
246 if (s == NULL)
247 abort ();
248 for (size_t i = 0; i < SIZE; i++)
249 s[i] = L('0');
250 s[SIZE] = L('\0');
251 int i = 42;
252 /* Scan multi-digit zero into `i`. */
253 if (SSCANF (s, L("%d"), &i) != 1)
255 printf ("FAIL: bug16618: SSCANF did not read one input item.\n");
256 result = 1;
258 if (i != 0)
260 printf ("FAIL: bug16618: Value of `i` was not zero as expected.\n");
261 result = 1;
263 free (s);
264 if (result != 1)
265 printf ("PASS: bug16618: Did not crash.\n");
266 #undef SIZE
270 return result;
273 #define TEST_FUNCTION do_test ()
274 #include "../test-skeleton.c"