home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / gnustuff / minix / libsrc~1.z / libsrc~1 / printk.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-12-28  |  4.1 KB  |  276 lines

  1. #define __SRC__
  2. #include "lib.h"
  3. void putc(int);
  4.  
  5. /*
  6.  * three compile time options:
  7.  *    STACKUP        fetch arguments using *p-- instead of *p++
  8.  *    NO_LONGD    %d and %ld/%D are equal
  9.  *    NO_FLOAT    abort on %e, %f and %g
  10.  */
  11.  
  12. #define    NO_FLOAT
  13.  
  14. #ifdef NO_FLOAT
  15. #define    MAXDIG        11    /* 32 bits in radix 8 */
  16. #else
  17. #define    MAXDIG        128    /* this must be enough */
  18. #endif
  19.  
  20. static char *
  21. _itoa(p, num, radix)
  22. register char *p;
  23. register unsigned num;
  24. register radix;
  25. {
  26.     register    i;
  27.     register char    *q;
  28.  
  29.     q = p + MAXDIG;
  30.     do {
  31.         i = (int)(num % radix);
  32.         i += '0';
  33.         if (i > '9')
  34.             i += 'A' - '0' - 10;
  35.         *--q = i;
  36.     } while (num = num / radix);
  37.     i = (int)(p - q) + MAXDIG ;
  38.     do
  39.         *p++ = *q++;
  40.     while (--i);
  41.     return(p);
  42. }
  43.  
  44. #ifndef NO_LONGD
  45. static char *
  46. ltoa(p, num, radix)
  47. register char *p;
  48. register unsigned long num;
  49. register radix;
  50. {
  51.     register    i;
  52.     register char    *q;
  53.  
  54.     q = p + MAXDIG;
  55.     do {
  56.         i = (int)(num % radix);
  57.         i += '0';
  58.         if (i > '9')
  59.             i += 'A' - '0' - 10;
  60.         *--q = i;
  61.     } while (num = num / radix);
  62.     i = (int)(p - q) + MAXDIG;
  63.     do
  64.         *p++ = *q++;
  65.     while (--i);
  66.     return(p);
  67. }
  68. #endif
  69.  
  70. #ifndef __GNUC__
  71. #ifndef NO_FLOAT
  72. extern char    *_ecvt();
  73. extern char    *_fcvt();
  74. extern char    *_gcvt();
  75. #endif
  76. #endif
  77.  
  78. #ifdef STACKUP
  79. #define    GETARG(typ)    *((typ *)args)--
  80. #else
  81. #define    GETARG(typ)    *((typ *)args)++
  82. #endif STACKUP
  83.  
  84. void printk(fmt, arg1)
  85. _CONST register char *fmt;
  86. int arg1;
  87. {
  88.     char        buf[MAXDIG+1];    /* +1 for sign */
  89.     register int    *args = &arg1;
  90.     register char    *p;
  91.     register char    *s;
  92.     register    c;
  93.     register    i;
  94.     register short    width;
  95.     register short    ndigit;
  96.     register    ndfnd;
  97.     register    ljust;
  98.     register    zfill;
  99. #ifndef NO_LONGD
  100.     register    lflag;
  101.     register long    l;
  102. #endif
  103.  
  104.     for (;;) {
  105.         c = *fmt++;
  106.         if (c == 0)
  107.             return;
  108.         if (c != '%') {
  109.             putc(c);
  110.             continue;
  111.         }
  112.         p = buf;
  113.         s = buf;
  114.         ljust = 0;
  115.         if (*fmt == '-') {
  116.             fmt++;
  117.             ljust++;
  118.         }
  119.         zfill = ' ';
  120.         if (*fmt == '0') {
  121.             fmt++;
  122.             zfill = '0';
  123.         }
  124.         for (width = 0;;) {
  125.             c = *fmt++;
  126.             if (c >= '0' && c <= '9')
  127.                 c -= '0';
  128.             else if (c == '*')
  129.                 c = GETARG(int);
  130.             else
  131.                 break;
  132.             width *= 10;
  133.             width += c;
  134.         }
  135.         ndfnd = 0;
  136.         ndigit = 0;
  137.         if (c == '.') {
  138.             for (;;) {
  139.                 c = *fmt++;
  140.                 if (c >= '0' && c <= '9')
  141.                     c -= '0';
  142.                 else if (c == '*')
  143.                     c = GETARG(int);
  144.                 else
  145.                     break;
  146.                 ndigit *= 10;
  147.                 ndigit += c;
  148.                 ndfnd++;
  149.             }
  150.         }
  151. #ifndef NO_LONGD
  152.         lflag = 0;
  153. #endif
  154.         if (c == 'l' || c == 'L') {
  155. #ifndef NO_LONGD
  156.             lflag++;
  157. #endif
  158.             if (*fmt)
  159.                 c = *fmt++;
  160.         }
  161.         switch (c) {
  162.         case 'X':
  163. #ifndef NO_LONGD
  164.             lflag++;
  165. #endif
  166.         case 'x':
  167.             c = 16;
  168.             goto oxu;
  169.         case 'U':
  170. #ifndef NO_LONGD
  171.             lflag++;
  172. #endif
  173.         case 'u':
  174.             c = 10;
  175.             goto oxu;
  176.         case 'O':
  177. #ifndef NO_LONGD
  178.             lflag++;
  179. #endif
  180.         case 'o':
  181.             c = 8;
  182.         oxu:
  183. #ifndef NO_LONGD
  184.             if (lflag) {
  185.                 p = ltoa(p, GETARG(long), c);
  186.                 break;
  187.             }
  188. #endif
  189.             p = _itoa(p, GETARG(int), c);
  190.             break;
  191.         case 'D':
  192. #ifndef NO_LONGD
  193.             lflag++;
  194. #endif
  195.         case 'd':
  196. #ifndef NO_LONGD
  197.             if (lflag) {
  198.                 if ((l = GETARG(long)) < 0) {
  199.                     *p++ = '-';
  200.                     l = -l;
  201.                 }
  202.                 p = ltoa(p, l, 10);
  203.                 break;
  204.             }
  205. #endif
  206.             if ((i = GETARG(int)) < 0) {
  207.                 *p++ = '-';
  208.                 i = -i;
  209.             }
  210.             p = _itoa(p, i, 10);
  211.             break;
  212. #ifdef NO_FLOAT
  213.         case 'e':
  214.         case 'f':
  215.         case 'g':
  216.             zfill = ' ';
  217.             *p++ = '?';
  218.             break;
  219. #else
  220.         case 'e':
  221.             if (ndfnd == 0)
  222.                 ndigit = 6;
  223.             ndigit++;
  224.             p = _ecvt(p, GETARG(double), ndigit);
  225.             break;
  226.         case 'f':
  227.             if (ndfnd == 0)
  228.                 ndigit = 6;
  229.             p = _fcvt(p, GETARG(double), ndigit);
  230.             break;
  231.         case 'g':
  232.             if (ndfnd == 0)
  233.                 ndigit = 6;
  234.             p = _gcvt(p, GETARG(double), ndigit);
  235.             break;
  236. #endif
  237.         case 'c':
  238.             zfill = ' ';
  239.             *p++ = GETARG(int);
  240.             break;
  241.         case 's':
  242.             zfill = ' ';
  243.             if ((s = GETARG(char *)) == 0)
  244.                 s = "(null)";
  245.             if (ndigit == 0)
  246.                 ndigit = 32767;
  247.             for (p = s; *p && --ndigit >= 0; p++)
  248.                 ;
  249.             break;
  250.         default:
  251.             *p++ = c;
  252.             break;
  253.         }
  254.         i = p - s;
  255.         if ((width -= i) < 0)
  256.             width = 0;
  257.         if (ljust == 0)
  258.             width = -width;
  259.         if (width < 0) {
  260.             if (*s == '-' && zfill == '0') {
  261.                 putc(*s++);
  262.                 i--;
  263.             }
  264.             do
  265.                 putc(zfill);
  266.             while (++width != 0);
  267.         }
  268.         while (--i >= 0)
  269.             putc(*s++);
  270.         while (width) {
  271.             putc(zfill);
  272.             width--;
  273.         }
  274.     }
  275. }
  276.