iPXE
Data Structures | Defines | Functions | Variables
vsprintf.c File Reference
#include <stddef.h>
#include <stdarg.h>
#include <stdio.h>
#include <errno.h>
#include <wchar.h>
#include <ipxe/vsprintf.h>

Go to the source code of this file.

Data Structures

struct  sputc_context
 Context used by vsnprintf() and friends. More...

Defines

#define CHAR_LEN   0
 "hh" length modifier
#define SHORT_LEN   1
 "h" length modifier
#define INT_LEN   2
 no length modifier
#define LONG_LEN   3
 "l" length modifier
#define LONGLONG_LEN   4
 "ll" length modifier
#define SIZE_T_LEN   5
 "z" length modifier
#define LCASE   0x20
 Use lower-case for hexadecimal digits.
#define ALT_FORM   0x02
 Use "alternate form".
#define ZPAD   0x10
 Use zero padding.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
static char * format_hex (char *end, unsigned long long num, int width, int flags)
 Format a hexadecimal number.
static char * format_decimal (char *end, signed long num, int width, int flags)
 Format a decimal number.
static void cputchar (struct printf_context *ctx, unsigned char c)
 Print character via a printf context.
size_t vcprintf (struct printf_context *ctx, const char *fmt, va_list args)
 Write a formatted string to a printf context.
static void printf_sputc (struct printf_context *ctx, unsigned int c)
 Write character to buffer.
int vsnprintf (char *buf, size_t size, const char *fmt, va_list args)
 Write a formatted string to a buffer.
int snprintf (char *buf, size_t size, const char *fmt,...)
 Write a formatted string to a buffer.
int vssnprintf (char *buf, ssize_t ssize, const char *fmt, va_list args)
 Version of vsnprintf() that accepts a signed buffer size.
int ssnprintf (char *buf, ssize_t ssize, const char *fmt,...)
 Version of vsnprintf() that accepts a signed buffer size.
static void printf_putchar (struct printf_context *ctx __unused, unsigned int c)
 Write character to console.
int vprintf (const char *fmt, va_list args)
 Write a formatted string to the console.
int printf (const char *fmt,...)
 Write a formatted string to the console.

Variables

static uint8_t type_sizes []

Detailed Description

Definition in file vsprintf.c.


Define Documentation

#define CHAR_LEN   0

"hh" length modifier

Definition at line 35 of file vsprintf.c.

#define SHORT_LEN   1

"h" length modifier

Definition at line 36 of file vsprintf.c.

#define INT_LEN   2

no length modifier

Definition at line 37 of file vsprintf.c.

Referenced by vcprintf().

#define LONG_LEN   3

"l" length modifier

Definition at line 38 of file vsprintf.c.

Referenced by vcprintf().

#define LONGLONG_LEN   4

"ll" length modifier

Definition at line 39 of file vsprintf.c.

#define SIZE_T_LEN   5

"z" length modifier

Definition at line 40 of file vsprintf.c.

Referenced by vcprintf().

#define LCASE   0x20

Use lower-case for hexadecimal digits.

Note that this value is set to 0x20 since that makes for very efficient calculations. (Bitwise-ORing with LCASE converts to a lower-case character, for example.)

Definition at line 58 of file vsprintf.c.

Referenced by format_hex(), and vcprintf().

#define ALT_FORM   0x02

Use "alternate form".

For hexadecimal numbers, this means to add a "0x" or "0X" prefix to the number.

Definition at line 66 of file vsprintf.c.

Referenced by format_hex(), and vcprintf().

#define ZPAD   0x10

Use zero padding.

Note that this value is set to 0x10 since that allows the pad character to be calculated as 0x20|(flags&ZPAD)

Definition at line 74 of file vsprintf.c.

Referenced by format_decimal(), format_hex(), and vcprintf().


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )
static char* format_hex ( char *  end,
unsigned long long  num,
int  width,
int  flags 
) [static]

Format a hexadecimal number.

Parameters:
endEnd of buffer to contain number
numNumber to format
widthMinimum field width
flagsFormat flags
Return values:
ptrEnd of buffer

Fills a buffer in reverse order with a formatted hexadecimal number. The number will be zero-padded to the specified width. Lower-case and "alternate form" (i.e. "0x" prefix) flags may be set.

There must be enough space in the buffer to contain the largest number that this function can format.

Definition at line 93 of file vsprintf.c.

References ALT_FORM, end, LCASE, pad, and ZPAD.

