home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_100 / 156_01 / printf1.c < prev    next >
Text File  |  1985-08-21  |  4KB  |  155 lines

  1. /*
  2.     history...
  3.         19 Sept 84  Can send output to a file using
  4.             putc() or STDOUT using putchar().
  5.         3 Aug 84  Calling putchar() directly rather
  6.             than through cout().
  7.         10 Aug 83  changed back to &argcnt+i-1.
  8.         8 Aug 83  Changed addr of first arg to
  9.             &argcnt + i + 1.
  10. */
  11. #include iolib.h
  12. #include printf1.h
  13. #define NULL 0
  14. #define ERR -1
  15.  
  16. int device;
  17.  
  18. /*
  19. ** printf(controlstring, arg, arg, ...)  or 
  20. ** printf(file, controlstring, arg, arg, ...) -- formatted print
  21. **        operates as described by Kernighan & Ritchie
  22. **        only d, x, c, s, and u specs are supported.
  23. */
  24. printf(argcnt) int argcnt; {
  25.   int i, width, prec, preclen, len, *nxtarg;
  26.   char *ctl, *cx, c, right, str[7], *sptr, pad;
  27.   i = argc();   /* fetch arg count from A reg first */
  28.   nxtarg = &argcnt + i - 1;
  29.   ctl = device = *nxtarg;
  30.   if (device==(device&31))    /* *small* value must be device # */
  31.     {ctl=*--nxtarg;}
  32.   else device=0;
  33.   while(c=*ctl++) {
  34.     if(c!='%') {_outc(c); continue;}
  35.     if(*ctl=='%') {_outc(*ctl++); continue;}
  36.     cx=ctl;
  37.     if(*cx=='-') {right=0; ++cx;} else right=1;
  38.     if(*cx=='0') {pad='0'; ++cx;} else pad=' ';
  39.     if((i=utoi(cx, &width)) >= 0) cx=cx+i; else continue;
  40.     if(*cx=='.') {
  41.       if((preclen=utoi(++cx, &prec)) >= 0) cx=cx+preclen;
  42.       else continue;
  43.       }
  44.     else preclen=0;
  45.     sptr=str; c=*cx++; i=*(--nxtarg);
  46.     if(c=='d') itod(i, str, 7);
  47.     else if(c=='x') itox(i, str, 7);
  48.     else if(c=='c') {str[0]=i; str[1]=NULL;}
  49.     else if(c=='s') sptr=i;
  50.     else if(c=='u') itou(i, str, 7);
  51.     else continue;
  52.     ctl=cx; /* accept conversion spec */
  53.     if(c!='s') while(*sptr==' ') ++sptr;
  54.     len=-1; while(sptr[++len]); /* get length */
  55.     if((c=='s')&(len>prec)&(preclen>0)) len=prec;
  56.     if(right) while(((width--)-len)>0) _outc(pad);
  57.     while(len) {_outc(*sptr++); --len; --width;}
  58.     while(((width--)-len)>0) _outc(pad);
  59.     }
  60.   }
  61.  
  62.  
  63. /*
  64. ** utoi -- convert unsigned decimal string to integer nbr
  65. **          returns field size, else ERR on error
  66. */
  67. utoi(decstr, nbr)  char *decstr;  int *nbr;  {
  68.   int d,t; d=0;
  69.   *nbr=0;
  70.   while((*decstr>='0')&(*decstr<='9')) {
  71.     t=*nbr;t=(10*t) + (*decstr++ - '0');
  72.     if ((t>=0)&(*nbr<0)) return ERR;
  73.     d++; *nbr=t;
  74.     }
  75.   return d;
  76.   }
  77.  
  78.  
  79. /*
  80. ** itod -- convert nbr to signed decimal string of width sz
  81. **         right adjusted, blank filled; returns str
  82. **
  83. **        if sz > 0 terminate with null byte
  84. **        if sz = 0 find end of string
  85. **        if sz < 0 use last byte for data
  86. */
  87. itod(nbr, str, sz)  int nbr;  char str[];  int sz;  {
  88.   char sgn;
  89.   if(nbr<0) {nbr = -nbr; sgn='-';}
  90.   else sgn=' ';
  91.   if(sz>0) str[--sz]=NULL;
  92.   else if(sz<0) sz = -sz;
  93.   else while(str[sz]!=NULL) ++sz;
  94.   while(sz) {
  95.     str[--sz]=(nbr%10+'0');
  96.     if((nbr=nbr/10)==0) break;
  97.     }
  98.   if(sz) str[--sz]=sgn;
  99.   while(sz>0) str[--sz]=' ';
  100.   return str;
  101.   }
  102.  
  103.  
  104. /*
  105. ** itou -- convert nbr to unsigned decimal string of width sz
  106. **         right adjusted, blank filled; returns str
  107. **
  108. **        if sz > 0 terminate with null byte
  109. **        if sz = 0 find end of string
  110. **        if sz < 0 use last byte for data
  111. */
  112. itou(nbr, str, sz)  int nbr;  char str[];  int sz;  {
  113.   int lowbit;
  114.   if(sz>0) str[--sz]=NULL;
  115.   else if(sz<0) sz = -sz;
  116.   else while(str[sz]!=NULL) ++sz;
  117.   while(sz) {
  118.     lowbit=nbr&1;
  119.     nbr=(nbr>>1)&32767;  /* divide by 2 */
  120.     str[--sz]=((nbr%5)<<1)+lowbit+'0';
  121.     if((nbr=nbr/5)==0) break;
  122.     }
  123.   while(sz) str[--sz]=' ';
  124.   return str;
  125.   }
  126.  
  127.  
  128. /*
  129. ** itox -- converts nbr to hex string of length sz
  130. **         right adjusted and blank filled, returns str
  131. **
  132. **        if sz > 0 terminate with null byte
  133. **        if sz = 0 find end of string
  134. **        if sz < 0 use last byte for data
  135. */
  136. itox(nbr, str, sz)  int nbr;  char str[];  int sz;  {
  137.   int digit, offset;
  138.   if(sz>0) str[--sz]=NULL;
  139.   else if(sz<0) sz = -sz;
  140.   else while(str[sz]!=NULL) ++sz;
  141.   while(sz) {
  142.     digit=nbr&15; nbr=(nbr>>4)&4095;
  143.     if(digit<10) offset=48; else offset=55;
  144.     str[--sz]=digit+offset;
  145.     if(nbr==0) break;
  146.     }
  147.   while(sz) str[--sz]=' ';
  148.   return str;
  149.   }
  150.  
  151. _outc(c) char c;
  152. {    if(device) putc(c,device);
  153.     else putchar(c);
  154. }
  155.