Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Terminal ansi colors #427

Merged
merged 22 commits into from
Jul 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
0d79732
Added array for escape codes in stream_target struct, added entry arg…
DR-Reg Jun 16, 2024
4e84861
Added defines for the default severity escape codes used
DR-Reg Jun 16, 2024
0e1cf3d
Added definition for the stumpless_set_severity_color and attempted t…
DR-Reg Jun 16, 2024
337661a
Added entry parameter in sendto_stream_target call so the severity is…
DR-Reg Jun 16, 2024
a9dc6ff
Used set_severity_color to set the default severity colors inside the…
DR-Reg Jun 16, 2024
ab2f945
Broke down fwrite in sendto_stream_target so that we can check the re…
DR-Reg Jun 16, 2024
c43e5c9
Fixed so that it passes StreamTargetStderr.NullName (and similar for …
DR-Reg Jun 16, 2024
f5a08db
Fixed documentation comments in include/stumpless/target/stream.h
DR-Reg Jul 2, 2024
e1f0949
Changed severity error checking to use severity_is_invalid and raise_…
DR-Reg Jul 2, 2024
ef0f068
Moved lock_target up in stumpless_set_severity_color so the target is…
DR-Reg Jul 2, 2024
0c5c8d8
Moved from 3 individual critical sections in sendto_stream_target to …
DR-Reg Jul 2, 2024
0523757
Fixed small typo where strlen of sev_code instead of reset_code was t…
DR-Reg Jul 2, 2024
fa90924
Added clear_error in stumpless_set_severity_color so error code is cl…
DR-Reg Jul 2, 2024
1a03b8e
Added tests for colored output when streaming to stdout and stderr
DR-Reg Jul 2, 2024
0fc108e
Fixed small error to do with unincluded header file
DR-Reg Jul 2, 2024
b7ec39c
Added preprocessor directives to test/function/target/stream.cpp so t…
DR-Reg Jul 3, 2024
a9cc2cc
Implemented a fix for tests on windows due to gtest's lack of reasona…
DR-Reg Jul 3, 2024
f6a7e1e
Fixed small bug where the function was not returning after raising an…
DR-Reg Jul 3, 2024
0f0fb56
Added test for stumpless_set_severity_color
DR-Reg Jul 3, 2024
1fa15f5
Added explanatory comments in ColoredStream tests in test/function/ta…
DR-Reg Jul 4, 2024
fa01e86
Added stumpless_set_severity_color to src/windows/stumpless.def
DR-Reg Jul 4, 2024
20553d0
Fixed leaks in test/function/target/stream.cpp by ensuring any heap m…
DR-Reg Jul 4, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion include/private/target/stream.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
# include <stddef.h>
# include <stdio.h>
# include <stumpless/config.h>
# include <stumpless/entry.h>
# include "private/config/wrapper/thread_safety.h"

/**
Expand All @@ -30,6 +31,8 @@
struct stream_target {
/** The stream this target writes to. */
FILE *stream;
/** ANSI colors for different severities (when using ansi terminal) */
char escape_codes[8][32];
# ifdef STUMPLESS_THREAD_SAFETY_SUPPORTED
/**
* Protects stream. This mutex must be locked by a thread before it can write
Expand Down Expand Up @@ -61,6 +64,7 @@ new_stream_target( FILE *stream );
int
sendto_stream_target( struct stream_target *target,
const char *msg,
size_t msg_length );
size_t msg_length,
const struct stumpless_entry *entry );

#endif /* __STUMPLESS_PRIVATE_TARGET_STREAM_H */
14 changes: 14 additions & 0 deletions include/stumpless/severity.h
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,20 @@ enum stumpless_severity {
STUMPLESS_FOREACH_SEVERITY( STUMPLESS_GENERATE_ENUM )
};

/**
* The default stumpless ansi terminal color values
*/
#define STUMPLESS_SEVERITY_EMERG_DEFAULT_COLOR "\33[31;1m"
#define STUMPLESS_SEVERITY_ALERT_DEFAULT_COLOR "\33[31;1m"
#define STUMPLESS_SEVERITY_CRIT_DEFAULT_COLOR "\33[31m"
#define STUMPLESS_SEVERITY_ERR_DEFAULT_COLOR "\33[31m"
#define STUMPLESS_SEVERITY_WARNING_DEFAULT_COLOR "\33[33m"
#define STUMPLESS_SEVERITY_NOTICE_DEFAULT_COLOR "\33[32m"
#define STUMPLESS_SEVERITY_INFO_DEFAULT_COLOR "\33[37m"
#define STUMPLESS_SEVERITY_DEBUG_DEFAULT_COLOR "\33[0m"



/**
* Equivalent to the DEBUG severity. Trace level messages include extra
* information, but do not have a distinct severity value in log entries.
Expand Down
29 changes: 29 additions & 0 deletions include/stumpless/target/stream.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
# include <stdio.h>
# include <stumpless/config.h>
# include <stumpless/target.h>
# include <stumpless/severity.h>

# ifdef __cplusplus
extern "C" {
Expand Down Expand Up @@ -154,6 +155,34 @@ STUMPLESS_PUBLIC_FUNCTION
struct stumpless_target *
stumpless_open_stream_target( const char *name, FILE *stream );

/**
DR-Reg marked this conversation as resolved.
Show resolved Hide resolved
* Sets the ANSI escape code (https://en.wikipedia.org/wiki/ANSI_escape_code) to
* be printed in a specific target when a log is made at some severity.
*
* It should be used with stdout or stderr as targets, since it is only for aesthetic purposes.
*
* **Thread Safety: MT-Safe race:escape_code**
* This function is thread safe, of course assuming that escape_code is not modified by
* any other threads during execution.
*
* **Async Signal Safety: AS-Unsafe lock**
* This function is not safe to call from signal handlers due to the destruction
* of a lock that may be in use.
*
* **Async Cancel Safety: AC-Unsafe lock**
* This function is not safe to call from threads that may be asynchronously
* cancelled, as the cleanup of the lock may not be completed.
*
* @param target The name of the target for which to set the colors.
*
* @param severity The severity code (LOG_ERR etc.) to which we set the specific color.
*
* @param escape_code The ANSI escape code representing the color.
*/
STUMPLESS_PUBLIC_FUNCTION
void
stumpless_set_severity_color( struct stumpless_target *target, enum stumpless_severity severity, const char *escape_code );

# ifdef __cplusplus
} /* extern "C" */
# endif
Expand Down
2 changes: 1 addition & 1 deletion src/target.c
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ stumpless_add_entry( struct stumpless_target *target,
break;

case STUMPLESS_STREAM_TARGET:
result = sendto_stream_target( target->id, buffer, builder_length );
result = sendto_stream_target( target->id, buffer, builder_length, entry );
break;

case STUMPLESS_WINDOWS_EVENT_LOG_TARGET:
Expand Down
94 changes: 88 additions & 6 deletions src/target/stream.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@

#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <stumpless/target.h>
#include <stumpless/severity.h>
#include <stumpless/entry.h>
#include <stumpless/target/stream.h>
#include "private/config/wrapper/locale.h"
#include "private/config/wrapper/thread_safety.h"
Expand All @@ -28,6 +31,7 @@
#include "private/target.h"
#include "private/target/stream.h"
#include "private/validate.h"
#include "private/severity.h"

void
stumpless_close_stream_target( const struct stumpless_target *target ) {
Expand All @@ -48,12 +52,39 @@

struct stumpless_target *
stumpless_open_stderr_target( const char *name ) {
return stumpless_open_stream_target( name, stderr );
struct stumpless_target *target = stumpless_open_stream_target( name, stderr );

if (target == NULL) return NULL;

stumpless_set_severity_color(target, STUMPLESS_SEVERITY_EMERG_VALUE , STUMPLESS_SEVERITY_EMERG_DEFAULT_COLOR );
stumpless_set_severity_color(target, STUMPLESS_SEVERITY_ALERT_VALUE , STUMPLESS_SEVERITY_ALERT_DEFAULT_COLOR );
stumpless_set_severity_color(target, STUMPLESS_SEVERITY_CRIT_VALUE , STUMPLESS_SEVERITY_CRIT_DEFAULT_COLOR );
stumpless_set_severity_color(target, STUMPLESS_SEVERITY_ERR_VALUE , STUMPLESS_SEVERITY_ERR_DEFAULT_COLOR );
stumpless_set_severity_color(target, STUMPLESS_SEVERITY_WARNING_VALUE, STUMPLESS_SEVERITY_WARNING_DEFAULT_COLOR);
stumpless_set_severity_color(target, STUMPLESS_SEVERITY_NOTICE_VALUE , STUMPLESS_SEVERITY_NOTICE_DEFAULT_COLOR );
stumpless_set_severity_color(target, STUMPLESS_SEVERITY_INFO_VALUE , STUMPLESS_SEVERITY_INFO_DEFAULT_COLOR );
stumpless_set_severity_color(target, STUMPLESS_SEVERITY_DEBUG_VALUE , STUMPLESS_SEVERITY_DEBUG_DEFAULT_COLOR );

return target;
}

struct stumpless_target *
stumpless_open_stdout_target( const char *name ) {
return stumpless_open_stream_target( name, stdout );
struct stumpless_target *target = stumpless_open_stream_target( name, stdout );

if (target == NULL) return NULL;

stumpless_set_severity_color(target, STUMPLESS_SEVERITY_EMERG_VALUE , STUMPLESS_SEVERITY_EMERG_DEFAULT_COLOR );
stumpless_set_severity_color(target, STUMPLESS_SEVERITY_ALERT_VALUE , STUMPLESS_SEVERITY_ALERT_DEFAULT_COLOR );
stumpless_set_severity_color(target, STUMPLESS_SEVERITY_CRIT_VALUE , STUMPLESS_SEVERITY_CRIT_DEFAULT_COLOR );
stumpless_set_severity_color(target, STUMPLESS_SEVERITY_ERR_VALUE , STUMPLESS_SEVERITY_ERR_DEFAULT_COLOR );
stumpless_set_severity_color(target, STUMPLESS_SEVERITY_WARNING_VALUE, STUMPLESS_SEVERITY_WARNING_DEFAULT_COLOR);
stumpless_set_severity_color(target, STUMPLESS_SEVERITY_NOTICE_VALUE , STUMPLESS_SEVERITY_NOTICE_DEFAULT_COLOR );
stumpless_set_severity_color(target, STUMPLESS_SEVERITY_INFO_VALUE , STUMPLESS_SEVERITY_INFO_DEFAULT_COLOR );
stumpless_set_severity_color(target, STUMPLESS_SEVERITY_DEBUG_VALUE , STUMPLESS_SEVERITY_DEBUG_DEFAULT_COLOR );


return target;
}

struct stumpless_target *
Expand All @@ -76,6 +107,9 @@
goto fail_id;
}

for (unsigned short i = 0; i < 8; i++)
((struct stream_target *)(target->id))->escape_codes[i][0] = 0;

stumpless_set_current_target( target );
return target;

Expand All @@ -85,6 +119,30 @@
return NULL;
}

