Subversion Repositories Kolibri OS

Rev

Rev 1869 | Rev 3031 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2.  *  linux/lib/vsprintf.c
  3.  *
  4.  *  Copyright (C) 1991, 1992  Linus Torvalds
  5.  */
  6.  
  7. /* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
  8. /*
  9.  * Wirzenius wrote this portably, Torvalds fucked it up :-)
  10.  */
  11.  
  12. /*
  13.  * Fri Jul 13 2001 Crutcher Dunnavant <crutcher+kernel@datastacks.com>
  14.  * - changed to provide snprintf and vsnprintf functions
  15.  * So Feb  1 16:51:32 CET 2004 Juergen Quade <quade@hsnr.de>
  16.  * - scnprintf and vscnprintf
  17.  */
  18.  
  19. #include <stdarg.h>
  20. #include <linux/module.h>
  21. #include <linux/types.h>
  22. #include <linux/string.h>
  23. #include <linux/ctype.h>
  24. #include <linux/kernel.h>
  25. #include <errno-base.h>
  26. #include <linux/ioport.h>
  27.  
  28. #include <asm/div64.h>
  29.  
  30. struct va_format {
  31.     const char *fmt;
  32.     va_list *va;
  33. };
  34.  
  35. #ifndef dereference_function_descriptor
  36. #define dereference_function_descriptor(p) (p)
  37. #endif
  38.  
  39. const char hex_asc[] = "0123456789abcdef";
  40.  
  41. /* Works only for digits and letters, but small and fast */
  42. #define TOLOWER(x) ((x) | 0x20)
  43.  
  44. static unsigned int simple_guess_base(const char *cp)
  45. {
  46.         if (cp[0] == '0') {
  47.                 if (TOLOWER(cp[1]) == 'x' && isxdigit(cp[2]))
  48.                         return 16;
  49.                 else
  50.                         return 8;
  51.         } else {
  52.                 return 10;
  53.         }
  54. }
  55.  
  56. /**
  57.  * simple_strtoull - convert a string to an unsigned long long
  58.  * @cp: The start of the string
  59.  * @endp: A pointer to the end of the parsed string will be placed here
  60.  * @base: The number base to use
  61.  */
  62. unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base)
  63. {
  64.         unsigned long long result = 0;
  65.  
  66.         if (!base)
  67.                 base = simple_guess_base(cp);
  68.  
  69.         if (base == 16 && cp[0] == '0' && TOLOWER(cp[1]) == 'x')
  70.                 cp += 2;
  71.  
  72.         while (isxdigit(*cp)) {
  73.                 unsigned int value;
  74.  
  75.                 value = isdigit(*cp) ? *cp - '0' : TOLOWER(*cp) - 'a' + 10;
  76.                 if (value >= base)
  77.                         break;
  78.                 result = result * base + value;
  79.                 cp++;
  80.         }
  81.         if (endp)
  82.                 *endp = (char *)cp;
  83.  
  84.         return result;
  85. }
  86. EXPORT_SYMBOL(simple_strtoull);
  87.  
  88. /**
  89.  * simple_strtoul - convert a string to an unsigned long
  90.  * @cp: The start of the string
  91.  * @endp: A pointer to the end of the parsed string will be placed here
  92.  * @base: The number base to use
  93.  */
  94. unsigned long simple_strtoul(const char *cp, char **endp, unsigned int base)
  95. {
  96.         return simple_strtoull(cp, endp, base);
  97. }
  98. EXPORT_SYMBOL(simple_strtoul);
  99.  
  100. /**
  101.  * simple_strtol - convert a string to a signed long
  102.  * @cp: The start of the string
  103.  * @endp: A pointer to the end of the parsed string will be placed here
  104.  * @base: The number base to use
  105.  */
  106. long simple_strtol(const char *cp, char **endp, unsigned int base)
  107. {
  108.         if (*cp == '-')
  109.                 return -simple_strtoul(cp + 1, endp, base);
  110.  
  111.         return simple_strtoul(cp, endp, base);
  112. }
  113. EXPORT_SYMBOL(simple_strtol);
  114.  
  115. /**
  116.  * simple_strtoll - convert a string to a signed long long
  117.  * @cp: The start of the string
  118.  * @endp: A pointer to the end of the parsed string will be placed here
  119.  * @base: The number base to use
  120.  */
  121. long long simple_strtoll(const char *cp, char **endp, unsigned int base)
  122. {
  123.         if (*cp == '-')
  124.                 return -simple_strtoull(cp + 1, endp, base);
  125.  
  126.         return simple_strtoull(cp, endp, base);
  127. }
  128. EXPORT_SYMBOL(simple_strtoll);
  129.  
  130. /**
  131.  * strict_strtoul - convert a string to an unsigned long strictly
  132.  * @cp: The string to be converted
  133.  * @base: The number base to use
  134.  * @res: The converted result value
  135.  *
  136.  * strict_strtoul converts a string to an unsigned long only if the
  137.  * string is really an unsigned long string, any string containing
  138.  * any invalid char at the tail will be rejected and -EINVAL is returned,
  139.  * only a newline char at the tail is acceptible because people generally
  140.  * change a module parameter in the following way:
  141.  *
  142.  *      echo 1024 > /sys/module/e1000/parameters/copybreak
  143.  *
  144.  * echo will append a newline to the tail.
  145.  *
  146.  * It returns 0 if conversion is successful and *res is set to the converted
  147.  * value, otherwise it returns -EINVAL and *res is set to 0.
  148.  *
  149.  * simple_strtoul just ignores the successive invalid characters and
  150.  * return the converted value of prefix part of the string.
  151.  */
  152. int strict_strtoul(const char *cp, unsigned int base, unsigned long *res)
  153. {
  154.         char *tail;
  155.         unsigned long val;
  156.  
  157.         *res = 0;
  158.         if (!*cp)
  159.                 return -EINVAL;
  160.  
  161.         val = simple_strtoul(cp, &tail, base);
  162.         if (tail == cp)
  163.                 return -EINVAL;
  164.  
  165.         if ((tail[0] == '\0') || (tail[0] == '\n' && tail[1] == '\0')) {
  166.                 *res = val;
  167.                 return 0;
  168.         }
  169.  
  170.         return -EINVAL;
  171. }
  172. EXPORT_SYMBOL(strict_strtoul);
  173.  
  174. /**
  175.  * strict_strtol - convert a string to a long strictly
  176.  * @cp: The string to be converted
  177.  * @base: The number base to use
  178.  * @res: The converted result value
  179.  *
  180.  * strict_strtol is similiar to strict_strtoul, but it allows the first
  181.  * character of a string is '-'.
  182.  *
  183.  * It returns 0 if conversion is successful and *res is set to the converted
  184.  * value, otherwise it returns -EINVAL and *res is set to 0.
  185.  */
  186. int strict_strtol(const char *cp, unsigned int base, long *res)
  187. {
  188.         int ret;
  189.         if (*cp == '-') {
  190.                 ret = strict_strtoul(cp + 1, base, (unsigned long *)res);
  191.                 if (!ret)
  192.                         *res = -(*res);
  193.         } else {
  194.                 ret = strict_strtoul(cp, base, (unsigned long *)res);
  195.         }
  196.  
  197.         return ret;
  198. }
  199. EXPORT_SYMBOL(strict_strtol);
  200.  
  201. /**
  202.  * strict_strtoull - convert a string to an unsigned long long strictly
  203.  * @cp: The string to be converted
  204.  * @base: The number base to use
  205.  * @res: The converted result value
  206.  *
  207.  * strict_strtoull converts a string to an unsigned long long only if the
  208.  * string is really an unsigned long long string, any string containing
  209.  * any invalid char at the tail will be rejected and -EINVAL is returned,
  210.  * only a newline char at the tail is acceptible because people generally
  211.  * change a module parameter in the following way:
  212.  *
  213.  *      echo 1024 > /sys/module/e1000/parameters/copybreak
  214.  *
  215.  * echo will append a newline to the tail of the string.
  216.  *
  217.  * It returns 0 if conversion is successful and *res is set to the converted
  218.  * value, otherwise it returns -EINVAL and *res is set to 0.
  219.  *
  220.  * simple_strtoull just ignores the successive invalid characters and
  221.  * return the converted value of prefix part of the string.
  222.  */
  223. int strict_strtoull(const char *cp, unsigned int base, unsigned long long *res)
  224. {
  225.         char *tail;
  226.         unsigned long long val;
  227.  
  228.         *res = 0;
  229.         if (!*cp)
  230.                 return -EINVAL;
  231.  
  232.         val = simple_strtoull(cp, &tail, base);
  233.         if (tail == cp)
  234.                 return -EINVAL;
  235.         if ((tail[0] == '\0') || (tail[0] == '\n' && tail[1] == '\0')) {
  236.                 *res = val;
  237.                 return 0;
  238.         }
  239.  
  240.         return -EINVAL;
  241. }
  242. EXPORT_SYMBOL(strict_strtoull);
  243.  
  244. /**
  245.  * strict_strtoll - convert a string to a long long strictly
  246.  * @cp: The string to be converted
  247.  * @base: The number base to use
  248.  * @res: The converted result value
  249.  *
  250.  * strict_strtoll is similiar to strict_strtoull, but it allows the first
  251.  * character of a string is '-'.
  252.  *
  253.  * It returns 0 if conversion is successful and *res is set to the converted
  254.  * value, otherwise it returns -EINVAL and *res is set to 0.
  255.  */
  256. int strict_strtoll(const char *cp, unsigned int base, long long *res)
  257. {
  258.         int ret;
  259.         if (*cp == '-') {
  260.                 ret = strict_strtoull(cp + 1, base, (unsigned long long *)res);
  261.                 if (!ret)
  262.                         *res = -(*res);
  263.         } else {
  264.                 ret = strict_strtoull(cp, base, (unsigned long long *)res);
  265.         }
  266.  
  267.         return ret;
  268. }
  269. EXPORT_SYMBOL(strict_strtoll);
  270.  
  271. static noinline_for_stack
  272. int skip_atoi(const char **s)
  273. {
  274.         int i = 0;
  275.  
  276.         while (isdigit(**s))
  277.                 i = i*10 + *((*s)++) - '0';
  278.  
  279.         return i;
  280. }
  281.  
  282. /* Decimal conversion is by far the most typical, and is used
  283.  * for /proc and /sys data. This directly impacts e.g. top performance
  284.  * with many processes running. We optimize it for speed
  285.  * using code from
  286.  * http://www.cs.uiowa.edu/~jones/bcd/decimal.html
  287.  * (with permission from the author, Douglas W. Jones). */
  288.  
  289. /* Formats correctly any integer in [0,99999].
  290.  * Outputs from one to five digits depending on input.
  291.  * On i386 gcc 4.1.2 -O2: ~250 bytes of code. */
  292. static noinline_for_stack
  293. char *put_dec_trunc(char *buf, unsigned q)
  294. {
  295.         unsigned d3, d2, d1, d0;
  296.         d1 = (q>>4) & 0xf;
  297.         d2 = (q>>8) & 0xf;
  298.         d3 = (q>>12);
  299.  
  300.         d0 = 6*(d3 + d2 + d1) + (q & 0xf);
  301.         q = (d0 * 0xcd) >> 11;
  302.         d0 = d0 - 10*q;
  303.         *buf++ = d0 + '0'; /* least significant digit */
  304.         d1 = q + 9*d3 + 5*d2 + d1;
  305.         if (d1 != 0) {
  306.                 q = (d1 * 0xcd) >> 11;
  307.                 d1 = d1 - 10*q;
  308.                 *buf++ = d1 + '0'; /* next digit */
  309.  
  310.                 d2 = q + 2*d2;
  311.                 if ((d2 != 0) || (d3 != 0)) {
  312.                         q = (d2 * 0xd) >> 7;
  313.                         d2 = d2 - 10*q;
  314.                         *buf++ = d2 + '0'; /* next digit */
  315.  
  316.                         d3 = q + 4*d3;
  317.                         if (d3 != 0) {
  318.                                 q = (d3 * 0xcd) >> 11;
  319.                                 d3 = d3 - 10*q;
  320.                                 *buf++ = d3 + '0';  /* next digit */
  321.                                 if (q != 0)
  322.                                         *buf++ = q + '0'; /* most sign. digit */
  323.                         }
  324.                 }
  325.         }
  326.  
  327.         return buf;
  328. }
  329. /* Same with if's removed. Always emits five digits */
  330. static noinline_for_stack
  331. char *put_dec_full(char *buf, unsigned q)
  332. {
  333.         /* BTW, if q is in [0,9999], 8-bit ints will be enough, */
  334.         /* but anyway, gcc produces better code with full-sized ints */
  335.         unsigned d3, d2, d1, d0;
  336.         d1 = (q>>4) & 0xf;
  337.         d2 = (q>>8) & 0xf;
  338.         d3 = (q>>12);
  339.  
  340.         /*
  341.          * Possible ways to approx. divide by 10
  342.          * gcc -O2 replaces multiply with shifts and adds
  343.          * (x * 0xcd) >> 11: 11001101 - shorter code than * 0x67 (on i386)
  344.          * (x * 0x67) >> 10:  1100111
  345.          * (x * 0x34) >> 9:    110100 - same
  346.          * (x * 0x1a) >> 8:     11010 - same
  347.          * (x * 0x0d) >> 7:      1101 - same, shortest code (on i386)
  348.          */
  349.         d0 = 6*(d3 + d2 + d1) + (q & 0xf);
  350.         q = (d0 * 0xcd) >> 11;
  351.         d0 = d0 - 10*q;
  352.         *buf++ = d0 + '0';
  353.         d1 = q + 9*d3 + 5*d2 + d1;
  354.                 q = (d1 * 0xcd) >> 11;
  355.                 d1 = d1 - 10*q;
  356.                 *buf++ = d1 + '0';
  357.  
  358.                 d2 = q + 2*d2;
  359.                         q = (d2 * 0xd) >> 7;
  360.                         d2 = d2 - 10*q;
  361.                         *buf++ = d2 + '0';
  362.  
  363.                         d3 = q + 4*d3;
  364.                                 q = (d3 * 0xcd) >> 11; /* - shorter code */
  365.                                 /* q = (d3 * 0x67) >> 10; - would also work */
  366.                                 d3 = d3 - 10*q;
  367.                                 *buf++ = d3 + '0';
  368.                                         *buf++ = q + '0';
  369.  
  370.         return buf;
  371. }
  372. /* No inlining helps gcc to use registers better */
  373. static noinline_for_stack
  374. char *put_dec(char *buf, unsigned long long num)
  375. {
  376.         while (1) {
  377.                 unsigned rem;
  378.                 if (num < 100000)
  379.                         return put_dec_trunc(buf, num);
  380.                 rem = do_div(num, 100000);
  381.                 buf = put_dec_full(buf, rem);
  382.         }
  383. }
  384.  
  385. #define ZEROPAD 1               /* pad with zero */
  386. #define SIGN    2               /* unsigned/signed long */
  387. #define PLUS    4               /* show plus */
  388. #define SPACE   8               /* space if plus */
  389. #define LEFT    16              /* left justified */
  390. #define SMALL   32              /* use lowercase in hex (must be 32 == 0x20) */
  391. #define SPECIAL 64              /* prefix hex with "0x", octal with "0" */
  392.  
  393. enum format_type {
  394.         FORMAT_TYPE_NONE, /* Just a string part */
  395.         FORMAT_TYPE_WIDTH,
  396.         FORMAT_TYPE_PRECISION,
  397.         FORMAT_TYPE_CHAR,
  398.         FORMAT_TYPE_STR,
  399.         FORMAT_TYPE_PTR,
  400.         FORMAT_TYPE_PERCENT_CHAR,
  401.         FORMAT_TYPE_INVALID,
  402.         FORMAT_TYPE_LONG_LONG,
  403.         FORMAT_TYPE_ULONG,
  404.         FORMAT_TYPE_LONG,
  405.         FORMAT_TYPE_UBYTE,
  406.         FORMAT_TYPE_BYTE,
  407.         FORMAT_TYPE_USHORT,
  408.         FORMAT_TYPE_SHORT,
  409.         FORMAT_TYPE_UINT,
  410.         FORMAT_TYPE_INT,
  411.         FORMAT_TYPE_NRCHARS,
  412.         FORMAT_TYPE_SIZE_T,
  413.         FORMAT_TYPE_PTRDIFF
  414. };
  415.  
  416. struct printf_spec {
  417.         u8      type;           /* format_type enum */
  418.         u8      flags;          /* flags to number() */
  419.         u8      base;           /* number base, 8, 10 or 16 only */
  420.         u8      qualifier;      /* number qualifier, one of 'hHlLtzZ' */
  421.         s16     field_width;    /* width of output field */
  422.         s16     precision;      /* # of digits/chars */
  423. };
  424.  
  425. static noinline_for_stack
  426. char *number(char *buf, char *end, unsigned long long num,
  427.              struct printf_spec spec)
  428. {
  429.         /* we are called with base 8, 10 or 16, only, thus don't need "G..."  */
  430.         static const char digits[16] = "0123456789ABCDEF"; /* "GHIJKLMNOPQRSTUVWXYZ"; */
  431.  
  432.         char tmp[66];
  433.         char sign;
  434.         char locase;
  435.         int need_pfx = ((spec.flags & SPECIAL) && spec.base != 10);
  436.         int i;
  437.  
  438.         /* locase = 0 or 0x20. ORing digits or letters with 'locase'
  439.          * produces same digits or (maybe lowercased) letters */
  440.         locase = (spec.flags & SMALL);
  441.         if (spec.flags & LEFT)
  442.                 spec.flags &= ~ZEROPAD;
  443.         sign = 0;
  444.         if (spec.flags & SIGN) {
  445.                 if ((signed long long)num < 0) {
  446.                         sign = '-';
  447.                         num = -(signed long long)num;
  448.                         spec.field_width--;
  449.                 } else if (spec.flags & PLUS) {
  450.                         sign = '+';
  451.                         spec.field_width--;
  452.                 } else if (spec.flags & SPACE) {
  453.                         sign = ' ';
  454.                         spec.field_width--;
  455.                 }
  456.         }
  457.         if (need_pfx) {
  458.                 spec.field_width--;
  459.                 if (spec.base == 16)
  460.                         spec.field_width--;
  461.         }
  462.  
  463.         /* generate full string in tmp[], in reverse order */
  464.         i = 0;
  465.         if (num == 0)
  466.                 tmp[i++] = '0';
  467.         /* Generic code, for any base:
  468.         else do {
  469.                 tmp[i++] = (digits[do_div(num,base)] | locase);
  470.         } while (num != 0);
  471.         */
  472.         else if (spec.base != 10) { /* 8 or 16 */
  473.                 int mask = spec.base - 1;
  474.                 int shift = 3;
  475.  
  476.                 if (spec.base == 16)
  477.                         shift = 4;
  478.                 do {
  479.                         tmp[i++] = (digits[((unsigned char)num) & mask] | locase);
  480.                         num >>= shift;
  481.                 } while (num);
  482.         } else { /* base 10 */
  483.                 i = put_dec(tmp, num) - tmp;
  484.         }
  485.  
  486.         /* printing 100 using %2d gives "100", not "00" */
  487.         if (i > spec.precision)
  488.                 spec.precision = i;
  489.         /* leading space padding */
  490.         spec.field_width -= spec.precision;
  491.         if (!(spec.flags & (ZEROPAD+LEFT))) {
  492.                 while (--spec.field_width >= 0) {
  493.                         if (buf < end)
  494.                                 *buf = ' ';
  495.                         ++buf;
  496.                 }
  497.         }
  498.         /* sign */
  499.         if (sign) {
  500.                 if (buf < end)
  501.                         *buf = sign;
  502.                 ++buf;
  503.         }
  504.         /* "0x" / "0" prefix */
  505.         if (need_pfx) {
  506.                 if (buf < end)
  507.                         *buf = '0';
  508.                 ++buf;
  509.                 if (spec.base == 16) {
  510.                         if (buf < end)
  511.                                 *buf = ('X' | locase);
  512.                         ++buf;
  513.                 }
  514.         }
  515.         /* zero or space padding */
  516.         if (!(spec.flags & LEFT)) {
  517.                 char c = (spec.flags & ZEROPAD) ? '0' : ' ';
  518.                 while (--spec.field_width >= 0) {
  519.                         if (buf < end)
  520.                                 *buf = c;
  521.                         ++buf;
  522.                 }
  523.         }
  524.         /* hmm even more zero padding? */
  525.         while (i <= --spec.precision) {
  526.                 if (buf < end)
  527.                         *buf = '0';
  528.                 ++buf;
  529.         }
  530.         /* actual digits of result */
  531.         while (--i >= 0) {
  532.                 if (buf < end)
  533.                         *buf = tmp[i];
  534.                 ++buf;
  535.         }
  536.         /* trailing space padding */
  537.         while (--spec.field_width >= 0) {
  538.                 if (buf < end)
  539.                         *buf = ' ';
  540.                 ++buf;
  541.         }
  542.  
  543.         return buf;
  544. }
  545.  
  546. static noinline_for_stack
  547. char *string(char *buf, char *end, const char *s, struct printf_spec spec)
  548. {
  549.         int len, i;
  550.  
  551.         if ((unsigned long)s < PAGE_SIZE)
  552.                 s = "(null)";
  553.  
  554.         len = strnlen(s, spec.precision);
  555.  
  556.         if (!(spec.flags & LEFT)) {
  557.                 while (len < spec.field_width--) {
  558.                         if (buf < end)
  559.                                 *buf = ' ';
  560.                         ++buf;
  561.                 }
  562.         }
  563.         for (i = 0; i < len; ++i) {
  564.                 if (buf < end)
  565.                         *buf = *s;
  566.                 ++buf; ++s;
  567.         }
  568.         while (len < spec.field_width--) {
  569.                 if (buf < end)
  570.                         *buf = ' ';
  571.                 ++buf;
  572.         }
  573.  
  574.         return buf;
  575. }
  576.  
  577. static noinline_for_stack
  578. char *symbol_string(char *buf, char *end, void *ptr,
  579.                     struct printf_spec spec, char ext)
  580. {
  581.         unsigned long value = (unsigned long) ptr;
  582. #ifdef CONFIG_KALLSYMS
  583.         char sym[KSYM_SYMBOL_LEN];
  584.         if (ext != 'f' && ext != 's')
  585.                 sprint_symbol(sym, value);
  586.         else
  587.                 kallsyms_lookup(value, NULL, NULL, NULL, sym);
  588.  
  589.         return string(buf, end, sym, spec);
  590. #else
  591.         spec.field_width = 2 * sizeof(void *);
  592.         spec.flags |= SPECIAL | SMALL | ZEROPAD;
  593.         spec.base = 16;
  594.  
  595.         return number(buf, end, value, spec);
  596. #endif
  597. }
  598.  
  599. static noinline_for_stack
  600. char *resource_string(char *buf, char *end, struct resource *res,
  601.                       struct printf_spec spec, const char *fmt)
  602. {
  603. #ifndef IO_RSRC_PRINTK_SIZE
  604. #define IO_RSRC_PRINTK_SIZE     6
  605. #endif
  606.  
  607. #ifndef MEM_RSRC_PRINTK_SIZE
  608. #define MEM_RSRC_PRINTK_SIZE    10
  609. #endif
  610.         static const struct printf_spec io_spec = {
  611.                 .base = 16,
  612.                 .field_width = IO_RSRC_PRINTK_SIZE,
  613.                 .precision = -1,
  614.                 .flags = SPECIAL | SMALL | ZEROPAD,
  615.         };
  616.         static const struct printf_spec mem_spec = {
  617.                 .base = 16,
  618.                 .field_width = MEM_RSRC_PRINTK_SIZE,
  619.                 .precision = -1,
  620.                 .flags = SPECIAL | SMALL | ZEROPAD,
  621.         };
  622.         static const struct printf_spec bus_spec = {
  623.                 .base = 16,
  624.                 .field_width = 2,
  625.                 .precision = -1,
  626.                 .flags = SMALL | ZEROPAD,
  627.         };
  628.         static const struct printf_spec dec_spec = {
  629.                 .base = 10,
  630.                 .precision = -1,
  631.                 .flags = 0,
  632.         };
  633.         static const struct printf_spec str_spec = {
  634.                 .field_width = -1,
  635.                 .precision = 10,
  636.                 .flags = LEFT,
  637.         };
  638.         static const struct printf_spec flag_spec = {
  639.                 .base = 16,
  640.                 .precision = -1,
  641.                 .flags = SPECIAL | SMALL,
  642.         };
  643.  
  644.         /* 32-bit res (sizeof==4): 10 chars in dec, 10 in hex ("0x" + 8)
  645.          * 64-bit res (sizeof==8): 20 chars in dec, 18 in hex ("0x" + 16) */
  646. #define RSRC_BUF_SIZE           ((2 * sizeof(resource_size_t)) + 4)
  647. #define FLAG_BUF_SIZE           (2 * sizeof(res->flags))
  648. #define DECODED_BUF_SIZE        sizeof("[mem - 64bit pref window disabled]")
  649. #define RAW_BUF_SIZE            sizeof("[mem - flags 0x]")
  650. #undef max
  651. #define max(a,b) ((a) > (b) ? (a) : (b))
  652.         char sym[max(2*RSRC_BUF_SIZE + DECODED_BUF_SIZE,
  653.                      2*RSRC_BUF_SIZE + FLAG_BUF_SIZE + RAW_BUF_SIZE)];
  654.  
  655.         char *p = sym, *pend = sym + sizeof(sym);
  656.         int decode = (fmt[0] == 'R') ? 1 : 0;
  657.         const struct printf_spec *specp;
  658.  
  659.         *p++ = '[';
  660.         if (res->flags & IORESOURCE_IO) {
  661.                 p = string(p, pend, "io  ", str_spec);
  662.                 specp = &io_spec;
  663.         } else if (res->flags & IORESOURCE_MEM) {
  664.                 p = string(p, pend, "mem ", str_spec);
  665.                 specp = &mem_spec;
  666.         } else if (res->flags & IORESOURCE_IRQ) {
  667.                 p = string(p, pend, "irq ", str_spec);
  668.                 specp = &dec_spec;
  669.         } else if (res->flags & IORESOURCE_DMA) {
  670.                 p = string(p, pend, "dma ", str_spec);
  671.                 specp = &dec_spec;
  672.         } else if (res->flags & IORESOURCE_BUS) {
  673.                 p = string(p, pend, "bus ", str_spec);
  674.                 specp = &bus_spec;
  675.         } else {
  676.                 p = string(p, pend, "??? ", str_spec);
  677.                 specp = &mem_spec;
  678.                 decode = 0;
  679.         }
  680.         p = number(p, pend, res->start, *specp);
  681.         if (res->start != res->end) {
  682.                 *p++ = '-';
  683.                 p = number(p, pend, res->end, *specp);
  684.         }
  685.         if (decode) {
  686.                 if (res->flags & IORESOURCE_MEM_64)
  687.                         p = string(p, pend, " 64bit", str_spec);
  688.                 if (res->flags & IORESOURCE_PREFETCH)
  689.                         p = string(p, pend, " pref", str_spec);
  690.                 if (res->flags & IORESOURCE_WINDOW)
  691.                         p = string(p, pend, " window", str_spec);
  692.                 if (res->flags & IORESOURCE_DISABLED)
  693.                         p = string(p, pend, " disabled", str_spec);
  694.         } else {
  695.                 p = string(p, pend, " flags ", str_spec);
  696.                 p = number(p, pend, res->flags, flag_spec);
  697.         }
  698.         *p++ = ']';
  699.         *p = '\0';
  700.  
  701.         return string(buf, end, sym, spec);
  702. }
  703.  
  704. static noinline_for_stack
  705. char *mac_address_string(char *buf, char *end, u8 *addr,
  706.                          struct printf_spec spec, const char *fmt)
  707. {
  708.         char mac_addr[sizeof("xx:xx:xx:xx:xx:xx")];
  709.         char *p = mac_addr;
  710.         int i;
  711.         char separator;
  712.  
  713.         if (fmt[1] == 'F') {            /* FDDI canonical format */
  714.                 separator = '-';
  715.         } else {
  716.                 separator = ':';
  717.         }
  718.  
  719.         for (i = 0; i < 6; i++) {
  720.                 p = pack_hex_byte(p, addr[i]);
  721.                 if (fmt[0] == 'M' && i != 5)
  722.                         *p++ = separator;
  723.         }
  724.         *p = '\0';
  725.  
  726.         return string(buf, end, mac_addr, spec);
  727. }
  728.  
  729. static noinline_for_stack
  730. char *ip4_string(char *p, const u8 *addr, const char *fmt)
  731. {
  732.         int i;
  733.         bool leading_zeros = (fmt[0] == 'i');
  734.         int index;
  735.         int step;
  736.  
  737.         switch (fmt[2]) {
  738.         case 'h':
  739. #ifdef __BIG_ENDIAN
  740.                 index = 0;
  741.                 step = 1;
  742. #else
  743.                 index = 3;
  744.                 step = -1;
  745. #endif
  746.                 break;
  747.         case 'l':
  748.                 index = 3;
  749.                 step = -1;
  750.                 break;
  751.         case 'n':
  752.         case 'b':
  753.         default:
  754.                 index = 0;
  755.                 step = 1;
  756.                 break;
  757.         }
  758.         for (i = 0; i < 4; i++) {
  759.                 char temp[3];   /* hold each IP quad in reverse order */
  760.                 int digits = put_dec_trunc(temp, addr[index]) - temp;
  761.                 if (leading_zeros) {
  762.                         if (digits < 3)
  763.                                 *p++ = '0';
  764.                         if (digits < 2)
  765.                                 *p++ = '0';
  766.                 }
  767.                 /* reverse the digits in the quad */
  768.                 while (digits--)
  769.                         *p++ = temp[digits];
  770.                 if (i < 3)
  771.                         *p++ = '.';
  772.                 index += step;
  773.         }
  774.         *p = '\0';
  775.  
  776.         return p;
  777. }
  778.  
  779.  
  780. static noinline_for_stack
  781. char *ip4_addr_string(char *buf, char *end, const u8 *addr,
  782.                       struct printf_spec spec, const char *fmt)
  783. {
  784.         char ip4_addr[sizeof("255.255.255.255")];
  785.  
  786.         ip4_string(ip4_addr, addr, fmt);
  787.  
  788.         return string(buf, end, ip4_addr, spec);
  789. }
  790.  
  791.  
  792. int kptr_restrict = 1;
  793.  
  794. /*
  795.  * Show a '%p' thing.  A kernel extension is that the '%p' is followed
  796.  * by an extra set of alphanumeric characters that are extended format
  797.  * specifiers.
  798.  *
  799.  * Right now we handle:
  800.  *
  801.  * - 'F' For symbolic function descriptor pointers with offset
  802.  * - 'f' For simple symbolic function names without offset
  803.  * - 'S' For symbolic direct pointers with offset
  804.  * - 's' For symbolic direct pointers without offset
  805.  * - 'R' For decoded struct resource, e.g., [mem 0x0-0x1f 64bit pref]
  806.  * - 'r' For raw struct resource, e.g., [mem 0x0-0x1f flags 0x201]
  807.  * - 'M' For a 6-byte MAC address, it prints the address in the
  808.  *       usual colon-separated hex notation
  809.  * - 'm' For a 6-byte MAC address, it prints the hex address without colons
  810.  * - 'MF' For a 6-byte MAC FDDI address, it prints the address
  811.  *       with a dash-separated hex notation
  812.  * - 'I' [46] for IPv4/IPv6 addresses printed in the usual way
  813.  *       IPv4 uses dot-separated decimal without leading 0's (1.2.3.4)
  814.  *       IPv6 uses colon separated network-order 16 bit hex with leading 0's
  815.  * - 'i' [46] for 'raw' IPv4/IPv6 addresses
  816.  *       IPv6 omits the colons (01020304...0f)
  817.  *       IPv4 uses dot-separated decimal with leading 0's (010.123.045.006)
  818.  * - '[Ii]4[hnbl]' IPv4 addresses in host, network, big or little endian order
  819.  * - 'I6c' for IPv6 addresses printed as specified by
  820.  *       http://tools.ietf.org/html/draft-ietf-6man-text-addr-representation-00
  821.  * - 'U' For a 16 byte UUID/GUID, it prints the UUID/GUID in the form
  822.  *       "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
  823.  *       Options for %pU are:
  824.  *         b big endian lower case hex (default)
  825.  *         B big endian UPPER case hex
  826.  *         l little endian lower case hex
  827.  *         L little endian UPPER case hex
  828.  *           big endian output byte order is:
  829.  *             [0][1][2][3]-[4][5]-[6][7]-[8][9]-[10][11][12][13][14][15]
  830.  *           little endian output byte order is:
  831.  *             [3][2][1][0]-[5][4]-[7][6]-[8][9]-[10][11][12][13][14][15]
  832.  * - 'V' For a struct va_format which contains a format string * and va_list *,
  833.  *       call vsnprintf(->format, *->va_list).
  834.  *       Implements a "recursive vsnprintf".
  835.  *       Do not use this feature without some mechanism to verify the
  836.  *       correctness of the format string and va_list arguments.
  837.  * - 'K' For a kernel pointer that should be hidden from unprivileged users
  838.  *
  839.  * Note: The difference between 'S' and 'F' is that on ia64 and ppc64
  840.  * function pointers are really function descriptors, which contain a
  841.  * pointer to the real address.
  842.  */
  843. static noinline_for_stack
  844. char *pointer(const char *fmt, char *buf, char *end, void *ptr,
  845.               struct printf_spec spec)
  846. {
  847.         if (!ptr) {
  848.                 /*
  849.                  * Print (null) with the same width as a pointer so it makes
  850.                  * tabular output look nice.
  851.                  */
  852.                 if (spec.field_width == -1)
  853.                         spec.field_width = 2 * sizeof(void *);
  854.                 return string(buf, end, "(null)", spec);
  855.         }
  856.  
  857.         switch (*fmt) {
  858.         case 'F':
  859.         case 'f':
  860.                 ptr = dereference_function_descriptor(ptr);
  861.                 /* Fallthrough */
  862.         case 'S':
  863.         case 's':
  864.                 return symbol_string(buf, end, ptr, spec, *fmt);
  865.         case 'R':
  866.         case 'r':
  867.                 return resource_string(buf, end, ptr, spec, fmt);
  868.         case 'M':                       /* Colon separated: 00:01:02:03:04:05 */
  869.         case 'm':                       /* Contiguous: 000102030405 */
  870.                                         /* [mM]F (FDDI, bit reversed) */
  871.                 return mac_address_string(buf, end, ptr, spec, fmt);
  872.         case 'I':                       /* Formatted IP supported
  873.                                          * 4:   1.2.3.4
  874.                                          * 6:   0001:0203:...:0708
  875.                                          * 6c:  1::708 or 1::1.2.3.4
  876.                                          */
  877.         case 'i':                       /* Contiguous:
  878.                                          * 4:   001.002.003.004
  879.                                          * 6:   000102...0f
  880.                                          */
  881.                 switch (fmt[1]) {
  882.                 case '4':
  883.                         return ip4_addr_string(buf, end, ptr, spec, fmt);
  884.                 }
  885.                 break;
  886.         case 'V':
  887.                 return buf + vsnprintf(buf, end - buf,
  888.                                        ((struct va_format *)ptr)->fmt,
  889.                                        *(((struct va_format *)ptr)->va));
  890.         }
  891.         spec.flags |= SMALL;
  892.         if (spec.field_width == -1) {
  893.                 spec.field_width = 2 * sizeof(void *);
  894.                 spec.flags |= ZEROPAD;
  895.         }
  896.         spec.base = 16;
  897.  
  898.         return number(buf, end, (unsigned long) ptr, spec);
  899. }
  900.  
  901. /*
  902.  * Helper function to decode printf style format.
  903.  * Each call decode a token from the format and return the
  904.  * number of characters read (or likely the delta where it wants
  905.  * to go on the next call).
  906.  * The decoded token is returned through the parameters
  907.  *
  908.  * 'h', 'l', or 'L' for integer fields
  909.  * 'z' support added 23/7/1999 S.H.
  910.  * 'z' changed to 'Z' --davidm 1/25/99
  911.  * 't' added for ptrdiff_t
  912.  *
  913.  * @fmt: the format string
  914.  * @type of the token returned
  915.  * @flags: various flags such as +, -, # tokens..
  916.  * @field_width: overwritten width
  917.  * @base: base of the number (octal, hex, ...)
  918.  * @precision: precision of a number
  919.  * @qualifier: qualifier of a number (long, size_t, ...)
  920.  */
  921. static noinline_for_stack
  922. int format_decode(const char *fmt, struct printf_spec *spec)
  923. {
  924.         const char *start = fmt;
  925.  
  926.         /* we finished early by reading the field width */
  927.         if (spec->type == FORMAT_TYPE_WIDTH) {
  928.                 if (spec->field_width < 0) {
  929.                         spec->field_width = -spec->field_width;
  930.                         spec->flags |= LEFT;
  931.                 }
  932.                 spec->type = FORMAT_TYPE_NONE;
  933.                 goto precision;
  934.         }
  935.  
  936.         /* we finished early by reading the precision */
  937.         if (spec->type == FORMAT_TYPE_PRECISION) {
  938.                 if (spec->precision < 0)
  939.                         spec->precision = 0;
  940.  
  941.                 spec->type = FORMAT_TYPE_NONE;
  942.                 goto qualifier;
  943.         }
  944.  
  945.         /* By default */
  946.         spec->type = FORMAT_TYPE_NONE;
  947.  
  948.         for (; *fmt ; ++fmt) {
  949.                 if (*fmt == '%')
  950.                         break;
  951.         }
  952.  
  953.         /* Return the current non-format string */
  954.         if (fmt != start || !*fmt)
  955.                 return fmt - start;
  956.  
  957.         /* Process flags */
  958.         spec->flags = 0;
  959.  
  960.         while (1) { /* this also skips first '%' */
  961.                 bool found = true;
  962.  
  963.                 ++fmt;
  964.  
  965.                 switch (*fmt) {
  966.                 case '-': spec->flags |= LEFT;    break;
  967.                 case '+': spec->flags |= PLUS;    break;
  968.                 case ' ': spec->flags |= SPACE;   break;
  969.                 case '#': spec->flags |= SPECIAL; break;
  970.                 case '0': spec->flags |= ZEROPAD; break;
  971.                 default:  found = false;
  972.                 }
  973.  
  974.                 if (!found)
  975.                         break;
  976.         }
  977.  
  978.         /* get field width */
  979.         spec->field_width = -1;
  980.  
  981.         if (isdigit(*fmt))
  982.                 spec->field_width = skip_atoi(&fmt);
  983.         else if (*fmt == '*') {
  984.                 /* it's the next argument */
  985.                 spec->type = FORMAT_TYPE_WIDTH;
  986.                 return ++fmt - start;
  987.         }
  988.  
  989. precision:
  990.         /* get the precision */
  991.         spec->precision = -1;
  992.         if (*fmt == '.') {
  993.                 ++fmt;
  994.                 if (isdigit(*fmt)) {
  995.                         spec->precision = skip_atoi(&fmt);
  996.                         if (spec->precision < 0)
  997.                                 spec->precision = 0;
  998.                 } else if (*fmt == '*') {
  999.                         /* it's the next argument */
  1000.                         spec->type = FORMAT_TYPE_PRECISION;
  1001.                         return ++fmt - start;
  1002.                 }
  1003.         }
  1004.  
  1005. qualifier:
  1006.         /* get the conversion qualifier */
  1007.         spec->qualifier = -1;
  1008.         if (*fmt == 'h' || TOLOWER(*fmt) == 'l' ||
  1009.             TOLOWER(*fmt) == 'z' || *fmt == 't') {
  1010.                 spec->qualifier = *fmt++;
  1011.                 if (unlikely(spec->qualifier == *fmt)) {
  1012.                         if (spec->qualifier == 'l') {
  1013.                                 spec->qualifier = 'L';
  1014.                                 ++fmt;
  1015.                         } else if (spec->qualifier == 'h') {
  1016.                                 spec->qualifier = 'H';
  1017.                                 ++fmt;
  1018.                         }
  1019.                 }
  1020.         }
  1021.  
  1022.         /* default base */
  1023.         spec->base = 10;
  1024.         switch (*fmt) {
  1025.         case 'c':
  1026.                 spec->type = FORMAT_TYPE_CHAR;
  1027.                 return ++fmt - start;
  1028.  
  1029.         case 's':
  1030.                 spec->type = FORMAT_TYPE_STR;
  1031.                 return ++fmt - start;
  1032.  
  1033.         case 'p':
  1034.                 spec->type = FORMAT_TYPE_PTR;
  1035.                 return fmt - start;
  1036.                 /* skip alnum */
  1037.  
  1038.         case 'n':
  1039.                 spec->type = FORMAT_TYPE_NRCHARS;
  1040.                 return ++fmt - start;
  1041.  
  1042.         case '%':
  1043.                 spec->type = FORMAT_TYPE_PERCENT_CHAR;
  1044.                 return ++fmt - start;
  1045.  
  1046.         /* integer number formats - set up the flags and "break" */
  1047.         case 'o':
  1048.                 spec->base = 8;
  1049.                 break;
  1050.  
  1051.         case 'x':
  1052.                 spec->flags |= SMALL;
  1053.  
  1054.         case 'X':
  1055.                 spec->base = 16;
  1056.                 break;
  1057.  
  1058.         case 'd':
  1059.         case 'i':
  1060.                 spec->flags |= SIGN;
  1061.         case 'u':
  1062.                 break;
  1063.  
  1064.         default:
  1065.                 spec->type = FORMAT_TYPE_INVALID;
  1066.                 return fmt - start;
  1067.         }
  1068.  
  1069.         if (spec->qualifier == 'L')
  1070.                 spec->type = FORMAT_TYPE_LONG_LONG;
  1071.         else if (spec->qualifier == 'l') {
  1072.                 if (spec->flags & SIGN)
  1073.                         spec->type = FORMAT_TYPE_LONG;
  1074.                 else
  1075.                         spec->type = FORMAT_TYPE_ULONG;
  1076.         } else if (TOLOWER(spec->qualifier) == 'z') {
  1077.                 spec->type = FORMAT_TYPE_SIZE_T;
  1078.         } else if (spec->qualifier == 't') {
  1079.                 spec->type = FORMAT_TYPE_PTRDIFF;
  1080.         } else if (spec->qualifier == 'H') {
  1081.                 if (spec->flags & SIGN)
  1082.                         spec->type = FORMAT_TYPE_BYTE;
  1083.                 else
  1084.                         spec->type = FORMAT_TYPE_UBYTE;
  1085.         } else if (spec->qualifier == 'h') {
  1086.                 if (spec->flags & SIGN)
  1087.                         spec->type = FORMAT_TYPE_SHORT;
  1088.                 else
  1089.                         spec->type = FORMAT_TYPE_USHORT;
  1090.         } else {
  1091.                 if (spec->flags & SIGN)
  1092.                         spec->type = FORMAT_TYPE_INT;
  1093.                 else
  1094.                         spec->type = FORMAT_TYPE_UINT;
  1095.         }
  1096.  
  1097.         return ++fmt - start;
  1098. }
  1099.  
  1100. /**
  1101.  * vsnprintf - Format a string and place it in a buffer
  1102.  * @buf: The buffer to place the result into
  1103.  * @size: The size of the buffer, including the trailing null space
  1104.  * @fmt: The format string to use
  1105.  * @args: Arguments for the format string
  1106.  *
  1107.  * This function follows C99 vsnprintf, but has some extensions:
  1108.  * %pS output the name of a text symbol with offset
  1109.  * %ps output the name of a text symbol without offset
  1110.  * %pF output the name of a function pointer with its offset
  1111.  * %pf output the name of a function pointer without its offset
  1112.  * %pR output the address range in a struct resource with decoded flags
  1113.  * %pr output the address range in a struct resource with raw flags
  1114.  * %pM output a 6-byte MAC address with colons
  1115.  * %pm output a 6-byte MAC address without colons
  1116.  * %pI4 print an IPv4 address without leading zeros
  1117.  * %pi4 print an IPv4 address with leading zeros
  1118.  * %pI6 print an IPv6 address with colons
  1119.  * %pi6 print an IPv6 address without colons
  1120.  * %pI6c print an IPv6 address as specified by
  1121.  *   http://tools.ietf.org/html/draft-ietf-6man-text-addr-representation-00
  1122.  * %pU[bBlL] print a UUID/GUID in big or little endian using lower or upper
  1123.  *   case.
  1124.  * %n is ignored
  1125.  *
  1126.  * The return value is the number of characters which would
  1127.  * be generated for the given input, excluding the trailing
  1128.  * '\0', as per ISO C99. If you want to have the exact
  1129.  * number of characters written into @buf as return value
  1130.  * (not including the trailing '\0'), use vscnprintf(). If the
  1131.  * return is greater than or equal to @size, the resulting
  1132.  * string is truncated.
  1133.  *
  1134.  * Call this function if you are already dealing with a va_list.
  1135.  * You probably want snprintf() instead.
  1136.  */
  1137. int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
  1138. {
  1139.         unsigned long long num;
  1140.         char *str, *end;
  1141.         struct printf_spec spec = {0};
  1142.  
  1143.         /* Reject out-of-range values early.  Large positive sizes are
  1144.            used for unknown buffer sizes. */
  1145.     if ((int)size < 0)
  1146.                 return 0;
  1147.  
  1148.         str = buf;
  1149.         end = buf + size;
  1150.  
  1151.         /* Make sure end is always >= buf */
  1152.         if (end < buf) {
  1153.                 end = ((void *)-1);
  1154.                 size = end - buf;
  1155.         }
  1156.  
  1157.         while (*fmt) {
  1158.                 const char *old_fmt = fmt;
  1159.                 int read = format_decode(fmt, &spec);
  1160.  
  1161.                 fmt += read;
  1162.  
  1163.                 switch (spec.type) {
  1164.                 case FORMAT_TYPE_NONE: {
  1165.                         int copy = read;
  1166.                         if (str < end) {
  1167.                                 if (copy > end - str)
  1168.                                         copy = end - str;
  1169.                                 memcpy(str, old_fmt, copy);
  1170.                         }
  1171.                         str += read;
  1172.                         break;
  1173.                 }
  1174.  
  1175.                 case FORMAT_TYPE_WIDTH:
  1176.                         spec.field_width = va_arg(args, int);
  1177.                         break;
  1178.  
  1179.                 case FORMAT_TYPE_PRECISION:
  1180.                         spec.precision = va_arg(args, int);
  1181.                         break;
  1182.  
  1183.                 case FORMAT_TYPE_CHAR: {
  1184.                         char c;
  1185.  
  1186.                         if (!(spec.flags & LEFT)) {
  1187.                                 while (--spec.field_width > 0) {
  1188.                                         if (str < end)
  1189.                                                 *str = ' ';
  1190.                                         ++str;
  1191.  
  1192.                                 }
  1193.                         }
  1194.                         c = (unsigned char) va_arg(args, int);
  1195.                         if (str < end)
  1196.                                 *str = c;
  1197.                         ++str;
  1198.                         while (--spec.field_width > 0) {
  1199.                                 if (str < end)
  1200.                                         *str = ' ';
  1201.                                 ++str;
  1202.                         }
  1203.                         break;
  1204.                 }
  1205.  
  1206.                 case FORMAT_TYPE_STR:
  1207.                         str = string(str, end, va_arg(args, char *), spec);
  1208.                         break;
  1209.  
  1210.                 case FORMAT_TYPE_PTR:
  1211.                         str = pointer(fmt+1, str, end, va_arg(args, void *),
  1212.                                       spec);
  1213.                         while (isalnum(*fmt))
  1214.                                 fmt++;
  1215.                         break;
  1216.  
  1217.                 case FORMAT_TYPE_PERCENT_CHAR:
  1218.                         if (str < end)
  1219.                                 *str = '%';
  1220.                         ++str;
  1221.                         break;
  1222.  
  1223.                 case FORMAT_TYPE_INVALID:
  1224.                         if (str < end)
  1225.                                 *str = '%';
  1226.                         ++str;
  1227.                         break;
  1228.  
  1229.                 case FORMAT_TYPE_NRCHARS: {
  1230.                         u8 qualifier = spec.qualifier;
  1231.  
  1232.                         if (qualifier == 'l') {
  1233.                                 long *ip = va_arg(args, long *);
  1234.                                 *ip = (str - buf);
  1235.                         } else if (TOLOWER(qualifier) == 'z') {
  1236.                                 size_t *ip = va_arg(args, size_t *);
  1237.                                 *ip = (str - buf);
  1238.                         } else {
  1239.                                 int *ip = va_arg(args, int *);
  1240.                                 *ip = (str - buf);
  1241.                         }
  1242.                         break;
  1243.                 }
  1244.  
  1245.                 default:
  1246.                         switch (spec.type) {
  1247.                         case FORMAT_TYPE_LONG_LONG:
  1248.                                 num = va_arg(args, long long);
  1249.                                 break;
  1250.                         case FORMAT_TYPE_ULONG:
  1251.                                 num = va_arg(args, unsigned long);
  1252.                                 break;
  1253.                         case FORMAT_TYPE_LONG:
  1254.                                 num = va_arg(args, long);
  1255.                                 break;
  1256.                         case FORMAT_TYPE_SIZE_T:
  1257.                                 num = va_arg(args, size_t);
  1258.                                 break;
  1259.                         case FORMAT_TYPE_PTRDIFF:
  1260.                                 num = va_arg(args, ptrdiff_t);
  1261.                                 break;
  1262.                         case FORMAT_TYPE_UBYTE:
  1263.                                 num = (unsigned char) va_arg(args, int);
  1264.                                 break;
  1265.                         case FORMAT_TYPE_BYTE:
  1266.                                 num = (signed char) va_arg(args, int);
  1267.                                 break;
  1268.                         case FORMAT_TYPE_USHORT:
  1269.                                 num = (unsigned short) va_arg(args, int);
  1270.                                 break;
  1271.                         case FORMAT_TYPE_SHORT:
  1272.                                 num = (short) va_arg(args, int);
  1273.                                 break;
  1274.                         case FORMAT_TYPE_INT:
  1275.                                 num = (int) va_arg(args, int);
  1276.                                 break;
  1277.                         default:
  1278.                                 num = va_arg(args, unsigned int);
  1279.                         }
  1280.  
  1281.                         str = number(str, end, num, spec);
  1282.                 }
  1283.         }
  1284.  
  1285.         if (size > 0) {
  1286.                 if (str < end)
  1287.                         *str = '\0';
  1288.                 else
  1289.                         end[-1] = '\0';
  1290.         }
  1291.  
  1292.         /* the trailing null byte doesn't count towards the total */
  1293.         return str-buf;
  1294.  
  1295. }
  1296. EXPORT_SYMBOL(vsnprintf);
  1297.  
  1298. int vsprintf(char *buf, const char *fmt, va_list args)
  1299. {
  1300.     return vsnprintf(buf, INT_MAX, fmt, args);
  1301. }
  1302.  
  1303.  
  1304. /**
  1305.  * snprintf - Format a string and place it in a buffer
  1306.  * @buf: The buffer to place the result into
  1307.  * @size: The size of the buffer, including the trailing null space
  1308.  * @fmt: The format string to use
  1309.  * @...: Arguments for the format string
  1310.  *
  1311.  * The return value is the number of characters which would be
  1312.  * generated for the given input, excluding the trailing null,
  1313.  * as per ISO C99.  If the return is greater than or equal to
  1314.  * @size, the resulting string is truncated.
  1315.  *
  1316.  * See the vsnprintf() documentation for format string extensions over C99.
  1317.  */
  1318. int snprintf(char *buf, size_t size, const char *fmt, ...)
  1319. {
  1320.         va_list args;
  1321.         int i;
  1322.  
  1323.         va_start(args, fmt);
  1324.         i = vsnprintf(buf, size, fmt, args);
  1325.         va_end(args);
  1326.  
  1327.         return i;
  1328. }
  1329. EXPORT_SYMBOL(snprintf);
  1330.  
  1331.  
  1332. /**
  1333.  * sprintf - Format a string and place it in a buffer
  1334.  * @buf: The buffer to place the result into
  1335.  * @fmt: The format string to use
  1336.  * @...: Arguments for the format string
  1337.  *
  1338.  * The function returns the number of characters written
  1339.  * into @buf. Use snprintf() or scnprintf() in order to avoid
  1340.  * buffer overflows.
  1341.  *
  1342.  * See the vsnprintf() documentation for format string extensions over C99.
  1343.  */
  1344. int sprintf(char *buf, const char *fmt, ...)
  1345. {
  1346.         va_list args;
  1347.         int i;
  1348.  
  1349.         va_start(args, fmt);
  1350.         i = vsnprintf(buf, INT_MAX, fmt, args);
  1351.         va_end(args);
  1352.  
  1353.         return i;
  1354. }
  1355.  
  1356.