ALib C++ Framework
by
Library Version: 2605 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
windowsconsolelogger.cpp
1using namespace alib::lox::textlogger;
2
3namespace alib::lox::loggers {
4
5using namespace detail;
6
7//##################################################################################################
8// Windows Console Colors
9//##################################################################################################
10 #define W32C_FOREGROUND_MASK 0xFFF0
11 #define W32C_BACKGROUND_MASK 0xFF0F
12
13 #define W32C_BLACK 0
14 #define W32C_RED FOREGROUND_RED
15 #define W32C_GREEN FOREGROUND_GREEN
16 #define W32C_BLUE FOREGROUND_BLUE
17 #define W32C_CYAN FOREGROUND_GREEN | FOREGROUND_BLUE
18 #define W32C_MAGENTA FOREGROUND_RED | FOREGROUND_BLUE
19 #define W32C_YELLOW FOREGROUND_RED | FOREGROUND_GREEN
20 #define W32C_WHITE FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY
21
22 #define W32C_GRAY_LIGHT FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE
23 #define W32C_GRAY_DARK FOREGROUND_INTENSITY
24
25 //! @cond NO_DOX
26 WORD win32Cols[]=
27 {
28 W32C_RED,
29 W32C_GREEN,
30 W32C_YELLOW,
31 W32C_BLUE,
32 W32C_MAGENTA,
33 W32C_CYAN,
34 };
35 //! @endcond
36
37//##################################################################################################
38// Constructor/Destructor
39//##################################################################################################
41: TextLogger( name, "WINDOWS_CONSOLE" ) {
42 // get actual console attributes
43 WORD actualAttributes;
44 {
45 HANDLE H= GetStdHandle(STD_OUTPUT_HANDLE);
46 CONSOLE_SCREEN_BUFFER_INFO info;
47 GetConsoleScreenBufferInfo( H, &info );
48 actualAttributes= info.wAttributes;
49 originalConsoleAttributes= actualAttributes;
50 }
51}
52
54{
57 return;
58
59
60 // evaluate environment variable "ALOX_CONSOLE_LIGHT_COLORS"
61 // If default, we assume dark background, hence use light color on foreground
63 (void) useLightColors.Define();
64 CFP= useLightColors.Get<ColorfulLoggerParameters>();
65
67 {
68 // default: dark background, hence use light color on foreground
69 CFP.LCU= ( originalConsoleAttributes & ~W32C_FOREGROUND_MASK ) < 7
72 }
73
74 // move verbosity information to the end to colorize the whole line
75 auto& fmt= varFormatMetaInfo.Get<FormatMetaInfo>();
77 fmt.VerbosityWarning.Reset(ESC::BLUE);
78 fmt.VerbosityInfo .Reset(A_CHAR(""));
79 fmt.VerbosityVerbose.Reset(ESC::GRAY);
80
81 // evaluate config variable CODEPAGE
83 if( codePage.IsDefined() )
84 CodePage= UINT(codePage.GetInt());
85}
86
87
88//##################################################################################################
89// logText
90//##################################################################################################
92 AString& msg,
93 ScopeInfo& , int , bool )
94{
95 HANDLE H= GetStdHandle(STD_OUTPUT_HANDLE);
96 DWORD ignore;
97
98 // get actual console attributes
99 WORD actualAttributes;
100 {
101 CONSOLE_SCREEN_BUFFER_INFO info;
102 GetConsoleScreenBufferInfo( H, &info );
103 actualAttributes= info.wAttributes;
104 }
105 WORD previousAttributes= actualAttributes;
106
107 // set codepage;
108 if ( CodePage != 0 )
109 SetConsoleOutputCP( CodePage );
110
111
112 // loop over message, print the parts between the escape sequences
113 integer column= 0;
114 Tokenizer msgParts( msg, '\x1B' );
115 Substring& actual= msgParts.Actual;
116 Substring& rest= msgParts.Rest;
117 for(;;)
118 {
119 if ( msgParts.Next(lang::Whitespaces::Keep ).IsNotEmpty() )
120 {
121 #if !ALIB_CHARACTERS_WIDE
122 WriteConsoleA( H, actual.Buffer(), (DWORD) actual.Length(), &ignore, NULL );
123 #else
124 WriteConsoleW( H, actual.Buffer(), (DWORD) actual.Length(), &ignore, NULL );
125 #endif
126 column+= actual.WStringLength();
127 }
128
129 if ( !msgParts.HasNext() )
130 break;
131
132 // found a delimiter: process ESC sequence
133 character c= rest.ConsumeChar<NC>();
134
135 // Colors
136 bool isForeGround= true;
137 if( c == 'C' || c == 'c' )
138 {
139 isForeGround= c== 'c';
140
141 c= rest.ConsumeChar();
142 int colNo= c - '0';
143 ALIB_ASSERT_WARNING(colNo >=0 && colNo <=9, "ALOX", "ConsoleLogger: Unknown ESC-c code")
144
145 WORD attr= 0;
148 == isForeGround )
149 ? FOREGROUND_INTENSITY
150 : 0;
151
152 // 0..5 (red, green, yellow, blue, magenta, cyan)
153 if ( colNo >= 0 && colNo < 6) attr= (win32Cols[colNo] | light);
154
155 else if ( colNo == 6 ) attr= W32C_BLACK;
156 else if ( colNo == 7 ) attr= W32C_WHITE;
157 else if ( colNo == 8 ) attr= light ? W32C_GRAY_LIGHT : W32C_GRAY_DARK;
158 else if ( colNo == 9 ) attr= isForeGround ? originalConsoleAttributes & ~W32C_FOREGROUND_MASK
159 : ( originalConsoleAttributes & ~W32C_BACKGROUND_MASK ) >> 4;
160 else
161 {
162 ALIB_WARNING( "ALOX", "Unknown ESC- code \"C{}{}...\"", c, rest.Substring(0,10) );
163 }
164
165 actualAttributes= isForeGround ? ( actualAttributes & W32C_FOREGROUND_MASK ) | attr
166 : ( actualAttributes & W32C_BACKGROUND_MASK ) | (attr << 4);
167 }
168
169 // Styles
170 else if ( c == 's' )
171 {
172 // bold/italics style not supported in Windows console
173
174 // reset all
175 if ( rest.ConsumeChar() == 'a' )
176 actualAttributes= originalConsoleAttributes;
177 }
178
179 // auto tab / end of meta
180 else if ( c == 't' || c == 'A' )
181 {
182 c= rest.ConsumeChar();
183 int extraSpace= c >= '0' && c <= '9' ? (int) ( c - '0' )
184 : (int) ( c - 'A' ) + 10;
185
186 // tab stop (write spaces using a growing buffer)
187 integer tabStop= varFormatAutoSizes.Get<FormatAutoSizes>().Main.Next(
188 AutoSizes::Types::Tabstop, column, extraSpace );
189 integer qtySpaces= tabStop - column;
190 if( qtySpaces > 0 )
191 {
192 column+= qtySpaces;
193 characters::AlignedCharArray<nchar, 8*sizeof(void*)> spaces( ' ' );
194 while (qtySpaces >= spaces.Length() ) {
195 WriteConsoleA( H, spaces.Buffer(), (DWORD) spaces.Length(), &ignore, NULL );
196 qtySpaces-= spaces.Length();
197 }
198 if (qtySpaces > 0)
199 WriteConsoleA( H, spaces.Buffer(), (DWORD) qtySpaces, &ignore, NULL );
200 }
201 }
202
203
204 // Link (we just colorize links here)
205 else if ( c == 'l' )
206 {
207 if ( rest.ConsumeChar() == 'S' )
208 actualAttributes= ( actualAttributes & W32C_FOREGROUND_MASK )
209 | W32C_BLUE
211 ? FOREGROUND_INTENSITY
212 : 0 );
213 else
214 actualAttributes= ( actualAttributes & W32C_FOREGROUND_MASK ) | ( originalConsoleAttributes & ~W32C_FOREGROUND_MASK );
215 }
216
217
218 else
219 {
220 ALIB_WARNING( "ALOX", "WindowsConsoleLogger: Unknown ESC code" );
221 }
222
223 // set the attributes
224 ALIB_ASSERT_RESULT_NOT_EQUALS( SetConsoleTextAttribute( H, actualAttributes ), 0 );
225
226
227 } // write loop
228
229 ALIB_ASSERT_RESULT_NOT_EQUALS( SetConsoleTextAttribute( H, previousAttributes ), 0 );
230
231 std::cout << std::endl;
232}
233
234} // namespace [alib::lox::loggers]
#define A_CHAR(STR)
#define ALIB_WARNING(domain,...)
#define ALIB_ASSERT_WARNING(cond, domain,...)
#define ALIB_ASSERT_RESULT_NOT_EQUALS( func, value)
static constexpr character GRAY[4]
Select gray color for foreground.
static constexpr character RED[4]
Select red color for foreground.
static constexpr character BLUE[4]
Select blue color for foreground.
textlogger::ColorfulLoggerParameters CFP
WindowsConsoleLogger(const NString &name=nullptr)
virtual void logText(detail::Domain &domain, Verbosity verbosity, AString &msg, detail::ScopeInfo &scope, int lineNumber, bool isRecursion)
WORD originalConsoleAttributes
The attributes that were set on the windows console at the time this object was created.
virtual void AcknowledgeLox(detail::LoxImpl *lox, lang::ContainerOp op) override
virtual void AcknowledgeLox(detail::LoxImpl *lox, lang::ContainerOp op) override
TextLogger(const NString &pName, const NString &typeName)
constexpr integer Length() const
Definition string.hpp:300
constexpr bool IsNotEmpty() const
Definition string.hpp:353
constexpr const TChar * Buffer() const
Definition string.hpp:295
integer WStringLength() const
TString< TChar > Substring(integer regionStart, integer regionLength=MAX_LEN) const
Definition string.hpp:368
@ Tabstop
denotes a tab stop entry.
Definition autosizes.hpp:55
TSubstring< TChar > Actual
Definition tokenizer.hpp:64
TSubstring< TChar > & Next(lang::Whitespaces trimming=lang::Whitespaces::Trim, TChar newDelim='\0')
Definition tokenizer.cpp:4
bool Define(Priority requestedPriority=Priority::Standard)
Definition variable.cpp:237
ContainerOp
Denotes standard container operations.
@ Insert
Denotes insertions.
@ Keep
Keep whitespaces in string.
This namespaces defines class #"%TextLogger" and its helpers.
Definition loxpimpl.hpp:13
@ CONSOLE_LIGHT_COLORS
Denotes configuration variable #"alxcvALOX_CONSOLE_LIGHT_COLORS" used by colorful specializations of ...
Definition aloxcamp.hpp:66
@ CODEPAGE
Denotes configuration variable #"alxcvALOX_CODEPAGE" used by the class #"WindowsConsoleLogger".
Definition aloxcamp.hpp:70
variables::Variable CampVariable(camp::Camp &camp)
Definition camp.hpp:283
strings::TString< nchar > NString
Type alias in namespace #"%alib".
Definition string.hpp:2174
variables::Variable Variable
Type alias in namespace #"%alib".
strings::util::TTokenizer< character > Tokenizer
Type alias in namespace #"%alib".
lox::ALoxCamp ALOX
The singleton instance of ALib Camp class #"ALoxCamp".
Definition aloxcamp.cpp:5
lang::integer integer
Type alias in namespace #"%alib".
Definition integers.hpp:149
strings::TSubstring< character > Substring
Type alias in namespace #"%alib".
characters::nchar nchar
Type alias in namespace #"%alib".
strings::TAString< character, lang::HeapAllocator > AString
Type alias in namespace #"%alib".
characters::character character
Type alias in namespace #"%alib".
Parameters specific to colorful loggers. As of today, this simply has one attribute.