printf.c revision 7992:fabe6a2d9c5e
111210SBrad.Beckmann@amd.com/*****************************************************************************
211210SBrad.Beckmann@amd.com
311210SBrad.Beckmann@amd.com       Copyright � 1993, 1994 Digital Equipment Corporation,
411210SBrad.Beckmann@amd.com                       Maynard, Massachusetts.
511210SBrad.Beckmann@amd.com
611210SBrad.Beckmann@amd.com                        All Rights Reserved
711210SBrad.Beckmann@amd.com
811210SBrad.Beckmann@amd.comPermission to use, copy, modify, and distribute this software and its
911210SBrad.Beckmann@amd.comdocumentation for any purpose and without fee is hereby granted, provided
1011210SBrad.Beckmann@amd.comthat the copyright notice and this permission notice appear in all copies
1111210SBrad.Beckmann@amd.comof software and supporting documentation, and that the name of Digital not
1211210SBrad.Beckmann@amd.combe used in advertising or publicity pertaining to distribution of the software
1311210SBrad.Beckmann@amd.comwithout specific, written prior permission. Digital grants this permission
1411210SBrad.Beckmann@amd.comprovided that you prominently mark, as not part of the original, any
1511210SBrad.Beckmann@amd.commodifications made to this software or documentation.
1611210SBrad.Beckmann@amd.com
1711210SBrad.Beckmann@amd.comDigital Equipment Corporation disclaims all warranties and/or guarantees
1811210SBrad.Beckmann@amd.comwith regard to this software, including all implied warranties of fitness for
1911210SBrad.Beckmann@amd.coma particular purpose and merchantability, and makes no representations
2011210SBrad.Beckmann@amd.comregarding the use of, or the results of the use of, the software and
2111210SBrad.Beckmann@amd.comdocumentation in terms of correctness, accuracy, reliability, currentness or
2211210SBrad.Beckmann@amd.comotherwise; and you rely on the software, documentation and results solely at
2311210SBrad.Beckmann@amd.comyour own risk.
2411210SBrad.Beckmann@amd.com
2511210SBrad.Beckmann@amd.com******************************************************************************/
2611210SBrad.Beckmann@amd.com
2711210SBrad.Beckmann@amd.com#ifndef LINT
2811210SBrad.Beckmann@amd.comstatic char *rcsid = "$Id: printf.c,v 1.1.1.1 1997/10/30 23:27:12 verghese Exp $";
2911210SBrad.Beckmann@amd.com#endif
3011210SBrad.Beckmann@amd.com
3111210SBrad.Beckmann@amd.com/*
3211210SBrad.Beckmann@amd.com * $Log: printf.c,v $
3311210SBrad.Beckmann@amd.com * Revision 1.1.1.1  1997/10/30 23:27:12  verghese
3411210SBrad.Beckmann@amd.com * current 10/29/97
3511210SBrad.Beckmann@amd.com *
3611210SBrad.Beckmann@amd.com * Revision 1.1  1995/06/26  21:09:35  berc
3711210SBrad.Beckmann@amd.com * Initial revision
3811210SBrad.Beckmann@amd.com *
3911210SBrad.Beckmann@amd.com * Revision 1.8  1994/10/06  20:29:08  fdh
4011210SBrad.Beckmann@amd.com * Corrected unsigned long declaration.
4111210SBrad.Beckmann@amd.com *
4211210SBrad.Beckmann@amd.com * Revision 1.7  1994/08/05  20:16:23  fdh
4311210SBrad.Beckmann@amd.com * Updated Copyright header and RCS $Id: identifier.
4411210SBrad.Beckmann@amd.com *
4511210SBrad.Beckmann@amd.com * Revision 1.6  1994/06/21  15:41:54  rusling
46 * fixedup WNT compiler warnings
47 *
48 * Revision 1.5  1994/06/17  19:35:37  fdh
49 * Clean-up...
50 *
51 * Revision 1.4  1994/01/19  10:40:08  rusling
52 * Ported to Alpha Windows NT.
53 *
54 * Revision 1.3  1993/11/02  21:57:45  fdh
55 * Fixed sign extension problem introduced in version 1.2
56 *
57 * Revision 1.2  1993/10/13  15:29:02  rusling
58 * Added floating point support in printf.  This meant adding variable arguments to
59 * it and FormatItem() and including stdarg.h.
60 *
61 * Revision 1.1  1993/06/08  19:56:24  fdh
62 * Initial revision
63 *
64 */
65
66
67
68/* printf.c
69   L. S.
70   Sun Feb 10 20:18:22 1985
71 */
72
73#include "system.h"
74#include "lib.h"
75#include <stdarg.h>
76
77
78
79
80
81/* The string s is terminated by a '\0' */
82void
83PutString(const char *s)
84{
85  while (*s) PutChar(*s++);
86}
87
88/* print c count times */
89void
90PutRepChar(char c, int count)
91{
92  while (count--) PutChar(c);
93}
94
95/* put string reverse */
96void
97PutStringReverse(const char *s, int index)
98{
99  while ((index--) > 0) PutChar(s[index]);
100}
101
102/* prints value in radix, in a field width width, with fill
103   character fill
104   if radix is negative, print as signed quantity
105   if width is negative, left justify
106   if width is 0, use whatever is needed
107   if fill is 0, use ' '
108 */
109void
110PutNumber(sl value, int radix, int width, char fill)
111{
112  char buffer[40];
113  ui bufferindex = 0;
114  ul uvalue;
115  uw digit;
116  uw left = FALSE;
117  uw negative = FALSE;
118
119  if (fill == 0) fill = ' ';
120
121  if (width < 0) {
122    width = -width;
123    left = TRUE;
124    }
125  if (width < 0 || width > 80) width = 0;
126
127  if (radix < 0) {
128    radix = -radix;
129    if (value < 0) {
130      negative = TRUE;
131      value = -value;
132      }
133    }
134  switch (radix) {
135    case 8:
136    case 10:
137    case 16: break;
138    default: {
139      PutString("****");
140      return;
141      }
142    }
143  uvalue = value;
144  do {
145    if (radix != 16)
146    {
147      digit = (uw)(uvalue % radix);
148      uvalue /= radix;
149    }
150    else
151    {
152      digit = (uw)(uvalue & 0xf);
153      uvalue = uvalue >> 4;
154    }
155    buffer[bufferindex] = digit + ((digit <= 9) ? '0' : ('A' - 10));
156    bufferindex += 1;
157    } while (uvalue != 0);
158  /* fill # ' ' and negative cannot happen at once */
159  if (negative) {
160    buffer[bufferindex] = '-';
161    bufferindex += 1;
162    }
163  if ((ui)width <= bufferindex) PutStringReverse(buffer, bufferindex);
164  else {
165    width -= bufferindex;
166    if (!left) PutRepChar(fill, width);
167    PutStringReverse(buffer, bufferindex);
168    if (left) PutRepChar(fill, width);
169    }
170}
171
172ul power(long base, long n)
173{
174  ul p;
175
176  for (p = 1; n > 0; --n)
177    p = p * base;
178  return p;
179}
180
181void putFloat(double a, int fieldwidth, char fill)
182{
183  int i;
184  ul b;
185
186/*
187 *  Put out everything before the decimal place.
188 */
189  PutNumber(((ul) a), 10, fieldwidth, fill);
190/*
191 *  Output the decimal place.
192 */
193  PutChar('.' & 0x7f);
194/*
195 *  Output the n digits after the decimal place.
196 */
197   for (i = 1; i < 6; i++) {
198     b = (ul)(power(10, i) * (double)(a - (ul) a));
199     PutChar((char)(b % 10) + '0');
200   }
201}
202const char *
203FormatItem(const char *f, va_list *ap)
204{
205  char c;
206  int fieldwidth = 0;
207  int leftjust = FALSE;
208  int radix = 0;
209  char fill = ' ';
210  if (*f == '0') fill = '0';
211  while (c = *f++) {
212    if (c >= '0' && c <= '9') {
213      fieldwidth = (fieldwidth * 10) + (c - '0');
214      }
215    else switch (c) {
216      case '\000': return(--f);
217      case '%': PutChar('%');
218        return(f);
219      case '-': leftjust = TRUE;
220        break;
221      case 'c': {
222        char a = va_arg(*ap, char *);
223
224        if (leftjust) PutChar(a & 0x7f);
225        if (fieldwidth > 0) PutRepChar(fill, fieldwidth - 1);
226        if (!leftjust) PutChar(a & 0x7f);
227        return(f);
228        }
229      case 's': {
230        const char *a = va_arg(*ap, const char *);
231
232        if (leftjust) PutString((const char *) a);
233        if (fieldwidth > strlen((const char *) a))
234          PutRepChar(fill, fieldwidth - strlen((const char *)a));
235        if (!leftjust) PutString((const char *) a);
236        return(f);
237        }
238      case 'd': radix = -10;
239        break;
240      case 'u': radix = 10;
241        break;
242      case 'x': radix = 16;
243        break;
244      case 'X': radix = 16;
245        break;
246      case 'o': radix = 8;
247        break;
248      case 'f': {
249        double a = va_arg(*ap, double);
250
251        putFloat(a, fieldwidth, fill);
252        return(f);
253      }
254      default:   /* unknown switch! */
255        radix = 3;
256        break;
257      }
258    if (radix) break;
259    }
260  if (leftjust) fieldwidth = -fieldwidth;
261  {
262     sl a = va_arg(*ap, sl);
263     PutNumber(a, radix, fieldwidth, fill);
264  }
265  return(f);
266}
267
268int
269printf(const char *f, ...)
270{
271  va_list ap;
272
273  va_start(ap, f);
274
275  while (*f) {
276    if (*f == '%') f = FormatItem(f + 1, &ap);
277    else PutChar(*f++);
278  }
279
280  if (*(f-1)=='\n') {
281     /* add a line-feed (SimOS console output goes to shell */
282     PutChar('\r');
283  }
284
285  va_end(ap);         /* clean up */
286  return 0;
287}
288
289void
290panic(const char *f, ...)
291{
292  va_list ap;
293
294  va_start(ap, f);
295
296  printf("CONSOLE PANIC (looping): ");
297  while (*f) {
298    if (*f == '%') f = FormatItem(f + 1, &ap);
299    else PutChar(*f++);
300    }
301
302  va_end(ap);         /* clean up */
303  while(1);
304}
305
306
307