new facility for formatted output

Peter A. Bigot

With the merge of Zephyr printk, shell_printf, minimal libc sprintf, and some other in-tree facilities use a common formatting functionality that supports almost everything in C18 *printf, with Kconfig options to reduce the code size impact based on controlling feature availability.

That PR added a C99 stdio value formatter capability named cbprintf() (plus related variants) where generated text is emitted through a callback. This allows generation of arbitrarily long output without a buffer, functionality that is core to printk, logging, and other system and application needs.

The formater supports most C99 specifications, excluding:
  • %L[aefg] long double conversion
  • wide character output
The new solution is derived from z_prf(), which had the most complete functionality available. Format parsing has been reimplemented, while floating point conversion has been retained and enhanced.

Kconfig options allow disabling features like floating-point conversion if they are not necessary.

Benefits include:
No more inconsistencies between printk, logging, and shell formatting capabilities.
  • Reduced inconsistencies due to toolchain libc capabilities.
  • Simplified (toolchain-independent) formatting feature selection via Kconfig.
  • Core infrastructure can avoid duplication with libc printf by using cbprintf variants.
  • Potentially a path to resolving #18351 and related issues, as the infrastructure can tell a caller the total size of arguments to the conversion string.
  • Fixed bugs with several specifications.
Costs include:
  • Applications that used only printk with no extra features consume more code space than the previous implementation.
More information is available at:

You may see either an increase or a decrease in code size depending on what your application uses.  Some code size can be reduced by switching in-tree use of snprintf to snprintfcb to avoid pulling in libc formatters.

I expect there'll be a burn-in period while we identify Kconfig settings that have to change to maintain compatibility.  Please mention me (@pabigot) in any issues or slack questions that you have about this.