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. More...
 
int vssnprintf (char *buf, ssize_t ssize, const char *fmt, va_list args)
 Version of vsnprintf() that accepts a signed buffer size. More...
 
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:

 - Flag characters
    - '#'           - Alternate form (i.e. "0x" prefix)
    - '0'           - Zero-pad
 - Field widths
 - Length modifiers
    - 'hh'          - Signed / unsigned char
    - 'h'           - Signed / unsigned short
    - 'l'           - Signed / unsigned long
    - 'll'          - Signed / unsigned long long
    - 'z'           - Signed / unsigned size_t
 - Conversion specifiers
    - 'd'           - Signed decimal
    - 'x','X'       - Unsigned hexadecimal
    - 'c'           - Character
    - 's'           - String
    - 'p'           - Pointer

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()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ vcprintf()

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.

187  {
188  int flags;
189  int width;
190  uint8_t *length;
191  char *ptr;
192  char tmp_buf[32]; /* 32 is enough for all numerical formats.
193  * Insane width fields could overflow this buffer. */
194  wchar_t *wptr;
195 
196  /* Initialise context */
197  ctx->len = 0;
198 
199  for ( ; *fmt ; fmt++ ) {
200  /* Pass through ordinary characters */
201  if ( *fmt != '%' ) {
202  cputchar ( ctx, *fmt );
203  continue;
204  }
205  fmt++;
206  /* Process flag characters */
207  flags = 0;
208  for ( ; ; fmt++ ) {
209  if ( *fmt == '#' ) {
210  flags |= ALT_FORM;
211  } else if ( *fmt == '0' ) {
212  flags |= ZPAD;
213  } else {
214  /* End of flag characters */
215  break;
216  }
217  }
218  /* Process field width */
219  width = 0;
220  for ( ; ; fmt++ ) {
221  if ( ( ( unsigned ) ( *fmt - '0' ) ) < 10 ) {
222  width = ( width * 10 ) + ( *fmt - '0' );
223  } else {
224  break;
225  }
226  }
227  /* We don't do floating point */
228  /* Process length modifier */
230  for ( ; ; fmt++ ) {
231  if ( *fmt == 'h' ) {
232  length--;
233  } else if ( *fmt == 'l' ) {
234  length++;
235  } else if ( *fmt == 'z' ) {
237  } else {
238  break;
239  }
240  }
241  /* Process conversion specifier */
242  ptr = tmp_buf + sizeof ( tmp_buf ) - 1;
243  *ptr = '\0';
244  wptr = NULL;
245  if ( *fmt == 'c' ) {
246  if ( length < &type_sizes[LONG_LEN] ) {
247  cputchar ( ctx, va_arg ( args, unsigned int ) );
248  } else {
249  wchar_t wc;
250  size_t len;
251 
252  wc = va_arg ( args, wint_t );
253  len = wcrtomb ( tmp_buf, wc, NULL );
254  tmp_buf[len] = '\0';
255  ptr = tmp_buf;
256  }
257  } else if ( *fmt == 's' ) {
258  if ( length < &type_sizes[LONG_LEN] ) {
259  ptr = va_arg ( args, char * );
260  if ( ! ptr )
261  ptr = "<NULL>";
262  } else {
263  wptr = va_arg ( args, wchar_t * );
264  if ( ! wptr )
265  ptr = "<NULL>";
266  }
267  } else if ( *fmt == 'p' ) {
268  intptr_t ptrval;
269 
270  ptrval = ( intptr_t ) va_arg ( args, void * );
271  ptr = format_hex ( ptr, ptrval, width,
272  ( ALT_FORM | LCASE ) );
273  } else if ( ( *fmt & ~0x20 ) == 'X' ) {
274  unsigned long long hex;
275 
276  flags |= ( *fmt & 0x20 ); /* LCASE */
277  if ( *length >= sizeof ( unsigned long long ) ) {
278  hex = va_arg ( args, unsigned long long );
279  } else if ( *length >= sizeof ( unsigned long ) ) {
280  hex = va_arg ( args, unsigned long );
281  } else {
282  hex = va_arg ( args, unsigned int );
283  }
284  ptr = format_hex ( ptr, hex, width, flags );
285  } else if ( ( *fmt == 'd' ) || ( *fmt == 'i' ) ){
286  signed long decimal;
287 
288  if ( *length >= sizeof ( signed long ) ) {
289  decimal = va_arg ( args, signed long );
290  } else {
291  decimal = va_arg ( args, signed int );
292  }
293  ptr = format_decimal ( ptr, decimal, width, flags );
294  } else {
295  *(--ptr) = *fmt;
296  }
297  /* Write out conversion result */
298  if ( wptr == NULL ) {
299  for ( ; *ptr ; ptr++ ) {
300  cputchar ( ctx, *ptr );
301  }
302  } else {
303  for ( ; *wptr ; wptr++ ) {
304  size_t len = wcrtomb ( tmp_buf, *wptr, NULL );
305  for ( ptr = tmp_buf ; len-- ; ptr++ ) {
306  cputchar ( ctx, *ptr );
307  }
308  }
309  }
310  }
311 
312  return ctx->len;
313 }
uint16_t length
Length.
Definition: intel.h:14
static wchar_t wc
Definition: wchar.h:22
#define ALT_FORM
Use "alternate form".
Definition: vsprintf.c:66
static void cputchar(struct printf_context *ctx, unsigned char c)
Print character via a printf context.
Definition: vsprintf.c:174
static char * format_decimal(char *end, signed long num, int width, int flags)
Format a decimal number.
Definition: vsprintf.c:133
char hex[8]
Count (as an eight-digit hex value)
Definition: pccrd.h:12
#define INT_LEN
no length modifier
Definition: vsprintf.c:37
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
unsigned long intptr_t
Definition: stdint.h:21
#define LCASE
Use lower-case for hexadecimal digits.
Definition: vsprintf.c:58
#define LONG_LEN
"l" length modifier
Definition: vsprintf.c:38
#define SIZE_T_LEN
"z" length modifier
Definition: vsprintf.c:40
#define va_arg(ap, type)
Definition: stdarg.h:8
uint8_t tmp_buf[tmp_len]
Definition: entropy.h:155
#define ZPAD
Use zero padding.
Definition: vsprintf.c:74
static char * format_hex(char *end, unsigned long long num, int width, int flags)
Format a hexadecimal number.
Definition: vsprintf.c:93
static uint8_t type_sizes[]
Definition: vsprintf.c:42
unsigned char uint8_t
Definition: stdint.h:10
uint32_t len
Length.
Definition: ena.h:14
int ssize_t const char * fmt
Definition: vsprintf.h:72
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
__WINT_TYPE__ wint_t
Definition: stddef.h:50
uint8_t flags
Flags.
Definition: ena.h:18

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

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

◆ vssnprintf()

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.

401  {
402 
403  /* Treat negative buffer size as zero buffer size */
404  if ( ssize < 0 )
405  ssize = 0;
406 
407  /* Hand off to vsnprintf */
408  return vsnprintf ( buf, ssize, fmt, args );
409 }
int ssize_t ssize
Definition: vsprintf.h:72
int ssize_t const char * fmt
Definition: vsprintf.h:72
int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
Write a formatted string to a buffer.
Definition: vsprintf.c:351

References sputc_context::buf, fmt, ssize, and vsnprintf().

Referenced by ssnprintf().

◆ __attribute__()

int __attribute__ ( (format(printf, 3, 4))  )

Variable Documentation

◆ ssize

int ssize_t ssize

Definition at line 72 of file vsprintf.h.

Referenced by ssnprintf(), and vssnprintf().

◆ fmt

int int size_t const char int const char * fmt