1 /* $NetBSD: subr_prf.c,v 1.47 1997/11/17 00:59:56 ross Exp $ */ 2 3 /*- 4 * Copyright (c) 1986, 1988, 1991, 1993 5 * The Regents of the University of California. All rights reserved. 6 * (c) UNIX System Laboratories, Inc. 7 * All or some portions of this file are derived from material licensed 8 * to the University of California by American Telephone and Telegraph 9 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 10 * the permission of UNIX System Laboratories, Inc. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 3. All advertising materials mentioning features or use of this software 21 * must display the following acknowledgement: 22 * This product includes software developed by the University of 23 * California, Berkeley and its contributors. 24 * 4. Neither the name of the University nor the names of its contributors 25 * may be used to endorse or promote products derived from this software 26 * without specific prior written permission. 27 * 28 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 31 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 38 * SUCH DAMAGE. 39 * 40 * @(#)subr_prf.c 8.3 (Berkeley) 1/21/94 41 */ 42 43 #include <sys/param.h> 44 #include <sys/systm.h> 45 #include <sys/buf.h> 46 #include <sys/conf.h> 47 #include <sys/reboot.h> 48 #include <sys/msgbuf.h> 49 #include <sys/proc.h> 50 #include <sys/ioctl.h> 51 #include <sys/vnode.h> 52 #include <sys/file.h> 53 #include <sys/tty.h> 54 #include <sys/tprintf.h> 55 #include <sys/syslog.h> 56 #include <sys/malloc.h> 57 58 #include <dev/cons.h> 59 60 /* 61 * note that stdarg.h and the ansi style va_start macro is used for both 62 * ansi and traditional c complers. 63 * XXX: this requires that stdarg.h define: va_alist and va_dcl 64 */ 65 #include <machine/stdarg.h> 66 67 #include "ipkdb.h" 68 69 #ifdef KGDB 70 #include <sys/kgdb.h> 71 #include <machine/cpu.h> 72 #endif 73 #ifdef DDB 74 #include <ddb/db_output.h> /* db_printf, db_putchar prototypes */ 75 extern int db_radix; /* XXX: for non-standard '%r' format */ 76 #endif 77 78 79 /* 80 * defines 81 */ 82 83 /* flags for kprintf */ 84 #define TOCONS 0x01 /* to the console */ 85 #define TOTTY 0x02 /* to the process' tty */ 86 #define TOLOG 0x04 /* to the kernel message buffer */ 87 #define TOBUFONLY 0x08 /* to the buffer (only) [for sprintf] */ 88 #define TODDB 0x10 /* to ddb console */ 89 90 /* max size buffer kprintf needs to print quad_t [size in base 8 + \0] */ 91 #define KPRINTF_BUFSIZE (sizeof(quad_t) * NBBY / 3 + 2) 92 93 94 /* 95 * local prototypes 96 */ 97 98 static int kprintf __P((const char *, int, struct tty *, 99 char *, va_list)); 100 static void putchar __P((int, int, struct tty *)); 101 102 103 /* 104 * globals 105 */ 106 107 struct tty *constty; /* pointer to console "window" tty */ 108 int consintr = 1; /* ok to handle console interrupts? */ 109 extern int log_open; /* subr_log: is /dev/klog open? */ 110 const char *panicstr; /* arg to first call to panic (used as a flag 111 to indicate that panic has already been called). */ 112 113 /* 114 * v_putc: routine to putc on virtual console 115 * 116 * the v_putc pointer can be used to redirect the console cnputc elsewhere 117 * [e.g. to a "virtual console"]. 118 */ 119 120 void (*v_putc) __P((int)) = cnputc; /* start with cnputc (normal cons) */ 121 122 123 /* 124 * functions 125 */ 126 127 /* 128 * tablefull: warn that a system table is full 129 */ 130 131 void 132 tablefull(tab) 133 const char *tab; 134 { 135 log(LOG_ERR, "%s: table is full\n", tab); 136 } 137 138 /* 139 * panic: handle an unresolvable fatal error 140 * 141 * prints "panic: <message>" and reboots. if called twice (i.e. recursive 142 * call) we avoid trying to sync the disk and just reboot (to avoid 143 * recursive panics). 144 */ 145 146 void 147 #ifdef __STDC__ 148 panic(const char *fmt, ...) 149 #else 150 panic(fmt, va_alist) 151 char *fmt; 152 va_dcl 153 #endif 154 { 155 int bootopt; 156 va_list ap; 157 158 bootopt = RB_AUTOBOOT | RB_DUMP; 159 if (panicstr) 160 bootopt |= RB_NOSYNC; 161 else 162 panicstr = fmt; 163 164 va_start(ap, fmt); 165 printf("panic: "); 166 vprintf(fmt, ap); 167 printf("\n"); 168 va_end(ap); 169 170 #if NIPKDB > 0 171 ipkdb_panic(); 172 #endif 173 #ifdef KGDB 174 kgdb_panic(); 175 #endif 176 #ifdef KADB 177 if (boothowto & RB_KDB) 178 kdbpanic(); 179 #endif 180 #ifdef DDB 181 if (db_onpanic) 182 Debugger(); 183 #endif 184 cpu_reboot(bootopt, NULL); 185 } 186 187 /* 188 * kernel logging functions: log, logpri, addlog 189 */ 190 191 /* 192 * log: write to the log buffer 193 * 194 * => will not sleep [so safe to call from interrupt] 195 * => will log to console if /dev/klog isn't open 196 */ 197 198 void 199 #ifdef __STDC__ 200 log(int level, const char *fmt, ...) 201 #else 202 log(level, fmt, va_alist) 203 int level; 204 char *fmt; 205 va_dcl 206 #endif 207 { 208 register int s; 209 va_list ap; 210 211 s = splhigh(); 212 logpri(level); /* log the level first */ 213 va_start(ap, fmt); 214 kprintf(fmt, TOLOG, NULL, NULL, ap); 215 splx(s); 216 va_end(ap); 217 if (!log_open) { 218 va_start(ap, fmt); 219 kprintf(fmt, TOCONS, NULL, NULL, ap); 220 va_end(ap); 221 } 222 logwakeup(); /* wake up anyone waiting for log msgs */ 223 } 224 225 /* 226 * logpri: log the priority level to the klog 227 */ 228 229 void /* XXXCDC: should be static? */ 230 logpri(level) 231 int level; 232 { 233 char *p; 234 char snbuf[KPRINTF_BUFSIZE]; 235 236 putchar('<', TOLOG, NULL); 237 sprintf(snbuf, "%d", level); 238 for (p = snbuf ; *p ; p++) 239 putchar(*p, TOLOG, NULL); 240 putchar('>', TOLOG, NULL); 241 } 242 243 /* 244 * addlog: add info to previous log message 245 */ 246 247 void 248 #ifdef __STDC__ 249 addlog(const char *fmt, ...) 250 #else 251 addlog(fmt, va_alist) 252 char *fmt; 253 va_dcl 254 #endif 255 { 256 register int s; 257 va_list ap; 258 259 s = splhigh(); 260 va_start(ap, fmt); 261 kprintf(fmt, TOLOG, NULL, NULL, ap); 262 splx(s); 263 va_end(ap); 264 if (!log_open) { 265 va_start(ap, fmt); 266 kprintf(fmt, TOCONS, NULL, NULL, ap); 267 va_end(ap); 268 } 269 logwakeup(); 270 } 271 272 273 /* 274 * putchar: print a single character on console or user terminal. 275 * 276 * => if console, then the last MSGBUFS chars are saved in msgbuf 277 * for inspection later (e.g. dmesg/syslog) 278 */ 279 static void 280 putchar(c, flags, tp) 281 register int c; 282 int flags; 283 struct tty *tp; 284 { 285 register struct kern_msgbuf *mbp; 286 287 if (panicstr) 288 constty = NULL; 289 if ((flags & TOCONS) && tp == NULL && constty) { 290 tp = constty; 291 flags |= TOTTY; 292 } 293 if ((flags & TOTTY) && tp && tputchar(c, tp) < 0 && 294 (flags & TOCONS) && tp == constty) 295 constty = NULL; 296 if ((flags & TOLOG) && 297 c != '\0' && c != '\r' && c != 0177 && msgbufenabled) { 298 mbp = msgbufp; 299 if (mbp->msg_magic != MSG_MAGIC) { 300 /* 301 * Arguably should panic or somehow notify the 302 * user... but how? Panic may be too drastic, 303 * and would obliterate the message being kicked 304 * out (maybe a panic itself), and printf 305 * would invoke us recursively. Silently punt 306 * for now. If syslog is running, it should 307 * notice. 308 */ 309 msgbufenabled = 0; 310 } else { 311 mbp->msg_bufc[mbp->msg_bufx++] = c; 312 if (mbp->msg_bufx < 0 || mbp->msg_bufx >= mbp->msg_bufs) 313 mbp->msg_bufx = 0; 314 } 315 } 316 if ((flags & TOCONS) && constty == NULL && c != '\0') 317 (*v_putc)(c); 318 #ifdef DDB 319 if (flags & TODDB) 320 db_putchar(c); 321 #endif 322 } 323 324 325 /* 326 * uprintf: print to the controlling tty of the current process 327 * 328 * => we may block if the tty queue is full 329 * => no message is printed if the queue doesn't clear in a reasonable 330 * time 331 */ 332 333 void 334 #ifdef __STDC__ 335 uprintf(const char *fmt, ...) 336 #else 337 uprintf(fmt, va_alist) 338 char *fmt; 339 va_dcl 340 #endif 341 { 342 register struct proc *p = curproc; 343 va_list ap; 344 345 if (p->p_flag & P_CONTROLT && p->p_session->s_ttyvp) { 346 va_start(ap, fmt); 347 kprintf(fmt, TOTTY, p->p_session->s_ttyp, NULL, ap); 348 va_end(ap); 349 } 350 } 351 352 /* 353 * tprintf functions: used to send messages to a specific process 354 * 355 * usage: 356 * get a tpr_t handle on a process "p" by using "tprintf_open(p)" 357 * use the handle when calling "tprintf" 358 * when done, do a "tprintf_close" to drop the handle 359 */ 360 361 /* 362 * tprintf_open: get a tprintf handle on a process "p" 363 * 364 * => returns NULL if process can't be printed to 365 */ 366 367 tpr_t 368 tprintf_open(p) 369 register struct proc *p; 370 { 371 372 if (p->p_flag & P_CONTROLT && p->p_session->s_ttyvp) { 373 SESSHOLD(p->p_session); 374 return ((tpr_t) p->p_session); 375 } 376 return ((tpr_t) NULL); 377 } 378 379 /* 380 * tprintf_close: dispose of a tprintf handle obtained with tprintf_open 381 */ 382 383 void 384 tprintf_close(sess) 385 tpr_t sess; 386 { 387 388 if (sess) 389 SESSRELE((struct session *) sess); 390 } 391 392 /* 393 * tprintf: given tprintf handle to a process [obtained with tprintf_open], 394 * send a message to the controlling tty for that process. 395 * 396 * => also sends message to /dev/klog 397 */ 398 void 399 #ifdef __STDC__ 400 tprintf(tpr_t tpr, const char *fmt, ...) 401 #else 402 tprintf(tpr, fmt, va_alist) 403 tpr_t tpr; 404 char *fmt; 405 va_dcl 406 #endif 407 { 408 register struct session *sess = (struct session *)tpr; 409 struct tty *tp = NULL; 410 int flags = TOLOG; 411 va_list ap; 412 413 logpri(LOG_INFO); 414 if (sess && sess->s_ttyvp && ttycheckoutq(sess->s_ttyp, 0)) { 415 flags |= TOTTY; 416 tp = sess->s_ttyp; 417 } 418 va_start(ap, fmt); 419 kprintf(fmt, flags, tp, NULL, ap); 420 va_end(ap); 421 logwakeup(); 422 } 423 424 425 /* 426 * ttyprintf: send a message to a specific tty 427 * 428 * => should be used only by tty driver or anything that knows the 429 * underlying tty will not be revoked(2)'d away. [otherwise, 430 * use tprintf] 431 */ 432 void 433 #ifdef __STDC__ 434 ttyprintf(struct tty *tp, const char *fmt, ...) 435 #else 436 ttyprintf(tp, fmt, va_alist) 437 struct tty *tp; 438 char *fmt; 439 va_dcl 440 #endif 441 { 442 va_list ap; 443 444 va_start(ap, fmt); 445 kprintf(fmt, TOTTY, tp, NULL, ap); 446 va_end(ap); 447 } 448 449 #ifdef DDB 450 451 /* 452 * db_printf: printf for DDB (via db_putchar) 453 */ 454 455 void 456 #ifdef __STDC__ 457 db_printf(const char *fmt, ...) 458 #else 459 db_printf(fmt, va_alist) 460 char *fmt; 461 va_dcl 462 #endif 463 { 464 va_list ap; 465 466 va_start(ap, fmt); 467 kprintf(fmt, TODDB, NULL, NULL, ap); 468 va_end(ap); 469 } 470 471 #endif /* DDB */ 472 473 474 /* 475 * normal kernel printf functions: printf, vprintf, sprintf 476 */ 477 478 /* 479 * printf: print a message to the console and the log 480 */ 481 void 482 #ifdef __STDC__ 483 printf(const char *fmt, ...) 484 #else 485 printf(fmt, va_alist) 486 char *fmt; 487 va_dcl 488 #endif 489 { 490 va_list ap; 491 int savintr; 492 493 savintr = consintr; /* disable interrupts */ 494 consintr = 0; 495 va_start(ap, fmt); 496 kprintf(fmt, TOCONS | TOLOG, NULL, NULL, ap); 497 va_end(ap); 498 if (!panicstr) 499 logwakeup(); 500 consintr = savintr; /* reenable interrupts */ 501 } 502 503 /* 504 * vprintf: print a message to the console and the log [already have 505 * va_alist] 506 */ 507 508 void 509 vprintf(fmt, ap) 510 const char *fmt; 511 va_list ap; 512 { 513 int savintr; 514 515 savintr = consintr; /* disable interrupts */ 516 consintr = 0; 517 kprintf(fmt, TOCONS | TOLOG, NULL, NULL, ap); 518 if (!panicstr) 519 logwakeup(); 520 consintr = savintr; /* reenable interrupts */ 521 } 522 523 /* 524 * sprintf: print a message to a buffer 525 */ 526 int 527 #ifdef __STDC__ 528 sprintf(char *buf, const char *fmt, ...) 529 #else 530 sprintf(buf, fmt, va_alist) 531 char *buf; 532 const char *cfmt; 533 va_dcl 534 #endif 535 { 536 int retval; 537 va_list ap; 538 539 va_start(ap, fmt); 540 retval = kprintf(fmt, TOBUFONLY, NULL, buf, ap); 541 va_end(ap); 542 *(buf + retval) = 0; /* null terminate */ 543 return(retval); 544 } 545 546 /* 547 * bitmask_snprintf: print a kernel-printf "%b" message to a buffer 548 * 549 * => returns pointer to the buffer 550 * => XXX: useful vs. kernel %b? 551 */ 552 char * 553 bitmask_snprintf(ul, p, buf, buflen) 554 u_long ul; 555 const char *p; 556 char *buf; 557 size_t buflen; 558 { 559 char *bp, *q; 560 size_t left; 561 register int n; 562 int tmp; 563 char snbuf[KPRINTF_BUFSIZE]; 564 565 bp = buf; 566 bzero(buf, buflen); 567 568 /* 569 * Always leave room for the trailing NULL. 570 */ 571 left = buflen - 1; 572 573 /* 574 * Print the value into the buffer. Abort if there's not 575 * enough room. 576 */ 577 if (buflen < KPRINTF_BUFSIZE) 578 return (buf); 579 580 if (*p == 8) 581 sprintf(snbuf,"%lo", ul); 582 else if (*p == 10) 583 sprintf(snbuf, "%ld", ul); 584 else if (*p == 16) 585 sprintf(snbuf, "%lx", ul); 586 else 587 return(buf); /* punt if not oct, dec, or hex */ 588 p++; 589 590 for (q = snbuf ; *q ; q++) { 591 *bp++ = *q; 592 left--; 593 } 594 595 /* 596 * If the value we printed was 0, or if we don't have room for 597 * "<x>", we're done. 598 */ 599 if (ul == 0 || left < 3) 600 return (buf); 601 602 #define PUTBYTE(b, c, l) \ 603 *(b)++ = (c); \ 604 if (--(l) == 0) \ 605 goto out; 606 607 for (tmp = 0; (n = *p++) != 0;) { 608 if (ul & (1 << (n - 1))) { 609 PUTBYTE(bp, tmp ? ',' : '<', left); 610 for (; (n = *p) > ' '; ++p) { 611 PUTBYTE(bp, n, left); 612 } 613 tmp = 1; 614 } else 615 for (; *p > ' '; ++p) 616 continue; 617 } 618 if (tmp) 619 *bp = '>'; 620 621 #undef PUTBYTE 622 623 out: 624 return (buf); 625 } 626 627 /* 628 * kprintf: scaled down version of printf(3). 629 * 630 * this version based on vfprintf() from libc which was derived from 631 * software contributed to Berkeley by Chris Torek. 632 * 633 * Two additional formats: 634 * 635 * The format %b is supported to decode error registers. 636 * Its usage is: 637 * 638 * printf("reg=%b\n", regval, "<base><arg>*"); 639 * 640 * where <base> is the output base expressed as a control character, e.g. 641 * \10 gives octal; \20 gives hex. Each arg is a sequence of characters, 642 * the first of which gives the bit number to be inspected (origin 1), and 643 * the next characters (up to a control character, i.e. a character <= 32), 644 * give the name of the register. Thus: 645 * 646 * kprintf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n"); 647 * 648 * would produce output: 649 * 650 * reg=3<BITTWO,BITONE> 651 * 652 * The format %: passes an additional format string and argument list 653 * recursively. Its usage is: 654 * 655 * fn(char *fmt, ...) 656 * { 657 * va_list ap; 658 * va_start(ap, fmt); 659 * printf("prefix: %: suffix\n", fmt, ap); 660 * va_end(ap); 661 * } 662 * 663 * this is the actual printf innards 664 * 665 * This code is large and complicated... 666 */ 667 668 /* 669 * macros for converting digits to letters and vice versa 670 */ 671 #define to_digit(c) ((c) - '0') 672 #define is_digit(c) ((unsigned)to_digit(c) <= 9) 673 #define to_char(n) ((n) + '0') 674 675 /* 676 * flags used during conversion. 677 */ 678 #define ALT 0x001 /* alternate form */ 679 #define HEXPREFIX 0x002 /* add 0x or 0X prefix */ 680 #define LADJUST 0x004 /* left adjustment */ 681 #define LONGDBL 0x008 /* long double; unimplemented */ 682 #define LONGINT 0x010 /* long integer */ 683 #define QUADINT 0x020 /* quad integer */ 684 #define SHORTINT 0x040 /* short integer */ 685 #define ZEROPAD 0x080 /* zero (as opposed to blank) pad */ 686 #define FPT 0x100 /* Floating point number */ 687 688 /* 689 * To extend shorts properly, we need both signed and unsigned 690 * argument extraction methods. 691 */ 692 #define SARG() \ 693 (flags&QUADINT ? va_arg(ap, quad_t) : \ 694 flags&LONGINT ? va_arg(ap, long) : \ 695 flags&SHORTINT ? (long)(short)va_arg(ap, int) : \ 696 (long)va_arg(ap, int)) 697 #define UARG() \ 698 (flags&QUADINT ? va_arg(ap, u_quad_t) : \ 699 flags&LONGINT ? va_arg(ap, u_long) : \ 700 flags&SHORTINT ? (u_long)(u_short)va_arg(ap, int) : \ 701 (u_long)va_arg(ap, u_int)) 702 703 #define KPRINTF_PUTCHAR(C) \ 704 (oflags == TOBUFONLY) ? *sbuf++ = (C) : putchar((C), oflags, tp); 705 706 int 707 kprintf(fmt0, oflags, tp, sbuf, ap) 708 const char *fmt0; 709 int oflags; 710 struct tty *tp; 711 char *sbuf; 712 va_list ap; 713 { 714 char *fmt; /* format string */ 715 int ch; /* character from fmt */ 716 int n; /* handy integer (short term usage) */ 717 char *cp; /* handy char pointer (short term usage) */ 718 int flags; /* flags as above */ 719 int ret; /* return value accumulator */ 720 int width; /* width from format (%8d), or 0 */ 721 int prec; /* precision from format (%.3d), or -1 */ 722 char sign; /* sign prefix (' ', '+', '-', or \0) */ 723 724 u_quad_t _uquad; /* integer arguments %[diouxX] */ 725 enum { OCT, DEC, HEX } base;/* base for [diouxX] conversion */ 726 int dprec; /* a copy of prec if [diouxX], 0 otherwise */ 727 int realsz; /* field size expanded by dprec */ 728 int size; /* size of converted field or string */ 729 char *xdigs; /* digits for [xX] conversion */ 730 char buf[KPRINTF_BUFSIZE]; /* space for %c, %[diouxX] */ 731 732 cp = NULL; /* XXX: shutup gcc */ 733 size = 0; /* XXX: shutup gcc */ 734 735 fmt = (char *)fmt0; 736 ret = 0; 737 738 xdigs = NULL; /* XXX: shut up gcc warning */ 739 740 /* 741 * Scan the format for conversions (`%' character). 742 */ 743 for (;;) { 744 while (*fmt != '%' && *fmt) { 745 KPRINTF_PUTCHAR(*fmt++); 746 ret++; 747 } 748 if (*fmt == 0) 749 goto done; 750 751 fmt++; /* skip over '%' */ 752 753 flags = 0; 754 dprec = 0; 755 width = 0; 756 prec = -1; 757 sign = '\0'; 758 759 rflag: ch = *fmt++; 760 reswitch: switch (ch) { 761 /* XXX: non-standard '%:' format */ 762 #ifndef __powerpc__ 763 case ':': 764 if (oflags != TOBUFONLY) { 765 cp = va_arg(ap, char *); 766 kprintf(cp, oflags, tp, 767 NULL, va_arg(ap, va_list)); 768 } 769 continue; /* no output */ 770 #endif 771 /* XXX: non-standard '%b' format */ 772 case 'b': { 773 char *b, *z; 774 int tmp; 775 _uquad = va_arg(ap, int); 776 b = va_arg(ap, char *); 777 if (*b == 8) 778 sprintf(buf, "%qo", _uquad); 779 else if (*b == 10) 780 sprintf(buf, "%qd", _uquad); 781 else if (*b == 16) 782 sprintf(buf, "%qx", _uquad); 783 else 784 break; 785 b++; 786 787 z = buf; 788 while (*z) { 789 KPRINTF_PUTCHAR(*z++); 790 ret++; 791 } 792 793 if (_uquad) { 794 tmp = 0; 795 while ((n = *b++) != 0) { 796 if (_uquad & (1 << (n - 1))) { 797 KPRINTF_PUTCHAR(tmp ? ',':'<'); 798 ret++; 799 while ((n = *b) > ' ') { 800 KPRINTF_PUTCHAR(n); 801 ret++; 802 b++; 803 } 804 tmp = 1; 805 } else { 806 while(*b > ' ') 807 b++; 808 } 809 } 810 if (tmp) { 811 KPRINTF_PUTCHAR('>'); 812 ret++; 813 } 814 } 815 continue; /* no output */ 816 } 817 818 #ifdef DDB 819 /* XXX: non-standard '%r' format (print int in db_radix) */ 820 case 'r': 821 if ((oflags & TODDB) == 0) 822 goto default_case; 823 824 if (db_radix == 16) 825 goto case_z; /* signed hex */ 826 _uquad = SARG(); 827 if ((quad_t)_uquad < 0) { 828 _uquad = -_uquad; 829 sign = '-'; 830 } 831 base = (db_radix == 8) ? OCT : DEC; 832 goto number; 833 834 835 /* XXX: non-standard '%z' format ("signed hex", a "hex %i")*/ 836 case 'z': 837 case_z: 838 if ((oflags & TODDB) == 0) 839 goto default_case; 840 841 xdigs = "0123456789abcdef"; 842 ch = 'x'; /* the 'x' in '0x' (below) */ 843 _uquad = SARG(); 844 base = HEX; 845 /* leading 0x/X only if non-zero */ 846 if (flags & ALT && _uquad != 0) 847 flags |= HEXPREFIX; 848 if ((quad_t)_uquad < 0) { 849 _uquad = -_uquad; 850 sign = '-'; 851 } 852 goto number; 853 #endif 854 855 case ' ': 856 /* 857 * ``If the space and + flags both appear, the space 858 * flag will be ignored.'' 859 * -- ANSI X3J11 860 */ 861 if (!sign) 862 sign = ' '; 863 goto rflag; 864 case '#': 865 flags |= ALT; 866 goto rflag; 867 case '*': 868 /* 869 * ``A negative field width argument is taken as a 870 * - flag followed by a positive field width.'' 871 * -- ANSI X3J11 872 * They don't exclude field widths read from args. 873 */ 874 if ((width = va_arg(ap, int)) >= 0) 875 goto rflag; 876 width = -width; 877 /* FALLTHROUGH */ 878 case '-': 879 flags |= LADJUST; 880 goto rflag; 881 case '+': 882 sign = '+'; 883 goto rflag; 884 case '.': 885 if ((ch = *fmt++) == '*') { 886 n = va_arg(ap, int); 887 prec = n < 0 ? -1 : n; 888 goto rflag; 889 } 890 n = 0; 891 while (is_digit(ch)) { 892 n = 10 * n + to_digit(ch); 893 ch = *fmt++; 894 } 895 prec = n < 0 ? -1 : n; 896 goto reswitch; 897 case '0': 898 /* 899 * ``Note that 0 is taken as a flag, not as the 900 * beginning of a field width.'' 901 * -- ANSI X3J11 902 */ 903 flags |= ZEROPAD; 904 goto rflag; 905 case '1': case '2': case '3': case '4': 906 case '5': case '6': case '7': case '8': case '9': 907 n = 0; 908 do { 909 n = 10 * n + to_digit(ch); 910 ch = *fmt++; 911 } while (is_digit(ch)); 912 width = n; 913 goto reswitch; 914 case 'h': 915 flags |= SHORTINT; 916 goto rflag; 917 case 'l': 918 if (*fmt == 'l') { 919 fmt++; 920 flags |= QUADINT; 921 } else { 922 flags |= LONGINT; 923 } 924 goto rflag; 925 case 'q': 926 flags |= QUADINT; 927 goto rflag; 928 case 'c': 929 *(cp = buf) = va_arg(ap, int); 930 size = 1; 931 sign = '\0'; 932 break; 933 case 'D': 934 flags |= LONGINT; 935 /*FALLTHROUGH*/ 936 case 'd': 937 case 'i': 938 _uquad = SARG(); 939 if ((quad_t)_uquad < 0) { 940 _uquad = -_uquad; 941 sign = '-'; 942 } 943 base = DEC; 944 goto number; 945 case 'n': 946 #ifdef DDB 947 /* XXX: non-standard '%n' format */ 948 /* 949 * XXX: HACK! DDB wants '%n' to be a '%u' printed 950 * in db_radix format. this should die since '%n' 951 * is already defined in standard printf to write 952 * the number of chars printed so far to the arg (which 953 * should be a pointer. 954 */ 955 if (oflags & TODDB) { 956 if (db_radix == 16) 957 ch = 'x'; /* convert to %x */ 958 else if (db_radix == 8) 959 ch = 'o'; /* convert to %o */ 960 else 961 ch = 'u'; /* convert to %u */ 962 963 /* ... and start again */ 964 goto reswitch; 965 } 966 967 #endif 968 if (flags & QUADINT) 969 *va_arg(ap, quad_t *) = ret; 970 else if (flags & LONGINT) 971 *va_arg(ap, long *) = ret; 972 else if (flags & SHORTINT) 973 *va_arg(ap, short *) = ret; 974 else 975 *va_arg(ap, int *) = ret; 976 continue; /* no output */ 977 case 'O': 978 flags |= LONGINT; 979 /*FALLTHROUGH*/ 980 case 'o': 981 _uquad = UARG(); 982 base = OCT; 983 goto nosign; 984 case 'p': 985 /* 986 * ``The argument shall be a pointer to void. The 987 * value of the pointer is converted to a sequence 988 * of printable characters, in an implementation- 989 * defined manner.'' 990 * -- ANSI X3J11 991 */ 992 /* NOSTRICT */ 993 _uquad = (u_long)va_arg(ap, void *); 994 base = HEX; 995 xdigs = "0123456789abcdef"; 996 flags |= HEXPREFIX; 997 ch = 'x'; 998 goto nosign; 999 case 's': 1000 if ((cp = va_arg(ap, char *)) == NULL) 1001 cp = "(null)"; 1002 if (prec >= 0) { 1003 /* 1004 * can't use strlen; can only look for the 1005 * NUL in the first `prec' characters, and 1006 * strlen() will go further. 1007 */ 1008 char *p = memchr(cp, 0, prec); 1009 1010 if (p != NULL) { 1011 size = p - cp; 1012 if (size > prec) 1013 size = prec; 1014 } else 1015 size = prec; 1016 } else 1017 size = strlen(cp); 1018 sign = '\0'; 1019 break; 1020 case 'U': 1021 flags |= LONGINT; 1022 /*FALLTHROUGH*/ 1023 case 'u': 1024 _uquad = UARG(); 1025 base = DEC; 1026 goto nosign; 1027 case 'X': 1028 xdigs = "0123456789ABCDEF"; 1029 goto hex; 1030 case 'x': 1031 xdigs = "0123456789abcdef"; 1032 hex: _uquad = UARG(); 1033 base = HEX; 1034 /* leading 0x/X only if non-zero */ 1035 if (flags & ALT && _uquad != 0) 1036 flags |= HEXPREFIX; 1037 1038 /* unsigned conversions */ 1039 nosign: sign = '\0'; 1040 /* 1041 * ``... diouXx conversions ... if a precision is 1042 * specified, the 0 flag will be ignored.'' 1043 * -- ANSI X3J11 1044 */ 1045 number: if ((dprec = prec) >= 0) 1046 flags &= ~ZEROPAD; 1047 1048 /* 1049 * ``The result of converting a zero value with an 1050 * explicit precision of zero is no characters.'' 1051 * -- ANSI X3J11 1052 */ 1053 cp = buf + KPRINTF_BUFSIZE; 1054 if (_uquad != 0 || prec != 0) { 1055 /* 1056 * Unsigned mod is hard, and unsigned mod 1057 * by a constant is easier than that by 1058 * a variable; hence this switch. 1059 */ 1060 switch (base) { 1061 case OCT: 1062 do { 1063 *--cp = to_char(_uquad & 7); 1064 _uquad >>= 3; 1065 } while (_uquad); 1066 /* handle octal leading 0 */ 1067 if (flags & ALT && *cp != '0') 1068 *--cp = '0'; 1069 break; 1070 1071 case DEC: 1072 /* many numbers are 1 digit */ 1073 while (_uquad >= 10) { 1074 *--cp = to_char(_uquad % 10); 1075 _uquad /= 10; 1076 } 1077 *--cp = to_char(_uquad); 1078 break; 1079 1080 case HEX: 1081 do { 1082 *--cp = xdigs[_uquad & 15]; 1083 _uquad >>= 4; 1084 } while (_uquad); 1085 break; 1086 1087 default: 1088 cp = "bug in kprintf: bad base"; 1089 size = strlen(cp); 1090 goto skipsize; 1091 } 1092 } 1093 size = buf + KPRINTF_BUFSIZE - cp; 1094 skipsize: 1095 break; 1096 default: /* "%?" prints ?, unless ? is NUL */ 1097 #ifdef DDB 1098 default_case: /* DDB */ 1099 #endif 1100 if (ch == '\0') 1101 goto done; 1102 /* pretend it was %c with argument ch */ 1103 cp = buf; 1104 *cp = ch; 1105 size = 1; 1106 sign = '\0'; 1107 break; 1108 } 1109 1110 /* 1111 * All reasonable formats wind up here. At this point, `cp' 1112 * points to a string which (if not flags&LADJUST) should be 1113 * padded out to `width' places. If flags&ZEROPAD, it should 1114 * first be prefixed by any sign or other prefix; otherwise, 1115 * it should be blank padded before the prefix is emitted. 1116 * After any left-hand padding and prefixing, emit zeroes 1117 * required by a decimal [diouxX] precision, then print the 1118 * string proper, then emit zeroes required by any leftover 1119 * floating precision; finally, if LADJUST, pad with blanks. 1120 * 1121 * Compute actual size, so we know how much to pad. 1122 * size excludes decimal prec; realsz includes it. 1123 */ 1124 realsz = dprec > size ? dprec : size; 1125 if (sign) 1126 realsz++; 1127 else if (flags & HEXPREFIX) 1128 realsz+= 2; 1129 1130 /* right-adjusting blank padding */ 1131 if ((flags & (LADJUST|ZEROPAD)) == 0) { 1132 n = width - realsz; 1133 while (n-- > 0) 1134 KPRINTF_PUTCHAR(' '); 1135 } 1136 1137 /* prefix */ 1138 if (sign) { 1139 KPRINTF_PUTCHAR(sign); 1140 } else if (flags & HEXPREFIX) { 1141 KPRINTF_PUTCHAR('0'); 1142 KPRINTF_PUTCHAR(ch); 1143 } 1144 1145 /* right-adjusting zero padding */ 1146 if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD) { 1147 n = width - realsz; 1148 while (n-- > 0) 1149 KPRINTF_PUTCHAR('0'); 1150 } 1151 1152 /* leading zeroes from decimal precision */ 1153 n = dprec - size; 1154 while (n-- > 0) 1155 KPRINTF_PUTCHAR('0'); 1156 1157 /* the string or number proper */ 1158 while (size--) 1159 KPRINTF_PUTCHAR(*cp++); 1160 /* left-adjusting padding (always blank) */ 1161 if (flags & LADJUST) { 1162 n = width - realsz; 1163 while (n-- > 0) 1164 KPRINTF_PUTCHAR(' '); 1165 } 1166 1167 /* finally, adjust ret */ 1168 ret += width > realsz ? width : realsz; 1169 1170 } 1171 done: 1172 return (ret); 1173 /* NOTREACHED */ 1174 } 1175