Console color output

Log level and download result string is now colored.
pull/36/head
Tatsuhiro Tsujikawa 2012-12-08 21:48:18 +09:00
parent 9a5fff0de0
commit e86fd44dc5
9 changed files with 104 additions and 11 deletions

View File

@ -54,11 +54,12 @@ BufferedFile::BufferedFile(const char* filename, const char* mode)
#else // !__MINGW32__
fp_(a2fopen(filename, mode)),
#endif // !__MINGW32__
open_(fp_)
open_(fp_),
supportsColor_(isatty(fileno(fp_)))
{}
BufferedFile::BufferedFile(FILE* fp)
: fp_(fp), open_(true)
: fp_(fp), open_(true), supportsColor_(isatty(fileno(fp)))
{}
BufferedFile::~BufferedFile()
@ -169,4 +170,9 @@ int BufferedFile::flush()
return fflush(fp_);
}
bool BufferedFile::supportsColor()
{
return supportsColor_;
}
} // namespace aria2

View File

@ -77,6 +77,7 @@ public:
virtual int printf(const char* format, ...);
// wrapper for fflush
virtual int flush();
virtual bool supportsColor();
// Mode for reading
static const char READ[];
// Mode for writing
@ -91,6 +92,7 @@ private:
FILE* fp_;
// true when file has been opened.
bool open_;
bool supportsColor_;
};
} // namespace aria2

View File

@ -34,6 +34,7 @@
/* copyright --> */
#include "Logger.h"
#include <unistd.h>
#include <cstring>
#include <cstdio>
@ -50,7 +51,14 @@ namespace aria2 {
Logger::Logger()
: logLevel_(Logger::A2_DEBUG),
stdoutField_(0)
stdoutField_(0),
#ifdef __MINGW32__
// Windows DOS prompt does not handle ANSI color code, so make
// this false.
useColor_(false)
#else // !__MINGW32__
useColor_(isatty(STDOUT_FILENO) == 1)
#endif // !__MINGW32__
{}
Logger::~Logger()
@ -132,10 +140,34 @@ void writeHeader
} // namespace
namespace {
template<typename Output>
void writeHeaderConsole(Output& fp, Logger::LEVEL level)
const char* levelColor(Logger::LEVEL level)
{
fp.printf("[%s] ", levelToString(level));
switch(level) {
case Logger::A2_DEBUG:
case Logger::A2_INFO:
// We don't print these levels in console
return "";
case Logger::A2_NOTICE:
return "\033[1;32m";
case Logger::A2_WARN:
return "\033[1;33m";
case Logger::A2_ERROR:
return "\033[1;31m";
default:
return "";
}
}
} // namespace
namespace {
template<typename Output>
void writeHeaderConsole(Output& fp, Logger::LEVEL level, bool useColor)
{
if(useColor) {
fp.printf("[%s%s\033[0m] ", levelColor(level), levelToString(level));
} else {
fp.printf("[%s] ", levelToString(level));
}
}
} // namespace
@ -164,7 +196,7 @@ void Logger::writeLog
}
if(toConsole) {
global::cout()->printf("\n");
writeHeaderConsole(*global::cout(), level);
writeHeaderConsole(*global::cout(), level, useColor_);
global::cout()->printf("%s\n", msg);
writeStackTrace(*global::cout(), trace);
global::cout()->flush();

View File

@ -59,6 +59,7 @@ private:
LEVEL logLevel_;
SharedHandle<OutputFile> fpp_;
int stdoutField_;
bool useColor_;
// Don't allow copying
Logger(const Logger&);
Logger& operator=(const Logger&);

View File

@ -45,6 +45,7 @@ public:
virtual size_t write(const char* str) { return 0; }
virtual int printf(const char* format, ...) { return 0; }
virtual int flush() { return 0; }
virtual bool supportsColor() { return false; }
};
} // namespace aria2

View File

@ -47,6 +47,8 @@ public:
virtual size_t write(const char* str) = 0;
virtual int printf(const char* format, ...) = 0;
virtual int flush() = 0;
// Returns true if the output medium supports ANSI color codes.
virtual bool supportsColor() = 0;
};
} // namespace aria2

View File

@ -716,6 +716,48 @@ RequestGroupMan::DownloadStat RequestGroupMan::getDownloadStat() const
lastError);
}
enum DownloadStatus {
A2_STATUS_OK,
A2_STATUS_INPR,
A2_STATUS_RM,
A2_STATUS_ERR
};
namespace {
const char* getStatusStr(DownloadStatus status, bool useColor)
{
// status string is formatted in 4 characters wide.
switch(status) {
case(A2_STATUS_OK):
if(useColor) {
return "\033[1;32mOK\033[0m ";
} else {
return "OK ";
}
case(A2_STATUS_INPR):
if(useColor) {
return "\033[1;34mINPR\033[0m";
} else {
return "INPR";
}
case(A2_STATUS_RM):
if(useColor) {
return "\033[1mRM\033[0m ";
} else {
return "RM ";
}
case(A2_STATUS_ERR):
if(useColor) {
return "\033[1;31mERR\033[0m ";
} else {
return "ERR ";
}
default:
return "";
}
}
} // namespace
void RequestGroupMan::showDownloadResults(OutputFile& o, bool full) const
{
#ifdef __MINGW32__
@ -739,6 +781,7 @@ void RequestGroupMan::showDownloadResults(OutputFile& o, bool full) const
}
std::string line(pathRowSize, '=');
o.printf("%s\n", line.c_str());
bool useColor = o.supportsColor();
int ok = 0;
int err = 0;
int inpr = 0;
@ -751,16 +794,16 @@ void RequestGroupMan::showDownloadResults(OutputFile& o, bool full) const
}
const char* status;
if((*itr)->result == error_code::FINISHED) {
status = "OK";
status = getStatusStr(A2_STATUS_OK, useColor);
++ok;
} else if((*itr)->result == error_code::IN_PROGRESS) {
status = "INPR";
status = getStatusStr(A2_STATUS_INPR, useColor);
++inpr;
} else if((*itr)->result == error_code::REMOVED) {
status = "RM";
status = getStatusStr(A2_STATUS_RM, useColor);
++rm;
} else {
status = "ERR";
status = getStatusStr(A2_STATUS_ERR, useColor);
++err;
}
if(full) {

View File

@ -103,4 +103,9 @@ int WinConsoleFile::flush()
return 0;
}
bool WinConsoleFile::supportsColor()
{
return false;
}
} // namespace aria2

View File

@ -47,6 +47,7 @@ public:
virtual size_t write(const char* str);
virtual int printf(const char* format, ...);
virtual int flush();
virtual bool supportsColor();
private:
DWORD stdHandle_;
// Don't allow copying