]>
Commit | Line | Data |
---|---|---|
b168057a | 1 | /* Copyright (C) 1991-2015 Free Software Foundation, Inc. |
c84142e8 UD |
2 | This file is part of the GNU C Library. |
3 | ||
4 | The GNU C Library is free software; you can redistribute it and/or | |
41bdb6e2 AJ |
5 | modify it under the terms of the GNU Lesser General Public |
6 | License as published by the Free Software Foundation; either | |
7 | version 2.1 of the License, or (at your option) any later version. | |
c84142e8 UD |
8 | |
9 | The GNU C Library is distributed in the hope that it will be useful, | |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
41bdb6e2 | 12 | Lesser General Public License for more details. |
c84142e8 | 13 | |
41bdb6e2 | 14 | You should have received a copy of the GNU Lesser General Public |
59ba27a6 PE |
15 | License along with the GNU C Library; if not, see |
16 | <http://www.gnu.org/licenses/>. */ | |
28f540f4 | 17 | |
28f540f4 RM |
18 | #ifdef BSD |
19 | #include </usr/include/stdio.h> | |
20 | #define EXIT_SUCCESS 0 | |
21 | #else | |
b3f7c665 | 22 | #include <limits.h> |
28f540f4 RM |
23 | #include <stdio.h> |
24 | #include <stdlib.h> | |
25 | #include <string.h> | |
26 | #endif | |
27 | ||
28 | #include <float.h> | |
1c4053db RM |
29 | #include <libc-internal.h> |
30 | ||
31 | /* This whole file is picayune tests of corner cases of printf format strings. | |
32 | The compiler warnings are not useful here. */ | |
33 | DIAG_IGNORE_NEEDS_COMMENT (4.9, "-Wformat"); | |
28f540f4 | 34 | |
1a511d31 AJ |
35 | static void rfg1 (void); |
36 | static void rfg2 (void); | |
75bfdfc7 | 37 | static void rfg3 (void); |
11336c16 | 38 | |
28f540f4 | 39 | |
1a511d31 | 40 | static void |
11336c16 | 41 | fmtchk (const char *fmt) |
28f540f4 RM |
42 | { |
43 | (void) fputs(fmt, stdout); | |
44 | (void) printf(":\t`"); | |
45 | (void) printf(fmt, 0x12); | |
46 | (void) printf("'\n"); | |
47 | } | |
48 | ||
1a511d31 | 49 | static void |
11336c16 | 50 | fmtst1chk (const char *fmt) |
28f540f4 RM |
51 | { |
52 | (void) fputs(fmt, stdout); | |
53 | (void) printf(":\t`"); | |
54 | (void) printf(fmt, 4, 0x12); | |
55 | (void) printf("'\n"); | |
56 | } | |
57 | ||
1a511d31 | 58 | static void |
11336c16 | 59 | fmtst2chk (const char *fmt) |
28f540f4 RM |
60 | { |
61 | (void) fputs(fmt, stdout); | |
62 | (void) printf(":\t`"); | |
63 | (void) printf(fmt, 4, 4, 0x12); | |
64 | (void) printf("'\n"); | |
65 | } | |
66 | \f | |
67 | /* This page is covered by the following copyright: */ | |
68 | ||
69 | /* (C) Copyright C E Chew | |
70 | * | |
71 | * Feel free to copy, use and distribute this software provided: | |
72 | * | |
73 | * 1. you do not pretend that you wrote it | |
74 | * 2. you leave this copyright notice intact. | |
75 | */ | |
76 | ||
77 | /* | |
78 | * Extracted from exercise.c for glibc-1.05 bug report by Bruce Evans. | |
79 | */ | |
80 | ||
81 | #define DEC -123 | |
82 | #define INT 255 | |
83 | #define UNS (~0) | |
84 | ||
85 | /* Formatted Output Test | |
86 | * | |
87 | * This exercises the output formatting code. | |
88 | */ | |
89 | ||
1a511d31 | 90 | static void |
11336c16 | 91 | fp_test (void) |
28f540f4 RM |
92 | { |
93 | int i, j, k, l; | |
94 | char buf[7]; | |
95 | char *prefix = buf; | |
96 | char tp[20]; | |
97 | ||
98 | puts("\nFormatted output test"); | |
99 | printf("prefix 6d 6o 6x 6X 6u\n"); | |
100 | strcpy(prefix, "%"); | |
101 | for (i = 0; i < 2; i++) { | |
102 | for (j = 0; j < 2; j++) { | |
103 | for (k = 0; k < 2; k++) { | |
104 | for (l = 0; l < 2; l++) { | |
105 | strcpy(prefix, "%"); | |
106 | if (i == 0) strcat(prefix, "-"); | |
107 | if (j == 0) strcat(prefix, "+"); | |
108 | if (k == 0) strcat(prefix, "#"); | |
109 | if (l == 0) strcat(prefix, "0"); | |
110 | printf("%5s |", prefix); | |
111 | strcpy(tp, prefix); | |
112 | strcat(tp, "6d |"); | |
113 | printf(tp, DEC); | |
114 | strcpy(tp, prefix); | |
115 | strcat(tp, "6o |"); | |
116 | printf(tp, INT); | |
117 | strcpy(tp, prefix); | |
118 | strcat(tp, "6x |"); | |
119 | printf(tp, INT); | |
120 | strcpy(tp, prefix); | |
121 | strcat(tp, "6X |"); | |
122 | printf(tp, INT); | |
123 | strcpy(tp, prefix); | |
124 | strcat(tp, "6u |"); | |
125 | printf(tp, UNS); | |
126 | printf("\n"); | |
127 | } | |
128 | } | |
129 | } | |
130 | } | |
131 | printf("%10s\n", (char *) NULL); | |
132 | printf("%-10s\n", (char *) NULL); | |
133 | } | |
134 | \f | |
135 | int | |
11336c16 | 136 | main (int argc, char *argv[]) |
28f540f4 RM |
137 | { |
138 | static char shortstr[] = "Hi, Z."; | |
139 | static char longstr[] = "Good morning, Doctor Chandra. This is Hal. \ | |
140 | I am ready for my first lesson today."; | |
31c46cf5 | 141 | int result = 0; |
28f540f4 RM |
142 | |
143 | fmtchk("%.4x"); | |
144 | fmtchk("%04x"); | |
145 | fmtchk("%4.4x"); | |
146 | fmtchk("%04.4x"); | |
147 | fmtchk("%4.3x"); | |
148 | fmtchk("%04.3x"); | |
149 | ||
150 | fmtst1chk("%.*x"); | |
151 | fmtst1chk("%0*x"); | |
152 | fmtst2chk("%*.*x"); | |
153 | fmtst2chk("%0*.*x"); | |
154 | ||
155 | #ifndef BSD | |
ceeeaa3d | 156 | printf("bad format:\t\"%b\"\n"); |
1f64ac13 | 157 | printf("nil pointer (padded):\t\"%10p\"\n", (void *) NULL); |
28f540f4 RM |
158 | #endif |
159 | ||
160 | printf("decimal negative:\t\"%d\"\n", -2345); | |
161 | printf("octal negative:\t\"%o\"\n", -2345); | |
162 | printf("hex negative:\t\"%x\"\n", -2345); | |
163 | printf("long decimal number:\t\"%ld\"\n", -123456L); | |
164 | printf("long octal negative:\t\"%lo\"\n", -2345L); | |
165 | printf("long unsigned decimal number:\t\"%lu\"\n", -123456L); | |
166 | printf("zero-padded LDN:\t\"%010ld\"\n", -123456L); | |
75bfdfc7 | 167 | printf("left-adjusted ZLDN:\t\"%-010ld\"\n", -123456L); |
28f540f4 RM |
168 | printf("space-padded LDN:\t\"%10ld\"\n", -123456L); |
169 | printf("left-adjusted SLDN:\t\"%-10ld\"\n", -123456L); | |
170 | ||
171 | printf("zero-padded string:\t\"%010s\"\n", shortstr); | |
172 | printf("left-adjusted Z string:\t\"%-010s\"\n", shortstr); | |
173 | printf("space-padded string:\t\"%10s\"\n", shortstr); | |
174 | printf("left-adjusted S string:\t\"%-10s\"\n", shortstr); | |
175 | printf("null string:\t\"%s\"\n", (char *)NULL); | |
176 | printf("limited string:\t\"%.22s\"\n", longstr); | |
177 | ||
178 | printf("e-style >= 1:\t\"%e\"\n", 12.34); | |
179 | printf("e-style >= .1:\t\"%e\"\n", 0.1234); | |
180 | printf("e-style < .1:\t\"%e\"\n", 0.001234); | |
181 | printf("e-style big:\t\"%.60e\"\n", 1e20); | |
182 | printf ("e-style == .1:\t\"%e\"\n", 0.1); | |
183 | printf("f-style >= 1:\t\"%f\"\n", 12.34); | |
184 | printf("f-style >= .1:\t\"%f\"\n", 0.1234); | |
185 | printf("f-style < .1:\t\"%f\"\n", 0.001234); | |
186 | printf("g-style >= 1:\t\"%g\"\n", 12.34); | |
187 | printf("g-style >= .1:\t\"%g\"\n", 0.1234); | |
188 | printf("g-style < .1:\t\"%g\"\n", 0.001234); | |
189 | printf("g-style big:\t\"%.60g\"\n", 1e20); | |
190 | ||
191 | printf (" %6.5f\n", .099999999860301614); | |
192 | printf (" %6.5f\n", .1); | |
193 | printf ("x%5.4fx\n", .5); | |
194 | ||
195 | printf ("%#03x\n", 1); | |
196 | ||
1a6d7967 | 197 | printf ("something really insane: %.10000f\n", 1.0); |
a0e5d73a | 198 | |
28f540f4 RM |
199 | { |
200 | double d = FLT_MIN; | |
201 | int niter = 17; | |
299a95b9 | 202 | |
28f540f4 RM |
203 | while (niter-- != 0) |
204 | printf ("%.17e\n", d / 2); | |
205 | fflush (stdout); | |
206 | } | |
207 | ||
208 | printf ("%15.5e\n", 4.9406564584124654e-324); | |
209 | ||
210 | #define FORMAT "|%12.4f|%12.4e|%12.4g|\n" | |
211 | printf (FORMAT, 0.0, 0.0, 0.0); | |
212 | printf (FORMAT, 1.0, 1.0, 1.0); | |
213 | printf (FORMAT, -1.0, -1.0, -1.0); | |
214 | printf (FORMAT, 100.0, 100.0, 100.0); | |
215 | printf (FORMAT, 1000.0, 1000.0, 1000.0); | |
216 | printf (FORMAT, 10000.0, 10000.0, 10000.0); | |
217 | printf (FORMAT, 12345.0, 12345.0, 12345.0); | |
218 | printf (FORMAT, 100000.0, 100000.0, 100000.0); | |
219 | printf (FORMAT, 123456.0, 123456.0, 123456.0); | |
220 | #undef FORMAT | |
221 | ||
222 | { | |
223 | char buf[20]; | |
a1648746 | 224 | char buf2[512]; |
28f540f4 | 225 | printf ("snprintf (\"%%30s\", \"foo\") == %d, \"%.*s\"\n", |
75bfdfc7 UD |
226 | snprintf (buf, sizeof (buf), "%30s", "foo"), (int) sizeof (buf), |
227 | buf); | |
228 | printf ("snprintf (\"%%.999999u\", 10) == %d\n", | |
a1648746 | 229 | snprintf(buf2, sizeof(buf2), "%.999999u", 10)); |
28f540f4 RM |
230 | } |
231 | ||
232 | fp_test (); | |
233 | ||
234 | printf ("%e should be 1.234568e+06\n", 1234567.8); | |
235 | printf ("%f should be 1234567.800000\n", 1234567.8); | |
236 | printf ("%g should be 1.23457e+06\n", 1234567.8); | |
237 | printf ("%g should be 123.456\n", 123.456); | |
238 | printf ("%g should be 1e+06\n", 1000000.0); | |
239 | printf ("%g should be 10\n", 10.0); | |
240 | printf ("%g should be 0.02\n", 0.02); | |
241 | ||
c06b947e UD |
242 | #if 0 |
243 | /* This test rather checks the way the compiler handles constant | |
244 | folding. gcc behavior wrt to this changed in 3.2 so it is not a | |
245 | portable test. */ | |
28f540f4 RM |
246 | { |
247 | double x=1.0; | |
248 | printf("%.17f\n",(1.0/x/10.0+1.0)*x-x); | |
249 | } | |
c06b947e | 250 | #endif |
28f540f4 | 251 | |
299a95b9 RM |
252 | { |
253 | char buf[200]; | |
299a95b9 RM |
254 | |
255 | sprintf(buf,"%*s%*s%*s",-1,"one",-20,"two",-30,"three"); | |
256 | ||
31c46cf5 UD |
257 | result |= strcmp (buf, |
258 | "onetwo three "); | |
299a95b9 RM |
259 | |
260 | puts (result != 0 ? "Test failed!" : "Test ok."); | |
299a95b9 | 261 | } |
31c46cf5 UD |
262 | |
263 | { | |
264 | char buf[200]; | |
265 | ||
266 | sprintf (buf, "%07Lo", 040000000000ll); | |
0755050e | 267 | printf ("sprintf (buf, \"%%07Lo\", 040000000000ll) = %s", buf); |
31c46cf5 UD |
268 | |
269 | if (strcmp (buf, "40000000000") != 0) | |
270 | { | |
271 | result = 1; | |
272 | fputs ("\tFAILED", stdout); | |
273 | } | |
274 | puts (""); | |
275 | } | |
276 | ||
b3f7c665 UD |
277 | printf ("printf (\"%%hhu\", %u) = %hhu\n", UCHAR_MAX + 2, UCHAR_MAX + 2); |
278 | printf ("printf (\"%%hu\", %u) = %hu\n", USHRT_MAX + 2, USHRT_MAX + 2); | |
d2dc7b08 UD |
279 | printf ("printf (\"%%hhi\", %i) = %hhi\n", UCHAR_MAX + 2, UCHAR_MAX + 2); |
280 | printf ("printf (\"%%hi\", %i) = %hi\n", USHRT_MAX + 2, USHRT_MAX + 2); | |
281 | ||
282 | printf ("printf (\"%%1$hhu\", %2$u) = %1$hhu\n", | |
283 | UCHAR_MAX + 2, UCHAR_MAX + 2); | |
284 | printf ("printf (\"%%1$hu\", %2$u) = %1$hu\n", USHRT_MAX + 2, USHRT_MAX + 2); | |
285 | printf ("printf (\"%%1$hhi\", %2$i) = %1$hhi\n", | |
286 | UCHAR_MAX + 2, UCHAR_MAX + 2); | |
287 | printf ("printf (\"%%1$hi\", %2$i) = %1$hi\n", USHRT_MAX + 2, USHRT_MAX + 2); | |
b3f7c665 | 288 | |
0755050e UD |
289 | puts ("--- Should be no further output. ---"); |
290 | rfg1 (); | |
291 | rfg2 (); | |
75bfdfc7 | 292 | rfg3 (); |
0755050e | 293 | |
b3f7c665 UD |
294 | { |
295 | char bytes[7]; | |
296 | char buf[20]; | |
297 | ||
298 | memset (bytes, '\xff', sizeof bytes); | |
299 | sprintf (buf, "foo%hhn\n", &bytes[3]); | |
300 | if (bytes[0] != '\xff' || bytes[1] != '\xff' || bytes[2] != '\xff' | |
301 | || bytes[4] != '\xff' || bytes[5] != '\xff' || bytes[6] != '\xff') | |
302 | { | |
303 | puts ("%hhn overwrite more bytes"); | |
304 | result = 1; | |
305 | } | |
306 | if (bytes[3] != 3) | |
307 | { | |
308 | puts ("%hhn wrote incorrect value"); | |
309 | result = 1; | |
310 | } | |
311 | } | |
312 | ||
31c46cf5 | 313 | return result != 0; |
28f540f4 RM |
314 | } |
315 | \f | |
1a511d31 | 316 | static void |
11336c16 | 317 | rfg1 (void) |
28f540f4 RM |
318 | { |
319 | char buf[100]; | |
320 | ||
321 | sprintf (buf, "%5.s", "xyz"); | |
322 | if (strcmp (buf, " ") != 0) | |
323 | printf ("got: '%s', expected: '%s'\n", buf, " "); | |
324 | sprintf (buf, "%5.f", 33.3); | |
325 | if (strcmp (buf, " 33") != 0) | |
326 | printf ("got: '%s', expected: '%s'\n", buf, " 33"); | |
327 | sprintf (buf, "%8.e", 33.3e7); | |
328 | if (strcmp (buf, " 3e+08") != 0) | |
329 | printf ("got: '%s', expected: '%s'\n", buf, " 3e+08"); | |
330 | sprintf (buf, "%8.E", 33.3e7); | |
331 | if (strcmp (buf, " 3E+08") != 0) | |
332 | printf ("got: '%s', expected: '%s'\n", buf, " 3E+08"); | |
333 | sprintf (buf, "%.g", 33.3); | |
334 | if (strcmp (buf, "3e+01") != 0) | |
335 | printf ("got: '%s', expected: '%s'\n", buf, "3e+01"); | |
336 | sprintf (buf, "%.G", 33.3); | |
337 | if (strcmp (buf, "3E+01") != 0) | |
338 | printf ("got: '%s', expected: '%s'\n", buf, "3E+01"); | |
28f540f4 RM |
339 | } |
340 | ||
1a511d31 | 341 | static void |
11336c16 | 342 | rfg2 (void) |
28f540f4 RM |
343 | { |
344 | int prec; | |
345 | char buf[100]; | |
346 | ||
347 | prec = 0; | |
348 | sprintf (buf, "%.*g", prec, 3.3); | |
349 | if (strcmp (buf, "3") != 0) | |
350 | printf ("got: '%s', expected: '%s'\n", buf, "3"); | |
351 | prec = 0; | |
352 | sprintf (buf, "%.*G", prec, 3.3); | |
353 | if (strcmp (buf, "3") != 0) | |
354 | printf ("got: '%s', expected: '%s'\n", buf, "3"); | |
355 | prec = 0; | |
356 | sprintf (buf, "%7.*G", prec, 3.33); | |
357 | if (strcmp (buf, " 3") != 0) | |
358 | printf ("got: '%s', expected: '%s'\n", buf, " 3"); | |
359 | prec = 3; | |
360 | sprintf (buf, "%04.*o", prec, 33); | |
361 | if (strcmp (buf, " 041") != 0) | |
362 | printf ("got: '%s', expected: '%s'\n", buf, " 041"); | |
363 | prec = 7; | |
364 | sprintf (buf, "%09.*u", prec, 33); | |
365 | if (strcmp (buf, " 0000033") != 0) | |
366 | printf ("got: '%s', expected: '%s'\n", buf, " 0000033"); | |
367 | prec = 3; | |
368 | sprintf (buf, "%04.*x", prec, 33); | |
369 | if (strcmp (buf, " 021") != 0) | |
370 | printf ("got: '%s', expected: '%s'\n", buf, " 021"); | |
371 | prec = 3; | |
372 | sprintf (buf, "%04.*X", prec, 33); | |
373 | if (strcmp (buf, " 021") != 0) | |
374 | printf ("got: '%s', expected: '%s'\n", buf, " 021"); | |
28f540f4 | 375 | } |
75bfdfc7 UD |
376 | |
377 | static void | |
378 | rfg3 (void) | |
379 | { | |
380 | char buf[100]; | |
381 | double g = 5.0000001; | |
382 | unsigned long l = 1234567890; | |
383 | double d = 321.7654321; | |
c06b947e | 384 | const char s[] = "test-string"; |
75bfdfc7 UD |
385 | int i = 12345; |
386 | int h = 1234; | |
387 | ||
388 | sprintf (buf, | |
389 | "%1$*5$d %2$*6$hi %3$*7$lo %4$*8$f %9$*12$e %10$*13$g %11$*14$s", | |
390 | i, h, l, d, 8, 5, 14, 14, d, g, s, 14, 3, 14); | |
391 | if (strcmp (buf, | |
392 | " 12345 1234 11145401322 321.765432 3.217654e+02 5 test-string") != 0) | |
393 | printf ("got: '%s', expected: '%s'\n", buf, | |
394 | " 12345 1234 11145401322 321.765432 3.217654e+02 5 test-string"); | |
395 | } |