Tizen 2.1 base
[platform/upstream/glib2.0.git] / glib / tests / test-printf.c
1 /* Unit tests for gprintf
2  * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * This work is provided "as is"; redistribution and modification
5  * in whole or in part, in any medium, physical or electronic is
6  * permitted without restriction.
7  *
8  * This work is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11  *
12  * In no event shall the authors or contributors be liable for any
13  * direct, indirect, incidental, special, exemplary, or consequential
14  * damages (including, but not limited to, procurement of substitute
15  * goods or services; loss of use, data, or profits; or business
16  * interruption) however caused and on any theory of liability, whether
17  * in contract, strict liability, or tort (including negligence or
18  * otherwise) arising in any way out of the use of this software, even
19  * if advised of the possibility of such damage.
20  */
21
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <string.h>
25 #include "glib.h"
26 #include "gstdio.h"
27
28 static void
29 test_retval_and_trunc (void)
30 {
31   gchar buf[128];
32   gint res;
33
34   res = g_snprintf (buf, 0, "abc");
35   g_assert_cmpint (res, ==, 3);
36
37   res = g_snprintf (NULL, 0, "abc");
38   g_assert_cmpint (res, ==, 3);
39
40   res = g_snprintf (buf, 5, "abc");
41   g_assert_cmpint (res, ==, 3);
42
43   res = g_snprintf (buf, 1, "abc");
44   g_assert_cmpint (res, ==, 3);
45   g_assert (buf[0] == '\0');
46   g_assert_cmpstr (buf, ==, "");
47
48   res = g_snprintf (buf, 2, "abc");
49   g_assert_cmpint (res, ==, 3);
50   g_assert (buf[1] == '\0');
51   g_assert_cmpstr (buf, ==, "a");
52
53   res = g_snprintf (buf, 3, "abc");
54   g_assert_cmpint (res, ==, 3);
55   g_assert (buf[2] == '\0');
56   g_assert_cmpstr (buf, ==, "ab");
57
58   res = g_snprintf (buf, 4, "abc");
59   g_assert_cmpint (res, ==, 3);
60   g_assert (buf[3] == '\0');
61   g_assert_cmpstr (buf, ==, "abc");
62
63   res = g_snprintf (buf, 5, "abc");
64   g_assert_cmpint (res, ==, 3);
65   g_assert (buf[3] == '\0');
66   g_assert_cmpstr (buf, ==, "abc");
67 }
68
69 static void
70 test_d (void)
71 {
72   gchar buf[128];
73   gint res;
74   const gchar *fmt;
75
76   /* %d basic formatting */
77
78   res = g_snprintf (buf, 128, "%d", 5);
79   g_assert_cmpint (res, ==, 1);
80   g_assert_cmpstr (buf, ==, "5");
81
82   res = g_snprintf (buf, 128, "%d", 0);
83   g_assert_cmpint (res, ==, 1);
84   g_assert_cmpstr (buf, ==, "0");
85
86   res = g_snprintf (buf, 128, "%.0d", 0);
87   g_assert_cmpint (res, ==, 0);
88   g_assert_cmpstr (buf, ==, "");
89
90   res = g_snprintf (buf, 128, "%.0d", 1);
91   g_assert_cmpint (res, ==, 1);
92   g_assert_cmpstr (buf, ==, "1");
93
94   res = g_snprintf (buf, 128, "%.d", 2);
95   g_assert_cmpint (res, ==, 1);
96   g_assert_cmpstr (buf, ==, "2");
97
98   res = g_snprintf (buf, 128, "%d", -1);
99   g_assert_cmpint (res, ==, 2);
100   g_assert_cmpstr (buf, ==, "-1");
101
102   res = g_snprintf (buf, 128, "%.3d", 5);
103   g_assert_cmpint (res, ==, 3);
104   g_assert_cmpstr (buf, ==, "005");
105
106   res = g_snprintf (buf, 128, "%.3d", -5);
107   g_assert_cmpint (res, ==, 4);
108   g_assert_cmpstr (buf, ==, "-005");
109
110   res = g_snprintf (buf, 128, "%5.3d", 5);
111   g_assert_cmpint (res, ==, 5);
112   g_assert_cmpstr (buf, ==, "  005");
113
114   res = g_snprintf (buf, 128, "%-5.3d", -5);
115   g_assert_cmpint (res, ==, 5);
116   g_assert_cmpstr (buf, ==, "-005 ");
117
118   /* %d, length modifiers */
119
120   res = g_snprintf (buf, 128, "%" G_GINT16_FORMAT, (gint16)-5);
121   g_assert_cmpint (res, ==, 2);
122   g_assert_cmpstr (buf, ==, "-5");
123
124   res = g_snprintf (buf, 128, "%" G_GUINT16_FORMAT, (guint16)5);
125   g_assert_cmpint (res, ==, 1);
126   g_assert_cmpstr (buf, ==, "5");
127
128   res = g_snprintf (buf, 128, "%" G_GINT32_FORMAT, (gint32)-5);
129   g_assert_cmpint (res, ==, 2);
130   g_assert_cmpstr (buf, ==, "-5");
131
132   res = g_snprintf (buf, 128, "%" G_GUINT32_FORMAT, (guint32)5);
133   g_assert_cmpint (res, ==, 1);
134   g_assert_cmpstr (buf, ==, "5");
135
136   res = g_snprintf (buf, 128, "%" G_GINT64_FORMAT, (gint64)-5);
137   g_assert_cmpint (res, ==, 2);
138   g_assert_cmpstr (buf, ==, "-5");
139
140   res = g_snprintf (buf, 128, "%" G_GUINT64_FORMAT, (guint64)5);
141   g_assert_cmpint (res, ==, 1);
142   g_assert_cmpstr (buf, ==, "5");
143
144   res = g_snprintf (buf, 128, "%" G_GSSIZE_FORMAT, (gssize)-5);
145   g_assert_cmpint (res, ==, 2);
146   g_assert_cmpstr (buf, ==, "-5");
147
148   res = g_snprintf (buf, 128, "%" G_GSIZE_FORMAT, (gsize)5);
149   g_assert_cmpint (res, ==, 1);
150   g_assert_cmpstr (buf, ==, "5");
151
152   /* %d, flags */
153
154   res = g_snprintf (buf, 128, "%-d", 5);
155   g_assert_cmpint (res, ==, 1);
156   g_assert_cmpstr (buf, ==, "5");
157
158   res = g_snprintf (buf, 128, "%-+d", 5);
159   g_assert_cmpint (res, ==, 2);
160   g_assert_cmpstr (buf, ==, "+5");
161
162   res = g_snprintf (buf, 128, "%+-d", 5);
163   g_assert_cmpint (res, ==, 2);
164   g_assert_cmpstr (buf, ==, "+5");
165
166   res = g_snprintf (buf, 128, "%+d", -5);
167   g_assert_cmpint (res, ==, 2);
168   g_assert_cmpstr (buf, ==, "-5");
169
170   res = g_snprintf (buf, 128, "% d", 5);
171   g_assert_cmpint (res, ==, 2);
172   g_assert_cmpstr (buf, ==, " 5");
173
174   res = g_snprintf (buf, 128, "% .0d", 0);
175   g_assert_cmpint (res, ==, 1);
176   g_assert_cmpstr (buf, ==, " ");
177
178   res = g_snprintf (buf, 128, "%03d", 5);
179   g_assert_cmpint (res, ==, 3);
180   g_assert_cmpstr (buf, ==, "005");
181
182   res = g_snprintf (buf, 128, "%03d", -5);
183   g_assert_cmpint (res, ==, 3);
184   g_assert_cmpstr (buf, ==, "-05");
185
186   /* gcc emits warnings for the following formats, since the C spec
187    * says some of the flags must be ignored. (The " " in "% +d" and
188    * the "0" in "%-03d".) But we need to test that our printf gets
189    * those rules right. So we fool gcc into not warning.
190    */
191   fmt = "% +d";
192   res = g_snprintf (buf, 128, fmt, 5);
193   g_assert_cmpint (res, ==, 2);
194   g_assert_cmpstr (buf, ==, "+5");
195
196   fmt = "%-03d";
197   res = g_snprintf (buf, 128, fmt, -5);
198   g_assert_cmpint (res, ==, 3);
199   g_assert_cmpstr (buf, ==, "-5 ");
200 }
201
202 static void
203 test_o (void)
204 {
205   gchar buf[128];
206   gint res;
207
208   /* %o basic formatting */
209
210   res = g_snprintf (buf, 128, "%o", 5);
211   g_assert_cmpint (res, ==, 1);
212   g_assert_cmpstr (buf, ==, "5");
213
214   res = g_snprintf (buf, 128, "%o", 8);
215   g_assert_cmpint (res, ==, 2);
216   g_assert_cmpstr (buf, ==, "10");
217
218   res = g_snprintf (buf, 128, "%o", 0);
219   g_assert_cmpint (res, ==, 1);
220   g_assert_cmpstr (buf, ==, "0");
221
222   res = g_snprintf (buf, 128, "%.0o", 0);
223   g_assert_cmpint (res, ==, 0);
224   g_assert_cmpstr (buf, ==, "");
225
226   res = g_snprintf (buf, 128, "%.0o", 1);
227   g_assert_cmpint (res, ==, 1);
228   g_assert_cmpstr (buf, ==, "1");
229
230   res = g_snprintf (buf, 128, "%.3o", 5);
231   g_assert_cmpint (res, ==, 3);
232   g_assert_cmpstr (buf, ==, "005");
233
234   res = g_snprintf (buf, 128, "%.3o", 8);
235   g_assert_cmpint (res, ==, 3);
236   g_assert_cmpstr (buf, ==, "010");
237
238   res = g_snprintf (buf, 128, "%5.3o", 5);
239   g_assert_cmpint (res, ==, 5);
240   g_assert_cmpstr (buf, ==, "  005");
241 }
242
243 static void
244 test_u (void)
245 {
246   gchar buf[128];
247   gint res;
248
249   /* %u, basic formatting */
250
251   res = g_snprintf (buf, 128, "%u", 5);
252   g_assert_cmpint (res, ==, 1);
253   g_assert_cmpstr (buf, ==, "5");
254
255   res = g_snprintf (buf, 128, "%u", 0);
256   g_assert_cmpint (res, ==, 1);
257   g_assert_cmpstr (buf, ==, "0");
258
259   res = g_snprintf (buf, 128, "%.0u", 0);
260   g_assert_cmpint (res, ==, 0);
261   g_assert_cmpstr (buf, ==, "");
262
263   res = g_snprintf (buf, 128, "%.0u", 1);
264   g_assert_cmpint (res, ==, 1);
265   g_assert_cmpstr (buf, ==, "1");
266
267   res = g_snprintf (buf, 128, "%.3u", 5);
268   g_assert_cmpint (res, ==, 3);
269   g_assert_cmpstr (buf, ==, "005");
270
271   res = g_snprintf (buf, 128, "%5.3u", 5);
272   g_assert_cmpint (res, ==, 5);
273   g_assert_cmpstr (buf, ==, "  005");
274 }
275
276 static void
277 test_x (void)
278 {
279   gchar buf[128];
280   gint res;
281
282   /* %x, basic formatting */
283
284   res = g_snprintf (buf, 128, "%x", 5);
285   g_assert_cmpint (res, ==, 1);
286   g_assert_cmpstr (buf, ==, "5");
287
288   res = g_snprintf (buf, 128, "%x", 31);
289   g_assert_cmpint (res, ==, 2);
290   g_assert_cmpstr (buf, ==, "1f");
291
292   res = g_snprintf (buf, 128, "%x", 0);
293   g_assert_cmpint (res, ==, 1);
294   g_assert_cmpstr (buf, ==, "0");
295
296   res = g_snprintf (buf, 128, "%.0x", 0);
297   g_assert_cmpint (res, ==, 0);
298   g_assert_cmpstr (buf, ==, "");
299
300   res = g_snprintf (buf, 128, "%.0x", 1);
301   g_assert_cmpint (res, ==, 1);
302   g_assert_cmpstr (buf, ==, "1");
303
304   res = g_snprintf (buf, 128, "%.3x", 5);
305   g_assert_cmpint (res, ==, 3);
306   g_assert_cmpstr (buf, ==, "005");
307
308   res = g_snprintf (buf, 128, "%.3x", 31);
309   g_assert_cmpint (res, ==, 3);
310   g_assert_cmpstr (buf, ==, "01f");
311
312   res = g_snprintf (buf, 128, "%5.3x", 5);
313   g_assert_cmpint (res, ==, 5);
314   g_assert_cmpstr (buf, ==, "  005");
315
316   /* %x, flags */
317
318   res = g_snprintf (buf, 128, "%-x", 5);
319   g_assert_cmpint (res, ==, 1);
320   g_assert_cmpstr (buf, ==, "5");
321
322   res = g_snprintf (buf, 128, "%03x", 5);
323   g_assert_cmpint (res, ==, 3);
324   g_assert_cmpstr (buf, ==, "005");
325
326   res = g_snprintf (buf, 128, "%#x", 31);
327   g_assert_cmpint (res, ==, 4);
328   g_assert_cmpstr (buf, ==, "0x1f");
329
330   res = g_snprintf (buf, 128, "%#x", 0);
331   g_assert_cmpint (res, ==, 1);
332   g_assert_cmpstr (buf, ==, "0");
333 }
334
335 static void
336 test_X (void)
337 {
338   gchar buf[128];
339   gint res;
340
341   /* %X, basic formatting */
342
343   res = g_snprintf (buf, 128, "%X", 5);
344   g_assert_cmpint (res, ==, 1);
345   g_assert_cmpstr (buf, ==, "5");
346
347   res = g_snprintf (buf, 128, "%X", 31);
348   g_assert_cmpint (res, ==, 2);
349   g_assert_cmpstr (buf, ==, "1F");
350
351   res = g_snprintf (buf, 128, "%X", 0);
352   g_assert_cmpint (res, ==, 1);
353   g_assert_cmpstr (buf, ==, "0");
354
355   res = g_snprintf (buf, 128, "%.0X", 0);
356   g_assert_cmpint (res, ==, 0);
357   g_assert_cmpstr (buf, ==, "");
358
359   res = g_snprintf (buf, 128, "%.0X", 1);
360   g_assert_cmpint (res, ==, 1);
361   g_assert_cmpstr (buf, ==, "1");
362
363   res = g_snprintf (buf, 128, "%.3X", 5);
364   g_assert_cmpint (res, ==, 3);
365   g_assert_cmpstr (buf, ==, "005");
366
367   res = g_snprintf (buf, 128, "%.3X", 31);
368   g_assert_cmpint (res, ==, 3);
369   g_assert_cmpstr (buf, ==, "01F");
370
371   res = g_snprintf (buf, 128, "%5.3X", 5);
372   g_assert_cmpint (res, ==, 5);
373   g_assert_cmpstr (buf, ==, "  005");
374
375   /* %X, flags */
376
377   res = g_snprintf (buf, 128, "%-X", 5);
378   g_assert_cmpint (res, ==, 1);
379   g_assert_cmpstr (buf, ==, "5");
380
381   res = g_snprintf (buf, 128, "%03X", 5);
382   g_assert_cmpint (res, ==, 3);
383   g_assert_cmpstr (buf, ==, "005");
384
385   res = g_snprintf (buf, 128, "%#X", 31);
386   g_assert_cmpint (res, ==, 4);
387   g_assert_cmpstr (buf, ==, "0X1F");
388
389   res = g_snprintf (buf, 128, "%#X", 0);
390   g_assert_cmpint (res, ==, 1);
391   g_assert_cmpstr (buf, ==, "0");
392 }
393
394 static void
395 test_f (void)
396 {
397   gchar buf[128];
398   gint res;
399
400   /* %f, basic formattting */
401
402   res = g_snprintf (buf, 128, "%f", G_PI);
403   g_assert_cmpint (res, ==, 8);
404   g_assert (0 == strncmp (buf, "3.14159", 7));
405
406   res = g_snprintf (buf, 128, "%.8f", G_PI);
407   g_assert_cmpint (res, ==, 10);
408   g_assert (0 == strncmp (buf, "3.1415926", 9));
409
410   res = g_snprintf (buf, 128, "%.0f", G_PI);
411   g_assert_cmpint (res, ==, 1);
412   g_assert_cmpstr (buf, ==, "3");
413
414   res = g_snprintf (buf, 128, "%1.f", G_PI);
415   g_assert_cmpint (res, ==, 1);
416   g_assert_cmpstr (buf, ==, "3");
417
418   res = g_snprintf (buf, 128, "%3.f", G_PI);
419   g_assert_cmpint (res, ==, 3);
420   g_assert_cmpstr (buf, ==, "  3");
421
422   /* %f, flags */
423
424   res = g_snprintf (buf, 128, "%+f", G_PI);
425   g_assert_cmpint (res, ==, 9);
426   g_assert (0 == strncmp (buf, "+3.14159", 8));
427
428   res = g_snprintf (buf, 128, "% f", G_PI);
429   g_assert_cmpint (res, ==, 9);
430   g_assert (0 == strncmp (buf, " 3.14159", 8));
431
432   res = g_snprintf (buf, 128, "%#.0f", G_PI);
433   g_assert_cmpint (res, ==, 2);
434   g_assert_cmpstr (buf, ==, "3.");
435
436   res = g_snprintf (buf, 128, "%05.2f", G_PI);
437   g_assert_cmpint (res, ==, 5);
438   g_assert_cmpstr (buf, ==, "03.14");
439 }
440
441 static gboolean
442 same_value (const gchar *actual, 
443             const gchar *expected)
444 {
445   gdouble actual_value, expected_value;
446
447   actual_value = g_ascii_strtod (actual, NULL);
448   expected_value = g_ascii_strtod (expected, NULL);
449
450   return actual_value == expected_value;
451 }
452
453 static void
454 test_e (void)
455 {
456   gchar buf[128];
457   gint res;
458
459   /* %e, basic formatting */
460   /* for %e we can't expect to reproduce exact strings and lengths, since SUS
461    * only guarantees that the exponent shall always contain at least two 
462    * digits. On Windows, it seems to be at least three digits long.
463    * Therefore, we compare the results of parsing the expected result and the
464    * actual result.
465    */
466
467   res = g_snprintf (buf, 128, "%e", G_PI);
468   g_assert_cmpint (res, >=, 12);
469   g_assert (same_value (buf, "3.141593e+00"));
470
471   res = g_snprintf (buf, 128, "%.8e", G_PI);
472   g_assert_cmpint (res, >=, 14);
473   g_assert (same_value (buf, "3.14159265e+00"));
474
475   res = g_snprintf (buf, 128, "%.0e", G_PI);
476   g_assert_cmpint (res, >=, 5);
477   g_assert (same_value (buf, "3e+00"));
478
479   res = g_snprintf (buf, 128, "%.1e", 0.0);
480   g_assert_cmpint (res, >=, 7);
481   g_assert (same_value (buf, "0.0e+00"));
482
483   res = g_snprintf (buf, 128, "%.1e", 0.00001);
484   g_assert_cmpint (res, >=, 7);
485   g_assert (same_value (buf, "1.0e-05"));
486
487   res = g_snprintf (buf, 128, "%.1e", 10000.0);
488   g_assert_cmpint (res, >=, 7);
489   g_assert (same_value (buf, "1.0e+04"));
490
491   /* %e, flags */
492
493   res = g_snprintf (buf, 128, "%+e", G_PI);
494   g_assert_cmpint (res, >=, 13);
495   g_assert (same_value (buf, "+3.141593e+00"));
496
497   res = g_snprintf (buf, 128, "% e", G_PI);
498   g_assert_cmpint (res, >=, 13);
499   g_assert (same_value (buf, " 3.141593e+00"));
500
501   res = g_snprintf (buf, 128, "%#.0e", G_PI);
502   g_assert_cmpint (res, >=, 6);
503   g_assert (same_value (buf, "3.e+00"));
504
505   res = g_snprintf (buf, 128, "%09.2e", G_PI);
506   g_assert_cmpint (res, >=, 9);
507   g_assert (same_value (buf, "03.14e+00"));
508 }
509
510 static void
511 test_c (void)
512 {
513   gchar buf[128];
514   gint res;
515
516   res = g_snprintf (buf, 128, "%c", 'a');
517   g_assert_cmpint (res, ==, 1);
518   g_assert_cmpstr (buf, ==, "a");
519 }
520
521 static void
522 test_s (void)
523 {
524   gchar buf[128];
525   gint res;
526
527   res = g_snprintf (buf, 128, "%.2s", "abc");
528   g_assert_cmpint (res, ==, 2);
529   g_assert_cmpstr (buf, ==, "ab");
530
531   res = g_snprintf (buf, 128, "%.6s", "abc");
532   g_assert_cmpint (res, ==, 3);
533   g_assert_cmpstr (buf, ==, "abc");
534
535   res = g_snprintf (buf, 128, "%5s", "abc");
536   g_assert_cmpint (res, ==, 5);
537   g_assert_cmpstr (buf, ==, "  abc");
538
539   res = g_snprintf (buf, 128, "%-5s", "abc");
540   g_assert_cmpint (res, ==, 5);
541   g_assert_cmpstr (buf, ==, "abc  ");
542
543   res = g_snprintf (buf, 128, "%5.2s", "abc");
544   g_assert_cmpint (res, ==, 5);
545   g_assert_cmpstr (buf, ==, "   ab");
546
547   res = g_snprintf (buf, 128, "%*s", 5, "abc");
548   g_assert_cmpint (res, ==, 5);
549   g_assert_cmpstr (buf, ==, "  abc");
550
551 #if 0 /* HP-UX doesn't get this right */
552   res = g_snprintf (buf, 128, "%*s", -5, "abc");
553   g_assert_cmpint (res, ==, 5);
554   g_assert_cmpstr (buf, ==, "abc  ");
555 #endif
556
557   res = g_snprintf (buf, 128, "%*.*s", 5, 2, "abc");
558   g_assert_cmpint (res, ==, 5);
559   g_assert_cmpstr (buf, ==, "   ab");
560 }
561
562 static void
563 test_n (void)
564 {
565   gchar buf[128];
566   gint res;
567   gint i;
568   glong l;
569
570   res = g_snprintf (buf, 128, "abc%n", &i);
571   g_assert_cmpint (res, ==, 3);
572   g_assert_cmpstr (buf, ==, "abc");
573   g_assert_cmpint (i, ==, 3);
574
575   res = g_snprintf (buf, 128, "abc%ln", &l);
576   g_assert_cmpint (res, ==, 3);
577   g_assert_cmpstr (buf, ==, "abc");
578   g_assert_cmpint (l, ==, 3);
579 }
580
581 static void
582 test_percent (void)
583 {
584   gchar buf[128];
585   gint res;
586
587   res = g_snprintf (buf, 128, "%%");
588   g_assert_cmpint (res, ==, 1);
589   g_assert_cmpstr (buf, ==, "%");
590 }
591
592 static void
593 test_positional_params (void)
594 {
595   gchar buf[128];
596   gint res;
597
598   res = g_snprintf (buf, 128, "%2$c %1$c", 'b', 'a');
599   g_assert_cmpint (res, ==, 3);
600   g_assert_cmpstr (buf, ==, "a b");
601
602   res = g_snprintf (buf, 128, "%1$*2$.*3$s", "abc", 5, 2);
603   g_assert_cmpint (res, ==, 5);
604   g_assert_cmpstr (buf, ==, "   ab");
605
606   res = g_snprintf (buf, 128, "%1$s%1$s", "abc");
607   g_assert_cmpint (res, ==, 6);
608   g_assert_cmpstr (buf, ==, "abcabc");
609 }
610
611 static void
612 test_positional_params2 (void)
613 {
614   gint res;
615
616   if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT))
617     {
618       res = g_printf ("%2$c %1$c", 'b', 'a');
619       g_assert_cmpint (res, ==, 3);
620       exit (0);
621     }
622   g_test_trap_assert_passed ();
623   g_test_trap_assert_stdout ("*a b*");
624
625   if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT))
626     {
627       res = g_printf ("%1$*2$.*3$s", "abc", 5, 2);
628       g_assert_cmpint (res, ==, 5);
629       exit (0);
630     }
631   g_test_trap_assert_passed ();
632   g_test_trap_assert_stdout ("*   ab*");
633
634   if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT))
635     {
636       res = g_printf ("%1$s%1$s", "abc");
637       g_assert_cmpint (res, ==, 6);
638       exit (0);
639     }
640   g_test_trap_assert_passed ();
641   g_test_trap_assert_stdout ("*abcabc*");
642 }
643
644 static void
645 test_positional_params3 (void)
646 {
647   gchar buf[128];
648   gint res;
649
650   res = g_sprintf (buf, "%2$c %1$c", 'b', 'a');
651   g_assert_cmpint (res, ==, 3);
652   g_assert_cmpstr (buf, ==, "a b");
653
654   res = g_sprintf (buf, "%1$*2$.*3$s", "abc", 5, 2);
655   g_assert_cmpint (res, ==, 5);
656   g_assert_cmpstr (buf, ==, "   ab");
657
658   res = g_sprintf (buf, "%1$s%1$s", "abc");
659   g_assert_cmpint (res, ==, 6);
660   g_assert_cmpstr (buf, ==, "abcabc");
661 }
662
663 static void
664 test_percent2 (void)
665 {
666   gint res;
667
668   if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT))
669     {
670       res = g_printf ("%%");
671       g_assert_cmpint (res, ==, 1);
672       exit (0);
673     }
674   g_test_trap_assert_passed ();
675   g_test_trap_assert_stdout ("*%*");
676 }
677
678 static void
679 test_64bit (void)
680 {
681   gchar buf[128];
682   gint res;
683
684   res = g_snprintf (buf, 128, "%" G_GINT64_FORMAT, (gint64)123456);
685   g_assert_cmpint (res, ==, 6);
686   g_assert_cmpstr (buf, ==, "123456");
687
688   res = g_snprintf (buf, 128, "%" G_GINT64_FORMAT, (gint64)-123456);
689   g_assert_cmpint (res, ==, 7);
690   g_assert_cmpstr (buf, ==, "-123456");
691
692   res = g_snprintf (buf, 128, "%" G_GUINT64_FORMAT, (guint64)123456);
693   g_assert_cmpint (res, ==, 6);
694   g_assert_cmpstr (buf, ==, "123456");
695
696   res = g_snprintf (buf, 128, "%" G_GINT64_MODIFIER "o", (gint64)123456);
697   g_assert_cmpint (res, ==, 6);
698   g_assert_cmpstr (buf, ==, "361100");
699
700   res = g_snprintf (buf, 128, "%#" G_GINT64_MODIFIER "o", (gint64)123456);
701   g_assert_cmpint (res, ==, 7);
702   g_assert_cmpstr (buf, ==, "0361100");
703
704   res = g_snprintf (buf, 128, "%" G_GINT64_MODIFIER "x", (gint64)123456);
705   g_assert_cmpint (res, ==, 5);
706   g_assert_cmpstr (buf, ==, "1e240");
707
708   res = g_snprintf (buf, 128, "%#" G_GINT64_MODIFIER "x", (gint64)123456);
709   g_assert_cmpint (res, ==, 7);
710   g_assert_cmpstr (buf, ==, "0x1e240");
711
712   res = g_snprintf (buf, 128, "%" G_GINT64_MODIFIER "X", (gint64)123456);
713   g_assert_cmpint (res, ==, 5);
714   g_assert_cmpstr (buf, ==, "1E240");
715
716 #ifdef G_OS_WIN32
717   /* On Win32, test that the "ll" modifier also works, for backward
718    * compatibility. One really should use the G_GINT64_MODIFIER (which
719    * on Win32 is the "I64" that the (msvcrt) C library's printf uses),
720    * but "ll" used to work with the "trio" g_printf implementation in
721    * GLib 2.2, so it's best if it continues to work.
722    */
723
724   res = g_snprintf (buf, 128, "%" "lli", (gint64)123456);
725   g_assert_cmpint (res, ==, 6);
726   g_assert_cmpstr (buf, ==, "123456");
727
728   res = g_snprintf (buf, 128, "%" "lli", (gint64)-123456);
729   g_assert_cmpint (res, ==, 7);
730   g_assert_cmpstr (buf, ==, "-123456");
731
732   res = g_snprintf (buf, 128, "%" "llu", (guint64)123456);
733   g_assert_cmpint (res, ==, 6);
734   g_assert_cmpstr (buf, ==, "123456");
735
736   res = g_snprintf (buf, 128, "%" "ll" "o", (gint64)123456);
737   g_assert_cmpint (res, ==, 6);
738   g_assert_cmpstr (buf, ==, "361100");
739
740   res = g_snprintf (buf, 128, "%#" "ll" "o", (gint64)123456);
741   g_assert_cmpint (res, ==, 7);
742   g_assert_cmpstr (buf, ==, "0361100");
743
744   res = g_snprintf (buf, 128, "%" "ll" "x", (gint64)123456);
745   g_assert_cmpint (res, ==, 5);
746   g_assert_cmpstr (buf, ==, "1e240");
747
748   res = g_snprintf (buf, 128, "%#" "ll" "x", (gint64)123456);
749   g_assert_cmpint (res, ==, 7);
750   g_assert_cmpstr (buf, ==, "0x1e240");
751
752   res = g_snprintf (buf, 128, "%" "ll" "X", (gint64)123456);
753   g_assert_cmpint (res, ==, 5);
754   g_assert_cmpstr (buf, ==, "1E240");
755 #endif
756 }
757
758 static void
759 test_64bit2 (void)
760 {
761   gint res;
762
763   if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT))
764     {
765       res = g_printf ("%" G_GINT64_FORMAT, (gint64)123456);
766       g_assert_cmpint (res, ==, 6);
767       exit (0);
768     }
769   g_test_trap_assert_passed ();
770   g_test_trap_assert_stdout ("*123456*");
771
772   if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT))
773     {
774       res = g_printf ("%" G_GINT64_FORMAT, (gint64)-123456);
775       g_assert_cmpint (res, ==, 7);
776       exit (0);
777     }
778   g_test_trap_assert_passed ();
779   g_test_trap_assert_stdout ("*-123456*");
780
781   if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT))
782     {
783       res = g_printf ("%" G_GUINT64_FORMAT, (guint64)123456);
784       g_assert_cmpint (res, ==, 6);
785       exit (0);
786     }
787   g_test_trap_assert_passed ();
788   g_test_trap_assert_stdout ("*123456*");
789
790   if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT))
791     {
792       res = g_printf ("%" G_GINT64_MODIFIER "o", (gint64)123456);
793       g_assert_cmpint (res, ==, 6);
794       exit (0);
795     }
796   g_test_trap_assert_passed ();
797   g_test_trap_assert_stdout ("*361100*");
798
799   if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT))
800     {
801       res = g_printf ("%#" G_GINT64_MODIFIER "o", (gint64)123456);
802       g_assert_cmpint (res, ==, 7);
803       exit (0);
804     }
805   g_test_trap_assert_passed ();
806   g_test_trap_assert_stdout ("*0361100*");
807
808   if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT))
809     {
810       res = g_printf ("%" G_GINT64_MODIFIER "x", (gint64)123456);
811       g_assert_cmpint (res, ==, 5);
812       exit (0);
813     }
814   g_test_trap_assert_passed ();
815   g_test_trap_assert_stdout ("*1e240*");
816
817   if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT))
818     {
819       res = g_printf ("%#" G_GINT64_MODIFIER "x", (gint64)123456);
820       g_assert_cmpint (res, ==, 7);
821       exit (0);
822     }
823   g_test_trap_assert_passed ();
824   g_test_trap_assert_stdout ("*0x1e240*");
825
826   if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT))
827     {
828       res = g_printf ("%" G_GINT64_MODIFIER "X", (gint64)123456);
829       g_assert_cmpint (res, ==, 5);
830       exit (0);
831     }
832   g_test_trap_assert_passed ();
833   g_test_trap_assert_stdout ("*1E240*");
834
835 #ifdef G_OS_WIN32
836   /* On Win32, test that the "ll" modifier also works, for backward
837    * compatibility. One really should use the G_GINT64_MODIFIER (which
838    * on Win32 is the "I64" that the (msvcrt) C library's printf uses),
839    * but "ll" used to work with the "trio" g_printf implementation in
840    * GLib 2.2, so it's best if it continues to work.
841    */
842
843   if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT))
844     {
845       res = g_printf ("%" "lli", (gint64)123456);
846       g_assert_cmpint (res, ==, 6);
847       exit (0);
848     }
849   g_test_trap_assert_passed ();
850   g_test_trap_assert_stdout ("*123456*");
851
852   if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT))
853     {
854       res = g_printf ("%" "lli", (gint64)-123456);
855       g_assert_cmpint (res, ==, 7);
856       exit (0);
857     }
858   g_test_trap_assert_passed ();
859   g_test_trap_assert_stdout ("*-123456*");
860
861   if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT))
862     {
863       res = g_printf ("%" "llu", (guint64)123456);
864       g_assert_cmpint (res, ==, 6);
865       exit (0);
866     }
867   g_test_trap_assert_passed ();
868   g_test_trap_assert_stdout ("*123456*");
869
870   if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT))
871     {
872       res = g_printf ("%" "ll" "o", (gint64)123456);
873       g_assert_cmpint (res, ==, 6);
874       exit (0);
875     }
876   g_test_trap_assert_passed ();
877   g_test_trap_assert_stdout ("*361100*");
878
879   if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT))
880     {
881       res = g_printf ("%#" "ll" "o", (gint64)123456);
882       g_assert_cmpint (res, ==, 7);
883       exit (0);
884     }
885   g_test_trap_assert_passed ();
886   g_test_trap_assert_stdout ("*0361100*");
887
888   if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT))
889     {
890       res = g_printf ("%" "ll" "x", (gint64)123456);
891       g_assert_cmpint (res, ==, 5);
892       exit (0);
893     }
894   g_test_trap_assert_passed ();
895   g_test_trap_assert_stdout ("*1e240*");
896
897   if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT))
898     {
899       res = g_printf ("%#" "ll" "x", (gint64)123456);
900       g_assert_cmpint (res, ==, 7);
901       exit (0);
902     }
903   g_test_trap_assert_passed ();
904   g_test_trap_assert_stdout ("*0x1e240*");
905
906   if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT))
907     {
908       res = g_printf ("%" "ll" "X", (gint64)123456);
909       g_assert_cmpint (res, ==, 5);
910       exit (0);
911     }
912   g_test_trap_assert_passed ();
913   g_test_trap_assert_stdout ("*1E240*");
914 #endif
915 }
916
917 static gsize
918 upper_bound (const gchar *format, ...)
919 {
920   va_list args;
921   gsize res;
922
923   va_start (args, format);
924   res = g_printf_string_upper_bound (format, args);
925   va_end (args);
926
927   return res;
928 }
929
930 static void
931 test_upper_bound (void)
932 {
933   gsize res;
934
935   res = upper_bound ("bla %s %d: %g\n", "bla", 123, 0.123);
936   g_assert_cmpint (res, ==, 20);
937 }
938
939 int
940 main (int   argc,
941       char *argv[])
942 {
943   g_test_init (&argc, &argv, NULL);
944
945   g_test_add_func ("/snprintf/retval-and-trunc", test_retval_and_trunc);
946   g_test_add_func ("/snprintf/%d", test_d);
947   g_test_add_func ("/snprintf/%o", test_o);
948   g_test_add_func ("/snprintf/%u", test_u);
949   g_test_add_func ("/snprintf/%x", test_x);
950   g_test_add_func ("/snprintf/%X", test_X);
951   g_test_add_func ("/snprintf/%f", test_f);
952   g_test_add_func ("/snprintf/%e", test_e);
953   g_test_add_func ("/snprintf/%c", test_c);
954   g_test_add_func ("/snprintf/%s", test_s);
955   g_test_add_func ("/snprintf/%n", test_n);
956   g_test_add_func ("/snprintf/test-percent", test_percent);
957   g_test_add_func ("/snprintf/test-positional-params", test_positional_params);
958   g_test_add_func ("/snprintf/test-64bit", test_64bit);
959
960   g_test_add_func ("/printf/test-percent", test_percent2);
961   g_test_add_func ("/printf/test-positional-params", test_positional_params2);
962   g_test_add_func ("/printf/test-64bit", test_64bit2);
963
964   g_test_add_func ("/sprintf/test-positional-params", test_positional_params3);
965   g_test_add_func ("/sprintf/upper-bound", test_upper_bound);
966
967   return g_test_run();
968 }