iPXE
Data Structures | Functions | Variables
vsprintf.h File Reference

printf() and friends More...

#include <stdint.h>
#include <stdarg.h>
#include <stdio.h>

Go to the source code of this file.

Data Structures

struct  printf_context
 A printf context. More...

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
size_t vcprintf (struct printf_context *ctx, const char *fmt, va_list args)
 Write a formatted string to a printf context.
int vssnprintf (char *buf, ssize_t ssize, const char *fmt, va_list args)
 Version of vsnprintf() that accepts a signed buffer size.
int __attribute__ ((format(printf, 3, 4))) ssnprintf(char *buf

Variables

int ssize_t ssize
int ssize_t const char * fmt

Detailed Description

printf() and friends

Etherboot's printf() functions understand the following subset of the standard C printf()'s format specifiers:

Hexadecimal numbers are always zero-padded to the specified field width (if any); decimal numbers are always space-padded. Decimal long longs are not supported.

Definition in file vsprintf.h.


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )
size_t vcprintf ( struct printf_context ctx,
const char *  fmt,
va_list  args 
)

Write a formatted string to a printf context.

Parameters:
ctxContext
fmtFormat string
argsArguments corresponding to the format string
Return values:
lenLength of formatted string

Definition at line 187 of file vsprintf.c.

References ALT_FORM, cputchar(), flags, fmt, format_decimal(), format_hex(), hex, INT_LEN, LCASE, printf_context::len, len, length, LONG_LEN, NULL, SIZE_T_LEN, type_sizes, va_arg, wc, and ZPAD.

Referenced by efi_vsnprintf(), vprintf(), vsnprintf(), and vw_printw().

                                                                              {
        int flags;
        int width;
        uint8_t *length;
        char *ptr;
        char tmp_buf[32]; /* 32 is enough for all numerical formats.
                           * Insane width fields could overflow this buffer. */
        wchar_t *wptr;

        /* Initialise context */
        ctx->len = 0;

        for ( ; *fmt ; fmt++ ) {
                /* Pass through ordinary characters */
                if ( *fmt != '%' ) {
                        cputchar ( ctx, *fmt );
                        continue;
                }
                fmt++;
                /* Process flag characters */
                flags = 0;
                for ( ; ; fmt++ ) {
                        if ( *fmt == '#' ) {
                                flags |= ALT_FORM;
                        } else if ( *fmt == '0' ) {
                                flags |= ZPAD;
                        } else {
                                /* End of flag characters */
                                break;
                        }
                }
                /* Process field width */
                width = 0;
                for ( ; ; fmt++ ) {
                        if ( ( ( unsigned ) ( *fmt - '0' ) ) < 10 ) {
                                width = ( width * 10 ) + ( *fmt - '0' );
                        } else {
                                break;
                        }
                }
                /* We don't do floating point */
                /* Process length modifier */
                length = &type_sizes[INT_LEN];
                for ( ; ; fmt++ ) {
                        if ( *fmt == 'h' ) {
                                length--;
                        } else if ( *fmt == 'l' ) {
                                length++;
                        } else if ( *fmt == 'z' ) {
                                length = &type_sizes[SIZE_T_LEN];
                        } else {
                                break;
                        }
                }
                /* Process conversion specifier */
                ptr = tmp_buf + sizeof ( tmp_buf ) - 1;
                *ptr = '\0';
                wptr = NULL;
                if ( *fmt == 'c' ) {
                        if ( length < &type_sizes[LONG_LEN] ) {
                                cputchar ( ctx, va_arg ( args, unsigned int ) );
                        } else {
                                wchar_t wc;
                                size_t len;

                                wc = va_arg ( args, wint_t );
                                len = wcrtomb ( tmp_buf, wc, NULL );
                                tmp_buf[len] = '\0';
                                ptr = tmp_buf;
                        }
                } else if ( *fmt == 's' ) {
                        if ( length < &type_sizes[LONG_LEN] ) {
                                ptr = va_arg ( args, char * );
                                if ( ! ptr )
                                        ptr = "<NULL>";
                        } else {
                                wptr = va_arg ( args, wchar_t * );
                                if ( ! wptr )
                                        ptr = "<NULL>";
                        }
                } else if ( *fmt == 'p' ) {
                        intptr_t ptrval;

                        ptrval = ( intptr_t ) va_arg ( args, void * );
                        ptr = format_hex ( ptr, ptrval, width, 
                                           ( ALT_FORM | LCASE ) );
                } else if ( ( *fmt & ~0x20 ) == 'X' ) {
                        unsigned long long hex;

                        flags |= ( *fmt & 0x20 ); /* LCASE */
                        if ( *length >= sizeof ( unsigned long long ) ) {
                                hex = va_arg ( args, unsigned long long );
                        } else if ( *length >= sizeof ( unsigned long ) ) {
                                hex = va_arg ( args, unsigned long );
                        } else {
                                hex = va_arg ( args, unsigned int );
                        }
                        ptr = format_hex ( ptr, hex, width, flags );
                } else if ( ( *fmt == 'd' ) || ( *fmt == 'i' ) ){
                        signed long decimal;

                        if ( *length >= sizeof ( signed long ) ) {
                                decimal = va_arg ( args, signed long );
                        } else {
                                decimal = va_arg ( args, signed int );
                        }
                        ptr = format_decimal ( ptr, decimal, width, flags );
                } else {
                        *(--ptr) = *fmt;
                }
                /* Write out conversion result */
                if ( wptr == NULL ) {
                        for ( ; *ptr ; ptr++ ) {
                                cputchar ( ctx, *ptr );
                        }
                } else {
                        for ( ; *wptr ; wptr++ ) {
                                size_t len = wcrtomb ( tmp_buf, *wptr, NULL );
                                for ( ptr = tmp_buf ; len-- ; ptr++ ) {
                                        cputchar ( ctx, *ptr );
                                }
                        }
                }
        }

        return ctx->len;
}
int vssnprintf ( char *  buf,
ssize_t  ssize,
const char *  fmt,
va_list  args 
)

Version of vsnprintf() that accepts a signed buffer size.

Parameters:
bufBuffer into which to write the string
sizeSize of buffer
fmtFormat string
argsArguments corresponding to the format string
Return values:
lenLength of formatted string

Definition at line 401 of file vsprintf.c.

References vsnprintf().

Referenced by ssnprintf().

                                                                           {

        /* Treat negative buffer size as zero buffer size */
        if ( ssize < 0 )
                ssize = 0;

        /* Hand off to vsnprintf */
        return vsnprintf ( buf, ssize, fmt, args );
}
int __attribute__ ( (format(printf, 3, 4))  )

Variable Documentation

Definition at line 72 of file vsprintf.h.

int int size_t const char int const char * fmt

Definition at line 72 of file vsprintf.h.

Referenced by slk_init(), slk_set(), and vcprintf().