Next: Predefined Printf Handlers, Previous: Defining the Output Handler, Up: Customizing Printf

#### 12.13.4 `printf` Extension Example

Here is an example showing how to define a `printf` handler function. This program defines a data structure called a `Widget` and defines the ‘`%W`’ conversion to print information about `Widget *` arguments, including the pointer value and the name stored in the data structure. The ‘`%W`’ conversion supports the minimum field width and left-justification options, but ignores everything else.

         #include <stdio.h>
         #include <stdlib.h>
         #include <printf.h>

         typedef struct
         {
           char *name;
         }
         Widget;

         int
         print_widget (FILE *stream,
                       const struct printf_info *info,
                       const void *const *args)
         {
           const Widget *w;
           char *buffer;
           int len;

           /* Format the output into a string. */
           w = *((const Widget **) (args[0]));
           len = asprintf (&buffer, "<Widget %p: %s>", w, w->name);
           if (len == -1)
             return -1;

           /* Pad to the minimum field width and print to the stream. */
           len = fprintf (stream, "%*s",
                          (info->left ? -info->width : info->width),
                          buffer);

           /* Clean up and return. */
           free (buffer);
           return len;
         }

         int
         print_widget_arginfo (const struct printf_info *info, size_t n,
                               int *argtypes)
         {
           /* We always take exactly one argument and this is a pointer to the
              structure.. */
           if (n > 0)
             argtypes[0] = PA_POINTER;
           return 1;
         }

         int
         main (void)
         {
           /* Make a widget to print. */
           Widget mywidget;
           mywidget.name = "mywidget";

           /* Register the print function for widgets. */
           register_printf_function ('W', print_widget, print_widget_arginfo);

           /* Now print the widget. */
           printf ("|%W|\n", &mywidget);
           printf ("|%35W|\n", &mywidget);
           printf ("|%-35W|\n", &mywidget);

           return 0;
         }

The output produced by this program looks like:

         |<Widget 0xffeffb7c: mywidget>|
         |      <Widget 0xffeffb7c: mywidget>|
         |<Widget 0xffeffb7c: mywidget>      |