1 /* Printf Extension Example
2    Copyright (C) 1991-2022 Free Software Foundation, Inc.
3 
4    This program is free software; you can redistribute it and/or
5    modify it under the terms of the GNU General Public License
6    as published by the Free Software Foundation; either version 2
7    of the License, or (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 <https://www.gnu.org/licenses/>.
16 */
17 
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <printf.h>
21 
22 /*@group*/
23 typedef struct
24 {
25   char *name;
26 }
27 Widget;
28 /*@end group*/
29 
30 int
print_widget(FILE * stream,const struct printf_info * info,const void * const * args)31 print_widget (FILE *stream,
32 	      const struct printf_info *info,
33 	      const void *const *args)
34 {
35   const Widget *w;
36   char *buffer;
37   int len;
38 
39   /* Format the output into a string. */
40   w = *((const Widget **) (args[0]));
41   len = asprintf (&buffer, "<Widget %p: %s>", w, w->name);
42   if (len == -1)
43     return -1;
44 
45   /* Pad to the minimum field width and print to the stream. */
46   len = fprintf (stream, "%*s",
47 		 (info->left ? -info->width : info->width),
48 		 buffer);
49 
50   /* Clean up and return. */
51   free (buffer);
52   return len;
53 }
54 
55 
56 int
print_widget_arginfo(const struct printf_info * info,size_t n,int * argtypes)57 print_widget_arginfo (const struct printf_info *info, size_t n,
58                       int *argtypes)
59 {
60   /* We always take exactly one argument and this is a pointer to the
61      structure..  */
62   if (n > 0)
63     argtypes[0] = PA_POINTER;
64   return 1;
65 }
66 
67 
68 int
main(void)69 main (void)
70 {
71   /* Make a widget to print. */
72   Widget mywidget;
73   mywidget.name = "mywidget";
74 
75   /* Register the print function for widgets. */
76   register_printf_function ('W', print_widget, print_widget_arginfo);
77 
78   /* Now print the widget. */
79   printf ("|%W|\n", &mywidget);
80   printf ("|%35W|\n", &mywidget);
81   printf ("|%-35W|\n", &mywidget);
82 
83   return 0;
84 }
85