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