1 /*- 2 * Copyright (c) 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * from: @(#)printf.c 8.1 (Berkeley) 6/11/93 34 * $Id: printf.c,v 1.3 1994/08/22 21:56:10 brezak Exp $ 35 */ 36 37 /* 38 * Scaled down version of printf(3). 39 * 40 * One additional format: 41 * 42 * The format %b is supported to decode error registers. 43 * Its usage is: 44 * 45 * printf("reg=%b\n", regval, "<base><arg>*"); 46 * 47 * where <base> is the output base expressed as a control character, e.g. 48 * \10 gives octal; \20 gives hex. Each arg is a sequence of characters, 49 * the first of which gives the bit number to be inspected (origin 1), and 50 * the next characters (up to a control character, i.e. a character <= 32), 51 * give the name of the register. Thus: 52 * 53 * printf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n"); 54 * 55 * would produce output: 56 * 57 * reg=3<BITTWO,BITONE> 58 */ 59 60 #include <sys/cdefs.h> 61 #include <sys/types.h> 62 #ifdef __STDC__ 63 #include <stdarg.h> 64 #else 65 #include <varargs.h> 66 #endif 67 68 #include "stand.h" 69 70 static void kprintn __P((u_long, int)); 71 72 void 73 #ifdef __STDC__ 74 printf(const char *fmt, ...) 75 #else 76 printf(fmt, va_alist) 77 char *fmt; 78 #endif 79 { 80 register char *p; 81 register int ch, n; 82 unsigned long ul; 83 int lflag, set; 84 va_list ap; 85 86 #ifdef __STDC__ 87 va_start(ap, fmt); 88 #else 89 va_start(ap); 90 #endif 91 for (;;) { 92 while ((ch = *fmt++) != '%') { 93 if (ch == '\0') 94 return; 95 putchar(ch); 96 } 97 lflag = 0; 98 reswitch: switch (ch = *fmt++) { 99 case 'l': 100 lflag = 1; 101 goto reswitch; 102 case 'b': 103 ul = va_arg(ap, int); 104 p = va_arg(ap, char *); 105 kprintn(ul, *p++); 106 107 if (!ul) 108 break; 109 110 for (set = 0; (n = *p++);) { 111 if (ul & (1 << (n - 1))) { 112 putchar(set ? ',' : '<'); 113 for (; (n = *p) > ' '; ++p) 114 putchar(n); 115 set = 1; 116 } else 117 for (; *p > ' '; ++p); 118 } 119 if (set) 120 putchar('>'); 121 break; 122 case 'c': 123 ch = va_arg(ap, int); 124 putchar(ch & 0x7f); 125 break; 126 case 's': 127 p = va_arg(ap, char *); 128 while ((ch = *p++)) 129 putchar(ch); 130 break; 131 case 'd': 132 ul = lflag ? 133 va_arg(ap, long) : va_arg(ap, int); 134 if ((long)ul < 0) { 135 putchar('-'); 136 ul = -(long)ul; 137 } 138 kprintn(ul, 10); 139 break; 140 case 'o': 141 ul = lflag ? 142 va_arg(ap, u_long) : va_arg(ap, u_int); 143 kprintn(ul, 8); 144 break; 145 case 'u': 146 ul = lflag ? 147 va_arg(ap, u_long) : va_arg(ap, u_int); 148 kprintn(ul, 10); 149 break; 150 case 'x': 151 ul = lflag ? 152 va_arg(ap, u_long) : va_arg(ap, u_int); 153 kprintn(ul, 16); 154 break; 155 default: 156 putchar('%'); 157 if (lflag) 158 putchar('l'); 159 putchar(ch); 160 } 161 } 162 va_end(ap); 163 } 164 165 static void 166 kprintn(ul, base) 167 unsigned long ul; 168 int base; 169 { 170 /* hold a long in base 8 */ 171 char *p, buf[(sizeof(long) * NBBY / 3) + 1]; 172 173 p = buf; 174 do { 175 *p++ = "0123456789abcdef"[ul % base]; 176 } while (ul /= base); 177 do { 178 putchar(*--p); 179 } while (p > buf); 180 } 181