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