slogcxx.h

Go to the documentation of this file.
00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 #ifndef SLOGCXX_H // Include guard
00016 #define SLOGCXX_H
00017 
00018 // C headers
00019 #include <cassert>
00020 
00021 // C++ headers
00022 #include <string>
00023 #include <vector>
00024 
00025 #include <iostream>
00026 #include <fstream>
00027 
00029 // MACROS 
00031 
00032 
00033 // This avoids warning of unused arguments when prefixed with USUSED
00034 #ifndef UNUSED
00035 #ifdef __GNUC__
00036 #define UNUSED __attribute((__unused__))
00037 #else
00038 
00045 // FIX: Can we or do we need something like this for Win32/VC++?
00046 #define UNUSED
00047 #endif
00048 #endif // ifndef UNUSED
00049 
00051 #define EXIT_DEBUG(why) std::cerr << "EXIT_DEBUG called at " \
00052   << __FILE__ << ":" << __LINE__<<": in function '" <<__FUNCTION__ << "'\n" \
00053   << "  STATED REASON: " << why << std::endl;                           \
00054   exit(EXIT_FAILURE);
00055 
00062 #if !defined (NLOG)
00063 #define WHERE Where(__FILE__,__LINE__,__FUNCTION__)
00064 #endif
00065 
00067 // Where class
00069 
00073 
00074 #ifndef NLOG
00075 class Where {
00076  public: 
00078     Where(const std::string &_file, const int _lineno, const std::string &_function);
00079     inline std::string const &getFile() const {return file;};
00080     inline int const &getLineno() const {return lineno;};
00081     inline std::string const &getFunction() const {return function;};
00082  private:
00083     std::string file;   
00084     int lineno;         
00085     std::string function;       
00086 };
00087 #endif // NLOG
00088 
00090 // ENUMS
00092 
00093 // FIX: these may need to be const int values.
00094 
00106 enum LogLevelsEnum { 
00107   // Kurt's names
00108   ALWAYS=INT_MIN, // Only use for entries()
00109   TERSE=1,
00110   TRACE,
00111   VERBOSE,
00112   BOMBASTIC,
00113   NEVER = INT_MAX // Only use for entries()
00114 };
00115 
00116 
00117 
00119 // The main slog class
00121 
00122 
00206 #if !defined(NLOG)
00207 class Slog {
00208  public:
00216   Slog(const std::string &filename="", const std::string &indentStr=" ", 
00217        const bool append=true, const bool enableXml=true, const bool enableTime=true);
00219   ~Slog();
00220 
00222 
00223 
00224   void setLevel(const int lvl) {assert(0<=lvl);logLevel=lvl;} 
00226   int getLevel() {return logLevel;}
00228   int inc() {return ++logLevel;}
00230   int dec() {--logLevel; if (0>logLevel) logLevel=0; return logLevel;}
00232 
00234 
00235 
00236   void enableTime() {timeEnabled=true;};
00238   void disableTime() {timeEnabled=false;};
00240   bool getTimeStatus() {return timeEnabled;};
00242 
00248 
00249 
00250   void enableXml() {xmlEnabled=true;}; 
00252   void disableXml() {xmlEnabled=false;};  
00254   bool getXmlStatus() {return xmlEnabled;};
00256 
00259   bool entry(const int lvl, const std::string str); 
00260 
00267   bool where(const std::string &file, const int lineno, const std::string &function);
00268 
00270 
00271 
00272   // The following messages are for controlling what the << log messages do
00273   void setMsgLevel(const int lvl) {assert(0<=lvl);msgLevel=lvl;}
00275   int getMsgLevel() {return msgLevel;}
00277   int incMsg() {return ++msgLevel;}
00279   int decMsg() {--msgLevel; if (0>msgLevel) msgLevel=0; return msgLevel;}
00281 
00284 
00285 
00286 
00287 
00288 
00289   bool partial(const int lvl, const std::string str); 
00292   bool complete();  
00294 
00296 
00297 
00298   void setStateIndent(const std::string &str) {stateIndent=str;};
00300   std::string getStateIndent() {return stateIndent;};
00302   std::string indent();
00304   std::string getStateNumberStr();
00305   std::string getCurScope() {if (0==getStateDepth()) return ""; return stateStack[stateStack.size()-1];}
00306 
00308   void pushState(std::string scope, int msgLvl = -1);
00310   std::string popState();
00313   void writeState(bool flat=true);
00314   int getStateDepth() {return stateStack.size();};
00316 
00317 
00318 
00319   // P 65 of EC++ 2nd ed wants the const.
00320   // FIX: is there any point in having an op=?  Should it be just an assert false?
00322   Slog& operator=(UNUSED const Slog& rhs) {
00323     std::cerr << "Slog op=!" << std::endl;
00324     assert ("WTF... do not copy!");
00325     return *this;
00326   }
00327 
00328  private:
00329   int logLevel; 
00330   int msgLevel; 
00331   std::string curStr; 
00332   bool xmlEnabled; 
00333   bool timeEnabled; 
00334   // FIX: how should time stamp formats be controlled?
00335 
00336   std::string stateIndent; 
00337   std::vector<std::string> stateStack; 
00338   std::vector<int> msgLvlStack; 
00339   
00340   std::ofstream logFile; 
00341 
00342 }; // end Slog class
00343 
00344 
00345 Slog& operator<<(Slog&s, Slog&(*manip)(Slog&)); 
00346 
00347 Slog& endl(Slog& s); 
00348 Slog& decl(Slog& s); 
00349 Slog& incl(Slog& s); 
00350 
00351 // Logging operators for basic types
00352 Slog& operator<< (Slog &s, const int &r); 
00353 Slog& operator<< (Slog &s, const size_t &r); 
00354 Slog& operator<< (Slog &s, const char *str); 
00355 Slog& operator<< (Slog &s, const std::string &str); 
00356 
00357 // FIX: can this be made to work?
00358 /* Quote from nntp:
00359 
00360 "You can't overload operators that involve only built in types. At
00361 least one operand must be of class/struct/enum type. Pointers are
00362 considered built in types, even if they point to user-defined
00363 types. Thus you cannot overload any operator that works exclusively on
00364 pointers."
00365 */
00366 
00367 //Slog* operator<< (Slog *s, const char *str);
00368 //Slog* foo (Slog *s, const char *str);
00369 //int foo(Slog &s);
00370 //int foo(Slog *s);
00371 
00372 Slog& operator<< (Slog &s, const char &c); 
00373 Slog& operator<< (Slog &s, const short &sh); 
00374 Slog& operator<< (Slog &s, const long &l); 
00375 //Slog& operator<< (Slog &s, const long long &ll); //!< Insert a long long character
00376 Slog& operator<< (Slog &s, const float &f); 
00377 Slog& operator<< (Slog &s, const double &d); 
00378 
00380 Slog& operator<< (Slog &s, const Where &w); 
00381 
00382 
00386 class LogState {
00387  public:
00391   LogState(Slog *logInstance, const std::string &scope, int msgLvl = -1);
00394   std::string pop(); 
00396   ~LogState();
00397  private:
00398   Slog *log; 
00399   bool popped; 
00400 };
00401 
00402 #endif // !defined(NLOG)
00403 
00408 
00409 // MODE TO ALLOW CODE TO STAY WITH MINIMAL COST
00410 
00411 #if defined(NLOG)
00412 #  include <slogcxx-nlog.h>
00413 #endif
00414 
00415 #endif // SLOGCXX_H

Generated on Tue Aug 15 10:09:38 2006 by  doxygen 1.4.6