From c1bfad9098d94caa4cc2fe64be6b552f4010a0b7 Mon Sep 17 00:00:00 2001 From: Lucas Czech Date: Wed, 23 Mar 2022 11:16:18 +0000 Subject: [PATCH] Add hts_log callback function and hts_log_set_logger() [DRAFT] Needs documentation in htslib/hts_log.h. Co-Authored-By: John Marshall --- hts.c | 21 +++++++++++++++++---- htslib/hts_log.h | 6 ++++++ test/sam.c | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 4 deletions(-) diff --git a/hts.c b/hts.c index 30c0c6890..9448d7f75 100644 --- a/hts.c +++ b/hts.c @@ -4754,19 +4754,32 @@ static char get_severity_tag(enum htsLogLevel severity) return '*'; } +static hts_log_func *hts_logger = NULL; +static void *hts_logger_data = NULL; + +void hts_log_set_logger(hts_log_func *logger, void *data) +{ + hts_logger = logger; + hts_logger_data = data; +} + void hts_log(enum htsLogLevel severity, const char *context, const char *format, ...) { int save_errno = errno; if (severity <= hts_verbose) { va_list argptr; - fprintf(stderr, "[%c::%s] ", get_severity_tag(severity), context); - va_start(argptr, format); - vfprintf(stderr, format, argptr); + if (hts_logger) { + hts_logger(hts_logger_data, severity, get_severity_tag(severity), context, format, argptr); + } + else { + fprintf(stderr, "[%c::%s] ", get_severity_tag(severity), context); + vfprintf(stderr, format, argptr); + fprintf(stderr, "\n"); + } va_end(argptr); - fprintf(stderr, "\n"); } errno = save_errno; } diff --git a/htslib/hts_log.h b/htslib/hts_log.h index b2336a4df..b6af29b81 100644 --- a/htslib/hts_log.h +++ b/htslib/hts_log.h @@ -29,6 +29,7 @@ SOFTWARE. #ifndef HTS_LOG_H #define HTS_LOG_H +#include #include "hts_defs.h" #ifdef __cplusplus @@ -89,6 +90,11 @@ HTS_FORMAT(HTS_PRINTF_FMT, 3, 4); /*! Logs an event with severity HTS_LOG_TRACE and default context. Parameters: format, ... */ #define hts_log_trace(...) hts_log(HTS_LOG_TRACE, __func__, __VA_ARGS__) +typedef void hts_log_func(void *data, enum htsLogLevel severity, char severity_tag, const char *context, const char *format, va_list args); + +HTSLIB_EXPORT +void hts_log_set_logger(hts_log_func *logger, void *data); + #ifdef __cplusplus } #endif diff --git a/test/sam.c b/test/sam.c index cc5bfe77a..e4ddbf37a 100644 --- a/test/sam.c +++ b/test/sam.c @@ -1874,6 +1874,37 @@ static void test_mempolicy(void) } } +static void my_logger(void *data, enum htsLogLevel severity, char severity_tag, const char *context, const char *format, va_list args) +{ + char msg[200]; + int *nptr = (int *) data; + (*nptr)++; + + if (severity != HTS_LOG_ERROR) fail("my_logger saw the wrong message"); + + vsprintf(msg, format, args); + if (strcmp(msg, "YOU SHOULD NOT SEE THIS MESSAGE") != 0) + fail("my_logger message was incorrect: \"%s\"", msg); +} + +static void test_logging(void) +{ + int old_level = hts_get_log_level(); + int n = 0; + + hts_set_log_level(HTS_LOG_WARNING); + + hts_log_set_logger(my_logger, &n); + hts_log_error("YOU SHOULD NOT SEE %s", "THIS MESSAGE"); + if (n != 1) fail("test_logging message one was not redirected"); + + hts_log_set_logger(NULL, NULL); + hts_log_warning("(expect to see this message)"); + if (n != 1) fail("test_logging message two was redirected"); + + hts_set_log_level(old_level); +} + static void test_bam_set1_minimal() { int r; @@ -2227,6 +2258,7 @@ int main(int argc, char **argv) check_big_ref(1); test_parse_decimal(); test_mempolicy(); + test_logging(); set_qname(); for (i = 1; i < argc; i++) faidx1(argv[i]);