X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fglog%2Flogging.h.in;h=d6cc865ab5d54a71dcc1ccb65d6ba99e988ec8fb;hb=0d8c6340f8c5276e0a67df6712f4249582cd79b3;hp=8e8af788c79627023afed4d18eacd81a75f7a214;hpb=8cf64cc167db391d6e46b6863a85925ff8021f27;p=platform%2Fupstream%2Fglog.git diff --git a/src/glog/logging.h.in b/src/glog/logging.h.in index 8e8af78..d6cc865 100644 --- a/src/glog/logging.h.in +++ b/src/glog/logging.h.in @@ -39,19 +39,23 @@ #include #include #include +#include +#include +#include #include #if @ac_cv_have_unistd_h@ # include #endif -#ifdef __DEPRECATED -// Make GCC quiet. -# undef __DEPRECATED -# include -# define __DEPRECATED +#include + +#if defined(_MSC_VER) +#define GLOG_MSVC_PUSH_DISABLE_WARNING(n) __pragma(warning(push)) \ + __pragma(warning(disable:n)) +#define GLOG_MSVC_POP_WARNING() __pragma(warning(pop)) #else -# include +#define GLOG_MSVC_PUSH_DISABLE_WARNING(n) +#define GLOG_MSVC_POP_WARNING() #endif -#include // Annoying stuff for windows -- makes sure clients can import these functions #ifndef GOOGLE_GLOG_DLL_DECL @@ -131,6 +135,23 @@ typedef unsigned __int64 uint64; #endif #endif +#ifndef GOOGLE_PREDICT_FALSE +#if @ac_cv_have___builtin_expect@ +#define GOOGLE_PREDICT_FALSE(x) (__builtin_expect(x, 0)) +#else +#define GOOGLE_PREDICT_FALSE(x) x +#endif +#endif + +#ifndef GOOGLE_PREDICT_TRUE +#if @ac_cv_have___builtin_expect@ +#define GOOGLE_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1)) +#else +#define GOOGLE_PREDICT_TRUE(x) x +#endif +#endif + + // Make a bunch of macros for logging. The way to log things is to stream // things to LOG(). E.g., // @@ -152,21 +173,21 @@ typedef unsigned __int64 uint64; // You can also do occasional logging (log every n'th occurrence of an // event): // -// LOG_EVERY_N(INFO, 10) << "Got the " << COUNTER << "th cookie"; +// LOG_EVERY_N(INFO, 10) << "Got the " << google::COUNTER << "th cookie"; // // The above will cause log messages to be output on the 1st, 11th, 21st, ... -// times it is executed. Note that the special COUNTER value is used to -// identify which repetition is happening. +// times it is executed. Note that the special google::COUNTER value is used +// to identify which repetition is happening. // // You can also do occasional conditional logging (log every n'th // occurrence of an event, when condition is satisfied): // -// LOG_IF_EVERY_N(INFO, (size > 1024), 10) << "Got the " << COUNTER +// LOG_IF_EVERY_N(INFO, (size > 1024), 10) << "Got the " << google::COUNTER // << "th big cookie"; // // You can log messages the first N times your code executes a line. E.g. // -// LOG_FIRST_N(INFO, 20) << "Got the " << COUNTER << "th cookie"; +// LOG_FIRST_N(INFO, 20) << "Got the " << google::COUNTER << "th cookie"; // // Outputs log messages for the first 20 times it is executed. // @@ -183,7 +204,7 @@ typedef unsigned __int64 uint64; // // DLOG_IF(INFO, num_cookies > 10) << "Got lots of cookies"; // -// DLOG_EVERY_N(INFO, 10) << "Got the " << COUNTER << "th cookie"; +// DLOG_EVERY_N(INFO, 10) << "Got the " << google::COUNTER << "th cookie"; // // All "debug mode" logging is compiled away to nothing for non-debug mode // compiles. @@ -227,11 +248,11 @@ typedef unsigned __int64 uint64; // "program with --v=1 or more"; // VLOG_EVERY_N(1, 10) // << "I'm printed every 10th occurrence, and when you run the program " -// "with --v=1 or more. Present occurence is " << COUNTER; +// "with --v=1 or more. Present occurence is " << google::COUNTER; // VLOG_IF_EVERY_N(1, (size > 1024), 10) // << "I'm printed on every 10th occurence of case when size is more " // " than 1024, when you run the program with --v=1 or more. "; -// "Present occurence is " << COUNTER; +// "Present occurence is " << google::COUNTER; // // The supported severity levels for macros that allow you to specify one // are (in increasing order of severity) INFO, WARNING, ERROR, and FATAL. @@ -286,27 +307,27 @@ typedef unsigned __int64 uint64; #ifndef DECLARE_VARIABLE #define MUST_UNDEF_GFLAGS_DECLARE_MACROS -#define DECLARE_VARIABLE(type, name, tn) \ - namespace FLAG__namespace_do_not_use_directly_use_DECLARE_##tn##_instead { \ - extern GOOGLE_GLOG_DLL_DECL type FLAGS_##name; \ - } \ - using FLAG__namespace_do_not_use_directly_use_DECLARE_##tn##_instead::FLAGS_##name +#define DECLARE_VARIABLE(type, shorttype, name, tn) \ + namespace fL##shorttype { \ + extern GOOGLE_GLOG_DLL_DECL type FLAGS_##name; \ + } \ + using fL##shorttype::FLAGS_##name // bool specialization #define DECLARE_bool(name) \ - DECLARE_VARIABLE(bool, name, bool) + DECLARE_VARIABLE(bool, B, name, bool) // int32 specialization #define DECLARE_int32(name) \ - DECLARE_VARIABLE(@ac_google_namespace@::int32, name, int32) + DECLARE_VARIABLE(@ac_google_namespace@::int32, I, name, int32) // Special case for string, because we have to specify the namespace // std::string, which doesn't play nicely with our FLAG__namespace hackery. -#define DECLARE_string(name) \ - namespace FLAG__namespace_do_not_use_directly_use_DECLARE_string_instead { \ - extern GOOGLE_GLOG_DLL_DECL std::string FLAGS_##name; \ - } \ - using FLAG__namespace_do_not_use_directly_use_DECLARE_string_instead::FLAGS_##name +#define DECLARE_string(name) \ + namespace fLS { \ + extern GOOGLE_GLOG_DLL_DECL std::string& FLAGS_##name; \ + } \ + using fLS::FLAGS_##name #endif // Set whether log messages go to stderr instead of logfiles @@ -315,6 +336,9 @@ DECLARE_bool(logtostderr); // Set whether log messages go to stderr in addition to logfiles. DECLARE_bool(alsologtostderr); +// Set color messages logged to stderr (if supported by terminal). +DECLARE_bool(colorlogtostderr); + // Log messages at a level >= this flag are automatically sent to // stderr in addition to log files. DECLARE_int32(stderrthreshold); @@ -337,6 +361,9 @@ DECLARE_int32(minloglevel); // default logging directory. DECLARE_string(log_dir); +// Set the log file mode. +DECLARE_int32(logfile_mode); + // Sets the path of the directory into which to put additional links // to the log files. DECLARE_string(log_link); @@ -368,7 +395,7 @@ DECLARE_bool(stop_logging_if_full_disk); #define COMPACT_GOOGLE_LOG_INFO @ac_google_namespace@::LogMessage( \ __FILE__, __LINE__) #define LOG_TO_STRING_INFO(message) @ac_google_namespace@::LogMessage( \ - __FILE__, __LINE__, @ac_google_namespace@::INFO, message) + __FILE__, __LINE__, @ac_google_namespace@::GLOG_INFO, message) #else #define COMPACT_GOOGLE_LOG_INFO @ac_google_namespace@::NullStream() #define LOG_TO_STRING_INFO(message) @ac_google_namespace@::NullStream() @@ -376,9 +403,9 @@ DECLARE_bool(stop_logging_if_full_disk); #if GOOGLE_STRIP_LOG <= 1 #define COMPACT_GOOGLE_LOG_WARNING @ac_google_namespace@::LogMessage( \ - __FILE__, __LINE__, @ac_google_namespace@::WARNING) + __FILE__, __LINE__, @ac_google_namespace@::GLOG_WARNING) #define LOG_TO_STRING_WARNING(message) @ac_google_namespace@::LogMessage( \ - __FILE__, __LINE__, @ac_google_namespace@::WARNING, message) + __FILE__, __LINE__, @ac_google_namespace@::GLOG_WARNING, message) #else #define COMPACT_GOOGLE_LOG_WARNING @ac_google_namespace@::NullStream() #define LOG_TO_STRING_WARNING(message) @ac_google_namespace@::NullStream() @@ -386,9 +413,9 @@ DECLARE_bool(stop_logging_if_full_disk); #if GOOGLE_STRIP_LOG <= 2 #define COMPACT_GOOGLE_LOG_ERROR @ac_google_namespace@::LogMessage( \ - __FILE__, __LINE__, @ac_google_namespace@::ERROR) + __FILE__, __LINE__, @ac_google_namespace@::GLOG_ERROR) #define LOG_TO_STRING_ERROR(message) @ac_google_namespace@::LogMessage( \ - __FILE__, __LINE__, @ac_google_namespace@::ERROR, message) + __FILE__, __LINE__, @ac_google_namespace@::GLOG_ERROR, message) #else #define COMPACT_GOOGLE_LOG_ERROR @ac_google_namespace@::NullStream() #define LOG_TO_STRING_ERROR(message) @ac_google_namespace@::NullStream() @@ -398,44 +425,50 @@ DECLARE_bool(stop_logging_if_full_disk); #define COMPACT_GOOGLE_LOG_FATAL @ac_google_namespace@::LogMessageFatal( \ __FILE__, __LINE__) #define LOG_TO_STRING_FATAL(message) @ac_google_namespace@::LogMessage( \ - __FILE__, __LINE__, @ac_google_namespace@::FATAL, message) + __FILE__, __LINE__, @ac_google_namespace@::GLOG_FATAL, message) #else #define COMPACT_GOOGLE_LOG_FATAL @ac_google_namespace@::NullStreamFatal() #define LOG_TO_STRING_FATAL(message) @ac_google_namespace@::NullStreamFatal() #endif +#if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON) +#define DCHECK_IS_ON() 0 +#else +#define DCHECK_IS_ON() 1 +#endif + // For DFATAL, we want to use LogMessage (as opposed to // LogMessageFatal), to be consistent with the original behavior. -#ifdef NDEBUG +#if !DCHECK_IS_ON() #define COMPACT_GOOGLE_LOG_DFATAL COMPACT_GOOGLE_LOG_ERROR #elif GOOGLE_STRIP_LOG <= 3 -#define COMPACT_GOOGLE_LOG_DFATAL LogMessage( \ - __FILE__, __LINE__, @ac_google_namespace@::FATAL) +#define COMPACT_GOOGLE_LOG_DFATAL @ac_google_namespace@::LogMessage( \ + __FILE__, __LINE__, @ac_google_namespace@::GLOG_FATAL) #else #define COMPACT_GOOGLE_LOG_DFATAL @ac_google_namespace@::NullStreamFatal() #endif -#define GOOGLE_LOG_INFO(counter) @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::INFO, counter, &@ac_google_namespace@::LogMessage::SendToLog) +#define GOOGLE_LOG_INFO(counter) @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::GLOG_INFO, counter, &@ac_google_namespace@::LogMessage::SendToLog) #define SYSLOG_INFO(counter) \ - @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::INFO, counter, \ + @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::GLOG_INFO, counter, \ &@ac_google_namespace@::LogMessage::SendToSyslogAndLog) #define GOOGLE_LOG_WARNING(counter) \ - @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::WARNING, counter, \ + @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::GLOG_WARNING, counter, \ &@ac_google_namespace@::LogMessage::SendToLog) #define SYSLOG_WARNING(counter) \ - @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::WARNING, counter, \ + @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::GLOG_WARNING, counter, \ &@ac_google_namespace@::LogMessage::SendToSyslogAndLog) #define GOOGLE_LOG_ERROR(counter) \ - @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::ERROR, counter, \ + @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::GLOG_ERROR, counter, \ &@ac_google_namespace@::LogMessage::SendToLog) #define SYSLOG_ERROR(counter) \ - @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::ERROR, counter, \ + @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::GLOG_ERROR, counter, \ &@ac_google_namespace@::LogMessage::SendToSyslogAndLog) #define GOOGLE_LOG_FATAL(counter) \ - @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::FATAL, counter, \ + @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::GLOG_FATAL, counter, \ &@ac_google_namespace@::LogMessage::SendToLog) #define SYSLOG_FATAL(counter) \ - @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::FATAL, counter, \ + @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::GLOG_FATAL, counter, \ &@ac_google_namespace@::LogMessage::SendToSyslogAndLog) #define GOOGLE_LOG_DFATAL(counter) \ @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::DFATAL_LEVEL, counter, \ @@ -447,15 +480,16 @@ DECLARE_bool(stop_logging_if_full_disk); #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) || defined(__CYGWIN32__) // A very useful logging macro to log windows errors: #define LOG_SYSRESULT(result) \ - if (FAILED(result)) { \ - LPTSTR message = NULL; \ - LPTSTR msg = reinterpret_cast(&message); \ - DWORD message_length = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | \ + if (FAILED(HRESULT_FROM_WIN32(result))) { \ + LPSTR message = NULL; \ + LPSTR msg = reinterpret_cast(&message); \ + DWORD message_length = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | \ FORMAT_MESSAGE_FROM_SYSTEM, \ 0, result, 0, msg, 100, NULL); \ if (message_length > 0) { \ - @ac_google_namespace@::LogMessage(__FILE__, __LINE__, ERROR, 0, \ - &@ac_google_namespace@::LogMessage::SendToLog).stream() << message; \ + @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::GLOG_ERROR, 0, \ + &@ac_google_namespace@::LogMessage::SendToLog).stream() \ + << reinterpret_cast(message); \ LocalFree(message); \ } \ } @@ -482,6 +516,9 @@ DECLARE_bool(stop_logging_if_full_disk); // specified by argv0 in log outputs. GOOGLE_GLOG_DLL_DECL void InitGoogleLogging(const char* argv0); +// Shutdown google's logging library. +GOOGLE_GLOG_DLL_DECL void ShutdownGoogleLogging(); + // Install a function which will be called after LOG(FATAL). GOOGLE_GLOG_DLL_DECL void InstallFailureFunction(void (*fail_func)()); @@ -498,12 +535,12 @@ class LogSink; // defined below #define LOG_TO_SINK(sink, severity) \ @ac_google_namespace@::LogMessage( \ __FILE__, __LINE__, \ - @ac_google_namespace@::severity, \ + @ac_google_namespace@::GLOG_ ## severity, \ static_cast<@ac_google_namespace@::LogSink*>(sink), true).stream() #define LOG_TO_SINK_BUT_NOT_TO_LOGFILE(sink, severity) \ @ac_google_namespace@::LogMessage( \ __FILE__, __LINE__, \ - @ac_google_namespace@::severity, \ + @ac_google_namespace@::GLOG_ ## severity, \ static_cast<@ac_google_namespace@::LogSink*>(sink), false).stream() // If a non-NULL string pointer is given, we write this message to that string. @@ -528,7 +565,7 @@ class LogSink; // defined below // vector *outvec; // The cast is to disambiguate NULL arguments. #define LOG_STRING(severity, outvec) \ - LOG_TO_STRING_##severity(static_cast*>(outvec)).stream() + LOG_TO_STRING_##severity(static_cast*>(outvec)).stream() #define LOG_IF(severity, condition) \ !(condition) ? (void) 0 : @ac_google_namespace@::LogMessageVoidify() & LOG(severity) @@ -541,7 +578,7 @@ class LogSink; // defined below SYSLOG_IF(FATAL, !(condition)) << "Assert failed: " #condition // CHECK dies with a fatal error if condition is not true. It is *not* -// controlled by NDEBUG, so the check will be executed regardless of +// controlled by DCHECK_IS_ON(), so the check will be executed regardless of // compilation mode. Therefore, it is safe to do things like: // CHECK(fp->Write(x) == 4) #define CHECK(condition) \ @@ -594,18 +631,68 @@ inline std::ostream& operator<<( @ac_google_start_namespace@ -// Build the error message string. -template -std::string* MakeCheckOpString(const t1& v1, const t2& v2, const char* names) { - // It means that we cannot use stl_logging if compiler doesn't - // support using expression for operator. - // TODO(hamaji): Figure out a way to fix. -#if @ac_cv_cxx_using_operator@ - using ::operator<<; -#endif - std::strstream ss; - ss << names << " (" << v1 << " vs. " << v2 << ")"; - return new std::string(ss.str(), ss.pcount()); +// This formats a value for a failing CHECK_XX statement. Ordinarily, +// it uses the definition for operator<<, with a few special cases below. +template +inline void MakeCheckOpValueString(std::ostream* os, const T& v) { + (*os) << v; +} + +// Overrides for char types provide readable values for unprintable +// characters. +template <> GOOGLE_GLOG_DLL_DECL +void MakeCheckOpValueString(std::ostream* os, const char& v); +template <> GOOGLE_GLOG_DLL_DECL +void MakeCheckOpValueString(std::ostream* os, const signed char& v); +template <> GOOGLE_GLOG_DLL_DECL +void MakeCheckOpValueString(std::ostream* os, const unsigned char& v); + +// Build the error message string. Specify no inlining for code size. +template +std::string* MakeCheckOpString(const T1& v1, const T2& v2, const char* exprtext) + @ac_cv___attribute___noinline@; + +namespace base { +namespace internal { + +// If "s" is less than base_logging::INFO, returns base_logging::INFO. +// If "s" is greater than base_logging::FATAL, returns +// base_logging::ERROR. Otherwise, returns "s". +LogSeverity NormalizeSeverity(LogSeverity s); + +} // namespace internal + +// A helper class for formatting "expr (V1 vs. V2)" in a CHECK_XX +// statement. See MakeCheckOpString for sample usage. Other +// approaches were considered: use of a template method (e.g., +// base::BuildCheckOpString(exprtext, base::Print, &v1, +// base::Print, &v2), however this approach has complications +// related to volatile arguments and function-pointer arguments). +class GOOGLE_GLOG_DLL_DECL CheckOpMessageBuilder { + public: + // Inserts "exprtext" and " (" to the stream. + explicit CheckOpMessageBuilder(const char *exprtext); + // Deletes "stream_". + ~CheckOpMessageBuilder(); + // For inserting the first variable. + std::ostream* ForVar1() { return stream_; } + // For inserting the second variable (adds an intermediate " vs. "). + std::ostream* ForVar2(); + // Get the result (inserts the closing ")"). + std::string* NewString(); + + private: + std::ostringstream *stream_; +}; + +} // namespace base + +template +std::string* MakeCheckOpString(const T1& v1, const T2& v2, const char* exprtext) { + base::CheckOpMessageBuilder comb(exprtext); + MakeCheckOpValueString(comb.ForVar1(), v1); + MakeCheckOpValueString(comb.ForVar2(), v2); + return comb.NewString(); } // Helper functions for CHECK_OP macro. @@ -613,26 +700,26 @@ std::string* MakeCheckOpString(const t1& v1, const t2& v2, const char* names) { // will not instantiate the template version of the function on values of // unnamed enum type - see comment below. #define DEFINE_CHECK_OP_IMPL(name, op) \ - template \ - inline std::string* Check##name##Impl(const t1& v1, const t2& v2, \ - const char* names) { \ - if (v1 op v2) return NULL; \ - else return MakeCheckOpString(v1, v2, names); \ + template \ + inline std::string* name##Impl(const T1& v1, const T2& v2, \ + const char* exprtext) { \ + if (GOOGLE_PREDICT_TRUE(v1 op v2)) return NULL; \ + else return MakeCheckOpString(v1, v2, exprtext); \ } \ - inline std::string* Check##name##Impl(int v1, int v2, const char* names) { \ - return Check##name##Impl(v1, v2, names); \ + inline std::string* name##Impl(int v1, int v2, const char* exprtext) { \ + return name##Impl(v1, v2, exprtext); \ } -// Use _EQ, _NE, _LE, etc. in case the file including base/logging.h -// provides its own #defines for the simpler names EQ, NE, LE, etc. +// We use the full name Check_EQ, Check_NE, etc. in case the file including +// base/logging.h provides its own #defines for the simpler names EQ, NE, etc. // This happens if, for example, those are used as token names in a // yacc grammar. -DEFINE_CHECK_OP_IMPL(_EQ, ==) -DEFINE_CHECK_OP_IMPL(_NE, !=) -DEFINE_CHECK_OP_IMPL(_LE, <=) -DEFINE_CHECK_OP_IMPL(_LT, < ) -DEFINE_CHECK_OP_IMPL(_GE, >=) -DEFINE_CHECK_OP_IMPL(_GT, > ) +DEFINE_CHECK_OP_IMPL(Check_EQ, ==) // Compilation error with CHECK_EQ(NULL, x)? +DEFINE_CHECK_OP_IMPL(Check_NE, !=) // Use CHECK(x == NULL) instead. +DEFINE_CHECK_OP_IMPL(Check_LE, <=) +DEFINE_CHECK_OP_IMPL(Check_LT, < ) +DEFINE_CHECK_OP_IMPL(Check_GE, >=) +DEFINE_CHECK_OP_IMPL(Check_GT, > ) #undef DEFINE_CHECK_OP_IMPL // Helper macro for binary operators. @@ -641,18 +728,18 @@ DEFINE_CHECK_OP_IMPL(_GT, > ) #if defined(STATIC_ANALYSIS) // Only for static analysis tool to know that it is equivalent to assert #define CHECK_OP_LOG(name, op, val1, val2, log) CHECK((val1) op (val2)) -#elif !defined(NDEBUG) +#elif DCHECK_IS_ON() // In debug mode, avoid constructing CheckOpStrings if possible, // to reduce the overhead of CHECK statments by 2x. // Real DCHECK-heavy tests have seen 1.5x speedups. -// The meaning of "string" might be different between now and +// The meaning of "string" might be different between now and // when this macro gets invoked (e.g., if someone is experimenting // with other string implementations that get defined after this -// file is included). Save the current meaning now and use it +// file is included). Save the current meaning now and use it // in the macro. typedef std::string _Check_string; -#define CHECK_OP_LOG(name, op, val1, val2, log) \ +#define CHECK_OP_LOG(name, op, val1, val2, log) \ while (@ac_google_namespace@::_Check_string* _result = \ @ac_google_namespace@::Check##name##Impl( \ @ac_google_namespace@::GetReferenceableValue(val1), \ @@ -663,13 +750,14 @@ typedef std::string _Check_string; #else // In optimized mode, use CheckOpString to hint to compiler that // the while condition is unlikely. -#define CHECK_OP_LOG(name, op, val1, val2, log) \ - while (@ac_google_namespace@::CheckOpString _result = \ - @ac_google_namespace@::Check##name##Impl(GetReferenceableValue(val1), \ - GetReferenceableValue(val2), \ - #val1 " " #op " " #val2)) \ +#define CHECK_OP_LOG(name, op, val1, val2, log) \ + while (@ac_google_namespace@::CheckOpString _result = \ + @ac_google_namespace@::Check##name##Impl( \ + @ac_google_namespace@::GetReferenceableValue(val1), \ + @ac_google_namespace@::GetReferenceableValue(val2), \ + #val1 " " #op " " #val2)) \ log(__FILE__, __LINE__, _result).stream() -#endif // STATIC_ANALYSIS, !NDEBUG +#endif // STATIC_ANALYSIS, DCHECK_IS_ON() #if GOOGLE_STRIP_LOG <= 3 #define CHECK_OP(name, op, val1, val2) \ @@ -767,7 +855,7 @@ DECLARE_CHECK_STROP_IMPL(strcasecmp, false) #define GOOGLE_PLOG(severity, counter) \ @ac_google_namespace@::ErrnoLogMessage( \ - __FILE__, __LINE__, @ac_google_namespace@::severity, counter, \ + __FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, counter, \ &@ac_google_namespace@::LogMessage::SendToLog) #define PLOG_IF(severity, condition) \ @@ -806,7 +894,7 @@ PLOG_IF(FATAL, GOOGLE_PREDICT_BRANCH_NOT_TAKEN((invocation) == -1)) \ if (++LOG_OCCURRENCES_MOD_N > n) LOG_OCCURRENCES_MOD_N -= n; \ if (LOG_OCCURRENCES_MOD_N == 1) \ @ac_google_namespace@::LogMessage( \ - __FILE__, __LINE__, @ac_google_namespace@::severity, LOG_OCCURRENCES, \ + __FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, LOG_OCCURRENCES, \ &what_to_do).stream() #define SOME_KIND_OF_LOG_IF_EVERY_N(severity, condition, n, what_to_do) \ @@ -815,7 +903,7 @@ PLOG_IF(FATAL, GOOGLE_PREDICT_BRANCH_NOT_TAKEN((invocation) == -1)) \ if (condition && \ ((LOG_OCCURRENCES_MOD_N=(LOG_OCCURRENCES_MOD_N + 1) % n) == (1 % n))) \ @ac_google_namespace@::LogMessage( \ - __FILE__, __LINE__, @ac_google_namespace@::severity, LOG_OCCURRENCES, \ + __FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, LOG_OCCURRENCES, \ &what_to_do).stream() #define SOME_KIND_OF_PLOG_EVERY_N(severity, n, what_to_do) \ @@ -824,7 +912,7 @@ PLOG_IF(FATAL, GOOGLE_PREDICT_BRANCH_NOT_TAKEN((invocation) == -1)) \ if (++LOG_OCCURRENCES_MOD_N > n) LOG_OCCURRENCES_MOD_N -= n; \ if (LOG_OCCURRENCES_MOD_N == 1) \ @ac_google_namespace@::ErrnoLogMessage( \ - __FILE__, __LINE__, @ac_google_namespace@::severity, LOG_OCCURRENCES, \ + __FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, LOG_OCCURRENCES, \ &what_to_do).stream() #define SOME_KIND_OF_LOG_FIRST_N(severity, n, what_to_do) \ @@ -833,7 +921,7 @@ PLOG_IF(FATAL, GOOGLE_PREDICT_BRANCH_NOT_TAKEN((invocation) == -1)) \ ++LOG_OCCURRENCES; \ if (LOG_OCCURRENCES <= n) \ @ac_google_namespace@::LogMessage( \ - __FILE__, __LINE__, @ac_google_namespace@::severity, LOG_OCCURRENCES, \ + __FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, LOG_OCCURRENCES, \ &what_to_do).stream() namespace glog_internal_namespace_ { @@ -841,13 +929,16 @@ template struct CompileAssert { }; struct CrashReason; + +// Returns true if FailureSignalHandler is installed. +bool IsFailureSignalHandlerInstalled(); } // namespace glog_internal_namespace_ #define GOOGLE_GLOG_COMPILE_ASSERT(expr, msg) \ typedef @ac_google_namespace@::glog_internal_namespace_::CompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1] #define LOG_EVERY_N(severity, n) \ - GOOGLE_GLOG_COMPILE_ASSERT(@ac_google_namespace@::severity < \ + GOOGLE_GLOG_COMPILE_ASSERT(@ac_google_namespace@::GLOG_ ## severity < \ @ac_google_namespace@::NUM_SEVERITIES, \ INVALID_REQUESTED_LOG_SEVERITY); \ SOME_KIND_OF_LOG_EVERY_N(severity, (n), @ac_google_namespace@::LogMessage::SendToLog) @@ -867,10 +958,31 @@ struct CrashReason; // We want the special COUNTER value available for LOG_EVERY_X()'ed messages enum PRIVATE_Counter {COUNTER}; +#ifdef GLOG_NO_ABBREVIATED_SEVERITIES +// wingdi.h defines ERROR to be 0. When we call LOG(ERROR), it gets +// substituted with 0, and it expands to COMPACT_GOOGLE_LOG_0. To allow us +// to keep using this syntax, we define this macro to do the same thing +// as COMPACT_GOOGLE_LOG_ERROR. +#define COMPACT_GOOGLE_LOG_0 COMPACT_GOOGLE_LOG_ERROR +#define SYSLOG_0 SYSLOG_ERROR +#define LOG_TO_STRING_0 LOG_TO_STRING_ERROR +// Needed for LOG_IS_ON(ERROR). +const LogSeverity GLOG_0 = GLOG_ERROR; +#else +// Users may include windows.h after logging.h without +// GLOG_NO_ABBREVIATED_SEVERITIES nor WIN32_LEAN_AND_MEAN. +// For this case, we cannot detect if ERROR is defined before users +// actually use ERROR. Let's make an undefined symbol to warn users. +# define GLOG_ERROR_MSG ERROR_macro_is_defined_Define_GLOG_NO_ABBREVIATED_SEVERITIES_before_including_logging_h_See_the_document_for_detail +# define COMPACT_GOOGLE_LOG_0 GLOG_ERROR_MSG +# define SYSLOG_0 GLOG_ERROR_MSG +# define LOG_TO_STRING_0 GLOG_ERROR_MSG +# define GLOG_0 GLOG_ERROR_MSG +#endif // Plus some debug-logging macros that get compiled to nothing for production -#ifndef NDEBUG +#if DCHECK_IS_ON() #define DLOG(severity) LOG(severity) #define DVLOG(verboselevel) VLOG(verboselevel) @@ -880,7 +992,7 @@ enum PRIVATE_Counter {COUNTER}; LOG_IF_EVERY_N(severity, condition, n) #define DLOG_ASSERT(condition) LOG_ASSERT(condition) -// debug-only checking. not executed in NDEBUG mode. +// debug-only checking. executed if DCHECK_IS_ON(). #define DCHECK(condition) CHECK(condition) #define DCHECK_EQ(val1, val2) CHECK_EQ(val1, val2) #define DCHECK_NE(val1, val2) CHECK_NE(val1, val2) @@ -888,12 +1000,13 @@ enum PRIVATE_Counter {COUNTER}; #define DCHECK_LT(val1, val2) CHECK_LT(val1, val2) #define DCHECK_GE(val1, val2) CHECK_GE(val1, val2) #define DCHECK_GT(val1, val2) CHECK_GT(val1, val2) +#define DCHECK_NOTNULL(val) CHECK_NOTNULL(val) #define DCHECK_STREQ(str1, str2) CHECK_STREQ(str1, str2) #define DCHECK_STRCASEEQ(str1, str2) CHECK_STRCASEEQ(str1, str2) #define DCHECK_STRNE(str1, str2) CHECK_STRNE(str1, str2) #define DCHECK_STRCASENE(str1, str2) CHECK_STRCASENE(str1, str2) -#else // NDEBUG +#else // !DCHECK_IS_ON() #define DLOG(severity) \ true ? (void) 0 : @ac_google_namespace@::LogMessageVoidify() & LOG(severity) @@ -914,52 +1027,67 @@ enum PRIVATE_Counter {COUNTER}; #define DLOG_ASSERT(condition) \ true ? (void) 0 : LOG_ASSERT(condition) +// MSVC warning C4127: conditional expression is constant #define DCHECK(condition) \ + GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \ while (false) \ - CHECK(condition) + GLOG_MSVC_POP_WARNING() CHECK(condition) #define DCHECK_EQ(val1, val2) \ + GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \ while (false) \ - CHECK_EQ(val1, val2) + GLOG_MSVC_POP_WARNING() CHECK_EQ(val1, val2) #define DCHECK_NE(val1, val2) \ + GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \ while (false) \ - CHECK_NE(val1, val2) + GLOG_MSVC_POP_WARNING() CHECK_NE(val1, val2) #define DCHECK_LE(val1, val2) \ + GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \ while (false) \ - CHECK_LE(val1, val2) + GLOG_MSVC_POP_WARNING() CHECK_LE(val1, val2) #define DCHECK_LT(val1, val2) \ + GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \ while (false) \ - CHECK_LT(val1, val2) + GLOG_MSVC_POP_WARNING() CHECK_LT(val1, val2) #define DCHECK_GE(val1, val2) \ + GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \ while (false) \ - CHECK_GE(val1, val2) + GLOG_MSVC_POP_WARNING() CHECK_GE(val1, val2) #define DCHECK_GT(val1, val2) \ + GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \ while (false) \ - CHECK_GT(val1, val2) + GLOG_MSVC_POP_WARNING() CHECK_GT(val1, val2) + +// You may see warnings in release mode if you don't use the return +// value of DCHECK_NOTNULL. Please just use DCHECK for such cases. +#define DCHECK_NOTNULL(val) (val) #define DCHECK_STREQ(str1, str2) \ + GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \ while (false) \ - CHECK_STREQ(str1, str2) + GLOG_MSVC_POP_WARNING() CHECK_STREQ(str1, str2) #define DCHECK_STRCASEEQ(str1, str2) \ + GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \ while (false) \ - CHECK_STRCASEEQ(str1, str2) + GLOG_MSVC_POP_WARNING() CHECK_STRCASEEQ(str1, str2) #define DCHECK_STRNE(str1, str2) \ + GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \ while (false) \ - CHECK_STRNE(str1, str2) + GLOG_MSVC_POP_WARNING() CHECK_STRNE(str1, str2) #define DCHECK_STRCASENE(str1, str2) \ + GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \ while (false) \ - CHECK_STRCASENE(str1, str2) - + GLOG_MSVC_POP_WARNING() CHECK_STRCASENE(str1, str2) -#endif // NDEBUG +#endif // DCHECK_IS_ON() // Log only in verbose mode. @@ -974,6 +1102,29 @@ enum PRIVATE_Counter {COUNTER}; #define VLOG_IF_EVERY_N(verboselevel, condition, n) \ LOG_IF_EVERY_N(INFO, (condition) && VLOG_IS_ON(verboselevel), n) +namespace base_logging { + +// LogMessage::LogStream is a std::ostream backed by this streambuf. +// This class ignores overflow and leaves two bytes at the end of the +// buffer to allow for a '\n' and '\0'. +class GOOGLE_GLOG_DLL_DECL LogStreamBuf : public std::streambuf { + public: + // REQUIREMENTS: "len" must be >= 2 to account for the '\n' and '\n'. + LogStreamBuf(char *buf, int len) { + setp(buf, buf + len - 2); + } + // This effectively ignores overflow. + virtual int_type overflow(int_type ch) { + return ch; + } + + // Legacy public ostrstream method. + size_t pcount() const { return pptr() - pbase(); } + char* pbase() const { return std::streambuf::pbase(); } +}; + +} // namespace base_logging + // // This class more or less represents a particular log message. You // create an instance of LogMessage and then stream stuff to it. @@ -1003,22 +1154,32 @@ public: #ifdef _MSC_VER # pragma warning(disable: 4275) #endif - class GOOGLE_GLOG_DLL_DECL LogStream : public std::ostrstream { + class GOOGLE_GLOG_DLL_DECL LogStream : public std::ostream { #ifdef _MSC_VER # pragma warning(default: 4275) #endif public: LogStream(char *buf, int len, int ctr) - : ostrstream(buf, len), - ctr_(ctr) { - self_ = this; + : std::ostream(NULL), + streambuf_(buf, len), + ctr_(ctr), + self_(this) { + rdbuf(&streambuf_); } int ctr() const { return ctr_; } void set_ctr(int ctr) { ctr_ = ctr; } LogStream* self() const { return self_; } + // Legacy std::streambuf methods. + size_t pcount() const { return streambuf_.pcount(); } + char* pbase() const { return streambuf_.pbase(); } + char* str() const { return pbase(); } + private: + LogStream(const LogStream&); + LogStream& operator=(const LogStream&); + base_logging::LogStreamBuf streambuf_; int ctr_; // Counter hack (for the LOG_EVERY_X() macro) LogStream *self_; // Consistency check hack }; @@ -1085,15 +1246,17 @@ public: void SendToSyslogAndLog(); // Actually dispatch to syslog and the logs // Call abort() or similar to perform LOG(FATAL) crash. - static void Fail() @ac_cv___attribute___noreturn@; + static void @ac_cv___attribute___noreturn@ Fail(); - std::ostream& stream() { return *(data_->stream_); } + std::ostream& stream(); - int preserved_errno() const { return data_->preserved_errno_; } + int preserved_errno() const; // Must be called without the log_mutex held. (L < log_mutex) static int64 num_messages(int severity); + struct LogMessageData; + private: // Fully internal SendMethod cases: void SendToSinkAndLog(); // Send to sink if provided and dispatch to the logs @@ -1115,41 +1278,6 @@ private: // We keep the data in a separate struct so that each instance of // LogMessage uses less stack space. - struct GOOGLE_GLOG_DLL_DECL LogMessageData { - LogMessageData() {}; - - int preserved_errno_; // preserved errno - char* buf_; - char* message_text_; // Complete message text (points to selected buffer) - LogStream* stream_alloc_; - LogStream* stream_; - char severity_; // What level is this LogMessage logged at? - int line_; // line number where logging call is. - void (LogMessage::*send_method_)(); // Call this in destructor to send - union { // At most one of these is used: union to keep the size low. - LogSink* sink_; // NULL or sink to send message to - std::vector* outvec_; // NULL or vector to push message onto - std::string* message_; // NULL or string to write message into - }; - time_t timestamp_; // Time of creation of LogMessage - struct ::tm tm_time_; // Time of creation of LogMessage - size_t num_prefix_chars_; // # of chars of prefix in this message - size_t num_chars_to_log_; // # of chars of msg to send to log - size_t num_chars_to_syslog_; // # of chars of msg to send to syslog - const char* basename_; // basename of file that called LOG - const char* fullname_; // fullname of file that called LOG - bool has_been_flushed_; // false => data has not been flushed - bool first_fatal_; // true => this was first fatal msg - - ~LogMessageData(); - private: - LogMessageData(const LogMessageData&); - void operator=(const LogMessageData&); - }; - - static LogMessageData fatal_msg_data_exclusive_; - static LogMessageData fatal_msg_data_shared_; - LogMessageData* allocated_; LogMessageData* data_; @@ -1166,7 +1294,7 @@ class GOOGLE_GLOG_DLL_DECL LogMessageFatal : public LogMessage { public: LogMessageFatal(const char* file, int line); LogMessageFatal(const char* file, int line, const CheckOpString& result); - ~LogMessageFatal() @ac_cv___attribute___noreturn@; + @ac_cv___attribute___noreturn@ ~LogMessageFatal(); }; // A non-macro interface to the log facility; (useful @@ -1179,7 +1307,36 @@ inline void LogAtLevel(int const severity, std::string const &msg) { // version since there are two advantages: 1. this version outputs the // file name and the line number where this macro is put like other // LOG macros, 2. this macro can be used as C++ stream. -#define LOG_AT_LEVEL(severity) LogMessage(__FILE__, __LINE__, severity).stream() +#define LOG_AT_LEVEL(severity) @ac_google_namespace@::LogMessage(__FILE__, __LINE__, severity).stream() + +// Check if it's compiled in C++11 mode. +// +// GXX_EXPERIMENTAL_CXX0X is defined by gcc and clang up to at least +// gcc-4.7 and clang-3.1 (2011-12-13). __cplusplus was defined to 1 +// in gcc before 4.7 (Crosstool 16) and clang before 3.1, but is +// defined according to the language version in effect thereafter. +// Microsoft Visual Studio 14 (2015) sets __cplusplus==199711 despite +// reasonably good C++11 support, so we set LANG_CXX for it and +// newer versions (_MSC_VER >= 1900). +#if (defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L || \ + (defined(_MSC_VER) && _MSC_VER >= 1900)) +// Helper for CHECK_NOTNULL(). +// +// In C++11, all cases can be handled by a single function. Since the value +// category of the argument is preserved (also for rvalue references), +// member initializer lists like the one below will compile correctly: +// +// Foo() +// : x_(CHECK_NOTNULL(MethodReturningUniquePtr())) {} +template +T CheckNotNull(const char* file, int line, const char* names, T&& t) { + if (t == nullptr) { + LogMessageFatal(file, line, new std::string(names)); + } + return std::forward(t); +} + +#else // A small helper for CHECK_NOTNULL(). template @@ -1189,6 +1346,7 @@ T* CheckNotNull(const char *file, int line, const char *names, T* t) { } return t; } +#endif // Allow folks to put a counter in the LOG_EVERY_X()'ed messages. This // only works if ostream is a LogStream. If the ostream is not a @@ -1428,8 +1586,12 @@ extern GOOGLE_GLOG_DLL_DECL void SetLogger(LogSeverity level, Logger* logger); // be set to an empty string, if this function failed. This means, in most // cases, you do not need to check the error code and you can directly // use the value of "buf". It will never have an undefined value. +// DEPRECATED: Use StrError(int) instead. GOOGLE_GLOG_DLL_DECL int posix_strerror_r(int err, char *buf, size_t len); +// A thread-safe replacement for strerror(). Returns a string describing the +// given POSIX error code. +GOOGLE_GLOG_DLL_DECL std::string StrError(int err); // A class for which we define operator<<, which does nothing. class GOOGLE_GLOG_DLL_DECL NullStream : public LogMessage::LogStream { @@ -1457,7 +1619,7 @@ class GOOGLE_GLOG_DLL_DECL NullStream : public LogMessage::LogStream { // converted to LogStream and the message will be computed and then // quietly discarded. template -inline NullStream& operator<<(NullStream &str, const T &value) { return str; } +inline NullStream& operator<<(NullStream &str, const T &) { return str; } // Similar to NullStream, but aborts the program (without stack // trace), like LogMessageFatal. @@ -1466,7 +1628,7 @@ class GOOGLE_GLOG_DLL_DECL NullStreamFatal : public NullStream { NullStreamFatal() { } NullStreamFatal(const char* file, int line, const CheckOpString& result) : NullStream(file, line, result) { } - @ac_cv___attribute___noreturn@ ~NullStreamFatal() { _exit(1); } + @ac_cv___attribute___noreturn@ ~NullStreamFatal() throw () { _exit(1); } }; // Install a signal handler that will dump signal information and a stack