@@ -87,6 +87,10 @@ bool g_rcutils_logging_initialized = false;
8787static char g_rcutils_logging_output_format_string [RCUTILS_LOGGING_MAX_OUTPUT_FORMAT_LEN ];
8888static const char * g_rcutils_logging_default_output_format =
8989 "[{severity}] [{time}] [{name}]: {message}" ;
90+ #ifdef _WIN32
91+ static DWORD g_original_console_mode = 0 ;
92+ static bool g_consol_mode_modified = false;
93+ #endif
9094
9195static rcutils_allocator_t g_rcutils_logging_allocator ;
9296
@@ -415,6 +419,30 @@ static const char * copy_from_orig(
415419 return logging_output -> buffer ;
416420}
417421
422+ #ifdef _WIN32
423+ #define ACTIVATE_VIRTUAL_TERMINAL_PROCESSING () \
424+ { \
425+ HANDLE std_error_handle = GetStdHandle(STD_ERROR_HANDLE); \
426+ if (std_error_handle == INVALID_HANDLE_VALUE) { \
427+ RCUTILS_SET_ERROR_MSG("Could not get error handle to activating virtual terminal."); \
428+ return; \
429+ } \
430+ if (!GetConsoleMode(std_error_handle, &g_original_console_mode)) { \
431+ RCUTILS_SET_ERROR_MSG("Could not get consol mode to activating virtual terminal."); \
432+ return; \
433+ } \
434+ DWORD newDwMode = g_original_console_mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING; \
435+ if (!SetConsoleMode(std_error_handle, newDwMode)) { \
436+ RCUTILS_SET_ERROR_MSG("Could not set consol mode to activating virtual terminal."); \
437+ return; \
438+ } \
439+ g_consol_mode_modified = true; \
440+ }
441+ #else
442+ // nothing todo for non-windows platform
443+ #define ACTIVATE_VIRTUAL_TERMINAL_PROCESSING ()
444+ #endif
445+
418446// copy buffers and decode escape characters if they exist
419447static void create_format_string (
420448 const char * logging_output_format_string )
@@ -440,14 +468,28 @@ static void create_format_string(
440468 break ;
441469 } else {
442470 const char * expected_char = NULL ;
443- switch (logging_output_format_string [i + back_slash_index + 1 ]) {
444- case 'a' : expected_char = "\a" ; break ; // alert
445- case 'b' : expected_char = "\b" ; break ; // backspace
446- case 'n' : expected_char = "\n" ; break ; // new line
447- case 'r' : expected_char = "\r" ; break ; // carriage return
448- case 't' : expected_char = "\t" ; break ; // horizontal tab
449- default :
450- break ;
471+ int skip_chars = 0 ;
472+
473+ if (logging_output_format_string [i + back_slash_index + 1 ] == 'x' &&
474+ logging_output_format_string [i + back_slash_index + 2 ] == '1' &&
475+ logging_output_format_string [i + back_slash_index + 3 ] == 'b' )
476+ {
477+ // detect escape sequence
478+ ACTIVATE_VIRTUAL_TERMINAL_PROCESSING ();
479+ expected_char = "\x1b" ;
480+ // the 4 char long "\x1b" string literal will become a 2 char long \x1b escape sequence
481+ // therefore we need to skip forward in parsing the output format string
482+ skip_chars = 2 ;
483+ } else {
484+ switch (logging_output_format_string [i + back_slash_index + 1 ]) {
485+ case 'a' : expected_char = "\a" ; break ; // alert
486+ case 'b' : expected_char = "\b" ; break ; // backspace
487+ case 'n' : expected_char = "\n" ; break ; // new line
488+ case 'r' : expected_char = "\r" ; break ; // carriage return
489+ case 't' : expected_char = "\t" ; break ; // horizontal tab
490+ default :
491+ break ;
492+ }
451493 }
452494
453495 if (expected_char ) {
@@ -466,12 +508,12 @@ static void create_format_string(
466508 // copy the decoded character
467509 g_rcutils_logging_output_format_string [dest_buffer_index ] = expected_char [0 ];
468510 dest_buffer_index += 1 ;
469- start_offset += 2 ;
511+ start_offset += 2 + skip_chars ;
470512 } else {
471513 start_offset_previous_not_copy += (back_slash_index + 2 );
472514 }
473515
474- i += (back_slash_index + 2 );
516+ i += (back_slash_index + 2 + skip_chars );
475517 }
476518 }
477519}
@@ -749,6 +791,12 @@ rcutils_ret_t rcutils_logging_shutdown(void)
749791 }
750792 g_num_log_msg_handlers = 0 ;
751793 g_rcutils_logging_initialized = false;
794+
795+ #ifdef _WIN32
796+ if (g_consol_mode_modified ) {
797+ SetConsoleMode (GetStdHandle (STD_ERROR_HANDLE ), g_original_console_mode );
798+ }
799+ #endif
752800 return ret ;
753801}
754802
0 commit comments