1 /*
2  * This file is part of gir-to-d.
3  *
4  * gir-to-d is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License
6  * as published by the Free Software Foundation, either version 3
7  * of the License, or (at your option) any later version.
8  *
9  * gir-to-d is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public License
15  * along with gir-to-d.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 module gtd.Log;
19 
20 import core.stdc.stdlib : exit;
21 
22 import std.stdio;
23 
24 void warning(Args...)(Args args)
25 {
26 	static if ( is(typeof(args[$-1].fileName)) && is(typeof(args[$-1].lineNumber)) )
27 	{
28 		stderr.writef("%s %s(%s): ", Color.blue("Warning"), args[$-1].fileName, args[$-1].lineNumber);
29 		stderr.writeln(args[0..$-1]);
30 	}
31 	else
32 	{
33 		stderr.write(Color.blue("Warning"), ": ");
34 		stderr.writeln(args);
35 	}
36 }
37 
38 void warningf(Args...)(Args args)
39 {
40 	static if ( is(typeof(args[$-1].fileName)) && is(typeof(args[$-1].lineNumber)) )
41 	{
42 		stderr.writef("%s %s(%s): ", Color.blue("Warning"), args[$-1].fileName, args[$-1].lineNumber);
43 		stderr.writefln(args[0..$-1]);
44 	}
45 	else
46 	{
47 	stderr.write(Color.blue("Warning"), ": ");
48 	stderr.writefln(args);
49 	}
50 }
51 
52 void error(Args...)(Args args)
53 {
54 	static if ( is(typeof(args[$-1].fileName)) && is(typeof(args[$-1].lineNumber)) )
55 	{
56 		stderr.writef("%s %s(%s): ", Color.red("Error"), args[$-1].fileName, args[$-1].lineNumber);
57 		stderr.writeln(args[0..$-1]);
58 	}
59 	else
60 	{
61 		stderr.write(Color.red("Error"), ": ");
62 		stderr.writeln(args);
63 	}
64 
65 	exit(1);
66 }
67 
68 void errorf(Args...)(Args args)
69 {
70 	static if ( is(typeof(args[$-1].fileName)) && is(typeof(args[$-1].lineNumber)) )
71 	{
72 		stderr.writef("%s %s(%s): ", Color.red("Error"), args[$-1].fileName, args[$-1].lineNumber);
73 		stderr.writefln(args[0..$-1]);
74 	}
75 	else
76 	{
77 		stderr.write(Color.red("Error"), ": ");
78 		stderr.writefln(args);
79 	}
80 
81 	exit(1);
82 }
83 
84 struct Color
85 {
86 	string esc;
87 	string text;
88 	string reset;
89 
90 	private static bool _useColor;
91 	private static bool supportsColor;
92 
93 	static this()
94 	{
95 		version(Windows)
96 		{
97 			import core.sys.windows.winbase: GetStdHandle, STD_ERROR_HANDLE;
98 			import core.sys.windows.wincon: GetConsoleMode, SetConsoleMode;
99 			import core.sys.windows.windef: DWORD, HANDLE;
100 
101 			if ( !isatty(stderr.fileno()) )
102 				return;
103 
104 			DWORD dwMode;
105 			HANDLE err = GetStdHandle(STD_ERROR_HANDLE);
106 
107 			if ( !GetConsoleMode(err, &dwMode) )
108 				return;
109 
110 			//ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004;
111 			dwMode |= 0x0004;
112 
113 			//Try to set VT100 support on Windows 10.
114 			if ( !SetConsoleMode(err, dwMode) )
115 				return;
116 
117 			supportsColor = true;
118 			_useColor = true;
119 		}
120 		else version(Posix)
121 		{
122 			if ( !isatty(stderr.fileno()) )
123 				return;
124 
125 			supportsColor = true;
126 			_useColor = true;
127 		}
128 	}
129 
130 	void toString(scope void delegate(const(char)[]) sink) const
131 	{
132 		if ( _useColor )
133 		{
134 			sink(esc);
135 			sink(text);
136 			sink(reset);
137 		}
138 		else
139 		{
140 			sink(text);
141 		}
142 	}
143 
144 	string toString() const
145 	{
146 		if ( _useColor )
147 			return esc ~ text ~ reset;
148 		else
149 			return text;
150 	}
151 
152 	void useColor(bool val)
153 	{
154 		if ( supportsColor )
155 			_useColor = val;
156 	}
157 
158 	static Color red(string text)
159 	{
160 		return Color("\033[1;31m", text, "\033[m");
161 	}
162 
163 	static Color blue(string text)
164 	{
165 		return Color("\033[1;34m", text, "\033[m");
166 	}
167 }
168 
169 extern(C) private int isatty(int);