From b1ddd558eeda0e3dc7941189cb70b83f046126fe Mon Sep 17 00:00:00 2001
From: Sascha Wildner <saw@online.de>
Date: Tue, 28 Dec 2021 21:00:21 +0100
Subject: [PATCH 1/6] printf(3)/scanf(3): Make ll and L equivalent.

POSIX defines L only for floats and ll only for integers, leaving for
example %Ld or %llg undefined. GCC allows these non-portable combinations
as an extension, i.e. -Wformat will not warn about them unless -pedantic
is passed.

To avoid surprises when compiling Linux code, go with glibc and make
ll and L equivalent. For new code, we still prefer going with the
standard of course.

Interestingly, the alternate printf(3) implementation in libc (enabled
by defining USE_XPRINTF in the environment) already treated them equally.
---
 lib/libc/stdio/printf.3      | 24 +++++++++++++++++---
 lib/libc/stdio/printflocal.h |  4 ++--
 lib/libc/stdio/scanf.3       | 43 +++++++++++++++++++++++++++++++-----
 lib/libc/stdio/vfscanf.c     |  6 +++--
 lib/libc/stdio/vfwscanf.c    |  6 +++--
 lib/libc/stdio/wprintf.3     | 24 +++++++++++++++++---
 lib/libc/stdio/wscanf.3      | 43 +++++++++++++++++++++++++++++++-----
 7 files changed, 128 insertions(+), 22 deletions(-)

diff --git a/lib/libc/stdio/printf.3 b/lib/libc/stdio/printf.3
index e25db478366..c77025cbd90 100644
--- a/lib/libc/stdio/printf.3
+++ b/lib/libc/stdio/printf.3
@@ -32,7 +32,7 @@
 .\"     @(#)printf.3	8.1 (Berkeley) 6/4/93
 .\" $FreeBSD: head/lib/libc/stdio/printf.3 303524 2016-07-30 01:00:16Z bapt $
 .\"
-.Dd June 30, 2021
+.Dd December 28, 2021
 .Dt PRINTF 3
 .Os
 .Sh NAME
@@ -325,12 +325,13 @@ The following length modifiers are valid for the
 or
 .Cm X
 conversion:
-.Bl -column ".Cm q Em (deprecated)" ".Vt signed char" ".Vt unsigned long long" ".Vt long long *"
+.Bl -column ".Cm q Em (non-standard)" ".Vt signed char" ".Vt unsigned long long" ".Vt long long *"
 .It Sy Modifier Ta Cm d , i Ta Cm o , u , x , X Ta Cm n
 .It Cm hh Ta Vt "signed char" Ta Vt "unsigned char" Ta Vt "signed char *"
 .It Cm h Ta Vt short Ta Vt "unsigned short" Ta Vt "short *"
 .It Cm l No (ell) Ta Vt long Ta Vt "unsigned long" Ta Vt "long *"
 .It Cm ll No (ell ell) Ta Vt "long long" Ta Vt "unsigned long long" Ta Vt "long long *"
+.It Cm L Em (non-standard) Ta Vt "long long" Ta Vt "unsigned long long" Ta Vt "long long *"
 .It Cm j Ta Vt intmax_t Ta Vt uintmax_t Ta Vt "intmax_t *"
 .It Cm t Ta Vt ptrdiff_t Ta (see note) Ta Vt "ptrdiff_t *"
 .It Cm z Ta (see note) Ta Vt size_t Ta (see note)
@@ -367,11 +368,12 @@ The following length modifier is valid for the
 or
 .Cm G
 conversion:
-.Bl -column ".Sy Modifier" ".Cm a , A , e , E , f , F , g , G"
+.Bl -column ".Cm ll Em (non-standard)" ".Cm a , A , e , E , f , F , g , G"
 .It Sy Modifier Ta Cm a , A , e , E , f , F , g , G
 .It Cm l No (ell) Ta Vt double
 (ignored, same behavior as without it)
 .It Cm L Ta Vt "long double"
