home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2002 March / PCWMAR02.iso / software / windowsxp / winbolo / winbolo109a-setup.exe / vsprintf.c < prev   
C/C++ Source or Header  |  1993-10-01  |  5KB  |  218 lines

  1. /* Parts of this code (C) Symantec */
  2.  
  3. #include "vsprintf.h"
  4.  
  5. static strlen(char *s)
  6.     {
  7.     int i=0;
  8.     while (*s++) i++;
  9.     return(i);
  10.     }
  11.  
  12. static struct format
  13.     {
  14.     unsigned         leftJustify : 1;
  15.     unsigned         forceSign : 1;
  16.     unsigned         altForm : 1;
  17.     unsigned         zeroPad : 1;
  18.     unsigned         havePrecision : 1;
  19.     unsigned         hSize : 1;
  20.     unsigned         lSize : 1;
  21.     unsigned         LSize : 1;
  22.     char            sign;
  23.     char            exponent;
  24.     int                fieldWidth;
  25.     int                precision;
  26.     } default_format;
  27.  
  28. struct decrec
  29.     {
  30.     char            sgn;
  31.     short            exp;
  32. //    char            sig[SIGDIGLEN];
  33.     short            pad;
  34.     // following fields aren't used by SANE
  35.     short            min;
  36.     short            dot;
  37.     short            max;
  38.     };
  39.  
  40. #define BUFLEN            512
  41.  
  42. int vsprintf(char *sbuffer, char *fmt, va_list arg)
  43.     {
  44.     register int c, i, j, nwritten = 0;
  45.     register unsigned long n;
  46.     register char *s;
  47.     char buf[BUFLEN], *digits, *t;
  48.     struct format F;
  49.     struct decrec D;
  50.  
  51.     for (c = *fmt; c; c = *++fmt)
  52.         {
  53.         if (c != '%') goto copy1;
  54.         F = default_format;
  55.  
  56.             //  decode flags
  57.  
  58.         for (;;)
  59.             {
  60.             c = *++fmt;
  61.             if      (c == '-')    F.leftJustify = TRUE;
  62.             else if (c == '+')    F.forceSign = TRUE;
  63.             else if (c == ' ')    F.sign = ' ';
  64.             else if (c == '#')    F.altForm = TRUE;
  65.             else if (c == '0')    F.zeroPad = TRUE;
  66.             else break;
  67.             }
  68.  
  69.             //  decode field width
  70.  
  71.         if (c == '*')
  72.             {
  73.             if ((F.fieldWidth = va_arg(arg, int)) < 0)
  74.                 {
  75.                 F.leftJustify = TRUE;
  76.                 F.fieldWidth = -F.fieldWidth;
  77.                 }
  78.             c = *++fmt;
  79.             }
  80.         else
  81.             {
  82.             for (; c >= '0' && c <= '9'; c = *++fmt)
  83.                 F.fieldWidth = (10 * F.fieldWidth) + (c - '0');
  84.             }
  85.  
  86.             //  decode precision
  87.  
  88.         if (c == '.')
  89.             {
  90.             if ((c = *++fmt) == '*')
  91.                 { F.precision = va_arg(arg, int); c = *++fmt; }
  92.             else for (; c >= '0' && c <= '9'; c = *++fmt)
  93.                     F.precision = (10 * F.precision) + (c - '0');
  94.             if (F.precision >= 0) F.havePrecision = TRUE;
  95.             }
  96.  
  97.             //  perform appropriate conversion
  98.  
  99.         s = &buf[BUFLEN];
  100.         if (F.leftJustify) F.zeroPad = FALSE;
  101.  
  102. conv:    switch (c)
  103.             {
  104.             case 'h' :    F.hSize = TRUE; c = *++fmt; goto conv;
  105.             case 'l' :    F.lSize = TRUE; c = *++fmt; goto conv;
  106.             case 'L' :    F.LSize = TRUE; c = *++fmt; goto conv;
  107.             case 'd' :
  108.             case 'i' :    if (F.lSize) n = va_arg(arg, long);
  109.                         else n = va_arg(arg, int);
  110.                         if (F.hSize) n = (short) n;
  111.                         if ((long) n < 0) { n = -n; F.sign = '-'; }
  112.                         else if (F.forceSign) F.sign = '+';
  113.                         goto decimal;
  114.             case 'u' :    if (F.lSize) n = va_arg(arg, unsigned long);
  115.                         else n = va_arg(arg, unsigned int);
  116.                         if (F.hSize) n = (unsigned short) n;
  117.                         F.sign = 0;
  118.                         goto decimal;
  119.             decimal:    if (!F.havePrecision)
  120.                             {
  121.                             if (F.zeroPad)
  122.                                 {
  123.                                 F.precision = F.fieldWidth;
  124.                                 if (F.sign) --F.precision;
  125.                                 }
  126.                             if (F.precision < 1) F.precision = 1;
  127.                             }
  128.                         for (i = 0; n; n /= 10, i++) *--s = n % 10 + '0';
  129.                         for (; i < F.precision; i++) *--s = '0';
  130.                         if (F.sign) { *--s = F.sign; i++; }
  131.                         break;
  132.  
  133.             case 'o' :    if (F.lSize) n = va_arg(arg, unsigned long);
  134.                         else n = va_arg(arg, unsigned int);
  135.                         if (F.hSize) n = (unsigned short) n;
  136.                         if (!F.havePrecision)
  137.                             {
  138.                             if (F.zeroPad) F.precision = F.fieldWidth;
  139.                             if (F.precision < 1) F.precision = 1;
  140.                             }
  141.                         for (i = 0; n; n /= 8, i++) *--s = n % 8 + '0';
  142.                         if (F.altForm && i && *s != '0') { *--s = '0'; i++; }
  143.                         for (; i < F.precision; i++) *--s = '0';
  144.                         break;
  145.  
  146.             case 'p' :    F.havePrecision = F.lSize = TRUE;
  147.                         F.precision = 8;
  148.             case 'X' :    digits = "0123456789ABCDEF";
  149.                         goto hexadecimal;
  150.             case 'x' :    digits = "0123456789abcdef";
  151.             hexadecimal:if (F.lSize) n = va_arg(arg, unsigned long);
  152.                         else n = va_arg(arg, unsigned int);
  153.                         if (F.hSize) n = (unsigned short) n;
  154.                         if (!F.havePrecision)
  155.                             {
  156.                             if (F.zeroPad)
  157.                                 {
  158.                                 F.precision = F.fieldWidth;
  159.                                 if (F.altForm) F.precision -= 2;
  160.                                 }
  161.                             if (F.precision < 1) F.precision = 1;
  162.                             }
  163.                         for (i = 0; n; n /= 16, i++) *--s = digits[n % 16];
  164.                         for (; i < F.precision; i++) *--s = '0';
  165.                         if (F.altForm) { *--s = c; *--s = '0'; i += 2; }
  166.                         break;
  167.  
  168.             case 'c' :    *--s = va_arg(arg, int); i = 1; break;
  169.  
  170.             case 's' :    s = va_arg(arg, char *);
  171.                         if (F.altForm)
  172.                             {
  173.                             i = (unsigned char) *s++;
  174.                             if (F.havePrecision && i > F.precision) i = F.precision;
  175.                             }
  176.                         else
  177.                             {
  178.                             i = strlen(s);
  179.                             if (F.havePrecision && i > F.precision) i = F.precision;
  180.                             }
  181.                         break;
  182.  
  183.             case 'n' :    s = va_arg(arg, void *);
  184.                         if      (F.hSize) * (short *) s = nwritten;
  185.                         else if (F.lSize) * (long  *) s = nwritten;
  186.                         else              * (int   *) s = nwritten;
  187.                         continue;
  188.  
  189.                 //  oops - unknown conversion, abort
  190.  
  191.             case 'M': case 'N': case 'O': case 'P': case 'Q':
  192.             case 'R': case 'S': case 'T': case 'U': case 'V':
  193.             // (extra cases force this to be an indexed switch)
  194.             default: goto done;
  195.  
  196.             case '%' :
  197.             copy1    :    *sbuffer++ = c; ++nwritten; continue;
  198.             }
  199.  
  200.             //  pad on the left
  201.  
  202.         if (i < F.fieldWidth && !F.leftJustify)
  203.             do { *sbuffer++ = ' '; ++nwritten; } while (i < --F.fieldWidth);
  204.  
  205.             //  write the converted result
  206.  
  207.         for (j=0; j<i; j++) *sbuffer++ = *s++;
  208.         nwritten += i;
  209.  
  210.             //  pad on the right
  211.  
  212.         for (; i < F.fieldWidth; i++)
  213.             { *sbuffer++ = ' '; ++nwritten; }
  214.         }
  215.  
  216. done: return(nwritten);
  217.     }
  218.