vsprintf: factorize "(null)" string
[safe/jmp/linux-2.6] / lib / vsprintf.c
index a6e1951..e5ab51f 100644 (file)
@@ -546,12 +546,12 @@ static char *number(char *buf, char *end, unsigned long long num,
        return buf;
 }
 
-static char *string(char *buf, char *end, char *s, struct printf_spec spec)
+static char *string(char *buf, char *end, const char *s, struct printf_spec spec)
 {
        int len, i;
 
        if ((unsigned long)s < PAGE_SIZE)
-               s = "<NULL>";
+               s = "(null)";
 
        len = strnlen(s, spec.precision);
 
@@ -624,13 +624,19 @@ static char *resource_string(char *buf, char *end, struct resource *res,
                .precision = -1,
                .flags = SPECIAL | SMALL,
        };
-       /*
-        * room for three actual numbers (decimal or hex), plus
-        * "[mem 0x-0x 64bit pref disabled flags 0x]\0"
-        */
-       char sym[3*3*sizeof(resource_size_t) + 41];
+
+       /* 32-bit res (sizeof==4): 10 chars in dec, 10 in hex ("0x" + 8)
+        * 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 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;
@@ -641,15 +647,17 @@ static char *resource_string(char *buf, char *end, struct resource *res,
        }
 
        *p++ = '[';
-       if (fmt[1] == 't' || fmt[1] == 'f') {
-               if (res->flags & IORESOURCE_IO)
-                       p = string(p, pend, "io  ", str_spec);
-               else if (res->flags & IORESOURCE_MEM)
-                       p = string(p, pend, "mem ", str_spec);
-               else if (res->flags & IORESOURCE_IRQ)
-                       p = string(p, pend, "irq ", str_spec);
-               else if (res->flags & IORESOURCE_DMA)
-                       p = string(p, pend, "dma ", str_spec);
+       if (res->flags & IORESOURCE_IO)
+               p = string(p, pend, "io  ", str_spec);
+       else if (res->flags & IORESOURCE_MEM)
+               p = string(p, pend, "mem ", str_spec);
+       else if (res->flags & IORESOURCE_IRQ)
+               p = string(p, pend, "irq ", str_spec);
+       else if (res->flags & IORESOURCE_DMA)
+               p = string(p, pend, "dma ", str_spec);
+       else {
+               p = string(p, pend, "??? ", str_spec);
+               decode = 0;
        }
        hex_spec.field_width = size;
        p = number(p, pend, res->start, addr ? hex_spec : dec_spec);
@@ -657,21 +665,19 @@ static char *resource_string(char *buf, char *end, struct resource *res,
                *p++ = '-';
                p = number(p, pend, res->end, addr ? hex_spec : dec_spec);
        }
-       if (fmt[1] == 't' || fmt[1] == 'f') {
+       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_DISABLED)
                        p = string(p, pend, " disabled", str_spec);
-               if (fmt[1] == 'f') {
-                       p = string(p, pend, " flags ", str_spec);
-                       p = number(p, pend, res->flags & ~IORESOURCE_TYPE_BITS,
-                                  flag_spec);
-               }
+       } else {
+               p = string(p, pend, " flags ", str_spec);
+               p = number(p, pend, res->flags, flag_spec);
        }
        *p++ = ']';
-       *p = 0;
+       *p = '\0';
 
        return string(buf, end, sym, spec);
 }
@@ -847,10 +853,8 @@ static char *ip4_addr_string(char *buf, char *end, const u8 *addr,
  * - 'f' For simple symbolic function names without offset
  * - 'S' For symbolic direct pointers with offset
  * - 's' For symbolic direct pointers without offset
- * - 'R' For a struct resource pointer, print:
- *       R   address range only ([0x0-0x1f])
- *       Rt  type and range ([mem 0x0-0x1f 64bit pref])
- *       Rf  type, range, and flags ([mem 0x0-0x1f 64bit pref flags 0x1])
+ * - 'R' For decoded struct resource, e.g., [mem 0x0-0x1f 64bit pref]
+ * - 'r' For raw struct resource, e.g., [mem 0x0-0x1f flags 0x201]
  * - '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
@@ -881,6 +885,7 @@ static char *pointer(const char *fmt, char *buf, char *end, void *ptr,
        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 */
@@ -1493,7 +1498,7 @@ do {                                                                      \
                        size_t len;
                        if ((unsigned long)save_str > (unsigned long)-PAGE_SIZE
                                        || (unsigned long)save_str < PAGE_SIZE)
-                               save_str = "<NULL>";
+                               save_str = "(null)";
                        len = strlen(save_str);
                        if (str + len + 1 < end)
                                memcpy(str, save_str, len + 1);