Page MenuHomeFreeBSD

D54286.id168316.diff
No OneTemporary

D54286.id168316.diff

diff --git a/share/man/man9/printf.9 b/share/man/man9/printf.9
--- a/share/man/man9/printf.9
+++ b/share/man/man9/printf.9
@@ -24,7 +24,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd April 25, 2023
+.Dd December 18, 2025
.Dt PRINTF 9
.Os
.Sh NAME
@@ -95,14 +95,15 @@
The base value is the output base (radix) expressed as an octal value;
for example, \e10 gives octal and \e20 gives hexadecimal.
The arguments are made up of a sequence of bit identifiers.
-Each bit identifier begins with an
-.Em octal
-value which is the number of the bit (starting from 1) this identifier
-describes.
+Each bit identifier begins with a character specifying the number of the bit
+(starting from 1) this identifier describes.
+The characters from \e01 to \e40 can be used to specify bit numbers in the
+range from 1 to 32 and characters from \e200 to \e377 to specify bit numbers
+in the range from 1 to 128.
The rest of the identifier is a string of characters containing the name of
the bit.
-The string is terminated by either the bit number at the start of the next
-bit identifier or
+The identifier is terminated by either the bit number at the start of the next
+bit identifier or by
.Dv NUL
for the last bit identifier.
.Pp
@@ -174,6 +175,17 @@
out: 41:41:5a:5a
.Ed
.Pp
+The same output will be generated by the following function:
+.Bd -literal -offset indent
+void
+printf_test(void)
+{
+
+ printf("reg=%b\en", 3, "\e10\e201BITTWO\e200BITONE");
+ printf("out: %4D\en", "AAZZ", ":");
+}
+.Ed
+.Pp
The call
.Bd -literal -offset indent
log(LOG_DEBUG, "%s%d: been there.\en", sc->sc_name, sc->sc_unit);
diff --git a/sys/kern/subr_prf.c b/sys/kern/subr_prf.c
--- a/sys/kern/subr_prf.c
+++ b/sys/kern/subr_prf.c
@@ -640,9 +640,12 @@
*
* where <base> is the output base expressed as a control character, e.g.
* \10 gives octal; \20 gives hex. Each arg is a sequence of characters,
- * the first of which gives the bit number to be inspected (origin 1), and
- * the next characters (up to a control character, i.e. a character <= 32),
- * give the name of the register. Thus:
+ * the first of which gives the bit number to be inspected and the next
+ * characters (up to the bit number of the next argument or a final NUL
+ * character), give the name of the register.
+ * The bit number can be encoded as a character between 1 and 32 or as a
+ * character between 128 and 255.
+ * Thus:
*
* kvprintf("reg=%b\n", 3, "\10\2BITTWO\1BITONE");
*
@@ -650,10 +653,27 @@
*
* reg=3<BITTWO,BITONE>
*
+ * The same output would be generated by using:
+ *
+ * kvprintf("reg=%b\n", 3, "\10\201BITTWO\200BITONE");
+ *
* XXX: %D -- Hexdump, takes pointer and separator string:
* ("%6D", ptr, ":") -> XX:XX:XX:XX:XX:XX
* ("%*D", len, ptr, " " -> XX XX XX XX ...
*/
+
+static inline bool
+isbitpos(char c)
+{
+ return (c != '\0' && (c <= ' ' || (c & 0x80) != 0));
+}
+
+static inline bool
+isprintnospace(char c)
+{
+ return (isprint(c) && c != ' ');
+}
+
int
kvprintf(char const *fmt, void (*func)(int, void*), void *arg, int radix, va_list ap)
{
@@ -950,15 +970,18 @@
if (bconv && num != 0) {
/* %b conversion flag format. */
tmp = retval;
- while (*q) {
- n = *q++;
- if (num & (1 << (n - 1))) {
+ while (isbitpos(*q)) {
+ if ((*q & 0x80) != 0)
+ n = *q++ & 0x7f;
+ else
+ n = *q++ - 1;
+ if (num & (1ULL << n)) {
PCHAR(retval != tmp ?
',' : '<');
- for (; (n = *q) > ' '; ++q)
- PCHAR(n);
+ for (; isprintnospace(*q); ++q)
+ PCHAR(*q);
} else
- for (; *q > ' '; ++q)
+ for (; isprintnospace(*q); ++q)
continue;
}
if (retval != tmp) {

File Metadata

Mime Type
text/plain
Expires
Sat, Dec 20, 2:09 AM (17 m, 46 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27079811
Default Alt Text
D54286.id168316.diff (3 KB)

Event Timeline