xref: /dragonfly/lib/libutil/snprintb.3 (revision 0982c5b8)
1.\"     $NetBSD: snprintb.3,v 1.24 2020/07/30 21:23:36 uwe Exp $
2.\"
3.\" Copyright (c) 1998 The NetBSD Foundation, Inc.
4.\" All rights reserved.
5.\"
6.\" This code is derived from software contributed to The NetBSD Foundation
7.\" by Jeremy Cooper.
8.\"
9.\" Redistribution and use in source and binary forms, with or without
10.\" modification, are permitted provided that the following conditions
11.\" are met:
12.\" 1. Redistributions of source code must retain the above copyright
13.\"    notice, this list of conditions and the following disclaimer.
14.\" 2. Redistributions in binary form must reproduce the above copyright
15.\"    notice, this list of conditions and the following disclaimer in the
16.\"    documentation and/or other materials provided with the distribution.
17.\"
18.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
19.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21.\" PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
22.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28.\" POSSIBILITY OF SUCH DAMAGE.
29.\"
30.Dd December 6, 2019
31.Dt SNPRINTB 3
32.Os
33.Sh NAME
34.Nm snprintb ,
35.Nm snprintb_m
36.Nd bitmask output conversion
37.Sh LIBRARY
38.Lb libutil
39.Sh SYNOPSIS
40.In util.h
41.Ft int
42.Fn "snprintb" "char *buf" "size_t buflen" "const char *fmt" "uint64_t val"
43.Ft int
44.Fn "snprintb_m" "char *buf" "size_t buflen" "const char *fmt" "uint64_t val" \
45"size_t max"
46.Sh DESCRIPTION
47The
48.Fn snprintb
49function formats a bitmask into a mnemonic form suitable for printing.
50.Pp
51This conversion is useful for decoding bit fields in device registers.
52It formats the integer
53.Fa val
54into the buffer
55.Fa buf ,
56of size
57.Fa buflen ,
58using a specified radix and an interpretation of
59the bits within that integer as though they were flags.
60The buffer is always NUL-terminated.
61If the buffer
62.Fa buf
63is too small to hold the formatted output,
64.Fn snprintb
65will fill as much as it can, and return the number of bytes
66that it would have written if the buffer were long enough excluding the
67terminating NUL.
68.Pp
69The decoding directive string
70.Fa fmt
71describes how the bitfield is to be interpreted and displayed.
72It follows two possible syntaxes, referred to as
73.Dq old
74and
75.Dq new .
76The main advantage of the
77.Dq new
78formatting is that it is capable of handling multi-bit fields.
79.Pp
80The first character of
81.Fa fmt
82may be
83.Li \e177 ,
84indicating that the remainder of the format string follows the
85.Dq new
86syntax.
87The second character
88.Pq the first for the old format
89is a binary character representation of the
90output numeral base in which the bitfield will be printed before it is decoded.
91Recognized radix values
92.Pq in C escape-character format
93are
94.Li \e10
95.Pq octal ,
96.Li \e12
97.Pq decimal ,
98and
99.Li \e20
100.Pq hexadecimal .
101.Pp
102The remaining characters in
103.Fa fmt
104are interpreted as a list of bit-position\(endescription pairs.
105From here the syntaxes diverge.
106.Pp
107The
108.Dq old
109format syntax is series of bit-position\(endescription pairs.
110Each begins with a binary character value that represents the position
111of the bit being described.
112A bit position value of one describes the least significant bit.
113Whereas a position value of 32
114.Pq octal 40, hexadecimal 20, the ASCII space character
115describes the most significant bit.
116.Pp
117The remaining characters in a bit-position\(endescription pair are the
118characters to print should the bit being described be set.
119Description strings are delimited by the next bit position value character
120encountered
121.Pq distinguishable by its value being \*[Le] 32 ,
122or the end of the decoding directive string itself.
123.Pp
124For the
125.Dq new
126format syntax, a bit-position\(endescription begins with a field type
127followed by a binary bit-position and possibly a field length.
128The least significant bit is bit-position zero, unlike the
129.Dq old
130syntax where it is one.
131.Bl -tag -width "xxxxx"
132.It Cm b\eB
133Describes a bit position.
134The bit-position
135.Fa B
136indicates the corresponding bit, as in the
137.Dq old
138format.
139.It Cm f\eB\eL
140Describes a multi-bit field beginning at bit-position
141.Fa B
142and having a bit-length of
143.Fa L .
144The remaining characters are printed as a description of the field
145followed by
146.Sq \&=
147and the value of the field.
148The value of the field is printed in the base specified as the second
149character of the decoding directive string
150.Ar fmt .
151.It Cm F\eB\eL
152Describes a multi-bit field like
153.Sq f ,
154but just extracts the value for use with the
155.Sq \&=
156and
157.Sq \&:
158formatting directives described below.
159.It Cm \&=\eV
160The field previously extracted by the last
161.Sq f
162or
163.Sq F
164operator is compared to the byte
165.Sq Cm V
166.Pq for values 0 through 255 .
167If they are equal,
168.Sq \&=
169followed by the string following
170.Sq Cm V
171is printed.
172This and the
173.Sq \&:
174operator may be repeated to annotate multiple possible values.
175.It Cm :\eV
176Operates like the
177.Sq \&=
178operator, but omits the leading
179.Sq \&= .
180.It Cm *FMT
181This provides a
182.Dq default
183case that prints
184.Ar FMT
185using
186.Xr printf 3
187when other
188.Sq \&:
189or
190.Sq \&=
191have not matched.
192.Ar FMT
193may contain a
194.Ft uintmax_t
195format specification that prints the value that
196did not match, since the field can be more than 32 bits wide.
197.El
198.Pp
199Finally, each field is delimited by a NUL
200.Pq Sq \e0
201character.
202By convention, the format string has an additional NUL character at
203the end, following that delimiting the last bit-position\(endescription
204pair.
205.Pp
206The
207.Fn snprintb_m
208function accepts an additional
209.Fa max
210argument.
211If this argument is zero, the
212.Fn snprintb_m
213function returns exactly the same results in the
214.Fa buf
215as the
216.Fn snprintb
217function.
218If the
219.Fa max
220argument is present and has a non-zero value, it represents the maximum
221length of a formatted string.
222If the formatted string would require more than
223.Fa max
224characters, the
225.Fn snprintb_m
226function returns multiple formatted strings in the output buffer
227.Fa buf .
228Each string is NUL-terminated, and the last string is followed by an
229additional NUL character (or, if you prefer, a zero-length string).
230.Sh RETURN VALUES
231The
232.Fn snprintb
233and
234.Fn snprintb_m
235functions return the number of bytes that would have written to the buffer
236if there was adequate space, excluding the final terminating NUL, or \-1 in
237case an error occurred.
238For
239.Fn snprintb_m ,
240the NUL characters terminating each individual string are included in the
241total number of bytes.
242.Sh EXAMPLES
243Two examples of the old formatting style:
244.Bd -literal -offset indent
245snprintb(buf, buflen, "\e10\e2BITTWO\e1BITONE", 3)
246\(rA "03<BITTWO,BITONE>"
247
248snprintb(buf, buflen,
249       "\e20\ex10NOTBOOT\ex0f" "FPP\ex0eSDVMA\ex0cVIDEO"
250       "\ex0bLORES\ex0a" "FPA\ex09" "DIAG\ex07" "CACHE"
251       "\ex06IOCACHE\ex05LOOPBACK\ex04" "DBGCACHE",
252       0xe860)
253\(rA "0xe860<NOTBOOT,FPP,SDVMA,VIDEO,CACHE,IOCACHE>"
254.Ed
255.Pp
256An example of the new formatting style:
257.Bd -literal -offset indent
258snprintb(buf, buflen,
259       "\e177\e020b\e0LSB\e0b\e1_BITONE\e0f\e4\e4NIBBLE2\e0"
260       "f\ex10\e4BURST\e0=\e4FOUR\e0=\exfSIXTEEN\e0"
261       "b\ex1fMSB\e0\e0",
262       0x800f0701)
263\(rA "0x800f0701<LSB,NIBBLE2=0x0,BURST=0xf=SIXTEEN,MSB>"
264.Ed
265.Pp
266A more complex example from
267.In sys/mman.h
268that uses the both bit position
269.Sq b
270formatting as well as the
271.Sq F
272multi-field formatting with a default case:
273.Bd -literal -offset indent
274#define MAP_FMT	"\e177\e020\e
275b\e0SHARED\e0\e
276b\e1PRIVATE\e0\e
277b\e2COPY\e0\e
278b\e4FIXED\e0\e
279b\e5RENAME\e0\e
280b\e6NORESERVE\e0\e
281b\e7INHERIT\e0\e
282b\e11HASSEMAPHORE\e0\e
283b\e12TRYFIXED\e0\e
284b\e13WIRED\e0\e
285F\e14\e1\e0\e
286:\e0FILE\e0\e
287:\e1ANONYMOUS\e0\e
288b\e15STACK\e0\e
289F\e30\e010\e0\e
290:\e000ALIGN=NONE\e0\e
291:\e012ALIGN=1KB\e0\e
292:\e013ALIGN=2KB\e0\e
293:\e014ALIGN=4KB\e0\e
294:\e015ALIGN=8KB\e0\e
295:\e016ALIGN=16KB\e0\e
296:\e017ALIGN=32KB\e0\e
297:\e020ALIGN=64KB\e0\e
298:\e021ALIGN=128KB\e0\e
299:\e022ALIGN=256KB\e0\e
300:\e023ALIGN=512KB\e0\e
301:\e024ALIGN=1MB\e0\e
302:\e030ALIGN=16MB\e0\e
303:\e034ALIGN=256MB\e0\e
304:\e040ALIGN=4GB\e0\e
305:\e044ALIGN=64GB\e0\e
306:\e050ALIGN=1TB\e0\e
307:\e054ALIGN=16TB\e0\e
308:\e060ALIGN=256TB\e0\e
309:\e064ALIGN=4PB\e0\e
310:\e070ALIGN=64PB\e0\e
311:\e074ALIGN=256PB\e0\e
312*ALIGN=2^%jd\e0\e
313"
314snprintb(buf, buflen, MAP_FMT, 0x0d001234)
315\(rA "0xd001234<COPY,FIXED,RENAME,HASSEMAPHORE,ANONYMOUS,ALIGN=8KB>"
316snprintb(buf, buflen, MAP_FMT, 0x2e000000)
317\(rA "0xd001234<0x2e000000<FILE,ALIGN=2^46>
318.Ed
319.Pp
320An example using snprintb_m:
321.Bd -literal -offset indent
322snprintb_m(buf, buflen,
323       "\e177\e020b\e0LSB\e0b\e1_BITONE\e0f\e4\e4NIBBLE2\e0"
324       "f\ex10\e4BURST\e0=\e4FOUR\e0=\exfSIXTEEN\e0"
325       "b\ex1fMSB\e0\e0",
326       0x800f0701, 34)
327\(rA "0x800f0701<LSB,NIBBLE2=0x0>\e00x800f0701<BURST=0xf=SIXTEEN,MSB>\e0"
328.Ed
329.Sh ERRORS
330.Fn snprintb
331will fail if:
332.Bl -tag -width Er
333.It Bq Er EINVAL
334The leading character does not describe a supported format,
335or
336.Fn snprintf
337failed.
338.El
339.Sh SEE ALSO
340.Xr printf 3 ,
341.Xr snprintf 3
342.Sh HISTORY
343The
344.Fn snprintb
345function was originally implemented as a non-standard
346.Li %b
347format string for the kernel
348.Fn printf
349function in
350.Nx 1.5
351and earlier releases.
352It was called
353.Fn bitmask_snprintf
354in
355.Nx 5.0
356and earlier releases.
357.Sh AUTHORS
358The
359.Dq new
360format was the invention of
361.An Chris Torek .
362