1 //
2 //  Copyright (C) 2009, 2012  Nick Gasson
3 //
4 //  This program is free software: you can redistribute it and/or modify
5 //  it under the terms of the GNU General Public License as published by
6 //  the Free Software Foundation, either version 3 of the License, or
7 //  (at your option) any later version.
8 //
9 //  This program 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 General Public License for more details.
13 //
14 //  You should have received a copy of the GNU General Public License
15 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 //
17 
18 #include "ILogger.hpp"
19 
20 #include <iostream>
21 #include <cstdio>
22 #include <cstdlib>
23 #include <cstring>
24 
25 #ifdef WIN32
26 #include <io.h>   // For _isatty
27 #else
28 #include <unistd.h>
29 #endif
30 
31 using namespace std;
32 
33 // Concrete logger implementation
34 class LoggerImpl : public ILogger {
35    friend struct PrintLine;
36 public:
37    LoggerImpl();
38 
39    PrintLinePtr write_msg(LogMsgType type);
40 };
41 
42 namespace {
43    bool is_stdoutTTY;
44 }
45 
LoggerImpl()46 LoggerImpl::LoggerImpl()
47 {
48 #ifdef WIN32
49    is_stdoutTTY = (_isatty(_fileno(stdout)) != 0);
50 #else
51    is_stdoutTTY = (isatty(fileno(stdout)) != 0);
52 
53    const char *term = getenv("TERM");
54    if (term != NULL && strcmp(term, "dumb") == 0)
55       is_stdoutTTY = false;
56 
57 #endif
58 
59    cout.precision(3);
60 }
61 
write_msg(LogMsgType type)62 PrintLinePtr LoggerImpl::write_msg(LogMsgType type)
63 {
64    if (is_stdoutTTY)
65       cout << "\x1B[1m";
66 
67    switch (type) {
68    case LOG_NORMAL:
69       cout << "[INFO ] ";
70       break;
71    case LOG_DEBUG:
72       if (is_stdoutTTY)
73          cout << "\x1B[36m";
74       cout << "[DEBUG] ";
75       break;
76    case LOG_WARN:
77       if (is_stdoutTTY)
78          cout << "\x1B[33m";
79       cout << "[WARN ] ";
80       break;
81    case LOG_ERROR:
82       if (is_stdoutTTY)
83          cout << "\x1B[31m";
84       cout << "[ERROR] ";
85       break;
86    }
87    return PrintLinePtr(new PrintLine(cout));
88 }
89 
PrintLine(ostream & a_stream)90 PrintLine::PrintLine(ostream& a_stream)
91    : stream(a_stream)
92 {
93 
94 }
95 
~PrintLine()96 PrintLine::~PrintLine()
97 {
98    if (is_stdoutTTY)
99       cout << "\x1B[0m";
100 
101    stream << endl;
102 }
103 
104 // Return the single instance of Logger
get_logger()105 ILoggerPtr get_logger()
106 {
107    static ILoggerPtr logger(new LoggerImpl);
108    return logger;
109 }
110