diff options
Diffstat (limited to 'contrib/syslinux/latest/com32/lib/vsnprintf.c')
-rw-r--r-- | contrib/syslinux/latest/com32/lib/vsnprintf.c | 454 |
1 files changed, 0 insertions, 454 deletions
diff --git a/contrib/syslinux/latest/com32/lib/vsnprintf.c b/contrib/syslinux/latest/com32/lib/vsnprintf.c deleted file mode 100644 index 1d1d2a2..0000000 --- a/contrib/syslinux/latest/com32/lib/vsnprintf.c +++ /dev/null @@ -1,454 +0,0 @@ -/* - * vsnprintf.c - * - * vsnprintf(), from which the rest of the printf() - * family is built - */ - -#include <stdarg.h> -#include <stddef.h> -#include <inttypes.h> -#include <string.h> -#include <limits.h> -#include <stdio.h> - -enum flags { - FL_ZERO = 0x01, /* Zero modifier */ - FL_MINUS = 0x02, /* Minus modifier */ - FL_PLUS = 0x04, /* Plus modifier */ - FL_TICK = 0x08, /* ' modifier */ - FL_SPACE = 0x10, /* Space modifier */ - FL_HASH = 0x20, /* # modifier */ - FL_SIGNED = 0x40, /* Number is signed */ - FL_UPPER = 0x80 /* Upper case digits */ -}; - -/* These may have to be adjusted on certain implementations */ -enum ranks { - rank_char = -2, - rank_short = -1, - rank_int = 0, - rank_long = 1, - rank_longlong = 2 -}; - -#define MIN_RANK rank_char -#define MAX_RANK rank_longlong - -#define INTMAX_RANK rank_longlong -#define SIZE_T_RANK rank_long -#define PTRDIFF_T_RANK rank_long - -#define EMIT(x) ({ if (o<n){*q++ = (x);} o++; }) - -static size_t -format_int(char *q, size_t n, uintmax_t val, enum flags flags, - int base, int width, int prec) -{ - char *qq; - size_t o = 0, oo; - static const char lcdigits[] = "0123456789abcdef"; - static const char ucdigits[] = "0123456789ABCDEF"; - const char *digits; - uintmax_t tmpval; - int minus = 0; - int ndigits = 0, nchars; - int tickskip, b4tick; - - /* Select type of digits */ - digits = (flags & FL_UPPER) ? ucdigits : lcdigits; - - /* If signed, separate out the minus */ - if (flags & FL_SIGNED && (intmax_t) val < 0) { - minus = 1; - val = (uintmax_t) (-(intmax_t) val); - } - - /* Count the number of digits needed. This returns zero for 0. */ - tmpval = val; - while (tmpval) { - tmpval /= base; - ndigits++; - } - - /* Adjust ndigits for size of output */ - - if (flags & FL_HASH && base == 8) { - if (prec < ndigits + 1) - prec = ndigits + 1; - } - - if (ndigits < prec) { - ndigits = prec; /* Mandatory number padding */ - } else if (val == 0) { - ndigits = 1; /* Zero still requires space */ - } - - /* For ', figure out what the skip should be */ - if (flags & FL_TICK) { - tickskip = (base == 16) ? 4 : 3; - } else { - tickskip = ndigits; /* No tick marks */ - } - - /* Tick marks aren't digits, but generated by the number converter */ - ndigits += (ndigits - 1) / tickskip; - - /* Now compute the number of nondigits */ - nchars = ndigits; - - if (minus || (flags & (FL_PLUS | FL_SPACE))) - nchars++; /* Need space for sign */ - if ((flags & FL_HASH) && base == 16) { - nchars += 2; /* Add 0x for hex */ - } - - /* Emit early space padding */ - if (!(flags & (FL_MINUS | FL_ZERO)) && width > nchars) { - while (width > nchars) { - EMIT(' '); - width--; - } - } - - /* Emit nondigits */ - if (minus) - EMIT('-'); - else if (flags & FL_PLUS) - EMIT('+'); - else if (flags & FL_SPACE) - EMIT(' '); - - if ((flags & FL_HASH) && base == 16) { - EMIT('0'); - EMIT((flags & FL_UPPER) ? 'X' : 'x'); - } - - /* Emit zero padding */ - if ((flags & (FL_MINUS | FL_ZERO)) == FL_ZERO && width > ndigits) { - while (width > nchars) { - EMIT('0'); - width--; - } - } - - /* Generate the number. This is done from right to left. */ - q += ndigits; /* Advance the pointer to end of number */ - o += ndigits; - qq = q; - oo = o; /* Temporary values */ - - b4tick = tickskip; - while (ndigits > 0) { - if (!b4tick--) { - qq--; - oo--; - ndigits--; - if (oo < n) - *qq = '_'; - b4tick = tickskip - 1; - } - qq--; - oo--; - ndigits--; - if (oo < n) - *qq = digits[val % base]; - val /= base; - } - - /* Emit late space padding */ - while ((flags & FL_MINUS) && width > nchars) { - EMIT(' '); - width--; - } - - return o; -} - -int vsnprintf(char *buffer, size_t n, const char *format, va_list ap) -{ - const char *p = format; - char ch; - char *q = buffer; - size_t o = 0; /* Number of characters output */ - uintmax_t val = 0; - int rank = rank_int; /* Default rank */ - int width = 0; - int prec = -1; - int base; - size_t sz; - enum flags flags = 0; - enum { - st_normal, /* Ground state */ - st_flags, /* Special flags */ - st_width, /* Field width */ - st_prec, /* Field precision */ - st_modifiers /* Length or conversion modifiers */ - } state = st_normal; - const char *sarg; /* %s string argument */ - char carg; /* %c char argument */ - int slen; /* String length */ - - while ((ch = *p++)) { - switch (state) { - case st_normal: - if (ch == '%') { - state = st_flags; - flags = 0; - rank = rank_int; - width = 0; - prec = -1; - } else { - EMIT(ch); - } - break; - - case st_flags: - switch (ch) { - case '-': - flags |= FL_MINUS; - break; - case '+': - flags |= FL_PLUS; - break; - case '\'': - flags |= FL_TICK; - break; - case ' ': - flags |= FL_SPACE; - break; - case '#': - flags |= FL_HASH; - break; - case '0': - flags |= FL_ZERO; - break; - default: - state = st_width; - p--; /* Process this character again */ - break; - } - break; - - case st_width: - if (ch >= '0' && ch <= '9') { - width = width * 10 + (ch - '0'); - } else if (ch == '*') { - width = va_arg(ap, int); - if (width < 0) { - width = -width; - flags |= FL_MINUS; - } - } else if (ch == '.') { - prec = 0; /* Precision given */ - state = st_prec; - } else { - state = st_modifiers; - p--; /* Process this character again */ - } - break; - - case st_prec: - if (ch >= '0' && ch <= '9') { - prec = prec * 10 + (ch - '0'); - } else if (ch == '*') { - prec = va_arg(ap, int); - if (prec < 0) - prec = -1; - } else { - state = st_modifiers; - p--; /* Process this character again */ - } - break; - - case st_modifiers: - switch (ch) { - /* Length modifiers - nonterminal sequences */ - case 'h': - rank--; /* Shorter rank */ - break; - case 'l': - rank++; /* Longer rank */ - break; - case 'j': - rank = INTMAX_RANK; - break; - case 'z': - rank = SIZE_T_RANK; - break; - case 't': - rank = PTRDIFF_T_RANK; - break; - case 'L': - case 'q': - rank += 2; - break; - default: - /* Output modifiers - terminal sequences */ - state = st_normal; /* Next state will be normal */ - if (rank < MIN_RANK) /* Canonicalize rank */ - rank = MIN_RANK; - else if (rank > MAX_RANK) - rank = MAX_RANK; - - switch (ch) { - case 'P': /* Upper case pointer */ - flags |= FL_UPPER; - /* fall through */ - case 'p': /* Pointer */ - base = 16; - prec = (CHAR_BIT * sizeof(void *) + 3) / 4; - flags |= FL_HASH; - val = (uintmax_t) (uintptr_t) va_arg(ap, void *); - goto is_integer; - - case 'd': /* Signed decimal output */ - case 'i': - base = 10; - flags |= FL_SIGNED; - switch (rank) { - case rank_char: - /* Yes, all these casts are needed... */ - val = - (uintmax_t) (intmax_t) (signed char)va_arg(ap, - signed - int); - break; - case rank_short: - val = - (uintmax_t) (intmax_t) (signed short)va_arg(ap, - signed - int); - break; - case rank_int: - val = (uintmax_t) (intmax_t) va_arg(ap, signed int); - break; - case rank_long: - val = (uintmax_t) (intmax_t) va_arg(ap, signed long); - break; - case rank_longlong: - val = - (uintmax_t) (intmax_t) va_arg(ap, signed long long); - break; - } - goto is_integer; - case 'o': /* Octal */ - base = 8; - goto is_unsigned; - case 'u': /* Unsigned decimal */ - base = 10; - goto is_unsigned; - case 'X': /* Upper case hexadecimal */ - flags |= FL_UPPER; - /* fall through */ - case 'x': /* Hexadecimal */ - base = 16; - goto is_unsigned; - -is_unsigned: - switch (rank) { - case rank_char: - val = - (uintmax_t) (unsigned char)va_arg(ap, unsigned int); - break; - case rank_short: - val = - (uintmax_t) (unsigned short)va_arg(ap, - unsigned int); - break; - case rank_int: - val = (uintmax_t) va_arg(ap, unsigned int); - break; - case rank_long: - val = (uintmax_t) va_arg(ap, unsigned long); - break; - case rank_longlong: - val = (uintmax_t) va_arg(ap, unsigned long long); - break; - } - /* fall through */ - -is_integer: - sz = format_int(q, (o < n) ? n - o : 0, val, flags, base, - width, prec); - q += sz; - o += sz; - break; - - case 'c': /* Character */ - carg = (char)va_arg(ap, int); - sarg = &carg; - slen = 1; - goto is_string; - case 's': /* String */ - sarg = va_arg(ap, const char *); - sarg = sarg ? sarg : "(null)"; - slen = strlen(sarg); - goto is_string; - -is_string: - { - char sch; - int i; - - if (prec != -1 && slen > prec) - slen = prec; - - if (width > slen && !(flags & FL_MINUS)) { - char pad = (flags & FL_ZERO) ? '0' : ' '; - while (width > slen) { - EMIT(pad); - width--; - } - } - for (i = slen; i; i--) { - sch = *sarg++; - EMIT(sch); - } - if (width > slen && (flags & FL_MINUS)) { - while (width > slen) { - EMIT(' '); - width--; - } - } - } - break; - - case 'n': /* Output the number of characters written */ - { - switch (rank) { - case rank_char: - *va_arg(ap, signed char *) = o; - break; - case rank_short: - *va_arg(ap, signed short *) = o; - break; - case rank_int: - *va_arg(ap, signed int *) = o; - break; - case rank_long: - *va_arg(ap, signed long *) = o; - break; - case rank_longlong: - *va_arg(ap, signed long long *) = o; - break; - } - } - break; - - default: /* Anything else, including % */ - EMIT(ch); - break; - } - } - } - } - - /* Null-terminate the string */ - if (o < n) - *q = '\0'; /* No overflow */ - else if (n > 0) - buffer[n - 1] = '\0'; /* Overflow - terminate at end of buffer */ - - return o; -} |