Merge "Add %m and %#x support for async_safe logging"
This commit is contained in:
commit
99ed14b85b
2 changed files with 52 additions and 5 deletions
|
@ -251,6 +251,7 @@ static void out_vformat(Out& o, const char* format, va_list args) {
|
||||||
char sign = '\0';
|
char sign = '\0';
|
||||||
int width = -1;
|
int width = -1;
|
||||||
int prec = -1;
|
int prec = -1;
|
||||||
|
bool alternate = false;
|
||||||
size_t bytelen = sizeof(int);
|
size_t bytelen = sizeof(int);
|
||||||
int slen;
|
int slen;
|
||||||
char buffer[32]; /* temporary buffer used to format numbers */
|
char buffer[32]; /* temporary buffer used to format numbers */
|
||||||
|
@ -293,6 +294,9 @@ static void out_vformat(Out& o, const char* format, va_list args) {
|
||||||
} else if (c == ' ' || c == '+') {
|
} else if (c == ' ' || c == '+') {
|
||||||
sign = c;
|
sign = c;
|
||||||
continue;
|
continue;
|
||||||
|
} else if (c == '#') {
|
||||||
|
alternate = true;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -344,9 +348,6 @@ static void out_vformat(Out& o, const char* format, va_list args) {
|
||||||
if (c == 's') {
|
if (c == 's') {
|
||||||
/* string */
|
/* string */
|
||||||
str = va_arg(args, const char*);
|
str = va_arg(args, const char*);
|
||||||
if (str == nullptr) {
|
|
||||||
str = "(null)";
|
|
||||||
}
|
|
||||||
} else if (c == 'c') {
|
} else if (c == 'c') {
|
||||||
/* character */
|
/* character */
|
||||||
/* NOTE: char is promoted to int when passed through the stack */
|
/* NOTE: char is promoted to int when passed through the stack */
|
||||||
|
@ -357,6 +358,9 @@ static void out_vformat(Out& o, const char* format, va_list args) {
|
||||||
buffer[0] = '0';
|
buffer[0] = '0';
|
||||||
buffer[1] = 'x';
|
buffer[1] = 'x';
|
||||||
format_integer(buffer + 2, sizeof(buffer) - 2, value, 'x');
|
format_integer(buffer + 2, sizeof(buffer) - 2, value, 'x');
|
||||||
|
} else if (c == 'm') {
|
||||||
|
char buf[256];
|
||||||
|
str = strerror_r(errno, buf, sizeof(buf));
|
||||||
} else if (c == 'd' || c == 'i' || c == 'o' || c == 'u' || c == 'x' || c == 'X') {
|
} else if (c == 'd' || c == 'i' || c == 'o' || c == 'u' || c == 'x' || c == 'X') {
|
||||||
/* integers - first read value from stack */
|
/* integers - first read value from stack */
|
||||||
uint64_t value;
|
uint64_t value;
|
||||||
|
@ -388,8 +392,19 @@ static void out_vformat(Out& o, const char* format, va_list args) {
|
||||||
value = static_cast<uint64_t>((static_cast<int64_t>(value << shift)) >> shift);
|
value = static_cast<uint64_t>((static_cast<int64_t>(value << shift)) >> shift);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* format the number properly into our buffer */
|
if (alternate && value != 0 && (c == 'x' || c == 'o')) {
|
||||||
format_integer(buffer, sizeof(buffer), value, c);
|
if (c == 'x') {
|
||||||
|
buffer[0] = '0';
|
||||||
|
buffer[1] = 'x';
|
||||||
|
format_integer(buffer + 2, sizeof(buffer) - 2, value, c);
|
||||||
|
} else {
|
||||||
|
buffer[0] = '0';
|
||||||
|
format_integer(buffer + 1, sizeof(buffer) - 1, value, c);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* format the number properly into our buffer */
|
||||||
|
format_integer(buffer, sizeof(buffer), value, c);
|
||||||
|
}
|
||||||
} else if (c == '%') {
|
} else if (c == '%') {
|
||||||
buffer[0] = '%';
|
buffer[0] = '%';
|
||||||
buffer[1] = '\0';
|
buffer[1] = '\0';
|
||||||
|
@ -397,6 +412,10 @@ static void out_vformat(Out& o, const char* format, va_list args) {
|
||||||
__assert(__FILE__, __LINE__, "conversion specifier unsupported");
|
__assert(__FILE__, __LINE__, "conversion specifier unsupported");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (str == nullptr) {
|
||||||
|
str = "(null)";
|
||||||
|
}
|
||||||
|
|
||||||
/* if we are here, 'str' points to the content that must be
|
/* if we are here, 'str' points to the content that must be
|
||||||
* outputted. handle padding and alignment now */
|
* outputted. handle padding and alignment now */
|
||||||
|
|
||||||
|
|
|
@ -64,6 +64,10 @@ TEST(async_safe_log, smoke) {
|
||||||
async_safe_format_buffer(buf, sizeof(buf), "a%ldb", 70000L);
|
async_safe_format_buffer(buf, sizeof(buf), "a%ldb", 70000L);
|
||||||
EXPECT_STREQ("a70000b", buf);
|
EXPECT_STREQ("a70000b", buf);
|
||||||
|
|
||||||
|
errno = EINVAL;
|
||||||
|
async_safe_format_buffer(buf, sizeof(buf), "a%mZ");
|
||||||
|
EXPECT_STREQ("aInvalid argumentZ", buf);
|
||||||
|
|
||||||
async_safe_format_buffer(buf, sizeof(buf), "a%pb", reinterpret_cast<void*>(0xb0001234));
|
async_safe_format_buffer(buf, sizeof(buf), "a%pb", reinterpret_cast<void*>(0xb0001234));
|
||||||
EXPECT_STREQ("a0xb0001234b", buf);
|
EXPECT_STREQ("a0xb0001234b", buf);
|
||||||
|
|
||||||
|
@ -97,6 +101,30 @@ TEST(async_safe_log, smoke) {
|
||||||
async_safe_format_buffer(buf, sizeof(buf), "a%03d:%d:%02dz", 5, 5, 5);
|
async_safe_format_buffer(buf, sizeof(buf), "a%03d:%d:%02dz", 5, 5, 5);
|
||||||
EXPECT_STREQ("a005:5:05z", buf);
|
EXPECT_STREQ("a005:5:05z", buf);
|
||||||
|
|
||||||
|
async_safe_format_buffer(buf, sizeof(buf), "a%#xZ", 34);
|
||||||
|
EXPECT_STREQ("a0x22Z", buf);
|
||||||
|
|
||||||
|
async_safe_format_buffer(buf, sizeof(buf), "a%#xZ", 0);
|
||||||
|
EXPECT_STREQ("a0Z", buf);
|
||||||
|
|
||||||
|
async_safe_format_buffer(buf, sizeof(buf), "a%#5xZ", 20);
|
||||||
|
EXPECT_STREQ("a 0x14Z", buf);
|
||||||
|
|
||||||
|
snprintf(buf, sizeof(buf), "a%#08.8xZ", 1);
|
||||||
|
EXPECT_STREQ("a0x00000001Z", buf);
|
||||||
|
|
||||||
|
async_safe_format_buffer(buf, sizeof(buf), "a%#oZ", 777);
|
||||||
|
EXPECT_STREQ("a01411Z", buf);
|
||||||
|
|
||||||
|
async_safe_format_buffer(buf, sizeof(buf), "a%#oZ", 0);
|
||||||
|
EXPECT_STREQ("a0Z", buf);
|
||||||
|
|
||||||
|
async_safe_format_buffer(buf, sizeof(buf), "a%#6oZ", 15);
|
||||||
|
EXPECT_STREQ("a 017Z", buf);
|
||||||
|
|
||||||
|
snprintf(buf, sizeof(buf), "a%#08.8oZ", 11);
|
||||||
|
EXPECT_STREQ("a00000013Z", buf);
|
||||||
|
|
||||||
void* p = nullptr;
|
void* p = nullptr;
|
||||||
async_safe_format_buffer(buf, sizeof(buf), "a%d,%pz", 5, p);
|
async_safe_format_buffer(buf, sizeof(buf), "a%d,%pz", 5, p);
|
||||||
EXPECT_STREQ("a5,0x0z", buf);
|
EXPECT_STREQ("a5,0x0z", buf);
|
||||||
|
|
Loading…
Reference in a new issue