Subversion Repositories Kolibri OS

Rev

Rev 1408 | Rev 1871 | 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.         char sym[max(2*RSRC_BUF_SIZE + DECODED_BUF_SIZE,
  651.                      2*RSRC_BUF_SIZE + FLAG_BUF_SIZE + RAW_BUF_SIZE)];
  652.  
  653.         char *p = sym, *pend = sym + sizeof(sym);
  654.         int decode = (fmt[0] == 'R') ? 1 : 0;
  655.         const struct printf_spec *specp;
  656.  
  657.         *p++ = '[';
  658.         if (res->flags & IORESOURCE_IO) {
  659.                 p = string(p, pend, "io  ", str_spec);
  660.                 specp = &io_spec;
  661.         } else if (res->flags & IORESOURCE_MEM) {
  662.                 p = string(p, pend, "mem ", str_spec);
  663.                 specp = &mem_spec;
  664.         } else if (res->flags & IORESOURCE_IRQ) {
  665.                 p = string(p, pend, "irq ", str_spec);
  666.                 specp = &dec_spec;
  667.         } else if (res->flags & IORESOURCE_DMA) {
  668.                 p = string(p, pend, "dma ", str_spec);
  669.                 specp = &dec_spec;
  670.         } else if (res->flags & IORESOURCE_BUS) {
  671.                 p = string(p, pend, "bus ", str_spec);
  672.                 specp = &bus_spec;
  673.         } else {
  674.                 p = string(p, pend, "??? ", str_spec);
  675.                 specp = &mem_spec;
  676.                 decode = 0;
  677.         }
  678.         p = number(p, pend, res->start, *specp);
  679.         if (res->start != res->end) {
  680.                 *p++ = '-';
  681.                 p = number(p, pend, res->end, *specp);
  682.         }
  683.         if (decode) {
  684.                 if (res->flags & IORESOURCE_MEM_64)
  685.                         p = string(p, pend, " 64bit", str_spec);
  686.                 if (res->flags & IORESOURCE_PREFETCH)
  687.                         p = string(p, pend, " pref", str_spec);
  688.                 if (res->flags & IORESOURCE_WINDOW)
  689.                         p = string(p, pend, " window", str_spec);
  690.                 if (res->flags & IORESOURCE_DISABLED)
  691.                         p = string(p, pend, " disabled", str_spec);
  692.         } else {
  693.                 p = string(p, pend, " flags ", str_spec);
  694.                 p = number(p, pend, res->flags, flag_spec);
  695.         }
  696.         *p++ = ']';
  697.         *p = '\0';
  698.  
  699.         return string(buf, end, sym, spec);
  700. }
  701.  
  702. static noinline_for_stack
  703. char *mac_address_string(char *buf, char *end, u8 *addr,
  704.                          struct printf_spec spec, const char *fmt)
  705. {
  706.         char mac_addr[sizeof("xx:xx:xx:xx:xx:xx")];
  707.         char *p = mac_addr;
  708.         int i;
  709.         char separator;
  710.  
  711.         if (fmt[1] == 'F') {            /* FDDI canonical format */
  712.                 separator = '-';
  713.         } else {
  714.                 separator = ':';
  715.         }
  716.  
  717.         for (i = 0; i < 6; i++) {
  718.                 p = pack_hex_byte(p, addr[i]);
  719.                 if (fmt[0] == 'M' && i != 5)
  720.                         *p++ = separator;
  721.         }
  722.         *p = '\0';
  723.  
  724.         return string(buf, end, mac_addr, spec);
  725. }
  726.  
  727. static noinline_for_stack
  728. char *ip4_string(char *p, const u8 *addr, const char *fmt)
  729. {
  730.         int i;
  731.         bool leading_zeros = (fmt[0] == 'i');
  732.         int index;
  733.         int step;
  734.  
  735.         switch (fmt[2]) {
  736.         case 'h':
  737. #ifdef __BIG_ENDIAN
  738.                 index = 0;
  739.                 step = 1;
  740. #else
  741.                 index = 3;
  742.                 step = -1;
  743. #endif
  744.                 break;
  745.         case 'l':
  746.                 index = 3;
  747.                 step = -1;
  748.                 break;
  749.         case 'n':
  750.         case 'b':
  751.         default:
  752.                 index = 0;
  753.                 step = 1;
  754.                 break;
  755.         }
  756.         for (i = 0; i < 4; i++) {
  757.                 char temp[3];   /* hold each IP quad in reverse order */
  758.                 int digits = put_dec_trunc(temp, addr[index]) - temp;
  759.                 if (leading_zeros) {
  760.                         if (digits < 3)
  761.                                 *p++ = '0';
  762.                         if (digits < 2)
  763.                                 *p++ = '0';
  764.                 }
  765.                 /* reverse the digits in the quad */
  766.                 while (digits--)
  767.                         *p++ = temp[digits];
  768.                 if (i < 3)
  769.                         *p++ = '.';
  770.                 index += step;
  771.         }
  772.         *p = '\0';
  773.  
  774.         return p;
  775. }
  776.  
  777.  
  778. static noinline_for_stack
  779. char *ip4_addr_string(char *buf, char *end, const u8 *addr,
  780.                       struct printf_spec spec, const char *fmt)
  781. {
  782.         char ip4_addr[sizeof("255.255.255.255")];
  783.  
  784.         ip4_string(ip4_addr, addr, fmt);
  785.  
  786.         return string(buf, end, ip4_addr, spec);
  787. }
  788.  
  789.  
  790. int kptr_restrict = 1;
  791.  
  792. /*
  793.  * Show a '%p' thing.  A kernel extension is that the '%p' is followed
  794.  * by an extra set of alphanumeric characters that are extended format
  795.  * specifiers.
  796.  *
  797.  * Right now we handle:
  798.  *
  799.  * - 'F' For symbolic function descriptor pointers with offset
  800.  * - 'f' For simple symbolic function names without offset
  801.  * - 'S' For symbolic direct pointers with offset
  802.  * - 's' For symbolic direct pointers without offset
  803.  * - 'R' For decoded struct resource, e.g., [mem 0x0-0x1f 64bit pref]
  804.  * - 'r' For raw struct resource, e.g., [mem 0x0-0x1f flags 0x201]
  805.  * - 'M' For a 6-byte MAC address, it prints the address in the
  806.  *       usual colon-separated hex notation
  807.  * - 'm' For a 6-byte MAC address, it prints the hex address without colons
  808.  * - 'MF' For a 6-byte MAC FDDI address, it prints the address
  809.  *       with a dash-separated hex notation
  810.  * - 'I' [46] for IPv4/IPv6 addresses printed in the usual way
  811.  *       IPv4 uses dot-separated decimal without leading 0's (1.2.3.4)
  812.  *       IPv6 uses colon separated network-order 16 bit hex with leading 0's
  813.  * - 'i' [46] for 'raw' IPv4/IPv6 addresses
  814.  *       IPv6 omits the colons (01020304...0f)
  815.  *       IPv4 uses dot-separated decimal with leading 0's (010.123.045.006)
  816.  * - '[Ii]4[hnbl]' IPv4 addresses in host, network, big or little endian order
  817.  * - 'I6c' for IPv6 addresses printed as specified by
  818.  *       http://tools.ietf.org/html/draft-ietf-6man-text-addr-representation-00
  819.  * - 'U' For a 16 byte UUID/GUID, it prints the UUID/GUID in the form
  820.  *       "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
  821.  *       Options for %pU are:
  822.  *         b big endian lower case hex (default)
  823.  *         B big endian UPPER case hex
  824.  *         l little endian lower case hex
  825.  *         L little endian UPPER case hex
  826.  *           big endian output byte order is:
  827.  *             [0][1][2][3]-[4][5]-[6][7]-[8][9]-[10][11][12][13][14][15]
  828.  *           little endian output byte order is:
  829.  *             [3][2][1][0]-[5][4]-[7][6]-[8][9]-[10][11][12][13][14][15]
  830.  * - 'V' For a struct va_format which contains a format string * and va_list *,
  831.  *       call vsnprintf(->format, *->va_list).
  832.  *       Implements a "recursive vsnprintf".
  833.  *       Do not use this feature without some mechanism to verify the
  834.  *       correctness of the format string and va_list arguments.
  835.  * - 'K' For a kernel pointer that should be hidden from unprivileged users
  836.  *
  837.  * Note: The difference between 'S' and 'F' is that on ia64 and ppc64
  838.  * function pointers are really function descriptors, which contain a
  839.  * pointer to the real address.
  840.  */
  841. static noinline_for_stack
  842. char *pointer(const char *fmt, char *buf, char *end, void *ptr,
  843.               struct printf_spec spec)
  844. {
  845.         if (!ptr) {
  846.                 /*
  847.                  * Print (null) with the same width as a pointer so it makes
  848.                  * tabular output look nice.
  849.                  */
  850.                 if (spec.field_width == -1)
  851.                         spec.field_width = 2 * sizeof(void *);
  852.                 return string(buf, end, "(null)", spec);
  853.         }
  854.  
  855.         switch (*fmt) {
  856.         case 'F':
  857.         case 'f':
  858.                 ptr = dereference_function_descriptor(ptr);
  859.                 /* Fallthrough */
  860.         case 'S':
  861.         case 's':
  862.                 return symbol_string(buf, end, ptr, spec, *fmt);
  863.         case 'R':
  864.         case 'r':
  865.                 return resource_string(buf, end, ptr, spec, fmt);
  866.         case 'M':                       /* Colon separated: 00:01:02:03:04:05 */
  867.         case 'm':                       /* Contiguous: 000102030405 */
  868.                                         /* [mM]F (FDDI, bit reversed) */
  869.                 return mac_address_string(buf, end, ptr, spec, fmt);
  870.         case 'I':                       /* Formatted IP supported
  871.                                          * 4:   1.2.3.4
  872.                                          * 6:   0001:0203:...:0708
  873.                                          * 6c:  1::708 or 1::1.2.3.4
  874.                                          */
  875.         case 'i':                       /* Contiguous:
  876.                                          * 4:   001.002.003.004
  877.                                          * 6:   000102...0f
  878.                                          */
  879.                 switch (fmt[1]) {
  880.                 case '4':
  881.                         return ip4_addr_string(buf, end, ptr, spec, fmt);
  882.                 }
  883.                 break;
  884.         case 'V':
  885.                 return buf + vsnprintf(buf, end - buf,
  886.                                        ((struct va_format *)ptr)->fmt,
  887.                                        *(((struct va_format *)ptr)->va));
  888.         }
  889.         spec.flags |= SMALL;
  890.         if (spec.field_width == -1) {
  891.                 spec.field_width = 2 * sizeof(void *);
  892.                 spec.flags |= ZEROPAD;
  893.         }
  894.         spec.base = 16;
  895.  
  896.         return number(buf, end, (unsigned long) ptr, spec);
  897. }
  898.  
  899. /*
  900.  * Helper function to decode printf style format.
  901.  * Each call decode a token from the format and return the
  902.  * number of characters read (or likely the delta where it wants
  903.  * to go on the next call).
  904.  * The decoded token is returned through the parameters
  905.  *
  906.  * 'h', 'l', or 'L' for integer fields
  907.  * 'z' support added 23/7/1999 S.H.
  908.  * 'z' changed to 'Z' --davidm 1/25/99
  909.  * 't' added for ptrdiff_t
  910.  *
  911.  * @fmt: the format string
  912.  * @type of the token returned
  913.  * @flags: various flags such as +, -, # tokens..
  914.  * @field_width: overwritten width
  915.  * @base: base of the number (octal, hex, ...)
  916.  * @precision: precision of a number
  917.  * @qualifier: qualifier of a number (long, size_t, ...)
  918.  */
  919. static noinline_for_stack
  920. int format_decode(const char *fmt, struct printf_spec *spec)
  921. {
  922.         const char *start = fmt;
  923.  
  924.         /* we finished early by reading the field width */
  925.         if (spec->type == FORMAT_TYPE_WIDTH) {
  926.                 if (spec->field_width < 0) {
  927.                         spec->field_width = -spec->field_width;
  928.                         spec->flags |= LEFT;
  929.                 }
  930.                 spec->type = FORMAT_TYPE_NONE;
  931.                 goto precision;
  932.         }
  933.  
  934.         /* we finished early by reading the precision */
  935.         if (spec->type == FORMAT_TYPE_PRECISION) {
  936.                 if (spec->precision < 0)
  937.                         spec->precision = 0;
  938.  
  939.                 spec->type = FORMAT_TYPE_NONE;
  940.                 goto qualifier;
  941.         }
  942.  
  943.         /* By default */
  944.         spec->type = FORMAT_TYPE_NONE;
  945.  
  946.         for (; *fmt ; ++fmt) {
  947.                 if (*fmt == '%')
  948.                         break;
  949.         }
  950.  
  951.         /* Return the current non-format string */
  952.         if (fmt != start || !*fmt)
  953.                 return fmt - start;
  954.  
  955.         /* Process flags */
  956.         spec->flags = 0;
  957.  
  958.         while (1) { /* this also skips first '%' */
  959.                 bool found = true;
  960.  
  961.                 ++fmt;
  962.  
  963.                 switch (*fmt) {
  964.                 case '-': spec->flags |= LEFT;    break;
  965.                 case '+': spec->flags |= PLUS;    break;
  966.                 case ' ': spec->flags |= SPACE;   break;
  967.                 case '#': spec->flags |= SPECIAL; break;
  968.                 case '0': spec->flags |= ZEROPAD; break;
  969.                 default:  found = false;
  970.                 }
  971.  
  972.                 if (!found)
  973.                         break;
  974.         }
  975.  
  976.         /* get field width */
  977.         spec->field_width = -1;
  978.  
  979.         if (isdigit(*fmt))
  980.                 spec->field_width = skip_atoi(&fmt);
  981.         else if (*fmt == '*') {
  982.                 /* it's the next argument */
  983.                 spec->type = FORMAT_TYPE_WIDTH;
  984.                 return ++fmt - start;
  985.         }
  986.  
  987. precision:
  988.         /* get the precision */
  989.         spec->precision = -1;
  990.         if (*fmt == '.') {
  991.                 ++fmt;
  992.                 if (isdigit(*fmt)) {
  993.                         spec->precision = skip_atoi(&fmt);
  994.                         if (spec->precision < 0)
  995.                                 spec->precision = 0;
  996.                 } else if (*fmt == '*') {
  997.                         /* it's the next argument */
  998.                         spec->type = FORMAT_TYPE_PRECISION;
  999.                         return ++fmt - start;
  1000.                 }
  1001.         }
  1002.  
  1003. qualifier:
  1004.         /* get the conversion qualifier */
  1005.         spec->qualifier = -1;
  1006.         if (*fmt == 'h' || TOLOWER(*fmt) == 'l' ||
  1007.             TOLOWER(*fmt) == 'z' || *fmt == 't') {
  1008.                 spec->qualifier = *fmt++;
  1009.                 if (unlikely(spec->qualifier == *fmt)) {
  1010.                         if (spec->qualifier == 'l') {
  1011.                                 spec->qualifier = 'L';
  1012.                                 ++fmt;
  1013.                         } else if (spec->qualifier == 'h') {
  1014.                                 spec->qualifier = 'H';
  1015.                                 ++fmt;
  1016.                         }
  1017.                 }
  1018.         }
  1019.  
  1020.         /* default base */
  1021.         spec->base = 10;
  1022.         switch (*fmt) {
  1023.         case 'c':
  1024.                 spec->type = FORMAT_TYPE_CHAR;
  1025.                 return ++fmt - start;
  1026.  
  1027.         case 's':
  1028.                 spec->type = FORMAT_TYPE_STR;
  1029.                 return ++fmt - start;
  1030.  
  1031.         case 'p':
  1032.                 spec->type = FORMAT_TYPE_PTR;
  1033.                 return fmt - start;
  1034.                 /* skip alnum */
  1035.  
  1036.         case 'n':
  1037.                 spec->type = FORMAT_TYPE_NRCHARS;
  1038.                 return ++fmt - start;
  1039.  
  1040.         case '%':
  1041.                 spec->type = FORMAT_TYPE_PERCENT_CHAR;
  1042.                 return ++fmt - start;
  1043.  
  1044.         /* integer number formats - set up the flags and "break" */
  1045.         case 'o':
  1046.                 spec->base = 8;
  1047.                 break;
  1048.  
  1049.         case 'x':
  1050.                 spec->flags |= SMALL;
  1051.  
  1052.         case 'X':
  1053.                 spec->base = 16;
  1054.                 break;
  1055.  
  1056.         case 'd':
  1057.         case 'i':
  1058.                 spec->flags |= SIGN;
  1059.         case 'u':
  1060.                 break;
  1061.  
  1062.         default:
  1063.                 spec->type = FORMAT_TYPE_INVALID;
  1064.                 return fmt - start;
  1065.         }
  1066.  
  1067.         if (spec->qualifier == 'L')
  1068.                 spec->type = FORMAT_TYPE_LONG_LONG;
  1069.         else if (spec->qualifier == 'l') {
  1070.                 if (spec->flags & SIGN)
  1071.                         spec->type = FORMAT_TYPE_LONG;
  1072.                 else
  1073.                         spec->type = FORMAT_TYPE_ULONG;
  1074.         } else if (TOLOWER(spec->qualifier) == 'z') {
  1075.                 spec->type = FORMAT_TYPE_SIZE_T;
  1076.         } else if (spec->qualifier == 't') {
  1077.                 spec->type = FORMAT_TYPE_PTRDIFF;
  1078.         } else if (spec->qualifier == 'H') {
  1079.                 if (spec->flags & SIGN)
  1080.                         spec->type = FORMAT_TYPE_BYTE;
  1081.                 else
  1082.                         spec->type = FORMAT_TYPE_UBYTE;
  1083.         } else if (spec->qualifier == 'h') {
  1084.                 if (spec->flags & SIGN)
  1085.                         spec->type = FORMAT_TYPE_SHORT;
  1086.                 else
  1087.                         spec->type = FORMAT_TYPE_USHORT;
  1088.         } else {
  1089.                 if (spec->flags & SIGN)
  1090.                         spec->type = FORMAT_TYPE_INT;
  1091.                 else
  1092.                         spec->type = FORMAT_TYPE_UINT;
  1093.         }
  1094.  
  1095.         return ++fmt - start;
  1096. }
  1097.  
  1098. /**
  1099.  * vsnprintf - Format a string and place it in a buffer
  1100.  * @buf: The buffer to place the result into
  1101.  * @size: The size of the buffer, including the trailing null space
  1102.  * @fmt: The format string to use
  1103.  * @args: Arguments for the format string
  1104.  *
  1105.  * This function follows C99 vsnprintf, but has some extensions:
  1106.  * %pS output the name of a text symbol with offset
  1107.  * %ps output the name of a text symbol without offset
  1108.  * %pF output the name of a function pointer with its offset
  1109.  * %pf output the name of a function pointer without its offset
  1110.  * %pR output the address range in a struct resource with decoded flags
  1111.  * %pr output the address range in a struct resource with raw flags
  1112.  * %pM output a 6-byte MAC address with colons
  1113.  * %pm output a 6-byte MAC address without colons
  1114.  * %pI4 print an IPv4 address without leading zeros
  1115.  * %pi4 print an IPv4 address with leading zeros
  1116.  * %pI6 print an IPv6 address with colons
  1117.  * %pi6 print an IPv6 address without colons
  1118.  * %pI6c print an IPv6 address as specified by
  1119.  *   http://tools.ietf.org/html/draft-ietf-6man-text-addr-representation-00
  1120.  * %pU[bBlL] print a UUID/GUID in big or little endian using lower or upper
  1121.  *   case.
  1122.  * %n is ignored
  1123.  *
  1124.  * The return value is the number of characters which would
  1125.  * be generated for the given input, excluding the trailing
  1126.  * '\0', as per ISO C99. If you want to have the exact
  1127.  * number of characters written into @buf as return value
  1128.  * (not including the trailing '\0'), use vscnprintf(). If the
  1129.  * return is greater than or equal to @size, the resulting
  1130.  * string is truncated.
  1131.  *
  1132.  * Call this function if you are already dealing with a va_list.
  1133.  * You probably want snprintf() instead.
  1134.  */
  1135. int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
  1136. {
  1137.         unsigned long long num;
  1138.         char *str, *end;
  1139.         struct printf_spec spec = {0};
  1140.  
  1141.         /* Reject out-of-range values early.  Large positive sizes are
  1142.            used for unknown buffer sizes. */
  1143.     if ((int)size < 0)
  1144.                 return 0;
  1145.  
  1146.         str = buf;
  1147.         end = buf + size;
  1148.  
  1149.         /* Make sure end is always >= buf */
  1150.         if (end < buf) {
  1151.                 end = ((void *)-1);
  1152.                 size = end - buf;
  1153.         }
  1154.  
  1155.         while (*fmt) {
  1156.                 const char *old_fmt = fmt;
  1157.                 int read = format_decode(fmt, &spec);
  1158.  
  1159.                 fmt += read;
  1160.  
  1161.                 switch (spec.type) {
  1162.                 case FORMAT_TYPE_NONE: {
  1163.                         int copy = read;
  1164.                         if (str < end) {
  1165.                                 if (copy > end - str)
  1166.                                         copy = end - str;
  1167.                                 memcpy(str, old_fmt, copy);
  1168.                         }
  1169.                         str += read;
  1170.                         break;
  1171.                 }
  1172.  
  1173.                 case FORMAT_TYPE_WIDTH:
  1174.                         spec.field_width = va_arg(args, int);
  1175.                         break;
  1176.  
  1177.                 case FORMAT_TYPE_PRECISION:
  1178.                         spec.precision = va_arg(args, int);
  1179.                         break;
  1180.  
  1181.                 case FORMAT_TYPE_CHAR: {
  1182.                         char c;
  1183.  
  1184.                         if (!(spec.flags & LEFT)) {
  1185.                                 while (--spec.field_width > 0) {
  1186.                                         if (str < end)
  1187.                                                 *str = ' ';
  1188.                                         ++str;
  1189.  
  1190.                                 }
  1191.                         }
  1192.                         c = (unsigned char) va_arg(args, int);
  1193.                         if (str < end)
  1194.                                 *str = c;
  1195.                         ++str;
  1196.                         while (--spec.field_width > 0) {
  1197.                                 if (str < end)
  1198.                                         *str = ' ';
  1199.                                 ++str;
  1200.                         }
  1201.                         break;
  1202.                 }
  1203.  
  1204.                 case FORMAT_TYPE_STR:
  1205.                         str = string(str, end, va_arg(args, char *), spec);
  1206.                         break;
  1207.  
  1208.                 case FORMAT_TYPE_PTR:
  1209.                         str = pointer(fmt+1, str, end, va_arg(args, void *),
  1210.                                       spec);
  1211.                         while (isalnum(*fmt))
  1212.                                 fmt++;
  1213.                         break;
  1214.  
  1215.                 case FORMAT_TYPE_PERCENT_CHAR:
  1216.                         if (str < end)
  1217.                                 *str = '%';
  1218.                         ++str;
  1219.                         break;
  1220.  
  1221.                 case FORMAT_TYPE_INVALID:
  1222.                         if (str < end)
  1223.                                 *str = '%';
  1224.                         ++str;
  1225.                         break;
  1226.  
  1227.                 case FORMAT_TYPE_NRCHARS: {
  1228.                         u8 qualifier = spec.qualifier;
  1229.  
  1230.                         if (qualifier == 'l') {
  1231.                                 long *ip = va_arg(args, long *);
  1232.                                 *ip = (str - buf);
  1233.                         } else if (TOLOWER(qualifier) == 'z') {
  1234.                                 size_t *ip = va_arg(args, size_t *);
  1235.                                 *ip = (str - buf);
  1236.                         } else {
  1237.                                 int *ip = va_arg(args, int *);
  1238.                                 *ip = (str - buf);
  1239.                         }
  1240.                         break;
  1241.                 }
  1242.  
  1243.                 default:
  1244.                         switch (spec.type) {
  1245.                         case FORMAT_TYPE_LONG_LONG:
  1246.                                 num = va_arg(args, long long);
  1247.                                 break;
  1248.                         case FORMAT_TYPE_ULONG:
  1249.                                 num = va_arg(args, unsigned long);
  1250.                                 break;
  1251.                         case FORMAT_TYPE_LONG:
  1252.                                 num = va_arg(args, long);
  1253.                                 break;
  1254.                         case FORMAT_TYPE_SIZE_T:
  1255.                                 num = va_arg(args, size_t);
  1256.                                 break;
  1257.                         case FORMAT_TYPE_PTRDIFF:
  1258.                                 num = va_arg(args, ptrdiff_t);
  1259.                                 break;
  1260.                         case FORMAT_TYPE_UBYTE:
  1261.                                 num = (unsigned char) va_arg(args, int);
  1262.                                 break;
  1263.                         case FORMAT_TYPE_BYTE:
  1264.                                 num = (signed char) va_arg(args, int);
  1265.                                 break;
  1266.                         case FORMAT_TYPE_USHORT:
  1267.                                 num = (unsigned short) va_arg(args, int);
  1268.                                 break;
  1269.                         case FORMAT_TYPE_SHORT:
  1270.                                 num = (short) va_arg(args, int);
  1271.                                 break;
  1272.                         case FORMAT_TYPE_INT:
  1273.                                 num = (int) va_arg(args, int);
  1274.                                 break;
  1275.                         default:
  1276.                                 num = va_arg(args, unsigned int);
  1277.                         }
  1278.  
  1279.                         str = number(str, end, num, spec);
  1280.                 }
  1281.         }
  1282.  
  1283.         if (size > 0) {
  1284.                 if (str < end)
  1285.                         *str = '\0';
  1286.                 else
  1287.                         end[-1] = '\0';
  1288.         }
  1289.  
  1290.         /* the trailing null byte doesn't count towards the total */
  1291.         return str-buf;
  1292.  
  1293. }
  1294. EXPORT_SYMBOL(vsnprintf);
  1295.  
  1296. int vsprintf(char *buf, const char *fmt, va_list args)
  1297. {
  1298.     return vsnprintf(buf, INT_MAX, fmt, args);
  1299. }
  1300.  
  1301.  
  1302. /**
  1303.  * snprintf - Format a string and place it in a buffer
  1304.  * @buf: The buffer to place the result into
  1305.  * @size: The size of the buffer, including the trailing null space
  1306.  * @fmt: The format string to use
  1307.  * @...: Arguments for the format string
  1308.  *
  1309.  * The return value is the number of characters which would be
  1310.  * generated for the given input, excluding the trailing null,
  1311.  * as per ISO C99.  If the return is greater than or equal to
  1312.  * @size, the resulting string is truncated.
  1313.  *
  1314.  * See the vsnprintf() documentation for format string extensions over C99.
  1315.  */
  1316. int snprintf(char *buf, size_t size, const char *fmt, ...)
  1317. {
  1318.         va_list args;
  1319.         int i;
  1320.  
  1321.         va_start(args, fmt);
  1322.         i = vsnprintf(buf, size, fmt, args);
  1323.         va_end(args);
  1324.  
  1325.         return i;
  1326. }
  1327. EXPORT_SYMBOL(snprintf);
  1328.  
  1329.  
  1330. /**
  1331.  * sprintf - Format a string and place it in a buffer
  1332.  * @buf: The buffer to place the result into
  1333.  * @fmt: The format string to use
  1334.  * @...: Arguments for the format string
  1335.  *
  1336.  * The function returns the number of characters written
  1337.  * into @buf. Use snprintf() or scnprintf() in order to avoid
  1338.  * buffer overflows.
  1339.  *
  1340.  * See the vsnprintf() documentation for format string extensions over C99.
  1341.  */
  1342. int sprintf(char *buf, const char *fmt, ...)
  1343. {
  1344.         va_list args;
  1345.         int i;
  1346.  
  1347.         va_start(args, fmt);
  1348.         i = vsnprintf(buf, INT_MAX, fmt, args);
  1349.         va_end(args);
  1350.  
  1351.         return i;
  1352. }
  1353.  
  1354.