diff options
Diffstat (limited to 'indra/llcommon/llerror.h')
-rwxr-xr-x | indra/llcommon/llerror.h | 180 |
1 files changed, 113 insertions, 67 deletions
diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h index ceff40e900..d7dc38a4c6 100755 --- a/indra/llcommon/llerror.h +++ b/indra/llcommon/llerror.h @@ -31,9 +31,66 @@ #include <sstream> #include <typeinfo> -#include "llerrorlegacy.h" #include "stdtypes.h" +#include "llpreprocessor.h" +#include <boost/static_assert.hpp> + +const int LL_ERR_NOERR = 0; + +// Define one of these for different error levels in release... +// #define RELEASE_SHOW_DEBUG // Define this if you want your release builds to show lldebug output. +#define RELEASE_SHOW_INFO // Define this if you want your release builds to show llinfo output +#define RELEASE_SHOW_WARN // Define this if you want your release builds to show llwarn output. + +#ifdef _DEBUG +#define SHOW_DEBUG +#define SHOW_WARN +#define SHOW_INFO +#define SHOW_ASSERT +#else // _DEBUG + +#ifdef LL_RELEASE_WITH_DEBUG_INFO +#define SHOW_ASSERT +#endif // LL_RELEASE_WITH_DEBUG_INFO + +#ifdef RELEASE_SHOW_DEBUG +#define SHOW_DEBUG +#endif + +#ifdef RELEASE_SHOW_WARN +#define SHOW_WARN +#endif + +#ifdef RELEASE_SHOW_INFO +#define SHOW_INFO +#endif + +#ifdef RELEASE_SHOW_ASSERT +#define SHOW_ASSERT +#endif + +#endif // !_DEBUG + +#define llassert_always(func) if (LL_UNLIKELY(!(func))) LL_ERRS() << "ASSERT (" << #func << ")" << LL_ENDL; + +#ifdef SHOW_ASSERT +#define llassert(func) llassert_always(func) +#define llverify(func) llassert_always(func) +#else +#define llassert(func) +#define llverify(func) do {if (func) {}} while(0) +#endif + +#ifdef LL_WINDOWS +#define LL_STATIC_ASSERT(func, msg) static_assert(func, msg) +#define LL_BAD_TEMPLATE_INSTANTIATION(type, msg) static_assert(false, msg) +#else +#define LL_STATIC_ASSERT(func, msg) BOOST_STATIC_ASSERT(func) +#define LL_BAD_TEMPLATE_INSTANTIATION(type, msg) BOOST_STATIC_ASSERT(sizeof(type) != 0 && false); +#endif + + /** Error Logging Facility Information for most users: @@ -121,26 +178,25 @@ namespace LLError They are not intended for general use. */ - class CallSite; + struct CallSite; class LL_COMMON_API Log { public: static bool shouldLog(CallSite&); static std::ostringstream* out(); - static void flush(std::ostringstream* out, char* message) ; + static void flush(std::ostringstream* out, char* message); static void flush(std::ostringstream*, const CallSite&); }; - class LL_COMMON_API CallSite + struct LL_COMMON_API CallSite { // Represents a specific place in the code where a message is logged // This is public because it is used by the macros below. It is not // intended for public use. - public: CallSite(ELevel, const char* file, int line, - const std::type_info& class_info, const char* function, const char* broadTag, const char* narrowTag, bool printOnce); - + const std::type_info& class_info, const char* function, bool printOnce, const char* broadTag = NULL, const char* narrowTag = NULL ); + #ifdef LL_LIBRARY_INCLUDE bool shouldLog(); #else // LL_LIBRARY_INCLUDE @@ -151,7 +207,6 @@ namespace LLError void invalidate(); - private: // these describe the call site and never change const ELevel mLevel; const char* const mFile; @@ -167,6 +222,11 @@ namespace LLError bool mShouldLog; friend class Log; + + private: + // 3 or more tags not currently supported + CallSite(ELevel, const char* file, int line, + const std::type_info& class_info, const char* function, bool printOnce, const char* broadTag, const char* narrowTag, const char*, ...); }; @@ -237,78 +297,64 @@ typedef LLError::NoClassInfo _LL_CLASS_TO_LOG; // Outside a class declaration, or in class without LOG_CLASS(), this // typedef causes the messages to not be associated with any class. +///////////////////////////////// +// Error Logging Macros +// See top of file for common usage. +///////////////////////////////// +#define lllog(level, once, ...) \ + do { \ + static LLError::CallSite _site( \ + level, __FILE__, __LINE__, typeid(_LL_CLASS_TO_LOG), __FUNCTION__, once, __VA_ARGS__ );\ + if (LL_UNLIKELY(_site.shouldLog())) \ + { \ + std::ostringstream* _out = LLError::Log::out(); \ + (*_out) +//Use this construct if you need to do computation in the middle of a +//message: +// +// LL_INFOS("AgentGesture") << "the agent " << agend_id; +// switch (f) +// { +// case FOP_SHRUGS: LL_CONT << "shrugs"; break; +// case FOP_TAPS: LL_CONT << "points at " << who; break; +// case FOP_SAYS: LL_CONT << "says " << message; break; +// } +// LL_CONT << " for " << t << " seconds" << LL_ENDL; +// +//Such computation is done iff the message will be logged. +#define LL_CONT (*_out) +#define LL_NEWLINE '\n' -/* - Error Logging Macros - See top of file for common usage. -*/ - -#define lllog(level, broadTag, narrowTag, once) \ - do { \ - static LLError::CallSite _site( \ - level, __FILE__, __LINE__, typeid(_LL_CLASS_TO_LOG), __FUNCTION__, broadTag, narrowTag, once);\ - if (LL_UNLIKELY(_site.shouldLog())) \ - { \ - std::ostringstream* _out = LLError::Log::out(); \ - (*_out) - -// DEPRECATED: Don't call directly, use LL_ENDL instead, which actually looks like a macro -#define llendl \ - LLError::End(); \ +#define LL_ENDL \ + LLError::End(); \ LLError::Log::flush(_out, _site); \ - } \ + } \ } while(0) -// DEPRECATED: Use the new macros that allow tags and *look* like macros. -#define lldebugs lllog(LLError::LEVEL_DEBUG, NULL, NULL, false) -#define llinfos lllog(LLError::LEVEL_INFO, NULL, NULL, false) -#define llwarns lllog(LLError::LEVEL_WARN, NULL, NULL, false) -#define llerrs lllog(LLError::LEVEL_ERROR, NULL, NULL, false) -#define llcont (*_out) - // NEW Macros for debugging, allow the passing of a string tag -// One Tag -#define LL_DEBUGS(broadTag) lllog(LLError::LEVEL_DEBUG, broadTag, NULL, false) -#define LL_INFOS(broadTag) lllog(LLError::LEVEL_INFO, broadTag, NULL, false) -#define LL_WARNS(broadTag) lllog(LLError::LEVEL_WARN, broadTag, NULL, false) -#define LL_ERRS(broadTag) lllog(LLError::LEVEL_ERROR, broadTag, NULL, false) -// Two Tags -#define LL_DEBUGS2(broadTag, narrowTag) lllog(LLError::LEVEL_DEBUG, broadTag, narrowTag, false) -#define LL_INFOS2(broadTag, narrowTag) lllog(LLError::LEVEL_INFO, broadTag, narrowTag, false) -#define LL_WARNS2(broadTag, narrowTag) lllog(LLError::LEVEL_WARN, broadTag, narrowTag, false) -#define LL_ERRS2(broadTag, narrowTag) lllog(LLError::LEVEL_ERROR, broadTag, narrowTag, false) +// Pass comma separated list of tags (currently only supports up to 0, 1, or 2) +#define LL_DEBUGS(...) lllog(LLError::LEVEL_DEBUG, false, __VA_ARGS__) +#define LL_INFOS(...) lllog(LLError::LEVEL_INFO, false, __VA_ARGS__) +#define LL_WARNS(...) lllog(LLError::LEVEL_WARN, false, __VA_ARGS__) +#define LL_ERRS(...) lllog(LLError::LEVEL_ERROR, false, __VA_ARGS__) // Only print the log message once (good for warnings or infos that would otherwise // spam the log file over and over, such as tighter loops). -#define LL_DEBUGS_ONCE(broadTag) lllog(LLError::LEVEL_DEBUG, broadTag, NULL, true) -#define LL_INFOS_ONCE(broadTag) lllog(LLError::LEVEL_INFO, broadTag, NULL, true) -#define LL_WARNS_ONCE(broadTag) lllog(LLError::LEVEL_WARN, broadTag, NULL, true) -#define LL_DEBUGS2_ONCE(broadTag, narrowTag) lllog(LLError::LEVEL_DEBUG, broadTag, narrowTag, true) -#define LL_INFOS2_ONCE(broadTag, narrowTag) lllog(LLError::LEVEL_INFO, broadTag, narrowTag, true) -#define LL_WARNS2_ONCE(broadTag, narrowTag) lllog(LLError::LEVEL_WARN, broadTag, narrowTag, true) - -#define LL_ENDL llendl -#define LL_CONT (*_out) +#define LL_DEBUGS_ONCE(...) lllog(LLError::LEVEL_DEBUG, true, __VA_ARGS__) +#define LL_INFOS_ONCE(...) lllog(LLError::LEVEL_INFO, true, __VA_ARGS__) +#define LL_WARNS_ONCE(...) lllog(LLError::LEVEL_WARN, true, __VA_ARGS__) - /* - Use this construct if you need to do computation in the middle of a - message: - - LL_INFOS("AgentGesture") << "the agent " << agend_id; - switch (f) - { - case FOP_SHRUGS: LL_CONT << "shrugs"; break; - case FOP_TAPS: LL_CONT << "points at " << who; break; - case FOP_SAYS: LL_CONT << "says " << message; break; - } - LL_CONT << " for " << t << " seconds" << LL_ENDL; - - Such computation is done iff the message will be logged. - */ +// DEPRECATED: Use the new macros that allow tags and *look* like macros. +#define lldebugs LL_DEBUGS() +#define llinfos LL_INFOS() +#define llwarns LL_WARNS() +#define llerrs LL_ERRS() +#define llcont LL_CONT +#define llendl LL_ENDL #endif // LL_LLERROR_H |