Formatted Printing: Difference between revisions

From OSDev.wiki
Jump to navigation Jump to search
[unchecked revision][unchecked revision]
Content deleted Content added
m Page in progress
Add another implementation, explain differences
Line 45: Line 45:


== Example Implementation ==
== Example Implementation ==
A more libc conformant implementation that uses kernel/OS provided capability (not bare metal capable).
[[User:A22347/Printf]]
[[User:A22347/Printf]]

A custom format for simple code that can run on bare metal.
[[User:Isaccbarker/String_Formatting]]


{{In Progress}}
{{In Progress}}

Revision as of 06:03, 14 March 2023

This article will cover the theory over formatted printing (i.e. printf()).

How printf() Works?

Your first step towards a reliable printf() function is the understanding of its work. Had you ever tried to imitate va_list and friends via a void** taking the example of a specific language, ... ‎General principles and goals - ‎Localising - ‎Translation tools - ‎Babel Manual:Language - or similitar technics? It surely won't work! You must use the va_list provided in the freestanding version of <stdarg.h> (or and equivalent implementation) in order to be able to use variadic functions. Assuming the use of <stdarg.h>, this is the prototype for printf()

int printf(const char *format, ...);

Have you seen the other members of the printf() family? They're

  • printf(): Write formatted data to stdout
  • fprintf(): Write formatted data to stream
  • sprintf(): Write formatted data to buffer
  • snprintf(): Write formatted data to buffer, limits maximum characters written
  • vprintf(): Write formatted data to stdout, uses a va_list instead of ...
  • vfprintf(): Write formatted data to stream, uses a va_list instead of ...
  • vsprintf(): Write formatted data to buffer, uses a va_list instead of ...
  • vsnprintf(): Write formatted data to buffer, limits maximum characters written, uses a va_list instead of ...

And the abstractions...

  • printf(): Wraps over vprintf()
  • fprintf(): Wraps over vfprintf()
  • sprintf(): Wraps over vsprintf()
  • snprintf(): Wraps over vsnprintf()
  • vprintf(): Wraps over vfprintf()
  • vfprintf(): Does the work!
  • vsprintf(): Wraps over vsnprintf() (with a magical number as limit).
  • vsnprintf(): Wraps over vfprintf() with fmemopen()

But, hey! This is a user-space C library example! Yes, it is. You'll more than likely only provide a printf() that does what vfprintf() is intented to do, but in one shot. Basically, the worker function will print where it must print, until finding a % character. If it's followed by another %, it's printed and process contiues. If it's followed by a valid specifier character, its parsing begins. Else the character is printed and process continues. We'll explain in detail the implementation of each item later.

The Definitions

Let's define some constants that we'll use a lot later on

#define FLAG_LEFT  0x01 // The '-' flag
#define FLAG_SIGN  0x02 // The '+' flag
#define FLAG_SPACE 0x04 // The ' ' flag
#define FLAG_TYPE  0x08 // The '#' flag
#define FLAG_ZERO  0x10 // The '0' flag

The General Recolection

Once you have found something after a %, you should start by declaring three signed variables:

Example Implementation

A more libc conformant implementation that uses kernel/OS provided capability (not bare metal capable). User:A22347/Printf

A custom format for simple code that can run on bare metal. User:Isaccbarker/String_Formatting

This page is a work in progress.
This page may thus be incomplete. Its content may be changed in the near future.