mailing list of musl libc
 help / color / mirror / code / Atom feed
* [musl] [C23 scanf 1/3] C23: Add the b specifier for scanf and allow 0b and 0B prefixes in integers
       [not found] <cover.1685536319.git.Jens.Gustedt@inria.fr>
@ 2023-05-31 14:05 ` Jens Gustedt
  2023-05-31 14:05 ` [musl] [C23 scanf 2/3] C23: add the SCNb macros Jens Gustedt
  2023-05-31 14:05 ` [musl] [C23 scanf 3/3] C23: implement wN and wfN specifiers for scanf functions Jens Gustedt
  2 siblings, 0 replies; 3+ messages in thread
From: Jens Gustedt @ 2023-05-31 14:05 UTC (permalink / raw)
  To: musl

This affects all functions that read integers from strings or streams
such as scanf and strtoX.

This patch changes the behavior deep down inside, namely the __intscan
function. This is a semantic change. Parsing of integers that use base
0 (for the strtoX functions) or the "i" specifier (for scanf) may
observe different behavior when linked (statically or dynamically)
against this new version.

The C committtee did explicitly reject concerns about this
incompatibility, judging it as being only a minor risk.
---
 src/internal/intscan.c | 13 +++++++++++--
 src/stdio/vfscanf.c    |  5 ++++-
 src/stdio/vfwscanf.c   |  4 ++--
 3 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/src/internal/intscan.c b/src/internal/intscan.c
index a4a5ae86..57424554 100644
--- a/src/internal/intscan.c
+++ b/src/internal/intscan.c
@@ -38,9 +38,9 @@ unsigned long long __intscan(FILE *f, unsigned base, int pok, unsigned long long
 		neg = -(c=='-');
 		c = shgetc(f);
 	}
-	if ((base == 0 || base == 16) && c=='0') {
+	if ((base == 0 || base == 2 || base == 16) && c=='0') {
 		c = shgetc(f);
-		if ((c|32)=='x') {
+		if ((c|32)=='x' && base != 2) {
 			c = shgetc(f);
 			if (val[c]>=16) {
 				shunget(f);
@@ -49,6 +49,15 @@ unsigned long long __intscan(FILE *f, unsigned base, int pok, unsigned long long
 				return 0;
 			}
 			base = 16;
+		} else if ((c|32)=='b' && base != 16) {
+			c = shgetc(f);
+			if (val[c]>=2) {
+				shunget(f);
+				if (pok) shunget(f);
+				else shlim(f, 0);
+				return 0;
+			}
+			base = 2;
 		} else if (base == 0) {
 			base = 8;
 		}
diff --git a/src/stdio/vfscanf.c b/src/stdio/vfscanf.c
index b78a374d..f72ac9c9 100644
--- a/src/stdio/vfscanf.c
+++ b/src/stdio/vfscanf.c
@@ -150,7 +150,7 @@ int vfscanf(FILE *restrict f, const char *restrict fmt, va_list ap)
 		case 'L':
 			size = SIZE_L;
 			break;
-		case 'd': case 'i': case 'o': case 'u': case 'x':
+		case 'b': case 'd': case 'i': case 'o': case 'u': case 'x':
 		case 'a': case 'e': case 'f': case 'g':
 		case 'A': case 'E': case 'F': case 'G': case 'X':
 		case 's': case 'c': case '[':
@@ -286,6 +286,9 @@ int vfscanf(FILE *restrict f, const char *restrict fmt, va_list ap)
 		case 'o':
 			base = 8;
 			goto int_common;
+		case 'b':
+			base = 2;
+			goto int_common;
 		case 'd':
 		case 'u':
 			base = 10;
diff --git a/src/stdio/vfwscanf.c b/src/stdio/vfwscanf.c
index 82f48604..17f5a2f9 100644
--- a/src/stdio/vfwscanf.c
+++ b/src/stdio/vfwscanf.c
@@ -173,7 +173,7 @@ int vfwscanf(FILE *restrict f, const wchar_t *restrict fmt, va_list ap)
 		case 'L':
 			size = SIZE_L;
 			break;
-		case 'd': case 'i': case 'o': case 'u': case 'x':
+		case 'b': case 'd': case 'i': case 'o': case 'u': case 'x':
 		case 'a': case 'e': case 'f': case 'g':
 		case 'A': case 'E': case 'F': case 'G': case 'X':
 		case 's': case 'c': case '[':
@@ -294,7 +294,7 @@ int vfwscanf(FILE *restrict f, const wchar_t *restrict fmt, va_list ap)
 			}
 			break;
 
-		case 'd': case 'i': case 'o': case 'u': case 'x':
+		case 'b': case 'd': case 'i': case 'o': case 'u': case 'x':
 		case 'a': case 'e': case 'f': case 'g':
 		case 'A': case 'E': case 'F': case 'G': case 'X':
 		case 'p':
-- 
2.34.1


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

* [musl] [C23 scanf 2/3] C23: add the SCNb macros
       [not found] <cover.1685536319.git.Jens.Gustedt@inria.fr>
  2023-05-31 14:05 ` [musl] [C23 scanf 1/3] C23: Add the b specifier for scanf and allow 0b and 0B prefixes in integers Jens Gustedt
@ 2023-05-31 14:05 ` Jens Gustedt
  2023-05-31 14:05 ` [musl] [C23 scanf 3/3] C23: implement wN and wfN specifiers for scanf functions Jens Gustedt
  2 siblings, 0 replies; 3+ messages in thread
From: Jens Gustedt @ 2023-05-31 14:05 UTC (permalink / raw)
  To: musl

---
 include/inttypes.h | 21 +++++++++++++++++++--
 1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/include/inttypes.h b/include/inttypes.h
index 73a42e32..780c2bb0 100644
--- a/include/inttypes.h
+++ b/include/inttypes.h
@@ -1,5 +1,5 @@
-#ifndef _INTTYPES_H
-#define _INTTYPES_H
+#ifndef __STDC_VERSION_INTTYPES_H__
+#define __STDC_VERSION_INTTYPES_H__ 201711L
 
 #ifdef __cplusplus
 extern "C" {
@@ -228,6 +228,21 @@ uintmax_t wcstoumax(const wchar_t *__restrict, wchar_t **__restrict, int);
 #define SCNoFAST32 "o"
 #define SCNoFAST64 __PRI64 "o"
 
+#define SCNb8   "hhb"
+#define SCNb16  "hb"
+#define SCNb32  "b"
+#define SCNb64  __PRI64 "b"
+
+#define SCNbLEAST8  "hhb"
+#define SCNbLEAST16 "hb"
+#define SCNbLEAST32 "b"
+#define SCNbLEAST64 __PRI64 "b"
+
+#define SCNbFAST8  "hhb"
+#define SCNbFAST16 "b"
+#define SCNbFAST32 "b"
+#define SCNbFAST64 __PRI64 "b"
+
 #define SCNx8   "hhx"
 #define SCNx16  "hx"
 #define SCNx32  "x"
@@ -243,12 +258,14 @@ uintmax_t wcstoumax(const wchar_t *__restrict, wchar_t **__restrict, int);
 #define SCNxFAST32 "x"
 #define SCNxFAST64 __PRI64 "x"
 
+#define SCNbMAX __PRI64 "b"
 #define SCNdMAX __PRI64 "d"
 #define SCNiMAX __PRI64 "i"
 #define SCNoMAX __PRI64 "o"
 #define SCNuMAX __PRI64 "u"
 #define SCNxMAX __PRI64 "x"
 
+#define SCNbPTR __PRIPTR "b"
 #define SCNdPTR __PRIPTR "d"
 #define SCNiPTR __PRIPTR "i"
 #define SCNoPTR __PRIPTR "o"
-- 
2.34.1


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

* [musl] [C23 scanf 3/3] C23: implement wN and wfN specifiers for scanf functions
       [not found] <cover.1685536319.git.Jens.Gustedt@inria.fr>
  2023-05-31 14:05 ` [musl] [C23 scanf 1/3] C23: Add the b specifier for scanf and allow 0b and 0B prefixes in integers Jens Gustedt
  2023-05-31 14:05 ` [musl] [C23 scanf 2/3] C23: add the SCNb macros Jens Gustedt
@ 2023-05-31 14:05 ` Jens Gustedt
  2 siblings, 0 replies; 3+ messages in thread
From: Jens Gustedt @ 2023-05-31 14:05 UTC (permalink / raw)
  To: musl

---
 src/stdio/vfscanf.c  | 30 ++++++++++++++++++++++++++++++
 src/stdio/vfwscanf.c | 30 ++++++++++++++++++++++++++++++
 2 files changed, 60 insertions(+)

diff --git a/src/stdio/vfscanf.c b/src/stdio/vfscanf.c
index f72ac9c9..f8ace92f 100644
--- a/src/stdio/vfscanf.c
+++ b/src/stdio/vfscanf.c
@@ -41,6 +41,15 @@ static void store_int(void *dest, int size, unsigned long long i)
 	}
 }
 
+static int getint(unsigned char const**s) {
+	int i=0;
+	if (**s != '0')	for (; isdigit(**s); (*s)++) {
+		if (i > INT_MAX/10U || **s-'0' > INT_MAX-10*i) i = -1;
+		else i = 10*i + (**s-'0');
+	}
+	return i;
+}
+
 static void *arg_n(va_list ap, unsigned int n)
 {
 	void *p;
@@ -57,6 +66,7 @@ int vfscanf(FILE *restrict f, const char *restrict fmt, va_list ap)
 {
 	int width;
 	int size;
+	int fast16;
 	int alloc = 0;
 	int base;
 	const unsigned char *p;
@@ -150,6 +160,26 @@ int vfscanf(FILE *restrict f, const char *restrict fmt, va_list ap)
 		case 'L':
 			size = SIZE_L;
 			break;
+		case 'w':
+			// See if "fast" is requested. Difference is only
+			// relevant for a fast type of minimum width 16.
+			fast16 = SIZE_h;
+			if (*p == 'f') {
+				fast16 = SIZE_def;
+				++p;
+			}
+			switch (getint(&p)) {
+			default: goto fmt_fail;
+			case 8:  size = SIZE_hh; break;
+			case 16: size = fast16; break;
+			case 32: size = SIZE_def; break;
+#if UINTPTR_MAX >= UINT64_MAX
+			case 64: size = SIZE_l; break;
+#else
+			case 64: size = SIZE_ll; break;
+#endif
+			}
+			break;
 		case 'b': case 'd': case 'i': case 'o': case 'u': case 'x':
 		case 'a': case 'e': case 'f': case 'g':
 		case 'A': case 'E': case 'F': case 'G': case 'X':
diff --git a/src/stdio/vfwscanf.c b/src/stdio/vfwscanf.c
index 17f5a2f9..6fe2749c 100644
--- a/src/stdio/vfwscanf.c
+++ b/src/stdio/vfwscanf.c
@@ -41,6 +41,15 @@ static void store_int(void *dest, int size, unsigned long long i)
 	}
 }
 
+static int getint(wchar_t const**s) {
+	int i=0;
+	if (**s != L'0') for (i=0; iswdigit(**s); (*s)++) {
+		if (i > INT_MAX/10U || **s-L'0' > INT_MAX-10*i) i = -1;
+		else i = 10*i + (**s-L'0');
+	}
+	return i;
+}
+
 static void *arg_n(va_list ap, unsigned int n)
 {
 	void *p;
@@ -87,6 +96,7 @@ int vfwscanf(FILE *restrict f, const wchar_t *restrict fmt, va_list ap)
 {
 	int width;
 	int size;
+	int fast16;
 	int alloc;
 	const wchar_t *p;
 	int c, t;
@@ -173,6 +183,26 @@ int vfwscanf(FILE *restrict f, const wchar_t *restrict fmt, va_list ap)
 		case 'L':
 			size = SIZE_L;
 			break;
+		case 'w':
+			// See if "fast" is requested. Difference is only
+			// relevant for a fast type of minimum width 16.
+			fast16 = SIZE_h;
+			if (*p == 'f') {
+				fast16 = SIZE_def;
+				++p;
+			}
+			switch (getint(&p)) {
+			default: goto fmt_fail;
+			case 8:  size = SIZE_hh; break;
+			case 16: size = fast16; break;
+			case 32: size = SIZE_def; break;
+#if UINTPTR_MAX >= UINT64_MAX
+			case 64: size = SIZE_l; break;
+#else
+			case 64: size = SIZE_ll; break;
+#endif
+			}
+			break;
 		case 'b': case 'd': case 'i': case 'o': case 'u': case 'x':
 		case 'a': case 'e': case 'f': case 'g':
 		case 'A': case 'E': case 'F': case 'G': case 'X':
-- 
2.34.1


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

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

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <cover.1685536319.git.Jens.Gustedt@inria.fr>
2023-05-31 14:05 ` [musl] [C23 scanf 1/3] C23: Add the b specifier for scanf and allow 0b and 0B prefixes in integers Jens Gustedt
2023-05-31 14:05 ` [musl] [C23 scanf 2/3] C23: add the SCNb macros Jens Gustedt
2023-05-31 14:05 ` [musl] [C23 scanf 3/3] C23: implement wN and wfN specifiers for scanf functions Jens 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).