/* Dumb printing routines Copyright (C) 1996 Pete A. Zaitcev 1997 Jakub Jelinek 2001 Ben Collins This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "promlib.h" #include /* * This part is rewritten by Igor Timkin . Than I * rewritten it again but kept the MISS style, originated from * Wladimir Butenko. --P3 */ #define OBSIZE 200 #ifndef NULL #define NULL (void *)0 #endif static void putchar_1 (char c) { /* P3: This buffer can be static while xprintf flushes it on exit. */ static char buff[OBSIZE + 1]; static int ox; if ((buff[ox] = c) == 0) { prom_puts (buff, ox); ox = 0; } else { if (++ox >= OBSIZE) { buff[ox] = 0; prom_puts (buff, ox); ox = 0; } } } int putchar (int __c) { char c = (char) __c; if (c == '\n') putchar_1 ('\r'); putchar_1 (c); return __c; } /* * Print an unsigned integer in base b, avoiding recursion. */ static int printn (long long n, int b) { static char prbuf[33]; register char *cp; int count = 0; if (b == 10 && n < 0) { putchar ('-'); count++; n = -n; } cp = prbuf; do *cp++ = "0123456789ABCDEF"[(unsigned int) (((unsigned long)n) % b)]; while ((n = ((unsigned long long)n) / b & 0x0FFFFFFFFFFFFFFFULL)); do { putchar (*--cp); count++; } while (cp > prbuf); return count; } int vprintf (char *fmt, va_list adx) { register int c; char *s; int count = 0; for (;;) { while ((c = *fmt++) != '%') { if (c == '\0') { putchar (0); return count; } putchar (c); } c = *fmt++; if (c == 'd' || c == 'o' || c == 'x' || c == 'X') { count += printn ((long long) va_arg (adx, unsigned), c == 'o' ? 8 : (c == 'd' ? 10 : 16)); } else if (c == 'c') { putchar (va_arg (adx, unsigned)); count++; } else if (c == 's') { if ((s = va_arg (adx, char *)) == NULL) s = (char *)"(null)"; while ((c = *s++)) { putchar (c); count++; } } else if (c == 'l' || c == 'O') { count += printn ((long long) va_arg (adx, long), c == 'l' ? 10 : 8); } else if (c == 'L') { int hex = 0; if (*fmt == 'x') { fmt++; hex = 1; } count += printn ((long long) va_arg (adx, long long), hex ? 16 : 10); } else { /* This is basically what libc's printf does */ putchar('%'); putchar(c); count += 2; } } return count; } /* * Scaled down version of C Library printf. * Only %c %s %d (==%u) %o %x %X %l %O are recognized. */ void prom_printf (char *fmt,...) { va_list x1; va_start (x1, fmt); vprintf (fmt, x1); va_end (x1); } static int sprintn (char *str, long long n, int b) { static char prbuf[33]; register char *cp; int count = 0; if (b == 10 && n < 0) { memset (str + count, '-', 1); count++; n = -n; } cp = prbuf; do *cp++ = "0123456789ABCDEF"[(unsigned int) (((unsigned long)n) % b)]; while ((n = ((unsigned long long)n) / b & 0x0FFFFFFFFFFFFFFFULL)); do { memset (str + count, *--cp, 1); count++; } while (cp > prbuf); return count; } int vsprintf (char *str, char *fmt, va_list adx) { register int c; char *s; int count = 0; for (;;) { while ((c = *fmt++) != '%') { memset (str + count, c, 1); if (c == '\0') { return count; } } c = *fmt++; if (c == 'd' || c == 'o' || c == 'x' || c == 'X') { count += sprintn (str + count, (long long) va_arg (adx, unsigned), c == 'o' ? 8 : (c == 'd' ? 10 : 16)); } else if (c == 'c') { memset (str + count, va_arg (adx, unsigned), 1); count++; } else if (c == 's') { if ((s = va_arg (adx, char *)) == NULL) s = (char *)"(null)"; while ((c = *s++)) { memset (str + count, c, 1); count++; } } else if (c == 'l' || c == 'O') { count += sprintn (str + count, (long long) va_arg (adx, long), c == 'l' ? 10 : 8); } else if (c == 'L') { int hex = 0; if (*fmt == 'x') { fmt++; hex = 1; } count += sprintn (str + count, (long long) va_arg (adx, long long), hex ? 16 : 10); } else { /* This is basically what libc's printf does */ memset (str + count, '%', 1); count++; memset (str + count, c, 1); count++; } } return count; } /* * Scaled down version of C Library sprintf. * Only %c %s %d (==%u) %o %x %X %l %O are recognized. */ int sprintf (char *s, char *format, ...) { va_list arg; int done; va_start (arg, format); done = vsprintf (s, format, arg); va_end (arg); return done; } .