Referenced by vcprintf().

                                       {
        char *ptr = end;
        int case_mod = ( flags & LCASE );
        int pad = ( ( flags & ZPAD ) | ' ' );

        /* Generate the number */
        do {
                *(--ptr) = "0123456789ABCDEF"[ num & 0xf ] | case_mod;
                num >>= 4;
        } while ( num );

        /* Pad to width */
        while ( ( end - ptr ) < width )
                *(--ptr) = pad;

        /* Add "0x" or "0X" if alternate form specified */
        if ( flags & ALT_FORM ) {
                *(--ptr) = 'X' | case_mod;
                *(--ptr) = '0';
        }

        return ptr;
}
static char* format_decimal ( char *  end,
signed long  num,
int  width,
int  flags 
) [static]

Format a decimal number.

Parameters:
endEnd of buffer to contain number
numNumber to format
widthMinimum field width
flagsFormat flags
Return values:
ptrEnd of buffer

Fills a buffer in reverse order with a formatted decimal number. The number will be space-padded to the specified width.

There must be enough space in the buffer to contain the largest number that this function can format.

Definition at line 133 of file vsprintf.c.

References end, num, pad, and ZPAD.

Referenced by vcprintf().

                                           {
        char *ptr = end;
        int negative = 0;
        int zpad = ( flags & ZPAD );
        int pad = ( zpad | ' ' );

        /* Generate the number */
        if ( num < 0 ) {
                negative = 1;
                num = -num;
        }
        do {
                *(--ptr) = '0' + ( num % 10 );
                num /= 10;
        } while ( num );

        /* Add "-" if necessary */
        if ( negative && ( ! zpad ) )
                *(--ptr) = '-';

        /* Pad to width */
        while ( ( end - ptr ) < width )
                *(--ptr) = pad;

        /* Add "-" if necessary */
        if ( negative && zpad )
                *ptr = '-';

        return ptr;
}
static void cputchar ( struct printf_context ctx,
unsigned char  c 
) [inline, static]

Print character via a printf context.

Parameters:
ctxContext
cCharacter

Call's the printf_context::handler() method and increments printf_context::len.

Definition at line 174 of file vsprintf.c.

References printf_context::handler, and printf_context::len.

Referenced by vcprintf().

                                                                            {
        ctx->handler ( ctx, c );
        ++ctx->len;
}
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;
}
static void printf_sputc ( struct printf_context ctx,
unsigned int  c 
) [static]

Write character to buffer.

Parameters:
ctxContext
cCharacter

Definition at line 330 of file vsprintf.c.

References sputc_context::buf, container_of, printf_context::len, and sputc_context::max_len.

Referenced by vsnprintf().

                                                                        {
        struct sputc_context * sctx =
                container_of ( ctx, struct sputc_context, ctx );

        if ( ctx->len < sctx->max_len )
                sctx->buf[ctx->len] = c;
}
int vsnprintf ( char *  buf,
size_t  size,
const char *  fmt,
va_list  args 
)

Write a formatted string to a buffer.

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

If the buffer is too small to contain the string, the returned length is the length that would have been written had enough space been available.

Definition at line 351 of file vsprintf.c.

References sputc_context::buf, sputc_context::ctx, end, printf_context::handler, len, sputc_context::max_len, printf_sputc(), size, and vcprintf().

Referenced by snprintf(), snprintf_okx(), vasprintf(), vmsg(), vsprintf(), and vssnprintf().

                                                                        {
        struct sputc_context sctx;
        size_t len;
        size_t end;

        /* Hand off to vcprintf */
        sctx.ctx.handler = printf_sputc;
        sctx.buf = buf;
        sctx.max_len = size;
        len = vcprintf ( &sctx.ctx, fmt, args );

        /* Add trailing NUL */
        if ( size ) {
                end = size - 1;
                if ( len < end )
                        end = len;
                buf[end] = '\0';
        }

        return len;
}
int snprintf ( char *  buf,
size_t  size,
const char *  fmt,
  ... 
)

Write a formatted string to a buffer.

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

Definition at line 382 of file vsprintf.c.

References va_end, va_start, and vsnprintf().

