diff options
Diffstat (limited to 'system/alpha/console/printf.c')
-rw-r--r-- | system/alpha/console/printf.c | 298 |
1 files changed, 298 insertions, 0 deletions
diff --git a/system/alpha/console/printf.c b/system/alpha/console/printf.c new file mode 100644 index 000000000..e0dc0426b --- /dev/null +++ b/system/alpha/console/printf.c @@ -0,0 +1,298 @@ +/***************************************************************************** + + Copyright © 1993, 1994 Digital Equipment Corporation, + Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, provided +that the copyright notice and this permission notice appear in all copies +of software and supporting documentation, and that the name of Digital not +be used in advertising or publicity pertaining to distribution of the software +without specific, written prior permission. Digital grants this permission +provided that you prominently mark, as not part of the original, any +modifications made to this software or documentation. + +Digital Equipment Corporation disclaims all warranties and/or guarantees +with regard to this software, including all implied warranties of fitness for +a particular purpose and merchantability, and makes no representations +regarding the use of, or the results of the use of, the software and +documentation in terms of correctness, accuracy, reliability, currentness or +otherwise; and you rely on the software, documentation and results solely at +your own risk. + +******************************************************************************/ + +#ifndef LINT +static char *rcsid = "$Id: printf.c,v 1.1.1.1 1997/10/30 23:27:12 verghese Exp $"; +#endif + +/* + * $Log: printf.c,v $ + * Revision 1.1.1.1 1997/10/30 23:27:12 verghese + * current 10/29/97 + * + * Revision 1.1 1995/06/26 21:09:35 berc + * Initial revision + * + * Revision 1.8 1994/10/06 20:29:08 fdh + * Corrected unsigned long declaration. + * + * Revision 1.7 1994/08/05 20:16:23 fdh + * Updated Copyright header and RCS $Id: identifier. + * + * Revision 1.6 1994/06/21 15:41:54 rusling + * fixedup WNT compiler warnings + * + * Revision 1.5 1994/06/17 19:35:37 fdh + * Clean-up... + * + * Revision 1.4 1994/01/19 10:40:08 rusling + * Ported to Alpha Windows NT. + * + * Revision 1.3 1993/11/02 21:57:45 fdh + * Fixed sign extension problem introduced in version 1.2 + * + * Revision 1.2 1993/10/13 15:29:02 rusling + * Added floating point support in printf. This meant adding variable arguments to + * it and FormatItem() and including stdarg.h. + * + * Revision 1.1 1993/06/08 19:56:24 fdh + * Initial revision + * + */ + + + +/* printf.c + L. S. + Sun Feb 10 20:18:22 1985 + */ + +#include "system.h" +#include "lib.h" +#include <stdarg.h> + + + + + +/* The string s is terminated by a '\0' */ +void PutString(char *s) +{ + while (*s) PutChar(*s++); +} + +/* print c count times */ +void PutRepChar(char c, int count) +{ + while (count--) PutChar(c); +} + +/* put string reverse */ +void PutStringReverse(char *s, int index) +{ + while ((index--) > 0) PutChar(s[index]); +} + +/* prints value in radix, in a field width width, with fill + character fill + if radix is negative, print as signed quantity + if width is negative, left justify + if width is 0, use whatever is needed + if fill is 0, use ' ' + */ +void PutNumber(sl value, int radix, int width, char fill) +{ + char buffer[40]; + ui bufferindex = 0; + ul uvalue; + uw digit; + uw left = FALSE; + uw negative = FALSE; + + if (fill == 0) fill = ' '; + + if (width < 0) { + width = -width; + left = TRUE; + } + if (width < 0 || width > 80) width = 0; + + if (radix < 0) { + radix = -radix; + if (value < 0) { + negative = TRUE; + value = -value; + } + } + switch (radix) { + case 8: + case 10: + case 16: break; + default: { + PutString("****"); + return; + } + } + uvalue = value; + do { + if (radix != 16) + { + digit = (uw)(uvalue % radix); + uvalue /= radix; + } + else + { + digit = (uw)(uvalue & 0xf); + uvalue = uvalue >> 4; + } + buffer[bufferindex] = digit + ((digit <= 9) ? '0' : ('A' - 10)); + bufferindex += 1; + } while (uvalue != 0); + /* fill # ' ' and negative cannot happen at once */ + if (negative) { + buffer[bufferindex] = '-'; + bufferindex += 1; + } + if ((ui)width <= bufferindex) PutStringReverse(buffer, bufferindex); + else { + width -= bufferindex; + if (!left) PutRepChar(fill, width); + PutStringReverse(buffer, bufferindex); + if (left) PutRepChar(fill, width); + } +} + +ul power(long base, long n) +{ + ul p; + + for (p = 1; n > 0; --n) + p = p * base; + return p; +} + +void putFloat(double a, int fieldwidth, char fill) +{ + int i; + ul b; + +/* + * Put out everything before the decimal place. + */ + PutNumber(((ul) a), 10, fieldwidth, fill); +/* + * Output the decimal place. + */ + PutChar('.' & 0x7f); +/* + * Output the n digits after the decimal place. + */ + for (i = 1; i < 6; i++) { + b = (ul)(power(10, i) * (double)(a - (ul) a)); + PutChar((char)(b % 10) + '0'); + } +} +char *FormatItem(char *f, va_list *ap) +{ + char c; + int fieldwidth = 0; + int leftjust = FALSE; + int radix = 0; + char fill = ' '; + if (*f == '0') fill = '0'; + while (c = *f++) { + if (c >= '0' && c <= '9') { + fieldwidth = (fieldwidth * 10) + (c - '0'); + } + else switch (c) { + case '\000': return(--f); + case '%': PutChar('%'); + return(f); + case '-': leftjust = TRUE; + break; + case 'c': { + char a = va_arg(*ap, char); + + if (leftjust) PutChar(a & 0x7f); + if (fieldwidth > 0) PutRepChar(fill, fieldwidth - 1); + if (!leftjust) PutChar(a & 0x7f); + return(f); + } + case 's': { + char *a = va_arg(*ap, char *); + + if (leftjust) PutString((char *) a); + if (fieldwidth > strlen((char *) a)) + PutRepChar(fill, fieldwidth - strlen((char *)a)); + if (!leftjust) PutString((char *) a); + return(f); + } + case 'd': radix = -10; + break; + case 'u': radix = 10; + break; + case 'x': radix = 16; + break; + case 'X': radix = 16; + break; + case 'o': radix = 8; + break; + case 'f': { + double a = va_arg(*ap, double); + + putFloat(a, fieldwidth, fill); + return(f); + } + default: /* unknown switch! */ + radix = 3; + break; + } + if (radix) break; + } + if (leftjust) fieldwidth = -fieldwidth; + { + sl a = va_arg(*ap, sl); + PutNumber(a, radix, fieldwidth, fill); + } + return(f); +} + +void printf(char *f, ...) +{ + va_list ap; + + va_start(ap, f); + + while (*f) { + if (*f == '%') f = FormatItem(f + 1, &ap); + else PutChar(*f++); + } + + if (*(f-1)=='\n') { + /* add a line-feed (SimOS console output goes to shell */ + PutChar('\r'); + } + + va_end(ap); /* clean up */ +} + +void panic(char *f, ...) +{ + va_list ap; + + va_start(ap, f); + + printf("CONSOLE PANIC (looping): "); + while (*f) { + if (*f == '%') f = FormatItem(f + 1, &ap); + else PutChar(*f++); + } + + va_end(ap); /* clean up */ + while(1); +} + + |