1 /* $OpenBSD: subr_prf.c,v 1.38 2002/01/23 15:46:48 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 #include <sys/pool.h> 59 60 #include <dev/cons.h> 61 62 /* 63 * note that stdarg.h and the ansi style va_start macro is used for both 64 * ansi and traditional c complers. 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 int kprintf __P((const char *, int, void *, char *, va_list)); 101 void putchar __P((int, int, struct tty *)); 102 103 104 /* 105 * globals 106 */ 107 108 struct tty *constty; /* pointer to console "window" tty */ 109 int consintr = 1; /* ok to handle console interrupts? */ 110 extern int log_open; /* subr_log: is /dev/klog open? */ 111 const char *panicstr; /* arg to first call to panic (used as a flag 112 to indicate that panic has already been called). */ 113 #ifdef DDB 114 /* 115 * Enter ddb on panic. 116 */ 117 int db_panic = 1; 118 119 /* 120 * db_console controls if we can be able to enter ddb by a special key 121 * combination (machine dependent). 122 * If DDB_SAFE_CONSOLE is defined in the kernel configuration it allows 123 * to break into console during boot. It's _really_ useful when debugging 124 * some things in the kernel that can cause init(8) to crash. 125 */ 126 #ifdef DDB_SAFE_CONSOLE 127 int db_console = 1; 128 #else 129 int db_console = 0; 130 #endif 131 #endif 132 133 /* 134 * v_putc: routine to putc on virtual console 135 * 136 * the v_putc pointer can be used to redirect the console cnputc elsewhere 137 * [e.g. to a "virtual console"]. 138 */ 139 140 void (*v_putc) __P((int)) = cnputc; /* start with cnputc (normal cons) */ 141 142 143 /* 144 * functions 145 */ 146 147 /* 148 * Partial support (the failure case) of the assertion facility 149 * commonly found in userland. 150 */ 151 void 152 __assert(t, f, l, e) 153 const char *t, *f, *e; 154 int l; 155 { 156 157 panic("kernel %sassertion \"%s\" failed: file \"%s\", line %d", 158 t, e, f, l); 159 } 160 161 /* 162 * tablefull: warn that a system table is full 163 */ 164 165 void 166 tablefull(tab) 167 const char *tab; 168 { 169 log(LOG_ERR, "%s: table is full\n", tab); 170 } 171 172 /* 173 * panic: handle an unresolvable fatal error 174 * 175 * prints "panic: <message>" and reboots. if called twice (i.e. recursive 176 * call) we avoid trying to sync the disk and just reboot (to avoid 177 * recursive panics). 178 */ 179 180 void 181 #ifdef __STDC__ 182 panic(const char *fmt, ...) 183 #else 184 panic(fmt, va_alist) 185 char *fmt; 186 va_dcl 187 #endif 188 { 189 static char panicbuf[512]; 190 int bootopt; 191 va_list ap; 192 193 bootopt = RB_AUTOBOOT | RB_DUMP; 194 #if defined(UVM_SWAP_ENCRYPT) 195 if (uvm_doswapencrypt) 196 bootopt &= ~RB_DUMP; 197 #endif 198 va_start(ap, fmt); 199 if (panicstr) 200 bootopt |= RB_NOSYNC; 201 else { 202 vsprintf(panicbuf, fmt, ap); 203 panicstr = panicbuf; 204 } 205 va_end(ap); 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 va_end(ap); 256 splx(s); 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 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 va_end(ap); 303 splx(s); 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 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 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 = NULL; /* 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 = 0; /* size of converted field or string */ 771 char *xdigs = NULL; /* digits for [xX] conversion */ 772 char buf[KPRINTF_BUFSIZE]; /* space for %c, %[diouxX] */ 773 char *tailp = NULL; /* tail pointer for snprintf */ 774 775 if (oflags == TOBUFONLY && (vp != NULL)) 776 tailp = *(char **)vp; 777 778 fmt = (char *)fmt0; 779 ret = 0; 780 781 /* 782 * Scan the format for conversions (`%' character). 783 */ 784 for (;;) { 785 while (*fmt != '%' && *fmt) { 786 ret++; 787 KPRINTF_PUTCHAR(*fmt++); 788 } 789 if (*fmt == 0) 790 goto done; 791 792 fmt++; /* skip over '%' */ 793 794 flags = 0; 795 dprec = 0; 796 width = 0; 797 prec = -1; 798 sign = '\0'; 799 800 rflag: ch = *fmt++; 801 reswitch: switch (ch) { 802 /* XXX: non-standard '%:' format */ 803 #ifndef __powerpc__ 804 case ':': 805 if (oflags != TOBUFONLY) { 806 cp = va_arg(ap, char *); 807 kprintf(cp, oflags, vp, 808 NULL, va_arg(ap, va_list)); 809 } 810 continue; /* no output */ 811 #endif 812 /* XXX: non-standard '%b' format */ 813 case 'b': { 814 char *b, *z; 815 int tmp; 816 _uquad = va_arg(ap, u_int); 817 b = va_arg(ap, char *); 818 if (*b == 8) 819 sprintf(buf, "%llo", _uquad); 820 else if (*b == 10) 821 sprintf(buf, "%lld", _uquad); 822 else if (*b == 16) 823 sprintf(buf, "%llx", _uquad); 824 else 825 break; 826 b++; 827 828 z = buf; 829 while (*z) { 830 ret++; 831 KPRINTF_PUTCHAR(*z++); 832 } 833 834 if (_uquad) { 835 tmp = 0; 836 while ((n = *b++) != 0) { 837 if (_uquad & (1 << (n - 1))) { 838 ret++; 839 KPRINTF_PUTCHAR(tmp ? ',':'<'); 840 while ((n = *b) > ' ') { 841 ret++; 842 KPRINTF_PUTCHAR(n); 843 b++; 844 } 845 tmp = 1; 846 } else { 847 while(*b > ' ') 848 b++; 849 } 850 } 851 if (tmp) { 852 ret++; 853 KPRINTF_PUTCHAR('>'); 854 } 855 } 856 continue; /* no output */ 857 } 858 859 #ifdef DDB 860 /* XXX: non-standard '%r' format (print int in db_radix) */ 861 case 'r': 862 if ((oflags & TODDB) == 0) 863 goto default_case; 864 865 if (db_radix == 16) 866 goto case_z; /* signed hex */ 867 _uquad = SARG(); 868 if ((quad_t)_uquad < 0) { 869 _uquad = -_uquad; 870 sign = '-'; 871 } 872 base = (db_radix == 8) ? OCT : DEC; 873 goto number; 874 875 876 /* XXX: non-standard '%z' format ("signed hex", a "hex %i")*/ 877 case 'z': 878 case_z: 879 if ((oflags & TODDB) == 0) 880 goto default_case; 881 882 xdigs = "0123456789abcdef"; 883 ch = 'x'; /* the 'x' in '0x' (below) */ 884 _uquad = SARG(); 885 base = HEX; 886 /* leading 0x/X only if non-zero */ 887 if (flags & ALT && _uquad != 0) 888 flags |= HEXPREFIX; 889 if ((quad_t)_uquad < 0) { 890 _uquad = -_uquad; 891 sign = '-'; 892 } 893 goto number; 894 #endif 895 896 case ' ': 897 /* 898 * ``If the space and + flags both appear, the space 899 * flag will be ignored.'' 900 * -- ANSI X3J11 901 */ 902 if (!sign) 903 sign = ' '; 904 goto rflag; 905 case '#': 906 flags |= ALT; 907 goto rflag; 908 case '*': 909 /* 910 * ``A negative field width argument is taken as a 911 * - flag followed by a positive field width.'' 912 * -- ANSI X3J11 913 * They don't exclude field widths read from args. 914 */ 915 if ((width = va_arg(ap, int)) >= 0) 916 goto rflag; 917 width = -width; 918 /* FALLTHROUGH */ 919 case '-': 920 flags |= LADJUST; 921 goto rflag; 922 case '+': 923 sign = '+'; 924 goto rflag; 925 case '.': 926 if ((ch = *fmt++) == '*') { 927 n = va_arg(ap, int); 928 prec = n < 0 ? -1 : n; 929 goto rflag; 930 } 931 n = 0; 932 while (is_digit(ch)) { 933 n = 10 * n + to_digit(ch); 934 ch = *fmt++; 935 } 936 prec = n < 0 ? -1 : n; 937 goto reswitch; 938 case '0': 939 /* 940 * ``Note that 0 is taken as a flag, not as the 941 * beginning of a field width.'' 942 * -- ANSI X3J11 943 */ 944 flags |= ZEROPAD; 945 goto rflag; 946 case '1': case '2': case '3': case '4': 947 case '5': case '6': case '7': case '8': case '9': 948 n = 0; 949 do { 950 n = 10 * n + to_digit(ch); 951 ch = *fmt++; 952 } while (is_digit(ch)); 953 width = n; 954 goto reswitch; 955 case 'h': 956 flags |= SHORTINT; 957 goto rflag; 958 case 'l': 959 if (*fmt == 'l') { 960 fmt++; 961 flags |= QUADINT; 962 } else { 963 flags |= LONGINT; 964 } 965 goto rflag; 966 case 'q': 967 flags |= QUADINT; 968 goto rflag; 969 case 'c': 970 *(cp = buf) = va_arg(ap, int); 971 size = 1; 972 sign = '\0'; 973 break; 974 case 'D': 975 flags |= LONGINT; 976 /*FALLTHROUGH*/ 977 case 'd': 978 case 'i': 979 _uquad = SARG(); 980 if ((quad_t)_uquad < 0) { 981 _uquad = -_uquad; 982 sign = '-'; 983 } 984 base = DEC; 985 goto number; 986 case 'n': 987 #ifdef DDB 988 /* XXX: non-standard '%n' format */ 989 /* 990 * XXX: HACK! DDB wants '%n' to be a '%u' printed 991 * in db_radix format. this should die since '%n' 992 * is already defined in standard printf to write 993 * the number of chars printed so far to the arg (which 994 * should be a pointer. 995 */ 996 if (oflags & TODDB) { 997 if (db_radix == 16) 998 ch = 'x'; /* convert to %x */ 999 else if (db_radix == 8) 1000 ch = 'o'; /* convert to %o */ 1001 else 1002 ch = 'u'; /* convert to %u */ 1003 1004 /* ... and start again */ 1005 goto reswitch; 1006 } 1007 1008 #endif 1009 if (flags & QUADINT) 1010 *va_arg(ap, quad_t *) = ret; 1011 else if (flags & LONGINT) 1012 *va_arg(ap, long *) = ret; 1013 else if (flags & SHORTINT) 1014 *va_arg(ap, short *) = ret; 1015 else 1016 *va_arg(ap, int *) = ret; 1017 continue; /* no output */ 1018 case 'O': 1019 flags |= LONGINT; 1020 /*FALLTHROUGH*/ 1021 case 'o': 1022 _uquad = UARG(); 1023 base = OCT; 1024 goto nosign; 1025 case 'p': 1026 /* 1027 * ``The argument shall be a pointer to void. The 1028 * value of the pointer is converted to a sequence 1029 * of printable characters, in an implementation- 1030 * defined manner.'' 1031 * -- ANSI X3J11 1032 */ 1033 /* NOSTRICT */ 1034 _uquad = (u_long)va_arg(ap, void *); 1035 base = HEX; 1036 xdigs = "0123456789abcdef"; 1037 flags |= HEXPREFIX; 1038 ch = 'x'; 1039 goto nosign; 1040 case 's': 1041 if ((cp = va_arg(ap, char *)) == NULL) 1042 cp = "(null)"; 1043 if (prec >= 0) { 1044 /* 1045 * can't use strlen; can only look for the 1046 * NUL in the first `prec' characters, and 1047 * strlen() will go further. 1048 */ 1049 char *p = memchr(cp, 0, prec); 1050 1051 if (p != NULL) { 1052 size = p - cp; 1053 if (size > prec) 1054 size = prec; 1055 } else 1056 size = prec; 1057 } else 1058 size = strlen(cp); 1059 sign = '\0'; 1060 break; 1061 case 'U': 1062 flags |= LONGINT; 1063 /*FALLTHROUGH*/ 1064 case 'u': 1065 _uquad = UARG(); 1066 base = DEC; 1067 goto nosign; 1068 case 'X': 1069 xdigs = "0123456789ABCDEF"; 1070 goto hex; 1071 case 'x': 1072 xdigs = "0123456789abcdef"; 1073 hex: _uquad = UARG(); 1074 base = HEX; 1075 /* leading 0x/X only if non-zero */ 1076 if (flags & ALT && _uquad != 0) 1077 flags |= HEXPREFIX; 1078 1079 /* unsigned conversions */ 1080 nosign: sign = '\0'; 1081 /* 1082 * ``... diouXx conversions ... if a precision is 1083 * specified, the 0 flag will be ignored.'' 1084 * -- ANSI X3J11 1085 */ 1086 number: if ((dprec = prec) >= 0) 1087 flags &= ~ZEROPAD; 1088 1089 /* 1090 * ``The result of converting a zero value with an 1091 * explicit precision of zero is no characters.'' 1092 * -- ANSI X3J11 1093 */ 1094 cp = buf + KPRINTF_BUFSIZE; 1095 if (_uquad != 0 || prec != 0) { 1096 /* 1097 * Unsigned mod is hard, and unsigned mod 1098 * by a constant is easier than that by 1099 * a variable; hence this switch. 1100 */ 1101 switch (base) { 1102 case OCT: 1103 do { 1104 *--cp = to_char(_uquad & 7); 1105 _uquad >>= 3; 1106 } while (_uquad); 1107 /* handle octal leading 0 */ 1108 if (flags & ALT && *cp != '0') 1109 *--cp = '0'; 1110 break; 1111 1112 case DEC: 1113 /* many numbers are 1 digit */ 1114 while (_uquad >= 10) { 1115 *--cp = to_char(_uquad % 10); 1116 _uquad /= 10; 1117 } 1118 *--cp = to_char(_uquad); 1119 break; 1120 1121 case HEX: 1122 do { 1123 *--cp = xdigs[_uquad & 15]; 1124 _uquad >>= 4; 1125 } while (_uquad); 1126 break; 1127 1128 default: 1129 cp = "bug in kprintf: bad base"; 1130 size = strlen(cp); 1131 goto skipsize; 1132 } 1133 } 1134 size = buf + KPRINTF_BUFSIZE - cp; 1135 skipsize: 1136 break; 1137 default: /* "%?" prints ?, unless ? is NUL */ 1138 #ifdef DDB 1139 default_case: /* DDB */ 1140 #endif 1141 if (ch == '\0') 1142 goto done; 1143 /* pretend it was %c with argument ch */ 1144 cp = buf; 1145 *cp = ch; 1146 size = 1; 1147 sign = '\0'; 1148 break; 1149 } 1150 1151 /* 1152 * All reasonable formats wind up here. At this point, `cp' 1153 * points to a string which (if not flags&LADJUST) should be 1154 * padded out to `width' places. If flags&ZEROPAD, it should 1155 * first be prefixed by any sign or other prefix; otherwise, 1156 * it should be blank padded before the prefix is emitted. 1157 * After any left-hand padding and prefixing, emit zeroes 1158 * required by a decimal [diouxX] precision, then print the 1159 * string proper, then emit zeroes required by any leftover 1160 * floating precision; finally, if LADJUST, pad with blanks. 1161 * 1162 * Compute actual size, so we know how much to pad. 1163 * size excludes decimal prec; realsz includes it. 1164 */ 1165 realsz = dprec > size ? dprec : size; 1166 if (sign) 1167 realsz++; 1168 else if (flags & HEXPREFIX) 1169 realsz+= 2; 1170 1171 /* adjust ret */ 1172 ret += width > realsz ? width : realsz; 1173 1174 /* right-adjusting blank padding */ 1175 if ((flags & (LADJUST|ZEROPAD)) == 0) { 1176 n = width - realsz; 1177 while (n-- > 0) 1178 KPRINTF_PUTCHAR(' '); 1179 } 1180 1181 /* prefix */ 1182 if (sign) { 1183 KPRINTF_PUTCHAR(sign); 1184 } else if (flags & HEXPREFIX) { 1185 KPRINTF_PUTCHAR('0'); 1186 KPRINTF_PUTCHAR(ch); 1187 } 1188 1189 /* right-adjusting zero padding */ 1190 if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD) { 1191 n = width - realsz; 1192 while (n-- > 0) 1193 KPRINTF_PUTCHAR('0'); 1194 } 1195 1196 /* leading zeroes from decimal precision */ 1197 n = dprec - size; 1198 while (n-- > 0) 1199 KPRINTF_PUTCHAR('0'); 1200 1201 /* the string or number proper */ 1202 while (size--) 1203 KPRINTF_PUTCHAR(*cp++); 1204 /* left-adjusting padding (always blank) */ 1205 if (flags & LADJUST) { 1206 n = width - realsz; 1207 while (n-- > 0) 1208 KPRINTF_PUTCHAR(' '); 1209 } 1210 } 1211 1212 done: 1213 if ((oflags == TOBUFONLY) && (vp != NULL)) 1214 *(char **)vp = sbuf; 1215 overflow: 1216 return (ret); 1217 /* NOTREACHED */ 1218 } 1219