summaryrefslogtreecommitdiff
path: root/system/alpha/console/printf.c
diff options
context:
space:
mode:
Diffstat (limited to 'system/alpha/console/printf.c')
-rw-r--r--system/alpha/console/printf.c298
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);
+}
+
+