home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / files / gnu / libsrc87 / printf.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-07-30  |  4.2 KB  |  215 lines

  1. /* from Dale Schumacher's dLibs library */
  2.  
  3. #ifndef __NO_FLOATS__
  4. #define FLOATS 1
  5. #endif
  6.  
  7. #include <stddef.h>
  8. #include <stdio.h>
  9. #include <ctype.h>
  10. #include <string.h>
  11. #include <memory.h>
  12.  
  13. #define alloca __builtin_alloca
  14.  
  15. #ifndef TRUE
  16. #define TRUE  1
  17. #define FALSE 0
  18. #endif
  19.  
  20. #define TEN_MUL(X)    ((((X) << 2) + (X)) << 1)
  21.  
  22. int _printf(op, put, fmt, args)
  23.     char *op;
  24.     unsigned int (*put)();
  25.     register unsigned char *fmt;
  26.     register unsigned int *args;
  27.     {
  28.     register int i, cnt = 0, ljustf, lval;
  29.     int preci, dpoint, width;
  30.     int prefixf;    /* `#' flag */
  31.     char pad, sign, radix;
  32.     register char *ptmp;
  33.         char *_ltoa(), *_ultoa();
  34. #if FLOATS
  35.     double fx;
  36. #endif
  37.     char prefix[3];
  38.     char *tmp = (char *)alloca((size_t)128);
  39.  
  40.     prefix[0] = '\0';
  41.     while(*fmt)
  42.         {
  43.         if(*fmt == '%')
  44.             {
  45.             ljustf = FALSE;    /* left justify flag */
  46.             sign = '\0';    /* sign char & status */
  47.             pad = ' ';    /* justification padding char */
  48.             width = -1;    /* min field width */
  49.             dpoint = FALSE;    /* found decimal point */
  50.             preci = -1;    /* max data width */
  51.             radix = 10;    /* number base */
  52.             ptmp = tmp;    /* pointer to area to print */
  53.             lval = FALSE;    /* long value flaged */
  54.             prefixf  = FALSE; /* add prefix flag */
  55. fmtnxt:
  56.             i = 0;
  57.             while (isdigit(*++fmt))
  58.                 {
  59.                 i = TEN_MUL(i) + (*fmt - '0');
  60.                 if (dpoint)
  61.                     preci = i;
  62.                 else if (!i && (pad == ' '))
  63.                     {
  64.                     pad = '0';
  65.                     goto fmtnxt;
  66.                     }
  67.                 else
  68.                     width = i;
  69.                 }
  70.  
  71.             switch(*fmt)
  72.                 {
  73.                 case '\0':    /* early EOS */
  74.                     --fmt;
  75.                     goto charout;
  76.  
  77.                 case '-':    /* left justification */
  78.                     ljustf = TRUE;
  79.                     goto fmtnxt;
  80.  
  81.                 case ' ':
  82.                 case '+':    /* leading sign flag */
  83.                     sign = *fmt;
  84.                     goto fmtnxt;
  85.  
  86.                 case '*':    /* parameter width value */
  87.                     i = *args++;
  88.                     if (dpoint)
  89.                         preci = i;
  90.                     else
  91.                         width = i;
  92.                     goto fmtnxt;
  93.  
  94.                 case '.':    /* secondary width field */
  95.                     dpoint = TRUE;
  96.                     goto fmtnxt;
  97.  
  98.                 case 'l':    /* long data */
  99.                     lval = TRUE;
  100.                     goto fmtnxt;
  101.                 case '#':
  102.                     prefixf = TRUE;
  103.                     goto fmtnxt;
  104.                     case 'h':  /* here for completeness, does
  105.                           not need to do anything 
  106.                           as short ints are promoted
  107.                           to ints at call time */
  108.                     goto fmtnxt;    
  109.  
  110.                 case 'd':    /* Signed decimal */
  111.                 case 'i':
  112.                                       _ltoa((long)((lval)
  113.                         ?(*((long *) args))
  114.                         :(*((int  *) args))),
  115.                           ptmp, 10);
  116.                     if(lval)
  117.                         args = ((unsigned int *)
  118.                             (((long *) args) + 1));
  119.                     else
  120.                         args = ((unsigned int *)
  121.                             (((int *) args) + 1));
  122.                     goto printit;
  123.  
  124.                 case 'b':    /* Unsigned binary */
  125.                     radix = 2;
  126.                     goto usproc;
  127.  
  128.                 case 'o':    /* Unsigned octal */
  129.                     if(prefixf) strcpy(prefix, "0");
  130.                     radix = 8;
  131.                     goto usproc;
  132.  
  133.                 case 'p':    /* Pointer */
  134.                     lval = TRUE;
  135.                     pad = '0';
  136.                     width = 6;
  137.                     preci = 8;
  138.                     radix = 16;
  139.                     goto usproc;
  140.  
  141.                 case 'x':    /* Unsigned hexadecimal */
  142.                 case 'X':
  143.                     if(prefixf) strcpy(prefix, "0X");
  144.                     radix = 16;
  145.                     /* fall thru */
  146.  
  147.                 case 'u':    /* Unsigned decimal */
  148. usproc:
  149.                         if(prefixf && prefix[0] != '\0')
  150.                     {
  151.                         strcpy(tmp, prefix);
  152.                         prefix[0] = '\0';
  153.                         while(*ptmp != '\0') ptmp++;
  154.                     }
  155.                     
  156.                                         _ultoa((unsigned long)((lval)
  157.                         ?(*((unsigned long *) args))
  158.                         : *args++ ),
  159.                           ptmp, radix);
  160.                     ptmp = tmp;
  161.                     if(lval)
  162.                         args = ((unsigned int *)
  163.                         (((unsigned long *) args) + 1));
  164.                     if (*fmt == 'x')
  165.                         strlwr(ptmp);
  166.                     goto printit;
  167.  
  168. #if FLOATS
  169.                 case 'e':    /* float */
  170.                 case 'f':
  171.                 case 'g':
  172.                 case 'E':
  173.                 case 'G':
  174.                     fx = *((double *) args);
  175.                     args=(unsigned int *)
  176.                          (((double *) args)+1);
  177.  
  178.                     fp_print(fx, *fmt, preci, ptmp);
  179.                     preci = -1;
  180.                     goto printit;
  181. #endif
  182.  
  183.                 case 'c':    /* Character */
  184.                     ptmp[0] = *args++;
  185.                     ptmp[1] = '\0';
  186.                     goto nopad;
  187.  
  188.                 case 's':    /* String */
  189.                     ptmp = *((char **) args);
  190.                     args = ((unsigned int *)
  191.                         (((char **) args) + 1));
  192. nopad:
  193.                     sign = '\0';
  194.                     pad  = ' ';
  195. printit:
  196.                     cnt += _prtfld(op, put, ptmp, ljustf,
  197.                                sign, pad, width, preci);
  198.                     break;
  199.  
  200.                 default:    /* unknown character */
  201.                     goto charout;
  202.                 }
  203.             }
  204.         else
  205.             {
  206. charout:
  207.             (*put)(*fmt, op);        /* normal char out */
  208.             ++cnt;
  209.             }
  210.         ++fmt;
  211.         }
  212.     return(cnt);
  213.     }
  214.  
  215.