Implement printf(3) family %m format string extension.

Reviewed by:	ed, dim (code only)
Sponsored by:	Mellanox Technologies
MFC after:	1 week
This commit is contained in:
Konstantin Belousov 2018-05-22 11:05:40 +00:00
parent 66971d57e9
commit e95725feca
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=334031
2 changed files with 28 additions and 1 deletions

View File

@ -32,7 +32,7 @@
.\" @(#)printf.3 8.1 (Berkeley) 6/4/93
.\" $FreeBSD$
.\"
.Dd July 30, 2016
.Dd May 22, 2018
.Dt PRINTF 3
.Os
.Sh NAME
@ -651,6 +651,12 @@ integer indicated by the
.Vt "int *"
(or variant) pointer argument.
No argument is converted.
.It Cm m
Print the string representation of the error code stored in the
.Dv errno
variable at the beginning of the call, as returned by
.Xr strerror 3 .
No argument is taken.
.It Cm %
A
.Ql %
@ -730,6 +736,12 @@ and
.Cm \&%U
are not standard and
are provided only for backward compatibility.
The conversion format
.Cm \&%m
is also not standard and provides the popular extension from the
.Tn GNU C
library.
.Pp
The effect of padding the
.Cm %p
format with zeros (either by the
@ -767,9 +779,11 @@ or the return value would be too large to be represented by an
.El
.Sh SEE ALSO
.Xr printf 1 ,
.Xr errno 2 ,
.Xr fmtcheck 3 ,
.Xr scanf 3 ,
.Xr setlocale 3 ,
.Xr strerror 3 ,
.Xr wprintf 3
.Sh STANDARDS
Subject to the caveats noted in the
@ -822,6 +836,12 @@ and
.Fn vdprintf
functions were added in
.Fx 8.0 .
The
.Cm \&%m
format extension first appeared in the
.Tn GNU C
library, and was implemented in
.Fx 12.0 .
.Sh BUGS
The
.Nm

View File

@ -317,6 +317,7 @@ __vfprintf(FILE *fp, locale_t locale, const char *fmt0, va_list ap)
int ret; /* return value accumulator */
int width; /* width from format (%8d), or 0 */
int prec; /* precision from format; <0 for N/A */
int saved_errno;
char sign; /* sign prefix (' ', '+', '-', or \0) */
struct grouping_state gs; /* thousands' grouping info */
@ -466,6 +467,7 @@ __vfprintf(FILE *fp, locale_t locale, const char *fmt0, va_list ap)
savserr = fp->_flags & __SERR;
fp->_flags &= ~__SERR;
saved_errno = errno;
convbuf = NULL;
fmt = (char *)fmt0;
argtable = NULL;
@ -776,6 +778,11 @@ reswitch: switch (ch) {
}
break;
#endif /* !NO_FLOATING_POINT */
case 'm':
cp = strerror(saved_errno);
size = (prec >= 0) ? strnlen(cp, prec) : strlen(cp);
sign = '\0';
break;
case 'n':
/*
* Assignment-like behavior is specified if the