Referenced by __vxge_hw_vpath_fw_ver_get(), alloc_usb(), aoedev_name(), ath9k_hw_name(), cpio_set_field(), dhcp_tag_name(), dhcpv6_type_name(), draw_menu_item(), efi_device_info(), efi_devpath_text(), efi_driver_name(), efi_driver_name2(), efi_file_find(), efi_local_open_path(), efi_locate_search_type_name(), efi_pci_info(), efi_pecoff_debug_name(), efi_status(), efi_usb_install(), eisabus_probe(), eoib_create(), fc_id_ntoa(), fc_ntoa(), fc_port_open(), fcp_parse_uri(), format_busdevfn_setting(), format_int_setting(), format_ipv4_setting(), format_ipv6_setting(), format_uint_setting(), format_uuid_setting(), guestinfo_fetch_type(), http_digest_authenticate(), http_format_authorization(), http_format_basic_auth(), http_format_connection(), http_format_content_length(), http_format_content_type(), http_format_host(), http_format_metadata_flavor(), http_format_p2p_peerdist(), http_format_p2p_peerdistex(), http_format_range(), http_format_user_agent(), ib_create_service_madx(), ib_sma_node_desc(), int22(), intelxl_admin_driver(), ipv6_sock_ntoa(), isabus_probe(), isapnpbus_probe(), iwlist(), linux_strerror(), mcabus_probe(), multiboot_add_cmdline(), multiboot_exec(), ndp_register_settings(), pci_read_config(), peerblk_retrieval_uri(), peerdist_discovery_reply_values(), peermux_progress(), profile_hex_fraction(), pxe_menu_draw_item(), pxenv_undi_get_iface_info(), register_ibdev(), register_image(), register_netdev(), select_setting_row(), setting_name(), settings_name(), show_menu(), skge_board_name(), strerror(), string_test_exec(), t509bus_probe(), tftp_apply_settings(), tftp_send_rrq(), tftp_uri(), undibus_probe(), uri_decode(), usb_bcd(), usb_endpoint_name(), usb_probe_all(), usb_speed_name(), validator_start_download(), vlan_create(), vmbus_probe_channels(), xcm_create(), xenbus_probe_device(), xenstore_write_num(), xhci_speed_name(), xsigo_xds_complete(), xsmp_session_type(), xsmp_xve_type(), and xve_create().

                                                              {
        va_list args;
        int i;

        va_start ( args, fmt );
        i = vsnprintf ( buf, size, fmt, args );
        va_end ( args );
        return i;
}
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 ssnprintf ( char *  buf,
ssize_t  ssize,
const char *  fmt,
  ... 
)

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

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

Definition at line 420 of file vsprintf.c.

References len, va_end, va_start, and vssnprintf().

Referenced by efi_handle_name(), format_uri(), hex_encode(), http_format_accept_encoding(), http_format_digest_auth(), http_format_headers(), iscsi_build_login_request_strings(), snpnet_mac_text(), and uri_encode().

                                                                 {
        va_list args;
        int len;

        /* Hand off to vssnprintf */
        va_start ( args, fmt );
        len = vssnprintf ( buf, ssize, fmt, args );
        va_end ( args );
        return len;
}
static void printf_putchar ( struct printf_context *ctx  __unused,
unsigned int  c 
) [static]

Write character to console.

Parameters:
ctxContext
cCharacter

Definition at line 437 of file vsprintf.c.

References putchar().

Referenced by vprintf().

                                              {
        putchar ( c );
}
int vprintf ( const char *  fmt,
va_list  args 
)

Write a formatted string to the console.

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

Definition at line 449 of file vsprintf.c.

References printf_context::handler, printf_putchar(), and vcprintf().

Referenced by dbg_printf(), log_vprintf(), and printf().

                                              {
        struct printf_context ctx;

        /* Hand off to vcprintf */
        ctx.handler = printf_putchar;   
        return vcprintf ( &ctx, fmt, args );    
}
int printf ( const char *  fmt,
  ... 
)

Write a formatted string to the console.

Parameters:
fmtFormat string
...Arguments corresponding to the format string
Return values:
lenLength of formatted string

Definition at line 464 of file vsprintf.c.

References va_end, va_start, and vprintf().

