summaryrefslogtreecommitdiff
path: root/lib/printf
diff options
context:
space:
mode:
Diffstat (limited to 'lib/printf')
-rw-r--r--lib/printf/README7
-rw-r--r--lib/printf/glue.c6
-rw-r--r--lib/printf/printf-pos.c20
-rw-r--r--lib/printf/printfcommon.h20
-rw-r--r--lib/printf/printflocal.h3
-rw-r--r--lib/printf/vfprintf.c71
6 files changed, 100 insertions, 27 deletions
diff --git a/lib/printf/README b/lib/printf/README
index ac283642d7..3c3ef74ca8 100644
--- a/lib/printf/README
+++ b/lib/printf/README
@@ -1,6 +1,7 @@
-This is the printf implementation from FreeBSD. It was imported on 2019-05-12,
-from SVN revision 347514 (but the code hadn't been touched for 2 years before
-that.)
+This is the printf implementation from FreeBSD. The history of this code is:
+- imported on 2019-05-12, from SVN revision 347514
+- resynced on 2023-09-03, to pick up `%b` implementation
+- resynced on 2024-03-10, to pick up `%w[f](8|16|32|64)d` implementation
Please don't reindent or otherwise mangle the files to make importing fixes
easy (not that there are significant changes likely to happen...)
diff --git a/lib/printf/glue.c b/lib/printf/glue.c
index 25e2ff37a3..f799378af3 100644
--- a/lib/printf/glue.c
+++ b/lib/printf/glue.c
@@ -273,6 +273,7 @@ static ssize_t printfrr_va(struct fbuf *buf, struct printfrr_eargs *ea,
{
const struct va_format *vaf = ptr;
va_list ap;
+ ssize_t s;
if (!vaf || !vaf->fmt || !vaf->va)
return bputs(buf, "NULL");
@@ -285,6 +286,9 @@ static ssize_t printfrr_va(struct fbuf *buf, struct printfrr_eargs *ea,
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
/* can't format check this */
- return vbprintfrr(buf, vaf->fmt, ap);
+ s = vbprintfrr(buf, vaf->fmt, ap);
#pragma GCC diagnostic pop
+ va_end(ap);
+
+ return s;
}
diff --git a/lib/printf/printf-pos.c b/lib/printf/printf-pos.c
index ac775bea4e..b2ba1a714d 100644
--- a/lib/printf/printf-pos.c
+++ b/lib/printf/printf-pos.c
@@ -355,7 +355,7 @@ reswitch: switch (ch) {
goto rflag;
case 'C':
flags |= LONGINT;
- /*FALLTHROUGH*/
+ fallthrough;
case 'c':
error = addtype(&types,
(flags & LONGINT) ? T_WINT : T_INT);
@@ -364,7 +364,7 @@ reswitch: switch (ch) {
break;
case 'D':
flags |= LONGINT;
- /*FALLTHROUGH*/
+ fallthrough;
case 'd':
case 'i':
if ((error = addsarg(&types, flags)))
@@ -408,7 +408,7 @@ reswitch: switch (ch) {
#endif
case 'O':
flags |= LONGINT;
- /*FALLTHROUGH*/
+ fallthrough;
case 'o':
if ((error = adduarg(&types, flags)))
goto error;
@@ -419,7 +419,7 @@ reswitch: switch (ch) {
break;
case 'S':
flags |= LONGINT;
- /*FALLTHROUGH*/
+ fallthrough;
case 's':
error = addtype(&types,
(flags & LONGINT) ? TP_WCHAR : TP_CHAR);
@@ -428,7 +428,7 @@ reswitch: switch (ch) {
break;
case 'U':
flags |= LONGINT;
- /*FALLTHROUGH*/
+ fallthrough;
case 'u':
case 'X':
case 'x':
@@ -549,7 +549,7 @@ reswitch: switch (ch) {
goto rflag;
case 'C':
flags |= LONGINT;
- /*FALLTHROUGH*/
+ fallthrough;
case 'c':
error = addtype(&types,
(flags & LONGINT) ? T_WINT : T_INT);
@@ -558,7 +558,7 @@ reswitch: switch (ch) {
break;
case 'D':
flags |= LONGINT;
- /*FALLTHROUGH*/
+ fallthrough;
case 'd':
case 'i':
if ((error = addsarg(&types, flags)))
@@ -602,7 +602,7 @@ reswitch: switch (ch) {
#endif
case 'O':
flags |= LONGINT;
- /*FALLTHROUGH*/
+ fallthrough;
case 'o':
if ((error = adduarg(&types, flags)))
goto error;
@@ -613,7 +613,7 @@ reswitch: switch (ch) {
break;
case 'S':
flags |= LONGINT;
- /*FALLTHROUGH*/
+ fallthrough;
case 's':
error = addtype(&types,
(flags & LONGINT) ? TP_WCHAR : TP_CHAR);
@@ -622,7 +622,7 @@ reswitch: switch (ch) {
break;
case 'U':
flags |= LONGINT;
- /*FALLTHROUGH*/
+ fallthrough;
case 'u':
case 'X':
case 'x':
diff --git a/lib/printf/printfcommon.h b/lib/printf/printfcommon.h
index 5c45520b4c..f777be8805 100644
--- a/lib/printf/printfcommon.h
+++ b/lib/printf/printfcommon.h
@@ -8,7 +8,7 @@
* Chris Torek.
*
* Copyright (c) 2011 The FreeBSD Foundation
- * All rights reserved.
+ *
* Portions of this software were developed by David Chisnall
* under sponsorship from the FreeBSD Foundation.
*
@@ -35,8 +35,6 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
/*
@@ -70,7 +68,7 @@ io_print(struct io_state *iop, const CHAR * __restrict ptr, size_t len)
{
size_t copylen = len;
- if (!iop->cb)
+ if (!iop->cb || !len)
return 0;
if (iop->avail < copylen)
copylen = iop->avail;
@@ -171,6 +169,13 @@ __ultoa(u_long val, CHAR *endp, int base, int octzero, const char *xdigs)
} while (sval != 0);
break;
+ case 2:
+ do {
+ *--cp = to_char(val & 1);
+ val >>= 1;
+ } while (val);
+ break;
+
case 8:
do {
*--cp = to_char(val & 7);
@@ -221,6 +226,13 @@ __ujtoa(uintmax_t val, CHAR *endp, int base, int octzero, const char *xdigs)
} while (sval != 0);
break;
+ case 2:
+ do {
+ *--cp = to_char(val & 1);
+ val >>= 1;
+ } while (val);
+ break;
+
case 8:
do {
*--cp = to_char(val & 7);
diff --git a/lib/printf/printflocal.h b/lib/printf/printflocal.h
index bac80e801c..93318c8fdb 100644
--- a/lib/printf/printflocal.h
+++ b/lib/printf/printflocal.h
@@ -30,8 +30,6 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#include "compiler.h"
@@ -54,6 +52,7 @@
#define PTRDIFFT 0x800 /* ptrdiff_t */
#define INTMAXT 0x1000 /* intmax_t */
#define CHARINT 0x2000 /* print char using int format */
+#define FASTINT 0x4000 /* int_fastN_t */
/*
* Macros for converting digits to letters and vice versa
diff --git a/lib/printf/vfprintf.c b/lib/printf/vfprintf.c
index cc886834fa..3f6700c838 100644
--- a/lib/printf/vfprintf.c
+++ b/lib/printf/vfprintf.c
@@ -8,7 +8,7 @@
* Chris Torek.
*
* Copyright (c) 2011 The FreeBSD Foundation
- * All rights reserved.
+ *
* Portions of this software were developed by David Chisnall
* under sponsorship from the FreeBSD Foundation.
*
@@ -340,7 +340,7 @@ reswitch: switch (ch) {
if (width >= 0)
goto rflag;
width = -width;
- /* FALLTHROUGH */
+ fallthrough;
case '-':
flags |= LADJUST;
goto rflag;
@@ -416,12 +416,68 @@ reswitch: switch (ch) {
case 't':
flags |= PTRDIFFT;
goto rflag;
+ case 'w':
+ /*
+ * Fixed-width integer types. On all platforms we
+ * support, int8_t is equivalent to char, int16_t
+ * is equivalent to short, int32_t is equivalent
+ * to int, int64_t is equivalent to long long int.
+ * Furthermore, int_fast8_t, int_fast16_t and
+ * int_fast32_t are equivalent to int, and
+ * int_fast64_t is equivalent to long long int.
+ */
+ flags &= ~(CHARINT|SHORTINT|LONGINT|LLONGINT|INTMAXT);
+ if (fmt[0] == 'f') {
+ flags |= FASTINT;
+ fmt++;
+ } else {
+ flags &= ~FASTINT;
+ }
+ if (fmt[0] == '8') {
+ if (!(flags & FASTINT))
+ flags |= CHARINT;
+ else
+ (void) 0; /* no flag set = 32 */
+ fmt += 1;
+ } else if (fmt[0] == '1' && fmt[1] == '6') {
+ if (!(flags & FASTINT))
+ flags |= SHORTINT;
+ else
+ (void) 0; /* no flag set = 32 */
+ fmt += 2;
+ } else if (fmt[0] == '3' && fmt[1] == '2') {
+ /* no flag set = 32 */
+ fmt += 2;
+ } else if (fmt[0] == '6' && fmt[1] == '4') {
+ flags |= LLONGINT;
+ fmt += 2;
+ } else {
+ if (flags & FASTINT) {
+ flags &= ~FASTINT;
+ fmt--;
+ }
+ goto invalid;
+ }
+ goto rflag;
case 'z':
flags |= SIZET;
goto rflag;
+ case 'B':
+ case 'b':
+ if (flags & INTMAX_SIZE)
+ ujval = UJARG();
+ else
+ ulval = UARG();
+ base = 2;
+ /* leading 0b/B only if non-zero */
+ if (flags & ALT &&
+ (flags & INTMAX_SIZE ? ujval != 0 : ulval != 0))
+ ox[1] = ch;
+ goto nosign;
+ break;
case 'C':
flags |= LONGINT;
- /*FALLTHROUGH*/
+ fallthrough;
case 'c':
#ifdef WCHAR_SUPPORT
if (flags & LONGINT) {
@@ -447,7 +503,7 @@ reswitch: switch (ch) {
break;
case 'D':
flags |= LONGINT;
- /*FALLTHROUGH*/
+ fallthrough;
case 'd':
case 'i':
if (flags & INTMAX_SIZE)
@@ -538,7 +594,7 @@ reswitch: switch (ch) {
break;
case 'O':
flags |= LONGINT;
- /*FALLTHROUGH*/
+ fallthrough;
case 'o':
if (flags & INTMAX_SIZE)
ujval = UJARG();
@@ -582,7 +638,7 @@ reswitch: switch (ch) {
goto nosign;
case 'S':
flags |= LONGINT;
- /*FALLTHROUGH*/
+ fallthrough;
case 's':
#ifdef WCHAR_SUPPORT
if (flags & LONGINT) {
@@ -608,7 +664,7 @@ reswitch: switch (ch) {
break;
case 'U':
flags |= LONGINT;
- /*FALLTHROUGH*/
+ fallthrough;
case 'u':
if (flags & INTMAX_SIZE)
ujval = UJARG();
@@ -671,6 +727,7 @@ number: if ((dprec = prec) >= 0)
default: /* "%?" prints ?, unless ? is NUL */
if (ch == '\0')
goto done;
+invalid:
/* pretend it was %c with argument ch */
buf[0] = ch;
cp = buf;