Commit 29f24e3c50

Andrew Kelley <superjoe30@gmail.com>
2015-12-01 09:06:10
add --color cli arg to override tty detection
1 parent 257cf09
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);
     }
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);
 
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,
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<int> *line_offsets;
 };
 
-void print_err_msg(ErrorMsg *msg);
+void print_err_msg(ErrorMsg *msg, ErrColor color);
 
 #endif
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 {
src/parser.cpp
@@ -242,6 +242,7 @@ struct ParseContext {
     ZigList<Token> *tokens;
     ZigList<AstNode *> *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<Token> *tokens, ImportTableEntry *owner) {
+AstNode *ast_parse(Buf *buf, ZigList<Token> *tokens, ImportTableEntry *owner, ErrColor err_color) {
     ParseContext pc = {0};
+    pc.err_color = err_color;
     pc.owner = owner;
     pc.buf = buf;
     pc.tokens = tokens;
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<Token> *tokens, ImportTableEntry *owner);
+AstNode * ast_parse(Buf *buf, ZigList<Token> *tokens, ImportTableEntry *owner, ErrColor err_color);
 
 const char *node_type_str(NodeType node_type);
 
src/semantic_info.hpp
@@ -89,6 +89,7 @@ struct CodeGen {
     int version_minor;
     int version_patch;
     bool verbose;
+    ErrColor err_color;
     ImportTableEntry *root_import;
 };
 
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);
 }