From 2434746dd4bc0c8c00d5a94e44f05604e2dca304 Mon Sep 17 00:00:00 2001 From: Imre Kaloz Date: Sun, 27 Dec 2009 21:28:02 +0000 Subject: 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 --- .../patches-2.6.28/981-vsprintf_backport.patch | 888 --------------------- 1 file changed, 888 deletions(-) delete mode 100644 target/linux/generic-2.6/patches-2.6.28/981-vsprintf_backport.patch (limited to 'target/linux/generic-2.6/patches-2.6.28/981-vsprintf_backport.patch') 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 37589b188f..0000000000 --- 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 = ""; - -- 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); - -- cgit v1.2.3