Add strerrordesc_np() and strerrorname_np().
strerrordesc_np() isn't very useful (being just another name for
strerror()), but strerrorname_np() lets you get "ENOSYS" for ENOSYS,
which will make some of our test assertion messages clearer when we
switch over from strerror().
This also adds `%#m` formatting to all the relevant functions.
Test: treehugger
Change-Id: Icfe07a39a307d591c3f4f2a09d008dc021643062
diff --git a/libc/stdio/vfwprintf.cpp b/libc/stdio/vfwprintf.cpp
index d6f6a6b..72f973c 100644
--- a/libc/stdio/vfwprintf.cpp
+++ b/libc/stdio/vfwprintf.cpp
@@ -52,6 +52,19 @@
#include "printf_common.h"
+#define print_utf8(utf8, prec) \
+ do { \
+ free(convbuf); \
+ convbuf = helpers::mbsconv(utf8, prec); \
+ if (convbuf == nullptr) { \
+ fp->_flags |= __SERR; \
+ goto error; \
+ } else { \
+ cp = convbuf; \
+ } \
+ goto string; \
+ } while (0)
+
int FUNCTION_NAME(FILE* fp, const CHAR_TYPE* fmt0, va_list ap) {
int caller_errno = errno;
int n, n2;
@@ -319,6 +332,7 @@
case 'd':
case 'i':
_umax = SARG();
+signed_decimal:
if ((intmax_t)_umax < 0) {
_umax = -_umax;
sign = '-';
@@ -447,16 +461,13 @@
case 'n':
__fortify_fatal("%%n not allowed on Android");
case 'm':
- free(convbuf);
- convbuf = helpers::mbsconv(strerror_r(caller_errno,
- reinterpret_cast<char*>(buf), sizeof(buf)), prec);
- if (convbuf == nullptr) {
- fp->_flags |= __SERR;
- goto error;
- } else {
- cp = convbuf;
+ if (flags & ALT) {
+ const char* name = strerrorname_np(caller_errno);
+ if (name) print_utf8(name, prec);
+ _umax = caller_errno;
+ goto signed_decimal;
}
- goto string;
+ print_utf8(strerror_r(caller_errno, reinterpret_cast<char*>(buf), sizeof(buf)), prec);
case 'O':
flags |= LONGINT;
__BIONIC_FALLTHROUGH;
@@ -486,14 +497,7 @@
} else {
char* mbsarg;
if ((mbsarg = GETARG(char*)) == nullptr) mbsarg = const_cast<char*>("(null)");
- free(convbuf);
- convbuf = helpers::mbsconv(mbsarg, prec);
- if (convbuf == nullptr) {
- fp->_flags |= __SERR;
- goto error;
- } else {
- cp = convbuf;
- }
+ print_utf8(mbsarg, prec);
}
string:
if (prec >= 0) {