Referenced by __attribute__(), _dump_regs(), amd79c901_read_mode(), amd8111e_poll_link(), amd8111e_probe_ext_phy(), amd8111e_restart(), amd8111e_transmit(), amd8111e_wait_tx_ring(), ansicol_set(), ansiscr_attrs(), ansiscr_cursor(), ansiscr_erase(), ansiscr_movetoyx(), ansiscr_reset(), autoboot(), beep(), bnx2_fw_sync(), bnx2_init_board(), bnx2_init_nvram(), bnx2_probe(), bnx2_report_link(), bnx2_reset_chip(), bnx2_transmit(), bofm_test(), bofm_test_init(), cert_exec(), certstat(), check_duplex(), choose_exec(), clrline(), colour_exec(), config_exec(), console_exec(), corkscrew_probe1(), cpair_exec(), cs89x0_probe(), cs89x0_transmit(), dbg_efi_openers(), dbg_efi_protocols(), dbg_md5_da(), detect_aui(), detect_bnc(), detect_tp(), digest_exec(), dm9132_id_table(), dmfe_poll(), dmfe_probe(), echo_exec(), eepro_poll(), eepro_probe(), eepro_transmit(), eeprom_rdy(), enable_multicast(), entropy_sample_test_exec(), epic100_open(), epic100_poll(), epic100_probe(), epic100_transmit(), eth_pio_write(), eth_probe(), execv(), fcels(), fcels_exec(), fcpeerstat(), fcportstat(), fetch_next_server_and_filename(), fetch_root_path(), fetch_san_filename(), fnrec_dump(), fnrec_init(), gdbserial_init(), gdbudp_init(), get_eeprom_data(), getopt_long(), goto_exec(), help_exec(), hfa384x_copy_from_bap(), hfa384x_copy_to_bap(), hfa384x_docmd_wait(), hfa384x_drvr_getconfig(), hfa384x_drvr_setconfig(), hfa384x_wait_for_event(), ibstat(), ics1893_read_mode(), ifconf(), iflinkwait(), ifopen(), ifstat(), ifstat_errors(), imgdownload(), imgmulti_exec(), imgsingle_exec(), imgstat(), imgtrust_exec(), imgverify_exec(), inc_exec(), ipstat(), ipxe(), iwlist(), iwstat(), legacy_probe(), list_check_contents(), login_exec(), loopback_test(), loopback_wait(), lotest_exec(), main(), match_long_option(), match_short_option(), monojob_wait(), netboot(), ns8390_poll(), nslookup(), nstat(), ntp_exec(), null_reboot(), parse_fc_els_handler(), parse_fc_port(), parse_fc_port_id(), parse_gdb_transport(), parse_integer(), parse_menu(), parse_net_args(), parse_netdev(), parse_netdev_configurator(), parse_parameters(), parse_setting(), parse_settings(), pciscan_exec(), ping(), ping_callback(), pnic_api_check(), pnic_command(), pnic_command_quiet(), pnic_probe(), poweroff_exec(), print_usage(), prism2_find_plx(), prism2_pci_probe(), prism2_probe(), prism2_transmit(), profstat(), prompt(), pxe_menu_prompt_and_select(), pxe_menu_select(), pxebs(), pxebs_exec(), readline_history(), route_ipv4_print(), route_ipv6_print(), rtl8201_read_mode(), run_all_tests(), run_tests(), send_test_pkt(), set_core_exec(), set_rx_mode(), shell_banner(), show_exec(), sis900_get_mac_addr(), sis900_init_rxd(), sis900_init_rxfilter(), sis900_init_txd(), sis900_poll(), sis900_probe(), sis900_read_mode(), sis900_transmit(), sis96x_get_mac_addr(), smc9000_poll(), smc9000_probe(), smc9000_transmit(), smc_detect_phy(), smc_read_phy_register(), smc_write_phy_register(), sundance_poll(), sundance_probe(), sundance_transmit(), sync_exec(), t509_poll(), t509_transmit(), t515_poll(), t515_reset(), t529_probe(), t595_poll(), t595_transmit(), t5x9_probe(), test_ok(), time_exec(), TLan_PhyDetect(), TLan_PhyFinishAutoNeg(), tlan_probe(), tlan_transmit(), umalloc_test(), uriboot(), vcreate_exec(), vdestroy_exec(), vt6103_read_mode(), vxge_probe(), vxgetlink(), vxsetlink(), w89c840_poll(), w89c840_probe(), w89c840_reset(), and w89c840_transmit().

                                    {
        va_list args;
        int i;

        va_start ( args, fmt );
        i = vprintf ( fmt, args );
        va_end ( args );
        return i;
}

Variable Documentation

uint8_t type_sizes[] [static]
Initial value:
 {
        [CHAR_LEN]      = sizeof ( char ),
        [SHORT_LEN]     = sizeof ( short ),
        [INT_LEN]       = sizeof ( int ),
        [LONG_LEN]      = sizeof ( long ),
        [LONGLONG_LEN]  = sizeof ( long long ),
        [SIZE_T_LEN]    = sizeof ( size_t ),
}

Definition at line 42 of file vsprintf.c.

Referenced by vcprintf().