Chinaunix首页 | 论坛 | 博客
  • 博客访问: 231141
  • 博文数量: 59
  • 博客积分: 1215
  • 博客等级: 少尉
  • 技术积分: 575
  • 用 户 组: 普通用户
  • 注册时间: 2011-11-09 02:18
文章分类

全部博文(59)

文章存档

2012年(53)

2011年(6)

分类: C/C++

2012-02-05 03:12:29

他们其实都是调用一个函数,侯先生说,源码面前了无秘密:
  1. /**
  2.  * vsnprintf - Format a string and place it in a buffer
  3.  * @buf: The buffer to place the result into
  4.  * @size: The size of the buffer, including the trailing null space
  5.  * @fmt: The format string to use
  6.  * @args: Arguments for the format string
  7.  *
  8.  * The return value is the number of characters which would
  9.  * be generated for the given input, excluding the trailing
  10.  * '\0', as per ISO C99. If you want to have the exact
  11.  * number of characters written into @buf as return value
  12.  * (not including the trailing '\0'), use vscnprintf. If the
  13.  * return is greater than or equal to @size, the resulting
  14.  * string is truncated.
  15.  *
  16.  * Call this function if you are already dealing with a va_list.
  17.  * You probably want snprintf instead.
  18.  */
  19. int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
  20. {
  21.     int len;
  22.     unsigned long long num;
  23.     int i, base;
  24.     char *str, *end, c;
  25.     const char *s;

  26.     int flags;        /* flags to number() */

  27.     int field_width;    /* width of output field */
  28.     int precision;        /* min. # of digits for integers; max
  29.                  number of chars for from string */
  30.     int qualifier;        /* 'h', 'l', or 'L' for integer fields */
  31.                 /* 'z' support added 23/7/1999 S.H. */
  32.                 /* 'z' changed to 'Z' --davidm 1/25/99 */

  33.     /* Reject out-of-range values early */
  34.     if (unlikely((int) size < 0)) {
  35.         /* There can be only one.. */
  36.         static int warn = 1;
  37.         WARN_ON(warn);
  38.         warn = 0;
  39.         return 0;
  40.     }

  41.     str = buf;
  42.     end = buf + size - 1;

  43.     if (end < buf - 1) {
  44.         end = ((void *) -1);
  45.         size = end - buf + 1;
  46.     }

  47.     for (; *fmt ; ++fmt) {
  48.         if (*fmt != '%') {
  49.             if (str <= end)
  50.                 *str = *fmt;
  51.             ++str;
  52.             continue;
  53.         }

  54.         /* process flags */
  55.         flags = 0;
  56.         repeat:
  57.             ++fmt;        /* this also skips first '%' */
  58.             switch (*fmt) {
  59.                 case '-': flags |= LEFT; goto repeat;
  60.                 case '+': flags |= PLUS; goto repeat;
  61.                 case ' ': flags |= SPACE; goto repeat;
  62.                 case '#': flags |= SPECIAL; goto repeat;
  63.                 case '0': flags |= ZEROPAD; goto repeat;
  64.             }

  65.         /* get field width */
  66.         field_width = -1;
  67.         if (isdigit(*fmt))
  68.             field_width = skip_atoi(&fmt);
  69.         else if (*fmt == '*') {
  70.             ++fmt;
  71.             /* it's the next argument */
  72.             field_width = va_arg(args, int);
  73.             if (field_width < 0) {
  74.                 field_width = -field_width;
  75.                 flags |= LEFT;
  76.             }
  77.         }

  78.         /* get the precision */
  79.         precision = -1;
  80.         if (*fmt == '.') {
  81.             ++fmt;    
  82.             if (isdigit(*fmt))
  83.                 precision = skip_atoi(&fmt);
  84.             else if (*fmt == '*') {
  85.                 ++fmt;
  86.                 /* it's the next argument */
  87.                 precision = va_arg(args, int);
  88.             }
  89.             if (precision < 0)
  90.                 precision = 0;
  91.         }

  92.         /* get the conversion qualifier */
  93.         qualifier = -1;
  94.         if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' ||
  95.          *fmt =='Z' || *fmt == 'z') {
  96.             qualifier = *fmt;
  97.             ++fmt;
  98.             if (qualifier == 'l' && *fmt == 'l') {
  99.                 qualifier = 'L';
  100.                 ++fmt;
  101.             }
  102.         }

  103.         /* default base */
  104.         base = 10;

  105.         switch (*fmt) {
  106.             case 'c':
  107.                 if (!(flags & LEFT)) {
  108.                     while (--field_width > 0) {
  109.                         if (str <= end)
  110.                             *str = ' ';
  111.                         ++str;
  112.                     }
  113.                 }
  114.                 c = (unsigned char) va_arg(args, int);
  115.                 if (str <= end)
  116.                     *str = c;
  117.                 ++str;
  118.                 while (--field_width > 0) {
  119.                     if (str <= end)
  120.                         *str = ' ';
  121.                     ++str;
  122.                 }
  123.                 continue;

  124.             case 's':
  125.                 s = va_arg(args, char *);
  126.                 if ((unsigned long)s < PAGE_SIZE)
  127.                     s = "";

  128.                 len = strnlen(s, precision);

  129.                 if (!(flags & LEFT)) {
  130.                     while (len < field_width--) {
  131.                         if (str <= end)
  132.                             *str = ' ';
  133.                         ++str;
  134.                     }
  135.                 }
  136.                 for (i = 0; i < len; ++i) {
  137.                     if (str <= end)
  138.                         *str = *s;
  139.                     ++str; ++s;
  140.                 }
  141.                 while (len < field_width--) {
  142.                     if (str <= end)
  143.                         *str = ' ';
  144.                     ++str;
  145.                 }
  146.                 continue;

  147.             case 'p':
  148.                 if (field_width == -1) {
  149.                     field_width = 2*sizeof(void *);
  150.                     flags |= ZEROPAD;
  151.                 }
  152.                 str = number(str, end,
  153.                         (unsigned long) va_arg(args, void *),
  154.                         16, field_width, precision, flags);
  155.                 continue;


  156.             case 'n':
  157.                 /* FIXME:
  158.                 * What does C99 say about the overflow case here? */
  159.                 if (qualifier == 'l') {
  160.                     long * ip = va_arg(args, long *);
  161.                     *ip = (str - buf);
  162.                 } else if (qualifier == 'Z' || qualifier == 'z') {
  163.                     size_t * ip = va_arg(args, size_t *);
  164.                     *ip = (str - buf);
  165.                 } else {
  166.                     int * ip = va_arg(args, int *);
  167.                     *ip = (str - buf);
  168.                 }
  169.                 continue;

  170.             case '%':
  171.                 if (str <= end)
  172.                     *str = '%';
  173.                 ++str;
  174.                 continue;

  175.                 /* integer number formats - set up the flags and "break" */
  176.             case 'o':
  177.                 base = 8;
  178.                 break;

  179.             case 'X':
  180.                 flags |= LARGE;
  181.             case 'x':
  182.                 base = 16;
  183.                 break;

  184.             case 'd':
  185.             case 'i':
  186.                 flags |= SIGN;
  187.             case 'u':
  188.                 break;

  189.             default:
  190.                 if (str <= end)
  191.                     *str = '%';
  192.                 ++str;
  193.                 if (*fmt) {
  194.                     if (str <= end)
  195.                         *str = *fmt;
  196.                     ++str;
  197.                 } else {
  198.                     --fmt;
  199.                 }
  200.                 continue;
  201.         }
  202.         if (qualifier == 'L')
  203.             num = va_arg(args, long long);
  204.         else if (qualifier == 'l') {
  205.             num = va_arg(args, unsigned long);
  206.             if (flags & SIGN)
  207.                 num = (signed long) num;
  208.         } else if (qualifier == 'Z' || qualifier == 'z') {
  209.             num = va_arg(args, size_t);
  210.         } else if (qualifier == 'h') {
  211.             num = (unsigned short) va_arg(args, int);
  212.             if (flags & SIGN)
  213.                 num = (signed short) num;
  214.         } else {
  215.             num = va_arg(args, unsigned int);
  216.             if (flags & SIGN)
  217.                 num = (signed int) num;
  218.         }
  219.         str = number(str, end, num, base,
  220.                 field_width, precision, flags);
  221.     }
  222.     if (str <= end)
  223.         *str = '\0';
  224.     else if (size > 0)
  225.         /* don't write out a null byte if the buf size is zero */
  226.         *end = '\0';
  227.     /* the trailing null byte doesn't count towards the total
  228.     * ++str;
  229.     */
  230.     return str-buf;
  231. }
 
 
阅读(1533) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~