From 9172b087f95ea050d620740459530ed16d059c41 Mon Sep 17 00:00:00 2001 From: m3g4d1v3r <99227953+m3g4d1v3r@users.noreply.github.com> Date: Sat, 9 Nov 2024 18:55:34 +0200 Subject: [PATCH] add stumpless_get_priority_string Adds a function to print privals in a more succinct representation that follows the priority string convention used by tools like logger, for example "local3.info". --- include/stumpless/prival.h | 27 +++++++++++++++++++++ src/prival.c | 45 +++++++++++++++++++++++++++++++++++ src/windows/stumpless.def | 4 ++-- test/function/prival.cpp | 48 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 122 insertions(+), 2 deletions(-) diff --git a/include/stumpless/prival.h b/include/stumpless/prival.h index b369312ae..0b2dbeba0 100644 --- a/include/stumpless/prival.h +++ b/include/stumpless/prival.h @@ -59,6 +59,33 @@ STUMPLESS_PUBLIC_FUNCTION const char * stumpless_get_prival_string( int prival ); +/** + * Gets the string representation of the given prival in the format + * "facility.level". + * + * The string returned must be freed by the caller when it is no longer + * needed to avoid memory leaks. + * + * **Thread Safety: MT-Safe** + * This function is thread safe. + * + * **Async Signal Safety: AS-Unsafe heap** + * This function is not safe to call from signal handlers due to the use of + * memory management functions. + * + * **Async Cancel Safety: AC-Unsafe heap** + * This function is not safe to call from threads that may be asynchronously + * cancelled due to the use of memory management functions. + * + * @param prival int to get the string from. + * + * @return The string representation of the given prival. + * +*/ +STUMPLESS_PUBLIC_FUNCTION +const char * +stumpless_get_priority_string( int prival ); + /** * Extract PRIVAL number (Facility and Severity) from the given string with * the direct number or with two names divided with a period in the order: diff --git a/src/prival.c b/src/prival.c index 05d0abd28..9fa14eff8 100644 --- a/src/prival.c +++ b/src/prival.c @@ -58,6 +58,51 @@ stumpless_get_prival_string( int prival ) { return prival_string; } +const char * +stumpless_get_priority_string( int prival ) { + const char *facility; + const char *severity; + + size_t priority_string_size; + char* priority_string; + + if ((prival & 0xff) != prival) + return NULL; + if (facility_is_invalid(get_facility(prival))) + return NULL; + + facility = stumpless_get_facility_string( get_facility( prival ) ); + severity = stumpless_get_severity_string( get_severity( prival ) ); + + facility = strrchr(facility, '_'); + severity = strrchr(severity, '_'); + + // inc by 1 to skip '_' + facility++; + severity++; + + size_t len_facility = strlen(facility); + size_t len_severity = strlen(severity); + + // +1 for '.' formatting, +1 for termination + priority_string_size = ( len_facility + len_severity + 2 ); + priority_string = alloc_mem( priority_string_size ); + + for (size_t idx = 0; idx < len_facility; idx++) { + priority_string[idx] = tolower(facility[idx]); + } + + priority_string[len_facility] = '.'; + + for (size_t idx = 0; idx < len_severity; idx++) { + priority_string[len_facility + 1 + idx] = tolower(severity[idx]); + } + + priority_string[priority_string_size - 1] = '\0'; + + return priority_string; +} + int stumpless_prival_from_string( const char *string ) { int prival; diff --git a/src/windows/stumpless.def b/src/windows/stumpless.def index 2bf9db7a0..80e31b8b5 100644 --- a/src/windows/stumpless.def +++ b/src/windows/stumpless.def @@ -247,7 +247,7 @@ EXPORTS stumpless_get_prival_string @230 stumpless_set_severity_color @231 - stumpless_get_malloc @232 stumpless_get_free @233 - stumpless_get_realloc @234 \ No newline at end of file + stumpless_get_realloc @234 + stumpless_get_priority_string @235 diff --git a/test/function/prival.cpp b/test/function/prival.cpp index 7c2623bf7..dcfc96f3f 100644 --- a/test/function/prival.cpp +++ b/test/function/prival.cpp @@ -121,4 +121,52 @@ namespace { free( ( void * ) result ); } + + TEST(GetPriorityString, ValidPrival) { + int prival; + const char *result; + + prival = STUMPLESS_SEVERITY_ERR | STUMPLESS_FACILITY_USER; + result = stumpless_get_priority_string( prival ); + EXPECT_STREQ( result, "user.err" ); + + free( ( void * ) result ); + } + + TEST(GetPriorityString, InvalidPrivalNegativeArgument) { + int prival; + const char *result; + + // Test for negative argument (falls outside of a byte) + prival = -1; + result = stumpless_get_priority_string( prival ); + EXPECT_STREQ( result, NULL ); + + free( ( void * ) result ); + } + + TEST(GetPriorityString, InvalidPrivalGreaterThanRange) { + int prival; + const char *result; + + // Test for argument greater than one byte + prival = 0x100; + result = stumpless_get_priority_string( prival ); + EXPECT_STREQ( result, NULL ); + + free( ( void * ) result ); + } + + TEST(GetPriorityString, InvalidPrivalFacilityGreaterThanRange) { + int prival; + const char *result; + + // Test for argument that translates into an invalid facility + // (greater than 0xbf) + prival = 0xc0; + result = stumpless_get_priority_string( prival ); + EXPECT_STREQ( result, NULL ); + + free( ( void * ) result ); + } }