mirror of
https://github.com/freebsd/freebsd-src
synced 2024-07-23 03:06:48 +00:00
libc: Implement N2680.
This adds specific width length modifiers in the form of wN and wfN (where N is 8, 16, 32, or 64) which allow printing intN_t and int_fastN_t without resorting to casts or PRI macros. Reviewed by: imp, emaste Differential Revision: https://reviews.freebsd.org/D41725
This commit is contained in:
parent
294bd2827e
commit
bce0bef3c6
|
@ -31,7 +31,7 @@
|
|||
.\"
|
||||
.\" @(#)printf.3 8.1 (Berkeley) 6/4/93
|
||||
.\"
|
||||
.Dd August 21, 2023
|
||||
.Dd September 5, 2023
|
||||
.Dt PRINTF 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -342,6 +342,8 @@ conversion:
|
|||
.It Cm ll No (ell ell) 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 w Ns Ar N Ta Vt intN_t Ta Vt uintN_t Ta Vt "intN_t *"
|
||||
.It Cm wf Ns Ar N Ta Vt int_fastN_t Ta Vt uint_fastN_t Ta Vt "int_fastN_t *"
|
||||
.It Cm z Ta (see note) Ta Vt size_t Ta (see note)
|
||||
.It Cm q Em (deprecated) Ta Vt quad_t Ta Vt u_quad_t Ta Vt "quad_t *"
|
||||
.El
|
||||
|
|
|
@ -49,6 +49,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
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
.\"
|
||||
.\" @(#)scanf.3 8.2 (Berkeley) 12/11/93
|
||||
.\"
|
||||
.Dd August 21, 2023
|
||||
.Dd September 5, 2023
|
||||
.Dt SCANF 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -217,6 +217,34 @@ and the next pointer is a pointer to a
|
|||
.Vt ptrdiff_t
|
||||
(rather than
|
||||
.Vt int ) .
|
||||
.It Cm w Ns Ar N
|
||||
.Po
|
||||
where
|
||||
.Ar N
|
||||
is 8, 16, 32, or 64
|
||||
.Pc
|
||||
Indicates that the conversion will be one of
|
||||
.Cm bdioux
|
||||
or
|
||||
.Cm n
|
||||
and the next pointer is a pointer to a
|
||||
.Vt intN_t
|
||||
(rather than
|
||||
.Vt int ) .
|
||||
.It Cm wf Ns Ar N
|
||||
.Po
|
||||
where
|
||||
.Ar N
|
||||
is 8, 16, 32, or 64
|
||||
.Pc
|
||||
Indicates that the conversion will be one of
|
||||
.Cm bdioux
|
||||
or
|
||||
.Cm n
|
||||
and the next pointer is a pointer to a
|
||||
.Vt int_fastN_t
|
||||
(rather than
|
||||
.Vt int ) .
|
||||
.It Cm z
|
||||
Indicates that the conversion will be one of
|
||||
.Cm bdioux
|
||||
|
|
|
@ -610,6 +610,49 @@ 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
|
||||
/* no flag set = 32 */ ;
|
||||
fmt += 1;
|
||||
} else if (fmt[0] == '1' && fmt[1] == '6') {
|
||||
if (!(flags & FASTINT))
|
||||
flags |= SHORTINT;
|
||||
else
|
||||
/* 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;
|
||||
|
@ -932,6 +975,7 @@ number: if ((dprec = prec) >= 0)
|
|||
default: /* "%?" prints ?, unless ? is NUL */
|
||||
if (ch == '\0')
|
||||
goto done;
|
||||
invalid:
|
||||
/* pretend it was %c with argument ch */
|
||||
cp = buf;
|
||||
*cp = ch;
|
||||
|
|
|
@ -75,6 +75,7 @@ static char sccsid[] = "@(#)vfscanf.c 8.1 (Berkeley) 6/4/93";
|
|||
#define SUPPRESS 0x08 /* *: suppress assignment */
|
||||
#define POINTER 0x10 /* p: void * (as hex) */
|
||||
#define NOSKIP 0x20 /* [ or c: do not skip blanks */
|
||||
#define FASTINT 0x200 /* wfN: int_fastN_t */
|
||||
#define LONGLONG 0x400 /* ll: long long (+ deprecated q: quad) */
|
||||
#define INTMAXT 0x800 /* j: intmax_t */
|
||||
#define PTRDIFFT 0x1000 /* t: ptrdiff_t */
|
||||
|
@ -555,6 +556,45 @@ again: c = *fmt++;
|
|||
case 't':
|
||||
flags |= PTRDIFFT;
|
||||
goto again;
|
||||
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 &= ~(SHORTSHORT|SHORT|LONG|LONGLONG|SIZET|INTMAXT|PTRDIFFT);
|
||||
if (fmt[0] == 'f') {
|
||||
flags |= FASTINT;
|
||||
fmt++;
|
||||
} else {
|
||||
flags &= ~FASTINT;
|
||||
}
|
||||
if (fmt[0] == '8') {
|
||||
if (!(flags & FASTINT))
|
||||
flags |= SHORTSHORT;
|
||||
else
|
||||
/* no flag set = 32 */ ;
|
||||
fmt += 1;
|
||||
} else if (fmt[0] == '1' && fmt[1] == '6') {
|
||||
if (!(flags & FASTINT))
|
||||
flags |= SHORT;
|
||||
else
|
||||
/* 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 |= LONGLONG;
|
||||
fmt += 2;
|
||||
} else {
|
||||
goto match_failure;
|
||||
}
|
||||
goto again;
|
||||
case 'z':
|
||||
flags |= SIZET;
|
||||
goto again;
|
||||
|
|
|
@ -681,6 +681,49 @@ 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
|
||||
/* no flag set = 32 */ ;
|
||||
fmt += 1;
|
||||
} else if (fmt[0] == '1' && fmt[1] == '6') {
|
||||
if (!(flags & FASTINT))
|
||||
flags |= SHORTINT;
|
||||
else
|
||||
/* 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;
|
||||
|
@ -993,6 +1036,7 @@ number: if ((dprec = prec) >= 0)
|
|||
default: /* "%?" prints ?, unless ? is NUL */
|
||||
if (ch == '\0')
|
||||
goto done;
|
||||
invalid:
|
||||
/* pretend it was %c with argument ch */
|
||||
cp = buf;
|
||||
*cp = ch;
|
||||
|
|
|
@ -73,6 +73,7 @@ static char sccsid[] = "@(#)vfscanf.c 8.1 (Berkeley) 6/4/93";
|
|||
#define SUPPRESS 0x08 /* *: suppress assignment */
|
||||
#define POINTER 0x10 /* p: void * (as hex) */
|
||||
#define NOSKIP 0x20 /* [ or c: do not skip blanks */
|
||||
#define FASTINT 0x200 /* wfN: int_fastN_t */
|
||||
#define LONGLONG 0x400 /* ll: long long (+ deprecated q: quad) */
|
||||
#define INTMAXT 0x800 /* j: intmax_t */
|
||||
#define PTRDIFFT 0x1000 /* t: ptrdiff_t */
|
||||
|
@ -539,6 +540,45 @@ again: c = *fmt++;
|
|||
case 't':
|
||||
flags |= PTRDIFFT;
|
||||
goto again;
|
||||
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 &= ~(SHORTSHORT|SHORT|LONG|LONGLONG|SIZET|INTMAXT|PTRDIFFT);
|
||||
if (fmt[0] == 'f') {
|
||||
flags |= FASTINT;
|
||||
fmt++;
|
||||
} else {
|
||||
flags &= ~FASTINT;
|
||||
}
|
||||
if (fmt[0] == '8') {
|
||||
if (!(flags & FASTINT))
|
||||
flags |= SHORTSHORT;
|
||||
else
|
||||
/* no flag set = 32 */ ;
|
||||
fmt += 1;
|
||||
} else if (fmt[0] == '1' && fmt[1] == '6') {
|
||||
if (!(flags & FASTINT))
|
||||
flags |= SHORT;
|
||||
else
|
||||
/* 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 |= LONGLONG;
|
||||
fmt += 2;
|
||||
} else {
|
||||
goto match_failure;
|
||||
}
|
||||
goto again;
|
||||
case 'z':
|
||||
flags |= SIZET;
|
||||
goto again;
|
||||
|
|
Loading…
Reference in a new issue