+.It Cm ll Em (non-standard) Ta Vt "long double"
 .El
 .Pp
 The following length modifier is valid for the
@@ -801,6 +803,22 @@ and
 .Fn vdprintf
 conform to
 .St -p1003.1-2008 .
+.Pp
+As an extension,
+.Dx
+treats the length modifiers
+.Cm ll
+and
+.Cm L
+as synonyms, so that the non-standard
+.Cm %Ld
+is equivalent to
+.Cm %ld
+and the non-standard
+.Cm %llg
+is equivalent
+to
+.Cm %Lg .
 .Sh HISTORY
 The functions
 .Fn asprintf
diff --git a/lib/libc/stdio/printflocal.h b/lib/libc/stdio/printflocal.h
index a866ff1bc3d..02237e8d219 100644
--- a/lib/libc/stdio/printflocal.h
+++ b/lib/libc/stdio/printflocal.h
@@ -37,9 +37,9 @@
  */
 #define	ALT		0x001		/* alternate form */
 #define	LADJUST		0x004		/* left adjustment */
-#define	LONGDBL		0x008		/* long double */
+#define	LONGDBL		0x008		/* long double / long long integer */
 #define	LONGINT		0x010		/* long integer */
-#define	LLONGINT	0x020		/* long long integer */
+#define	LLONGINT	LONGDBL		/* long double / long long integer */
 #define	SHORTINT	0x040		/* short integer */
 #define	ZEROPAD		0x080		/* zero (as opposed to blank) pad */
 #define	FPT		0x100		/* Floating point number */
diff --git a/lib/libc/stdio/scanf.3 b/lib/libc/stdio/scanf.3
index 5e4328d02be..cf83d1187bb 100644
--- a/lib/libc/stdio/scanf.3
+++ b/lib/libc/stdio/scanf.3
@@ -32,7 +32,7 @@
 .\"     @(#)scanf.3	8.2 (Berkeley) 12/11/93
 .\" $FreeBSD: head/lib/libc/stdio/scanf.3 235363 2012-05-12 20:27:13Z joel $
 .\"
-.Dd August 26, 2006
+.Dd December 28, 2021
 .Dt SCANF 3
 .Os
 .Sh NAME
@@ -192,14 +192,30 @@ or
 and the next pointer is a pointer to a
 .Vt "long long int"
 (rather than
-.Vt int ) .
+.Vt int ) ,
+or that the conversion will be one of
+.Cm a , e , f ,
+or
+.Cm g
+and the next pointer is a pointer to
+.Vt "long double"
+(non-standard).
 .It Cm L
 Indicates that the conversion will be one of
 .Cm a , e , f ,
 or
 .Cm g
 and the next pointer is a pointer to
-.Vt "long double" .
+.Vt "long double" ,
+or that the conversion will be one of
+.Cm dioux
+or
+.Cm n
+and the next pointer is a pointer to a
+.Vt "long long int"
+(rather than
+.Vt int )
+(non-standard).
 .It Cm j
 Indicates that the conversion will be one of
 .Cm dioux
@@ -309,9 +325,10 @@ Matches a floating-point number in the style of
 The next pointer must be a pointer to
 .Vt float
 (unless
-.Cm l
-or
+.Cm l ,
 .Cm L
+or
+.Cm ll
 is specified.)
 .It Cm s
 Matches a sequence of non-white-space characters;
@@ -474,6 +491,22 @@ and
 .Fn vsscanf
 conform to
 .St -isoC-99 .
+.Pp
+As an extension,
+.Dx
+treats the length modifiers
+.Cm ll
+and
+.Cm L
+as synonyms, so that the non-standard
+.Cm %Ld
+is equivalent to
+.Cm %ld
+and the non-standard
+.Cm %llg
+is equivalent
+to
+.Cm %Lg .
 .Sh BUGS
 Earlier implementations of
 .Nm
