Merge branch 'next-devicetree' of git://git.secretlab.ca/git/linux-2.6
[linux-2.6.git] / lib / vsprintf.c
index 2e1dda2..46d34b0 100644 (file)
@@ -47,14 +47,14 @@ static unsigned int simple_guess_base(const char *cp)
 }
 
 /**
- * simple_strtoul - convert a string to an unsigned long
+ * simple_strtoull - convert a string to an unsigned long long
  * @cp: The start of the string
  * @endp: A pointer to the end of the parsed string will be placed here
  * @base: The number base to use
  */
-unsigned long simple_strtoul(const char *cp, char **endp, unsigned int base)
+unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base)
 {
-       unsigned long result = 0;
+       unsigned long long result = 0;
 
        if (!base)
                base = simple_guess_base(cp);
@@ -76,54 +76,34 @@ unsigned long simple_strtoul(const char *cp, char **endp, unsigned int base)
 
        return result;
 }
-EXPORT_SYMBOL(simple_strtoul);
+EXPORT_SYMBOL(simple_strtoull);
 
 /**
- * simple_strtol - convert a string to a signed long
+ * simple_strtoul - convert a string to an unsigned long
  * @cp: The start of the string
  * @endp: A pointer to the end of the parsed string will be placed here
  * @base: The number base to use
  */
-long simple_strtol(const char *cp, char **endp, unsigned int base)
+unsigned long simple_strtoul(const char *cp, char **endp, unsigned int base)
 {
-       if (*cp == '-')
-               return -simple_strtoul(cp + 1, endp, base);
-
-       return simple_strtoul(cp, endp, base);
+       return simple_strtoull(cp, endp, base);
 }
-EXPORT_SYMBOL(simple_strtol);
+EXPORT_SYMBOL(simple_strtoul);
 
 /**
- * simple_strtoull - convert a string to an unsigned long long
+ * simple_strtol - convert a string to a signed long
  * @cp: The start of the string
  * @endp: A pointer to the end of the parsed string will be placed here
  * @base: The number base to use
  */
-unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base)
+long simple_strtol(const char *cp, char **endp, unsigned int base)
 {
-       unsigned long long result = 0;
-
-       if (!base)
-               base = simple_guess_base(cp);
-
-       if (base == 16 && cp[0] == '0' && TOLOWER(cp[1]) == 'x')
-               cp += 2;
-
-       while (isxdigit(*cp)) {
-               unsigned int value;
-
-               value = isdigit(*cp) ? *cp - '0' : TOLOWER(*cp) - 'a' + 10;
-               if (value >= base)
-                       break;
-               result = result * base + value;
-               cp++;
-       }
-       if (endp)
-               *endp = (char *)cp;
+       if (*cp == '-')
+               return -simple_strtoul(cp + 1, endp, base);
 
-       return result;
+       return simple_strtoul(cp, endp, base);
 }
-EXPORT_SYMBOL(simple_strtoull);
+EXPORT_SYMBOL(simple_strtol);
 
 /**
  * simple_strtoll - convert a string to a signed long long
@@ -138,6 +118,7 @@ long long simple_strtoll(const char *cp, char **endp, unsigned int base)
 
        return simple_strtoull(cp, endp, base);
 }
+EXPORT_SYMBOL(simple_strtoll);
 
 /**
  * strict_strtoul - convert a string to an unsigned long strictly
@@ -401,8 +382,8 @@ static noinline char *put_dec(char *buf, unsigned long long num)
 #define PLUS   4               /* show plus */
 #define SPACE  8               /* space if plus */
 #define LEFT   16              /* left justified */
