mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-24 00:10:10 +01:00
util/log: improve logger_file newline handling
Add logger_vasnprintf that will be used by other loggers. For
logger_file, it improves newline handling for
mesa_logd("%s", "hello\n");
Reviewed-by: Emma Anholt <emma@anholt.net>
Reviewed-by: Jesse Natalie <jenatali@microsoft.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21454>
This commit is contained in:
parent
63864d4dfc
commit
7a18a1712a
1 changed files with 84 additions and 10 deletions
|
|
@ -88,24 +88,98 @@ level_to_str(enum mesa_log_level l)
|
||||||
unreachable("bad mesa_log_level");
|
unreachable("bad mesa_log_level");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum logger_vasnprintf_affix {
|
||||||
|
LOGGER_VASNPRINTF_AFFIX_TAG = 1 << 0,
|
||||||
|
LOGGER_VASNPRINTF_AFFIX_LEVEL = 1 << 1,
|
||||||
|
LOGGER_VASNPRINTF_AFFIX_NEWLINE = 1 << 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Try vsnprintf first and fall back to vasprintf if buf is too small. This
|
||||||
|
* function handles all errors and never fails.
|
||||||
|
*/
|
||||||
|
static char *
|
||||||
|
logger_vasnprintf(char *buf,
|
||||||
|
int size,
|
||||||
|
int affixes,
|
||||||
|
enum mesa_log_level level,
|
||||||
|
const char *tag,
|
||||||
|
const char *format,
|
||||||
|
va_list va)
|
||||||
|
{
|
||||||
|
struct {
|
||||||
|
char *cur;
|
||||||
|
int rem;
|
||||||
|
int total;
|
||||||
|
bool invalid;
|
||||||
|
} state = {
|
||||||
|
.cur = buf,
|
||||||
|
.rem = size,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define APPEND(state, func, ...) \
|
||||||
|
do { \
|
||||||
|
int ret = func(state.cur, state.rem, __VA_ARGS__); \
|
||||||
|
if (ret < 0) { \
|
||||||
|
state.invalid = true; \
|
||||||
|
} else { \
|
||||||
|
state.total += ret; \
|
||||||
|
if (ret >= state.rem) \
|
||||||
|
ret = state.rem; \
|
||||||
|
state.cur += ret; \
|
||||||
|
state.rem -= ret; \
|
||||||
|
} \
|
||||||
|
} while (false)
|
||||||
|
|
||||||
|
if (affixes & LOGGER_VASNPRINTF_AFFIX_TAG)
|
||||||
|
APPEND(state, snprintf, "%s: ", tag);
|
||||||
|
if (affixes & LOGGER_VASNPRINTF_AFFIX_LEVEL)
|
||||||
|
APPEND(state, snprintf, "%s: ", level_to_str(level));
|
||||||
|
|
||||||
|
APPEND(state, vsnprintf, format, va);
|
||||||
|
|
||||||
|
if (affixes & LOGGER_VASNPRINTF_AFFIX_NEWLINE) {
|
||||||
|
if (state.cur == buf || state.cur[-1] != '\n')
|
||||||
|
APPEND(state, snprintf, "\n");
|
||||||
|
}
|
||||||
|
#undef APPEND
|
||||||
|
|
||||||
|
assert(size >= 64);
|
||||||
|
if (state.invalid) {
|
||||||
|
strncpy(buf, "invalid message format", size);
|
||||||
|
} else if (state.total >= size) {
|
||||||
|
/* print again into alloc to avoid truncation */
|
||||||
|
void *alloc = malloc(state.total + 1);
|
||||||
|
if (alloc) {
|
||||||
|
buf = logger_vasnprintf(alloc, state.total + 1, affixes, level, tag,
|
||||||
|
format, va);
|
||||||
|
assert(buf == alloc);
|
||||||
|
} else {
|
||||||
|
/* pretty-truncate the message */
|
||||||
|
strncpy(buf + size - 4, "...", 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
logger_file(enum mesa_log_level level,
|
logger_file(enum mesa_log_level level,
|
||||||
const char *tag,
|
const char *tag,
|
||||||
const char *format,
|
const char *format,
|
||||||
va_list va)
|
va_list va)
|
||||||
{
|
{
|
||||||
#if !DETECT_OS_WINDOWS
|
FILE *fp = stderr;
|
||||||
flockfile(stderr);
|
char local_msg[1024];
|
||||||
#endif
|
char *msg = logger_vasnprintf(local_msg, sizeof(local_msg),
|
||||||
|
LOGGER_VASNPRINTF_AFFIX_TAG |
|
||||||
|
LOGGER_VASNPRINTF_AFFIX_LEVEL |
|
||||||
|
LOGGER_VASNPRINTF_AFFIX_NEWLINE,
|
||||||
|
level, tag, format, va);
|
||||||
|
|
||||||
fprintf(stderr, "%s: %s: ", tag, level_to_str(level));
|
fprintf(fp, "%s", msg);
|
||||||
vfprintf(stderr, format, va);
|
|
||||||
if (format[strlen(format) - 1] != '\n')
|
|
||||||
fprintf(stderr, "\n");
|
|
||||||
|
|
||||||
#if !DETECT_OS_WINDOWS
|
if (msg != local_msg)
|
||||||
funlockfile(stderr);
|
free(msg);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if DETECT_OS_ANDROID
|
#if DETECT_OS_ANDROID
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue