Next: , 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>      |