X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/1c79356b52d46aa6b508fb032f5ae709b1f2897b..13fec9890cf095cc781fdf7b8917cb03bf32dd4c:/bsd/kern/subr_prf.c diff --git a/bsd/kern/subr_prf.c b/bsd/kern/subr_prf.c index 814ac7056..3b77fb394 100644 --- a/bsd/kern/subr_prf.c +++ b/bsd/kern/subr_prf.c @@ -77,20 +77,18 @@ #include #include -#include #include #include #include -#include +#include #include #include -#include +#include #include #include #include #include #include -#include #include #include /* for cpu_number() */ @@ -115,6 +113,11 @@ int (*v_putc)() = cnputc; /* routine to putc on virtual console */ extern struct tty cons; /* standard console tty */ extern struct tty *constty; /* pointer to console "window" tty */ +extern int __doprnt(const char *fmt, + va_list *argp, + void (*putc)(int, void *arg), + void *arg, + int radix); /* * Record cpu that panic'd and lock around panic data @@ -123,8 +126,6 @@ extern struct tty *constty; /* pointer to console "window" tty */ static void puts(const char *s, int flags, struct tty *ttyp); static void printn(u_long n, int b, int flags, struct tty *ttyp, int zf, int fld_size); -/* MP printf stuff */ -decl_simple_lock_data(,printf_lock) #if NCPUS > 1 boolean_t new_printf_cpu_number; /* do we need to output who we are */ #endif @@ -132,11 +133,16 @@ boolean_t new_printf_cpu_number; /* do we need to output who we are */ extern void logwakeup(); extern void halt_cpu(); extern boot(); -int putchar(); + static void snprintf_func(int ch, void *arg); +struct putchar_args { + int flags; + struct tty *tty; +}; +static void putchar(int c, void *arg); /* @@ -148,28 +154,27 @@ void uprintf(const char *fmt, ...) { register struct proc *p = current_proc(); + struct putchar_args pca; va_list ap; + + pca.flags = TOTTY; + pca.tty = (struct tty *)p->p_session->s_ttyp; - unix_master(); /* sessions, sigh */ if (p->p_flag & P_CONTROLT && p->p_session->s_ttyvp) { va_start(ap, fmt); - prf(fmt, ap, TOTTY, (struct tty *)p->p_session->s_ttyvp); + __doprnt(fmt, &ap, putchar, &pca, 10); va_end(ap); } - unix_release(); } tpr_t tprintf_open(p) register struct proc *p; { - unix_master(); /* sessions, sigh */ if (p->p_flag & P_CONTROLT && p->p_session->s_ttyvp) { SESSHOLD(p->p_session); - unix_release(); return ((tpr_t) p->p_session); } - unix_release(); return ((tpr_t) NULL); } @@ -177,10 +182,8 @@ void tprintf_close(sess) tpr_t sess; { - unix_master(); /* sessions, sigh */ if (sess) SESSRELE((struct session *) sess); - unix_release(); } /* @@ -194,19 +197,20 @@ tprintf(tpr_t tpr, const char *fmt, ...) struct tty *tp = NULL; int flags = TOLOG; va_list ap; + struct putchar_args pca; logpri(LOG_INFO); - unix_master(); /* sessions, sigh */ if (sess && sess->s_ttyvp && ttycheckoutq(sess->s_ttyp, 0)) { flags |= TOTTY; tp = sess->s_ttyp; } - if (tp != NULL) { - va_start(ap, fmt); - prf(fmt, ap, TOTTY, tp); - va_end(ap); - } - unix_release(); + + pca.flags = flags; + pca.tty = tp; + va_start(ap, fmt); + __doprnt(fmt, &ap, putchar, &pca, 10); + va_end(ap); + logwakeup(); } @@ -221,8 +225,12 @@ ttyprintf(struct tty *tp, const char *fmt, ...) va_list ap; if (tp != NULL) { + struct putchar_args pca; + pca.flags = TOTTY; + pca.tty = tp; + va_start(ap, fmt); - prf(fmt, ap, TOTTY, tp); + __doprnt(fmt, &ap, putchar, &pca, 10); va_end(ap); } } @@ -234,10 +242,13 @@ void logpri(level) int level; { - - putchar('<', TOLOG, (struct tty *)0); + struct putchar_args pca; + pca.flags = TOLOG; + pca.tty = NULL; + + putchar('<', &pca); printn((u_long)level, 10, TOLOG, (struct tty *)0, 0, 0); - putchar('>', TOLOG, (struct tty *)0); + putchar('>', &pca); } void @@ -245,256 +256,80 @@ addlog(const char *fmt, ...) { register s = splhigh(); va_list ap; + struct putchar_args pca; + + pca.flags = TOLOG; + pca.tty = NULL; va_start(ap, fmt); - prf(fmt, ap, TOLOG, (struct tty *)0); + __doprnt(fmt, &ap, putchar, &pca, 10); + splx(s); - if (!log_open) - prf(fmt, ap, TOCONS, (struct tty *)0); + if (!log_open) { + pca.flags = TOCONS; + __doprnt(fmt, &ap, putchar, &pca, 10); + } va_end(ap); logwakeup(); } void _printf(int flags, struct tty *ttyp, const char *format, ...) { va_list ap; + struct putchar_args pca; + + pca.flags = flags; + pca.tty = ttyp; va_start(ap, format); - prf(format, ap, flags, ttyp); + __doprnt(format, &ap, putchar, &pca, 10); va_end(ap); } int prf(const char *fmt, va_list ap, int flags, struct tty *ttyp) { - register int b, c, i; - char *s; - int any; - int zf = 0, fld_size; - -#if NCPUS > 1 - int cpun = cpu_number(); + struct putchar_args pca; - if(ttyp == 0) { - simple_lock(&printf_lock); + pca.flags = flags; + pca.tty = ttyp; + +#if NCPUS > 1 + int cpun = cpu_number(); + + if(ttyp == 0) { } else TTY_LOCK(ttyp); - + if (cpun != master_cpu) - new_printf_cpu_number = TRUE; + new_printf_cpu_number = TRUE; if (new_printf_cpu_number) { putchar('{', flags, ttyp); printn((u_long)cpun, 10, flags, ttyp, 0, 0); putchar('}', flags, ttyp); } -#endif /* NCPUS > 1 */ -loop: - while ((c = *fmt++) != '%') { - if (c == '\0') { -#if NCPUS > 1 - if(ttyp == 0) { - simple_unlock(&printf_lock); - } else - TTY_UNLOCK(ttyp); -#endif - return 0; - } - putchar(c, flags, ttyp); - } -again: - zf = 0; - fld_size = 0; - c = *fmt++; - if (c == '0') - zf = '0'; - fld_size = 0; - for (;c <= '9' && c >= '0'; c = *fmt++) - fld_size = fld_size * 10 + c - '0'; - - /* THIS CODE IS VAX DEPENDENT IN HANDLING %l? AND %c */ - switch (c) { - - case 'l': - goto again; - case 'x': case 'X': - b = 16; - goto number; - case 'd': case 'D': - case 'u': /* what a joke */ - b = 10; - goto number; - case 'o': case 'O': - b = 8; -number: - printn(va_arg(ap, unsigned), b, flags, ttyp, zf, fld_size); - break; - case 'c': - b = va_arg(ap, unsigned); -#if BYTE_ORDER == LITTLE_ENDIAN - for (i = 24; i >= 0; i -= 8) - if (c = (b >> i) & 0x7f) - putchar(c, flags, ttyp); -#endif -#if BYTE_ORDER == BIG_ENDIAN - if ((c = (b & 0x7f))) - putchar(c, flags, ttyp); -#endif - break; - case 'b': - b = va_arg(ap, unsigned); - s = va_arg(ap, char *); - printn((u_long)b, *s++, flags, ttyp, 0, 0); - any = 0; - if (b) { - while ((i = *s++)) { - if (*s <= 32) { - register int j; - - if (any++) - putchar(',', flags, ttyp); - j = *s++ ; - for (; (c = *s) > 32 ; s++) - putchar(c, flags, ttyp); - printn( (u_long)( (b >> (j-1)) & - ( (2 << (i-j)) -1)), - 8, flags, ttyp, 0, 0); - } else if (b & (1 << (i-1))) { - putchar(any? ',' : '<', flags, ttyp); - any = 1; - for (; (c = *s) > 32; s++) - putchar(c, flags, ttyp); - } else - for (; *s > 32; s++) - ; - } - putchar('>', flags, ttyp); - } - break; - - case 's': - s = va_arg(ap, char *); -#ifdef DEBUG - if (fld_size) { - while (fld_size-- > 0) - putchar((c = *s++)? c : '_', flags, ttyp); - } else { - while ((c = *s++)) - putchar(c, flags, ttyp); - } -#else - while (c = *s++) - putchar(c, flags, ttyp); -#endif - break; - - case '%': - putchar('%', flags, ttyp); - goto loop; - case 'C': - b = va_arg(ap, unsigned); -#if BYTE_ORDER == LITTLE_ENDIAN - for (i = 24; i >= 0; i -= 8) - if (c = (b >> i) & 0x7f) - putchar(c, flags, ttyp); -#endif -#if BYTE_ORDER == BIG_ENDIAN - if ((c = (b & 0x7f))) - putchar(c, flags, ttyp); -#endif +#endif /* NCPUS > 1 */ + + __doprnt(fmt, &ap, putchar, &pca, 10); - case 'r': - case 'R': - b = va_arg(ap, unsigned); - s = va_arg(ap, char *); - if (c == 'R') { - puts("0x", flags, ttyp); - printn((u_long)b, 16, flags, ttyp, 0, 0); - } - any = 0; - if (c == 'r' || b) { - register struct reg_desc *rd; - register struct reg_values *rv; - unsigned field; - - putchar('<', flags, ttyp); - for (rd = (struct reg_desc *)s; rd->rd_mask; rd++) { - field = b & rd->rd_mask; - field = (rd->rd_shift > 0) - ? field << rd->rd_shift - : field >> -rd->rd_shift; - if (any && - (rd->rd_format || rd->rd_values - || (rd->rd_name && field) - ) - ) - putchar(',', flags, ttyp); - if (rd->rd_name) { - if (rd->rd_format || rd->rd_values - || field) { - puts(rd->rd_name, flags, ttyp); - any = 1; - } - if (rd->rd_format || rd->rd_values) { - putchar('=', flags, ttyp); - any = 1; - } - } - if (rd->rd_format) { - _printf(flags, ttyp, rd->rd_format, - field); - any = 1; - if (rd->rd_values) - putchar(':', flags, ttyp); - } - if (rd->rd_values) { - any = 1; - for (rv = rd->rd_values; - rv->rv_name; - rv++) { - if (field == rv->rv_value) { - puts(rv->rv_name, flags, - ttyp); - break; - } - } - if (rv->rv_name == NULL) - puts("???", flags, ttyp); - } - } - putchar('>', flags, ttyp); - } - break; - - case 'n': - case 'N': - { - register struct reg_values *rv; - - b = va_arg(ap, unsigned); - s = va_arg(ap,char *); - for (rv = (struct reg_values *)s; rv->rv_name; rv++) { - if (b == rv->rv_value) { - puts(rv->rv_name, flags, ttyp); - break; - } - } - if (rv->rv_name == NULL) - puts("???", flags, ttyp); - if (c == 'N' || rv->rv_name == NULL) { - putchar(':', flags, ttyp); - printn((u_long)b, 10, flags, ttyp, 0, 0); - } - } - break; - } - goto loop; +#if NCPUS > 1 + if(ttyp == 0) { + } else + TTY_UNLOCK(ttyp); +#endif + + return 0; } static void puts(const char *s, int flags, struct tty *ttyp) { register char c; + struct putchar_args pca; + + pca.flags = flags; + pca.tty = ttyp; while ((c = *s++)) - putchar(c, flags, ttyp); + putchar(c, &pca); } /* @@ -505,9 +340,13 @@ static void printn(u_long n, int b, int flags, struct tty *ttyp, int zf, int fld { char prbuf[11]; register char *cp; + struct putchar_args pca; + + pca.flags = flags; + pca.tty = ttyp; if (b == 10 && (int)n < 0) { - putchar('-', flags, ttyp); + putchar('-', &pca); n = (unsigned)(-(int)n); } cp = prbuf; @@ -518,12 +357,12 @@ static void printn(u_long n, int b, int flags, struct tty *ttyp, int zf, int fld if (fld_size) { for (fld_size -= cp - prbuf; fld_size > 0; fld_size--) if (zf) - putchar('0', flags, ttyp); + putchar('0', &pca); else - putchar(' ', flags, ttyp); + putchar(' ', &pca); } do - putchar(*--cp, flags, ttyp); + putchar(*--cp, &pca); while (cp > prbuf); } @@ -543,32 +382,30 @@ void tablefull(const char *tab) * are saved in msgbuf for inspection later. */ /*ARGSUSED*/ -int -putchar(c, flags, tp) - register int c; - struct tty *tp; +void +putchar(int c, void *arg) { + struct putchar_args *pca = arg; register struct msgbuf *mbp; - char **sp = (char**) tp; + char **sp = (char**) pca->tty; if (panicstr) constty = 0; - if ((flags & TOCONS) && tp == NULL && constty) { - tp = constty; - flags |= TOTTY; + if ((pca->flags & TOCONS) && pca->tty == NULL && constty) { + pca->tty = constty; + pca->flags |= TOTTY; } - if ((flags & TOTTY) && tp && tputchar(c, tp) < 0 && - (flags & TOCONS) && tp == constty) + if ((pca->flags & TOTTY) && pca->tty && tputchar(c, pca->tty) < 0 && + (pca->flags & TOCONS) && pca->tty == constty) constty = 0; - if ((flags & TOLOG) && c != '\0' && c != '\r' && c != 0177) + if ((pca->flags & TOLOG) && c != '\0' && c != '\r' && c != 0177) log_putc(c); - if ((flags & TOCONS) && constty == 0 && c != '\0') + if ((pca->flags & TOCONS) && constty == 0 && c != '\0') (*v_putc)(c); - if (flags & TOSTR) { + if (pca->flags & TOSTR) { **sp = c; (*sp)++; } - return 0; } @@ -580,10 +417,16 @@ int vsprintf(char *buf, const char *cfmt, va_list ap) { int retval; + struct snprintf_arg info; - retval = kvprintf(cfmt, NULL, (void *)buf, 10, ap); - buf[retval] = '\0'; - return retval; + info.str = buf; + info.remain = 999999; + + retval = __doprnt(cfmt, &ap, snprintf_func, &info, 10); + if (info.remain >= 1) { + *info.str++ = '\0'; + } + return 0; } /* @@ -612,7 +455,7 @@ vsnprintf(char *str, size_t size, const char *format, va_list ap) info.str = str; info.remain = size; - retval = kvprintf(format, snprintf_func, &info, 10, ap); + retval = __doprnt(format, &ap, snprintf_func, &info, 10); if (info.remain >= 1) *info.str++ = '\0'; return retval; @@ -629,274 +472,10 @@ snprintf_func(int ch, void *arg) } } -/* - * Put a number (base <= 16) in a buffer in reverse order; return an - * optional length and a pointer to the NULL terminated (preceded?) - * buffer. - */ -static char * -ksprintn(ul, base, lenp) - register u_long ul; - register int base, *lenp; -{ /* A long in base 8, plus NULL. */ - static char buf[sizeof(long) * NBBY / 3 + 2]; - register char *p; - - p = buf; - do { - *++p = hex2ascii(ul % base); - } while (ul /= base); - if (lenp) - *lenp = p - buf; - return (p); -} - -/* - * Scaled down version of printf(3). - * - * Two additional formats: - * - * The format %b is supported to decode error registers. - * Its usage is: - * - * printf("reg=%b\n", regval, "*"); - * - * where is the output base expressed as a control character, e.g. - * \10 gives octal; \20 gives hex. Each arg is a sequence of characters, - * the first of which gives the bit number to be inspected (origin 1), and - * the next characters (up to a control character, i.e. a character <= 32), - * give the name of the register. Thus: - * - * kvprintf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n"); - * - * would produce output: - * - * reg=3 - * - * XXX: %D -- Hexdump, takes pointer and separator string: - * ("%6D", ptr, ":") -> XX:XX:XX:XX:XX:XX - * ("%*D", len, ptr, " " -> XX XX XX XX ... - */ int kvprintf(char const *fmt, void (*func)(int, void*), void *arg, int radix, va_list ap) { -#define PCHAR(c) {int cc=(c); if (func) (*func)(cc,arg); else *d++ = cc; retval++; } - char *p, *q, *d; - u_char *up; - int ch, n; - u_long ul; - int base, lflag, tmp, width, ladjust, sharpflag, neg, sign, dot; - int dwidth; - char padc; - int retval = 0; - - if (!func) - d = (char *) arg; - else - d = NULL; - - if (fmt == NULL) - fmt = "(fmt null)\n"; - - if (radix < 2 || radix > 36) - radix = 10; - - for (;;) { - padc = ' '; - width = 0; - while ((ch = (u_char)*fmt++) != '%') { - if (ch == '\0') - return retval; - PCHAR(ch); - } - lflag = 0; ladjust = 0; sharpflag = 0; neg = 0; - sign = 0; dot = 0; dwidth = 0; -reswitch: switch (ch = (u_char)*fmt++) { - case '.': - dot = 1; - goto reswitch; - case '#': - sharpflag = 1; - goto reswitch; - case '+': - sign = 1; - goto reswitch; - case '-': - ladjust = 1; - goto reswitch; - case '%': - PCHAR(ch); - break; - case '*': - if (!dot) { - width = va_arg(ap, int); - if (width < 0) { - ladjust = !ladjust; - width = -width; - } - } else { - dwidth = va_arg(ap, int); - } - goto reswitch; - case '0': - if (!dot) { - padc = '0'; - goto reswitch; - } - case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - for (n = 0;; ++fmt) { - n = n * 10 + ch - '0'; - ch = *fmt; - if (ch < '0' || ch > '9') - break; - } - if (dot) - dwidth = n; - else - width = n; - goto reswitch; - case 'b': - ul = va_arg(ap, int); - p = va_arg(ap, char *); - for (q = ksprintn(ul, *p++, NULL); *q;) - PCHAR(*q--); - - if (!ul) - break; - - for (tmp = 0; *p;) { - n = *p++; - if (ul & (1 << (n - 1))) { - PCHAR(tmp ? ',' : '<'); - for (; (n = *p) > ' '; ++p) - PCHAR(n); - tmp = 1; - } else - for (; *p > ' '; ++p) - continue; - } - if (tmp) - PCHAR('>'); - break; - case 'c': - PCHAR(va_arg(ap, int)); - break; - case 'D': - up = va_arg(ap, u_char *); - p = va_arg(ap, char *); - if (!width) - width = 16; - while(width--) { - PCHAR(hex2ascii(*up >> 4)); - PCHAR(hex2ascii(*up & 0x0f)); - up++; - if (width) - for (q=p;*q;q++) - PCHAR(*q); - } - break; - case 'd': - ul = lflag ? va_arg(ap, long) : va_arg(ap, int); - sign = 1; - base = 10; - goto number; - case 'l': - lflag = 1; - goto reswitch; - case 'o': - ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int); - base = 8; - goto nosign; - case 'p': - ul = (uintptr_t)va_arg(ap, void *); - base = 16; - sharpflag = (width == 0); - goto nosign; - case 'n': - case 'r': - ul = lflag ? va_arg(ap, u_long) : - sign ? (u_long)va_arg(ap, int) : va_arg(ap, u_int); - base = radix; - goto number; - case 's': - p = va_arg(ap, char *); - if (p == NULL) - p = "(null)"; - if (!dot) - n = strlen (p); - else - for (n = 0; n < dwidth && p[n]; n++) - continue; - - width -= n; - - if (!ladjust && width > 0) - while (width--) - PCHAR(padc); - while (n--) - PCHAR(*p++); - if (ladjust && width > 0) - while (width--) - PCHAR(padc); - break; - case 'u': - ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int); - base = 10; - goto nosign; - case 'x': - ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int); - base = 16; - goto nosign; - case 'z': - ul = lflag ? va_arg(ap, u_long) : - sign ? (u_long)va_arg(ap, int) : va_arg(ap, u_int); - base = 16; - goto number; -nosign: sign = 0; -number: if (sign && (long)ul < 0L) { - neg = 1; - ul = -(long)ul; - } - p = ksprintn(ul, base, &tmp); - if (sharpflag && ul != 0) { - if (base == 8) - tmp++; - else if (base == 16) - tmp += 2; - } - if (neg) - tmp++; - - if (!ladjust && width && (width -= tmp) > 0) - while (width--) - PCHAR(padc); - if (neg) - PCHAR('-'); - if (sharpflag && ul != 0) { - if (base == 8) { - PCHAR('0'); - } else if (base == 16) { - PCHAR('0'); - PCHAR('x'); - } - } - - while (*p) - PCHAR(*p--); - - if (ladjust && width && (width -= tmp) > 0) - while (width--) - PCHAR(padc); - - break; - default: - PCHAR('%'); - if (lflag) - PCHAR('l'); - PCHAR(ch); - break; - } - } -#undef PCHAR + __doprnt(fmt, &ap, func, arg, radix); + return 0; } +