From cfce4ef4d3bd3f821474e72f530de71adf926e95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Fri, 10 Nov 2023 21:14:32 +0300 Subject: [PATCH] =?UTF-8?q?mdbx-test:=20=D1=8F=D0=B2=D0=BD=D0=B0=D1=8F=20?= =?UTF-8?q?=D1=83=D1=81=D1=82=D0=B0=D0=BD=D0=BE=D0=B2=D0=BA=D0=B0=20append?= =?UTF-8?q?-=D1=80=D0=B5=D0=B6=D0=B8=D0=BC=D0=B0=20=D0=B4=D0=BB=D1=8F=20st?= =?UTF-8?q?dout/stderr.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/log.c++ | 100 ++++++++++++++++++++++---------------------------- test/log.h++ | 2 +- test/main.c++ | 13 ++++++- 3 files changed, 57 insertions(+), 58 deletions(-) diff --git a/test/log.c++ b/test/log.c++ index 5fe485c8..dd55fb70 100644 --- a/test/log.c++ +++ b/test/log.c++ @@ -56,7 +56,7 @@ namespace logging { static std::string prefix; static std::string suffix; static loglevel level; -static FILE *last; +static FILE *flow; void setlevel(loglevel priority) { level = priority; @@ -67,13 +67,13 @@ void setlevel(loglevel priority) { log_trace("set mdbx debug-opts: 0x%02x", rc); } +void setup(const std::string &_prefix) { prefix = _prefix; } + void setup(loglevel priority, const std::string &_prefix) { setlevel(priority); - prefix = _prefix; + setup(_prefix); } -void setup(const std::string &_prefix) { prefix = _prefix; } - const char *level2str(const loglevel alevel) { switch (alevel) { default: @@ -108,18 +108,13 @@ bool output(const loglevel priority, const char *format, ...) { return true; } -bool ln() { - if (last) { - putc('\n', last); - fflush(last); - if (last == stderr) { +void ln() { + if (flow) { + putc('\n', flow); + if (flow != stdout) putc('\n', stdout); - fflush(stdout); - } - last = nullptr; - return true; + flow = nullptr; } - return false; } void output_nocheckloglevel_ap(const logging::loglevel priority, @@ -139,8 +134,7 @@ void output_nocheckloglevel_ap(const logging::loglevel priority, if (rc != MDBX_SUCCESS) failure_perror("localtime_r()", rc); - last = stdout; - fprintf(last, + fprintf(stdout, "[ %02d%02d%02d-%02d:%02d:%02d.%06d_%05lu %-10s %.4s ] %s" /* TODO */, tm.tm_year - 100, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, chrono::fractional2us(now.fractional), (long)osal_getpid(), @@ -150,19 +144,17 @@ void output_nocheckloglevel_ap(const logging::loglevel priority, memset(&ones, 0, sizeof(ones)) /* zap MSVC and other goofy compilers */; if (same_or_higher(priority, error)) va_copy(ones, ap); - vfprintf(last, format, ap); + vfprintf(stdout, format, ap); size_t len = strlen(format); char end = len ? format[len - 1] : '\0'; switch (end) { default: - putc('\n', last); - MDBX_CXX17_FALLTHROUGH; // fall through + putc('\n', stdout); + break; case '\n': - fflush(last); - last = nullptr; - MDBX_CXX17_FALLTHROUGH; // fall through + break; case ' ': case '_': case ':': @@ -172,46 +164,39 @@ void output_nocheckloglevel_ap(const logging::loglevel priority, case '\b': case '\r': case '\0': + flow = stdout; break; } if (same_or_higher(priority, error)) { - if (last != stderr) { - fprintf(stderr, "[ %05lu %-10s %.4s ] %s", (long)osal_getpid(), - prefix.c_str(), level2str(priority), suffix.c_str()); - vfprintf(stderr, format, ones); - if (end == '\n') - fflush(stderr); - else - last = stderr; - } + if (flow) + flow = stderr; + fprintf(stderr, "[ %05lu %-10s %.4s ] %s", (long)osal_getpid(), + prefix.c_str(), level2str(priority), suffix.c_str()); + vfprintf(stderr, format, ones); va_end(ones); } } bool feed_ap(const char *format, va_list ap) { - if (!last) + if (!flow) return false; - if (last == stderr) { + if (flow == stderr) { va_list ones; va_copy(ones, ap); vfprintf(stdout, format, ones); va_end(ones); } - vfprintf(last, format, ap); + vfprintf(flow, format, ap); size_t len = strlen(format); - if (len && format[len - 1] == '\n') { - fflush(last); - if (last == stderr) - fflush(stdout); - last = nullptr; - } + if (len && format[len - 1] == '\n') + flow = nullptr; return true; } bool feed(const char *format, ...) { - if (!last) + if (!flow) return false; va_list ap; @@ -299,73 +284,73 @@ void progress_canary(bool active) { } // namespace logging void log_extra(const char *msg, ...) { + logging::ln(); if (logging::same_or_higher(logging::extra, logging::level)) { va_list ap; va_start(ap, msg); logging::output_nocheckloglevel_ap(logging::extra, msg, ap); va_end(ap); - } else - logging::last = nullptr; + } } void log_trace(const char *msg, ...) { + logging::ln(); if (logging::same_or_higher(logging::trace, logging::level)) { va_list ap; va_start(ap, msg); logging::output_nocheckloglevel_ap(logging::trace, msg, ap); va_end(ap); - } else - logging::last = nullptr; + } } void log_debug(const char *msg, ...) { + logging::ln(); if (logging::same_or_higher(logging::debug, logging::level)) { va_list ap; va_start(ap, msg); logging::output_nocheckloglevel_ap(logging::debug, msg, ap); va_end(ap); - } else - logging::last = nullptr; + } } void log_verbose(const char *msg, ...) { + logging::ln(); if (logging::same_or_higher(logging::verbose, logging::level)) { va_list ap; va_start(ap, msg); logging::output_nocheckloglevel_ap(logging::verbose, msg, ap); va_end(ap); - } else - logging::last = nullptr; + } } void log_notice(const char *msg, ...) { + logging::ln(); if (logging::same_or_higher(logging::notice, logging::level)) { va_list ap; va_start(ap, msg); logging::output_nocheckloglevel_ap(logging::notice, msg, ap); va_end(ap); - } else - logging::last = nullptr; + } } void log_warning(const char *msg, ...) { + logging::ln(); if (logging::same_or_higher(logging::warning, logging::level)) { va_list ap; va_start(ap, msg); logging::output_nocheckloglevel_ap(logging::warning, msg, ap); va_end(ap); - } else - logging::last = nullptr; + } } void log_error(const char *msg, ...) { + logging::ln(); if (logging::same_or_higher(logging::error, logging::level)) { va_list ap; va_start(ap, msg); logging::output_nocheckloglevel_ap(logging::error, msg, ap); va_end(ap); - } else - logging::last = nullptr; + } } void log_trouble(const char *where, const char *what, int errnum) { @@ -376,4 +361,7 @@ bool log_enabled(const logging::loglevel priority) { return logging::same_or_higher(priority, logging::level); } -void log_flush(void) { fflushall(); } +void log_flush(void) { + logging::ln(); + fflushall(); +} diff --git a/test/log.h++ b/test/log.h++ index 96d68848..cf955551 100644 --- a/test/log.h++ +++ b/test/log.h++ @@ -55,7 +55,7 @@ bool MDBX_PRINTF_ARGS(2, 3) output(const loglevel priority, const char *format, ...); bool feed_ap(const char *format, va_list ap); bool MDBX_PRINTF_ARGS(1, 2) feed(const char *format, ...); -bool ln(); +void ln(); void inline MDBX_PRINTF_ARGS(2, 3) output_nocheckloglevel(const loglevel priority, const char *format, ...) { diff --git a/test/main.c++ b/test/main.c++ index ba086e90..6242a05d 100644 --- a/test/main.c++ +++ b/test/main.c++ @@ -267,8 +267,19 @@ static void fixup4qemu(actor_params ¶ms) { (void)params; } -int main(int argc, char *const argv[]) { +static void set_linebuf_append(FILE *out) { + setvbuf(out, NULL, _IOLBF, 65536); +#if !defined(_WIN32) && !defined(_WIN64) + int fd = fileno(out); + int flags = fcntl(fd, F_GETFD); + if (flags != -1) + (void)fcntl(fd, F_SETFD, O_APPEND | flags); +#endif /* !Windows */ +} +int main(int argc, char *const argv[]) { + set_linebuf_append(stdout); + set_linebuf_append(stderr); #ifdef _DEBUG log_trace("#argc = %d", argc); for (int i = 0; i < argc; ++i)