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