#### 12.12.10 Parsing a Template String ¶

You can use the function `parse_printf_format` to obtain information about the number and types of arguments that are expected by a given template string. This function permits interpreters that provide interfaces to `printf` to avoid passing along invalid arguments from the user’s program, which could cause a crash.

All the symbols described in this section are declared in the header file `printf.h`.

Function: `size_t` parse_printf_format `(const char *template, size_t n, int *argtypes)` ¶

  Preliminary: | MT-Safe locale | AS-Safe | AC-Safe | See POSIX Safety Concepts.

  This function returns information about the number and types of arguments expected by the `printf` template string template. The information is stored in the array argtypes; each element of this array describes one argument. This information is encoded using the various ‘`PA_`’ macros, listed below.

  The argument n specifies the number of elements in the array argtypes. This is the maximum number of elements that `parse_printf_format` will try to write.

  `parse_printf_format` returns the total number of arguments required by template. If this number is greater than n, then the information returned describes only the first n arguments. If you want information about additional arguments, allocate a bigger array and call `parse_printf_format` again.

The argument types are encoded as a combination of a basic type and modifier flag bits.

Macro: `int` PA_FLAG_MASK ¶

  This macro is a bitmask for the type modifier flag bits. You can write the expression `(argtypes[i] & PA_FLAG_MASK)` to extract just the flag bits for an argument, or `(argtypes[i] & ~PA_FLAG_MASK)` to extract just the basic type code.

Here are symbolic constants that represent the basic types; they stand for integer values.

`PA_INT` ¶

  This specifies that the base type is `int`.

`PA_CHAR` ¶

  This specifies that the base type is `int`, cast to `char`.

`PA_STRING` ¶

  This specifies that the base type is `char *`, a null-terminated string.

`PA_POINTER` ¶

  This specifies that the base type is `void *`, an arbitrary pointer.

`PA_FLOAT` ¶

  This specifies that the base type is `float`.

`PA_DOUBLE` ¶

  This specifies that the base type is `double`.

`PA_LAST` ¶

  You can define additional base types for your own programs as offsets from `PA_LAST`. For example, if you have data types ‘`foo`’ and ‘`bar`’ with their own specialized `printf` conversions, you could define encodings for these types as:

      #define PA_FOO  PA_LAST
      #define PA_BAR  (PA_LAST + 1)

Here are the flag bits that modify a basic type. They are combined with the code for the basic type using inclusive-or.

`PA_FLAG_PTR` ¶

  If this bit is set, it indicates that the encoded type is a pointer to the base type, rather than an immediate value. For example, ‘`PA_INT|PA_FLAG_PTR`’ represents the type ‘`int *`’.

`PA_FLAG_SHORT` ¶

  If this bit is set, it indicates that the base type is modified with `short`. (This corresponds to the ‘`h`’ type modifier.)

`PA_FLAG_LONG` ¶

  If this bit is set, it indicates that the base type is modified with `long`. (This corresponds to the ‘`l`’ type modifier.)

`PA_FLAG_LONG_LONG` ¶

  If this bit is set, it indicates that the base type is modified with `long long`. (This corresponds to the ‘`L`’ type modifier.)

`PA_FLAG_LONG_DOUBLE` ¶

  This is a synonym for `PA_FLAG_LONG_LONG`, used by convention with a base type of `PA_DOUBLE` to indicate a type of `long double`.