[userboot] provide a mini-printf-to-log utility
Change-Id: Id7a5d80899b61dd59356c1051801fdda3262f4a6
Esse commit está contido em:
commit de
CQ bot account: commit-bot@chromium.org
pai
a8a283aced
commit
f4ffdea785
@@ -37,8 +37,6 @@ void print(mx_handle_t log, const char* s, ...) {
|
||||
} while (s != NULL);
|
||||
va_end(ap);
|
||||
|
||||
*p = '\0';
|
||||
|
||||
if (log == MX_HANDLE_INVALID) {
|
||||
mx_debug_write(buffer, p - buffer);
|
||||
} else {
|
||||
@@ -52,3 +50,126 @@ void fail(mx_handle_t log, mx_status_t status, const char* msg) {
|
||||
print(log, msg, NULL);
|
||||
mx_process_exit(status);
|
||||
}
|
||||
|
||||
static char* hexstring(char* s, size_t len, uint64_t n) {
|
||||
char tmp[16];
|
||||
char* hex = tmp;
|
||||
do {
|
||||
*hex++ = "0123456789abcdef"[n & 15];
|
||||
n >>= 4;
|
||||
} while (n);
|
||||
|
||||
while ((hex > tmp) && (len > 0)) {
|
||||
*s++ = *--hex;
|
||||
len--;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
static char* u64string(char* s, size_t len, uint64_t n) {
|
||||
char tmp[21]; // strlen(maxint64) + 1
|
||||
char* dec = tmp;
|
||||
do {
|
||||
*dec++ = "0123456789"[n % 10];
|
||||
n /= 10;
|
||||
} while (n > 0);
|
||||
|
||||
while ((dec > tmp) && (len > 0)) {
|
||||
*s++ = *--dec;
|
||||
len--;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
static char* i64string(char* s, size_t len, int64_t n) {
|
||||
if (n < 0) {
|
||||
// this will never be called with len < 1 so we
|
||||
// don't need to check for len
|
||||
n = -n;
|
||||
*s++ = '-';
|
||||
len--;
|
||||
}
|
||||
return u64string(s, len, n);
|
||||
}
|
||||
|
||||
void vprintl(mx_handle_t log, const char* fmt, va_list ap) {
|
||||
char buffer[MX_LOG_RECORD_MAX - sizeof(mx_log_record_t)];
|
||||
static_assert(sizeof(LOG_PREFIX) < sizeof(buffer), "buffer too small");
|
||||
|
||||
memcpy(buffer, LOG_PREFIX, sizeof(LOG_PREFIX) - 1);
|
||||
char* p = &buffer[sizeof(LOG_PREFIX) - 1];
|
||||
|
||||
size_t avail;
|
||||
const char* s;
|
||||
uint64_t n;
|
||||
int64_t i;
|
||||
|
||||
while (*fmt && (avail = (size_t)(&buffer[sizeof(buffer)] - p))) {
|
||||
if (*fmt != '%') {
|
||||
*p++ = *fmt++;
|
||||
continue;
|
||||
}
|
||||
switch (*++fmt) {
|
||||
case 's':
|
||||
s = va_arg(ap, const char*);
|
||||
while (avail && *s) {
|
||||
*p++ = *s++;
|
||||
avail--;
|
||||
}
|
||||
break;
|
||||
case 'z':
|
||||
fmt++;
|
||||
switch (*fmt) {
|
||||
case 'u':
|
||||
n = va_arg(ap, uint64_t);
|
||||
goto u64print;
|
||||
case 'd':
|
||||
i = va_arg(ap, int64_t);
|
||||
goto i64print;
|
||||
case 'x':
|
||||
n = va_arg(ap, uint64_t);
|
||||
goto x64print;
|
||||
default:
|
||||
goto bad_format;
|
||||
}
|
||||
break;
|
||||
case 'p':
|
||||
n = va_arg(ap, uint64_t);
|
||||
goto x64print;
|
||||
case 'u':
|
||||
n = va_arg(ap, uint32_t);
|
||||
u64print:
|
||||
p = u64string(p, avail, n);
|
||||
break;
|
||||
case 'd':
|
||||
i = va_arg(ap, int32_t);
|
||||
i64print:
|
||||
p = i64string(p, avail, i);
|
||||
break;
|
||||
case 'x':
|
||||
n = va_arg(ap, uint32_t);
|
||||
x64print:
|
||||
p = hexstring(p, avail, n);
|
||||
break;
|
||||
default:
|
||||
bad_format:
|
||||
printl(log, "printl: invalid fmt char 0x%x", *fmt);
|
||||
mx_process_exit(-1);
|
||||
}
|
||||
fmt++;
|
||||
}
|
||||
|
||||
done:
|
||||
if ((log == MX_HANDLE_INVALID) ||
|
||||
(mx_log_write(log, p - buffer, buffer, 0) != MX_OK)) {
|
||||
mx_debug_write(buffer, p - buffer);
|
||||
mx_debug_write("\n", 1);
|
||||
}
|
||||
}
|
||||
|
||||
void printl(mx_handle_t log, const char* fmt, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vprintl(log, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
@@ -6,8 +6,14 @@
|
||||
|
||||
#pragma GCC visibility push(hidden)
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <magenta/types.h>
|
||||
|
||||
// printl() is printf-like, understanding %s %p %d %u %x %zu %zd %zx.
|
||||
// No other formatting features are supported.
|
||||
void printl(mx_handle_t log, const char* fmt, ...);
|
||||
void vprintl(mx_handle_t log, const char* fmt, va_list ap);
|
||||
|
||||
void print(mx_handle_t log, const char* s, ...) __attribute__((sentinel));
|
||||
_Noreturn void fail(mx_handle_t log, mx_status_t status, const char* msg);
|
||||
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário