Fri Dec 6 19:36:22 2019 UTC ()
Formalize that the printf formats should be uintmax_t so we can
uniformly use 'j' in the user-provided formatting strings instead
of depending on _LP64 to use 'll' or 'l' (and the PRI macros). The
alternative is to parse the printf format manually to determine
which modifier to apply which would make this transparent to the
user (they could still always use '%u' or '%x'), but that's too
painful.


(christos)
diff -r1.21 -r1.22 src/common/lib/libutil/snprintb.c

cvs diff -r1.21 -r1.22 src/common/lib/libutil/snprintb.c (expand / switch to unified diff)

--- src/common/lib/libutil/snprintb.c 2019/06/17 17:03:58 1.21
+++ src/common/lib/libutil/snprintb.c 2019/12/06 19:36:22 1.22
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: snprintb.c,v 1.21 2019/06/17 17:03:58 christos Exp $ */ 1/* $NetBSD: snprintb.c,v 1.22 2019/12/06 19:36:22 christos Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2002 The NetBSD Foundation, Inc. 4 * Copyright (c) 2002 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -31,37 +31,37 @@ @@ -31,37 +31,37 @@
31 * 31 *
32 * => returns the length of the buffer that would be required to print the 32 * => returns the length of the buffer that would be required to print the
33 * string minus the terminating NUL. 33 * string minus the terminating NUL.
34 */ 34 */
35#ifndef _STANDALONE 35#ifndef _STANDALONE
36# ifndef _KERNEL 36# ifndef _KERNEL
37 37
38# if HAVE_NBTOOL_CONFIG_H 38# if HAVE_NBTOOL_CONFIG_H
39# include "nbtool_config.h" 39# include "nbtool_config.h"
40# endif 40# endif
41 41
42# include <sys/cdefs.h> 42# include <sys/cdefs.h>
43# if defined(LIBC_SCCS) && !defined(lint) 43# if defined(LIBC_SCCS) && !defined(lint)
44__RCSID("$NetBSD: snprintb.c,v 1.21 2019/06/17 17:03:58 christos Exp $"); 44__RCSID("$NetBSD: snprintb.c,v 1.22 2019/12/06 19:36:22 christos Exp $");
45# endif 45# endif
46 46
47# include <sys/types.h> 47# include <sys/types.h>
48# include <inttypes.h> 48# include <inttypes.h>
49# include <stdio.h> 49# include <stdio.h>
50# include <util.h> 50# include <util.h>
51# include <errno.h> 51# include <errno.h>
52# else /* ! _KERNEL */ 52# else /* ! _KERNEL */
53# include <sys/cdefs.h> 53# include <sys/cdefs.h>
54__KERNEL_RCSID(0, "$NetBSD: snprintb.c,v 1.21 2019/06/17 17:03:58 christos Exp $"); 54__KERNEL_RCSID(0, "$NetBSD: snprintb.c,v 1.22 2019/12/06 19:36:22 christos Exp $");
55# include <sys/param.h> 55# include <sys/param.h>
56# include <sys/inttypes.h> 56# include <sys/inttypes.h>
57# include <sys/systm.h> 57# include <sys/systm.h>
58# include <lib/libkern/libkern.h> 58# include <lib/libkern/libkern.h>
59# endif /* ! _KERNEL */ 59# endif /* ! _KERNEL */
60 60
61# ifndef HAVE_SNPRINTB_M 61# ifndef HAVE_SNPRINTB_M
62int 62int
63snprintb_m(char *buf, size_t buflen, const char *bitfmt, uint64_t val, 63snprintb_m(char *buf, size_t buflen, const char *bitfmt, uint64_t val,
64 size_t l_max) 64 size_t l_max)
65{ 65{
66 char *bp = buf, *s_bp = NULL; 66 char *bp = buf, *s_bp = NULL;
67 const char *c_fmt, *s_fmt = NULL, *cur_fmt; 67 const char *c_fmt, *s_fmt = NULL, *cur_fmt;
@@ -71,43 +71,43 @@ snprintb_m(char *buf, size_t buflen, con @@ -71,43 +71,43 @@ snprintb_m(char *buf, size_t buflen, con
71 uint64_t field; 71 uint64_t field;
72 72
73#ifdef _KERNEL 73#ifdef _KERNEL
74 /* 74 /*
75 * For safety; no other *s*printf() do this, but in the kernel 75 * For safety; no other *s*printf() do this, but in the kernel
76 * we don't usually check the return value 76 * we don't usually check the return value
77 */ 77 */
78 (void)memset(buf, 0, buflen); 78 (void)memset(buf, 0, buflen);
79#endif /* _KERNEL */ 79#endif /* _KERNEL */
80 80
81 ch = *bitfmt++; 81 ch = *bitfmt++;
82 switch (ch != '\177' ? ch : *bitfmt++) { 82 switch (ch != '\177' ? ch : *bitfmt++) {
83 case 8: 83 case 8:
84 sbase = "0%" PRIo64; 84 sbase = "%#jo";
85 break; 85 break;
86 case 10: 86 case 10:
87 sbase = "%" PRId64; 87 sbase = "%ju";
88 break; 88 break;
89 case 16: 89 case 16:
90 sbase = "0x%" PRIx64; 90 sbase = "%#jx";
91 break; 91 break;
92 default: 92 default:
93 goto internal; 93 goto internal;
94 } 94 }
95 95
96 /* Reserve space for trailing blank line if needed */ 96 /* Reserve space for trailing blank line if needed */
97 if (l_max > 0) 97 if (l_max > 0)
98 buflen--; 98 buflen--;
99 99
100 t_len = snprintf(bp, buflen, sbase, val); 100 t_len = snprintf(bp, buflen, sbase, (uintmax_t)val);
101 if (t_len < 0) 101 if (t_len < 0)
102 goto internal; 102 goto internal;
103 103
104 v_len = l_len = t_len; 104 v_len = l_len = t_len;
105 105
106 if ((size_t)t_len < buflen) 106 if ((size_t)t_len < buflen)
107 bp += t_len; 107 bp += t_len;
108 else 108 else
109 bp += buflen - 1; 109 bp += buflen - 1;
110 110
111 /* 111 /*
112 * If the value we printed was 0 and we're using the old-style format, 112 * If the value we printed was 0 and we're using the old-style format,
113 * we're done. 113 * we're done.
@@ -118,27 +118,27 @@ snprintb_m(char *buf, size_t buflen, con @@ -118,27 +118,27 @@ snprintb_m(char *buf, size_t buflen, con
118#define STORE(c) do { l_len++; \ 118#define STORE(c) do { l_len++; \
119 if ((size_t)(++t_len) < buflen) \ 119 if ((size_t)(++t_len) < buflen) \
120 *bp++ = (c); \ 120 *bp++ = (c); \
121 } while ( /* CONSTCOND */ 0) 121 } while ( /* CONSTCOND */ 0)
122 122
123#define BACKUP do { if (s_bp != NULL) { \ 123#define BACKUP do { if (s_bp != NULL) { \
124 bp = s_bp; s_bp = NULL; \ 124 bp = s_bp; s_bp = NULL; \
125 t_len -= l_len - s_len; \ 125 t_len -= l_len - s_len; \
126 restart = 1; \ 126 restart = 1; \
127 bitfmt = s_fmt; \ 127 bitfmt = s_fmt; \
128 } \ 128 } \
129 STORE('>'); STORE('\0'); \ 129 STORE('>'); STORE('\0'); \
130 if ((size_t)t_len < buflen) \ 130 if ((size_t)t_len < buflen) \
131 snprintf(bp, buflen - t_len, sbase, val); \ 131 snprintf(bp, buflen - t_len, sbase, (uintmax_t)val);\
132 t_len += v_len; l_len = v_len; bp += v_len; \ 132 t_len += v_len; l_len = v_len; bp += v_len; \
133 } while ( /* CONSTCOND */ 0) 133 } while ( /* CONSTCOND */ 0)
134 134
135#define PUTSEP do { \ 135#define PUTSEP do { \
136 if (l_max > 0 && (size_t)l_len >= l_max) { \ 136 if (l_max > 0 && (size_t)l_len >= l_max) { \
137 BACKUP; \ 137 BACKUP; \
138 STORE('<'); \ 138 STORE('<'); \
139 } else { \ 139 } else { \
140 /* Remember separator location */ \ 140 /* Remember separator location */ \
141 if (l_max > 0 && sep != '<') { \ 141 if (l_max > 0 && sep != '<') { \
142 s_len = l_len; \ 142 s_len = l_len; \
143 s_bp = bp; \ 143 s_bp = bp; \
144 s_fmt = cur_fmt; \ 144 s_fmt = cur_fmt; \
@@ -158,27 +158,27 @@ snprintb_m(char *buf, size_t buflen, con @@ -158,27 +158,27 @@ snprintb_m(char *buf, size_t buflen, con
158 } else { \ 158 } else { \
159 STORE(c); \ 159 STORE(c); \
160 restart = 0; \ 160 restart = 0; \
161 } \ 161 } \
162 } while ( /* CONSTCOND */ 0) 162 } while ( /* CONSTCOND */ 0)
163 163
164#define PUTS(s) while ((ch = *(s)++) != 0) { \ 164#define PUTS(s) while ((ch = *(s)++) != 0) { \
165 PUTCHR(ch); \ 165 PUTCHR(ch); \
166 if (restart) \ 166 if (restart) \
167 break; \ 167 break; \
168 } 168 }
169#define FMTSTR(sb, f) \ 169#define FMTSTR(sb, f) \
170 do { \ 170 do { \
171 f_len = snprintf(bp, buflen - t_len, sb, f); \ 171 f_len = snprintf(bp, buflen - t_len, sb, (uintmax_t)f); \
172 if (f_len < 0) \ 172 if (f_len < 0) \
173 goto internal; \ 173 goto internal; \
174 t_len += f_len; \ 174 t_len += f_len; \
175 l_len += f_len; \ 175 l_len += f_len; \
176 if ((size_t)t_len < buflen) \ 176 if ((size_t)t_len < buflen) \
177 bp += f_len; \ 177 bp += f_len; \
178 } while (/*CONSTCOND*/0) 178 } while (/*CONSTCOND*/0)
179 179
180 /* 180 /*
181 * Chris Torek's new bitmask format is identified by a leading \177 181 * Chris Torek's new bitmask format is identified by a leading \177
182 */ 182 */
183 sep = '<'; 183 sep = '<';
184 if (ch != '\177') { 184 if (ch != '\177') {