printf.c revision 8012
18012Ssaidi@eecs.umich.edu/*
28012Ssaidi@eecs.umich.eduCopyright 1993, 1994 Hewlett-Packard Development Company, L.P.
37977Shsul@eecs.umich.edu
48012Ssaidi@eecs.umich.eduPermission is hereby granted, free of charge, to any person obtaining a copy of
58012Ssaidi@eecs.umich.eduthis software and associated documentation files (the "Software"), to deal in
68012Ssaidi@eecs.umich.eduthe Software without restriction, including without limitation the rights to
78012Ssaidi@eecs.umich.eduuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
88012Ssaidi@eecs.umich.eduof the Software, and to permit persons to whom the Software is furnished to do
98012Ssaidi@eecs.umich.eduso, subject to the following conditions:
107977Shsul@eecs.umich.edu
118012Ssaidi@eecs.umich.eduThe above copyright notice and this permission notice shall be included in all
128012Ssaidi@eecs.umich.educopies or substantial portions of the Software.
137977Shsul@eecs.umich.edu
148012Ssaidi@eecs.umich.eduTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
158012Ssaidi@eecs.umich.eduIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
168012Ssaidi@eecs.umich.eduFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
178012Ssaidi@eecs.umich.eduAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
188012Ssaidi@eecs.umich.eduLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
198012Ssaidi@eecs.umich.eduOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
208012Ssaidi@eecs.umich.eduSOFTWARE.
218012Ssaidi@eecs.umich.edu*/
227977Shsul@eecs.umich.edu
237977Shsul@eecs.umich.edu#ifndef LINT
247977Shsul@eecs.umich.edustatic char *rcsid = "$Id: printf.c,v 1.1.1.1 1997/10/30 23:27:12 verghese Exp $";
257977Shsul@eecs.umich.edu#endif
267977Shsul@eecs.umich.edu
277977Shsul@eecs.umich.edu/*
287977Shsul@eecs.umich.edu * $Log: printf.c,v $
297977Shsul@eecs.umich.edu * Revision 1.1.1.1  1997/10/30 23:27:12  verghese
307977Shsul@eecs.umich.edu * current 10/29/97
317977Shsul@eecs.umich.edu *
327977Shsul@eecs.umich.edu * Revision 1.1  1995/06/26  21:09:35  berc
337977Shsul@eecs.umich.edu * Initial revision
347977Shsul@eecs.umich.edu *
357977Shsul@eecs.umich.edu * Revision 1.8  1994/10/06  20:29:08  fdh
367977Shsul@eecs.umich.edu * Corrected unsigned long declaration.
377977Shsul@eecs.umich.edu *
387977Shsul@eecs.umich.edu * Revision 1.7  1994/08/05  20:16:23  fdh
397977Shsul@eecs.umich.edu * Updated Copyright header and RCS $Id: identifier.
407977Shsul@eecs.umich.edu *
417977Shsul@eecs.umich.edu * Revision 1.6  1994/06/21  15:41:54  rusling
427977Shsul@eecs.umich.edu * fixedup WNT compiler warnings
437977Shsul@eecs.umich.edu *
447977Shsul@eecs.umich.edu * Revision 1.5  1994/06/17  19:35:37  fdh
457977Shsul@eecs.umich.edu * Clean-up...
467977Shsul@eecs.umich.edu *
477977Shsul@eecs.umich.edu * Revision 1.4  1994/01/19  10:40:08  rusling
487977Shsul@eecs.umich.edu * Ported to Alpha Windows NT.
497977Shsul@eecs.umich.edu *
507977Shsul@eecs.umich.edu * Revision 1.3  1993/11/02  21:57:45  fdh
517977Shsul@eecs.umich.edu * Fixed sign extension problem introduced in version 1.2
527977Shsul@eecs.umich.edu *
537977Shsul@eecs.umich.edu * Revision 1.2  1993/10/13  15:29:02  rusling
547977Shsul@eecs.umich.edu * Added floating point support in printf.  This meant adding variable arguments to
557977Shsul@eecs.umich.edu * it and FormatItem() and including stdarg.h.
567977Shsul@eecs.umich.edu *
577977Shsul@eecs.umich.edu * Revision 1.1  1993/06/08  19:56:24  fdh
587977Shsul@eecs.umich.edu * Initial revision
597977Shsul@eecs.umich.edu *
607977Shsul@eecs.umich.edu */
617977Shsul@eecs.umich.edu
627977Shsul@eecs.umich.edu
637977Shsul@eecs.umich.edu
647977Shsul@eecs.umich.edu/* printf.c
657977Shsul@eecs.umich.edu   L. S.
667977Shsul@eecs.umich.edu   Sun Feb 10 20:18:22 1985
677977Shsul@eecs.umich.edu */
687977Shsul@eecs.umich.edu
697996Ssaidi@eecs.umich.edu//#include "system.h"
707977Shsul@eecs.umich.edu#include "lib.h"
717977Shsul@eecs.umich.edu#include <stdarg.h>
727977Shsul@eecs.umich.edu
737977Shsul@eecs.umich.edu
747977Shsul@eecs.umich.edu
757977Shsul@eecs.umich.edu
767977Shsul@eecs.umich.edu
777977Shsul@eecs.umich.edu/* The string s is terminated by a '\0' */
787978Sbinkertn@umich.eduvoid
797978Sbinkertn@umich.eduPutString(const char *s)
807977Shsul@eecs.umich.edu{
817977Shsul@eecs.umich.edu  while (*s) PutChar(*s++);
827977Shsul@eecs.umich.edu}
837977Shsul@eecs.umich.edu
847977Shsul@eecs.umich.edu/* print c count times */
857978Sbinkertn@umich.eduvoid
867978Sbinkertn@umich.eduPutRepChar(char c, int count)
877977Shsul@eecs.umich.edu{
887977Shsul@eecs.umich.edu  while (count--) PutChar(c);
897977Shsul@eecs.umich.edu}
907977Shsul@eecs.umich.edu
917977Shsul@eecs.umich.edu/* put string reverse */
927978Sbinkertn@umich.eduvoid
937978Sbinkertn@umich.eduPutStringReverse(const char *s, int index)
947977Shsul@eecs.umich.edu{
957977Shsul@eecs.umich.edu  while ((index--) > 0) PutChar(s[index]);
967977Shsul@eecs.umich.edu}
977977Shsul@eecs.umich.edu
987977Shsul@eecs.umich.edu/* prints value in radix, in a field width width, with fill
997977Shsul@eecs.umich.edu   character fill
1007977Shsul@eecs.umich.edu   if radix is negative, print as signed quantity
1017977Shsul@eecs.umich.edu   if width is negative, left justify
1027977Shsul@eecs.umich.edu   if width is 0, use whatever is needed
1037977Shsul@eecs.umich.edu   if fill is 0, use ' '
1047977Shsul@eecs.umich.edu */
1057978Sbinkertn@umich.eduvoid
1067978Sbinkertn@umich.eduPutNumber(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}
1987978Sbinkertn@umich.educonst char *
1997978Sbinkertn@umich.eduFormatItem(const char *f, va_list *ap)
2007977Shsul@eecs.umich.edu{
2017977Shsul@eecs.umich.edu  char c;
2027977Shsul@eecs.umich.edu  int fieldwidth = 0;
2037977Shsul@eecs.umich.edu  int leftjust = FALSE;
2047977Shsul@eecs.umich.edu  int radix = 0;
2057977Shsul@eecs.umich.edu  char fill = ' ';
2067977Shsul@eecs.umich.edu  if (*f == '0') fill = '0';
2077977Shsul@eecs.umich.edu  while (c = *f++) {
2087977Shsul@eecs.umich.edu    if (c >= '0' && c <= '9') {
2097977Shsul@eecs.umich.edu      fieldwidth = (fieldwidth * 10) + (c - '0');
2107977Shsul@eecs.umich.edu      }
2117977Shsul@eecs.umich.edu    else switch (c) {
2127977Shsul@eecs.umich.edu      case '\000': return(--f);
2137977Shsul@eecs.umich.edu      case '%': PutChar('%');
2147977Shsul@eecs.umich.edu        return(f);
2157977Shsul@eecs.umich.edu      case '-': leftjust = TRUE;
2167977Shsul@eecs.umich.edu        break;
2177977Shsul@eecs.umich.edu      case 'c': {
2187992Ssaidi@eecs.umich.edu        char a = va_arg(*ap, char *);
2197977Shsul@eecs.umich.edu
2207977Shsul@eecs.umich.edu        if (leftjust) PutChar(a & 0x7f);
2217977Shsul@eecs.umich.edu        if (fieldwidth > 0) PutRepChar(fill, fieldwidth - 1);
2227977Shsul@eecs.umich.edu        if (!leftjust) PutChar(a & 0x7f);
2237977Shsul@eecs.umich.edu        return(f);
2247977Shsul@eecs.umich.edu        }
2257977Shsul@eecs.umich.edu      case 's': {
2267978Sbinkertn@umich.edu        const char *a = va_arg(*ap, const char *);
2277977Shsul@eecs.umich.edu
2287978Sbinkertn@umich.edu        if (leftjust) PutString((const char *) a);
2297978Sbinkertn@umich.edu        if (fieldwidth > strlen((const char *) a))
2307978Sbinkertn@umich.edu          PutRepChar(fill, fieldwidth - strlen((const char *)a));
2317978Sbinkertn@umich.edu        if (!leftjust) PutString((const char *) a);
2327977Shsul@eecs.umich.edu        return(f);
2337977Shsul@eecs.umich.edu        }
2347977Shsul@eecs.umich.edu      case 'd': radix = -10;
2357977Shsul@eecs.umich.edu        break;
2367977Shsul@eecs.umich.edu      case 'u': radix = 10;
2377977Shsul@eecs.umich.edu        break;
2387977Shsul@eecs.umich.edu      case 'x': radix = 16;
2397977Shsul@eecs.umich.edu        break;
2407977Shsul@eecs.umich.edu      case 'X': radix = 16;
2417977Shsul@eecs.umich.edu        break;
2427977Shsul@eecs.umich.edu      case 'o': radix = 8;
2437977Shsul@eecs.umich.edu        break;
2447977Shsul@eecs.umich.edu      case 'f': {
2457977Shsul@eecs.umich.edu        double a = va_arg(*ap, double);
2467977Shsul@eecs.umich.edu
2477977Shsul@eecs.umich.edu        putFloat(a, fieldwidth, fill);
2487977Shsul@eecs.umich.edu        return(f);
2497977Shsul@eecs.umich.edu      }
2507977Shsul@eecs.umich.edu      default:   /* unknown switch! */
2517977Shsul@eecs.umich.edu        radix = 3;
2527977Shsul@eecs.umich.edu        break;
2537977Shsul@eecs.umich.edu      }
2547977Shsul@eecs.umich.edu    if (radix) break;
2557977Shsul@eecs.umich.edu    }
2567977Shsul@eecs.umich.edu  if (leftjust) fieldwidth = -fieldwidth;
2577977Shsul@eecs.umich.edu  {
2587977Shsul@eecs.umich.edu     sl a = va_arg(*ap, sl);
2597977Shsul@eecs.umich.edu     PutNumber(a, radix, fieldwidth, fill);
2607977Shsul@eecs.umich.edu  }
2617977Shsul@eecs.umich.edu  return(f);
2627977Shsul@eecs.umich.edu}
2637977Shsul@eecs.umich.edu
2647978Sbinkertn@umich.eduint
2657978Sbinkertn@umich.eduprintf(const char *f, ...)
2667977Shsul@eecs.umich.edu{
2677977Shsul@eecs.umich.edu  va_list ap;
2687977Shsul@eecs.umich.edu
2697977Shsul@eecs.umich.edu  va_start(ap, f);
2707977Shsul@eecs.umich.edu
2717977Shsul@eecs.umich.edu  while (*f) {
2727977Shsul@eecs.umich.edu    if (*f == '%') f = FormatItem(f + 1, &ap);
2737977Shsul@eecs.umich.edu    else PutChar(*f++);
2747977Shsul@eecs.umich.edu  }
2757977Shsul@eecs.umich.edu
2767977Shsul@eecs.umich.edu  if (*(f-1)=='\n') {
2777977Shsul@eecs.umich.edu     /* add a line-feed (SimOS console output goes to shell */
2787977Shsul@eecs.umich.edu     PutChar('\r');
2797977Shsul@eecs.umich.edu  }
2807977Shsul@eecs.umich.edu
2817977Shsul@eecs.umich.edu  va_end(ap);         /* clean up */
2827978Sbinkertn@umich.edu  return 0;
2837977Shsul@eecs.umich.edu}
2847977Shsul@eecs.umich.edu
2857978Sbinkertn@umich.eduvoid
2867978Sbinkertn@umich.edupanic(const char *f, ...)
2877977Shsul@eecs.umich.edu{
2887977Shsul@eecs.umich.edu  va_list ap;
2897977Shsul@eecs.umich.edu
2907977Shsul@eecs.umich.edu  va_start(ap, f);
2917977Shsul@eecs.umich.edu
2927977Shsul@eecs.umich.edu  printf("CONSOLE PANIC (looping): ");
2937977Shsul@eecs.umich.edu  while (*f) {
2947977Shsul@eecs.umich.edu    if (*f == '%') f = FormatItem(f + 1, &ap);
2957977Shsul@eecs.umich.edu    else PutChar(*f++);
2967977Shsul@eecs.umich.edu    }
2977977Shsul@eecs.umich.edu
2987977Shsul@eecs.umich.edu  va_end(ap);         /* clean up */
2997977Shsul@eecs.umich.edu  while(1);
3007977Shsul@eecs.umich.edu}
3017977Shsul@eecs.umich.edu
3027977Shsul@eecs.umich.edu
303