1/* Test of u16_v[a]s[n]printf() function.
2   Copyright (C) 2007, 2009, 2010 Free Software Foundation, Inc.
3
4   This program is free software: you can redistribute it and/or modify
5   it under the terms of the GNU General Public License as published by
6   the Free Software Foundation; either version 3 of the License, or
7   (at your option) any later version.
8
9   This program 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
12   GNU General Public License for more details.
13
14   You should have received a copy of the GNU General Public License
15   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
16
17/* Written by Bruno Haible <bruno@clisp.org>, 2007.  */
18
19static void
20test_xfunction (uint16_t * (*my_xasprintf) (const char *, ...))
21{
22  /* Test support of size specifiers as in C99.  */
23
24  {
25    uint16_t *result =
26      my_xasprintf ("%ju %d", (uintmax_t) 12345671, 33, 44, 55);
27    static const uint16_t expected[] =
28      { '1', '2', '3', '4', '5', '6', '7', '1', ' ', '3', '3', 0 };
29    ASSERT (result != NULL);
30    ASSERT (u16_strcmp (result, expected) == 0);
31    free (result);
32  }
33
34  {
35    uint16_t *result =
36      my_xasprintf ("%zu %d", (size_t) 12345672, 33, 44, 55);
37    static const uint16_t expected[] =
38      { '1', '2', '3', '4', '5', '6', '7', '2', ' ', '3', '3', 0 };
39    ASSERT (result != NULL);
40    ASSERT (u16_strcmp (result, expected) == 0);
41    free (result);
42  }
43
44  {
45    uint16_t *result =
46      my_xasprintf ("%tu %d", (ptrdiff_t) 12345673, 33, 44, 55);
47    static const uint16_t expected[] =
48      { '1', '2', '3', '4', '5', '6', '7', '3', ' ', '3', '3', 0 };
49    ASSERT (result != NULL);
50    ASSERT (u16_strcmp (result, expected) == 0);
51    free (result);
52  }
53
54  {
55    uint16_t *result =
56      my_xasprintf ("%Lg %d", (long double) 1.5, 33, 44, 55);
57    static const uint16_t expected[] =
58      { '1', '.', '5', ' ', '3', '3', 0 };
59    ASSERT (result != NULL);
60    ASSERT (u16_strcmp (result, expected) == 0);
61    free (result);
62  }
63
64  /* Test the support of the 'U' conversion specifier for Unicode strings.  */
65
66  {
67    static const uint8_t unicode_string[] = "Hello";
68    {
69      uint16_t *result =
70        my_xasprintf ("%U %d", unicode_string, 33, 44, 55);
71      static const uint16_t expected[] =
72        { 'H', 'e', 'l', 'l', 'o', ' ', '3', '3', 0 };
73      ASSERT (result != NULL);
74      ASSERT (u16_strcmp (result, expected) == 0);
75      free (result);
76    }
77    { /* Width.  */
78      uint16_t *result =
79        my_xasprintf ("%10U %d", unicode_string, 33, 44, 55);
80      static const uint16_t expected[] =
81        { ' ', ' ', ' ', ' ', ' ', 'H', 'e', 'l', 'l', 'o', ' ', '3', '3', 0 };
82      ASSERT (result != NULL);
83      ASSERT (u16_strcmp (result, expected) == 0);
84      free (result);
85    }
86    { /* FLAG_LEFT.  */
87      uint16_t *result =
88        my_xasprintf ("%-10U %d", unicode_string, 33, 44, 55);
89      static const uint16_t expected[] =
90        { 'H', 'e', 'l', 'l', 'o', ' ', ' ', ' ', ' ', ' ', ' ', '3', '3', 0 };
91      ASSERT (result != NULL);
92      ASSERT (u16_strcmp (result, expected) == 0);
93      free (result);
94    }
95    { /* FLAG_ZERO: no effect.  */
96      uint16_t *result =
97        my_xasprintf ("%010U %d", unicode_string, 33, 44, 55);
98      static const uint16_t expected[] =
99        { ' ', ' ', ' ', ' ', ' ', 'H', 'e', 'l', 'l', 'o', ' ', '3', '3', 0 };
100      ASSERT (result != NULL);
101      ASSERT (u16_strcmp (result, expected) == 0);
102      free (result);
103    }
104  }
105
106  {
107    static const uint16_t unicode_string[] = { 'H', 'e', 'l', 'l', 'o', 0 };
108    {
109      uint16_t *result =
110        my_xasprintf ("%lU %d", unicode_string, 33, 44, 55);
111      static const uint16_t expected[] =
112        { 'H', 'e', 'l', 'l', 'o', ' ', '3', '3', 0 };
113      ASSERT (result != NULL);
114      ASSERT (u16_strcmp (result, expected) == 0);
115      free (result);
116    }
117    { /* Width.  */
118      uint16_t *result =
119        my_xasprintf ("%10lU %d", unicode_string, 33, 44, 55);
120      static const uint16_t expected[] =
121        { ' ', ' ', ' ', ' ', ' ', 'H', 'e', 'l', 'l', 'o', ' ', '3', '3', 0 };
122      ASSERT (result != NULL);
123      ASSERT (u16_strcmp (result, expected) == 0);
124      free (result);
125    }
126    { /* FLAG_LEFT.  */
127      uint16_t *result =
128        my_xasprintf ("%-10lU %d", unicode_string, 33, 44, 55);
129      static const uint16_t expected[] =
130        { 'H', 'e', 'l', 'l', 'o', ' ', ' ', ' ', ' ', ' ', ' ', '3', '3', 0 };
131      ASSERT (result != NULL);
132      ASSERT (u16_strcmp (result, expected) == 0);
133      free (result);
134    }
135    { /* FLAG_ZERO: no effect.  */
136      uint16_t *result =
137        my_xasprintf ("%010lU %d", unicode_string, 33, 44, 55);
138      static const uint16_t expected[] =
139        { ' ', ' ', ' ', ' ', ' ', 'H', 'e', 'l', 'l', 'o', ' ', '3', '3', 0 };
140      ASSERT (result != NULL);
141      ASSERT (u16_strcmp (result, expected) == 0);
142      free (result);
143    }
144  }
145
146  {
147    static const uint32_t unicode_string[] = { 'H', 'e', 'l', 'l', 'o', 0 };
148    {
149      uint16_t *result =
150        my_xasprintf ("%llU %d", unicode_string, 33, 44, 55);
151      static const uint16_t expected[] =
152        { 'H', 'e', 'l', 'l', 'o', ' ', '3', '3', 0 };
153      ASSERT (result != NULL);
154      ASSERT (u16_strcmp (result, expected) == 0);
155      free (result);
156    }
157    { /* Width.  */
158      uint16_t *result =
159        my_xasprintf ("%10llU %d", unicode_string, 33, 44, 55);
160      static const uint16_t expected[] =
161        { ' ', ' ', ' ', ' ', ' ', 'H', 'e', 'l', 'l', 'o', ' ', '3', '3', 0 };
162      ASSERT (result != NULL);
163      ASSERT (u16_strcmp (result, expected) == 0);
164      free (result);
165    }
166    { /* FLAG_LEFT.  */
167      uint16_t *result =
168        my_xasprintf ("%-10llU %d", unicode_string, 33, 44, 55);
169      static const uint16_t expected[] =
170        { 'H', 'e', 'l', 'l', 'o', ' ', ' ', ' ', ' ', ' ', ' ', '3', '3', 0 };
171      ASSERT (result != NULL);
172      ASSERT (u16_strcmp (result, expected) == 0);
173      free (result);
174    }
175    { /* FLAG_ZERO: no effect.  */
176      uint16_t *result =
177        my_xasprintf ("%010llU %d", unicode_string, 33, 44, 55);
178      static const uint16_t expected[] =
179        { ' ', ' ', ' ', ' ', ' ', 'H', 'e', 'l', 'l', 'o', ' ', '3', '3', 0 };
180      ASSERT (result != NULL);
181      ASSERT (u16_strcmp (result, expected) == 0);
182      free (result);
183    }
184  }
185
186  /* Test the support of the 's' conversion specifier for strings.  */
187
188  {
189    uint16_t *result =
190      my_xasprintf ("Mr. %s %d", "Ronald Reagan", 33, 44, 55);
191    static const uint16_t expected[] =
192      { 'M', 'r', '.', ' ', 'R', 'o', 'n', 'a', 'l', 'd',
193        ' ', 'R', 'e', 'a', 'g', 'a', 'n', ' ', '3', '3',
194        0
195      };
196    ASSERT (result != NULL);
197    ASSERT (u16_strcmp (result, expected) == 0);
198    free (result);
199  }
200
201  { /* Width.  */
202    uint16_t *result =
203      my_xasprintf ("Mr. %20s %d", "Ronald Reagan", 33, 44, 55);
204    static const uint16_t expected[] =
205      { 'M', 'r', '.', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
206        ' ', 'R', 'o', 'n', 'a', 'l', 'd', ' ', 'R', 'e',
207        'a', 'g', 'a', 'n', ' ', '3', '3', 0
208      };
209    ASSERT (result != NULL);
210    ASSERT (u16_strcmp (result, expected) == 0);
211    free (result);
212  }
213
214  { /* FLAG_LEFT.  */
215    uint16_t *result =
216      my_xasprintf ("Mr. %-20s %d", "Ronald Reagan", 33, 44, 55);
217    static const uint16_t expected[] =
218      { 'M', 'r', '.', ' ', 'R', 'o', 'n', 'a', 'l', 'd',
219        ' ', 'R', 'e', 'a', 'g', 'a', 'n', ' ', ' ', ' ',
220        ' ', ' ', ' ', ' ', ' ', '3', '3', 0
221      };
222    ASSERT (result != NULL);
223    ASSERT (u16_strcmp (result, expected) == 0);
224    free (result);
225  }
226
227  { /* FLAG_ZERO: no effect.  */
228    uint16_t *result =
229      my_xasprintf ("Mr. %020s %d", "Ronald Reagan", 33, 44, 55);
230    static const uint16_t expected[] =
231      { 'M', 'r', '.', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
232        ' ', 'R', 'o', 'n', 'a', 'l', 'd', ' ', 'R', 'e',
233        'a', 'g', 'a', 'n', ' ', '3', '3', 0
234      };
235    ASSERT (result != NULL);
236    ASSERT (u16_strcmp (result, expected) == 0);
237    free (result);
238  }
239
240  /* Test the support of the 'a' and 'A' conversion specifier for hexadecimal
241     output of floating-point numbers.  */
242
243  { /* A positive number.  */
244    uint16_t *result =
245      my_xasprintf ("%a %d", 3.1416015625, 33, 44, 55);
246    static const uint16_t expected1[] =
247      { '0', 'x', '1', '.', '9', '2', '2', 'p', '+', '1', ' ', '3', '3', 0 };
248    static const uint16_t expected2[] =
249      { '0', 'x', '3', '.', '2', '4', '4', 'p', '+', '0', ' ', '3', '3', 0 };
250    static const uint16_t expected3[] =
251      { '0', 'x', '6', '.', '4', '8', '8', 'p', '-', '1', ' ', '3', '3', 0 };
252    static const uint16_t expected4[] =
253      { '0', 'x', 'c', '.', '9', '1', 'p', '-', '2', ' ', '3', '3', 0 };
254    ASSERT (result != NULL);
255    ASSERT (u16_strcmp (result, expected1) == 0
256            || u16_strcmp (result, expected2) == 0
257            || u16_strcmp (result, expected3) == 0
258            || u16_strcmp (result, expected4) == 0);
259    free (result);
260  }
261
262  { /* Width.  */
263    uint16_t *result =
264      my_xasprintf ("%10a %d", 1.75, 33, 44, 55);
265    static const uint16_t expected1[] =
266      { ' ', ' ', '0', 'x', '1', '.', 'c', 'p', '+', '0', ' ', '3', '3', 0 };
267    static const uint16_t expected2[] =
268      { ' ', ' ', '0', 'x', '3', '.', '8', 'p', '-', '1', ' ', '3', '3', 0 };
269    static const uint16_t expected3[] =
270      { ' ', ' ', ' ', ' ', '0', 'x', '7', 'p', '-', '2', ' ', '3', '3', 0 };
271    static const uint16_t expected4[] =
272      { ' ', ' ', ' ', ' ', '0', 'x', 'e', 'p', '-', '3', ' ', '3', '3', 0 };
273    ASSERT (result != NULL);
274    ASSERT (u16_strcmp (result, expected1) == 0
275            || u16_strcmp (result, expected2) == 0
276            || u16_strcmp (result, expected3) == 0
277            || u16_strcmp (result, expected4) == 0);
278    free (result);
279  }
280
281  { /* Small precision.  */
282    uint16_t *result =
283      my_xasprintf ("%.10a %d", 1.75, 33, 44, 55);
284    static const uint16_t expected1[] =
285      { '0', 'x', '1', '.', 'c', '0', '0', '0', '0', '0',
286        '0', '0', '0', '0', 'p', '+', '0', ' ', '3', '3',
287        0
288      };
289    static const uint16_t expected2[] =
290      { '0', 'x', '3', '.', '8', '0', '0', '0', '0', '0',
291        '0', '0', '0', '0', 'p', '-', '1', ' ', '3', '3',
292        0
293      };
294    static const uint16_t expected3[] =
295      { '0', 'x', '7', '.', '0', '0', '0', '0', '0', '0',
296        '0', '0', '0', '0', 'p', '-', '2', ' ', '3', '3',
297        0
298      };
299    static const uint16_t expected4[] =
300      { '0', 'x', 'e', '.', '0', '0', '0', '0', '0', '0',
301        '0', '0', '0', '0', 'p', '-', '3', ' ', '3', '3',
302        0
303      };
304    ASSERT (result != NULL);
305    ASSERT (u16_strcmp (result, expected1) == 0
306            || u16_strcmp (result, expected2) == 0
307            || u16_strcmp (result, expected3) == 0
308            || u16_strcmp (result, expected4) == 0);
309    free (result);
310  }
311
312  { /* Large precision.  */
313    uint16_t *result =
314      my_xasprintf ("%.50a %d", 1.75, 33, 44, 55);
315    static const uint16_t expected1[] =
316      { '0', 'x', '1', '.', 'c', '0', '0', '0', '0', '0',
317        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
318        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
319        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
320        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
321        '0', '0', '0', '0', 'p', '+', '0', ' ', '3', '3',
322        0
323      };
324    static const uint16_t expected2[] =
325      { '0', 'x', '3', '.', '8', '0', '0', '0', '0', '0',
326        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
327        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
328        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
329        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
330        '0', '0', '0', '0', 'p', '-', '1', ' ', '3', '3',
331        0
332      };
333    static const uint16_t expected3[] =
334      { '0', 'x', '7', '.', '0', '0', '0', '0', '0', '0',
335        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
336        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
337        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
338        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
339        '0', '0', '0', '0', 'p', '-', '2', ' ', '3', '3',
340        0
341      };
342    static const uint16_t expected4[] =
343      { '0', 'x', 'e', '.', '0', '0', '0', '0', '0', '0',
344        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
345        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
346        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
347        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
348        '0', '0', '0', '0', 'p', '-', '3', ' ', '3', '3',
349        0
350      };
351    ASSERT (result != NULL);
352    ASSERT (u16_strcmp (result, expected1) == 0
353            || u16_strcmp (result, expected2) == 0
354            || u16_strcmp (result, expected3) == 0
355            || u16_strcmp (result, expected4) == 0);
356    free (result);
357  }
358
359  { /* A positive number.  */
360    uint16_t *result =
361      my_xasprintf ("%La %d", 3.1416015625L, 33, 44, 55);
362    static const uint16_t expected1[] =
363      { '0', 'x', '1', '.', '9', '2', '2', 'p', '+', '1',
364        ' ', '3', '3', 0
365      };
366    static const uint16_t expected2[] =
367      { '0', 'x', '3', '.', '2', '4', '4', 'p', '+', '0',
368        ' ', '3', '3', 0
369      };
370    static const uint16_t expected3[] =
371      { '0', 'x', '6', '.', '4', '8', '8', 'p', '-', '1',
372        ' ', '3', '3', 0
373      };
374    static const uint16_t expected4[] =
375      { '0', 'x', 'c', '.', '9', '1', 'p', '-', '2', ' ',
376        '3', '3', 0
377      };
378    ASSERT (result != NULL);
379    ASSERT (u16_strcmp (result, expected1) == 0
380            || u16_strcmp (result, expected2) == 0
381            || u16_strcmp (result, expected3) == 0
382            || u16_strcmp (result, expected4) == 0);
383    free (result);
384  }
385
386  { /* Width.  */
387    uint16_t *result =
388      my_xasprintf ("%10La %d", 1.75L, 33, 44, 55);
389    static const uint16_t expected1[] =
390      { ' ', ' ', '0', 'x', '1', '.', 'c', 'p', '+', '0', ' ', '3', '3', 0 };
391    static const uint16_t expected2[] =
392      { ' ', ' ', '0', 'x', '3', '.', '8', 'p', '-', '1', ' ', '3', '3', 0 };
393    static const uint16_t expected3[] =
394      { ' ', ' ', ' ', ' ', '0', 'x', '7', 'p', '-', '2', ' ', '3', '3', 0 };
395    static const uint16_t expected4[] =
396      { ' ', ' ', ' ', ' ', '0', 'x', 'e', 'p', '-', '3', ' ', '3', '3', 0 };
397    ASSERT (result != NULL);
398    ASSERT (u16_strcmp (result, expected1) == 0
399            || u16_strcmp (result, expected2) == 0
400            || u16_strcmp (result, expected3) == 0
401            || u16_strcmp (result, expected4) == 0);
402    free (result);
403  }
404
405  { /* Small precision.  */
406    uint16_t *result =
407      my_xasprintf ("%.10La %d", 1.75L, 33, 44, 55);
408    static const uint16_t expected1[] =
409      { '0', 'x', '1', '.', 'c', '0', '0', '0', '0', '0',
410        '0', '0', '0', '0', 'p', '+', '0', ' ', '3', '3',
411        0
412      };
413    static const uint16_t expected2[] =
414      { '0', 'x', '3', '.', '8', '0', '0', '0', '0', '0',
415        '0', '0', '0', '0', 'p', '-', '1', ' ', '3', '3',
416        0
417      };
418    static const uint16_t expected3[] =
419      { '0', 'x', '7', '.', '0', '0', '0', '0', '0', '0',
420        '0', '0', '0', '0', 'p', '-', '2', ' ', '3', '3',
421        0
422      };
423    static const uint16_t expected4[] =
424      { '0', 'x', 'e', '.', '0', '0', '0', '0', '0', '0',
425        '0', '0', '0', '0', 'p', '-', '3', ' ', '3', '3',
426        0
427      };
428    ASSERT (result != NULL);
429    ASSERT (u16_strcmp (result, expected1) == 0
430            || u16_strcmp (result, expected2) == 0
431            || u16_strcmp (result, expected3) == 0
432            || u16_strcmp (result, expected4) == 0);
433    free (result);
434  }
435
436  { /* Large precision.  */
437    uint16_t *result =
438      my_xasprintf ("%.50La %d", 1.75L, 33, 44, 55);
439    static const uint16_t expected1[] =
440      { '0', 'x', '1', '.', 'c', '0', '0', '0', '0', '0',
441        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
442        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
443        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
444        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
445        '0', '0', '0', '0', 'p', '+', '0', ' ', '3', '3',
446        0
447      };
448    static const uint16_t expected2[] =
449      { '0', 'x', '3', '.', '8', '0', '0', '0', '0', '0',
450        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
451        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
452        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
453        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
454        '0', '0', '0', '0', 'p', '-', '1', ' ', '3', '3',
455        0
456      };
457    static const uint16_t expected3[] =
458      { '0', 'x', '7', '.', '0', '0', '0', '0', '0', '0',
459        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
460        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
461        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
462        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
463        '0', '0', '0', '0', 'p', '-', '2', ' ', '3', '3',
464        0
465      };
466    static const uint16_t expected4[] =
467      { '0', 'x', 'e', '.', '0', '0', '0', '0', '0', '0',
468        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
469        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
470        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
471        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
472        '0', '0', '0', '0', 'p', '-', '3', ' ', '3', '3',
473        0
474      };
475    ASSERT (result != NULL);
476    ASSERT (u16_strcmp (result, expected1) == 0
477            || u16_strcmp (result, expected2) == 0
478            || u16_strcmp (result, expected3) == 0
479            || u16_strcmp (result, expected4) == 0);
480    free (result);
481  }
482
483  /* Test the support of the %f format directive.  */
484
485  { /* A positive number.  */
486    uint16_t *result =
487      my_xasprintf ("%f %d", 12.75, 33, 44, 55);
488    static const uint16_t expected[] =
489      { '1', '2', '.', '7', '5', '0', '0', '0', '0', ' ', '3', '3', 0 };
490    ASSERT (result != NULL);
491    ASSERT (u16_strcmp (result, expected) == 0);
492    free (result);
493  }
494
495  { /* Width.  */
496    uint16_t *result =
497      my_xasprintf ("%10f %d", 1.75, 33, 44, 55);
498    static const uint16_t expected[] =
499      { ' ', ' ', '1', '.', '7', '5', '0', '0', '0', '0', ' ', '3', '3', 0 };
500    ASSERT (result != NULL);
501    ASSERT (u16_strcmp (result, expected) == 0);
502    free (result);
503  }
504
505  { /* Precision.  */
506    uint16_t *result =
507      my_xasprintf ("%.f %d", 1234.0, 33, 44, 55);
508    static const uint16_t expected[] =
509      { '1', '2', '3', '4', ' ', '3', '3', 0 };
510    ASSERT (result != NULL);
511    ASSERT (u16_strcmp (result, expected) == 0);
512    free (result);
513  }
514
515  { /* A positive number.  */
516    uint16_t *result =
517      my_xasprintf ("%Lf %d", 12.75L, 33, 44, 55);
518    static const uint16_t expected[] =
519      { '1', '2', '.', '7', '5', '0', '0', '0', '0', ' ', '3', '3', 0 };
520    ASSERT (result != NULL);
521    ASSERT (u16_strcmp (result, expected) == 0);
522    free (result);
523  }
524
525  { /* Width.  */
526    uint16_t *result =
527      my_xasprintf ("%10Lf %d", 1.75L, 33, 44, 55);
528    static const uint16_t expected[] =
529      { ' ', ' ', '1', '.', '7', '5', '0', '0', '0', '0', ' ', '3', '3', 0 };
530    ASSERT (result != NULL);
531    ASSERT (u16_strcmp (result, expected) == 0);
532    free (result);
533  }
534
535  { /* Precision.  */
536    uint16_t *result =
537      my_xasprintf ("%.Lf %d", 1234.0L, 33, 44, 55);
538    static const uint16_t expected[] =
539      { '1', '2', '3', '4', ' ', '3', '3', 0 };
540    ASSERT (result != NULL);
541    ASSERT (u16_strcmp (result, expected) == 0);
542    free (result);
543  }
544
545  /* Test the support of the %F format directive.  */
546
547  { /* A positive number.  */
548    uint16_t *result =
549      my_xasprintf ("%F %d", 12.75, 33, 44, 55);
550    static const uint16_t expected[] =
551      { '1', '2', '.', '7', '5', '0', '0', '0', '0', ' ', '3', '3', 0 };
552    ASSERT (result != NULL);
553    ASSERT (u16_strcmp (result, expected) == 0);
554    free (result);
555  }
556
557  { /* Precision.  */
558    uint16_t *result =
559      my_xasprintf ("%.F %d", 1234.0, 33, 44, 55);
560    static const uint16_t expected[] =
561      { '1', '2', '3', '4', ' ', '3', '3', 0 };
562    ASSERT (result != NULL);
563    ASSERT (u16_strcmp (result, expected) == 0);
564    free (result);
565  }
566
567  { /* A positive number.  */
568    uint16_t *result =
569      my_xasprintf ("%LF %d", 12.75L, 33, 44, 55);
570    static const uint16_t expected[] =
571      { '1', '2', '.', '7', '5', '0', '0', '0', '0', ' ', '3', '3', 0 };
572    ASSERT (result != NULL);
573    ASSERT (u16_strcmp (result, expected) == 0);
574    free (result);
575  }
576
577  { /* Precision.  */
578    uint16_t *result =
579      my_xasprintf ("%.LF %d", 1234.0L, 33, 44, 55);
580    static const uint16_t expected[] =
581      { '1', '2', '3', '4', ' ', '3', '3', 0 };
582    ASSERT (result != NULL);
583    ASSERT (u16_strcmp (result, expected) == 0);
584    free (result);
585  }
586
587  /* Test the support of the %e format directive.  */
588
589  { /* A positive number.  */
590    uint16_t *result =
591      my_xasprintf ("%e %d", 12.75, 33, 44, 55);
592    static const uint16_t expected1[] =
593      { '1', '.', '2', '7', '5', '0', '0', '0', 'e', '+',
594        '0', '1', ' ', '3', '3', 0
595      };
596    static const uint16_t expected2[] =
597      { '1', '.', '2', '7', '5', '0', '0', '0', 'e', '+',
598        '0', '0', '1', ' ', '3', '3', 0
599      };
600    ASSERT (result != NULL);
601    ASSERT (u16_strcmp (result, expected1) == 0
602            || u16_strcmp (result, expected2) == 0);
603    free (result);
604  }
605
606  { /* Width.  */
607    uint16_t *result =
608      my_xasprintf ("%15e %d", 1.75, 33, 44, 55);
609    static const uint16_t expected1[] =
610      { ' ', ' ', ' ', '1', '.', '7', '5', '0', '0', '0',
611        '0', 'e', '+', '0', '0', ' ', '3', '3', 0
612      };
613    static const uint16_t expected2[] =
614      { ' ', ' ', '1', '.', '7', '5', '0', '0', '0', '0',
615        'e', '+', '0', '0', '0', ' ', '3', '3', 0
616      };
617    ASSERT (result != NULL);
618    ASSERT (u16_strcmp (result, expected1) == 0
619            || u16_strcmp (result, expected2) == 0);
620    free (result);
621  }
622
623  { /* Precision.  */
624    uint16_t *result =
625      my_xasprintf ("%.e %d", 1234.0, 33, 44, 55);
626    static const uint16_t expected1[] =
627      { '1', 'e', '+', '0', '3', ' ', '3', '3', 0 };
628    static const uint16_t expected2[] =
629      { '1', 'e', '+', '0', '0', '3', ' ', '3', '3', 0 };
630    ASSERT (result != NULL);
631    ASSERT (u16_strcmp (result, expected1) == 0
632            || u16_strcmp (result, expected2) == 0);
633    free (result);
634  }
635
636  { /* A positive number.  */
637    uint16_t *result =
638      my_xasprintf ("%Le %d", 12.75L, 33, 44, 55);
639    static const uint16_t expected[] =
640      { '1', '.', '2', '7', '5', '0', '0', '0', 'e', '+',
641        '0', '1', ' ', '3', '3', 0
642      };
643    ASSERT (result != NULL);
644    ASSERT (u16_strcmp (result, expected) == 0);
645    free (result);
646  }
647
648  { /* Width.  */
649    uint16_t *result =
650      my_xasprintf ("%15Le %d", 1.75L, 33, 44, 55);
651    static const uint16_t expected[] =
652      { ' ', ' ', ' ', '1', '.', '7', '5', '0', '0', '0',
653        '0', 'e', '+', '0', '0', ' ', '3', '3', 0
654      };
655    ASSERT (result != NULL);
656    ASSERT (u16_strcmp (result, expected) == 0);
657    free (result);
658  }
659
660  { /* Precision.  */
661    uint16_t *result =
662      my_xasprintf ("%.Le %d", 1234.0L, 33, 44, 55);
663    static const uint16_t expected[] =
664      { '1', 'e', '+', '0', '3', ' ', '3', '3', 0 };
665    ASSERT (result != NULL);
666    ASSERT (u16_strcmp (result, expected) == 0);
667    free (result);
668  }
669
670  /* Test the support of the %g format directive.  */
671
672  { /* A positive number.  */
673    uint16_t *result =
674      my_xasprintf ("%g %d", 12.75, 33, 44, 55);
675    static const uint16_t expected[] =
676      { '1', '2', '.', '7', '5', ' ', '3', '3', 0 };
677    ASSERT (result != NULL);
678    ASSERT (u16_strcmp (result, expected) == 0);
679    free (result);
680  }
681
682  { /* Width.  */
683    uint16_t *result =
684      my_xasprintf ("%10g %d", 1.75, 33, 44, 55);
685    static const uint16_t expected[] =
686      { ' ', ' ', ' ', ' ', ' ', ' ', '1', '.', '7', '5', ' ', '3', '3', 0 };
687    ASSERT (result != NULL);
688    ASSERT (u16_strcmp (result, expected) == 0);
689    free (result);
690  }
691
692  { /* Precision.  */
693    uint16_t *result =
694      my_xasprintf ("%.g %d", 1234.0, 33, 44, 55);
695    static const uint16_t expected1[] =
696      { '1', 'e', '+', '0', '3', ' ', '3', '3', 0 };
697    static const uint16_t expected2[] =
698      { '1', 'e', '+', '0', '0', '3', ' ', '3', '3', 0 };
699    ASSERT (result != NULL);
700    ASSERT (u16_strcmp (result, expected1) == 0
701            || u16_strcmp (result, expected2) == 0);
702    free (result);
703  }
704
705  { /* A positive number.  */
706    uint16_t *result =
707      my_xasprintf ("%Lg %d", 12.75L, 33, 44, 55);
708    static const uint16_t expected[] =
709      { '1', '2', '.', '7', '5', ' ', '3', '3', 0 };
710    ASSERT (result != NULL);
711    ASSERT (u16_strcmp (result, expected) == 0);
712    free (result);
713  }
714
715  { /* Width.  */
716    uint16_t *result =
717      my_xasprintf ("%10Lg %d", 1.75L, 33, 44, 55);
718    static const uint16_t expected[] =
719      { ' ', ' ', ' ', ' ', ' ', ' ', '1', '.', '7', '5', ' ', '3', '3', 0 };
720    ASSERT (result != NULL);
721    ASSERT (u16_strcmp (result, expected) == 0);
722    free (result);
723  }
724
725  { /* Precision.  */
726    uint16_t *result =
727      my_xasprintf ("%.Lg %d", 1234.0L, 33, 44, 55);
728    static const uint16_t expected[] =
729      { '1', 'e', '+', '0', '3', ' ', '3', '3', 0 };
730    ASSERT (result != NULL);
731    ASSERT (u16_strcmp (result, expected) == 0);
732    free (result);
733  }
734
735  /* Test the support of the %n format directive.  */
736
737  {
738    int count = -1;
739    uint16_t *result =
740      my_xasprintf ("%d %n", 123, &count, 33, 44, 55);
741    static const uint16_t expected[] =
742      { '1', '2', '3', ' ', 0 };
743    ASSERT (result != NULL);
744    ASSERT (u16_strcmp (result, expected) == 0);
745    ASSERT (count == 4);
746    free (result);
747  }
748
749  /* Test the support of the POSIX/XSI format strings with positions.  */
750
751  {
752    uint16_t *result =
753      my_xasprintf ("%2$d %1$d", 33, 55);
754    static const uint16_t expected[] =
755      { '5', '5', ' ', '3', '3', 0 };
756    ASSERT (result != NULL);
757    ASSERT (u16_strcmp (result, expected) == 0);
758    free (result);
759  }
760
761  /* Test the support of the grouping flag.  */
762
763  {
764    uint16_t *result =
765      my_xasprintf ("%'d %d", 1234567, 99);
766    ASSERT (result != NULL);
767    ASSERT (result[u16_strlen (result) - 1] == '9');
768    free (result);
769  }
770
771  /* Test the support of the 'U' conversion specifier for Unicode strings.  */
772
773  {
774    static const uint8_t unicode_string[] = "Rafa\305\202 Maszkowski"; /* Rafa�� Maszkowski */
775    {
776      uint16_t *result =
777        my_xasprintf ("%U %d", unicode_string, 33, 44, 55);
778      static const uint16_t expected[] =
779        { 'R', 'a', 'f', 'a', 0x0142, ' ', 'M', 'a', 's', 'z',
780          'k', 'o', 'w', 's', 'k', 'i', ' ', '3', '3', 0
781        };
782      ASSERT (result != NULL);
783      ASSERT (u16_strcmp (result, expected) == 0);
784      free (result);
785    }
786    { /* Width.  */
787      uint16_t *result =
788        my_xasprintf ("%20U %d", unicode_string, 33, 44, 55);
789      static const uint16_t expected[] =
790        { ' ', ' ', ' ', ' ', 'R', 'a', 'f', 'a', 0x0142, ' ',
791          'M', 'a', 's', 'z', 'k', 'o', 'w', 's', 'k', 'i',
792          ' ', '3', '3', 0
793        };
794      ASSERT (result != NULL);
795      ASSERT (u16_strcmp (result, expected) == 0);
796      free (result);
797    }
798    { /* FLAG_LEFT.  */
799      uint16_t *result =
800        my_xasprintf ("%-20U %d", unicode_string, 33, 44, 55);
801      static const uint16_t expected[] =
802        { 'R', 'a', 'f', 'a', 0x0142, ' ', 'M', 'a', 's', 'z',
803          'k', 'o', 'w', 's', 'k', 'i', ' ', ' ', ' ', ' ',
804          ' ', '3', '3', 0
805        };
806      ASSERT (result != NULL);
807      ASSERT (u16_strcmp (result, expected) == 0);
808      free (result);
809    }
810    { /* FLAG_ZERO: no effect.  */
811      uint16_t *result =
812        my_xasprintf ("%020U %d", unicode_string, 33, 44, 55);
813      static const uint16_t expected[] =
814        { ' ', ' ', ' ', ' ', 'R', 'a', 'f', 'a', 0x0142, ' ',
815          'M', 'a', 's', 'z', 'k', 'o', 'w', 's', 'k', 'i',
816          ' ', '3', '3', 0
817        };
818      ASSERT (result != NULL);
819      ASSERT (u16_strcmp (result, expected) == 0);
820      free (result);
821    }
822  }
823
824  {
825    static const uint16_t unicode_string[] = /* Rafa�� Maszkowski */
826      {
827        'R', 'a', 'f', 'a', 0x0142, ' ', 'M', 'a', 's', 'z', 'k', 'o', 'w',
828        's', 'k', 'i', 0
829      };
830    {
831      uint16_t *result =
832        my_xasprintf ("%lU %d", unicode_string, 33, 44, 55);
833      static const uint16_t expected[] =
834        { 'R', 'a', 'f', 'a', 0x0142, ' ', 'M', 'a', 's', 'z',
835          'k', 'o', 'w', 's', 'k', 'i', ' ', '3', '3', 0
836        };
837      ASSERT (result != NULL);
838      ASSERT (u16_strcmp (result, expected) == 0);
839      free (result);
840    }
841    { /* Width.  */
842      uint16_t *result =
843        my_xasprintf ("%20lU %d", unicode_string, 33, 44, 55);
844      static const uint16_t expected[] =
845        { ' ', ' ', ' ', ' ', 'R', 'a', 'f', 'a', 0x0142, ' ',
846          'M', 'a', 's', 'z', 'k', 'o', 'w', 's', 'k', 'i',
847          ' ', '3', '3', 0
848        };
849      ASSERT (result != NULL);
850      ASSERT (u16_strcmp (result, expected) == 0);
851      free (result);
852    }
853    { /* FLAG_LEFT.  */
854      uint16_t *result =
855        my_xasprintf ("%-20lU %d", unicode_string, 33, 44, 55);
856      static const uint16_t expected[] =
857        { 'R', 'a', 'f', 'a', 0x0142, ' ', 'M', 'a', 's', 'z',
858          'k', 'o', 'w', 's', 'k', 'i', ' ', ' ', ' ', ' ',
859          ' ', '3', '3', 0
860        };
861      ASSERT (result != NULL);
862      ASSERT (u16_strcmp (result, expected) == 0);
863      free (result);
864    }
865    { /* FLAG_ZERO: no effect.  */
866      uint16_t *result =
867        my_xasprintf ("%020lU %d", unicode_string, 33, 44, 55);
868      static const uint16_t expected[] =
869        { ' ', ' ', ' ', ' ', 'R', 'a', 'f', 'a', 0x0142, ' ',
870          'M', 'a', 's', 'z', 'k', 'o', 'w', 's', 'k', 'i',
871          ' ', '3', '3', 0
872        };
873      ASSERT (result != NULL);
874      ASSERT (u16_strcmp (result, expected) == 0);
875      free (result);
876    }
877  }
878
879  {
880    static const uint32_t unicode_string[] = /* Rafa�� Maszkowski */
881      {
882        'R', 'a', 'f', 'a', 0x0142, ' ', 'M', 'a', 's', 'z', 'k', 'o', 'w',
883        's', 'k', 'i', 0
884      };
885    {
886      uint16_t *result =
887        my_xasprintf ("%llU %d", unicode_string, 33, 44, 55);
888      static const uint16_t expected[] =
889        { 'R', 'a', 'f', 'a', 0x0142, ' ', 'M', 'a', 's', 'z',
890          'k', 'o', 'w', 's', 'k', 'i', ' ', '3', '3', 0
891        };
892      ASSERT (result != NULL);
893      ASSERT (u16_strcmp (result, expected) == 0);
894      free (result);
895    }
896    { /* Width.  */
897      uint16_t *result =
898        my_xasprintf ("%20llU %d", unicode_string, 33, 44, 55);
899      static const uint16_t expected[] =
900        { ' ', ' ', ' ', ' ', 'R', 'a', 'f', 'a', 0x0142, ' ',
901          'M', 'a', 's', 'z', 'k', 'o', 'w', 's', 'k', 'i',
902          ' ', '3', '3', 0
903        };
904      ASSERT (result != NULL);
905      ASSERT (u16_strcmp (result, expected) == 0);
906      free (result);
907    }
908    { /* FLAG_LEFT.  */
909      uint16_t *result =
910        my_xasprintf ("%-20llU %d", unicode_string, 33, 44, 55);
911      static const uint16_t expected[] =
912        { 'R', 'a', 'f', 'a', 0x0142, ' ', 'M', 'a', 's', 'z',
913          'k', 'o', 'w', 's', 'k', 'i', ' ', ' ', ' ', ' ',
914          ' ', '3', '3', 0
915        };
916      ASSERT (result != NULL);
917      ASSERT (u16_strcmp (result, expected) == 0);
918      free (result);
919    }
920    { /* FLAG_ZERO: no effect.  */
921      uint16_t *result =
922        my_xasprintf ("%020llU %d", unicode_string, 33, 44, 55);
923      static const uint16_t expected[] =
924        { ' ', ' ', ' ', ' ', 'R', 'a', 'f', 'a', 0x0142, ' ',
925          'M', 'a', 's', 'z', 'k', 'o', 'w', 's', 'k', 'i',
926          ' ', '3', '3', 0
927        };
928      ASSERT (result != NULL);
929      ASSERT (u16_strcmp (result, expected) == 0);
930      free (result);
931    }
932  }
933
934  /* Test non-ASCII characters in the format string.  */
935
936  {
937    uint16_t *result =
938      my_xasprintf ("\304rger", 33, 44, 55);
939    ASSERT (result == NULL && errno == EINVAL);
940  }
941}
942