/*] Copyright (c) 2009-2010, Charles McGarvey [************************** **] All rights reserved. * * vi:ts=4 sw=4 tw=75 * * Distributable under the terms and conditions of the 2-clause BSD license; * see the file COPYING for a complete text of the license. * **************************************************************************/ #ifndef _MOOF_LOG_H_ #define _MOOF_LOG_H_ /** * \file Log.h * Functions related to logging the process. * The logging functions are logError(), logWarning(), and logInfo(), * listed from most critical to least critical. */ #include // exit #include /** * Macro which tests an assertion and issues a logError() and exits if the * assertion is false. * \param X test to perform */ #undef ASSERT #if NDEBUG #define ASSERT(X) #else #define ASSERT(X) if (!(X)) Mf::logError \ << "false assertion at " << __FILE__ << ":" << __LINE__ << ", " \ << #X, exit(1) #endif namespace Mf { /** * A class for handling a log priority. There are two ways to log * messages: by treating a log object as a function whose parameters are * printed with default spacing, or by treating a log object as an output * stream. Either way, any object can be printed to the log as long as * there is an override for the ostream insertion operator. */ class Log { public: /** * A type for the level or priority of a log message. */ enum Level { NONE = 0, ///< Disable all logging. ERRORR = 1, ///< Log only errors. WARNING = 2, ///< Log warnings and errors. INFO = 3, ///< Log everything. }; /** * Set the lowest-priority log message that will be outputted to the * log. Any logging with a lower priority will be ignored. * \param level The log level. */ static void setLevel(Level level); /** * Get the current lowest-priority log level. If unchanged, the * default level is INFO. * \return The log level. */ static Level level(); /** * Construct a log with a certain priority and prefix string. * \param level The log level. * \param prefix The string printed before each log message. */ Log(Level level, const char* prefix) : mLevel(level), mPrefix(prefix) /* only pass literal strings */ {} template void operator () (const A& a) { *this << a << std::endl; } template void operator () (const A& a, const B& b) { *this << a << " " << b << std::endl; } template void operator () (const A& a, const B& b, const C& c) { *this << a << " " << b << " " << c << std::endl; } template void operator () (const A& a, const B& b, const C& c, const D& d) { *this << a << " " << b << " " << c << " " << d << std::endl; } template void operator () (const A& a, const B& b, const C& c, const D& d, const E& e) { *this << a << " " << b << " " << c << " " << d << " " << e << std::endl; } private: template friend std::ostream& operator << (Log&, const T&); static Level gLevel; Level mLevel; const char* mPrefix; }; extern std::ostream& log; extern std::ostream& nullLog; extern Log logError; extern Log logWarning; extern Log logInfo; template inline std::ostream& operator << (Log& logObj, const T& item) { if (Log::gLevel < logObj.mLevel) return nullLog; return log << logObj.mPrefix << item; } class Script; void importLogFunctions(Script& script); } // namespace Mf #endif // _MOOF_LOG_H_