log.hh

00001 /*
00002 ** TowBowlTactics, an adaptation of the tabletop game Blood Bowl.
00003 **
00004 ** Copyright (C) 2006 The TBT Team.
00005 **
00006 ** This program is free software; you can redistribute it and/or
00007 ** modify it under the terms of the GNU General Public License
00008 ** as published by the Free Software Foundation; either version 2
00009 ** of the License, or (at your option) any later version.
00010 **
00011 ** The complete GNU General Public Licence Notice can be found as the
00012 ** `NOTICE' file in the root directory.
00013 **
00014 ** The TBT Team consists of people listed in the `AUTHORS' file.
00015 */
00016 
00017 #ifndef LOG_HH_
00018 # define LOG_HH_
00019 
00020 # include <cassert>
00021 # include <iostream>
00022 # include "misc/compose.hpp"
00023 
00031 class Log
00032 {
00033 public:
00034   Log(int verbose_level = 1, const char* suffix = NULL);
00035   ~Log();
00036 
00039   void setVerboseLevel(int level);
00044   void setVerboseMask(int mask);
00047   void setModuleSuffix(const char* name);
00049   void setPrintLoc(bool enable = true);
00051   void setUseColor(bool enable = true);
00052 
00054   static Log* getInst();
00056   std::ostream& getStream();
00057 
00058   // Don't use them directly !
00059   static pthread_mutex_t lock_;
00060   int verbose_mask_;
00061   bool print_loc_;
00062   bool use_color_;
00063   char modsuffix_[64];
00064 
00065 private:
00066   pthread_t pth_id_;
00067   char orig_modsuffix_[32];
00068 
00069   typedef std::map<pthread_t, Log*> ThreadList;
00070   static ThreadList thread_list_;
00071   static int ref_count_;
00072 };
00073 
00074 inline Log* Log::getInst()
00075 {
00076   // If this assert breaks, you probably not have a Log object instancied.
00077   ThreadList::iterator it = thread_list_.find(pthread_self());
00078   assert(it != thread_list_.end());
00079   return it->second;
00080 }
00081 
00082 inline std::ostream& Log::getStream()
00083 {
00084   return std::cerr;
00085 }
00086 
00089 
00090 // Set default MODULE_NAME and MODULE_COLOR, in case they are not provided.
00091 # ifndef MODULE_NAME
00092 #  define MODULE_NAME "unset"
00093 # endif
00094 # ifdef MODULE_COLOR
00095 #  define C_NONE        "\e[0m"
00096 #  define C_RED         "\e[1;31m"
00097 #  define C_GREEN       "\e[1;32m"
00098 #  define C_BROWN       "\e[1;33m"
00099 #  define C_BLUE        "\e[1;34m"
00100 #  define C_PURPLE      "\e[1;35m"
00101 #  define C_CYAN        "\e[1;36m"
00102 #  define C_GRAY        "\e[0;30m"
00103 #  define C_BRED        "\e[0;31m"
00104 #  define C_BGREEN      "\e[0;32m"
00105 #  define C_YELLOW      "\e[0;33m"
00106 #  define C_BBLUE       "\e[0;34m"
00107 #  define C_BPURPLE     "\e[0;35m"
00108 #  define C_BCYAN       "\e[0;36m"
00109 # else
00110 #  define MODULE_COLOR  ""
00111 #  define C_NONE        ""
00112 #  define C_RED         ""
00113 #  define C_GREEN       ""
00114 #  define C_BROWN       ""
00115 #  define C_BLUE        ""
00116 #  define C_PURPLE      ""
00117 #  define C_CYAN        ""
00118 #  define C_GRAY        ""
00119 #  define C_BRED        ""
00120 #  define C_BGREEN      ""
00121 #  define C_YELLOW      ""
00122 #  define C_BBLUE       ""
00123 #  define C_BPURPLE     ""
00124 #  define C_BCYAN       ""
00125 # endif
00126 
00127 // Do not use it. Prefer the ERR, WARN, and LOG? macros
00128 # define LOG(Level, Msg)                                                        \
00129 do {                                                                            \
00130   Log* l__ = Log::getInst();                                                    \
00131   if (l__->verbose_mask_ & (1 << Level)) {                                      \
00132     pthread_mutex_lock(&Log::lock_);                                            \
00133     std::ostringstream os__;                                                    \
00134     if (Level == 0)                                                             \
00135       if (l__->use_color_)                                                      \
00136         os__ << C_BRED "Error: " C_NONE;                                        \
00137       else                                                                      \
00138         os__ << "Error: ";                                                      \
00139     else if (Level == 1)                                                        \
00140       if (l__->use_color_)                                                      \
00141         os__ << C_YELLOW "Warning: " C_NONE;                                    \
00142       else                                                                      \
00143         os__ << "Warning: ";                                                    \
00144     os__ << Msg;                                                                \
00145     if (l__->print_loc_)                                                        \
00146       if (l__->use_color_)                                                      \
00147         l__->getStream() << "[" MODULE_COLOR MODULE_NAME << l__->modsuffix_     \
00148                        << C_NONE "] " << __FILE__ << ":" << __LINE__ << ": "    \
00149                        << os__.str() << std::endl;                              \
00150       else                                                                      \
00151         l__->getStream() << "[" MODULE_NAME << l__->modsuffix_                  \
00152                        << "] " << __FILE__ << ":" << __LINE__ << ": "           \
00153                        << os__.str() << std::endl;                              \
00154     else                                                                        \
00155       if (l__->use_color_)                                                      \
00156         l__->getStream() << "[" MODULE_COLOR MODULE_NAME << l__->modsuffix_     \
00157                        << C_NONE "] " << os__.str() << std::endl;               \
00158       else                                                                      \
00159         l__->getStream() << "[" MODULE_NAME << l__->modsuffix_                  \
00160                        << "] " << os__.str() << std::endl;                      \
00161     pthread_mutex_unlock(&Log::lock_);                                          \
00162   }                                                                             \
00163 } while (0)
00164 
00165 # define ERR(Msg...) LOG(0, String::compose(Msg))
00166 # define WARN(Msg...) LOG(1, String::compose(Msg))
00167 
00168 # define LOG1(Msg...) LOG(2, String::compose(Msg))
00169 # define LOG2(Msg...) LOG(3, String::compose(Msg))
00170 # define LOG3(Msg...) LOG(4, String::compose(Msg))
00171 # define LOG4(Msg...) LOG(5, String::compose(Msg))
00172 # define LOG5(Msg...) LOG(6, String::compose(Msg))
00173 # define LOG6(Msg...) LOG(7, String::compose(Msg))
00174 
00176 
00177 #endif /* !LOG_H_ */

Generated on Sat Jun 23 16:07:23 2007 for Stechec/TBT by  doxygen 1.4.7