@@ -639,9 +639,68 @@ int os_get_cwd(Buf *out_cwd) {
639
639
#endif
640
640
}
641
641
642
+ #if defined(ZIG_OS_WINDOWS)
643
+ #define is_wprefix (s, prefix ) \
644
+ (wcsncmp((s), (prefix), sizeof (prefix) / sizeof (WCHAR) - 1 ) == 0 )
645
+ static bool is_stderr_cyg_pty (void ) {
646
+ HANDLE stderr_handle = GetStdHandle (STD_ERROR_HANDLE);
647
+ if (stderr_handle == INVALID_HANDLE_VALUE)
648
+ return false ;
649
+
650
+ HANDLE h;
651
+ int size = sizeof (FILE_NAME_INFO) + sizeof (WCHAR) * MAX_PATH;
652
+ FILE_NAME_INFO *nameinfo;
653
+ WCHAR *p = NULL ;
654
+
655
+ // Cygwin/msys's pty is a pipe.
656
+ if (GetFileType (stderr_handle) != FILE_TYPE_PIPE) {
657
+ return 0 ;
658
+ }
659
+ nameinfo = (FILE_NAME_INFO *)allocate<char >(size);
660
+ if (nameinfo == NULL ) {
661
+ return 0 ;
662
+ }
663
+ // Check the name of the pipe:
664
+ // '\{cygwin,msys}-XXXXXXXXXXXXXXXX-ptyN-{from,to}-master'
665
+ if (GetFileInformationByHandleEx (stderr_handle, FileNameInfo, nameinfo, size)) {
666
+ nameinfo->FileName [nameinfo->FileNameLength / sizeof (WCHAR)] = L' \0 ' ;
667
+ p = nameinfo->FileName ;
668
+ if (is_wprefix (p, L" \\ cygwin-" )) { /* Cygwin */
669
+ p += 8 ;
670
+ } else if (is_wprefix (p, L" \\ msys-" )) { /* MSYS and MSYS2 */
671
+ p += 6 ;
672
+ } else {
673
+ p = NULL ;
674
+ }
675
+ if (p != NULL ) {
676
+ while (*p && isxdigit (*p)) /* Skip 16-digit hexadecimal. */
677
+ ++p;
678
+ if (is_wprefix (p, L" -pty" )) {
679
+ p += 4 ;
680
+ } else {
681
+ p = NULL ;
682
+ }
683
+ }
684
+ if (p != NULL ) {
685
+ while (*p && isdigit (*p)) /* Skip pty number. */
686
+ ++p;
687
+ if (is_wprefix (p, L" -from-master" )) {
688
+ // p += 12;
689
+ } else if (is_wprefix (p, L" -to-master" )) {
690
+ // p += 10;
691
+ } else {
692
+ p = NULL ;
693
+ }
694
+ }
695
+ }
696
+ free (nameinfo);
697
+ return (p != NULL );
698
+ }
699
+ #endif
700
+
642
701
bool os_stderr_tty (void ) {
643
702
#if defined(ZIG_OS_WINDOWS)
644
- return _isatty (_fileno (stderr)) != 0 ;
703
+ return _isatty (_fileno (stderr)) != 0 || is_stderr_cyg_pty () ;
645
704
#elif defined(ZIG_OS_POSIX)
646
705
return isatty (STDERR_FILENO) != 0 ;
647
706
#else
@@ -859,3 +918,76 @@ int os_self_exe_path(Buf *out_path) {
859
918
#endif
860
919
return ErrorFileNotFound;
861
920
}
921
+
922
+ #define VT_RED " \x1b [31;1m"
923
+ #define VT_GREEN " \x1b [32;1m"
924
+ #define VT_CYAN " \x1b [36;1m"
925
+ #define VT_WHITE " \x1b [37;1m"
926
+ #define VT_RESET " \x1b [0m"
927
+
928
+ static void set_color_posix (TermColor color) {
929
+ switch (color) {
930
+ case TermColorRed:
931
+ fprintf (stderr, VT_RED);
932
+ break ;
933
+ case TermColorGreen:
934
+ fprintf (stderr, VT_GREEN);
935
+ break ;
936
+ case TermColorCyan:
937
+ fprintf (stderr, VT_CYAN);
938
+ break ;
939
+ case TermColorWhite:
940
+ fprintf (stderr, VT_WHITE);
941
+ break ;
942
+ case TermColorReset:
943
+ fprintf (stderr, VT_RESET);
944
+ break ;
945
+ }
946
+ }
947
+
948
+ void os_stderr_set_color (TermColor color) {
949
+ #if defined(ZIG_OS_WINDOWS)
950
+ if (is_stderr_cyg_pty ()) {
951
+ set_color_posix (color);
952
+ return ;
953
+ }
954
+ HANDLE stderr_handle = GetStdHandle (STD_ERROR_HANDLE);
955
+ if (stderr_handle == INVALID_HANDLE_VALUE)
956
+ zig_panic (" unable to get stderr handle" );
957
+ fflush (stderr);
958
+ DWORD ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004 ;
959
+ if (color != TermColorReset) {
960
+ DWORD mode_flags = 0 ;
961
+ GetConsoleMode (stderr_handle, &mode_flags);
962
+ mode_flags |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
963
+ SetConsoleMode (stderr_handle, mode_flags);
964
+ }
965
+ DWORD chars_written;
966
+ switch (color) {
967
+ case TermColorRed:
968
+ WriteConsole (stderr_handle, VT_RED, strlen (VT_RED), &chars_written, NULL );
969
+ break ;
970
+ case TermColorGreen:
971
+ WriteConsole (stderr_handle, VT_GREEN, strlen (VT_GREEN), &chars_written, NULL );
972
+ break ;
973
+ case TermColorCyan:
974
+ WriteConsole (stderr_handle, VT_CYAN, strlen (VT_CYAN), &chars_written, NULL );
975
+ break ;
976
+ case TermColorWhite:
977
+ WriteConsole (stderr_handle, VT_WHITE, strlen (VT_WHITE), &chars_written, NULL );
978
+ break ;
979
+ case TermColorReset:
980
+ {
981
+ WriteConsole (stderr_handle, VT_RESET, strlen (VT_RESET), &chars_written, NULL );
982
+
983
+ DWORD mode_flags = 0 ;
984
+ GetConsoleMode (stderr_handle, &mode_flags);
985
+ mode_flags &= ~ENABLE_VIRTUAL_TERMINAL_PROCESSING;
986
+ SetConsoleMode (stderr_handle, mode_flags);
987
+ break ;
988
+ }
989
+ }
990
+ #else
991
+ set_color_posix (color);
992
+ #endif
993
+ }
0 commit comments