home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 387b.lha / dice_v2.02 / lib / stdio / pfmt.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-06-03  |  4.6 KB  |  297 lines

  1.  
  2. /*
  3.  *  PFMT.C
  4.  *
  5.  *  (c)Copyright 1990, Matthew Dillon, All Rights Reserved
  6.  *
  7.  *  func format same as fwrite: func(buf, 1, n, desc)
  8.  */
  9.  
  10. #include <stdarg.h>
  11. #include <stdio.h>
  12.  
  13. #define F_SPAC        1
  14. #define F_PLUS        2
  15. #define F_MINUS     4
  16. #define F_HASH        8
  17. #define F_ZERO        16
  18.  
  19. #define F_SHORT     32
  20. #define F_LONG        64
  21. #define F_DLONG     128
  22.  
  23. int
  24. _pfmt(ctl, va, func, desc)
  25. char *ctl;
  26. va_list va;
  27. int (*func)();
  28. void *desc;
  29. {
  30.     char *base = ctl;
  31.     char c;
  32.     int error = 0;
  33.     int bytes = 0;
  34.     short flags;
  35.     short i1, i2;
  36.  
  37.     for (;;) {
  38.     while (*ctl && *ctl != '%')
  39.         ++ctl;
  40.     if (ctl != base) {
  41.         error = (*func)(base, 1, ctl - base, desc);
  42.         if (error > 0)
  43.         bytes += error;
  44.     }
  45.     if (*ctl++ == 0)
  46.         return(0);
  47.     c = *ctl;
  48.     if (c == '%') {
  49.         base = ctl++;
  50.         continue;
  51.     }
  52.  
  53.     /*
  54.      *  %[flags][val[.val]]c
  55.      */
  56.  
  57.     flags = 0;
  58.     for (;; c = *++ctl) {
  59.         if (c == '-') {
  60.         flags |= F_MINUS;
  61.         continue;
  62.         }
  63.         if (c == '+') {
  64.         flags |= F_PLUS;
  65.         continue;
  66.         }
  67.         if (c == ' ') {
  68.         flags |= F_SPAC;
  69.         continue;
  70.         }
  71.         if (c == '#') {
  72.         flags |= F_HASH;
  73.         continue;
  74.         }
  75.         if (c == '0') {
  76.         flags |= F_ZERO;
  77.         continue;
  78.         }
  79.         break;
  80.     }
  81.     if (c == '*') {
  82.         c = *++ctl;
  83.         i1 = va_arg(va, int);
  84.     } else if (c >= '0' && c <= '9') {
  85.         i1 = 0;
  86.         while (c >= '0' && c <= '9') {
  87.         i1 = i1 * 10 + (c - '0');
  88.         c = *++ctl;
  89.         }
  90.     } else {
  91.         i1 = -1;
  92.     }
  93.     i2 = -1;
  94.     if (c == '.') {
  95.         c = *++ctl;
  96.         if (c == '*') {
  97.         c = *++ctl;
  98.         i2 = va_arg(va, int);
  99.         } else {
  100.         i2 = 0;
  101.         while (c >= '0' && c <= '9') {
  102.             i2 = i2 * 10 + (c - '0');
  103.             c = *++ctl;
  104.         }
  105.         }
  106.     }
  107.     if (i1 > 4096 || i2 > 4096)    /*  bad for business! */
  108.         continue;
  109.     for (;;) {
  110.         if (c == 'h') {
  111.         c = *++ctl;
  112.         flags |= F_SHORT;   /*    only if sizeof(int) != 4 */
  113.         continue;
  114.         }
  115.         if (c == 'l') {
  116.         c = *++ctl;
  117.         flags |= F_LONG;
  118.         continue;
  119.         }
  120.         if (c == 'L') {
  121.         c = *++ctl;
  122.         flags |= F_DLONG;
  123.         continue;
  124.         }
  125.         break;
  126.     }
  127.     error = _pfmtone(c, &va, func, desc, flags, i1, i2);
  128.     if (error > 0)
  129.         bytes += error;
  130.  
  131.     if (error != -2) {
  132.         base = ++ctl;
  133.     }
  134.     }
  135.     if (error < 0)
  136.     return(error);
  137.     return(bytes);      /*  # bytes written */
  138. }
  139.  
  140. int
  141. _pfmtone(c, pva, func, desc, flags, i1, i2)
  142. char c;
  143. va_list *pva;
  144. int (*func)();
  145. void *desc;
  146. short flags;
  147. int i1, i2;
  148. {
  149.     va_list va = *pva;
  150.     int len = 0;
  151.     int error = 0;
  152.     int bytes = 0;
  153.     char buf[32];
  154.     char *ptr = buf;
  155.  
  156.     switch(c) {
  157.     case 'c':
  158.     c = va_arg(va, int);
  159.     ptr = &c;
  160.     len = 1;
  161.     break;
  162.     case 'd':
  163.     case 'u':
  164.     {
  165.         short neg = 0;
  166.         unsigned long v = va_arg(va, unsigned long);
  167.  
  168.         ptr = buf + sizeof(buf);
  169.         if (c != 'u' && (long)v < 0) {
  170.         v = -v;
  171.         neg = 1;
  172.         }
  173.         do {
  174.         *--ptr = v % 10 + '0';
  175.         v = v / 10;
  176.         } while (v);
  177.         if (neg)
  178.         *--ptr = '-';
  179.         len = buf + sizeof(buf) - ptr;
  180.     }
  181.     break;
  182.     case 'e':
  183.     case 'E':
  184.     case 'f':
  185.     case 'g':
  186.     case 'G':
  187.     case 'i':
  188.     case 'n':
  189.     break;
  190.     case 'o':
  191.     {
  192.         short neg = 0;
  193.         unsigned long v = va_arg(va, unsigned long);
  194.  
  195.         ptr = buf + sizeof(buf);
  196.         if (c != 'u' && (long)v < 0) {
  197.         v = -v;
  198.         neg = 1;
  199.         }
  200.         do {
  201.         *--ptr = (v & 7) + '0';
  202.         v = v >> 3;
  203.         } while (v);
  204.         if (neg)
  205.         *--ptr = '-';
  206.         len = buf + sizeof(buf) - ptr;
  207.     }
  208.     break;
  209.     case 'p':
  210.     break;
  211.     case 's':
  212.     ptr = va_arg(va, char *);
  213.     len = strlen(ptr);
  214.     break;
  215.     case 'x':
  216.     case 'X':
  217.     {
  218.         unsigned long v = va_arg(va, unsigned long);
  219.         static char IToHC[17] = { "0123456789ABCDEF" };
  220.  
  221.         ptr = buf + sizeof(buf);
  222.         do {
  223.         *--ptr = IToHC[v & 0x0F];
  224.         v = v >> 4;
  225.         } while (v);
  226.         len = buf + sizeof(buf) - ptr;
  227.     }
  228.     break;
  229.     default:
  230.     return(-2); /*  unknown conversion specifier    */
  231.     }
  232.  
  233.     if (i2 < 0)
  234.     i2 = len;
  235.     if (i2 < len)
  236.     len = i2;
  237.     if (i1 < len)
  238.     i1 = len;
  239.  
  240.     if (i1 > len && !(flags & F_MINUS)) {     /*  pre-pad   */
  241.     int n = i1 - len;
  242.     int r;
  243.     char tmp[64];
  244.  
  245.     r = sizeof(tmp);
  246.     if (n < r)
  247.         r = n;
  248.  
  249.     if (flags & F_ZERO) {
  250.         _slow_bset(tmp, r, '0');
  251.     } else {
  252.         _slow_bset(tmp, r, ' ');
  253.     }
  254.     while (n) {
  255.         error = (*func)(tmp, 1, r, desc);
  256.         if (error > 0)
  257.         bytes += error;
  258.         n -= r;
  259.         if (n < sizeof(tmp))
  260.         r = n;
  261.     }
  262.     }
  263.     if (len > 0) {
  264.     error = (*func)(ptr, 1, len, desc);
  265.     if (error > 0)
  266.         bytes += error;
  267.     }
  268.  
  269.     if (i1 > len && (flags & F_MINUS)) {     /*  pos-pad   */
  270.     int n = i1 - len;
  271.     int r;
  272.     char tmp[64];
  273.  
  274.     r = sizeof(tmp);
  275.     if (n < r)
  276.         r = n;
  277.  
  278.     _slow_bset(tmp, r, ' ');
  279.  
  280.     while (n) {
  281.         error = (*func)(tmp, 1, r, desc);
  282.         if (error > 0)
  283.         bytes += error;
  284.         n -= r;
  285.         if (n < sizeof(tmp))
  286.         r = n;
  287.     }
  288.     }
  289.  
  290.     *pva = va;
  291.     if (error < 0)
  292.     return(error);
  293.     return(bytes);
  294. }
  295.  
  296.  
  297.