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