diff --git a/src/color.c b/src/color.c new file mode 100644 index 000000000000..9e681ec6b9a6 --- /dev/null +++ b/src/color.c @@ -0,0 +1,72 @@ + +/* Compiler implementation of the D programming language + * Copyright (c) 1999-2014 by Digital Mars + * All Rights Reserved + * written by Walter Bright + * http://www.digitalmars.com + * Distributed under the Boost Software License, Version 1.0. + * http://www.boost.org/LICENSE_1_0.txt + * https://github.com/D-Programming-Language/dmd/blob/master/src/mars.c + */ + +#include "color.h" + +#include + +#if _WIN32 +#define WIN32_LEAN_AND_MEAN +#include +#include +#endif + +#if __linux__ || __APPLE__ || __FreeBSD__ || __OpenBSD__ || __sun +#include +#include +#include +#endif + +#if _WIN32 +static CONSOLE_SCREEN_BUFFER_INFO sbi; +static const BOOL sbi_inited = GetConsoleScreenBufferInfo(GetStdHandle(STD_ERROR_HANDLE), &sbi); +#endif + +int isConsoleColorSupported() +{ +#if _WIN32 + return _isatty(_fileno(stderr)); +#elif __linux__ || __APPLE__ || __FreeBSD__ || __OpenBSD__ || __sun + const char *term = getenv("TERM"); + return isatty(STDERR_FILENO) && term && term[0] && 0 != strcmp(term, "dumb"); +#else + return 0; +#endif +} + +void setConsoleColorBright() +{ +#if _WIN32 + SetConsoleTextAttribute(GetStdHandle(STD_ERROR_HANDLE), sbi.wAttributes | FOREGROUND_INTENSITY); +#else + fprintf(stderr, "\033[1m"); +#endif +} + +void setConsoleColorError() +{ +#if _WIN32 + enum { FOREGROUND_WHITE = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE }; + SetConsoleTextAttribute(GetStdHandle(STD_ERROR_HANDLE), (sbi.wAttributes & ~FOREGROUND_WHITE) | FOREGROUND_RED | FOREGROUND_INTENSITY); +#else + fprintf(stderr, "\033[1;31m"); +#endif +} + +void resetConsoleColor() +{ +#if _WIN32 + SetConsoleTextAttribute(GetStdHandle(STD_ERROR_HANDLE), sbi.wAttributes); +#else + fprintf(stderr, "\033[m"); +#endif +} + diff --git a/src/color.h b/src/color.h new file mode 100644 index 000000000000..42b8a197003b --- /dev/null +++ b/src/color.h @@ -0,0 +1,16 @@ + +/* Compiler implementation of the D programming language + * Copyright (c) 1999-2014 by Digital Mars + * All Rights Reserved + * written by Walter Bright + * http://www.digitalmars.com + * Distributed under the Boost Software License, Version 1.0. + * http://www.boost.org/LICENSE_1_0.txt + * https://github.com/D-Programming-Language/dmd/blob/master/src/mars.c + */ + +extern int isConsoleColorSupported(); +extern void setConsoleColorBright(); +extern void setConsoleColorError(); +extern void resetConsoleColor(); + diff --git a/src/mars.c b/src/mars.c index 25afc78ddadc..6c628c7eb7b3 100644 --- a/src/mars.c +++ b/src/mars.c @@ -38,6 +38,7 @@ #include "declaration.h" #include "hdrgen.h" #include "doc.h" +#include "color.h" bool response_expand(size_t *pargc, const char ***pargv); void browse(const char *url); @@ -269,11 +270,17 @@ void verrorPrint(Loc loc, const char *header, const char *format, va_list ap, { char *p = loc.toChars(); + if (global.params.color) + setConsoleColorBright(); if (*p) fprintf(stderr, "%s: ", p); mem.free(p); + if (global.params.color) + setConsoleColorError(); fputs(header, stderr); + if (global.params.color) + resetConsoleColor(); if (p1) fprintf(stderr, "%s ", p1); if (p2) @@ -415,6 +422,7 @@ Usage:\n\ @cmdfile read arguments from cmdfile\n\ -allinst generate code for all template instantiations\n\ -c do not link\n\ + -color[=on|off] force colored console output on or off\n\ -cov do code coverage analysis\n\ -cov=nnn require at least nnn%% code coverage\n\ -D generate documentation\n\ @@ -567,6 +575,7 @@ int tryMain(size_t argc, const char *argv[]) // Set default values global.params.argv0 = argv[0]; + global.params.color = isConsoleColorSupported(); global.params.link = true; global.params.useAssert = true; global.params.useInvariants = true; @@ -679,6 +688,22 @@ int tryMain(size_t argc, const char *argv[]) global.params.useDeprecated = 2; else if (strcmp(p + 1, "c") == 0) global.params.link = false; + else if (memcmp(p + 1, "color", 5) == 0) + { + global.params.color = true; + // Parse: + // -color + // -color=on|off + if (p[6] == '=') + { + if (strcmp(p + 7, "off") == 0) + global.params.color = false; + else if (strcmp(p + 7, "on") != 0) + goto Lerror; + } + else if (p[6]) + goto Lerror; + } else if (memcmp(p + 1, "cov", 3) == 0) { global.params.cov = true; diff --git a/src/mars.h b/src/mars.h index 1f1b2cc0bf1b..9cdce95528b7 100644 --- a/src/mars.h +++ b/src/mars.h @@ -130,6 +130,7 @@ struct Param // 1: warnings as errors // 2: informational warnings (no errors) bool pic; // generate position-independent-code for shared libs + bool color; // use ANSI colors in console output bool cov; // generate code coverage data unsigned char covPercent; // 0..100 code coverage percentage required bool nofloat; // code should not pull in floating point support diff --git a/src/posix.mak b/src/posix.mak index f0b47fd34301..7c7446e9f5aa 100644 --- a/src/posix.mak +++ b/src/posix.mak @@ -136,7 +136,7 @@ DMD_OBJS = \ builtin.o ctfeexpr.o clone.o aliasthis.o \ arrayop.o json.o unittests.o \ imphint.o argtypes.o apply.o sapply.o sideeffect.o \ - intrange.o canthrow.o target.o nspace.o + intrange.o canthrow.o target.o nspace.o color.o ROOT_OBJS = \ rmem.o port.o man.o stringtable.o response.o \ diff --git a/src/win32.mak b/src/win32.mak index 38eeaaf41b38..49254b421b60 100644 --- a/src/win32.mak +++ b/src/win32.mak @@ -140,7 +140,8 @@ FRONTOBJ= enum.obj struct.obj dsymbol.obj import.obj id.obj \ interpret.obj ctfeexpr.obj traits.obj aliasthis.obj \ builtin.obj clone.obj arrayop.obj \ json.obj unittests.obj imphint.obj argtypes.obj apply.obj sapply.obj \ - sideeffect.obj intrange.obj canthrow.obj target.obj nspace.obj + sideeffect.obj intrange.obj canthrow.obj target.obj nspace.obj \ + color.obj # Glue layer GLUEOBJ=glue.obj msc.obj s2ir.obj todt.obj e2ir.obj tocsym.obj \