summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2012-12-08 21:48:18 +0900
committerTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2012-12-08 21:48:18 +0900
commite86fd44dc5a87d64efc18652b2833ae17b72bf10 (patch)
tree557a4e62c7feb46e64c87aaeee6724ed207ee13c /src
parent9a5fff0de095078932e2878338acaa12a5c9daa3 (diff)
Console color output
Log level and download result string is now colored.
Diffstat (limited to 'src')
-rw-r--r--src/BufferedFile.cc10
-rw-r--r--src/BufferedFile.h2
-rw-r--r--src/Logger.cc40
-rw-r--r--src/Logger.h1
-rw-r--r--src/NullOutputFile.h1
-rw-r--r--src/OutputFile.h2
-rw-r--r--src/RequestGroupMan.cc51
-rw-r--r--src/WinConsoleFile.cc5
-rw-r--r--src/WinConsoleFile.h1
9 files changed, 103 insertions, 10 deletions
diff --git a/src/BufferedFile.cc b/src/BufferedFile.cc
index 4ebd2641..b06ac3c6 100644
--- a/src/BufferedFile.cc
+++ b/src/BufferedFile.cc
@@ -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
diff --git a/src/BufferedFile.h b/src/BufferedFile.h
index aeba3a85..0e267f0a 100644
--- a/src/BufferedFile.h
+++ b/src/BufferedFile.h
@@ -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
diff --git a/src/Logger.cc b/src/Logger.cc
index 99e6aa3e..e7e83f03 100644
--- a/src/Logger.cc
+++ b/src/Logger.cc
@@ -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 {
+const char* levelColor(Logger::LEVEL 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)
+void writeHeaderConsole(Output& fp, Logger::LEVEL level, bool useColor)
{
- fp.printf("[%s] ", levelToString(level));
+ 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();
diff --git a/src/Logger.h b/src/Logger.h
index fb7068bc..b04237be 100644
--- a/src/Logger.h
+++ b/src/Logger.h
@@ -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&);
diff --git a/src/NullOutputFile.h b/src/NullOutputFile.h
index 9ee29b78..c152f108 100644
--- a/src/NullOutputFile.h
+++ b/src/NullOutputFile.h
@@ -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
diff --git a/src/OutputFile.h b/src/OutputFile.h
index 66d1e729..ba0ccb3f 100644
--- a/src/OutputFile.h
+++ b/src/OutputFile.h
@@ -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
diff --git a/src/RequestGroupMan.cc b/src/RequestGroupMan.cc
index 83914ea9..86a26b39 100644
--- a/src/RequestGroupMan.cc
+++ b/src/RequestGroupMan.cc
@@ -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) {
diff --git a/src/WinConsoleFile.cc b/src/WinConsoleFile.cc
index dc9de9f7..0938d89d 100644
--- a/src/WinConsoleFile.cc
+++ b/src/WinConsoleFile.cc
@@ -103,4 +103,9 @@ int WinConsoleFile::flush()
return 0;
}
+bool WinConsoleFile::supportsColor()
+{
+ return false;
+}
+
} // namespace aria2
diff --git a/src/WinConsoleFile.h b/src/WinConsoleFile.h
index d3c16d25..ccd2388f 100644
--- a/src/WinConsoleFile.h
+++ b/src/WinConsoleFile.h
@@ -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