Now let's look at how to define the handler and arginfo functions which are passed as arguments to register_printf_function
.
You should define your handler functions with a prototype like:
int function (FILE *stream, const struct printf_info *info, va_list *ap_pointer)
The stream
argument passed to the handler function is the stream to which it should write output.
The info
argument is a pointer to a structure that contains information about the various options that were included with the conversion in the template string. You should not modify this structure inside your handler function. See Conversion Specifier Options, for a description of this data structure.
The ap_pointer
argument is used to pass the tail of the variable argument list containing the values to be printed to your handler. Unlike most other functions that can be passed an explicit variable argument list, this is a pointer to a va_list
, rather than the va_list
itself. Thus, you should fetch arguments by means of va_arg (type, *ap_pointer)
.
(Passing a pointer here allows the function that calls your handler function to update its own va_list
variable to account for the arguments that your handler processes. See Variadic Functions.)
Your handler function should return a value just like printf
does: it should return the number of characters it has written, or a negative value to indicate an error.
If you are going to use parse_printf_format
in your application, you should also define a function to pass as the arginfo-function argument for each new conversion you install with register_printf_function
.
You should define these functions with a prototype like:
int function (const struct printf_info *info, size_t n, int *argtypes)
The return value from the function should be the number of arguments the conversion expects. The function should also fill in no more than n elements of the argtypes array with information about the types of each of these arguments. This information is encoded using the various `PA_' macros. (You will notice that this is the same calling convention parse_printf_format
itself uses.)