Commit 0a4283b38b
Changed files (3)
src/errmsg.cpp
@@ -10,12 +10,6 @@
#include <stdio.h>
-#define RED "\x1b[31;1m"
-#define GREEN "\x1b[32;1m"
-#define CYAN "\x1b[36;1m"
-#define WHITE "\x1b[37;1m"
-#define RESET "\x1b[0m"
-
enum ErrType {
ErrTypeError,
ErrTypeNote,
@@ -27,12 +21,26 @@ static void print_err_msg_type(ErrorMsg *err, ErrColor color, ErrType err_type)
size_t col = err->column_start + 1;
const char *text = buf_ptr(err->msg);
-
- if (color == ErrColorOn || (color == ErrColorAuto && os_stderr_tty())) {
+ bool is_tty = os_stderr_tty();
+ if (color == ErrColorOn || (color == ErrColorAuto && is_tty)) {
if (err_type == ErrTypeError) {
- fprintf(stderr, WHITE "%s:%" ZIG_PRI_usize ":%" ZIG_PRI_usize ": " RED "error:" WHITE " %s" RESET "\n", path, line, col, text);
+ os_stderr_set_color(TermColorWhite);
+ fprintf(stderr, "%s:%" ZIG_PRI_usize ":%" ZIG_PRI_usize ": ", path, line, col);
+ os_stderr_set_color(TermColorRed);
+ fprintf(stderr, "error:");
+ os_stderr_set_color(TermColorWhite);
+ fprintf(stderr, " %s", text);
+ os_stderr_set_color(TermColorReset);
+ fprintf(stderr, "\n");
} else if (err_type == ErrTypeNote) {
- fprintf(stderr, WHITE "%s:%" ZIG_PRI_usize ":%" ZIG_PRI_usize ": " CYAN "note:" WHITE " %s" RESET "\n", path, line, col, text);
+ os_stderr_set_color(TermColorWhite);
+ fprintf(stderr, "%s:%" ZIG_PRI_usize ":%" ZIG_PRI_usize ": ", path, line, col);
+ os_stderr_set_color(TermColorCyan);
+ fprintf(stderr, "note:");
+ os_stderr_set_color(TermColorWhite);
+ fprintf(stderr, " %s", text);
+ os_stderr_set_color(TermColorReset);
+ fprintf(stderr, "\n");
} else {
zig_unreachable();
}
@@ -41,7 +49,10 @@ static void print_err_msg_type(ErrorMsg *err, ErrColor color, ErrType err_type)
for (size_t i = 0; i < err->column_start; i += 1) {
fprintf(stderr, " ");
}
- fprintf(stderr, GREEN "^" RESET "\n");
+ os_stderr_set_color(TermColorGreen);
+ fprintf(stderr, "^");
+ os_stderr_set_color(TermColorReset);
+ fprintf(stderr, "\n");
} else {
if (err_type == ErrTypeError) {
fprintf(stderr, "%s:%" ZIG_PRI_usize ":%" ZIG_PRI_usize ": error: %s\n", path, line, col, text);
src/os.cpp
@@ -639,9 +639,68 @@ int os_get_cwd(Buf *out_cwd) {
#endif
}
+#if defined(ZIG_OS_WINDOWS)
+#define is_wprefix(s, prefix) \
+ (wcsncmp((s), (prefix), sizeof(prefix) / sizeof(WCHAR) - 1) == 0)
+static bool is_stderr_cyg_pty(void) {
+ HANDLE stderr_handle = GetStdHandle(STD_ERROR_HANDLE);
+ if (stderr_handle == INVALID_HANDLE_VALUE)
+ return false;
+
+ HANDLE h;
+ int size = sizeof(FILE_NAME_INFO) + sizeof(WCHAR) * MAX_PATH;
+ FILE_NAME_INFO *nameinfo;
+ WCHAR *p = NULL;
+
+ // Cygwin/msys's pty is a pipe.
+ if (GetFileType(stderr_handle) != FILE_TYPE_PIPE) {
+ return 0;
+ }
+ nameinfo = (FILE_NAME_INFO *)allocate<char>(size);
+ if (nameinfo == NULL) {
+ return 0;
+ }
+ // Check the name of the pipe:
+ // '\{cygwin,msys}-XXXXXXXXXXXXXXXX-ptyN-{from,to}-master'
+ if (GetFileInformationByHandleEx(stderr_handle, FileNameInfo, nameinfo, size)) {
+ nameinfo->FileName[nameinfo->FileNameLength / sizeof(WCHAR)] = L'\0';
+ p = nameinfo->FileName;
+ if (is_wprefix(p, L"\\cygwin-")) { /* Cygwin */
+ p += 8;
+ } else if (is_wprefix(p, L"\\msys-")) { /* MSYS and MSYS2 */
+ p += 6;
+ } else {
+ p = NULL;
+ }
+ if (p != NULL) {
+ while (*p && isxdigit(*p)) /* Skip 16-digit hexadecimal. */
+ ++p;
+ if (is_wprefix(p, L"-pty")) {
+ p += 4;
+ } else {
+ p = NULL;
+ }
+ }
+ if (p != NULL) {
+ while (*p && isdigit(*p)) /* Skip pty number. */
+ ++p;
+ if (is_wprefix(p, L"-from-master")) {
+ //p += 12;
+ } else if (is_wprefix(p, L"-to-master")) {
+ //p += 10;
+ } else {
+ p = NULL;
+ }
+ }
+ }
+ free(nameinfo);
+ return (p != NULL);
+}
+#endif
+
bool os_stderr_tty(void) {
#if defined(ZIG_OS_WINDOWS)
- return _isatty(_fileno(stderr)) != 0;
+ return _isatty(_fileno(stderr)) != 0 || is_stderr_cyg_pty();
#elif defined(ZIG_OS_POSIX)
return isatty(STDERR_FILENO) != 0;
#else
@@ -859,3 +918,76 @@ int os_self_exe_path(Buf *out_path) {
#endif
return ErrorFileNotFound;
}
+
+#define VT_RED "\x1b[31;1m"
+#define VT_GREEN "\x1b[32;1m"
+#define VT_CYAN "\x1b[36;1m"
+#define VT_WHITE "\x1b[37;1m"
+#define VT_RESET "\x1b[0m"
+
+static void set_color_posix(TermColor color) {
+ switch (color) {
+ case TermColorRed:
+ fprintf(stderr, VT_RED);
+ break;
+ case TermColorGreen:
+ fprintf(stderr, VT_GREEN);
+ break;
+ case TermColorCyan:
+ fprintf(stderr, VT_CYAN);
+ break;
+ case TermColorWhite:
+ fprintf(stderr, VT_WHITE);
+ break;
+ case TermColorReset:
+ fprintf(stderr, VT_RESET);
+ break;
+ }
+}
+
+void os_stderr_set_color(TermColor color) {
+#if defined(ZIG_OS_WINDOWS)
+ if (is_stderr_cyg_pty()) {
+ set_color_posix(color);
+ return;
+ }
+ HANDLE stderr_handle = GetStdHandle(STD_ERROR_HANDLE);
+ if (stderr_handle == INVALID_HANDLE_VALUE)
+ zig_panic("unable to get stderr handle");
+ fflush(stderr);
+ DWORD ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004;
+ if (color != TermColorReset) {
+ DWORD mode_flags = 0;
+ GetConsoleMode(stderr_handle, &mode_flags);
+ mode_flags |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
+ SetConsoleMode(stderr_handle, mode_flags);
+ }
+ DWORD chars_written;
+ switch (color) {
+ case TermColorRed:
+ WriteConsole(stderr_handle, VT_RED, strlen(VT_RED), &chars_written, NULL);
+ break;
+ case TermColorGreen:
+ WriteConsole(stderr_handle, VT_GREEN, strlen(VT_GREEN), &chars_written, NULL);
+ break;
+ case TermColorCyan:
+ WriteConsole(stderr_handle, VT_CYAN, strlen(VT_CYAN), &chars_written, NULL);
+ break;
+ case TermColorWhite:
+ WriteConsole(stderr_handle, VT_WHITE, strlen(VT_WHITE), &chars_written, NULL);
+ break;
+ case TermColorReset:
+ {
+ WriteConsole(stderr_handle, VT_RESET, strlen(VT_RESET), &chars_written, NULL);
+
+ DWORD mode_flags = 0;
+ GetConsoleMode(stderr_handle, &mode_flags);
+ mode_flags &= ~ENABLE_VIRTUAL_TERMINAL_PROCESSING;
+ SetConsoleMode(stderr_handle, mode_flags);
+ break;
+ }
+ }
+#else
+ set_color_posix(color);
+#endif
+}
src/os.hpp
@@ -15,6 +15,14 @@
#include <stdio.h>
#include <inttypes.h>
+enum TermColor {
+ TermColorRed,
+ TermColorGreen,
+ TermColorCyan,
+ TermColorWhite,
+ TermColorReset,
+};
+
enum TerminationId {
TerminationIdClean,
TerminationIdSignaled,
@@ -53,6 +61,7 @@ int os_fetch_file_path(Buf *full_path, Buf *out_contents);
int os_get_cwd(Buf *out_cwd);
bool os_stderr_tty(void);
+void os_stderr_set_color(TermColor color);
int os_buf_to_tmp_file(Buf *contents, Buf *suffix, Buf *out_tmp_path);
int os_delete_file(Buf *path);