summaryrefslogtreecommitdiffstats
path: root/target/linux/generic-2.6/patches-2.6.28/981-vsprintf_backport.patch
diff options
context:
space:
mode:
authorkaloz <kaloz@3c298f89-4303-0410-b956-a3cf2f4a3e73>2009-12-27 21:28:02 +0000
committerkaloz <kaloz@3c298f89-4303-0410-b956-a3cf2f4a3e73>2009-12-27 21:28:02 +0000
commitb281497b69f2ecc02747c8e5d9cdd2b19cf95429 (patch)
tree180b2c74131eb4d4bd7c855e1de0ca28bda8127c /target/linux/generic-2.6/patches-2.6.28/981-vsprintf_backport.patch
parent259f6426607dfd76f98eb9ffa44cb88554ffeffc (diff)
switch ixp4xx and ubicom32 to 2.6.30, get rid of 2.6.28 files
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@18952 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux/generic-2.6/patches-2.6.28/981-vsprintf_backport.patch')
-rw-r--r--target/linux/generic-2.6/patches-2.6.28/981-vsprintf_backport.patch888
1 files changed, 0 insertions, 888 deletions
diff --git a/target/linux/generic-2.6/patches-2.6.28/981-vsprintf_backport.patch b/target/linux/generic-2.6/patches-2.6.28/981-vsprintf_backport.patch
deleted file mode 100644
index 37589b188..000000000
--- a/target/linux/generic-2.6/patches-2.6.28/981-vsprintf_backport.patch
+++ /dev/null
@@ -1,888 +0,0 @@
---- a/lib/vsprintf.c
-+++ b/lib/vsprintf.c
-@@ -170,6 +170,8 @@ int strict_strtoul(const char *cp, unsig
- return -EINVAL;
-
- val = simple_strtoul(cp, &tail, base);
-+ if (tail == cp)
-+ return -EINVAL;
- if ((*tail == '\0') ||
- ((len == (size_t)(tail - cp) + 1) && (*tail == '\n'))) {
- *res = val;
-@@ -241,6 +243,8 @@ int strict_strtoull(const char *cp, unsi
- return -EINVAL;
-
- val = simple_strtoull(cp, &tail, base);
-+ if (tail == cp)
-+ return -EINVAL;
- if ((*tail == '\0') ||
- ((len == (size_t)(tail - cp) + 1) && (*tail == '\n'))) {
- *res = val;
-@@ -392,7 +396,38 @@ static noinline char* put_dec(char *buf,
- #define SMALL 32 /* Must be 32 == 0x20 */
- #define SPECIAL 64 /* 0x */
-
--static char *number(char *buf, char *end, unsigned long long num, int base, int size, int precision, int type)
-+enum format_type {
-+ FORMAT_TYPE_NONE, /* Just a string part */
-+ FORMAT_TYPE_WIDTH,
-+ FORMAT_TYPE_PRECISION,
-+ FORMAT_TYPE_CHAR,
-+ FORMAT_TYPE_STR,
-+ FORMAT_TYPE_PTR,
-+ FORMAT_TYPE_PERCENT_CHAR,
-+ FORMAT_TYPE_INVALID,
-+ FORMAT_TYPE_LONG_LONG,
-+ FORMAT_TYPE_ULONG,
-+ FORMAT_TYPE_LONG,
-+ FORMAT_TYPE_USHORT,
-+ FORMAT_TYPE_SHORT,
-+ FORMAT_TYPE_UINT,
-+ FORMAT_TYPE_INT,
-+ FORMAT_TYPE_NRCHARS,
-+ FORMAT_TYPE_SIZE_T,
-+ FORMAT_TYPE_PTRDIFF
-+};
-+
-+struct printf_spec {
-+ enum format_type type;
-+ int flags; /* flags to number() */
-+ int field_width; /* width of output field */
-+ int base;
-+ int precision; /* # of digits/chars */
-+ int qualifier;
-+};
-+
-+static char *number(char *buf, char *end, unsigned long long num,
-+ struct printf_spec spec)
- {
- /* we are called with base 8, 10 or 16, only, thus don't need "G..." */
- static const char digits[16] = "0123456789ABCDEF"; /* "GHIJKLMNOPQRSTUVWXYZ"; */
-@@ -400,32 +435,32 @@ static char *number(char *buf, char *end
- char tmp[66];
- char sign;
- char locase;
-- int need_pfx = ((type & SPECIAL) && base != 10);
-+ int need_pfx = ((spec.flags & SPECIAL) && spec.base != 10);
- int i;
-
- /* locase = 0 or 0x20. ORing digits or letters with 'locase'
- * produces same digits or (maybe lowercased) letters */
-- locase = (type & SMALL);
-- if (type & LEFT)
-- type &= ~ZEROPAD;
-+ locase = (spec.flags & SMALL);
-+ if (spec.flags & LEFT)
-+ spec.flags &= ~ZEROPAD;
- sign = 0;
-- if (type & SIGN) {
-+ if (spec.flags & SIGN) {
- if ((signed long long) num < 0) {
- sign = '-';
- num = - (signed long long) num;
-- size--;
-- } else if (type & PLUS) {
-+ spec.field_width--;
-+ } else if (spec.flags & PLUS) {
- sign = '+';
-- size--;
-- } else if (type & SPACE) {
-+ spec.field_width--;
-+ } else if (spec.flags & SPACE) {
- sign = ' ';
-- size--;
-+ spec.field_width--;
- }
- }
- if (need_pfx) {
-- size--;
-- if (base == 16)
-- size--;
-+ spec.field_width--;
-+ if (spec.base == 16)
-+ spec.field_width--;
- }
-
- /* generate full string in tmp[], in reverse order */
-@@ -437,10 +472,10 @@ static char *number(char *buf, char *end
- tmp[i++] = (digits[do_div(num,base)] | locase);
- } while (num != 0);
- */
-- else if (base != 10) { /* 8 or 16 */
-- int mask = base - 1;
-+ else if (spec.base != 10) { /* 8 or 16 */
-+ int mask = spec.base - 1;
- int shift = 3;
-- if (base == 16) shift = 4;
-+ if (spec.base == 16) shift = 4;
- do {
- tmp[i++] = (digits[((unsigned char)num) & mask] | locase);
- num >>= shift;
-@@ -450,12 +485,12 @@ static char *number(char *buf, char *end
- }
-
- /* printing 100 using %2d gives "100", not "00" */
-- if (i > precision)
-- precision = i;
-+ if (i > spec.precision)
-+ spec.precision = i;
- /* leading space padding */
-- size -= precision;
-- if (!(type & (ZEROPAD+LEFT))) {
-- while(--size >= 0) {
-+ spec.field_width -= spec.precision;
-+ if (!(spec.flags & (ZEROPAD+LEFT))) {
-+ while(--spec.field_width >= 0) {
- if (buf < end)
- *buf = ' ';
- ++buf;
-@@ -472,23 +507,23 @@ static char *number(char *buf, char *end
- if (buf < end)
- *buf = '0';
- ++buf;
-- if (base == 16) {
-+ if (spec.base == 16) {
- if (buf < end)
- *buf = ('X' | locase);
- ++buf;
- }
- }
- /* zero or space padding */
-- if (!(type & LEFT)) {
-- char c = (type & ZEROPAD) ? '0' : ' ';
-- while (--size >= 0) {
-+ if (!(spec.flags & LEFT)) {
-+ char c = (spec.flags & ZEROPAD) ? '0' : ' ';
-+ while (--spec.field_width >= 0) {
- if (buf < end)
- *buf = c;
- ++buf;
- }
- }
- /* hmm even more zero padding? */
-- while (i <= --precision) {
-+ while (i <= --spec.precision) {
- if (buf < end)
- *buf = '0';
- ++buf;
-@@ -500,7 +535,7 @@ static char *number(char *buf, char *end
- ++buf;
- }
- /* trailing space padding */
-- while (--size >= 0) {
-+ while (--spec.field_width >= 0) {
- if (buf < end)
- *buf = ' ';
- ++buf;
-@@ -508,17 +543,17 @@ static char *number(char *buf, char *end
- return buf;
- }
-
--static char *string(char *buf, char *end, char *s, int field_width, int precision, int flags)
-+static char *string(char *buf, char *end, char *s, struct printf_spec spec)
- {
- int len, i;
-
- if ((unsigned long)s < PAGE_SIZE)
- s = "<NULL>";
-
-- len = strnlen(s, precision);
-+ len = strnlen(s, spec.precision);
-
-- if (!(flags & LEFT)) {
-- while (len < field_width--) {
-+ if (!(spec.flags & LEFT)) {
-+ while (len < spec.field_width--) {
- if (buf < end)
- *buf = ' ';
- ++buf;
-@@ -529,7 +564,7 @@ static char *string(char *buf, char *end
- *buf = *s;
- ++buf; ++s;
- }
-- while (len < field_width--) {
-+ while (len < spec.field_width--) {
- if (buf < end)
- *buf = ' ';
- ++buf;
-@@ -537,21 +572,24 @@ static char *string(char *buf, char *end
- return buf;
- }
-
--static char *symbol_string(char *buf, char *end, void *ptr, int field_width, int precision, int flags)
-+static char *symbol_string(char *buf, char *end, void *ptr,
-+ struct printf_spec spec)
- {
- unsigned long value = (unsigned long) ptr;
- #ifdef CONFIG_KALLSYMS
- char sym[KSYM_SYMBOL_LEN];
- sprint_symbol(sym, value);
-- return string(buf, end, sym, field_width, precision, flags);
-+ return string(buf, end, sym, spec);
- #else
-- field_width = 2*sizeof(void *);
-- flags |= SPECIAL | SMALL | ZEROPAD;
-- return number(buf, end, value, 16, field_width, precision, flags);
-+ spec.field_width = 2*sizeof(void *);
-+ spec.flags |= SPECIAL | SMALL | ZEROPAD;
-+ spec.base = 16;
-+ return number(buf, end, value, spec);
- #endif
- }
-
--static char *resource_string(char *buf, char *end, struct resource *res, int field_width, int precision, int flags)
-+static char *resource_string(char *buf, char *end, struct resource *res,
-+ struct printf_spec spec)
- {
- #ifndef IO_RSRC_PRINTK_SIZE
- #define IO_RSRC_PRINTK_SIZE 4
-@@ -560,7 +598,11 @@ static char *resource_string(char *buf,
- #ifndef MEM_RSRC_PRINTK_SIZE
- #define MEM_RSRC_PRINTK_SIZE 8
- #endif
--
-+ struct printf_spec num_spec = {
-+ .base = 16,
-+ .precision = -1,
-+ .flags = SPECIAL | SMALL | ZEROPAD,
-+ };
- /* room for the actual numbers, the two "0x", -, [, ] and the final zero */
- char sym[4*sizeof(resource_size_t) + 8];
- char *p = sym, *pend = sym + sizeof(sym);
-@@ -572,13 +614,73 @@ static char *resource_string(char *buf,
- size = MEM_RSRC_PRINTK_SIZE;
-
- *p++ = '[';
-- p = number(p, pend, res->start, 16, size, -1, SPECIAL | SMALL | ZEROPAD);
-+ num_spec.field_width = size;
-+ p = number(p, pend, res->start, num_spec);
- *p++ = '-';
-- p = number(p, pend, res->end, 16, size, -1, SPECIAL | SMALL | ZEROPAD);
-+ p = number(p, pend, res->end, num_spec);
- *p++ = ']';
- *p = 0;
-
-- return string(buf, end, sym, field_width, precision, flags);
-+ return string(buf, end, sym, spec);
-+}
-+
-+static char *mac_address_string(char *buf, char *end, u8 *addr,
-+ struct printf_spec spec)
-+{
-+ char mac_addr[6 * 3]; /* (6 * 2 hex digits), 5 colons and trailing zero */
-+ char *p = mac_addr;
-+ int i;
-+
-+ for (i = 0; i < 6; i++) {
-+ p = pack_hex_byte(p, addr[i]);
-+ if (!(spec.flags & SPECIAL) && i != 5)
-+ *p++ = ':';
-+ }
-+ *p = '\0';
-+ spec.flags &= ~SPECIAL;
-+
-+ return string(buf, end, mac_addr, spec);
-+}
-+
-+static char *ip6_addr_string(char *buf, char *end, u8 *addr,
-+ struct printf_spec spec)
-+{
-+ char ip6_addr[8 * 5]; /* (8 * 4 hex digits), 7 colons and trailing zero */
-+ char *p = ip6_addr;
-+ int i;
-+
-+ for (i = 0; i < 8; i++) {
-+ p = pack_hex_byte(p, addr[2 * i]);
-+ p = pack_hex_byte(p, addr[2 * i + 1]);
-+ if (!(spec.flags & SPECIAL) && i != 7)
-+ *p++ = ':';
-+ }
-+ *p = '\0';
-+ spec.flags &= ~SPECIAL;
-+
-+ return string(buf, end, ip6_addr, spec);
-+}
-+
-+static char *ip4_addr_string(char *buf, char *end, u8 *addr,
-+ struct printf_spec spec)
-+{
-+ char ip4_addr[4 * 4]; /* (4 * 3 decimal digits), 3 dots and trailing zero */
-+ char temp[3]; /* hold each IP quad in reverse order */
-+ char *p = ip4_addr;
-+ int i, digits;
-+
-+ for (i = 0; i < 4; i++) {
-+ digits = put_dec_trunc(temp, addr[i]) - temp;
-+ /* reverse the digits in the quad */
-+ while (digits--)
-+ *p++ = temp[digits];
-+ if (i != 3)
-+ *p++ = '.';
-+ }
-+ *p = '\0';
-+ spec.flags &= ~SPECIAL;
-+
-+ return string(buf, end, ip4_addr, spec);
- }
-
- /*
-@@ -592,28 +694,244 @@ static char *resource_string(char *buf,
- * - 'S' For symbolic direct pointers
- * - 'R' For a struct resource pointer, it prints the range of
- * addresses (not the name nor the flags)
-+ * - 'M' For a 6-byte MAC address, it prints the address in the
-+ * usual colon-separated hex notation
-+ * - 'I' [46] for IPv4/IPv6 addresses printed in the usual way (dot-separated
-+ * decimal for v4 and colon separated network-order 16 bit hex for v6)
-+ * - 'i' [46] for 'raw' IPv4/IPv6 addresses, IPv6 omits the colons, IPv4 is
-+ * currently the same
- *
- * Note: The difference between 'S' and 'F' is that on ia64 and ppc64
- * function pointers are really function descriptors, which contain a
- * pointer to the real address.
- */
--static char *pointer(const char *fmt, char *buf, char *end, void *ptr, int field_width, int precision, int flags)
-+static char *pointer(const char *fmt, char *buf, char *end, void *ptr,
-+ struct printf_spec spec)
- {
-+ if (!ptr)
-+ return string(buf, end, "(null)", spec);
-+
- switch (*fmt) {
- case 'F':
- ptr = dereference_function_descriptor(ptr);
- /* Fallthrough */
- case 'S':
-- return symbol_string(buf, end, ptr, field_width, precision, flags);
-+ return symbol_string(buf, end, ptr, spec);
- case 'R':
-- return resource_string(buf, end, ptr, field_width, precision, flags);
-+ return resource_string(buf, end, ptr, spec);
-+ case 'm':
-+ spec.flags |= SPECIAL;
-+ /* Fallthrough */
-+ case 'M':
-+ return mac_address_string(buf, end, ptr, spec);
-+ case 'i':
-+ spec.flags |= SPECIAL;
-+ /* Fallthrough */
-+ case 'I':
-+ if (fmt[1] == '6')
-+ return ip6_addr_string(buf, end, ptr, spec);
-+ if (fmt[1] == '4')
-+ return ip4_addr_string(buf, end, ptr, spec);
-+ spec.flags &= ~SPECIAL;
-+ break;
- }
-- flags |= SMALL;
-- if (field_width == -1) {
-- field_width = 2*sizeof(void *);
-- flags |= ZEROPAD;
-+ spec.flags |= SMALL;
-+ if (spec.field_width == -1) {
-+ spec.field_width = 2*sizeof(void *);
-+ spec.flags |= ZEROPAD;
- }
-- return number(buf, end, (unsigned long) ptr, 16, field_width, precision, flags);
-+ spec.base = 16;
-+
-+ return number(buf, end, (unsigned long) ptr, spec);
-+}
-+
-+/*
-+ * Helper function to decode printf style format.
-+ * Each call decode a token from the format and return the
-+ * number of characters read (or likely the delta where it wants
-+ * to go on the next call).
-+ * The decoded token is returned through the parameters
-+ *
-+ * 'h', 'l', or 'L' for integer fields
-+ * 'z' support added 23/7/1999 S.H.
-+ * 'z' changed to 'Z' --davidm 1/25/99
-+ * 't' added for ptrdiff_t
-+ *
-+ * @fmt: the format string
-+ * @type of the token returned
-+ * @flags: various flags such as +, -, # tokens..
-+ * @field_width: overwritten width
-+ * @base: base of the number (octal, hex, ...)
-+ * @precision: precision of a number
-+ * @qualifier: qualifier of a number (long, size_t, ...)
-+ */
-+static int format_decode(const char *fmt, struct printf_spec *spec)
-+{
-+ const char *start = fmt;
-+
-+ /* we finished early by reading the field width */
-+ if (spec->type == FORMAT_TYPE_WIDTH) {
-+ if (spec->field_width < 0) {
-+ spec->field_width = -spec->field_width;
-+ spec->flags |= LEFT;
-+ }
-+ spec->type = FORMAT_TYPE_NONE;
-+ goto precision;
-+ }
-+
-+ /* we finished early by reading the precision */
-+ if (spec->type == FORMAT_TYPE_PRECISION) {
-+ if (spec->precision < 0)
-+ spec->precision = 0;
-+
-+ spec->type = FORMAT_TYPE_NONE;
-+ goto qualifier;
-+ }
-+
-+ /* By default */
-+ spec->type = FORMAT_TYPE_NONE;
-+
-+ for (; *fmt ; ++fmt) {
-+ if (*fmt == '%')
-+ break;
-+ }
-+
-+ /* Return the current non-format string */
-+ if (fmt != start || !*fmt)
-+ return fmt - start;
-+
-+ /* Process flags */
-+ spec->flags = 0;
-+
-+ while (1) { /* this also skips first '%' */
-+ bool found = true;
-+
-+ ++fmt;
-+
-+ switch (*fmt) {
-+ case '-': spec->flags |= LEFT; break;
-+ case '+': spec->flags |= PLUS; break;
-+ case ' ': spec->flags |= SPACE; break;
-+ case '#': spec->flags |= SPECIAL; break;
-+ case '0': spec->flags |= ZEROPAD; break;
-+ default: found = false;
-+ }
-+
-+ if (!found)
-+ break;
-+ }
-+
-+ /* get field width */
-+ spec->field_width = -1;
-+
-+ if (isdigit(*fmt))
-+ spec->field_width = skip_atoi(&fmt);
-+ else if (*fmt == '*') {
-+ /* it's the next argument */
-+ spec->type = FORMAT_TYPE_WIDTH;
-+ return ++fmt - start;
-+ }
-+
-+precision:
-+ /* get the precision */
-+ spec->precision = -1;
-+ if (*fmt == '.') {
-+ ++fmt;
-+ if (isdigit(*fmt)) {
-+ spec->precision = skip_atoi(&fmt);
-+ if (spec->precision < 0)
-+ spec->precision = 0;
-+ } else if (*fmt == '*') {
-+ /* it's the next argument */
-+ spec->type = FORMAT_TYPE_PRECISION;
-+ return ++fmt - start;
-+ }
-+ }
-+
-+qualifier:
-+ /* get the conversion qualifier */
-+ spec->qualifier = -1;
-+ if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' ||
-+ *fmt == 'Z' || *fmt == 'z' || *fmt == 't') {
-+ spec->qualifier = *fmt;
-+ ++fmt;
-+ if (spec->qualifier == 'l' && *fmt == 'l') {
-+ spec->qualifier = 'L';
-+ ++fmt;
-+ }
-+ }
-+
-+ /* default base */
-+ spec->base = 10;
-+ switch (*fmt) {
-+ case 'c':
-+ spec->type = FORMAT_TYPE_CHAR;
-+ return ++fmt - start;
-+
-+ case 's':
-+ spec->type = FORMAT_TYPE_STR;
-+ return ++fmt - start;
-+
-+ case 'p':
-+ spec->type = FORMAT_TYPE_PTR;
-+ return fmt - start;
-+ /* skip alnum */
-+
-+ case 'n':
-+ spec->type = FORMAT_TYPE_NRCHARS;
-+ return ++fmt - start;
-+
-+ case '%':
-+ spec->type = FORMAT_TYPE_PERCENT_CHAR;
-+ return ++fmt - start;
-+
-+ /* integer number formats - set up the flags and "break" */
-+ case 'o':
-+ spec->base = 8;
-+ break;
-+
-+ case 'x':
-+ spec->flags |= SMALL;
-+
-+ case 'X':
-+ spec->base = 16;
-+ break;
-+
-+ case 'd':
-+ case 'i':
-+ spec->flags |= SIGN;
-+ case 'u':
-+ break;
-+
-+ default:
-+ spec->type = FORMAT_TYPE_INVALID;
-+ return fmt - start;
-+ }
-+
-+ if (spec->qualifier == 'L')
-+ spec->type = FORMAT_TYPE_LONG_LONG;
-+ else if (spec->qualifier == 'l') {
-+ if (spec->flags & SIGN)
-+ spec->type = FORMAT_TYPE_LONG;
-+ else
-+ spec->type = FORMAT_TYPE_ULONG;
-+ } else if (spec->qualifier == 'Z' || spec->qualifier == 'z') {
-+ spec->type = FORMAT_TYPE_SIZE_T;
-+ } else if (spec->qualifier == 't') {
-+ spec->type = FORMAT_TYPE_PTRDIFF;
-+ } else if (spec->qualifier == 'h') {
-+ if (spec->flags & SIGN)
-+ spec->type = FORMAT_TYPE_SHORT;
-+ else
-+ spec->type = FORMAT_TYPE_USHORT;
-+ } else {
-+ if (spec->flags & SIGN)
-+ spec->type = FORMAT_TYPE_INT;
-+ else
-+ spec->type = FORMAT_TYPE_UINT;
-+ }
-+
-+ return ++fmt - start;
- }
-
- /**
-@@ -642,18 +960,9 @@ static char *pointer(const char *fmt, ch
- int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
- {
- unsigned long long num;
-- int base;
- char *str, *end, c;
--
-- int flags; /* flags to number() */
--
-- int field_width; /* width of output field */
-- int precision; /* min. # of digits for integers; max
-- number of chars for from string */
-- int qualifier; /* 'h', 'l', or 'L' for integer fields */
-- /* 'z' support added 23/7/1999 S.H. */
-- /* 'z' changed to 'Z' --davidm 1/25/99 */
-- /* 't' added for ptrdiff_t */
-+ int read;
-+ struct printf_spec spec = {0};
-
- /* Reject out-of-range values early. Large positive sizes are
- used for unknown buffer sizes. */
-@@ -674,184 +983,137 @@ int vsnprintf(char *buf, size_t size, co
- size = end - buf;
- }
-
-- for (; *fmt ; ++fmt) {
-- if (*fmt != '%') {
-- if (str < end)
-- *str = *fmt;
-- ++str;
-- continue;
-- }
-+ while (*fmt) {
-+ const char *old_fmt = fmt;
-
-- /* process flags */
-- flags = 0;
-- repeat:
-- ++fmt; /* this also skips first '%' */
-- switch (*fmt) {
-- case '-': flags |= LEFT; goto repeat;
-- case '+': flags |= PLUS; goto repeat;
-- case ' ': flags |= SPACE; goto repeat;
-- case '#': flags |= SPECIAL; goto repeat;
-- case '0': flags |= ZEROPAD; goto repeat;
-- }
-+ read = format_decode(fmt, &spec);
-
-- /* get field width */
-- field_width = -1;
-- if (isdigit(*fmt))
-- field_width = skip_atoi(&fmt);
-- else if (*fmt == '*') {
-- ++fmt;
-- /* it's the next argument */
-- field_width = va_arg(args, int);
-- if (field_width < 0) {
-- field_width = -field_width;
-- flags |= LEFT;
-- }
-- }
-+ fmt += read;
-
-- /* get the precision */
-- precision = -1;
-- if (*fmt == '.') {
-- ++fmt;
-- if (isdigit(*fmt))
-- precision = skip_atoi(&fmt);
-- else if (*fmt == '*') {
-- ++fmt;
-- /* it's the next argument */
-- precision = va_arg(args, int);
-+ switch (spec.type) {
-+ case FORMAT_TYPE_NONE: {
-+ int copy = read;
-+ if (str < end) {
-+ if (copy > end - str)
-+ copy = end - str;
-+ memcpy(str, old_fmt, copy);
- }
-- if (precision < 0)
-- precision = 0;
-+ str += read;
-+ break;
- }
-
-- /* get the conversion qualifier */
-- qualifier = -1;
-- if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' ||
-- *fmt =='Z' || *fmt == 'z' || *fmt == 't') {
-- qualifier = *fmt;
-- ++fmt;
-- if (qualifier == 'l' && *fmt == 'l') {
-- qualifier = 'L';
-- ++fmt;
-- }
-- }
-+ case FORMAT_TYPE_WIDTH:
-+ spec.field_width = va_arg(args, int);
-+ break;
-
-- /* default base */
-- base = 10;
-+ case FORMAT_TYPE_PRECISION:
-+ spec.precision = va_arg(args, int);
-+ break;
-
-- switch (*fmt) {
-- case 'c':
-- if (!(flags & LEFT)) {
-- while (--field_width > 0) {
-- if (str < end)
-- *str = ' ';
-- ++str;
-- }
-- }
-- c = (unsigned char) va_arg(args, int);
-- if (str < end)
-- *str = c;
-- ++str;
-- while (--field_width > 0) {
-+ case FORMAT_TYPE_CHAR:
-+ if (!(spec.flags & LEFT)) {
-+ while (--spec.field_width > 0) {
- if (str < end)
- *str = ' ';
- ++str;
-- }
-- continue;
--
-- case 's':
-- str = string(str, end, va_arg(args, char *), field_width, precision, flags);
-- continue;
--
-- case 'p':
-- str = pointer(fmt+1, str, end,
-- va_arg(args, void *),
-- field_width, precision, flags);
-- /* Skip all alphanumeric pointer suffixes */
-- while (isalnum(fmt[1]))
-- fmt++;
-- continue;
-
-- case 'n':
-- /* FIXME:
-- * What does C99 say about the overflow case here? */
-- if (qualifier == 'l') {
-- long * ip = va_arg(args, long *);
-- *ip = (str - buf);
-- } else if (qualifier == 'Z' || qualifier == 'z') {
-- size_t * ip = va_arg(args, size_t *);
-- *ip = (str - buf);
-- } else {
-- int * ip = va_arg(args, int *);
-- *ip = (str - buf);
- }
-- continue;
--
-- case '%':
-+ }
-+ c = (unsigned char) va_arg(args, int);
-+ if (str < end)
-+ *str = c;
-+ ++str;
-+ while (--spec.field_width > 0) {
- if (str < end)
-- *str = '%';
-+ *str = ' ';
- ++str;
-- continue;
-+ }
-+ break;
-
-- /* integer number formats - set up the flags and "break" */
-- case 'o':
-- base = 8;
-- break;
-+ case FORMAT_TYPE_STR:
-+ str = string(str, end, va_arg(args, char *), spec);
-+ break;
-
-- case 'x':
-- flags |= SMALL;
-- case 'X':
-- base = 16;
-- break;
-+ case FORMAT_TYPE_PTR:
-+ str = pointer(fmt+1, str, end, va_arg(args, void *),
-+ spec);
-+ while (isalnum(*fmt))
-+ fmt++;
-+ break;
-
-- case 'd':
-- case 'i':
-- flags |= SIGN;
-- case 'u':
-- break;
-+ case FORMAT_TYPE_PERCENT_CHAR:
-+ if (str < end)
-+ *str = '%';
-+ ++str;
-+ break;
-
-- default:
-- if (str < end)
-- *str = '%';
-- ++str;
-- if (*fmt) {
-- if (str < end)
-- *str = *fmt;
-- ++str;
-- } else {
-- --fmt;
-- }
-- continue;
-+ case FORMAT_TYPE_INVALID:
-+ if (str < end)
-+ *str = '%';
-+ ++str;
-+ break;
-+
-+ case FORMAT_TYPE_NRCHARS: {
-+ int qualifier = spec.qualifier;
-+
-+ if (qualifier == 'l') {
-+ long *ip = va_arg(args, long *);
-+ *ip = (str - buf);
-+ } else if (qualifier == 'Z' ||
-+ qualifier == 'z') {
-+ size_t *ip = va_arg(args, size_t *);
-+ *ip = (str - buf);
-+ } else {
-+ int *ip = va_arg(args, int *);
-+ *ip = (str - buf);
-+ }
-+ break;
- }
-- if (qualifier == 'L')
-- num = va_arg(args, long long);
-- else if (qualifier == 'l') {
-- num = va_arg(args, unsigned long);
-- if (flags & SIGN)
-- num = (signed long) num;
-- } else if (qualifier == 'Z' || qualifier == 'z') {
-- num = va_arg(args, size_t);
-- } else if (qualifier == 't') {
-- num = va_arg(args, ptrdiff_t);
-- } else if (qualifier == 'h') {
-- num = (unsigned short) va_arg(args, int);
-- if (flags & SIGN)
-- num = (signed short) num;
-- } else {
-- num = va_arg(args, unsigned int);
-- if (flags & SIGN)
-- num = (signed int) num;
-+
-+ default:
-+ switch (spec.type) {
-+ case FORMAT_TYPE_LONG_LONG:
-+ num = va_arg(args, long long);
-+ break;
-+ case FORMAT_TYPE_ULONG:
-+ num = va_arg(args, unsigned long);
-+ break;
-+ case FORMAT_TYPE_LONG:
-+ num = va_arg(args, long);
-+ break;
-+ case FORMAT_TYPE_SIZE_T:
-+ num = va_arg(args, size_t);
-+ break;
-+ case FORMAT_TYPE_PTRDIFF:
-+ num = va_arg(args, ptrdiff_t);
-+ break;
-+ case FORMAT_TYPE_USHORT:
-+ num = (unsigned short) va_arg(args, int);
-+ break;
-+ case FORMAT_TYPE_SHORT:
-+ num = (short) va_arg(args, int);
-+ break;
-+ case FORMAT_TYPE_INT:
-+ num = (int) va_arg(args, int);
-+ break;
-+ default:
-+ num = va_arg(args, unsigned int);
-+ }
-+
-+ str = number(str, end, num, spec);
- }
-- str = number(str, end, num, base,
-- field_width, precision, flags);
- }
-+
- if (size > 0) {
- if (str < end)
- *str = '\0';
- else
- end[-1] = '\0';
- }
-+
- /* the trailing null byte doesn't count towards the total */
- return str-buf;
-+
- }
- EXPORT_SYMBOL(vsnprintf);
-