-#define SMALL  32              /* Must be 32 == 0x20 */
-#define SPECIAL        64              /* 0x */
+#define SMALL  32              /* use lowercase in hex (must be 32 == 0x20) */
+#define SPECIAL        64              /* prefix hex with "0x", octal with "0" */
 
 enum format_type {
        FORMAT_TYPE_NONE, /* Just a string part */
@@ -428,12 +409,12 @@ enum format_type {
 };
 
 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;
+       u8      type;           /* format_type enum */
+       u8      flags;          /* flags to number() */
+       u8      base;           /* number base, 8, 10 or 16 only */
+       u8      qualifier;      /* number qualifier, one of 'hHlLtzZ' */
+       s16     field_width;    /* width of output field */
+       s16     precision;      /* # of digits/chars */
 };
 
 static char *number(char *buf, char *end, unsigned long long num,
@@ -617,22 +598,35 @@ static char *resource_string(char *buf, char *end, struct resource *res,
 #ifndef MEM_RSRC_PRINTK_SIZE
 #define MEM_RSRC_PRINTK_SIZE   10
 #endif
-       struct printf_spec hex_spec = {
+       static const struct printf_spec io_spec = {
+               .base = 16,
+               .field_width = IO_RSRC_PRINTK_SIZE,
+               .precision = -1,
+               .flags = SPECIAL | SMALL | ZEROPAD,
+       };
+       static const struct printf_spec mem_spec = {
                .base = 16,
+               .field_width = MEM_RSRC_PRINTK_SIZE,
                .precision = -1,
                .flags = SPECIAL | SMALL | ZEROPAD,
        };
-       struct printf_spec dec_spec = {
+       static const struct printf_spec bus_spec = {
+               .base = 16,
+               .field_width = 2,
+               .precision = -1,
+               .flags = SMALL | ZEROPAD,
+       };
+       static const struct printf_spec dec_spec = {
                .base = 10,
                .precision = -1,
                .flags = 0,
        };
-       struct printf_spec str_spec = {
+       static const struct printf_spec str_spec = {
                .field_width = -1,
                .precision = 10,
                .flags = LEFT,
        };
-       struct printf_spec flag_spec = {
+       static const struct printf_spec flag_spec = {
                .base = 16,
                .precision = -1,
                .flags = SPECIAL | SMALL,
@@ -642,47 +636,48 @@ static char *resource_string(char *buf, char *end, struct resource *res,
         * 64-bit res (sizeof==8): 20 chars in dec, 18 in hex ("0x" + 16) */
 #define RSRC_BUF_SIZE          ((2 * sizeof(resource_size_t)) + 4)
 #define FLAG_BUF_SIZE          (2 * sizeof(res->flags))
-#define DECODED_BUF_SIZE       sizeof("[mem - 64bit pref disabled]")
+#define DECODED_BUF_SIZE       sizeof("[mem - 64bit pref window disabled]")
 #define RAW_BUF_SIZE           sizeof("[mem - flags 0x]")
        char sym[max(2*RSRC_BUF_SIZE + DECODED_BUF_SIZE,
                     2*RSRC_BUF_SIZE + FLAG_BUF_SIZE + RAW_BUF_SIZE)];
 
        char *p = sym, *pend = sym + sizeof(sym);
-       int size = -1, addr = 0;
        int decode = (fmt[0] == 'R') ? 1 : 0;
-
-       if (res->flags & IORESOURCE_IO) {
-               size = IO_RSRC_PRINTK_SIZE;
-               addr = 1;
-       } else if (res->flags & IORESOURCE_MEM) {
-               size = MEM_RSRC_PRINTK_SIZE;
-               addr = 1;
-       }
+       const struct printf_spec *specp;
 
        *p++ = '[';
-       if (res->flags & IORESOURCE_IO)
+       if (res->flags & IORESOURCE_IO) {
                p = string(p, pend, "io  ", str_spec);
-       else if (res->flags & IORESOURCE_MEM)
+               specp = &io_spec;
+       } else if (res->flags & IORESOURCE_MEM) {
                p = string(p, pend, "mem ", str_spec);
-       else if (res->flags & IORESOURCE_IRQ)
+               specp = &mem_spec;
+       } else if (res->flags & IORESOURCE_IRQ) {
                p = string(p, pend, "irq ", str_spec);
-       else if (res->flags & IORESOURCE_DMA)
+               specp = &dec_spec;
+       } else if (res->flags & IORESOURCE_DMA) {
                p = string(p, pend, "dma ", str_spec);
-       else {
+               specp = &dec_spec;
+       } else if (res->flags & IORESOURCE_BUS) {
+               p = string(p, pend, "bus ", str_spec);
+               specp = &bus_spec;
+       } else {
                p = string(p, pend, "??? ", str_spec);
+               specp = &mem_spec;
                decode = 0;
        }
-       hex_spec.field_width = size;
-       p = number(p, pend, res->start, addr ? hex_spec : dec_spec);
+       p = number(p, pend, res->start, *specp);
        if (res->start != res->end) {
                *p++ = '-';
-               p = number(p, pend, res->end, addr ? hex_spec : dec_spec);
+               p = number(p, pend, res->end, *specp);
        }
        if (decode) {
                if (res->flags & IORESOURCE_MEM_64)
                        p = string(p, pend, " 64bit", str_spec);
                if (res->flags & IORESOURCE_PREFETCH)
                        p = string(p, pend, " pref", str_spec);
+               if (res->flags & IORESOURCE_WINDOW)
+                       p = string(p, pend, " window", str_spec);
                if (res->flags & IORESOURCE_DISABLED)
                        p = string(p, pend, " disabled", str_spec);
        } else {
@@ -701,24 +696,55 @@ static char *mac_address_string(char *buf, char *end, u8 *addr,
        char mac_addr[sizeof("xx:xx:xx:xx:xx:xx")];
        char *p = mac_addr;
        int i;
+       char separator;
+
+       if (fmt[1] == 'F') {            /* FDDI canonical format */
+               separator = '-';
+       } else {
+               separator = ':';
+       }
 
        for (i = 0; i < 6; i++) {
                p = pack_hex_byte(p, addr[i]);
                if (fmt[0] == 'M' && i != 5)
-                       *p++ = ':';
+                       *p++ = separator;
        }
        *p = '\0';
 
        return string(buf, end, mac_addr, spec);
 }
 
-static char *ip4_string(char *p, const u8 *addr, bool leading_zeros)
+static char *ip4_string(char *p, const u8 *addr, const char *fmt)
 {
        int i;
-
+       bool leading_zeros = (fmt[0] == 'i');
+       int index;
+       int step;
+
+       switch (fmt[2]) {
+       case 'h':
+#ifdef __BIG_ENDIAN
+               index = 0;
+               step = 1;
+#else
+               index = 3;
+               step = -1;
+#endif
+               break;
+       case 'l':
+               index = 3;
+               step = -1;
+               break;
+       case 'n':
+       case 'b':
+       default:
+               index = 0;
+               step = 1;
+               break;
+       }
        for (i = 0; i < 4; i++) {
                char temp[3];   /* hold each IP quad in reverse order */
-               int digits = put_dec_trunc(temp, addr[i]) - temp;
+               int digits = put_dec_trunc(temp, addr[index]) - temp;
                if (leading_zeros) {
                        if (digits < 3)
                                *p++ = '0';
@@ -730,6 +756,7 @@ static char *ip4_string(char *p, const u8 *addr, bool leading_zeros)
                        *p++ = temp[digits];
                if (i < 3)
                        *p++ = '.';
+               index += step;
        }
        *p = '\0';
 
@@ -797,8 +824,9 @@ static char *ip6_compressed_string(char *p, const char *addr)
                                p = pack_hex_byte(p, hi);
                        else
                                *p++ = hex_asc_lo(hi);
+                       p = pack_hex_byte(p, lo);
                }
-               if (hi || lo > 0x0f)
+               else if (lo > 0x0f)
                        p = pack_hex_byte(p, lo);
                else
                        *p++ = hex_asc_lo(lo);
@@ -808,7 +836,7 @@ static char *ip6_compressed_string(char *p, const char *addr)
        if (useIPv4) {
                if (needcolon)
                        *p++ = ':';
-               p = ip4_string(p, &in6.s6_addr[12], false);
+               p = ip4_string(p, &in6.s6_addr[12], "I4");
        }
        *p = '\0';
 
@@ -848,11 +876,57 @@ static char *ip4_addr_string(char *buf, char *end, const u8 *addr,
 {
        char ip4_addr[sizeof("255.255.255.255")];
 
-       ip4_string(ip4_addr, addr, fmt[0] == 'i');
+       ip4_string(ip4_addr, addr, fmt);
 
        return string(buf, end, ip4_addr, spec);
 }
 
+static char *uuid_string(char *buf, char *end, const u8 *addr,
+                        struct printf_spec spec, const char *fmt)
+{
+       char uuid[sizeof("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")];
+       char *p = uuid;
+       int i;
+       static const u8 be[16] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
+       static const u8 le[16] = {3,2,1,0,5,4,7,6,8,9,10,11,12,13,14,15};
+       const u8 *index = be;
+       bool uc = false;
+
+       switch (*(++fmt)) {
+       case 'L':
+               uc = true;              /* fall-through */
+       case 'l':
+               index = le;
+               break;
+       case 'B':
+               uc = true;
+               break;
+       }
+
+       for (i = 0; i < 16; i++) {
+               p = pack_hex_byte(p, addr[index[i]]);
+               switch (i) {
+               case 3:
+               case 5:
+               case 7:
+               case 9:
+                       *p++ = '-';
+                       break;
+               }
+       }
+
+       *p = 0;
+
+       if (uc) {
+               p = uuid;
+               do {
+                       *p = toupper(*p);
+               } while (*(++p));
+       }
+
+       return string(buf, end, uuid, spec);
+}
+
 /*
  * Show a '%p' thing.  A kernel extension is that the '%p' is followed
  * by an extra set of alphanumeric characters that are extended format
@@ -869,14 +943,29 @@ static char *ip4_addr_string(char *buf, char *end, const u8 *addr,
  * - 'M' For a 6-byte MAC address, it prints the address in the
  *       usual colon-separated hex notation
  * - 'm' For a 6-byte MAC address, it prints the hex address without colons
+ * - 'MF' For a 6-byte MAC FDDI address, it prints the address
+ *       with a dash-separated hex notation
  * - 'I' [46] for IPv4/IPv6 addresses printed in the usual way
  *       IPv4 uses dot-separated decimal without leading 0's (1.2.3.4)
  *       IPv6 uses colon separated network-order 16 bit hex with leading 0's
  * - 'i' [46] for 'raw' IPv4/IPv6 addresses
  *       IPv6 omits the colons (01020304...0f)
  *       IPv4 uses dot-separated decimal with leading 0's (010.123.045.006)
+ * - '[Ii]4[hnbl]' IPv4 addresses in host, network, big or little endian order
  * - 'I6c' for IPv6 addresses printed as specified by
- *       http://www.ietf.org/id/draft-kawamura-ipv6-text-representation-03.txt
+ *       http://tools.ietf.org/html/draft-ietf-6man-text-addr-representation-00
+ * - 'U' For a 16 byte UUID/GUID, it prints the UUID/GUID in the form
+ *       "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
+ *       Options for %pU are:
+ *         b big endian lower case hex (default)
+ *         B big endian UPPER case hex
+ *         l little endian lower case hex
+ *         L little endian UPPER case hex
+ *           big endian output byte order is:
+ *             [0][1][2][3]-[4][5]-[6][7]-[8][9]-[10][11][12][13][14][15]
+ *           little endian output byte order is:
+ *             [3][2][1][0]-[5][4]-[7][6]-[8][9]-[10][11][12][13][14][15]
+ *
  * 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.
@@ -891,15 +980,16 @@ static char *pointer(const char *fmt, char *buf, char *end, void *ptr,
        case 'F':
        case 'f':
                ptr = dereference_function_descriptor(ptr);
-       case 's':
                /* Fallthrough */
        case 'S':
+       case 's':
                return symbol_string(buf, end, ptr, spec, *fmt);
        case 'R':
        case 'r':
                return resource_string(buf, end, ptr, spec, fmt);
        case 'M':                       /* Colon separated: 00:01:02:03:04:05 */
        case 'm':                       /* Contiguous: 000102030405 */
+                                       /* [mM]F (FDDI, bit reversed) */
                return mac_address_string(buf, end, ptr, spec, fmt);
        case 'I':                       /* Formatted IP supported
                                         * 4:   1.2.3.4
@@ -917,6 +1007,8 @@ static char *pointer(const char *fmt, char *buf, char *end, void *ptr,
                        return ip4_addr_string(buf, end, ptr, spec, fmt);
                }
                break;
+       case 'U':
+               return uuid_string(buf, end, ptr, spec, fmt);
        }
        spec.flags |= SMALL;
        if (spec.field_width == -1) {
@@ -1034,8 +1126,8 @@ precision:
 qualifier:
        /* get the conversion qualifier */
        spec->qualifier = -1;
-       if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' ||
-           *fmt == 'Z' || *fmt == 'z' || *fmt == 't') {
+       if (*fmt == 'h' || TOLOWER(*fmt) == 'l' ||
+           TOLOWER(*fmt) == 'z' || *fmt == 't') {
                spec->qualifier = *fmt++;
                if (unlikely(spec->qualifier == *fmt)) {
                        if (spec->qualifier == 'l') {
@@ -1102,7 +1194,7 @@ qualifier:
                        spec->type = FORMAT_TYPE_LONG;
                else
                        spec->type = FORMAT_TYPE_ULONG;
-       } else if (spec->qualifier == 'Z' || spec->qualifier == 'z') {
+       } else if (TOLOWER(spec->qualifier) == 'z') {
                spec->type = FORMAT_TYPE_SIZE_T;
        } else if (spec->qualifier == 't') {
                spec->type = FORMAT_TYPE_PTRDIFF;
@@ -1138,7 +1230,18 @@ qualifier:
  * %ps output the name of a text symbol without offset
  * %pF output the name of a function pointer with its offset
  * %pf output the name of a function pointer without its offset
- * %pR output the address range in a struct resource
+ * %pR output the address range in a struct resource with decoded flags
+ * %pr output the address range in a struct resource with raw flags
+ * %pM output a 6-byte MAC address with colons
+ * %pm output a 6-byte MAC address without colons
+ * %pI4 print an IPv4 address without leading zeros
+ * %pi4 print an IPv4 address with leading zeros
+ * %pI6 print an IPv6 address with colons
+ * %pi6 print an IPv6 address without colons
+ * %pI6c print an IPv6 address as specified by
+ *   http://tools.ietf.org/html/draft-ietf-6man-text-addr-representation-00
+ * %pU[bBlL] print a UUID/GUID in big or little endian using lower or upper
+ *   case.
  * %n is ignored
  *
  * The return value is the number of characters which would
@@ -1155,8 +1258,7 @@ qualifier:
 int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
 {
        unsigned long long num;
-       char *str, *end, c;
-       int read;
+       char *str, *end;
        struct printf_spec spec = {0};
 
        /* Reject out-of-range values early.  Large positive sizes are
@@ -1175,8 +1277,7 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
 
        while (*fmt) {
                const char *old_fmt = fmt;
-
-               read = format_decode(fmt, &spec);
+               int read = format_decode(fmt, &spec);
 
                fmt += read;
 
@@ -1200,7 +1301,9 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
                        spec.precision = va_arg(args, int);
                        break;
 
-               case FORMAT_TYPE_CHAR:
+               case FORMAT_TYPE_CHAR: {
+                       char c;
+
                        if (!(spec.flags & LEFT)) {
                                while (--spec.field_width > 0) {
                                        if (str < end)
@@ -1219,6 +1322,7 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
                                ++str;
                        }
                        break;
+               }
 
                case FORMAT_TYPE_STR:
                        str = string(str, end, va_arg(args, char *), spec);
@@ -1244,13 +1348,12 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
                        break;
 
                case FORMAT_TYPE_NRCHARS: {
-                       int qualifier = spec.qualifier;
+                       u8 qualifier = spec.qualifier;
 
                        if (qualifier == 'l') {
                                long *ip = va_arg(args, long *);
                                *ip = (str - buf);
-                       } else if (qualifier == 'Z' ||
-                                       qualifier == 'z') {
+                       } else if (TOLOWER(qualifier) == 'z') {
                                size_t *ip = va_arg(args, size_t *);
                                *ip = (str - buf);
                        } else {
@@ -1464,7 +1567,6 @@ int vbin_printf(u32 *bin_buf, size_t size, const char *fmt, va_list args)
 {
        struct printf_spec spec = {0};
        char *str, *end;
-       int read;
 
        str = (char *)bin_buf;
        end = (char *)(bin_buf + size);
@@ -1490,12 +1592,14 @@ do {                                                                    \
 } while (0)
 
        while (*fmt) {
-               read = format_decode(fmt, &spec);
+               int read = format_decode(fmt, &spec);
 
                fmt += read;
 
                switch (spec.type) {
                case FORMAT_TYPE_NONE:
+               case FORMAT_TYPE_INVALID:
+               case FORMAT_TYPE_PERCENT_CHAR:
                        break;
 
                case FORMAT_TYPE_WIDTH:
@@ -1528,19 +1632,13 @@ do {                                                                    \
                                fmt++;
                        break;
 
-               case FORMAT_TYPE_PERCENT_CHAR:
-                       break;
-
-               case FORMAT_TYPE_INVALID:
-                       break;
-
                case FORMAT_TYPE_NRCHARS: {
                        /* skip %n 's argument */
-                       int qualifier = spec.qualifier;
+                       u8 qualifier = spec.qualifier;
                        void *skip_arg;
                        if (qualifier == 'l')
                                skip_arg = va_arg(args, long *);
-                       else if (qualifier == 'Z' || qualifier == 'z')
+                       else if (TOLOWER(qualifier) == 'z')
                                skip_arg = va_arg(args, size_t *);
                        else
                                skip_arg = va_arg(args, int *);
@@ -1606,10 +1704,9 @@ EXPORT_SYMBOL_GPL(vbin_printf);
  */
 int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf)
 {
-       unsigned long long num;
-       char *str, *end, c;
-       const char *args = (const char *)bin_buf;
        struct printf_spec spec = {0};
+       char *str, *end;
+       const char *args = (const char *)bin_buf;
 
        if (WARN_ON_ONCE((int) size < 0))
                return 0;
@@ -1639,10 +1736,8 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf)
        }
 
        while (*fmt) {
-               int read;
                const char *old_fmt = fmt;
-
-               read = format_decode(fmt, &spec);
+               int read = format_decode(fmt, &spec);
 
                fmt += read;
 
@@ -1666,7 +1761,9 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf)
                        spec.precision = get_arg(int);
                        break;
 
-               case FORMAT_TYPE_CHAR:
+               case FORMAT_TYPE_CHAR: {
+                       char c;
+
                        if (!(spec.flags & LEFT)) {
                                while (--spec.field_width > 0) {
                                        if (str < end)
@@ -1684,11 +1781,11 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf)
                                ++str;
                        }
                        break;
+               }
 
                case FORMAT_TYPE_STR: {
                        const char *str_arg = args;
-                       size_t len = strlen(str_arg);
-                       args += len + 1;
+                       args += strlen(str_arg) + 1;
                        str = string(str, end, (char *)str_arg, spec);
                        break;
                }
@@ -1700,11 +1797,6 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf)
                        break;
 
                case FORMAT_TYPE_PERCENT_CHAR:
-                       if (str < end)
-                               *str = '%';
-                       ++str;
-                       break;
-
                case FORMAT_TYPE_INVALID:
                        if (str < end)
                                *str = '%';
@@ -1715,15 +1807,15 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf)
                        /* skip */
                        break;
 
-               default:
+               default: {
+                       unsigned long long num;
+
                        switch (spec.type) {
 
                        case FORMAT_TYPE_LONG_LONG:
                                num = get_arg(long long);
                                break;
                        case FORMAT_TYPE_ULONG:
-                               num = get_arg(unsigned long);
-                               break;
                        case FORMAT_TYPE_LONG:
                                num = get_arg(unsigned long);
                                break;
@@ -1753,8 +1845,9 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf)
                        }
 
                        str = number(str, end, num, spec);
-               }
-       }
+               } /* default: */
+               } /* switch(spec.type) */
+       } /* while(*fmt) */
 
        if (size > 0) {
                if (str < end)
@@ -1807,8 +1900,10 @@ int vsscanf(const char *buf, const char *fmt, va_list args)
        char *next;
        char digit;
        int num = 0;
-       int qualifier, base, field_width;
-       int is_sign = 0;
+       u8 qualifier;
+       u8 base;
+       s16 field_width;
+       bool is_sign;
 
        while (*fmt && *str) {
                /* skip any white space in format */
@@ -1816,10 +1911,8 @@ int vsscanf(const char *buf, const char *fmt, va_list args)
                 * white space, including none, in the input.
                 */
                if (isspace(*fmt)) {
-                       while (isspace(*fmt))
-                               ++fmt;
-                       while (isspace(*str))
-                               ++str;
+                       fmt = skip_spaces(++fmt);
+                       str = skip_spaces(str);
                }
 
                /* anything that is not a conversion must match exactly */
@@ -1851,8 +1944,8 @@ int vsscanf(const char *buf, const char *fmt, va_list args)
 
                /* get conversion qualifier */
                qualifier = -1;
-               if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' ||
-                   *fmt == 'Z' || *fmt == 'z') {
+               if (*fmt == 'h' || TOLOWER(*fmt) == 'l' ||
+                   TOLOWER(*fmt) == 'z') {
                        qualifier = *fmt++;
                        if (unlikely(qualifier == *fmt)) {
                                if (qualifier == 'h') {
@@ -1864,12 +1957,13 @@ int vsscanf(const char *buf, const char *fmt, va_list args)
                                }
                        }
                }
-               base = 10;
-               is_sign = 0;
 
                if (!*fmt || !*str)
                        break;
 
+               base = 10;
+               is_sign = 0;
+
                switch (*fmt++) {
                case 'c':
                {
@@ -1886,10 +1980,9 @@ int vsscanf(const char *buf, const char *fmt, va_list args)
                {
                        char *s = (char *)va_arg(args, char *);
                        if (field_width == -1)
-                               field_width = INT_MAX;
+                               field_width = SHORT_MAX;
                        /* first, skip leading white space in buffer */
-                       while (isspace(*str))
-                               str++;
+                       str = skip_spaces(str);
 
                        /* now copy until next white space */
                        while (*str && !isspace(*str) && field_width--)
@@ -1931,8 +2024,7 @@ int vsscanf(const char *buf, const char *fmt, va_list args)
                /* have some sort of integer conversion.
                 * first, skip white space in buffer.
                 */
-               while (isspace(*str))
-                       str++;
+               str = skip_spaces(str);
 
                digit = *str;
                if (is_sign && digit == '-')