00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "global.hpp"
00021
00022 #include "SDL.h"
00023
00024 #include "log.hpp"
00025
00026 #include <algorithm>
00027 #include <ctime>
00028 #include <sstream>
00029 #include <streambuf>
00030
00031 namespace {
00032
00033 class null_streambuf : public std::streambuf
00034 {
00035 virtual int overflow(int c) { return std::char_traits< char >::not_eof(c); }
00036 public:
00037 null_streambuf() {}
00038 };
00039
00040 }
00041
00042 static std::ostream null_ostream(new null_streambuf);
00043 static int indent = 0;
00044 static bool timestamp = true;
00045
00046 namespace lg {
00047
00048 std::vector< lg::logd > log_domains;
00049 void timestamps(bool t) { timestamp = t; }
00050
00051 logger err("error", 0), warn("warning", 1), info("info", 2), debug("debug", 3);
00052 log_domain general("general"), ai("ai"), config("config"), display("display"),
00053 engine("engine"), network("network"), mp_server("server"),
00054 filesystem("filesystem"), audio("audio"), notifs("notifs"),
00055 replay("replay"), help("help"), gui("gui"), gui_parse("gui_parse"),
00056 gui_draw("gui_draw"), gui_event("gui_event");
00057
00058 log_domain::log_domain(char const *name) : domain_(log_domains.size())
00059 {
00060 logd d = { name, 0 };
00061 log_domains.push_back(d);
00062 }
00063
00064 bool set_log_domain_severity(std::string const &name, int severity)
00065 {
00066 std::vector< logd >::iterator
00067 it = log_domains.begin(),
00068 it_end = log_domains.end();
00069 if (name == "all") {
00070 for(; it != it_end; ++it)
00071 it->severity_ = severity;
00072 } else {
00073 for(; it != it_end; ++it)
00074 if (name == it->name_) break;
00075 if (it == it_end)
00076 return false;
00077 it->severity_ = severity;
00078 }
00079 return true;
00080 }
00081
00082 std::string list_logdomains()
00083 {
00084 std::vector< logd >::iterator
00085 it_begin = log_domains.begin(),
00086 it_end = log_domains.end(),
00087 it;
00088 std::string domainlist = "";
00089 for(it = it_begin; it != it_end; ++it) {
00090 if (it != it_begin)
00091 domainlist += ", ";
00092 domainlist += it->name_;
00093 }
00094 return domainlist;
00095 }
00096
00097 std::string get_timestamp(const time_t& t, const std::string& format) {
00098 char buf[100] = {0};
00099 tm* lt = localtime(&t);
00100 if (lt) {
00101 strftime(buf, 100, format.c_str(), lt);
00102 }
00103 return buf;
00104 }
00105
00106 std::ostream &logger::operator()(log_domain const &domain, bool show_names, bool do_indent) const
00107 {
00108 logd const &d = log_domains[domain.domain_];
00109 if (severity_ > d.severity_)
00110 return null_ostream;
00111 else {
00112 if(do_indent) {
00113 for(int i = 0; i != indent; ++i)
00114 std::cerr << " ";
00115 }
00116 if (timestamp) {
00117 std::cerr << get_timestamp(time(NULL));
00118 }
00119 if (show_names) {
00120 std::cerr << name_ << ' ' << d.name_ << ": ";
00121 }
00122 return std::cerr;
00123 }
00124 }
00125
00126 void scope_logger::do_log_entry(log_domain const &domain, const char* str)
00127 {
00128 output_ = &debug(domain, false, true);
00129 str_ = str;
00130 ticks_ = SDL_GetTicks();
00131 (*output_) << "BEGIN: " << str_ << "\n";
00132 ++indent;
00133 }
00134
00135 void scope_logger::do_log_exit()
00136 {
00137 const int ticks = SDL_GetTicks() - ticks_;
00138 --indent;
00139 do_indent();
00140 if (timestamp) (*output_) << get_timestamp(time(NULL));
00141 (*output_) << "END: " << str_ << " (took " << ticks << "ms)\n";
00142 }
00143
00144 void scope_logger::do_indent() const
00145 {
00146 for(int i = 0; i != indent; ++i)
00147 (*output_) << " ";
00148 }
00149
00150 std::stringstream wml_error;
00151
00152 }
00153