Subversion Repositories Kolibri OS

Rev

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