1 /* Test for user-defined types in vfprintf.
2 Copyright (C) 2017-2021 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
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 <https://www.gnu.org/licenses/>. */
19 /* This test contains a printf format specifier, %P, with a custom
20 type which is a long/double pair. If a precision is specified,
21 this indicates the number of such pairs which constitute the
29 #include <support/check.h>
30 #include <support/support.h>
31 #include <support/test-driver.h>
34 /* Initialized by do_test using register_printf_type. */
44 my_va_arg_function (void *mem
, va_list *ap
)
47 printf ("info: %s (%p) called\n", __func__
, mem
);
49 struct two_argument
*pair
= mem
;
50 pair
->i
= va_arg (*ap
, long);
51 pair
->d
= va_arg (*ap
, double);
55 my_printf_function (FILE *fp
, const struct printf_info
*info
,
56 const void *const *args
)
59 printf ("info: %s (%p, %p, {%p}@%p) called for %%%lc (prec %d)\n",
60 __func__
, fp
, info
, args
[0], args
, (wint_t) info
->spec
,
63 TEST_VERIFY (info
->spec
== 'P');
68 if (fputc ('{', fp
) < 0)
79 for (size_t i
= 0; i
< nargs
; ++i
)
83 if (fputc (',', fp
) < 0)
88 /* NB: Triple pointer indirection. ARGS is an array of void *,
89 and those pointers point to a pointer to the memory area
90 supplied to my_va_arg_function. */
91 struct two_argument
*pair
= *(void **) args
[i
];
92 int ret
= fprintf (fp
, "(%ld, %f)", pair
->i
, pair
->d
);
99 if (fputc ('}', fp
) < 0)
107 my_arginfo_function (const struct printf_info
*info
,
108 size_t n
, int *argtypes
, int *size
)
110 /* Avoid recursion. */
111 if (info
->spec
!= 'P')
113 if (test_verbose
> 0)
114 printf ("info: %s (%p, %zu, %p, %p) called for %%%lc (prec %d)\n",
115 __func__
, info
, n
, argtypes
, size
, (wint_t) info
->spec
,
118 TEST_VERIFY_EXIT (n
>= 1);
125 size_t to_fill
= nargs
;
128 for (size_t i
= 0; i
< to_fill
; ++i
)
130 argtypes
[i
] = user_type
;
131 size
[i
] = sizeof (struct two_argument
);
133 if (test_verbose
> 0)
134 printf ("info: %s return value: %zu\n", __func__
, nargs
);
141 user_type
= register_printf_type (my_va_arg_function
);
142 if (test_verbose
> 0)
143 printf ("info: allocated user type: %d\n", user_type
);
144 TEST_VERIFY_EXIT (user_type
>= PA_LAST
);
145 TEST_VERIFY_EXIT (register_printf_specifier
146 ('P', my_printf_function
, my_arginfo_function
) >= 0);
148 /* Alias declaration for asprintf, to avoid the format string
149 attribute and the associated warning. */
150 #if __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI == 1
151 extern int asprintf_alias (char **, const char *, ...) __asm__ ("__asprintfieee128");
153 extern int asprintf_alias (char **, const char *, ...) __asm__ ("asprintf");
155 TEST_VERIFY (asprintf_alias
== asprintf
);
157 TEST_VERIFY (asprintf_alias (&str
, "[[%P]]", 123L, 456.0) >= 0);
158 if (test_verbose
> 0)
159 printf ("info: %s\n", str
);
160 TEST_VERIFY (strcmp (str
, "[[(123, 456.000000)]]") == 0);
164 TEST_VERIFY (asprintf_alias (&str
, "[[%1$P %1$P]]", 123L, 457.0) >= 0);
165 if (test_verbose
> 0)
166 printf ("info: %s\n", str
);
167 TEST_VERIFY (strcmp (str
, "[[(123, 457.000000) (123, 457.000000)]]") == 0);
171 TEST_VERIFY (asprintf_alias (&str
, "[[%.1P]]", 1L, 2.0) >= 0);
172 if (test_verbose
> 0)
173 printf ("info: %s\n", str
);
174 TEST_VERIFY (strcmp (str
, "[[{(1, 2.000000)}]]") == 0);
178 TEST_VERIFY (asprintf_alias (&str
, "[[%.2P]]", 1L, 2.0, 3L, 4.0) >= 0);
179 if (test_verbose
> 0)
180 printf ("info: %s\n", str
);
181 TEST_VERIFY (strcmp (str
, "[[{(1, 2.000000),(3, 4.000000)}]]") == 0);
185 TEST_VERIFY (asprintf_alias
186 (&str
, "[[%.2P | %.3P]]",
187 /* argument 1: */ 1L, 2.0, 3L, 4.0,
188 /* argument 2: */ 5L, 6.0, 7L, 8.0, 9L, 10.0)
190 if (test_verbose
> 0)
191 printf ("info: %s\n", str
);
192 TEST_VERIFY (strcmp (str
,
194 "{(1, 2.000000),(3, 4.000000)}"
196 "{(5, 6.000000),(7, 8.000000),(9, 10.000000)}"
200 /* The following subtest fails due to bug 21534. */
203 TEST_VERIFY (asprintf_alias
204 (&str
, "[[%1$.2P | %2$.3P | %1$.2P]]",
205 /* argument 1: */ 1L, 2.0, 3L, 4.0,
206 /* argument 2: */ 5L, 6.0, 7L, 8.0, 9L, 10.0)
208 if (test_verbose
> 0)
209 printf ("info: %s\n", str
);
210 TEST_VERIFY (strcmp (str
,
212 "{(1, 2.000000),(3, 4.000000)}"
214 "{(5, 6.000000),(7, 8.000000),(9, 10.000000)}"
216 "{(1, 2.000000),(3, 4.000000)}"
224 #include <support/test-driver.c>