1: /* $Header: /home/hyperion/mu/christos/src/sys/tcsh-6.00/RCS/tc.printf.c,v 3.0 1991/07/04 21:49:28 christos Exp $ */
   2: /*
   3:  * tc.printf.c: A public-domain, minimal printf/sprintf routine that prints
   4:  *	       through the putchar() routine.  Feel free to use for
   5:  *	       anything...  -- 7/17/87 Paul Placeway
   6:  */
   7: /*-
   8:  * Copyright (c) 1980, 1991 The Regents of the University of California.
   9:  * All rights reserved.
  10:  *
  11:  * Redistribution and use in source and binary forms, with or without
  12:  * modification, are permitted provided that the following conditions
  13:  * are met:
  14:  * 1. Redistributions of source code must retain the above copyright
  15:  *    notice, this list of conditions and the following disclaimer.
  16:  * 2. Redistributions in binary form must reproduce the above copyright
  17:  *    notice, this list of conditions and the following disclaimer in the
  18:  *    documentation and/or other materials provided with the distribution.
  19:  * 3. All advertising materials mentioning features or use of this software
  20:  *    must display the following acknowledgement:
  21:  *	This product includes software developed by the University of
  22:  *	California, Berkeley and its contributors.
  23:  * 4. Neither the name of the University nor the names of its contributors
  24:  *    may be used to endorse or promote products derived from this software
  25:  *    without specific prior written permission.
  26:  *
  27:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  28:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  29:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  30:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  31:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  32:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  33:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  34:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  35:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  36:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  37:  * SUCH DAMAGE.
  38:  */
  39: #include "config.h"
  40: #if !defined(lint) && !defined(pdp11)
  41: static char *rcsid()
  42:     { return "$Id: tc.printf.c,v 3.0 1991/07/04 21:49:28 christos Exp $"; }
  43: #endif
  44: 
  45: #include "sh.h"
  46: 
  47: #ifdef lint
  48: #undef va_arg
  49: #define va_arg(a, b) (a ? (b) 0 : (b) 0)
  50: #endif
  51: 
  52: #define INF 32766       /* should be bigger than any field to print */
  53: 
  54: static unsigned char buf[128];
  55: 
  56: static  void    xaddchar    __P((int));
  57: static  void    doprnt      __P((void (*) __P((int)), char *, va_list));
  58: 
  59: static void
  60: doprnt(addchar, sfmt, ap)
  61:     void    (*addchar)();
  62:     char   *sfmt;
  63:     va_list ap;
  64: {
  65:     register unsigned char *f, *bp;
  66:     register long l;
  67:     register u_long u;
  68:     register int i;
  69:     register int fmt;
  70:     register unsigned char pad = ' ';
  71:     int     flush_left = 0, f_width = 0, prec = INF, hash = 0, do_long = 0;
  72:     int     sign = 0;
  73:     int     attributes = 0;
  74: 
  75: 
  76:     f = (unsigned char *) sfmt;
  77:     for (; *f; f++) {
  78:     if (*f != '%') {    /* then just out the char */
  79:         (*addchar) ((int) (*f | attributes));
  80:     }
  81:     else {
  82:         f++;        /* skip the % */
  83: 
  84:         if (*f == '-') {    /* minus: flush left */
  85:         flush_left = 1;
  86:         f++;
  87:         }
  88: 
  89:         if (*f == '0' || *f == '.') {
  90:         /* padding with 0 rather than blank */
  91:         pad = '0';
  92:         f++;
  93:         }
  94:         if (*f == '*') {    /* field width */
  95:         f_width = va_arg(ap, int);
  96:         f++;
  97:         }
  98:         else if (Isdigit(*f)) {
  99:         f_width = atoi((char *) f);
 100:         while (Isdigit(*f))
 101:             f++;    /* skip the digits */
 102:         }
 103: 
 104:         if (*f == '.') {    /* precision */
 105:         f++;
 106:         if (*f == '*') {
 107:             prec = va_arg(ap, int);
 108:             f++;
 109:         }
 110:         else if (Isdigit(*f)) {
 111:             prec = atoi((char *) f);
 112:             while (Isdigit(*f))
 113:             f++;    /* skip the digits */
 114:         }
 115:         }
 116: 
 117:         if (*f == '#') {    /* alternate form */
 118:         hash = 1;
 119:         f++;
 120:         }
 121: 
 122:         if (*f == 'l') {    /* long format */
 123:         do_long = 1;
 124:         f++;
 125:         }
 126: 
 127:         fmt = *f;
 128:         if (Isupper(fmt)) {
 129:         do_long = 1;
 130:         fmt = Tolower(fmt);
 131:         }
 132:         bp = buf;
 133:         switch (fmt) {  /* do the format */
 134:         case 'd':
 135:         if (do_long)
 136:             l = va_arg(ap, long);
 137:         else
 138:             l = (long) (va_arg(ap, int));
 139:         if (l < 0) {
 140:             sign = 1;
 141:             l = -l;
 142:         }
 143:         do {
 144:             *bp++ = l % 10 + '0';
 145:         } while ((l /= 10) > 0);
 146:         if (sign)
 147:             *bp++ = '-';
 148:         f_width = f_width - (bp - buf);
 149:         if (!flush_left)
 150:             while (f_width-- > 0)
 151:             (*addchar) ((int) (pad | attributes));
 152:         for (bp--; bp >= buf; bp--)
 153:             (*addchar) ((int) (*bp | attributes));
 154:         if (flush_left)
 155:             while (f_width-- > 0)
 156:             (*addchar) ((int) (' ' | attributes));
 157:         break;
 158: 
 159:         case 'o':
 160:         case 'x':
 161:         case 'u':
 162:         if (do_long)
 163:             u = va_arg(ap, u_long);
 164:         else
 165:             u = (u_long) (va_arg(ap, unsigned));
 166:         if (fmt == 'u') {   /* unsigned decimal */
 167:             do {
 168:             *bp++ = u % 10 + '0';
 169:             } while ((u /= 10) > 0);
 170:         }
 171:         else if (fmt == 'o') {  /* octal */
 172:             do {
 173:             *bp++ = u % 8 + '0';
 174:             } while ((u /= 8) > 0);
 175:             if (hash)
 176:             *bp++ = '0';
 177:         }
 178:         else if (fmt == 'x') {  /* hex */
 179:             do {
 180:             i = u % 16;
 181:             if (i < 10)
 182:                 *bp++ = i + '0';
 183:             else
 184:                 *bp++ = i - 10 + 'a';
 185:             } while ((u /= 16) > 0);
 186:             if (hash) {
 187:             *bp++ = 'x';
 188:             *bp++ = '0';
 189:             }
 190:         }
 191:         i = f_width - (bp - buf);
 192:         if (!flush_left)
 193:             while (i-- > 0)
 194:             (*addchar) ((int) (pad | attributes));
 195:         for (bp--; bp >= buf; bp--)
 196:             (*addchar) ((int) (*bp | attributes));
 197:         if (flush_left)
 198:             while (i-- > 0)
 199:             (*addchar) ((int) (' ' | attributes));
 200:         break;
 201: 
 202: 
 203:         case 'c':
 204:         i = va_arg(ap, int);
 205:         (*addchar) ((int) (i | attributes));
 206:         break;
 207: 
 208:         case 's':
 209:         bp = va_arg(ap, unsigned char *);
 210:         if (!bp)
 211:             bp = (unsigned char *) "(nil)";
 212:         f_width = f_width - strlen((char *) bp);
 213:         if (!flush_left)
 214:             while (f_width-- > 0)
 215:             (*addchar) ((int) (pad | attributes));
 216:         for (i = 0; *bp && i < prec; i++) {
 217:             (*addchar) ((int) (*bp | attributes));
 218:             bp++;
 219:         }
 220:         if (flush_left)
 221:             while (f_width-- > 0)
 222:             (*addchar) ((int) (' ' | attributes));
 223: 
 224:         break;
 225: 
 226:         case 'a':
 227:         attributes = va_arg(ap, int);
 228:         break;
 229: 
 230:         case '%':
 231:         (*addchar) ((int) ('%' | attributes));
 232:         break;
 233:         }
 234:         flush_left = 0, f_width = 0, prec = INF, hash = 0, do_long = 0;
 235:         sign = 0;
 236:         pad = ' ';
 237:     }
 238:     }
 239: }
 240: 
 241: 
 242: static unsigned char *xstring;
 243: static void
 244: xaddchar(c)
 245:     int     c;
 246: {
 247:     *xstring++ = c;
 248: }
 249: 
 250: 
 251: void
 252: /*VARARGS*/
 253: #if __STDC__
 254: xsprintf(char *str, char *fmt, ...)
 255: #else
 256: xsprintf(va_alist)
 257:     va_dcl
 258: #endif
 259: {
 260:     va_list va;
 261: #if __STDC__
 262:     va_start(va, fmt);
 263: #else
 264:     char *str, *fmt;
 265: 
 266:     va_start(va);
 267:     str = va_arg(va, char *);
 268:     fmt = va_arg(va, char *);
 269: #endif
 270: 
 271:     xstring = (unsigned char *) str;
 272:     doprnt(xaddchar, fmt, va);
 273:     va_end(va);
 274:     *xstring++ = '\0';
 275: }
 276: 
 277: 
 278: void
 279: /*VARARGS*/
 280: #if __STDC__
 281: xprintf(char *fmt, ...)
 282: #else
 283: xprintf(va_alist)
 284:     va_dcl
 285: #endif
 286: {
 287:     va_list va;
 288: #if __STDC__
 289:     va_start(va, fmt);
 290: #else
 291:     char   *fmt;
 292: 
 293:     va_start(va);
 294:     fmt = va_arg(va, char *);
 295: #endif
 296:     doprnt(xputchar, fmt, va);
 297:     va_end(va);
 298: }
 299: 
 300: 
 301: void
 302: xvprintf(fmt, va)
 303:     char   *fmt;
 304:     va_list va;
 305: {
 306:     doprnt(xputchar, fmt, va);
 307: }
 308: 
 309: void
 310: xvsprintf(str, fmt, va)
 311:     char   *str;
 312:     char   *fmt;
 313:     va_list va;
 314: {
 315:     xstring = (unsigned char *) str;
 316:     doprnt(xaddchar, fmt, va);
 317:     *xstring++ = '\0';
 318: }

Defined functions

doprnt defined in line 59; used 4 times
rcsid defined in line 41; never used
xaddchar defined in line 243; used 2 times
xsprintf defined in line 251; used 8 times
xvprintf defined in line 301; never used
xvsprintf defined in line 309; never used

Defined variables

buf defined in line 54; used 5 times
xstring defined in line 242; used 5 times

Defined macros

INF defined in line 52; used 2 times
va_arg defined in line 49; used 13 times
Last modified: 1991-08-20
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3381
Valid CSS Valid XHTML 1.0 Strict