11 March 2014

Adding format specifiers to printf

It is possible to add specifiers for the printf function family. To do this, the register_printf_specifier can be used.
Two functions must be created for this.
int print_data_struture(FILE *stream, const struct printf_info *info, const void *const *args)
{
 char buffer[256];
 int len = 0;
 data_structure_t *data = 0;

 data = *((data_structure_t **)(args[0]));

 print_data_structure_to_string(buffer, data);

 len = fprintf(stream, "%*s", (info->left?-info->width:info->width), buffer);

 return len;
}

int print_data_structure_arginfo(FILE *stream, const struct printf_info *info, const void *const *args)
{
 if (n>0) {
  argtypes[0] = PA_POINTER;
  return 1;
 }
 return 0;
}

Afterwards, at the start of the program, the register_format_specifier must be called with the two functions and the specifier as parameters.
int main()
{
 register_print_specifier('W', print_data_structure, print_data_structure_arginfo);

 ...

 data_structure_t data;
 /* initialize data */

 ...

 printf("%W\n", &data); 

This should print the data variable as specified in the print_data_structure_to_string function. However, while the program will compile, there are two major issues with it.
Firstly, the register_format_specifier function is a GNU extension, it is not part of the ISO C standard.
Secondly, while the program will compile and execute correctly, the compiler (gcc) will give warnings when compiling with -Wformat (or -Wall), and these warnings cannot be avoided, since it is not possible to add specifiers to the ones supported by the gcc static check.

No comments:

Post a Comment