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
| |
| |