FreeBSD/Linux Kernel Cross Reference
sys/kern/subr_prf2.c
1 /* $NetBSD: subr_prf2.c,v 1.3 2008/09/23 22:20:24 pooka 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. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 *
36 * @(#)subr_prf.c 8.4 (Berkeley) 5/4/95
37 */
38
39 #include <sys/cdefs.h>
40 __KERNEL_RCSID(0, "$NetBSD: subr_prf2.c,v 1.3 2008/09/23 22:20:24 pooka Exp $");
41
42 #include <sys/param.h>
43 #include <sys/kprintf.h>
44 #include <sys/syslog.h>
45 #include <sys/systm.h>
46
47 /*
48 * This function is in its own separate module to permit easier
49 * standalone compilation without pulling in kprintf(), panic(), etcetc.
50 */
51
52 const char hexdigits[] = "0123456789abcdef";
53 const char HEXDIGITS[] = "0123456789ABCDEF";
54
55 /*
56 * tablefull: warn that a system table is full
57 */
58
59 void
60 tablefull(const char *tab, const char *hint)
61 {
62 if (hint)
63 log(LOG_ERR, "%s: table is full - %s\n", tab, hint);
64 else
65 log(LOG_ERR, "%s: table is full\n", tab);
66 }
67
68 /*
69 * bitmask_snprintf: print an interpreted bitmask to a buffer
70 *
71 * => returns pointer to the buffer
72 */
73 char *
74 bitmask_snprintf(u_quad_t val, const char *p, char *bf, size_t buflen)
75 {
76 char *bp, *q;
77 size_t left;
78 const char *sbase;
79 char snbuf[KPRINTF_BUFSIZE];
80 int base, bit, ch, len, sep;
81 u_quad_t field;
82
83 bp = bf;
84 memset(bf, 0, buflen);
85
86 /*
87 * Always leave room for the trailing NULL.
88 */
89 left = buflen - 1;
90
91 /*
92 * Print the value into the buffer. Abort if there's not
93 * enough room.
94 */
95 if (buflen < KPRINTF_BUFSIZE)
96 return (bf);
97
98 ch = *p++;
99 base = ch != '\177' ? ch : *p++;
100 sbase = base == 8 ? "%qo" : base == 10 ? "%qd" : base == 16 ? "%qx" : 0;
101 if (sbase == 0)
102 return (bf); /* punt if not oct, dec, or hex */
103
104 snprintf(snbuf, sizeof(snbuf), sbase, val);
105 for (q = snbuf ; *q ; q++) {
106 *bp++ = *q;
107 left--;
108 }
109
110 /*
111 * If the value we printed was 0 and we're using the old-style format,
112 * or if we don't have room for "<x>", we're done.
113 */
114 if (((val == 0) && (ch != '\177')) || left < 3)
115 return (bf);
116
117 #define PUTBYTE(b, c, l) do { \
118 *(b)++ = (c); \
119 if (--(l) == 0) \
120 goto out; \
121 } while (/*CONSTCOND*/ 0)
122 #define PUTSTR(b, p, l) do { \
123 int c; \
124 while ((c = *(p)++) != 0) { \
125 *(b)++ = c; \
126 if (--(l) == 0) \
127 goto out; \
128 } \
129 } while (/*CONSTCOND*/ 0)
130
131 /*
132 * Chris Torek's new bitmask format is identified by a leading \177
133 */
134 sep = '<';
135 if (ch != '\177') {
136 /* old (standard) format. */
137 for (;(bit = *p++) != 0;) {
138 if (val & (1 << (bit - 1))) {
139 PUTBYTE(bp, sep, left);
140 for (; (ch = *p) > ' '; ++p) {
141 PUTBYTE(bp, ch, left);
142 }
143 sep = ',';
144 } else
145 for (; *p > ' '; ++p)
146 continue;
147 }
148 } else {
149 /* new quad-capable format; also does fields. */
150 field = val;
151 while ((ch = *p++) != '\0') {
152 bit = *p++; /* now 0-origin */
153 switch (ch) {
154 case 'b':
155 if (((u_int)(val >> bit) & 1) == 0)
156 goto skip;
157 PUTBYTE(bp, sep, left);
158 PUTSTR(bp, p, left);
159 sep = ',';
160 break;
161 case 'f':
162 case 'F':
163 len = *p++; /* field length */
164 field = (val >> bit) & ((1ULL << len) - 1);
165 if (ch == 'F') /* just extract */
166 break;
167 PUTBYTE(bp, sep, left);
168 sep = ',';
169 PUTSTR(bp, p, left);
170 PUTBYTE(bp, '=', left);
171 sprintf(snbuf, sbase, field);
172 q = snbuf; PUTSTR(bp, q, left);
173 break;
174 case '=':
175 case ':':
176 /*
177 * Here "bit" is actually a value instead,
178 * to be compared against the last field.
179 * This only works for values in [0..255],
180 * of course.
181 */
182 if ((int)field != bit)
183 goto skip;
184 if (ch == '=')
185 PUTBYTE(bp, '=', left);
186 else {
187 PUTBYTE(bp, sep, left);
188 sep = ',';
189 }
190 PUTSTR(bp, p, left);
191 break;
192 default:
193 skip:
194 while (*p++ != '\0')
195 continue;
196 break;
197 }
198 }
199 }
200 if (sep != '<')
201 PUTBYTE(bp, '>', left);
202
203 out:
204 return (bf);
205
206 #undef PUTBYTE
207 #undef PUTSTR
208 }
Cache object: 27115057783db0e375f96a90dcc4dd3e
|