1 | #include <array_length.h> |
2 | #include <float.h> |
3 | #include <math.h> |
4 | #include <stdio.h> |
5 | #include <string.h> |
6 | #include <wchar.h> |
7 | #include <libc-diag.h> |
8 | |
9 | static int |
10 | t1 (void) |
11 | { |
12 | int n = -1; |
13 | sscanf ("abc " , "abc %n" , &n); |
14 | printf (format: "t1: count=%d\n" , n); |
15 | |
16 | return n != 5; |
17 | } |
18 | |
19 | static int |
20 | t2 (void) |
21 | { |
22 | int result = 0; |
23 | int n; |
24 | long N; |
25 | int retval; |
26 | #define SCAN(INPUT, FORMAT, VAR, EXP_RES, EXP_VAL) \ |
27 | VAR = -1; \ |
28 | retval = sscanf (INPUT, FORMAT, &VAR); \ |
29 | printf ("sscanf (\"%s\", \"%s\", &x) => %d, x = %ld\n", \ |
30 | INPUT, FORMAT, retval, (long int) VAR); \ |
31 | result |= retval != EXP_RES || VAR != EXP_VAL |
32 | |
33 | /* This function is testing corner cases of the scanf format string, |
34 | so they do not all conform to -Wformat's expectations. */ |
35 | DIAG_PUSH_NEEDS_COMMENT; |
36 | DIAG_IGNORE_NEEDS_COMMENT (4.9, "-Wformat" ); |
37 | DIAG_IGNORE_NEEDS_COMMENT (4.9, "-Wformat-extra-args" ); |
38 | |
39 | SCAN ("12345" , "%ld" , N, 1, 12345); |
40 | SCAN ("12345" , "%llllld" , N, 0, -1); |
41 | SCAN ("12345" , "%LLLLLd" , N, 0, -1); |
42 | SCAN ("test " , "%*s%n" , n, 0, 4); |
43 | SCAN ("test " , "%2*s%n" , n, 0, -1); |
44 | SCAN ("12 " , "%l2d" , n, 0, -1); |
45 | SCAN ("12 " , "%2ld" , N, 1, 12); |
46 | |
47 | n = -1; |
48 | N = -1; |
49 | retval = sscanf ("1 1" , "%d %Z" , &n, &N); |
50 | printf (format: "sscanf (\"1 1\", \"%%d %%Z\", &n, &N) => %d, n = %d, N = %ld\n" , \ |
51 | retval, n, N); \ |
52 | result |= retval != 1 || n != 1 || N != -1; |
53 | |
54 | DIAG_POP_NEEDS_COMMENT; |
55 | |
56 | return result; |
57 | } |
58 | |
59 | static int |
60 | t3 (void) |
61 | { |
62 | char buf[80]; |
63 | wchar_t wbuf[80]; |
64 | int result = 0; |
65 | int retval; |
66 | |
67 | retval = sprintf (buf, "%p" , (char *) NULL); |
68 | result |= retval != 5 || strcmp (buf, "(nil)" ) != 0; |
69 | |
70 | retval = swprintf (s: wbuf, array_length (wbuf), format: L"%p" , (char *) NULL); |
71 | result |= retval != 5 || wcscmp (s1: wbuf, s2: L"(nil)" ) != 0; |
72 | |
73 | return result; |
74 | } |
75 | |
76 | volatile double qnanval; |
77 | volatile long double lqnanval; |
78 | /* A sNaN is only guaranteed to be representable in variables with static (or |
79 | thread-local) storage duration. */ |
80 | static volatile double snanval = __builtin_nans ("" ); |
81 | static volatile double msnanval = -__builtin_nans ("" ); |
82 | static volatile long double lsnanval = __builtin_nansl ("" ); |
83 | static volatile long double lmsnanval = -__builtin_nansl ("" ); |
84 | volatile double infval; |
85 | volatile long double linfval; |
86 | |
87 | |
88 | static int |
89 | F (void) |
90 | { |
91 | char buf[80]; |
92 | wchar_t wbuf[40]; |
93 | int result = 0; |
94 | |
95 | qnanval = NAN; |
96 | |
97 | /* The %f and %F arguments are in fact constants, but GCC is |
98 | prevented from seeing this (volatile is used) so it cannot tell |
99 | that the output is not truncated. */ |
100 | DIAG_PUSH_NEEDS_COMMENT; |
101 | #if __GNUC_PREREQ (7, 0) |
102 | DIAG_IGNORE_NEEDS_COMMENT (7.0, "-Wformat-truncation" ); |
103 | #endif |
104 | |
105 | snprintf (s: buf, maxlen: sizeof buf, format: "%a %A %e %E %f %F %g %G" , |
106 | qnanval, qnanval, qnanval, qnanval, |
107 | qnanval, qnanval, qnanval, qnanval); |
108 | result |= strcmp (buf, "nan NAN nan NAN nan NAN nan NAN" ) != 0; |
109 | printf (format: "expected \"nan NAN nan NAN nan NAN nan NAN\", got \"%s\"\n" , buf); |
110 | |
111 | snprintf (s: buf, maxlen: sizeof buf, format: "%a %A %e %E %f %F %g %G" , |
112 | -qnanval, -qnanval, -qnanval, -qnanval, |
113 | -qnanval, -qnanval, -qnanval, -qnanval); |
114 | result |= strcmp (buf, "-nan -NAN -nan -NAN -nan -NAN -nan -NAN" ) != 0; |
115 | printf (format: "expected \"-nan -NAN -nan -NAN -nan -NAN -nan -NAN\", got \"%s\"\n" , |
116 | buf); |
117 | |
118 | snprintf (s: buf, maxlen: sizeof buf, format: "%a %A %e %E %f %F %g %G" , |
119 | snanval, snanval, snanval, snanval, |
120 | snanval, snanval, snanval, snanval); |
121 | result |= strcmp (buf, "nan NAN nan NAN nan NAN nan NAN" ) != 0; |
122 | printf (format: "expected \"nan NAN nan NAN nan NAN nan NAN\", got \"%s\"\n" , buf); |
123 | |
124 | snprintf (s: buf, maxlen: sizeof buf, format: "%a %A %e %E %f %F %g %G" , |
125 | msnanval, msnanval, msnanval, msnanval, |
126 | msnanval, msnanval, msnanval, msnanval); |
127 | result |= strcmp (buf, "-nan -NAN -nan -NAN -nan -NAN -nan -NAN" ) != 0; |
128 | printf (format: "expected \"-nan -NAN -nan -NAN -nan -NAN -nan -NAN\", got \"%s\"\n" , |
129 | buf); |
130 | |
131 | infval = DBL_MAX * DBL_MAX; |
132 | |
133 | snprintf (s: buf, maxlen: sizeof buf, format: "%a %A %e %E %f %F %g %G" , |
134 | infval, infval, infval, infval, infval, infval, infval, infval); |
135 | result |= strcmp (buf, "inf INF inf INF inf INF inf INF" ) != 0; |
136 | printf (format: "expected \"inf INF inf INF inf INF inf INF\", got \"%s\"\n" , buf); |
137 | |
138 | snprintf (s: buf, maxlen: sizeof buf, format: "%a %A %e %E %f %F %g %G" , |
139 | -infval, -infval, -infval, -infval, |
140 | -infval, -infval, -infval, -infval); |
141 | result |= strcmp (buf, "-inf -INF -inf -INF -inf -INF -inf -INF" ) != 0; |
142 | printf (format: "expected \"-inf -INF -inf -INF -inf -INF -inf -INF\", got \"%s\"\n" , |
143 | buf); |
144 | |
145 | swprintf (s: wbuf, array_length (wbuf), format: L"%a %A %e %E %f %F %g %G" , |
146 | qnanval, qnanval, qnanval, qnanval, |
147 | qnanval, qnanval, qnanval, qnanval); |
148 | result |= wcscmp (s1: wbuf, s2: L"nan NAN nan NAN nan NAN nan NAN" ) != 0; |
149 | printf (format: "expected L\"nan NAN nan NAN nan NAN nan NAN\", got L\"%S\"\n" , wbuf); |
150 | |
151 | swprintf (s: wbuf, array_length (wbuf), format: L"%a %A %e %E %f %F %g %G" , |
152 | -qnanval, -qnanval, -qnanval, -qnanval, |
153 | -qnanval, -qnanval, -qnanval, -qnanval); |
154 | result |= wcscmp (s1: wbuf, s2: L"-nan -NAN -nan -NAN -nan -NAN -nan -NAN" ) != 0; |
155 | printf (format: "expected L\"-nan -NAN -nan -NAN -nan -NAN -nan -NAN\", got L\"%S\"\n" , |
156 | wbuf); |
157 | |
158 | swprintf (s: wbuf, array_length (wbuf), format: L"%a %A %e %E %f %F %g %G" , |
159 | snanval, snanval, snanval, snanval, |
160 | snanval, snanval, snanval, snanval); |
161 | result |= wcscmp (s1: wbuf, s2: L"nan NAN nan NAN nan NAN nan NAN" ) != 0; |
162 | printf (format: "expected L\"nan NAN nan NAN nan NAN nan NAN\", got L\"%S\"\n" , wbuf); |
163 | |
164 | swprintf (s: wbuf, array_length (wbuf), format: L"%a %A %e %E %f %F %g %G" , |
165 | msnanval, msnanval, msnanval, msnanval, |
166 | msnanval, msnanval, msnanval, msnanval); |
167 | result |= wcscmp (s1: wbuf, s2: L"-nan -NAN -nan -NAN -nan -NAN -nan -NAN" ) != 0; |
168 | printf (format: "expected L\"-nan -NAN -nan -NAN -nan -NAN -nan -NAN\", got L\"%S\"\n" , |
169 | wbuf); |
170 | |
171 | swprintf (s: wbuf, array_length (wbuf), format: L"%a %A %e %E %f %F %g %G" , |
172 | infval, infval, infval, infval, infval, infval, infval, infval); |
173 | result |= wcscmp (s1: wbuf, s2: L"inf INF inf INF inf INF inf INF" ) != 0; |
174 | printf (format: "expected L\"inf INF inf INF inf INF inf INF\", got L\"%S\"\n" , wbuf); |
175 | |
176 | swprintf (s: wbuf, array_length (wbuf), format: L"%a %A %e %E %f %F %g %G" , |
177 | -infval, -infval, -infval, -infval, |
178 | -infval, -infval, -infval, -infval); |
179 | result |= wcscmp (s1: wbuf, s2: L"-inf -INF -inf -INF -inf -INF -inf -INF" ) != 0; |
180 | printf (format: "expected L\"-inf -INF -inf -INF -inf -INF -inf -INF\", got L\"%S\"\n" , |
181 | wbuf); |
182 | |
183 | lqnanval = NAN; |
184 | |
185 | snprintf (s: buf, maxlen: sizeof buf, format: "%La %LA %Le %LE %Lf %LF %Lg %LG" , |
186 | lqnanval, lqnanval, lqnanval, lqnanval, |
187 | lqnanval, lqnanval, lqnanval, lqnanval); |
188 | result |= strcmp (buf, "nan NAN nan NAN nan NAN nan NAN" ) != 0; |
189 | printf (format: "expected \"nan NAN nan NAN nan NAN nan NAN\", got \"%s\"\n" , buf); |
190 | |
191 | snprintf (s: buf, maxlen: sizeof buf, format: "%La %LA %Le %LE %Lf %LF %Lg %LG" , |
192 | -lqnanval, -lqnanval, -lqnanval, -lqnanval, |
193 | -lqnanval, -lqnanval, -lqnanval, -lqnanval); |
194 | result |= strcmp (buf, "-nan -NAN -nan -NAN -nan -NAN -nan -NAN" ) != 0; |
195 | printf (format: "expected \"-nan -NAN -nan -NAN -nan -NAN -nan -NAN\", got \"%s\"\n" , |
196 | buf); |
197 | |
198 | snprintf (s: buf, maxlen: sizeof buf, format: "%La %LA %Le %LE %Lf %LF %Lg %LG" , |
199 | lsnanval, lsnanval, lsnanval, lsnanval, |
200 | lsnanval, lsnanval, lsnanval, lsnanval); |
201 | result |= strcmp (buf, "nan NAN nan NAN nan NAN nan NAN" ) != 0; |
202 | printf (format: "expected \"nan NAN nan NAN nan NAN nan NAN\", got \"%s\"\n" , buf); |
203 | |
204 | snprintf (s: buf, maxlen: sizeof buf, format: "%La %LA %Le %LE %Lf %LF %Lg %LG" , |
205 | lmsnanval, lmsnanval, lmsnanval, lmsnanval, |
206 | lmsnanval, lmsnanval, lmsnanval, lmsnanval); |
207 | result |= strcmp (buf, "-nan -NAN -nan -NAN -nan -NAN -nan -NAN" ) != 0; |
208 | printf (format: "expected \"-nan -NAN -nan -NAN -nan -NAN -nan -NAN\", got \"%s\"\n" , |
209 | buf); |
210 | |
211 | linfval = LDBL_MAX * LDBL_MAX; |
212 | |
213 | snprintf (s: buf, maxlen: sizeof buf, format: "%La %LA %Le %LE %Lf %LF %Lg %LG" , |
214 | linfval, linfval, linfval, linfval, |
215 | linfval, linfval, linfval, linfval); |
216 | result |= strcmp (buf, "inf INF inf INF inf INF inf INF" ) != 0; |
217 | printf (format: "expected \"inf INF inf INF inf INF inf INF\", got \"%s\"\n" , buf); |
218 | |
219 | snprintf (s: buf, maxlen: sizeof buf, format: "%La %LA %Le %LE %Lf %LF %Lg %LG" , |
220 | -linfval, -linfval, -linfval, -linfval, |
221 | -linfval, -linfval, -linfval, -linfval); |
222 | result |= strcmp (buf, "-inf -INF -inf -INF -inf -INF -inf -INF" ) != 0; |
223 | printf (format: "expected \"-inf -INF -inf -INF -inf -INF -inf -INF\", got \"%s\"\n" , |
224 | buf); |
225 | |
226 | swprintf (s: wbuf, array_length (wbuf), |
227 | format: L"%La %LA %Le %LE %Lf %LF %Lg %LG" , |
228 | lqnanval, lqnanval, lqnanval, lqnanval, |
229 | lqnanval, lqnanval, lqnanval, lqnanval); |
230 | result |= wcscmp (s1: wbuf, s2: L"nan NAN nan NAN nan NAN nan NAN" ) != 0; |
231 | printf (format: "expected L\"nan NAN nan NAN nan NAN nan NAN\", got L\"%S\"\n" , wbuf); |
232 | |
233 | swprintf (s: wbuf, array_length (wbuf), |
234 | format: L"%La %LA %Le %LE %Lf %LF %Lg %LG" , |
235 | -lqnanval, -lqnanval, -lqnanval, -lqnanval, |
236 | -lqnanval, -lqnanval, -lqnanval, -lqnanval); |
237 | result |= wcscmp (s1: wbuf, s2: L"-nan -NAN -nan -NAN -nan -NAN -nan -NAN" ) != 0; |
238 | printf (format: "expected L\"-nan -NAN -nan -NAN -nan -NAN -nan -NAN\", got L\"%S\"\n" , |
239 | wbuf); |
240 | |
241 | swprintf (s: wbuf, array_length (wbuf), |
242 | format: L"%La %LA %Le %LE %Lf %LF %Lg %LG" , |
243 | lsnanval, lsnanval, lsnanval, lsnanval, |
244 | lsnanval, lsnanval, lsnanval, lsnanval); |
245 | result |= wcscmp (s1: wbuf, s2: L"nan NAN nan NAN nan NAN nan NAN" ) != 0; |
246 | printf (format: "expected L\"nan NAN nan NAN nan NAN nan NAN\", got L\"%S\"\n" , wbuf); |
247 | |
248 | swprintf (s: wbuf, array_length (wbuf), |
249 | format: L"%La %LA %Le %LE %Lf %LF %Lg %LG" , |
250 | lmsnanval, lmsnanval, lmsnanval, lmsnanval, |
251 | lmsnanval, lmsnanval, lmsnanval, lmsnanval); |
252 | result |= wcscmp (s1: wbuf, s2: L"-nan -NAN -nan -NAN -nan -NAN -nan -NAN" ) != 0; |
253 | printf (format: "expected L\"-nan -NAN -nan -NAN -nan -NAN -nan -NAN\", got L\"%S\"\n" , |
254 | wbuf); |
255 | |
256 | swprintf (s: wbuf, array_length (wbuf), |
257 | format: L"%La %LA %Le %LE %Lf %LF %Lg %LG" , |
258 | linfval, linfval, linfval, linfval, |
259 | linfval, linfval, linfval, linfval); |
260 | result |= wcscmp (s1: wbuf, s2: L"inf INF inf INF inf INF inf INF" ) != 0; |
261 | printf (format: "expected L\"inf INF inf INF inf INF inf INF\", got L\"%S\"\n" , wbuf); |
262 | |
263 | swprintf (s: wbuf, array_length (wbuf), |
264 | format: L"%La %LA %Le %LE %Lf %LF %Lg %LG" , |
265 | -linfval, -linfval, -linfval, -linfval, |
266 | -linfval, -linfval, -linfval, -linfval); |
267 | result |= wcscmp (s1: wbuf, s2: L"-inf -INF -inf -INF -inf -INF -inf -INF" ) != 0; |
268 | printf (format: "expected L\"-inf -INF -inf -INF -inf -INF -inf -INF\", got L\"%S\"\n" , |
269 | wbuf); |
270 | |
271 | DIAG_POP_NEEDS_COMMENT; |
272 | |
273 | return result; |
274 | } |
275 | |
276 | int |
277 | main (int argc, char *argv[]) |
278 | { |
279 | int result = 0; |
280 | |
281 | result |= t1 (); |
282 | result |= t2 (); |
283 | result |= t3 (); |
284 | result |= F (); |
285 | |
286 | result |= fflush (stdout) == EOF; |
287 | |
288 | return result; |
289 | } |
290 | |