mailing list of musl libc
 help / color / mirror / code / Atom feed
* [musl] [C23 printf 0/3] to be replaced
@ 2023-05-31 14:04 Jens Gustedt
  2023-05-31 14:04 ` [musl] [C23 printf 1/3] C23: implement the b and B printf specifiers Jens Gustedt
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Jens Gustedt @ 2023-05-31 14:04 UTC (permalink / raw)
  To: musl

There have been other approaches proposed for these patches that are
considered superior to these here, although functionally
equivalent. Take these ones here to ensure a functioning C23 system
with 128 bit support, now. The 128 bit patches will be rebased on the
new approaches once their implementation is completed.

Jens Gustedt (3):
  C23: implement the b and B printf specifiers
  C23: implement the wN length specifiers for printf
  C23: implement the wfN length modifiers for printf

 include/inttypes.h    | 34 +++++++++++++++++++++++++++++
 src/stdio/vfprintf.c  | 50 +++++++++++++++++++++++++++++++++++++++----
 src/stdio/vfwprintf.c | 42 +++++++++++++++++++++++++++++++-----
 3 files changed, 117 insertions(+), 9 deletions(-)

-- 
2.34.1


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [musl] [C23 printf 1/3] C23: implement the b and B printf specifiers
  2023-05-31 14:04 [musl] [C23 printf 0/3] to be replaced Jens Gustedt
@ 2023-05-31 14:04 ` Jens Gustedt
  2023-05-31 14:04 ` [musl] [C23 printf 2/3] C23: implement the wN length specifiers for printf Jens Gustedt
  2023-05-31 14:04 ` [musl] [C23 printf 3/3] C23: implement the wfN length modifiers " Jens Gustedt
  2 siblings, 0 replies; 8+ messages in thread
From: Jens Gustedt @ 2023-05-31 14:04 UTC (permalink / raw)
  To: musl

The b specifier is mandatory for C23. It has been reserved previously,
so we may safely add it, even for older compilation modes.

The B specifier is optional, but recommended for those implementations
that didn't have it reserved previously for other purposes.

The PRIbXXX and PRIBXXX macros are mandatory if the specifiers are
supported and may serve as feature test macros for users.
---
 include/inttypes.h    | 34 ++++++++++++++++++++++++++++++++++
 src/stdio/vfprintf.c  | 19 ++++++++++++++++++-
 src/stdio/vfwprintf.c | 11 +++++++++--
 3 files changed, 61 insertions(+), 3 deletions(-)

diff --git a/include/inttypes.h b/include/inttypes.h
index 61dcb727..73a42e32 100644
--- a/include/inttypes.h
+++ b/include/inttypes.h
@@ -120,12 +120,44 @@ uintmax_t wcstoumax(const wchar_t *__restrict, wchar_t **__restrict, int);
 #define PRIXFAST32 "X"
 #define PRIXFAST64 __PRI64 "X"
 
+#define PRIb8  "b"
+#define PRIb16 "b"
+#define PRIb32 "b"
+#define PRIb64 __PRI64 "b"
+
+#define PRIbLEAST8  "b"
+#define PRIbLEAST16 "b"
+#define PRIbLEAST32 "b"
+#define PRIbLEAST64 __PRI64 "b"
+
+#define PRIbFAST8  "b"
+#define PRIbFAST16 "b"
+#define PRIbFAST32 "b"
+#define PRIbFAST64 __PRI64 "b"
+
+#define PRIB8  "B"
+#define PRIB16 "B"
+#define PRIB32 "B"
+#define PRIB64 __PRI64 "B"
+
+#define PRIBLEAST8  "B"
+#define PRIBLEAST16 "B"
+#define PRIBLEAST32 "B"
+#define PRIBLEAST64 __PRI64 "B"
+
+#define PRIBFAST8  "B"
+#define PRIBFAST16 "B"
+#define PRIBFAST32 "B"
+#define PRIBFAST64 __PRI64 "B"
+
 #define PRIdMAX __PRI64 "d"
 #define PRIiMAX __PRI64 "i"
 #define PRIoMAX __PRI64 "o"
 #define PRIuMAX __PRI64 "u"
 #define PRIxMAX __PRI64 "x"
 #define PRIXMAX __PRI64 "X"
+#define PRIbMAX __PRI64 "b"
+#define PRIBMAX __PRI64 "B"
 
 #define PRIdPTR __PRIPTR "d"
 #define PRIiPTR __PRIPTR "i"
@@ -133,6 +165,8 @@ uintmax_t wcstoumax(const wchar_t *__restrict, wchar_t **__restrict, int);
 #define PRIuPTR __PRIPTR "u"
 #define PRIxPTR __PRIPTR "x"
 #define PRIXPTR __PRIPTR "X"
+#define PRIbPTR __PRIPTR "b"
+#define PRIBPTR __PRIPTR "B"
 
 #define SCNd8   "hhd"
 #define SCNd16  "hd"
