0031036: Foundation Classes, Message_PrinterOStream - add option printing colored...
[occt.git] / src / Message / Message_PrinterOStream.cxx
1 // Created on: 2001-01-06
2 // Created by: OCC Team
3 // Copyright (c) 2001-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #ifdef _WIN32
17   #include <windows.h>
18 #endif
19
20 #include <Message_PrinterOStream.hxx>
21
22 #include <OSD_OpenFile.hxx>
23 #include <TCollection_AsciiString.hxx>
24 #include <TCollection_ExtendedString.hxx>
25
26 IMPLEMENT_STANDARD_RTTIEXT(Message_PrinterOStream,Message_Printer)
27
28 #if !defined(_MSC_VER)
29   #include <strings.h>
30 #endif
31
32 //=======================================================================
33 //function : Constructor
34 //purpose  : Empty constructor, defaulting to cerr
35 //=======================================================================
36 Message_PrinterOStream::Message_PrinterOStream (const Message_Gravity theTraceLevel)
37 : myStream  (&std::cout),
38   myIsFile  (Standard_False),
39   myUseUtf8 (Standard_False),
40   myToColorize (Standard_False)
41 {
42   myTraceLevel = theTraceLevel;
43 }
44
45 //=======================================================================
46 //function : Constructor
47 //purpose  : Opening a file as an std::ostream
48 //           for specific file names standard streams are created
49 //=======================================================================
50 Message_PrinterOStream::Message_PrinterOStream (const Standard_CString theFileName,
51                                                 const Standard_Boolean theToAppend,
52                                                 const Message_Gravity  theTraceLevel)
53 : myStream (&std::cout),
54   myIsFile (Standard_False),
55   myUseUtf8 (Standard_False),
56   myToColorize (Standard_False)
57 {
58   myTraceLevel = theTraceLevel;
59   if (strcasecmp(theFileName, "cerr") == 0)
60   {
61     myStream = &std::cerr;
62     return;
63   }
64   else if (strcasecmp(theFileName, "cout") == 0)
65   {
66     myStream = &std::cout;
67     return;
68   }
69
70   TCollection_AsciiString aFileName (theFileName);
71 #ifdef _WIN32
72   aFileName.ChangeAll ('/', '\\');
73 #endif
74
75   std::ofstream* aFile = new std::ofstream();
76   OSD_OpenStream (*aFile, aFileName.ToCString(), (theToAppend ? (std::ios_base::app | std::ios_base::out) : std::ios_base::out));
77   if (aFile->is_open())
78   {
79     myStream = (Standard_OStream* )aFile;
80     myIsFile = Standard_True;
81   }
82   else
83   {
84     delete aFile;
85     myStream = &std::cout;
86 #ifdef OCCT_DEBUG
87     std::cerr << "Error opening " << theFileName << std::endl << std::flush;
88 #endif
89   }
90 }
91
92 //=======================================================================
93 //function : Close
94 //purpose  : 
95 //=======================================================================
96
97 void Message_PrinterOStream::Close ()
98 {
99   if ( ! myStream ) return;
100   Standard_OStream* ostr = (Standard_OStream*)myStream;
101   myStream = 0;
102
103   ostr->flush();
104   if ( myIsFile )
105   {
106     std::ofstream* ofile = (std::ofstream* )ostr;
107     ofile->close();
108     delete ofile;
109     myIsFile = Standard_False;
110   }
111 }
112
113 //=======================================================================
114 //function : Send
115 //purpose  : 
116 //=======================================================================
117
118 void Message_PrinterOStream::Send (const Standard_CString theString,
119                                    const Message_Gravity theGravity,
120                                    const Standard_Boolean putEndl) const
121 {
122   if (theGravity < myTraceLevel
123    || myStream == NULL)
124   {
125     return;
126   }
127
128   Message_ConsoleColor aColor = Message_ConsoleColor_Default;
129   bool toIntense = false;
130   if (myToColorize && !myIsFile)
131   {
132     switch(theGravity)
133     {
134       case Message_Trace:
135         aColor = Message_ConsoleColor_Yellow;
136         break;
137       case Message_Info:
138         aColor = Message_ConsoleColor_Green;
139         toIntense = true;
140         break;
141       case Message_Warning:
142         aColor = Message_ConsoleColor_Yellow;
143         toIntense = true;
144         break;
145       case Message_Alarm:
146         aColor = Message_ConsoleColor_Red;
147         toIntense = true;
148         break;
149       case Message_Fail:
150         aColor = Message_ConsoleColor_Red;
151         toIntense = true;
152         break;
153     }
154   }
155
156   Standard_OStream* aStream = (Standard_OStream*)myStream;
157   if (toIntense || aColor != Message_ConsoleColor_Default)
158   {
159     SetConsoleTextColor (aStream, aColor, toIntense);
160     *aStream << theString;
161     SetConsoleTextColor (aStream, Message_ConsoleColor_Default, false);
162   }
163   else
164   {
165     *aStream << theString;
166   }
167   if (putEndl)
168   {
169     (*aStream) << std::endl;
170   }
171 }
172
173 //=======================================================================
174 //function : Send
175 //purpose  : 
176 //=======================================================================
177
178 void Message_PrinterOStream::Send (const TCollection_AsciiString &theString,
179                                    const Message_Gravity theGravity,
180                                    const Standard_Boolean putEndl) const
181 {
182   Send ( theString.ToCString(), theGravity, putEndl );
183 }
184
185 //=======================================================================
186 //function : Send
187 //purpose  : 
188 //=======================================================================
189
190 void Message_PrinterOStream::Send (const TCollection_ExtendedString &theString,
191                                    const Message_Gravity theGravity,
192                                    const Standard_Boolean putEndl) const
193 {
194   TCollection_AsciiString aStr (theString, myUseUtf8 ? Standard_Character(0) : '?');
195   Send (aStr.ToCString(), theGravity, putEndl);
196 }
197
198 //=======================================================================
199 //function : SetConsoleTextColor
200 //purpose  :
201 //=======================================================================
202 void Message_PrinterOStream::SetConsoleTextColor (Standard_OStream* theOStream,
203                                                   Message_ConsoleColor theTextColor,
204                                                   bool theIsIntenseText)
205 {
206 #ifdef _WIN32
207   // there is no difference between STD_OUTPUT_HANDLE/STD_ERROR_HANDLE for std::cout/std::cerr
208   (void )theOStream;
209   if (HANDLE anStdOut = GetStdHandle (STD_OUTPUT_HANDLE))
210   {
211     WORD aFlags = 0;
212     if (theIsIntenseText)
213     {
214       aFlags |= FOREGROUND_INTENSITY;
215     }
216     switch (theTextColor)
217     {
218       case Message_ConsoleColor_Default:
219       case Message_ConsoleColor_White:
220         aFlags |= FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
221         break;
222       case Message_ConsoleColor_Black:
223         break;
224       case Message_ConsoleColor_Red:
225         aFlags |= FOREGROUND_RED;
226         break;
227       case Message_ConsoleColor_Green:
228         aFlags |= FOREGROUND_GREEN;
229         break;
230       case Message_ConsoleColor_Blue:
231         aFlags |= FOREGROUND_BLUE;
232         break;
233       case Message_ConsoleColor_Yellow:
234         aFlags |= FOREGROUND_RED | FOREGROUND_GREEN;
235         break;
236       case Message_ConsoleColor_Cyan:
237         aFlags |= FOREGROUND_GREEN | FOREGROUND_BLUE;
238         break;
239       case Message_ConsoleColor_Magenta:
240         aFlags |= FOREGROUND_RED | FOREGROUND_BLUE;
241         break;
242     }
243     SetConsoleTextAttribute (anStdOut, aFlags);
244   }
245 #else
246   if (theOStream == NULL)
247   {
248     return;
249   }
250
251   const char* aCode = "\e[0m";
252   switch (theTextColor)
253   {
254     case Message_ConsoleColor_Default:
255       aCode = theIsIntenseText ? "\e[0;1m" : "\e[0m";
256       break;
257     case Message_ConsoleColor_Black:
258       aCode = theIsIntenseText ? "\e[30;1m" : "\e[30m";
259       break;
260     case Message_ConsoleColor_Red:
261       aCode = theIsIntenseText ? "\e[31;1m" : "\e[31m";
262       break;
263     case Message_ConsoleColor_Green:
264       aCode = theIsIntenseText ? "\e[32;1m" : "\e[32m";
265       break;
266     case Message_ConsoleColor_Yellow:
267       aCode = theIsIntenseText ? "\e[33;1m" : "\e[33m";
268       break;
269     case Message_ConsoleColor_Blue:
270       aCode = theIsIntenseText ? "\e[34;1m" : "\e[34m";
271       break;
272     case Message_ConsoleColor_Magenta:
273       aCode = theIsIntenseText ? "\e[35;1m" : "\e[35m";
274       break;
275     case Message_ConsoleColor_Cyan:
276       aCode = theIsIntenseText ? "\e[36;1m" : "\e[36m";
277       break;
278     case Message_ConsoleColor_White:
279       aCode = theIsIntenseText ? "\e[37;1m" : "\e[37m";
280       break;
281   }
282   *theOStream << aCode;
283 #endif
284 }