printf.c revision 7977
17977Shsul@eecs.umich.edu/*****************************************************************************
27977Shsul@eecs.umich.edu
37977Shsul@eecs.umich.edu       Copyright � 1993, 1994 Digital Equipment Corporation,
47977Shsul@eecs.umich.edu                       Maynard, Massachusetts.
57977Shsul@eecs.umich.edu
67977Shsul@eecs.umich.edu                        All Rights Reserved
77977Shsul@eecs.umich.edu
87977Shsul@eecs.umich.eduPermission to use, copy, modify, and distribute this software and its
97977Shsul@eecs.umich.edudocumentation for any purpose and without fee is hereby granted, provided
107977Shsul@eecs.umich.eduthat the copyright notice and this permission notice appear in all copies
117977Shsul@eecs.umich.eduof software and supporting documentation, and that the name of Digital not
127977Shsul@eecs.umich.edube used in advertising or publicity pertaining to distribution of the software
137977Shsul@eecs.umich.eduwithout specific, written prior permission. Digital grants this permission
147977Shsul@eecs.umich.eduprovided that you prominently mark, as not part of the original, any
157977Shsul@eecs.umich.edumodifications made to this software or documentation.
167977Shsul@eecs.umich.edu
177977Shsul@eecs.umich.eduDigital Equipment Corporation disclaims all warranties and/or guarantees
187977Shsul@eecs.umich.eduwith regard to this software, including all implied warranties of fitness for
197977Shsul@eecs.umich.edua particular purpose and merchantability, and makes no representations
207977Shsul@eecs.umich.eduregarding the use of, or the results of the use of, the software and
217977Shsul@eecs.umich.edudocumentation in terms of correctness, accuracy, reliability, currentness or
227977Shsul@eecs.umich.eduotherwise; and you rely on the software, documentation and results solely at
237977Shsul@eecs.umich.eduyour own risk.
247977Shsul@eecs.umich.edu
257977Shsul@eecs.umich.edu******************************************************************************/
267977Shsul@eecs.umich.edu
277977Shsul@eecs.umich.edu#ifndef LINT
287977Shsul@eecs.umich.edustatic char *rcsid = "$Id: printf.c,v 1.1.1.1 1997/10/30 23:27:12 verghese Exp $";
297977Shsul@eecs.umich.edu#endif
307977Shsul@eecs.umich.edu
317977Shsul@eecs.umich.edu/*
327977Shsul@eecs.umich.edu * $Log: printf.c,v $
337977Shsul@eecs.umich.edu * Revision 1.1.1.1  1997/10/30 23:27:12  verghese
347977Shsul@eecs.umich.edu * current 10/29/97
357977Shsul@eecs.umich.edu *
367977Shsul@eecs.umich.edu * Revision 1.1  1995/06/26  21:09:35  berc
377977Shsul@eecs.umich.edu * Initial revision
387977Shsul@eecs.umich.edu *
397977Shsul@eecs.umich.edu * Revision 1.8  1994/10/06  20:29:08  fdh
407977Shsul@eecs.umich.edu * Corrected unsigned long declaration.
417977Shsul@eecs.umich.edu *
427977Shsul@eecs.umich.edu * Revision 1.7  1994/08/05  20:16:23  fdh
437977Shsul@eecs.umich.edu * Updated Copyright header and RCS $Id: identifier.
447977Shsul@eecs.umich.edu *
457977Shsul@eecs.umich.edu * Revision 1.6  1994/06/21  15:41:54  rusling
467977Shsul@eecs.umich.edu * fixedup WNT compiler warnings
477977Shsul@eecs.umich.edu *
487977Shsul@eecs.umich.edu * Revision 1.5  1994/06/17  19:35:37  fdh
497977Shsul@eecs.umich.edu * Clean-up...
507977Shsul@eecs.umich.edu *
517977Shsul@eecs.umich.edu * Revision 1.4  1994/01/19  10:40:08  rusling
527977Shsul@eecs.umich.edu * Ported to Alpha Windows NT.
537977Shsul@eecs.umich.edu *
547977Shsul@eecs.umich.edu * Revision 1.3  1993/11/02  21:57:45  fdh
557977Shsul@eecs.umich.edu * Fixed sign extension problem introduced in version 1.2
567977Shsul@eecs.umich.edu *
577977Shsul@eecs.umich.edu * Revision 1.2  1993/10/13  15:29:02  rusling
587977Shsul@eecs.umich.edu * Added floating point support in printf.  This meant adding variable arguments to
597977Shsul@eecs.umich.edu * it and FormatItem() and including stdarg.h.
607977Shsul@eecs.umich.edu *
617977Shsul@eecs.umich.edu * Revision 1.1  1993/06/08  19:56:24  fdh
627977Shsul@eecs.umich.edu * Initial revision
637977Shsul@eecs.umich.edu *
647977Shsul@eecs.umich.edu */
657977Shsul@eecs.umich.edu
667977Shsul@eecs.umich.edu
677977Shsul@eecs.umich.edu
687977Shsul@eecs.umich.edu/* printf.c
697977Shsul@eecs.umich.edu   L. S.
707977Shsul@eecs.umich.edu   Sun Feb 10 20:18:22 1985
717977Shsul@eecs.umich.edu */
727977Shsul@eecs.umich.edu
737977Shsul@eecs.umich.edu#include "system.h"
747977Shsul@eecs.umich.edu#include "lib.h"
757977Shsul@eecs.umich.edu#include <stdarg.h>
767977Shsul@eecs.umich.edu
777977Shsul@eecs.umich.edu
787977Shsul@eecs.umich.edu
797977Shsul@eecs.umich.edu
807977Shsul@eecs.umich.edu
817977Shsul@eecs.umich.edu/* The string s is terminated by a '\0' */
827977Shsul@eecs.umich.eduvoid PutString(char *s)
837977Shsul@eecs.umich.edu{
847977Shsul@eecs.umich.edu  while (*s) PutChar(*s++);
857977Shsul@eecs.umich.edu}
867977Shsul@eecs.umich.edu
877977Shsul@eecs.umich.edu/* print c count times */
887977Shsul@eecs.umich.eduvoid PutRepChar(char c, int count)
897977Shsul@eecs.umich.edu{
907977Shsul@eecs.umich.edu  while (count--) PutChar(c);
917977Shsul@eecs.umich.edu}
927977Shsul@eecs.umich.edu
937977Shsul@eecs.umich.edu/* put string reverse */
947977Shsul@eecs.umich.eduvoid PutStringReverse(char *s, int index)
957977Shsul@eecs.umich.edu{
967977Shsul@eecs.umich.edu  while ((index--) > 0) PutChar(s[index]);
977977Shsul@eecs.umich.edu}
987977Shsul@eecs.umich.edu
997977Shsul@eecs.umich.edu/* prints value in radix, in a field width width, with fill
1007977Shsul@eecs.umich.edu   character fill
1017977Shsul@eecs.umich.edu   if radix is negative, print as signed quantity
1027977Shsul@eecs.umich.edu   if width is negative, left justify
1037977Shsul@eecs.umich.edu   if width is 0, use whatever is needed
1047977Shsul@eecs.umich.edu   if fill is 0, use ' '
1057977Shsul@eecs.umich.edu */
1067977Shsul@eecs.umich.eduvoid PutNumber(sl value, int radix, int width, char fill)
1077977Shsul@eecs.umich.edu{
1087977Shsul@eecs.umich.edu  char buffer[40];
1097977Shsul@eecs.umich.edu  ui bufferindex = 0;
1107977Shsul@eecs.umich.edu  ul uvalue;
1117977Shsul@eecs.umich.edu  uw digit;
1127977Shsul@eecs.umich.edu  uw left = FALSE;
1137977Shsul@eecs.umich.edu  uw negative = FALSE;
1147977Shsul@eecs.umich.edu
1157977Shsul@eecs.umich.edu  if (fill == 0) fill = ' ';
1167977Shsul@eecs.umich.edu
1177977Shsul@eecs.umich.edu  if (width < 0) {
1187977Shsul@eecs.umich.edu    width = -width;
1197977Shsul@eecs.umich.edu    left = TRUE;
1207977Shsul@eecs.umich.edu    }
1217977Shsul@eecs.umich.edu  if (width < 0 || width > 80) width = 0;
1227977Shsul@eecs.umich.edu
1237977Shsul@eecs.umich.edu  if (radix < 0) {
1247977Shsul@eecs.umich.edu    radix = -radix;
1257977Shsul@eecs.umich.edu    if (value < 0) {
1267977Shsul@eecs.umich.edu      negative = TRUE;
1277977Shsul@eecs.umich.edu      value = -value;
1287977Shsul@eecs.umich.edu      }
1297977Shsul@eecs.umich.edu    }
1307977Shsul@eecs.umich.edu  switch (radix) {
1317977Shsul@eecs.umich.edu    case 8:
1327977Shsul@eecs.umich.edu    case 10:
1337977Shsul@eecs.umich.edu    case 16: break;
1347977Shsul@eecs.umich.edu    default: {
1357977Shsul@eecs.umich.edu      PutString("****");
1367977Shsul@eecs.umich.edu      return;
1377977Shsul@eecs.umich.edu      }
1387977Shsul@eecs.umich.edu    }
1397977Shsul@eecs.umich.edu  uvalue = value;
1407977Shsul@eecs.umich.edu  do {
1417977Shsul@eecs.umich.edu    if (radix != 16)
1427977Shsul@eecs.umich.edu    {
1437977Shsul@eecs.umich.edu      digit = (uw)(uvalue % radix);
1447977Shsul@eecs.umich.edu      uvalue /= radix;
1457977Shsul@eecs.umich.edu    }
1467977Shsul@eecs.umich.edu    else
1477977Shsul@eecs.umich.edu    {
1487977Shsul@eecs.umich.edu      digit = (uw)(uvalue & 0xf);
1497977Shsul@eecs.umich.edu      uvalue = uvalue >> 4;
1507977Shsul@eecs.umich.edu    }
1517977Shsul@eecs.umich.edu    buffer[bufferindex] = digit + ((digit <= 9) ? '0' : ('A' - 10));
1527977Shsul@eecs.umich.edu    bufferindex += 1;
1537977Shsul@eecs.umich.edu    } while (uvalue != 0);
1547977Shsul@eecs.umich.edu  /* fill # ' ' and negative cannot happen at once */
1557977Shsul@eecs.umich.edu  if (negative) {
1567977Shsul@eecs.umich.edu    buffer[bufferindex] = '-';
1577977Shsul@eecs.umich.edu    bufferindex += 1;
1587977Shsul@eecs.umich.edu    }
1597977Shsul@eecs.umich.edu  if ((ui)width <= bufferindex) PutStringReverse(buffer, bufferindex);
1607977Shsul@eecs.umich.edu  else {
1617977Shsul@eecs.umich.edu    width -= bufferindex;
1627977Shsul@eecs.umich.edu    if (!left) PutRepChar(fill, width);
1637977Shsul@eecs.umich.edu    PutStringReverse(buffer, bufferindex);
1647977Shsul@eecs.umich.edu    if (left) PutRepChar(fill, width);
1657977Shsul@eecs.umich.edu    }
1667977Shsul@eecs.umich.edu}
1677977Shsul@eecs.umich.edu
1687977Shsul@eecs.umich.eduul power(long base, long n)
1697977Shsul@eecs.umich.edu{
1707977Shsul@eecs.umich.edu  ul p;
1717977Shsul@eecs.umich.edu
1727977Shsul@eecs.umich.edu  for (p = 1; n > 0; --n)
1737977Shsul@eecs.umich.edu    p = p * base;
1747977Shsul@eecs.umich.edu  return p;
1757977Shsul@eecs.umich.edu}
1767977Shsul@eecs.umich.edu
1777977Shsul@eecs.umich.eduvoid putFloat(double a, int fieldwidth, char fill)
1787977Shsul@eecs.umich.edu{
1797977Shsul@eecs.umich.edu  int i;
1807977Shsul@eecs.umich.edu  ul b;
1817977Shsul@eecs.umich.edu
1827977Shsul@eecs.umich.edu/*
1837977Shsul@eecs.umich.edu *  Put out everything before the decimal place.
1847977Shsul@eecs.umich.edu */
1857977Shsul@eecs.umich.edu  PutNumber(((ul) a), 10, fieldwidth, fill);
1867977Shsul@eecs.umich.edu/*
1877977Shsul@eecs.umich.edu *  Output the decimal place.
1887977Shsul@eecs.umich.edu */
1897977Shsul@eecs.umich.edu  PutChar('.' & 0x7f);
1907977Shsul@eecs.umich.edu/*
1917977Shsul@eecs.umich.edu *  Output the n digits after the decimal place.
1927977Shsul@eecs.umich.edu */
1937977Shsul@eecs.umich.edu   for (i = 1; i < 6; i++) {
1947977Shsul@eecs.umich.edu     b = (ul)(power(10, i) * (double)(a - (ul) a));
1957977Shsul@eecs.umich.edu     PutChar((char)(b % 10) + '0');
1967977Shsul@eecs.umich.edu   }
1977977Shsul@eecs.umich.edu}
1987977Shsul@eecs.umich.educhar *FormatItem(char *f, va_list *ap)
1997977Shsul@eecs.umich.edu{
2007977Shsul@eecs.umich.edu  char c;
2017977Shsul@eecs.umich.edu  int fieldwidth = 0;
2027977Shsul@eecs.umich.edu  int leftjust = FALSE;
2037977Shsul@eecs.umich.edu  int radix = 0;
2047977Shsul@eecs.umich.edu  char fill = ' ';
2057977Shsul@eecs.umich.edu  if (*f == '0') fill = '0';
2067977Shsul@eecs.umich.edu  while (c = *f++) {
2077977Shsul@eecs.umich.edu    if (c >= '0' && c <= '9') {
2087977Shsul@eecs.umich.edu      fieldwidth = (fieldwidth * 10) + (c - '0');
2097977Shsul@eecs.umich.edu      }
2107977Shsul@eecs.umich.edu    else switch (c) {
2117977Shsul@eecs.umich.edu      case '\000': return(--f);
2127977Shsul@eecs.umich.edu      case '%': PutChar('%');
2137977Shsul@eecs.umich.edu        return(f);
2147977Shsul@eecs.umich.edu      case '-': leftjust = TRUE;
2157977Shsul@eecs.umich.edu        break;
2167977Shsul@eecs.umich.edu      case 'c': {
2177977Shsul@eecs.umich.edu        char a = va_arg(*ap, char);
2187977Shsul@eecs.umich.edu
2197977Shsul@eecs.umich.edu        if (leftjust) PutChar(a & 0x7f);
2207977Shsul@eecs.umich.edu        if (fieldwidth > 0) PutRepChar(fill, fieldwidth - 1);
2217977Shsul@eecs.umich.edu        if (!leftjust) PutChar(a & 0x7f);
2227977Shsul@eecs.umich.edu        return(f);
2237977Shsul@eecs.umich.edu        }
2247977Shsul@eecs.umich.edu      case 's': {
2257977Shsul@eecs.umich.edu        char *a = va_arg(*ap, char *);
2267977Shsul@eecs.umich.edu
2277977Shsul@eecs.umich.edu        if (leftjust) PutString((char *) a);
2287977Shsul@eecs.umich.edu        if (fieldwidth > strlen((char *) a))
2297977Shsul@eecs.umich.edu          PutRepChar(fill, fieldwidth - strlen((char *)a));
2307977Shsul@eecs.umich.edu        if (!leftjust) PutString((char *) a);
2317977Shsul@eecs.umich.edu        return(f);
2327977Shsul@eecs.umich.edu        }
2337977Shsul@eecs.umich.edu      case 'd': radix = -10;
2347977Shsul@eecs.umich.edu        break;
2357977Shsul@eecs.umich.edu      case 'u': radix = 10;
2367977Shsul@eecs.umich.edu        break;
2377977Shsul@eecs.umich.edu      case 'x': radix = 16;
2387977Shsul@eecs.umich.edu        break;
2397977Shsul@eecs.umich.edu      case 'X': radix = 16;
2407977Shsul@eecs.umich.edu        break;
2417977Shsul@eecs.umich.edu      case 'o': radix = 8;
2427977Shsul@eecs.umich.edu        break;
2437977Shsul@eecs.umich.edu      case 'f': {
2447977Shsul@eecs.umich.edu        double a = va_arg(*ap, double);
2457977Shsul@eecs.umich.edu
2467977Shsul@eecs.umich.edu        putFloat(a, fieldwidth, fill);
2477977Shsul@eecs.umich.edu        return(f);
2487977Shsul@eecs.umich.edu      }
2497977Shsul@eecs.umich.edu      default:   /* unknown switch! */
2507977Shsul@eecs.umich.edu        radix = 3;
2517977Shsul@eecs.umich.edu        break;
2527977Shsul@eecs.umich.edu      }
2537977Shsul@eecs.umich.edu    if (radix) break;
2547977Shsul@eecs.umich.edu    }
2557977Shsul@eecs.umich.edu  if (leftjust) fieldwidth = -fieldwidth;
2567977Shsul@eecs.umich.edu  {
2577977Shsul@eecs.umich.edu     sl a = va_arg(*ap, sl);
2587977Shsul@eecs.umich.edu     PutNumber(a, radix, fieldwidth, fill);
2597977Shsul@eecs.umich.edu  }
2607977Shsul@eecs.umich.edu  return(f);
2617977Shsul@eecs.umich.edu}
2627977Shsul@eecs.umich.edu
2637977Shsul@eecs.umich.eduvoid printf(char *f, ...)
2647977Shsul@eecs.umich.edu{
2657977Shsul@eecs.umich.edu  va_list ap;
2667977Shsul@eecs.umich.edu
2677977Shsul@eecs.umich.edu  va_start(ap, f);
2687977Shsul@eecs.umich.edu
2697977Shsul@eecs.umich.edu  while (*f) {
2707977Shsul@eecs.umich.edu    if (*f == '%') f = FormatItem(f + 1, &ap);
2717977Shsul@eecs.umich.edu    else PutChar(*f++);
2727977Shsul@eecs.umich.edu  }
2737977Shsul@eecs.umich.edu
2747977Shsul@eecs.umich.edu  if (*(f-1)=='\n') {
2757977Shsul@eecs.umich.edu     /* add a line-feed (SimOS console output goes to shell */
2767977Shsul@eecs.umich.edu     PutChar('\r');
2777977Shsul@eecs.umich.edu  }
2787977Shsul@eecs.umich.edu
2797977Shsul@eecs.umich.edu  va_end(ap);         /* clean up */
2807977Shsul@eecs.umich.edu}
2817977Shsul@eecs.umich.edu
2827977Shsul@eecs.umich.eduvoid panic(char *f, ...)
2837977Shsul@eecs.umich.edu{
2847977Shsul@eecs.umich.edu  va_list ap;
2857977Shsul@eecs.umich.edu
2867977Shsul@eecs.umich.edu  va_start(ap, f);
2877977Shsul@eecs.umich.edu
2887977Shsul@eecs.umich.edu  printf("CONSOLE PANIC (looping): ");
2897977Shsul@eecs.umich.edu  while (*f) {
2907977Shsul@eecs.umich.edu    if (*f == '%') f = FormatItem(f + 1, &ap);
2917977Shsul@eecs.umich.edu    else PutChar(*f++);
2927977Shsul@eecs.umich.edu    }
2937977Shsul@eecs.umich.edu
2947977Shsul@eecs.umich.edu  va_end(ap);         /* clean up */
2957977Shsul@eecs.umich.edu  while(1);
2967977Shsul@eecs.umich.edu}
2977977Shsul@eecs.umich.edu
2987977Shsul@eecs.umich.edu
299