diff --git a/src/stdio/vfprintf.c b/src/stdio/vfprintf.c
index a712d80f..cbc79783 100644
--- a/src/stdio/vfprintf.c
+++ b/src/stdio/vfprintf.c
@@ -48,6 +48,7 @@ enum {
 
 static const unsigned char states[]['z'-'A'+1] = {
 	{ /* 0: bare types */
+		S('b') = UINT, S('B') = UINT,
 		S('d') = INT, S('i') = INT,
 		S('o') = UINT, S('u') = UINT, S('x') = UINT, S('X') = UINT,
 		S('e') = DBL, S('f') = DBL, S('g') = DBL, S('a') = DBL,
@@ -58,6 +59,7 @@ static const unsigned char states[]['z'-'A'+1] = {
 		S('l') = LPRE, S('h') = HPRE, S('L') = BIGLPRE,
 		S('z') = ZTPRE, S('j') = JPRE, S('t') = ZTPRE,
 	}, { /* 1: l-prefixed */
+		S('b') = ULONG, S('B') = ULONG,
 		S('d') = LONG, S('i') = LONG,
 		S('o') = ULONG, S('u') = ULONG, S('x') = ULONG, S('X') = ULONG,
 		S('e') = DBL, S('f') = DBL, S('g') = DBL, S('a') = DBL,
@@ -65,17 +67,20 @@ static const unsigned char states[]['z'-'A'+1] = {
 		S('c') = INT, S('s') = PTR, S('n') = PTR,
 		S('l') = LLPRE,
 	}, { /* 2: ll-prefixed */
+		S('b') = ULLONG, S('B') = ULLONG,
 		S('d') = LLONG, S('i') = LLONG,
 		S('o') = ULLONG, S('u') = ULLONG,
 		S('x') = ULLONG, S('X') = ULLONG,
 		S('n') = PTR,
 	}, { /* 3: h-prefixed */
+		S('b') = USHORT, S('B') = USHORT,
 		S('d') = SHORT, S('i') = SHORT,
 		S('o') = USHORT, S('u') = USHORT,
 		S('x') = USHORT, S('X') = USHORT,
 		S('n') = PTR,
 		S('h') = HHPRE,
 	}, { /* 4: hh-prefixed */
+		S('b') = UCHAR, S('B') = UCHAR,
 		S('d') = CHAR, S('i') = CHAR,
 		S('o') = UCHAR, S('u') = UCHAR,
 		S('x') = UCHAR, S('X') = UCHAR,
@@ -85,11 +90,13 @@ static const unsigned char states[]['z'-'A'+1] = {
 		S('E') = LDBL, S('F') = LDBL, S('G') = LDBL, S('A') = LDBL,
 		S('n') = PTR,
 	}, { /* 6: z- or t-prefixed (assumed to be same size) */
+		S('b') = SIZET, S('B') = SIZET,
 		S('d') = PDIFF, S('i') = PDIFF,
 		S('o') = SIZET, S('u') = SIZET,
 		S('x') = SIZET, S('X') = SIZET,
 		S('n') = PTR,
 	}, { /* 7: j-prefixed */
+		S('b') = UMAX, S('B') = UMAX,
 		S('d') = IMAX, S('i') = IMAX,
 		S('o') = UMAX, S('u') = UMAX,
 		S('x') = UMAX, S('X') = UMAX,
@@ -156,6 +163,12 @@ static char *fmt_x(uintmax_t x, char *s, int lower)
 	return s;
 }
 
+static char *fmt_b(uintmax_t x, char *s)
+{
+	for (; x; x>>=1) *--s = '0' + (x&1);
+	return s;
+}
+
 static char *fmt_o(uintmax_t x, char *s)
 {
 	for (; x; x>>=3) *--s = '0' + (x&7);
@@ -437,7 +450,7 @@ static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg,
 	unsigned st, ps;
 	int cnt=0, l=0;
 	size_t i;
-	char buf[sizeof(uintmax_t)*3+3+LDBL_MANT_DIG/4];
+	char buf[sizeof(uintmax_t)*CHAR_BIT+3+LDBL_MANT_DIG/4];
 	const char *prefix;
 	int t, pl;
 	wchar_t wc[2], *ws;
@@ -564,6 +577,10 @@ static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg,
 			a = fmt_x(arg.i, z, t&32);
 			if (arg.i && (fl & ALT_FORM)) prefix+=(t>>4), pl=2;
 			if (0) {
+		case 'b': case 'B':
+			a = fmt_b(arg.i, z);
+			if (arg.i && (fl & ALT_FORM)) prefix = (t == 'b' ? "0b" : "0B"), pl=2;
+			} if (0) {
 		case 'o':
 			a = fmt_o(arg.i, z);
 			if ((fl&ALT_FORM) && p<z-a+1) p=z-a+1;
diff --git a/src/stdio/vfwprintf.c b/src/stdio/vfwprintf.c
index 53697701..dbc93f74 100644
--- a/src/stdio/vfwprintf.c
+++ b/src/stdio/vfwprintf.c
@@ -41,6 +41,7 @@ enum {
 
 static const unsigned char states[]['z'-'A'+1] = {
 	{ /* 0: bare types */
+		S('b') = UINT, S('B') = UINT,
 		S('d') = INT, S('i') = INT,
 		S('o') = UINT, S('u') = UINT, S('x') = UINT, S('X') = UINT,
 		S('e') = DBL, S('f') = DBL, S('g') = DBL, S('a') = DBL,
@@ -51,6 +52,7 @@ static const unsigned char states[]['z'-'A'+1] = {
 		S('l') = LPRE, S('h') = HPRE, S('L') = BIGLPRE,
 		S('z') = ZTPRE, S('j') = JPRE, S('t') = ZTPRE,
 	}, { /* 1: l-prefixed */
+		S('b') = ULONG, S('B') = ULONG,
 		S('d') = LONG, S('i') = LONG,
 		S('o') = ULONG, S('u') = ULONG, S('x') = ULONG, S('X') = ULONG,
 		S('e') = DBL, S('f') = DBL, S('g') = DBL, S('a') = DBL,
@@ -58,17 +60,20 @@ static const unsigned char states[]['z'-'A'+1] = {
 		S('c') = INT, S('s') = PTR, S('n') = PTR,
 		S('l') = LLPRE,
 	}, { /* 2: ll-prefixed */
+		S('b') = ULLONG, S('B') = ULLONG,
 		S('d') = LLONG, S('i') = LLONG,
 		S('o') = ULLONG, S('u') = ULLONG,
 		S('x') = ULLONG, S('X') = ULLONG,
 		S('n') = PTR,
 	}, { /* 3: h-prefixed */
+		S('b') = USHORT, S('B') = USHORT,
 		S('d') = SHORT, S('i') = SHORT,
 		S('o') = USHORT, S('u') = USHORT,
 		S('x') = USHORT, S('X') = USHORT,
 		S('n') = PTR,
 		S('h') = HHPRE,
 	}, { /* 4: hh-prefixed */
+		S('b') = UCHAR, S('B') = UCHAR,
 		S('d') = CHAR, S('i') = CHAR,
 		S('o') = UCHAR, S('u') = UCHAR,
 		S('x') = UCHAR, S('X') = UCHAR,
@@ -78,11 +83,13 @@ static const unsigned char states[]['z'-'A'+1] = {
 		S('E') = LDBL, S('F') = LDBL, S('G') = LDBL, S('A') = LDBL,
 		S('n') = PTR,
 	}, { /* 6: z- or t-prefixed (assumed to be same size) */
+		S('b') = SIZET, S('B') = SIZET,
 		S('d') = PDIFF, S('i') = PDIFF,
 		S('o') = SIZET, S('u') = SIZET,
 		S('x') = SIZET, S('X') = SIZET,
 		S('n') = PTR,
 	}, { /* 7: j-prefixed */
+		S('b') = UMAX, S('B') = UMAX,
 		S('d') = IMAX, S('i') = IMAX,
 		S('o') = UMAX, S('u') = UMAX,
 		S('x') = UMAX, S('X') = UMAX,
@@ -145,7 +152,7 @@ static int getint(wchar_t **s) {
 
 static const char sizeprefix['y'-'a'] = {
 ['a'-'a']='L', ['e'-'a']='L', ['f'-'a']='L', ['g'-'a']='L',
-['d'-'a']='j', ['i'-'a']='j', ['o'-'a']='j', ['u'-'a']='j', ['x'-'a']='j',
+['b'-'a']='j', ['d'-'a']='j', ['i'-'a']='j', ['o'-'a']='j', ['u'-'a']='j', ['x'-'a']='j',
 ['p'-'a']='j'
 };
 
@@ -321,7 +328,7 @@ static int wprintf_core(FILE *f, const wchar_t *fmt, va_list *ap, union arg *nl_
 		case 'a': case 'e': case 'f': case 'g':
 			l = fprintf(f, charfmt, w, p, arg.f);
 			break;
-		case 'd': case 'i': case 'o': case 'u': case 'x': case 'p':
+		case 'b': case 'd': case 'i': case 'o': case 'u': case 'x': case 'p':
 			l = fprintf(f, charfmt, w, p, arg.i);
 			break;
 		}
-- 
2.34.1


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [musl] [C23 printf 2/3] C23: implement the wN length specifiers for printf
  2023-05-31 14:04 [musl] [C23 printf 0/3] to be replaced Jens Gustedt
  2023-05-31 14:04 ` [musl] [C23 printf 1/3] C23: implement the b and B printf specifiers Jens Gustedt
@ 2023-05-31 14:04 ` Jens Gustedt
  2023-05-31 14:04 ` [musl] [C23 printf 3/3] C23: implement the wfN length modifiers " Jens Gustedt
  2 siblings, 0 replies; 8+ messages in thread
From: Jens Gustedt @ 2023-05-31 14:04 UTC (permalink / raw)
  To: musl

These are mandatory for C23 and concern all types for which the
platform has `int_leastN_t` and `uint_leastN_t`. For musl these types
always coincide with `intN_t` and `uintN_t` and are always present for
N equal 8, 16, 32 and 64.

They can be added for general use since all lowercase letters were
previously reserved.

Nevertheless, users that use these modifiers will see a lot of
warnings from compilers in the beginning. This is because the
compilers have not yet integrated this form of a specifier into their
correponding extensions (gcc attributes). So unfortunately also
testing this feature may be a bit noisy for the moment.

The only architecture dependend choice is the type for N == 64, which
may be `long` or `long long`. We just mimick the test that is done in
other places to compare `UINTPTR_MAX` and `UINT64_MAX` to determine
that.
---
 src/stdio/vfprintf.c  | 28 +++++++++++++++++++++++++---
 src/stdio/vfwprintf.c | 28 +++++++++++++++++++++++++---
 2 files changed, 50 insertions(+), 6 deletions(-)

diff --git a/src/stdio/vfprintf.c b/src/stdio/vfprintf.c
index cbc79783..265fb7ad 100644
--- a/src/stdio/vfprintf.c
+++ b/src/stdio/vfprintf.c
@@ -33,7 +33,7 @@
 
 enum {
 	BARE, LPRE, LLPRE, HPRE, HHPRE, BIGLPRE,
-	ZTPRE, JPRE,
+	ZTPRE, JPRE, WPRE,
 	STOP,
 	PTR, INT, UINT, ULLONG,
 	LONG, ULONG,
@@ -57,7 +57,7 @@ static const unsigned char states[]['z'-'A'+1] = {
 		S('s') = PTR, S('S') = PTR, S('p') = UIPTR, S('n') = PTR,
 		S('m') = NOARG,
 		S('l') = LPRE, S('h') = HPRE, S('L') = BIGLPRE,
-		S('z') = ZTPRE, S('j') = JPRE, S('t') = ZTPRE,
+		S('z') = ZTPRE, S('j') = JPRE, S('t') = ZTPRE, S('w') = WPRE,
 	}, { /* 1: l-prefixed */
 		S('b') = ULONG, S('B') = ULONG,
 		S('d') = LONG, S('i') = LONG,
@@ -101,6 +101,12 @@ static const unsigned char states[]['z'-'A'+1] = {
 		S('o') = UMAX, S('u') = UMAX,
 		S('x') = UMAX, S('X') = UMAX,
 		S('n') = PTR,
+	}, { /* 8: w-prefixed */
+		S('b') = UINT, S('B') = UINT,
+		S('d') = INT, S('i') = INT,
+		S('o') = UINT, S('u') = UINT,
+		S('x') = UINT, S('X') = UINT,
+		S('n') = PTR,
 	}
 };
 
@@ -447,7 +453,7 @@ static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg,
 	int w, p, xp;
 	union arg arg;
 	int argpos;
-	unsigned st, ps;
+	unsigned st, ps, width=0;
 	int cnt=0, l=0;
 	size_t i;
 	char buf[sizeof(uintmax_t)*CHAR_BIT+3+LDBL_MANT_DIG/4];
@@ -527,9 +533,25 @@ static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg,
 			if (OOB(*s)) goto inval;
 			ps=st;
 			st=states[st]S(*s++);
+ 			if (st == WPRE) {
+				if (*s == '0') goto inval;
+				width = getint(&s);
+                        }
 		} while (st-1<STOP);
 		if (!st) goto inval;
 
+		if (ps == WPRE) switch (width) {
+		case 8:   ps = HHPRE; st = (st == UINT) ? UCHAR  : ((st == INT) ? CHAR  : PTR); break;
+		case 16:  ps = HPRE;  st = (st == UINT) ? USHORT : ((st == INT) ? SHORT : PTR); break;
+		case 32:  ps = BARE;  break;
+#if UINTPTR_MAX >= UINT64_MAX
+		case 64:  ps = LPRE;  st = (st == UINT) ? ULONG  : ((st == INT) ? LONG  : PTR); break;
+#else
+		case 64:  ps = LLPRE; st = (st == UINT) ? ULLONG : ((st == INT) ? LLONG : PTR); break;
+#endif
+		default:  goto inval;
+		}
+
 		/* Check validity of argument type (nl/normal) */
 		if (st==NOARG) {
 			if (argpos>=0) goto inval;
diff --git a/src/stdio/vfwprintf.c b/src/stdio/vfwprintf.c
index dbc93f74..c3e81d2a 100644
--- a/src/stdio/vfwprintf.c
+++ b/src/stdio/vfwprintf.c
@@ -26,7 +26,7 @@
 
 enum {
 	BARE, LPRE, LLPRE, HPRE, HHPRE, BIGLPRE,
-	ZTPRE, JPRE,
+	ZTPRE, JPRE, WPRE,
 	STOP,
 	PTR, INT, UINT, ULLONG,
 	LONG, ULONG,
@@ -50,7 +50,7 @@ static const unsigned char states[]['z'-'A'+1] = {
 		S('s') = PTR, S('S') = PTR, S('p') = UIPTR, S('n') = PTR,
 		S('m') = NOARG,
 		S('l') = LPRE, S('h') = HPRE, S('L') = BIGLPRE,
-		S('z') = ZTPRE, S('j') = JPRE, S('t') = ZTPRE,
+		S('z') = ZTPRE, S('j') = JPRE, S('t') = ZTPRE, S('w') = WPRE,
 	}, { /* 1: l-prefixed */
 		S('b') = ULONG, S('B') = ULONG,
 		S('d') = LONG, S('i') = LONG,
@@ -94,6 +94,12 @@ static const unsigned char states[]['z'-'A'+1] = {
 		S('o') = UMAX, S('u') = UMAX,
 		S('x') = UMAX, S('X') = UMAX,
 		S('n') = PTR,
+	}, { /* 8: w-prefixed */
+		S('b') = UINT, S('B') = UINT,
+		S('d') = INT, S('i') = INT,
+		S('o') = UINT, S('u') = UINT,
+		S('x') = UINT, S('X') = UINT,
+		S('n') = PTR,
 	}
 };
 
@@ -163,7 +169,7 @@ static int wprintf_core(FILE *f, const wchar_t *fmt, va_list *ap, union arg *nl_
 	int w, p, xp;
 	union arg arg;
 	int argpos;
-	unsigned st, ps;
+	unsigned st, ps, width=0;
 	int cnt=0, l=0;
 	int i;
 	int t;
@@ -242,9 +248,25 @@ static int wprintf_core(FILE *f, const wchar_t *fmt, va_list *ap, union arg *nl_
 			if (OOB(*s)) goto inval;
 			ps=st;
 			st=states[st]S(*s++);
+ 			if (st == WPRE) {
+				if (*s == L'0') goto inval;
+				width = getint(&s);
+                        }
 		} while (st-1<STOP);
 		if (!st) goto inval;
 
+		if (ps == WPRE) switch (width) {
+		case 8:   ps = HHPRE; st = (st == UINT) ? UCHAR  : ((st == INT) ? CHAR  : PTR); break;
+		case 16:  ps = HPRE;  st = (st == UINT) ? USHORT : ((st == INT) ? SHORT : PTR); break;
+		case 32:  ps = BARE;  break;
+#if UINTPTR_MAX >= UINT64_MAX
+		case 64:  ps = LPRE;  st = (st == UINT) ? ULONG  : ((st == INT) ? LONG  : PTR); break;
+#else
+		case 64:  ps = LLPRE; st = (st == UINT) ? ULLONG : ((st == INT) ? LLONG : PTR); break;
+#endif
+		default:  goto inval;
+		}
+
 		/* Check validity of argument type (nl/normal) */
 		if (st==NOARG) {
 			if (argpos>=0) goto inval;
-- 
2.34.1


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [musl] [C23 printf 3/3] C23: implement the wfN length modifiers for printf
  2023-05-31 14:04 [musl] [C23 printf 0/3] to be replaced Jens Gustedt
  2023-05-31 14:04 ` [musl] [C23 printf 1/3] C23: implement the b and B printf specifiers Jens Gustedt
  2023-05-31 14:04 ` [musl] [C23 printf 2/3] C23: implement the wN length specifiers for printf Jens Gustedt
@ 2023-05-31 14:04 ` Jens Gustedt
  2 siblings, 0 replies; 8+ messages in thread
From: Jens Gustedt @ 2023-05-31 14:04 UTC (permalink / raw)
  To: musl

Musl only has a difference between fixed-width and fastest-width
integer types for N == 16. And even here all architectures have made
the same choice, namely mapping to 32 bit types.
---
 src/stdio/vfprintf.c  | 3 +++
 src/stdio/vfwprintf.c | 3 +++
 2 files changed, 6 insertions(+)

diff --git a/src/stdio/vfprintf.c b/src/stdio/vfprintf.c
index 265fb7ad..a531a513 100644
--- a/src/stdio/vfprintf.c
+++ b/src/stdio/vfprintf.c
@@ -534,8 +534,11 @@ static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg,
 			ps=st;
 			st=states[st]S(*s++);
  			if (st == WPRE) {
+                        	_Bool fast = (*s == 'f');
+                                if (fast) ++s;
 				if (*s == '0') goto inval;
 				width = getint(&s);
+                                if (fast && width == 16) width = 32;
                         }
 		} while (st-1<STOP);
 		if (!st) goto inval;
diff --git a/src/stdio/vfwprintf.c b/src/stdio/vfwprintf.c
index c3e81d2a..3689c2d5 100644
--- a/src/stdio/vfwprintf.c
+++ b/src/stdio/vfwprintf.c
@@ -249,8 +249,11 @@ static int wprintf_core(FILE *f, const wchar_t *fmt, va_list *ap, union arg *nl_
 			ps=st;
 			st=states[st]S(*s++);
  			if (st == WPRE) {
+                        	_Bool fast = (*s == L'f');
+                                if (fast) ++s;
 				if (*s == L'0') goto inval;
 				width = getint(&s);
+                                if (fast && width == 16) width = 32;
                         }
 		} while (st-1<STOP);
 		if (!st) goto inval;
-- 
2.34.1


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [musl] [C23 printf 3/3] C23: implement the wfN length modifiers for printf
       [not found] <cover.1685429467.git.Jens.Gustedt@inria.fr>
@ 2023-05-30  6:55 ` Jens Gustedt
  0 siblings, 0 replies; 8+ messages in thread
From: Jens Gustedt @ 2023-05-30  6:55 UTC (permalink / raw)
  To: musl, jens.gustedt

Musl only has a difference between fixed-width and fastest-width
integer types for N == 16. And even here all architectures have made
the same choice, namely mapping to 32 bit types.
---
 src/stdio/vfprintf.c  | 3 +++
 src/stdio/vfwprintf.c | 3 +++
 2 files changed, 6 insertions(+)

diff --git a/src/stdio/vfprintf.c b/src/stdio/vfprintf.c
index 265fb7ad..a531a513 100644
--- a/src/stdio/vfprintf.c
+++ b/src/stdio/vfprintf.c
@@ -534,8 +534,11 @@ static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg,
 			ps=st;
 			st=states[st]S(*s++);
  			if (st == WPRE) {
+                        	_Bool fast = (*s == 'f');
+                                if (fast) ++s;
 				if (*s == '0') goto inval;
 				width = getint(&s);
+                                if (fast && width == 16) width = 32;
                         }
 		} while (st-1<STOP);
 		if (!st) goto inval;
diff --git a/src/stdio/vfwprintf.c b/src/stdio/vfwprintf.c
index c3e81d2a..3689c2d5 100644
--- a/src/stdio/vfwprintf.c
+++ b/src/stdio/vfwprintf.c
@@ -249,8 +249,11 @@ static int wprintf_core(FILE *f, const wchar_t *fmt, va_list *ap, union arg *nl_
 			ps=st;
 			st=states[st]S(*s++);
  			if (st == WPRE) {
+                        	_Bool fast = (*s == L'f');
+                                if (fast) ++s;
 				if (*s == L'0') goto inval;
 				width = getint(&s);
+                                if (fast && width == 16) width = 32;
                         }
 		} while (st-1<STOP);
 		if (!st) goto inval;
-- 
2.34.1


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [musl] [C23 printf 3/3] C23: implement the wfN length modifiers for printf
  2023-05-26 20:33   ` Rich Felker
@ 2023-05-26 21:00     ` Jₑₙₛ Gustedt
  0 siblings, 0 replies; 8+ messages in thread
From: Jₑₙₛ Gustedt @ 2023-05-26 21:00 UTC (permalink / raw)
  To: Rich Felker; +Cc: musl

[-- Attachment #1: Type: text/plain, Size: 3099 bytes --]

Rich,

on Fri, 26 May 2023 16:33:59 -0400 you (Rich Felker <dalias@libc.org>)
wrote:

> On Fri, May 26, 2023 at 09:41:04PM +0200, Jens Gustedt wrote:
> > Musl only has a difference between fixed-width and fastest-width
> > integer types for N == 16. And even here all architectures have made
> > the same choice, namely mapping to 32 bit types.
> > ---
> >  src/stdio/vfprintf.c  | 9 ++++++++-
> >  src/stdio/vfwprintf.c | 9 ++++++++-
> >  2 files changed, 16 insertions(+), 2 deletions(-)
> > 
> > diff --git a/src/stdio/vfprintf.c b/src/stdio/vfprintf.c
> > index 1a516663..9f02a594 100644
> > --- a/src/stdio/vfprintf.c
> > +++ b/src/stdio/vfprintf.c
> > @@ -529,9 +529,16 @@ static int printf_core(FILE *f, const char
> > *fmt, va_list *ap, union arg *nl_arg, ps=st;
> >  			st=states[st]S(*s++);
> >  			if (st == WPRE) {
> > +				// See if "fast" is requested.
> > Difference is only
> > +				// relevant for a fast type of
> > minimum width 16.
> > +				int fast16 = HPRE;
> > +				if (*s == 'f') {
> > +					fast16 = BARE;
> > +					++s;
> > +				}
> >  				switch (getint(&s)) {
> >  				case 8:  st = HHPRE; goto wpre;
> > -				case 16: st = HPRE; goto wpre;
> > +				case 16: st = fast16; goto wpre;
> >  				case 32: st = BARE; goto wpre;
> >  #if UINTPTR_MAX >= UINT64_MAX
> >  				case 64: st = LPRE; goto wpre;
> > diff --git a/src/stdio/vfwprintf.c b/src/stdio/vfwprintf.c
> > index 4320761a..4e9ce63a 100644
> > --- a/src/stdio/vfwprintf.c
> > +++ b/src/stdio/vfwprintf.c
> > @@ -244,9 +244,16 @@ static int wprintf_core(FILE *f, const wchar_t
> > *fmt, va_list *ap, union arg *nl_ ps=st;
> >  			st=states[st]S(*s++);
> >  			if (st == WPRE) {
> > +				// See if "fast" is requested.
> > Difference is only
> > +				// relevant for a fast type of
> > minimum width 16.
> > +				int fast16 = HPRE;
> > +				if (*s == 'f') {
> > +					fast16 = BARE;
> > +					++s;
> > +				}
> >  				switch (getint(&s)) {
> >  				case 8:  st = HHPRE; goto wpre;
> > -				case 16: st = HPRE; goto wpre;
> > +				case 16: st = fast16; goto wpre;
> >  				case 32: st = BARE; goto wpre;
> >  #if UINTPTR_MAX >= UINT64_MAX
> >  				case 64: st = LPRE; goto wpre;
> > -- 
> > 2.34.1  
> 
> It may just work to have w8, w16, wf8, and wf16 all resolve to BARE
> unconditionally, as the default promitions for variadic functions
> force these all to be passed as int. In the current code, for h and hh
> prefixes we cast down and discard any high bits, but unless the caller
> invoked UB by passing an argument with mismatched type, the cast is
> guaranteed not to change the value.

This might be a nice simplification, I'd have to think of this. At a
first glance this sounds a bit user unfriendly to me.

Jₑₙₛ

-- 
:: ICube :::::::::::::::::::::::::::::: deputy director ::
:: Université de Strasbourg :::::::::::::::::::::: ICPS ::
:: INRIA Nancy Grand Est :::::::::::::::::::::::: Camus ::
:: :::::::::::::::::::::::::::::::::::: ☎ +33 368854536 ::
:: https://icube-icps.unistra.fr/index.php/Jens_Gustedt ::

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [musl] [C23 printf 3/3] C23: implement the wfN length modifiers for printf
  2023-05-26 19:41 ` [musl] [C23 printf 3/3] C23: implement the wfN length modifiers for printf Jens Gustedt
@ 2023-05-26 20:33   ` Rich Felker
  2023-05-26 21:00     ` Jₑₙₛ Gustedt
  0 siblings, 1 reply; 8+ messages in thread
From: Rich Felker @ 2023-05-26 20:33 UTC (permalink / raw)
  To: Jens Gustedt; +Cc: musl

On Fri, May 26, 2023 at 09:41:04PM +0200, Jens Gustedt wrote:
> Musl only has a difference between fixed-width and fastest-width
> integer types for N == 16. And even here all architectures have made
> the same choice, namely mapping to 32 bit types.
> ---
>  src/stdio/vfprintf.c  | 9 ++++++++-
>  src/stdio/vfwprintf.c | 9 ++++++++-
>  2 files changed, 16 insertions(+), 2 deletions(-)
> 
> diff --git a/src/stdio/vfprintf.c b/src/stdio/vfprintf.c
> index 1a516663..9f02a594 100644
> --- a/src/stdio/vfprintf.c
> +++ b/src/stdio/vfprintf.c
> @@ -529,9 +529,16 @@ static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg,
>  			ps=st;
>  			st=states[st]S(*s++);
>  			if (st == WPRE) {
> +				// See if "fast" is requested. Difference is only
> +				// relevant for a fast type of minimum width 16.
> +				int fast16 = HPRE;
> +				if (*s == 'f') {
> +					fast16 = BARE;
> +					++s;
> +				}
>  				switch (getint(&s)) {
>  				case 8:  st = HHPRE; goto wpre;
> -				case 16: st = HPRE; goto wpre;
> +				case 16: st = fast16; goto wpre;
>  				case 32: st = BARE; goto wpre;
>  #if UINTPTR_MAX >= UINT64_MAX
>  				case 64: st = LPRE; goto wpre;
> diff --git a/src/stdio/vfwprintf.c b/src/stdio/vfwprintf.c
> index 4320761a..4e9ce63a 100644
> --- a/src/stdio/vfwprintf.c
> +++ b/src/stdio/vfwprintf.c
> @@ -244,9 +244,16 @@ static int wprintf_core(FILE *f, const wchar_t *fmt, va_list *ap, union arg *nl_
>  			ps=st;
>  			st=states[st]S(*s++);
>  			if (st == WPRE) {
> +				// See if "fast" is requested. Difference is only
> +				// relevant for a fast type of minimum width 16.
> +				int fast16 = HPRE;
> +				if (*s == 'f') {
> +					fast16 = BARE;
> +					++s;
> +				}
>  				switch (getint(&s)) {
>  				case 8:  st = HHPRE; goto wpre;
> -				case 16: st = HPRE; goto wpre;
> +				case 16: st = fast16; goto wpre;
>  				case 32: st = BARE; goto wpre;
>  #if UINTPTR_MAX >= UINT64_MAX
>  				case 64: st = LPRE; goto wpre;
> -- 
> 2.34.1

It may just work to have w8, w16, wf8, and wf16 all resolve to BARE
unconditionally, as the default promitions for variadic functions
force these all to be passed as int. In the current code, for h and hh
prefixes we cast down and discard any high bits, but unless the caller
invoked UB by passing an argument with mismatched type, the cast is
guaranteed not to change the value.

Rich

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [musl] [C23 printf 3/3] C23: implement the wfN length modifiers for printf
  2023-05-26 19:41 [musl] [C23 printf 0/3] Jens Gustedt
@ 2023-05-26 19:41 ` Jens Gustedt
  2023-05-26 20:33   ` Rich Felker
  0 siblings, 1 reply; 8+ messages in thread
From: Jens Gustedt @ 2023-05-26 19:41 UTC (permalink / raw)
  To: musl

Musl only has a difference between fixed-width and fastest-width
integer types for N == 16. And even here all architectures have made
the same choice, namely mapping to 32 bit types.
---
 src/stdio/vfprintf.c  | 9 ++++++++-
 src/stdio/vfwprintf.c | 9 ++++++++-
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/src/stdio/vfprintf.c b/src/stdio/vfprintf.c
index 1a516663..9f02a594 100644
--- a/src/stdio/vfprintf.c
+++ b/src/stdio/vfprintf.c
@@ -529,9 +529,16 @@ static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg,
 			ps=st;
 			st=states[st]S(*s++);
 			if (st == WPRE) {
+				// See if "fast" is requested. Difference is only
+				// relevant for a fast type of minimum width 16.
+				int fast16 = HPRE;
+				if (*s == 'f') {
+					fast16 = BARE;
+					++s;
+				}
 				switch (getint(&s)) {
 				case 8:  st = HHPRE; goto wpre;
-				case 16: st = HPRE; goto wpre;
+				case 16: st = fast16; goto wpre;
 				case 32: st = BARE; goto wpre;
 #if UINTPTR_MAX >= UINT64_MAX
 				case 64: st = LPRE; goto wpre;
diff --git a/src/stdio/vfwprintf.c b/src/stdio/vfwprintf.c
index 4320761a..4e9ce63a 100644
--- a/src/stdio/vfwprintf.c
+++ b/src/stdio/vfwprintf.c
@@ -244,9 +244,16 @@ static int wprintf_core(FILE *f, const wchar_t *fmt, va_list *ap, union arg *nl_
 			ps=st;
 			st=states[st]S(*s++);
 			if (st == WPRE) {
+				// See if "fast" is requested. Difference is only
+				// relevant for a fast type of minimum width 16.
+				int fast16 = HPRE;
+				if (*s == 'f') {
+					fast16 = BARE;
+					++s;
+				}
 				switch (getint(&s)) {
 				case 8:  st = HHPRE; goto wpre;
-				case 16: st = HPRE; goto wpre;
+				case 16: st = fast16; goto wpre;
 				case 32: st = BARE; goto wpre;
 #if UINTPTR_MAX >= UINT64_MAX
 				case 64: st = LPRE; goto wpre;
-- 
2.34.1


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2023-05-31 14:05 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-05-31 14:04 [musl] [C23 printf 0/3] to be replaced Jens Gustedt
2023-05-31 14:04 ` [musl] [C23 printf 1/3] C23: implement the b and B printf specifiers Jens Gustedt
2023-05-31 14:04 ` [musl] [C23 printf 2/3] C23: implement the wN length specifiers for printf Jens Gustedt
2023-05-31 14:04 ` [musl] [C23 printf 3/3] C23: implement the wfN length modifiers " Jens Gustedt
     [not found] <cover.1685429467.git.Jens.Gustedt@inria.fr>
2023-05-30  6:55 ` Jens Gustedt
  -- strict thread matches above, loose matches on Subject: below --
2023-05-26 19:41 [musl] [C23 printf 0/3] Jens Gustedt
2023-05-26 19:41 ` [musl] [C23 printf 3/3] C23: implement the wfN length modifiers for printf Jens Gustedt
2023-05-26 20:33   ` Rich Felker
2023-05-26 21:00     ` Jₑₙₛ Gustedt

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/musl/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).