diff --git a/src/codegen.cpp b/src/codegen.cpp index 3717fb63d4..2f9bf47383 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -42,6 +42,10 @@ void codegen_set_verbose(CodeGen *g, bool verbose) { g->verbose = verbose; } +void codegen_set_errmsg_color(CodeGen *g, ErrColor err_color) { + g->err_color = err_color; +} + void codegen_set_strip(CodeGen *g, bool strip) { g->strip_debug_symbols = strip; } @@ -693,7 +697,7 @@ static ImportTableEntry *codegen_add_code(CodeGen *g, Buf *source_path, Buf *sou err->source = source_code; err->line_offsets = tokenization.line_offsets; - print_err_msg(err); + print_err_msg(err, g->err_color); exit(1); } @@ -709,7 +713,7 @@ static ImportTableEntry *codegen_add_code(CodeGen *g, Buf *source_path, Buf *sou import_entry->line_offsets = tokenization.line_offsets; import_entry->path = source_path; import_entry->fn_table.init(32); - import_entry->root = ast_parse(source_code, tokenization.tokens, import_entry); + import_entry->root = ast_parse(source_code, tokenization.tokens, import_entry, g->err_color); assert(import_entry->root); if (g->verbose) { ast_print(import_entry->root, 0); @@ -756,7 +760,7 @@ void codegen_add_root_code(CodeGen *g, Buf *source_path, Buf *source_code) { } else { for (int i = 0; i < g->errors.length; i += 1) { ErrorMsg *err = g->errors.at(i); - print_err_msg(err); + print_err_msg(err, g->err_color); } exit(1); } diff --git a/src/codegen.hpp b/src/codegen.hpp index 5795a5a946..8c83e2144a 100644 --- a/src/codegen.hpp +++ b/src/codegen.hpp @@ -9,6 +9,7 @@ #define ZIG_CODEGEN_HPP #include "parser.hpp" +#include "errmsg.hpp" struct CodeGen; @@ -19,7 +20,6 @@ enum OutType { OutTypeObj, }; - CodeGen *codegen_create(Buf *root_source_dir); enum CodeGenBuildType { @@ -30,6 +30,7 @@ void codegen_set_build_type(CodeGen *codegen, CodeGenBuildType build_type); void codegen_set_is_static(CodeGen *codegen, bool is_static); void codegen_set_strip(CodeGen *codegen, bool strip); void codegen_set_verbose(CodeGen *codegen, bool verbose); +void codegen_set_errmsg_color(CodeGen *codegen, ErrColor err_color); void codegen_set_out_type(CodeGen *codegen, OutType out_type); void codegen_set_out_name(CodeGen *codegen, Buf *out_name); diff --git a/src/errmsg.cpp b/src/errmsg.cpp index 36d203a48f..00557e0214 100644 --- a/src/errmsg.cpp +++ b/src/errmsg.cpp @@ -8,8 +8,8 @@ #define GREEN "\x1b[32;1m" #define RESET "\x1b[0m" -void print_err_msg(ErrorMsg *err) { - if (os_stderr_tty()) { +void print_err_msg(ErrorMsg *err, ErrColor color) { + if (color == ErrColorOn || (color == ErrColorAuto && os_stderr_tty())) { fprintf(stderr, WHITE "%s:%d:%d: " RED "error:" WHITE " %s" RESET "\n", buf_ptr(err->path), err->line_start + 1, err->column_start + 1, diff --git a/src/errmsg.hpp b/src/errmsg.hpp index fa851d44bc..1f31020902 100644 --- a/src/errmsg.hpp +++ b/src/errmsg.hpp @@ -11,6 +11,12 @@ #include "buffer.hpp" #include "list.hpp" +enum ErrColor { + ErrColorAuto, + ErrColorOff, + ErrColorOn, +}; + struct ErrorMsg { int line_start; int column_start; @@ -22,6 +28,6 @@ struct ErrorMsg { ZigList *line_offsets; }; -void print_err_msg(ErrorMsg *msg); +void print_err_msg(ErrorMsg *msg, ErrColor color); #endif diff --git a/src/main.cpp b/src/main.cpp index d96cb92e40..f0060c2c1d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -25,6 +25,7 @@ static int usage(const char *arg0) { " --name [name] override output name\n" " --output [file] override destination path\n" " --verbose turn on compiler debug output\n" + " --color [auto|off|on] enable or disable colored error messages\n" , arg0); return EXIT_FAILURE; } @@ -43,6 +44,7 @@ struct Build { OutType out_type; const char *out_name; bool verbose; + ErrColor color; }; static int build(const char *arg0, Build *b) { @@ -73,6 +75,7 @@ static int build(const char *arg0, Build *b) { if (b->out_name) codegen_set_out_name(g, buf_create_from_str(b->out_name)); codegen_set_verbose(g, b->verbose); + codegen_set_errmsg_color(g, b->color); codegen_add_root_code(g, &root_source_name, &root_source_code); codegen_link(g, b->out_file); @@ -106,7 +109,9 @@ int main(int argc, char **argv) { return usage(arg0); } else { i += 1; - if (strcmp(arg, "--output") == 0) { + if (i >= argc) { + return usage(arg0); + } else if (strcmp(arg, "--output") == 0) { b.out_file = argv[i]; } else if (strcmp(arg, "--export") == 0) { if (strcmp(argv[i], "exe") == 0) { @@ -118,6 +123,16 @@ int main(int argc, char **argv) { } else { return usage(arg0); } + } else if (strcmp(arg, "--color") == 0) { + if (strcmp(argv[i], "auto") == 0) { + b.color = ErrColorAuto; + } else if (strcmp(argv[i], "on") == 0) { + b.color = ErrColorOn; + } else if (strcmp(argv[i], "off") == 0) { + b.color = ErrColorOff; + } else { + return usage(arg0); + } } else if (strcmp(arg, "--name") == 0) { b.out_name = argv[i]; } else { diff --git a/src/parser.cpp b/src/parser.cpp index a6809a2777..665bbee3cb 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -242,6 +242,7 @@ struct ParseContext { ZigList *tokens; ZigList *directive_list; ImportTableEntry *owner; + ErrColor err_color; }; __attribute__ ((format (printf, 3, 4))) @@ -262,7 +263,7 @@ static void ast_error(ParseContext *pc, Token *token, const char *format, ...) { err->source = pc->owner->source_code; err->line_offsets = pc->owner->line_offsets; - print_err_msg(err); + print_err_msg(err, pc->err_color); exit(EXIT_FAILURE); } @@ -1334,8 +1335,9 @@ static AstNode *ast_parse_root(ParseContext *pc, int *token_index) { return node; } -AstNode *ast_parse(Buf *buf, ZigList *tokens, ImportTableEntry *owner) { +AstNode *ast_parse(Buf *buf, ZigList *tokens, ImportTableEntry *owner, ErrColor err_color) { ParseContext pc = {0}; + pc.err_color = err_color; pc.owner = owner; pc.buf = buf; pc.tokens = tokens; diff --git a/src/parser.hpp b/src/parser.hpp index 3346763acb..4f433fe8eb 100644 --- a/src/parser.hpp +++ b/src/parser.hpp @@ -11,6 +11,7 @@ #include "list.hpp" #include "buffer.hpp" #include "tokenizer.hpp" +#include "errmsg.hpp" struct AstNode; struct CodeGenNode; @@ -199,7 +200,7 @@ void ast_token_error(Token *token, const char *format, ...); // This function is provided by generated code, generated by parsergen.cpp -AstNode * ast_parse(Buf *buf, ZigList *tokens, ImportTableEntry *owner); +AstNode * ast_parse(Buf *buf, ZigList *tokens, ImportTableEntry *owner, ErrColor err_color); const char *node_type_str(NodeType node_type); diff --git a/src/semantic_info.hpp b/src/semantic_info.hpp index 5a8ec35cb6..075b1c8bdc 100644 --- a/src/semantic_info.hpp +++ b/src/semantic_info.hpp @@ -89,6 +89,7 @@ struct CodeGen { int version_minor; int version_patch; bool verbose; + ErrColor err_color; ImportTableEntry *root_import; }; diff --git a/test/run_tests.cpp b/test/run_tests.cpp index 34a1668675..69a99590ce 100644 --- a/test/run_tests.cpp +++ b/test/run_tests.cpp @@ -48,6 +48,8 @@ static void add_simple_case(const char *case_name, const char *source, const cha test_case->compiler_args.append("--release"); test_case->compiler_args.append("--strip"); test_case->compiler_args.append("--verbose"); + test_case->compiler_args.append("--color"); + test_case->compiler_args.append("on"); test_cases.append(test_case); }