diff --git a/include/criterion/logging.h b/include/criterion/logging.h index 6764876..fff5724 100644 --- a/include/criterion/logging.h +++ b/include/criterion/logging.h @@ -24,17 +24,12 @@ #ifndef CRITERION_LOGGING_H_ # define CRITERION_LOGGING_H_ -# ifdef __cplusplus -# include -using std::va_list; -# else -# include -# include -# endif # include "internal/common.h" # include "internal/ordered-set.h" # include "stats.h" +CR_BEGIN_C_API + enum criterion_logging_level { CRITERION_INFO = 1, CRITERION_IMPORTANT, @@ -42,66 +37,18 @@ enum criterion_logging_level { CRITERION_LOG_LEVEL_QUIET = 1 << 30, }; -enum criterion_logging_prefix { - CRITERION_LOGGING_PREFIX_DASHES, - CRITERION_LOGGING_PREFIX_EQUALS, - CRITERION_LOGGING_PREFIX_RUN, - CRITERION_LOGGING_PREFIX_SKIP, - CRITERION_LOGGING_PREFIX_PASS, - CRITERION_LOGGING_PREFIX_FAIL, - CRITERION_LOGGING_PREFIX_ERR, +enum criterion_severity { + CR_LOG_INFO, + CR_LOG_WARNING, + CR_LOG_ERROR, }; -struct criterion_prefix_data { - const char *prefix; - const char *color; -}; - -# ifdef CRITERION_LOGGING_COLORS -# define CRIT_COLOR_NORMALIZE(Str) (criterion_options.use_ascii ? "" : Str) - -# define CRIT_FG_BOLD "\33[0;1m" -# define CRIT_FG_RED "\33[0;31m" -# define CRIT_FG_GREEN "\33[0;32m" -# define CRIT_FG_GOLD "\33[0;33m" -# define CRIT_FG_BLUE "\33[0;34m" -# define CRIT_RESET "\33[0m" - -# define CR_FG_BOLD CRIT_COLOR_NORMALIZE(CRIT_FG_BOLD) -# define CR_FG_RED CRIT_COLOR_NORMALIZE(CRIT_FG_RED) -# define CR_FG_GREEN CRIT_COLOR_NORMALIZE(CRIT_FG_GREEN) -# define CR_FG_GOLD CRIT_COLOR_NORMALIZE(CRIT_FG_GOLD) -# define CR_FG_BLUE CRIT_COLOR_NORMALIZE(CRIT_FG_BLUE) -# define CR_RESET CRIT_COLOR_NORMALIZE(CRIT_RESET) -# endif - -CR_BEGIN_C_API - -extern const struct criterion_prefix_data g_criterion_logging_prefixes[]; - -# define CRITERION_PREFIX_DASHES (&g_criterion_logging_prefixes[CRITERION_LOGGING_PREFIX_DASHES]) -# define CRITERION_PREFIX_EQUALS (&g_criterion_logging_prefixes[CRITERION_LOGGING_PREFIX_EQUALS]) -# define CRITERION_PREFIX_RUN (&g_criterion_logging_prefixes[CRITERION_LOGGING_PREFIX_RUN ]) -# define CRITERION_PREFIX_SKIP (&g_criterion_logging_prefixes[CRITERION_LOGGING_PREFIX_SKIP ]) -# define CRITERION_PREFIX_PASS (&g_criterion_logging_prefixes[CRITERION_LOGGING_PREFIX_PASS ]) -# define CRITERION_PREFIX_FAIL (&g_criterion_logging_prefixes[CRITERION_LOGGING_PREFIX_FAIL ]) -# define CRITERION_PREFIX_ERR (&g_criterion_logging_prefixes[CRITERION_LOGGING_PREFIX_ERR ]) - -CR_API void criterion_vlog(enum criterion_logging_level level, const char *msg, va_list args); - -CR_FORMAT(printf, 3, 4) -CR_API void criterion_plog(enum criterion_logging_level level, const struct criterion_prefix_data *prefix, const char *msg, ...); - CR_FORMAT(printf, 2, 3) -CR_API void criterion_log(enum criterion_logging_level level, const char *msg, ...); +CR_API void cr_log(enum criterion_severity severity, const char *msg, ...); -# define criterion_info(...) criterion_log(CRITERION_INFO, __VA_ARGS__) -# define criterion_important(...) criterion_log(CRITERION_IMPORTANT, __VA_ARGS__) - -# define criterion_pinfo(...) criterion_plog(CRITERION_INFO, __VA_ARGS__) -# define criterion_pimportant(...) criterion_plog(CRITERION_IMPORTANT, __VA_ARGS__) - -# define criterion_perror(...) criterion_plog(CRITERION_IMPORTANT, CRITERION_PREFIX_ERR, __VA_ARGS__) +# define cr_log_info(...) cr_log(CR_LOG_INFO, __VA_ARGS__) +# define cr_log_warn(...) cr_log(CR_LOG_WARNING, __VA_ARGS__) +# define cr_log_error(...) cr_log(CR_LOG_ERROR, __VA_ARGS__) struct criterion_logger { void (*log_pre_all )(struct criterion_test_set *set); @@ -119,6 +66,7 @@ struct criterion_logger { void (*log_post_fini )(struct criterion_test_stats *stats); void (*log_post_suite )(struct criterion_suite_stats *stats); void (*log_post_all )(struct criterion_global_stats *stats); + void (*log_message )(enum criterion_severity, const char *msg); }; extern struct criterion_logger normal_logging; diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index 0d77cf1..3be58d4 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -22,7 +22,7 @@ set(SAMPLES timeout.c redirect.c parameterized.c - + log.c ) if (CMAKE_CXX_COMPILER_WORKS) diff --git a/samples/log.c b/samples/log.c new file mode 100644 index 0000000..61657a7 --- /dev/null +++ b/samples/log.c @@ -0,0 +1,15 @@ +#include +#include + +Test(logging, simple) { + cr_log_info("This is an informational message. They are not displayed " + "by default."); + cr_log_warn("This is a warning. They indicate some possible malfunction " + "or misconfiguration in the test."); + cr_log_error("This is an error. They indicate serious problems and " + "are usually shown before the test is aborted."); +} + +Test(logging, format) { + cr_log_info("Log messages are %s.", "printf-formatted strings"); +} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c479354..0b9773b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -53,6 +53,7 @@ set(SOURCE_FILES src/io/xml.c src/io/json.c src/log/logging.c + src/log/logging.h src/log/normal.c src/string/i18n.c src/string/i18n.h diff --git a/src/compat/alloc.c b/src/compat/alloc.c index c712692..e2737df 100644 --- a/src/compat/alloc.c +++ b/src/compat/alloc.c @@ -23,7 +23,7 @@ */ #include "alloc.h" #include "internal.h" -#include "criterion/logging.h" +#include "log/logging.h" #include #ifdef VANILLA_WIN32 diff --git a/src/compat/kill.c b/src/compat/kill.c index 962091c..726fb19 100644 --- a/src/compat/kill.c +++ b/src/compat/kill.c @@ -23,7 +23,7 @@ */ #include "kill.h" #include "internal.h" -#include "criterion/logging.h" +#include "log/logging.h" #include "core/report.h" #include "core/stats.h" #include "io/event.h" diff --git a/src/compat/pipe.h b/src/compat/pipe.h index 0591feb..59c955f 100644 --- a/src/compat/pipe.h +++ b/src/compat/pipe.h @@ -27,7 +27,7 @@ # include # include # include "common.h" -# include "criterion/logging.h" +# include "log/logging.h" struct pipe_handle; typedef struct pipe_handle s_pipe_handle; diff --git a/src/core/client.c b/src/core/client.c index d4fe7d0..ae370eb 100644 --- a/src/core/client.c +++ b/src/core/client.c @@ -27,8 +27,8 @@ #include "compat/strtok.h" #include "protocol/protocol.h" #include "protocol/messages.h" -#include "criterion/logging.h" #include "criterion/options.h" +#include "log/logging.h" #include "io/event.h" #include "report.h" #include "stats.h" @@ -481,6 +481,8 @@ bool handle_assert(struct server_ctx *sctx, struct client_ctx *ctx, const criter bool handle_message(struct server_ctx *sctx, struct client_ctx *ctx, const criterion_protocol_msg *msg) { (void) sctx; (void) ctx; - (void) msg; + const criterion_protocol_log *lg = &msg->data.value.message; + + log(message, (enum criterion_severity) lg->severity, lg->message); return false; } diff --git a/src/core/report.c b/src/core/report.c index afee441..6bbdf0e 100644 --- a/src/core/report.c +++ b/src/core/report.c @@ -26,9 +26,9 @@ #include #include "criterion/types.h" #include "criterion/stats.h" -#include "criterion/logging.h" #include "criterion/options.h" #include "criterion/internal/ordered-set.h" +#include "log/logging.h" #include "report.h" #include "config.h" #include "compat/posix.h" diff --git a/src/core/runner.c b/src/core/runner.c index 58f245f..e299801 100644 --- a/src/core/runner.c +++ b/src/core/runner.c @@ -31,7 +31,6 @@ #include "criterion/internal/test.h" #include "criterion/options.h" #include "criterion/internal/ordered-set.h" -#include "criterion/logging.h" #include "criterion/internal/preprocess.h" #include "criterion/redirect.h" #include "protocol/protocol.h" @@ -44,6 +43,7 @@ #include "string/i18n.h" #include "io/event.h" #include "io/output.h" +#include "log/logging.h" #include "runner_coroutine.h" #include "stats.h" #include "runner.h" diff --git a/src/core/runner_coroutine.c b/src/core/runner_coroutine.c index f80873d..8e1649a 100644 --- a/src/core/runner_coroutine.c +++ b/src/core/runner_coroutine.c @@ -24,8 +24,8 @@ #include #include #include -#include "criterion/logging.h" #include "criterion/internal/parameterized.h" +#include "log/logging.h" #include "runner_coroutine.h" #include "worker.h" #include "stats.h" diff --git a/src/io/json.c b/src/io/json.c index 5b1b78f..c15902d 100644 --- a/src/io/json.c +++ b/src/io/json.c @@ -26,9 +26,9 @@ #include #include #include "criterion/stats.h" -#include "criterion/logging.h" #include "criterion/options.h" #include "criterion/internal/ordered-set.h" +#include "log/logging.h" #include "compat/posix.h" #include "compat/strtok.h" #include "compat/time.h" diff --git a/src/io/output.c b/src/io/output.c index d3fd05d..1408920 100644 --- a/src/io/output.c +++ b/src/io/output.c @@ -4,7 +4,7 @@ #include #include #include "criterion/output.h" -#include "criterion/logging.h" +#include "log/logging.h" #include "string/i18n.h" typedef const char *const msg_t; diff --git a/src/io/xml.c b/src/io/xml.c index ca5664b..a0960f5 100644 --- a/src/io/xml.c +++ b/src/io/xml.c @@ -26,9 +26,9 @@ #include #include #include "criterion/stats.h" -#include "criterion/logging.h" #include "criterion/options.h" #include "criterion/internal/ordered-set.h" +#include "log/logging.h" #include "compat/posix.h" #include "compat/strtok.h" #include "compat/time.h" diff --git a/src/log/logging.c b/src/log/logging.c index cf4ad12..e17cc47 100644 --- a/src/log/logging.c +++ b/src/log/logging.c @@ -25,8 +25,13 @@ #include #include #include -#include "criterion/logging.h" +#include "criterion/criterion.h" #include "criterion/options.h" +#include "compat/process.h" +#include "log/logging.h" +#include "io/asprintf.h" +#include "protocol/protocol.h" +#include "protocol/messages.h" #include "string/i18n.h" #ifdef ENABLE_NLS @@ -45,9 +50,46 @@ const struct criterion_prefix_data g_criterion_logging_prefixes[] = { [CRITERION_LOGGING_PREFIX_PASS] = { "PASS", CRIT_FG_GREEN }, [CRITERION_LOGGING_PREFIX_FAIL] = { "FAIL", CRIT_FG_RED }, [CRITERION_LOGGING_PREFIX_ERR] = { "ERR ", CRIT_FG_RED }, + [CRITERION_LOGGING_PREFIX_WARN] = { "WARN", CRIT_FG_GOLD }, { NULL, NULL } }; +void criterion_log_noformat(enum criterion_severity severity, const char *msg) { + static const struct criterion_prefix_data *prefixes[] = { + [CR_LOG_INFO] = CRITERION_PREFIX_DASHES, + [CR_LOG_WARNING] = CRITERION_PREFIX_WARN, + [CR_LOG_ERROR] = CRITERION_PREFIX_ERR, + }; + + static enum criterion_logging_level severity_to_level[] = { + [CR_LOG_INFO] = CRITERION_INFO, + [CR_LOG_WARNING] = CRITERION_IMPORTANT, + [CR_LOG_ERROR] = CRITERION_IMPORTANT, + }; + + if (severity_to_level[severity] < criterion_options.logging_threshold) + return; + + const struct criterion_prefix_data *prefix = prefixes[severity]; + if (severity == CR_LOG_ERROR) { + fprintf(stderr, _(ERROR_FORMAT), + CRIT_COLOR_NORMALIZE(prefix->color), + prefix->prefix, + CR_RESET, + CR_FG_RED, + CR_FG_BOLD, + msg, + CR_RESET); + } else { + fprintf(stderr, _(LOG_FORMAT), + CRIT_COLOR_NORMALIZE(prefix->color), + prefix->prefix, + CR_RESET, + msg); + } + fprintf(stderr, "\n"); +} + void criterion_plog(enum criterion_logging_level level, const struct criterion_prefix_data *prefix, const char *msg, ...) { va_list args; @@ -91,3 +133,28 @@ void criterion_vlog(enum criterion_logging_level level, const char *msg, va_list vfprintf(stderr, msg, args); } + +void cr_log_noformat(enum criterion_severity severity, const char *out) { + criterion_protocol_msg msg = criterion_message(message, + .severity = (criterion_protocol_log_level) severity, + .message = (char *) out); + criterion_message_set_id(msg); + cr_send_to_runner(&msg); +} + +void cr_log(enum criterion_severity severity, const char *msg, ...) { + va_list args; + char *out = NULL; + + va_start(args, msg); + int res = cr_vasprintf(&out, msg, args); + va_end(args); + + if (res == -1) { + cr_log_noformat(CR_LOG_ERROR, "Could not format log message"); + abort(); + } + + cr_log_noformat(severity, out); + free(out); +} diff --git a/src/log/logging.h b/src/log/logging.h new file mode 100644 index 0000000..7e03de5 --- /dev/null +++ b/src/log/logging.h @@ -0,0 +1,100 @@ +/* + * The MIT License (MIT) + * + * Copyright © 2015-2016 Franklin "Snaipe" Mathieu + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#ifndef LOGGING_H_ +# define LOGGING_H_ + +# ifdef __cplusplus +# include +using std::va_list; +# else +# include +# include +# endif +# include "criterion/logging.h" + +enum criterion_logging_prefix { + CRITERION_LOGGING_PREFIX_DASHES, + CRITERION_LOGGING_PREFIX_EQUALS, + CRITERION_LOGGING_PREFIX_RUN, + CRITERION_LOGGING_PREFIX_SKIP, + CRITERION_LOGGING_PREFIX_PASS, + CRITERION_LOGGING_PREFIX_FAIL, + CRITERION_LOGGING_PREFIX_ERR, + CRITERION_LOGGING_PREFIX_WARN, +}; + +struct criterion_prefix_data { + const char *prefix; + const char *color; +}; + +# ifdef CRITERION_LOGGING_COLORS +# define CRIT_COLOR_NORMALIZE(Str) (criterion_options.use_ascii ? "" : Str) + +# define CRIT_FG_BOLD "\33[0;1m" +# define CRIT_FG_RED "\33[0;31m" +# define CRIT_FG_GREEN "\33[0;32m" +# define CRIT_FG_GOLD "\33[0;33m" +# define CRIT_FG_BLUE "\33[0;34m" +# define CRIT_RESET "\33[0m" + +# define CR_FG_BOLD CRIT_COLOR_NORMALIZE(CRIT_FG_BOLD) +# define CR_FG_RED CRIT_COLOR_NORMALIZE(CRIT_FG_RED) +# define CR_FG_GREEN CRIT_COLOR_NORMALIZE(CRIT_FG_GREEN) +# define CR_FG_GOLD CRIT_COLOR_NORMALIZE(CRIT_FG_GOLD) +# define CR_FG_BLUE CRIT_COLOR_NORMALIZE(CRIT_FG_BLUE) +# define CR_RESET CRIT_COLOR_NORMALIZE(CRIT_RESET) +# endif + +extern const struct criterion_prefix_data g_criterion_logging_prefixes[]; + +# define CRITERION_PREFIX_DASHES (&g_criterion_logging_prefixes[CRITERION_LOGGING_PREFIX_DASHES]) +# define CRITERION_PREFIX_EQUALS (&g_criterion_logging_prefixes[CRITERION_LOGGING_PREFIX_EQUALS]) +# define CRITERION_PREFIX_RUN (&g_criterion_logging_prefixes[CRITERION_LOGGING_PREFIX_RUN ]) +# define CRITERION_PREFIX_SKIP (&g_criterion_logging_prefixes[CRITERION_LOGGING_PREFIX_SKIP ]) +# define CRITERION_PREFIX_PASS (&g_criterion_logging_prefixes[CRITERION_LOGGING_PREFIX_PASS ]) +# define CRITERION_PREFIX_FAIL (&g_criterion_logging_prefixes[CRITERION_LOGGING_PREFIX_FAIL ]) +# define CRITERION_PREFIX_ERR (&g_criterion_logging_prefixes[CRITERION_LOGGING_PREFIX_ERR ]) +# define CRITERION_PREFIX_WARN (&g_criterion_logging_prefixes[CRITERION_LOGGING_PREFIX_WARN ]) + +CR_API void criterion_vlog(enum criterion_logging_level level, const char *msg, va_list args); + +CR_FORMAT(printf, 3, 4) +CR_API void criterion_plog(enum criterion_logging_level level, const struct criterion_prefix_data *prefix, const char *msg, ...); + +CR_FORMAT(printf, 2, 3) +CR_API void criterion_log(enum criterion_logging_level level, const char *msg, ...); + +# define criterion_info(...) criterion_log(CRITERION_INFO, __VA_ARGS__) +# define criterion_important(...) criterion_log(CRITERION_IMPORTANT, __VA_ARGS__) + +# define criterion_pinfo(...) criterion_plog(CRITERION_INFO, __VA_ARGS__) +# define criterion_pimportant(...) criterion_plog(CRITERION_IMPORTANT, __VA_ARGS__) + +# define criterion_perror(...) criterion_plog(CRITERION_IMPORTANT, CRITERION_PREFIX_ERR, __VA_ARGS__) + +void cr_log_noformat(enum criterion_severity severity, const char *out); +void criterion_log_noformat(enum criterion_severity severity, const char *msg); + +#endif /* !LOGGING_H_ */ diff --git a/src/log/normal.c b/src/log/normal.c index 300266e..95dffb2 100644 --- a/src/log/normal.c +++ b/src/log/normal.c @@ -27,9 +27,9 @@ #include #include #include "criterion/stats.h" -#include "criterion/logging.h" #include "criterion/options.h" #include "criterion/internal/ordered-set.h" +#include "log/logging.h" #include "compat/posix.h" #include "compat/strtok.h" #include "compat/time.h" @@ -233,6 +233,10 @@ void normal_log_test_abort(CR_UNUSED struct criterion_test_stats *stats, const c free(dup); } +void normal_log_message(enum criterion_severity severity, const char *msg) { + criterion_log_noformat(severity, msg); +} + struct criterion_logger normal_logging = { .log_pre_all = normal_log_pre_all, .log_pre_init = normal_log_pre_init, @@ -247,4 +251,5 @@ struct criterion_logger normal_logging = { .log_post_test = normal_log_post_test, .log_post_suite = normal_log_post_suite, .log_post_all = normal_log_post_all, + .log_message = normal_log_message, }; diff --git a/src/protocol/messages.c b/src/protocol/messages.c index 6a03697..788d66e 100644 --- a/src/protocol/messages.c +++ b/src/protocol/messages.c @@ -24,7 +24,7 @@ #include #include #include "protocol/protocol.h" -#include "criterion/logging.h" +#include "log/logging.h" #include "io/event.h" #include "io/asprintf.h"