Printf Extension Example (The GNU C Library)

#### 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>      |