printf.c (8012:2f71125bf413) printf.c (8013:2dfcde2e9998)
1/*
1/*
2Copyright 1993, 1994 Hewlett-Packard Development Company, L.P.
3
4Permission is hereby granted, free of charge, to any person obtaining a copy of
5this software and associated documentation files (the "Software"), to deal in
6the Software without restriction, including without limitation the rights to
7use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
8of the Software, and to permit persons to whom the Software is furnished to do
9so, subject to the following conditions:
10
11The above copyright notice and this permission notice shall be included in all
12copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20SOFTWARE.
21*/
22
23#ifndef LINT
24static char *rcsid = "$Id: printf.c,v 1.1.1.1 1997/10/30 23:27:12 verghese Exp $";
25#endif
26
27/*
28 * $Log: printf.c,v $
29 * Revision 1.1.1.1 1997/10/30 23:27:12 verghese
30 * current 10/29/97
2 * Copyright (c) 2003, 2004
3 * The Regents of The University of Michigan
4 * All Rights Reserved
31 *
5 *
32 * Revision 1.1 1995/06/26 21:09:35 berc
33 * Initial revision
6 * This code is part of the M5 simulator, developed by Nathan Binkert,
7 * Erik Hallnor, Steve Raasch, and Steve Reinhardt, with contributions
8 * from Ron Dreslinski, Dave Greene, Lisa Hsu, Ali Saidi, and Andrew
9 * Schultz.
34 *
10 *
35 * Revision 1.8 1994/10/06 20:29:08 fdh
36 * Corrected unsigned long declaration.
11 * Permission is granted to use, copy, create derivative works and
12 * redistribute this software and such derivative works for any purpose,
13 * so long as the copyright notice above, this grant of permission, and
14 * the disclaimer below appear in all copies made; and so long as the
15 * name of The University of Michigan is not used in any advertising or
16 * publicity pertaining to the use or distribution of this software
17 * without specific, written prior authorization.
37 *
18 *
38 * Revision 1.7 1994/08/05 20:16:23 fdh
39 * Updated Copyright header and RCS $Id: identifier.
19 * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE
20 * UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND WITHOUT
21 * WARRANTY BY THE UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER EXPRESS OR
22 * IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF
23 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE REGENTS OF
24 * THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE FOR ANY DAMAGES,
25 * INCLUDING DIRECT, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
26 * DAMAGES, WITH RESPECT TO ANY CLAIM ARISING OUT OF OR IN CONNECTION
27 * WITH THE USE OF THE SOFTWARE, EVEN IF IT HAS BEEN OR IS HEREAFTER
28 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
29 */
30
31/*
32 * Copyright 1993 Hewlett-Packard Development Company, L.P.
40 *
33 *
41 * Revision 1.6 1994/06/21 15:41:54 rusling
42 * fixedup WNT compiler warnings
34 * Permission is hereby granted, free of charge, to any person
35 * obtaining a copy of this software and associated documentation
36 * files (the "Software"), to deal in the Software without
37 * restriction, including without limitation the rights to use, copy,
38 * modify, merge, publish, distribute, sublicense, and/or sell copies
39 * of the Software, and to permit persons to whom the Software is
40 * furnished to do so, subject to the following conditions:
43 *
41 *
44 * Revision 1.5 1994/06/17 19:35:37 fdh
45 * Clean-up...
42 * The above copyright notice and this permission notice shall be
43 * included in all copies or substantial portions of the Software.
46 *
44 *
47 * Revision 1.4 1994/01/19 10:40:08 rusling
48 * Ported to Alpha Windows NT.
49 *
50 * Revision 1.3 1993/11/02 21:57:45 fdh
51 * Fixed sign extension problem introduced in version 1.2
52 *
53 * Revision 1.2 1993/10/13 15:29:02 rusling
54 * Added floating point support in printf. This meant adding variable arguments to
55 * it and FormatItem() and including stdarg.h.
56 *
57 * Revision 1.1 1993/06/08 19:56:24 fdh
58 * Initial revision
59 *
45 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
46 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
47 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
48 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
49 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
50 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
51 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
52 * SOFTWARE.
60 */
61
53 */
54
62
63
64/* printf.c
65 L. S.
66 Sun Feb 10 20:18:22 1985
67 */
68
69//#include "system.h"
70#include "lib.h"
55#include <sys/types.h>
71#include <stdarg.h>
72
56#include <stdarg.h>
57
73
74
75
76
77/* The string s is terminated by a '\0' */
78void
79PutString(const char *s)
80{
58/* The string s is terminated by a '\0' */
59void
60PutString(const char *s)
61{
81 while (*s) PutChar(*s++);
62 while (*s)
63 PutChar(*s++);
82}
83
84/* print c count times */
85void
86PutRepChar(char c, int count)
87{
64}
65
66/* print c count times */
67void
68PutRepChar(char c, int count)
69{
88 while (count--) PutChar(c);
70 while (count--)
71 PutChar(c);
89}
90
91/* put string reverse */
92void
93PutStringReverse(const char *s, int index)
94{
72}
73
74/* put string reverse */
75void
76PutStringReverse(const char *s, int index)
77{
95 while ((index--) > 0) PutChar(s[index]);
78 while (index-- > 0)
79 PutChar(s[index]);
96}
97
80}
81
98/* prints value in radix, in a field width width, with fill
99 character fill
100 if radix is negative, print as signed quantity
101 if width is negative, left justify
102 if width is 0, use whatever is needed
103 if fill is 0, use ' '
82/*
83 * prints value in radix, in a field width width, with fill
84 * character fill
85 * if radix is negative, print as signed quantity
86 * if width is negative, left justify
87 * if width is 0, use whatever is needed
88 * if fill is 0, use ' '
104 */
105void
89 */
90void
106PutNumber(sl value, int radix, int width, char fill)
91PutNumber(long value, int radix, int width, char fill)
107{
92{
108 char buffer[40];
109 ui bufferindex = 0;
110 ul uvalue;
111 uw digit;
112 uw left = FALSE;
113 uw negative = FALSE;
93 char buffer[40];
94 uint bufferindex = 0;
95 ulong uvalue;
96 ushort digit;
97 ushort left = 0;
98 ushort negative = 0;
114
99
115 if (fill == 0) fill = ' ';
100 if (fill == 0)
101 fill = ' ';
116
102
117 if (width < 0) {
118 width = -width;
119 left = TRUE;
103 if (width < 0) {
104 width = -width;
105 left = 1;
120 }
106 }
121 if (width < 0 || width > 80) width = 0;
122
107
123 if (radix < 0) {
124 radix = -radix;
125 if (value < 0) {
126 negative = TRUE;
127 value = -value;
128 }
108 if (width < 0 || width > 80)
109 width = 0;
110
111 if (radix < 0) {
112 radix = -radix;
113 if (value < 0) {
114 negative = 1;
115 value = -value;
116 }
129 }
117 }
130 switch (radix) {
131 case 8:
132 case 10:
133 case 16: break;
134 default: {
135 PutString("****");
136 return;
137 }
118
119 switch (radix) {
120 case 8:
121 case 10:
122 case 16:
123 break;
124
125 default:
126 PutString("****");
127 return;
138 }
128 }
139 uvalue = value;
140 do {
141 if (radix != 16)
142 {
143 digit = (uw)(uvalue % radix);
144 uvalue /= radix;
145 }
146 else
147 {
148 digit = (uw)(uvalue & 0xf);
149 uvalue = uvalue >> 4;
150 }
151 buffer[bufferindex] = digit + ((digit <= 9) ? '0' : ('A' - 10));
152 bufferindex += 1;
129
130 uvalue = value;
131
132 do {
133 if (radix != 16) {
134 digit = (ushort)(uvalue % radix);
135 uvalue /= radix;
136 } else {
137 digit = (ushort)(uvalue & 0xf);
138 uvalue = uvalue >> 4;
139 }
140 buffer[bufferindex] = digit + ((digit <= 9) ? '0' : ('A' - 10));
141 bufferindex += 1;
153 } while (uvalue != 0);
142 } while (uvalue != 0);
143
154 /* fill # ' ' and negative cannot happen at once */
144 /* fill # ' ' and negative cannot happen at once */
155 if (negative) {
156 buffer[bufferindex] = '-';
157 bufferindex += 1;
145 if (negative) {
146 buffer[bufferindex] = '-';
147 bufferindex += 1;
158 }
148 }
159 if ((ui)width <= bufferindex) PutStringReverse(buffer, bufferindex);
160 else {
161 width -= bufferindex;
162 if (!left) PutRepChar(fill, width);
163 PutStringReverse(buffer, bufferindex);
164 if (left) PutRepChar(fill, width);
149
150 if ((uint)width <= bufferindex) {
151 PutStringReverse(buffer, bufferindex);
152 } else {
153 width -= bufferindex;
154 if (!left)
155 PutRepChar(fill, width);
156 PutStringReverse(buffer, bufferindex);
157 if (left)
158 PutRepChar(fill, width);
165 }
166}
167
159 }
160}
161
168ul power(long base, long n)
162ulong
163power(long base, long n)
169{
164{
170 ul p;
165 ulong p;
171
166
172 for (p = 1; n > 0; --n)
173 p = p * base;
174 return p;
167 for (p = 1; n > 0; --n)
168 p = p * base;
169 return p;
175}
176
170}
171
177void putFloat(double a, int fieldwidth, char fill)
172void
173putFloat(double a, int fieldwidth, char fill)
178{
174{
179 int i;
180 ul b;
175 int i;
176 ulong b;
181
177
182/*
183 * Put out everything before the decimal place.
184 */
185 PutNumber(((ul) a), 10, fieldwidth, fill);
186/*
187 * Output the decimal place.
188 */
189 PutChar('.' & 0x7f);
190/*
191 * Output the n digits after the decimal place.
192 */
193 for (i = 1; i < 6; i++) {
194 b = (ul)(power(10, i) * (double)(a - (ul) a));
195 PutChar((char)(b % 10) + '0');
196 }
178 /*
179 * Put out everything before the decimal place.
180 */
181 PutNumber(((ulong) a), 10, fieldwidth, fill);
182
183 /*
184 * Output the decimal place.
185 */
186 PutChar('.' & 0x7f);
187
188 /*
189 * Output the n digits after the decimal place.
190 */
191 for (i = 1; i < 6; i++) {
192 b = (ulong)(power(10, i) * (double)(a - (ulong) a));
193 PutChar((char)(b % 10) + '0');
194 }
197}
195}
196
198const char *
199FormatItem(const char *f, va_list *ap)
200{
197const char *
198FormatItem(const char *f, va_list *ap)
199{
201 char c;
202 int fieldwidth = 0;
203 int leftjust = FALSE;
204 int radix = 0;
205 char fill = ' ';
206 if (*f == '0') fill = '0';
207 while (c = *f++) {
208 if (c >= '0' && c <= '9') {
209 fieldwidth = (fieldwidth * 10) + (c - '0');
210 }
211 else switch (c) {
212 case '\000': return(--f);
213 case '%': PutChar('%');
214 return(f);
215 case '-': leftjust = TRUE;
216 break;
217 case 'c': {
218 char a = va_arg(*ap, char *);
200 char c;
201 int fieldwidth = 0;
202 int leftjust = 0;
203 int radix = 0;
204 char fill = ' ';
219
205
220 if (leftjust) PutChar(a & 0x7f);
221 if (fieldwidth > 0) PutRepChar(fill, fieldwidth - 1);
222 if (!leftjust) PutChar(a & 0x7f);
223 return(f);
224 }
225 case 's': {
226 const char *a = va_arg(*ap, const char *);
206 if (*f == '0')
207 fill = '0';
227
208
228 if (leftjust) PutString((const char *) a);
229 if (fieldwidth > strlen((const char *) a))
230 PutRepChar(fill, fieldwidth - strlen((const char *)a));
231 if (!leftjust) PutString((const char *) a);
232 return(f);
209 while (c = *f++) {
210 if (c >= '0' && c <= '9') {
211 fieldwidth = (fieldwidth * 10) + (c - '0');
212 } else {
213 switch (c) {
214 case '\000':
215 return(--f);
216 case '%':
217 PutChar('%');
218 return(f);
219 case '-':
220 leftjust = 1;
221 break;
222 case 'c': {
223 char a = (char)va_arg(*ap, int);
224
225 if (leftjust)
226 PutChar(a & 0x7f);
227 if (fieldwidth > 0)
228 PutRepChar(fill, fieldwidth - 1);
229 if (!leftjust)
230 PutChar(a & 0x7f);
231 return(f);
232 }
233 case 's': {
234 const char *a = va_arg(*ap, const char *);
235
236 if (leftjust)
237 PutString((const char *) a);
238 if (fieldwidth > strlen((const char *) a))
239 PutRepChar(fill, fieldwidth - strlen((const char *)a));
240 if (!leftjust)
241 PutString((const char *) a);
242 return(f);
243 }
244 case 'd':
245 radix = -10;
246 break;
247 case 'u':
248 radix = 10;
249 break;
250 case 'x':
251 radix = 16;
252 break;
253 case 'X':
254 radix = 16;
255 break;
256 case 'o':
257 radix = 8;
258 break;
259 case 'f': {
260 double a = va_arg(*ap, double);
261
262 putFloat(a, fieldwidth, fill);
263 return(f);
264 }
265 default: /* unknown switch! */
266 radix = 3;
267 break;
268 }
233 }
269 }
234 case 'd': radix = -10;
235 break;
236 case 'u': radix = 10;
237 break;
238 case 'x': radix = 16;
239 break;
240 case 'X': radix = 16;
241 break;
242 case 'o': radix = 8;
243 break;
244 case 'f': {
245 double a = va_arg(*ap, double);
246
270
247 putFloat(a, fieldwidth, fill);
248 return(f);
249 }
250 default: /* unknown switch! */
251 radix = 3;
252 break;
253 }
254 if (radix) break;
271 if (radix)
272 break;
255 }
273 }
256 if (leftjust) fieldwidth = -fieldwidth;
257 {
258 sl a = va_arg(*ap, sl);
259 PutNumber(a, radix, fieldwidth, fill);
260 }
261 return(f);
274
275 if (leftjust)
276 fieldwidth = -fieldwidth;
277
278 long a = va_arg(*ap, long);
279 PutNumber(a, radix, fieldwidth, fill);
280
281 return(f);
262}
263
264int
265printf(const char *f, ...)
266{
282}
283
284int
285printf(const char *f, ...)
286{
267 va_list ap;
287 va_list ap;
268
288
269 va_start(ap, f);
289 va_start(ap, f);
270
290
271 while (*f) {
272 if (*f == '%') f = FormatItem(f + 1, &ap);
273 else PutChar(*f++);
274 }
291 while (*f) {
292 if (*f == '%')
293 f = FormatItem(f + 1, &ap);
294 else
295 PutChar(*f++);
296 }
275
297
276 if (*(f-1)=='\n') {
277 /* add a line-feed (SimOS console output goes to shell */
278 PutChar('\r');
279 }
298 if (*(f - 1) == '\n') {
299 /* add a line-feed (SimOS console output goes to shell */
300 PutChar('\r');
301 }
280
302
281 va_end(ap); /* clean up */
282 return 0;
303 va_end(ap); /* clean up */
304 return 0;
283}
284
285void
286panic(const char *f, ...)
287{
305}
306
307void
308panic(const char *f, ...)
309{
288 va_list ap;
310 va_list ap;
289
311
290 va_start(ap, f);
312 va_start(ap, f);
291
313
292 printf("CONSOLE PANIC (looping): ");
293 while (*f) {
294 if (*f == '%') f = FormatItem(f + 1, &ap);
295 else PutChar(*f++);
314 printf("CONSOLE PANIC (looping): ");
315 while (*f) {
316 if (*f == '%')
317 f = FormatItem(f + 1, &ap);
318 else
319 PutChar(*f++);
296 }
297
320 }
321
298 va_end(ap); /* clean up */
299 while(1);
322 va_end(ap); /* clean up */
323 while(1);
300}
324}
301
302