mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-23 19:50:11 +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");
|
||||
}
|
||||
|
||||
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
|
||||
logger_file(enum mesa_log_level level,
|
||||
const char *tag,
|
||||
const char *format,
|
||||
va_list va)
|
||||
{
|
||||
#if !DETECT_OS_WINDOWS
|
||||
flockfile(stderr);
|
||||
#endif
|
||||
FILE *fp = stderr;
|
||||
char local_msg[1024];
|
||||
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));
|
||||
vfprintf(stderr, format, va);
|
||||
if (format[strlen(format) - 1] != '\n')
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(fp, "%s", msg);
|
||||
|
||||
#if !DETECT_OS_WINDOWS
|
||||
funlockfile(stderr);
|
||||
#endif
|
||||
if (msg != local_msg)
|
||||
free(msg);
|
||||
}
|
||||
|
||||
#if DETECT_OS_ANDROID
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue