Legends-of-Azeroth-Pandaria-5.4.8

Форк
0
212 строк · 7.8 Кб
1
/*
2
* This file is part of the Pandaria 5.4.8 Project. See THANKS file for Copyright information
3
*
4
* This program is free software; you can redistribute it and/or modify it
5
* under the terms of the GNU General Public License as published by the
6
* Free Software Foundation; either version 2 of the License, or (at your
7
* option) any later version.
8
*
9
* This program is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12
* more details.
13
*
14
* You should have received a copy of the GNU General Public License along
15
* with this program. If not, see <http://www.gnu.org/licenses/>.
16
*/
17

18
#include "AppenderConsole.h"
19
#include "LogMessage.h"
20
#include "SmartEnum.h"
21
#include "StringFormat.h"
22
#include "StringConvert.h"
23
#include "Util.h"
24
#include <sstream>
25

26
#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS
27
  #include <Windows.h>
28
#endif
29

30
AppenderConsole::AppenderConsole(uint8 id, std::string const& name, LogLevel level, AppenderFlags flags, std::vector<std::string_view> const& args)
31
    : Appender(id, name, level, flags), _colored(false)
32
{
33
    for (uint8 i = 0; i < NUM_ENABLED_LOG_LEVELS; ++i)
34
        _colors[i] = ColorTypes(NUM_COLOR_TYPES);
35

36
    if (3 < args.size())
37
        InitColors(name, args[3]);
38
}
39

40
void AppenderConsole::InitColors(std::string const& name, std::string_view str)
41
{
42
    if (str.empty())
43
    {
44
        _colored = false;
45
        return;
46
    }
47

48
    std::vector<std::string_view> colorStrs = Trinity::Tokenize(str, ' ', false);
49
    if (colorStrs.size() != NUM_ENABLED_LOG_LEVELS)
50
    {
51
        throw InvalidAppenderArgsException(Trinity::StringFormat("Log::CreateAppenderFromConfig: Invalid color data '%s' for console appender %s (expected %u entries, got %zu)",
52
            std::string(str).c_str(), name.c_str(), NUM_ENABLED_LOG_LEVELS, colorStrs.size()));
53
    }
54

55
    for (uint8 i = 0; i < NUM_ENABLED_LOG_LEVELS; ++i)
56
    {
57
        if (Optional<uint8> color = Trinity::StringTo<uint8>(colorStrs[i]); color && EnumUtils::IsValid<ColorTypes>(*color))
58
            _colors[i] = static_cast<ColorTypes>(*color);
59
        else
60
        {
61
            throw InvalidAppenderArgsException(Trinity::StringFormat("Log::CreateAppenderFromConfig: Invalid color '%s' for log level %s on console appender %s",
62
                std::string(colorStrs[i]).c_str(), EnumUtils::ToTitle(static_cast<LogLevel>(i)), name.c_str()));
63
        }
64
    }
65

66
    _colored = true;
67
}
68

69
void AppenderConsole::SetColor(bool stdout_stream, ColorTypes color)
70
{
71
#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS
72
    static WORD WinColorFG[NUM_COLOR_TYPES] =
73
    {
74
        0,                                                  // BLACK
75
        FOREGROUND_RED,                                     // RED
76
        FOREGROUND_GREEN,                                   // GREEN
77
        FOREGROUND_RED | FOREGROUND_GREEN,                  // BROWN
78
        FOREGROUND_BLUE,                                    // BLUE
79
        FOREGROUND_RED |                    FOREGROUND_BLUE, // MAGENTA
80
        FOREGROUND_GREEN | FOREGROUND_BLUE,                 // CYAN
81
        FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE, // WHITE
82
                                                            // YELLOW
83
        FOREGROUND_RED | FOREGROUND_GREEN |                   FOREGROUND_INTENSITY,
84
                                                            // RED_BOLD
85
        FOREGROUND_RED |                                      FOREGROUND_INTENSITY,
86
                                                            // GREEN_BOLD
87
        FOREGROUND_GREEN |                   FOREGROUND_INTENSITY,
88
        FOREGROUND_BLUE | FOREGROUND_INTENSITY,             // BLUE_BOLD
89
                                                            // MAGENTA_BOLD
90
        FOREGROUND_RED |                    FOREGROUND_BLUE | FOREGROUND_INTENSITY,
91
                                                            // CYAN_BOLD
92
        FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY,
93
                                                            // WHITE_BOLD
94
        FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY
95
    };
96

97
    HANDLE hConsole = GetStdHandle(stdout_stream ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE);
98
    SetConsoleTextAttribute(hConsole, WinColorFG[color]);
99
#else
100
    enum ANSITextAttr
101
    {
102
        TA_NORMAL                                = 0,
103
        TA_BOLD                                  = 1,
104
        TA_BLINK                                 = 5,
105
        TA_REVERSE                               = 7
106
    };
107

108
    enum ANSIFgTextAttr
109
    {
110
        FG_BLACK                                 = 30,
111
        FG_RED,
112
        FG_GREEN,
113
        FG_BROWN,
114
        FG_BLUE,
115
        FG_MAGENTA,
116
        FG_CYAN,
117
        FG_WHITE,
118
        FG_YELLOW
119
    };
120

121
    enum ANSIBgTextAttr
122
    {
123
        BG_BLACK                                 = 40,
124
        BG_RED,
125
        BG_GREEN,
126
        BG_BROWN,
127
        BG_BLUE,
128
        BG_MAGENTA,
129
        BG_CYAN,
130
        BG_WHITE
131
    };
132

133
    static uint8 UnixColorFG[NUM_COLOR_TYPES] =
134
    {
135
        FG_BLACK,                                          // BLACK
136
        FG_RED,                                            // RED
137
        FG_GREEN,                                          // GREEN
138
        FG_BROWN,                                          // BROWN
139
        FG_BLUE,                                           // BLUE
140
        FG_MAGENTA,                                        // MAGENTA
141
        FG_CYAN,                                           // CYAN
142
        FG_WHITE,                                          // WHITE
143
        FG_YELLOW,                                         // YELLOW
144
        FG_RED,                                            // LRED
145
        FG_GREEN,                                          // LGREEN
146
        FG_BLUE,                                           // LBLUE
147
        FG_MAGENTA,                                        // LMAGENTA
148
        FG_CYAN,                                           // LCYAN
149
        FG_WHITE                                           // LWHITE
150
    };
151

152
    fprintf((stdout_stream? stdout : stderr), "\x1b[%d%sm", UnixColorFG[color], (color >= YELLOW && color < NUM_COLOR_TYPES ? ";1" : ""));
153
    #endif
154
}
155

156
void AppenderConsole::ResetColor(bool stdout_stream)
157
{
158
    #if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS
159
    HANDLE hConsole = GetStdHandle(stdout_stream ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE);
160
    SetConsoleTextAttribute(hConsole, FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED);
161
    #else
162
    fprintf((stdout_stream ? stdout : stderr), "\x1b[0m");
163
    #endif
164
}
165

166
void AppenderConsole::Print(std::string const& str, bool error)
167
{
168
#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS
169
    WriteWinConsole(str + "\n", error);
170
#else
171
    utf8printf(error ? stderr : stdout, "%s\n", str.c_str());
172
#endif
173
}
174

175
void AppenderConsole::_write(LogMessage const* message)
176
{
177
    bool stdout_stream = !(message->level == LOG_LEVEL_ERROR || message->level == LOG_LEVEL_FATAL);
178

179
    if (_colored)
180
    {
181
        uint8 index;
182
        switch (message->level)
183
        {
184
            case LOG_LEVEL_TRACE:
185
               index = 5;
186
               break;
187
            case LOG_LEVEL_DEBUG:
188
               index = 4;
189
               break;
190
            case LOG_LEVEL_INFO:
191
               index = 3;
192
               break;
193
            case LOG_LEVEL_WARN:
194
               index = 2;
195
               break;
196
            case LOG_LEVEL_FATAL:
197
               index = 0;
198
               break;
199
            case LOG_LEVEL_ERROR:
200
                [[fallthrough]];
201
            default:
202
               index = 1;
203
               break;
204
        }
205

206
        SetColor(stdout_stream, _colors[index]);
207
        Print(message->prefix + message->text, !stdout_stream);
208
        ResetColor(stdout_stream);
209
    }
210
    else
211
        Print(message->prefix + message->text, !stdout_stream);
212
}
213

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.