diff --git a/lib/libc/stdio/vfscanf.c b/lib/libc/stdio/vfscanf.c
index 7e808ae4f06..5ef8a585900 100644
--- a/lib/libc/stdio/vfscanf.c
+++ b/lib/libc/stdio/vfscanf.c
@@ -66,12 +66,14 @@
  * Flags used during conversion.
  */
 #define	LONG		0x01	/* l: long or double */
-#define	LONGDBL		0x02	/* L: long double */
+#define	LONGDBL		0x02	/* ll/L: long long, long double */
+				/* (+ deprecated q: quad) */
 #define	SHORT		0x04	/* h: short */
 #define	SUPPRESS	0x08	/* *: suppress assignment */
 #define	POINTER		0x10	/* p: void * (as hex) */
 #define	NOSKIP		0x20	/* [ or c: do not skip blanks */
-#define	LONGLONG	0x400	/* ll: long long (+ deprecated q: quad) */
+#define	LONGLONG	LONGDBL	/* ll/L: long long, long double */
+				/* (+ deprecated q: quad) */
 #define	INTMAXT		0x800	/* j: intmax_t */
 #define	PTRDIFFT	0x1000	/* t: ptrdiff_t */
 #define	SIZET		0x2000	/* z: size_t */
diff --git a/lib/libc/stdio/vfwscanf.c b/lib/libc/stdio/vfwscanf.c
index 9732cde763f..1d8e5db27bf 100644
--- a/lib/libc/stdio/vfwscanf.c
+++ b/lib/libc/stdio/vfwscanf.c
@@ -61,12 +61,14 @@
  * Flags used during conversion.
  */
 #define	LONG		0x01	/* l: long or double */
-#define	LONGDBL		0x02	/* L: long double */
+#define	LONGDBL		0x02	/* ll/L: long long, long double */
+				/* (+ deprecated q: quad) */
 #define	SHORT		0x04	/* h: short */
 #define	SUPPRESS	0x08	/* *: suppress assignment */
 #define	POINTER		0x10	/* p: void * (as hex) */
 #define	NOSKIP		0x20	/* [ or c: do not skip blanks */
-#define	LONGLONG	0x400	/* ll: long long (+ deprecated q: quad) */
+#define	LONGLONG	LONGDBL	/* ll/L: long long, long double */
+				/* (+ deprecated q: quad) */
 #define	INTMAXT		0x800	/* j: intmax_t */
 #define	PTRDIFFT	0x1000	/* t: ptrdiff_t */
 #define	SIZET		0x2000	/* z: size_t */
diff --git a/lib/libc/stdio/wprintf.3 b/lib/libc/stdio/wprintf.3
index b2cf9feae4d..008a8418b31 100644
--- a/lib/libc/stdio/wprintf.3
+++ b/lib/libc/stdio/wprintf.3
@@ -32,7 +32,7 @@
 .\"     @(#)printf.3	8.1 (Berkeley) 6/4/93
 .\" $FreeBSD: head/lib/libc/stdio/wprintf.3 208027 2010-05-13 12:07:55Z uqs $
 .\"
-.Dd July 5, 2003
+.Dd December 28, 2021
 .Dt WPRINTF 3
 .Os
 .Sh NAME
@@ -253,12 +253,13 @@ The following length modifiers are valid for the
 or
 .Cm X
 conversion:
-.Bl -column ".Cm q Em (deprecated)" ".Vt signed char" ".Vt unsigned long long" ".Vt long long *"
+.Bl -column ".Cm q Em (non-standard)" ".Vt signed char" ".Vt unsigned long long" ".Vt long long *"
 .It Sy Modifier Ta Cm d , i Ta Cm o , u , x , X Ta Cm n
 .It Cm hh Ta Vt "signed char" Ta Vt "unsigned char" Ta Vt "signed char *"
 .It Cm h Ta Vt short Ta Vt "unsigned short" Ta Vt "short *"
 .It Cm l No (ell) Ta Vt long Ta Vt "unsigned long" Ta Vt "long *"
 .It Cm ll No (ell ell) Ta Vt "long long" Ta Vt "unsigned long long" Ta Vt "long long *"
