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