void
stumpless_set_severity_color( struct stumpless_target *target, enum stumpless_severity severity, const char *escape_code )
{
if (severity_is_invalid(severity)) {
raise_invalid_severity(severity);
return;
}

lock_target(target);
if (target->type != STUMPLESS_STREAM_TARGET) {
raise_target_unsupported("This function is only supported for stream targets");
goatshriek marked this conversation as resolved.
Show resolved Hide resolved
return;
}

struct stream_target *starget = (struct stream_target *)target->id;

strncpy(starget->escape_codes[severity], escape_code, 32);
starget->escape_codes[severity][31] = 0;

unlock_target(target);
clear_error();
}
DR-Reg marked this conversation as resolved.
Show resolved Hide resolved


/* private definitions */

void
Expand All @@ -111,20 +169,44 @@
int
sendto_stream_target( struct stream_target *target,
const char *msg,
size_t msg_length ) {
size_t msg_length,
const struct stumpless_entry *entry ) {
size_t fwrite_result;

enum stumpless_severity severity = stumpless_get_entry_severity(entry);
const char *sev_code = target->escape_codes[severity];
unsigned short sev_code_len = strlen(sev_code);
const char *reset_code = "\33[0m";
unsigned short reset_code_len = strlen(reset_code);

config_lock_mutex( &target->stream_mutex );
fwrite_result = fwrite( msg, sizeof( char ), msg_length, target->stream );
config_unlock_mutex( &target->stream_mutex );
if (sev_code_len != 0)
{
fwrite_result = fwrite( sev_code, sizeof( char ), sev_code_len, target->stream );

if( fwrite_result != sev_code_len ) {
goto write_failure;
}
}

fwrite_result = fwrite( msg, sizeof( char ), msg_length, target->stream );
if( fwrite_result != msg_length ) {
goto write_failure;
}

if (sev_code_len != 0)
{
fwrite_result = fwrite( reset_code, sizeof( char ), reset_code_len, target->stream );

if( fwrite_result != reset_code_len ) {
goto write_failure;

Check warning on line 201 in src/target/stream.c

View check run for this annotation

Codecov / codecov/patch

src/target/stream.c#L201

Added line #L201 was not covered by tests
}
}

config_unlock_mutex( &target->stream_mutex );
return cap_size_t_to_int( fwrite_result + 1 );

write_failure:
config_unlock_mutex( &target->stream_mutex );
raise_stream_write_failure( );
return -1;
}
1 change: 1 addition & 0 deletions src/windows/stumpless.def
Original file line number Diff line number Diff line change
Expand Up @@ -246,3 +246,4 @@ EXPORTS
stumpless_set_entry_message_str_w @229

stumpless_get_prival_string @230
stumpless_set_severity_color @231
Loading
Loading