+.It Cm L Em (non-standard) Ta Vt "long long" Ta Vt "unsigned long long" Ta Vt "long long *"
 .It Cm j Ta Vt intmax_t Ta Vt uintmax_t Ta Vt "intmax_t *"
 .It Cm t Ta Vt ptrdiff_t Ta (see note) Ta Vt "ptrdiff_t *"
 .It Cm z Ta (see note) Ta Vt size_t Ta (see note)
@@ -295,9 +296,10 @@ The following length modifier is valid for the
 or
 .Cm G
 conversion:
-.Bl -column ".Sy Modifier" ".Cm a , A , e , E , f , F , g , G"
+.Bl -column ".Cm ll Em (non-standard)" ".Cm a , A , e , E , f , F , g , G"
 .It Sy Modifier Ta Cm a , A , e , E , f , F , g , G
 .It Cm L Ta Vt "long double"
+.It Cm ll Em (non-standard) Ta Vt "long double"
 .El
 .Pp
 The following length modifier is valid for the
@@ -612,6 +614,22 @@ and
 functions
 conform to
 .St -isoC-99 .
+.Pp
+As an extension,
+.Dx
+treats the length modifiers
+.Cm ll
+and
+.Cm L
+as synonyms, so that the non-standard
+.Cm %Ld
+is equivalent to
+.Cm %ld
+and the non-standard
+.Cm %llg
+is equivalent
+to
+.Cm %Lg .
 .Sh SECURITY CONSIDERATIONS
 Refer to
 .Xr printf 3 .
diff --git a/lib/libc/stdio/wscanf.3 b/lib/libc/stdio/wscanf.3
index 422154fe7c6..7497e83a0fb 100644
--- a/lib/libc/stdio/wscanf.3
+++ b/lib/libc/stdio/wscanf.3
@@ -33,7 +33,7 @@
 .\" FreeBSD: src/lib/libc/stdio/scanf.3,v 1.24 2003/06/28 09:03:25 das Exp
 .\" $FreeBSD: head/lib/libc/stdio/wscanf.3 235363 2012-05-12 20:27:13Z joel $
 .\"
-.Dd July 5, 2003
+.Dd December 28, 2021
 .Dt WSCANF 3
 .Os
 .Sh NAME
@@ -193,14 +193,30 @@ or
 and the next pointer is a pointer to a
 .Vt "long long int"
 (rather than
-.Vt int ) .
+.Vt int ) ,
+or that the conversion will be one of
+.Cm a , e , f ,
+or
+.Cm g
+and the next pointer is a pointer to
+.Vt "long double"
+(non-standard).
 .It Cm L
 Indicates that the conversion will be one of
 .Cm a , e , f ,
 or
 .Cm g
 and the next pointer is a pointer to
-.Vt "long double" .
+.Vt "long double" ,
+or that the conversion will be one of
+.Cm dioux
+or
+.Cm n
+and the next pointer is a pointer to a
+.Vt "long long int"
+(rather than
+.Vt int )
+(non-standard).
 .It Cm j
 Indicates that the conversion will be one of
 .Cm dioux
@@ -303,9 +319,10 @@ Matches a floating-point number in the style of
 The next pointer must be a pointer to
 .Vt float
 (unless
-.Cm l
-or
+.Cm l ,
 .Cm L
+or
+.Cm ll
 is specified.)
 .It Cm s
 Matches a sequence of non-white-space wide characters;
@@ -468,6 +485,22 @@ and
 functions
 conform to
 .St -isoC-99 .
+.Pp
+As an extension,
+.Dx
+treats the length modifiers
+.Cm ll
+and
+.Cm L
+as synonyms, so that the non-standard
+.Cm %Ld
+is equivalent to
+.Cm %ld
+and the non-standard
+.Cm %llg
+is equivalent
+to
+.Cm %Lg .
 .Sh BUGS
 In addition to the bugs documented in
 .Xr scanf 3 ,
-- 
2.32.0

