|  | // Copyright 2016 The Bazel Authors. All rights reserved. | 
|  | // | 
|  | // Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | // you may not use this file except in compliance with the License. | 
|  | // You may obtain a copy of the License at | 
|  | // | 
|  | //    http://www.apache.org/licenses/LICENSE-2.0 | 
|  | // | 
|  | // Unless required by applicable law or agreed to in writing, software | 
|  | // distributed under the License is distributed on an "AS IS" BASIS, | 
|  | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | // See the License for the specific language governing permissions and | 
|  | // limitations under the License. | 
|  | #ifndef BAZEL_SRC_MAIN_CPP_LOGGING_H_ | 
|  | #define BAZEL_SRC_MAIN_CPP_LOGGING_H_ | 
|  |  | 
|  | #include <memory> | 
|  | #include <sstream> | 
|  | #include <string> | 
|  |  | 
|  | // This file is based off the logging work by the protobuf team in | 
|  | // stubs/logging.h, | 
|  | // | 
|  | // Users of this logging library should use BAZEL_LOG(level) << ""; format, | 
|  | // and specify how they wish to handle the output of the log messages by | 
|  | // creating a LogHandler to pass to SetLogHandler(). | 
|  | namespace blaze_util { | 
|  |  | 
|  | enum LogLevel { | 
|  | LOGLEVEL_INFO, | 
|  | LOGLEVEL_USER, | 
|  | LOGLEVEL_WARNING, | 
|  | LOGLEVEL_ERROR, | 
|  | LOGLEVEL_FATAL, | 
|  |  | 
|  | #ifdef NDEBUG | 
|  | LOGLEVEL_DFATAL = LOGLEVEL_ERROR | 
|  | #else | 
|  | LOGLEVEL_DFATAL = LOGLEVEL_FATAL | 
|  | #endif | 
|  | }; | 
|  |  | 
|  | // Returns a string representation of the log level. | 
|  | const char* LogLevelName(LogLevel level); | 
|  |  | 
|  | namespace internal { | 
|  |  | 
|  | class LogFinisher; | 
|  | class LogMessage { | 
|  | public: | 
|  | LogMessage(LogLevel level, const std::string& filename, int line); | 
|  | LogMessage(LogLevel level, const std::string& filename, int line, | 
|  | int exit_code); | 
|  |  | 
|  | LogMessage& operator<<(const std::string& value); | 
|  | LogMessage& operator<<(const std::wstring& wstr); | 
|  | LogMessage& operator<<(const char* value); | 
|  | LogMessage& operator<<(char value); | 
|  | LogMessage& operator<<(bool value); | 
|  | LogMessage& operator<<(short value); | 
|  | LogMessage& operator<<(int value); | 
|  | LogMessage& operator<<(unsigned int value); | 
|  | LogMessage& operator<<(long value); | 
|  | LogMessage& operator<<(unsigned long value); | 
|  | LogMessage& operator<<(long long value); | 
|  | LogMessage& operator<<(unsigned long long value); | 
|  | LogMessage& operator<<(float value); | 
|  | LogMessage& operator<<(double value); | 
|  | LogMessage& operator<<(long double value); | 
|  | LogMessage& operator<<(void* value); | 
|  |  | 
|  | private: | 
|  | friend class LogFinisher; | 
|  | void Finish(); | 
|  |  | 
|  | const LogLevel level_; | 
|  | const std::string& filename_; | 
|  | const int line_; | 
|  | // Only used for FATAL log messages. | 
|  | const int exit_code_; | 
|  | std::stringstream message_; | 
|  | }; | 
|  |  | 
|  | // Used to make the entire "LOG(BLAH) << etc." expression have a void return | 
|  | // type and print a newline after each message. | 
|  | class LogFinisher { | 
|  | public: | 
|  | void operator=(LogMessage& other); | 
|  | }; | 
|  |  | 
|  | template <typename T> | 
|  | bool IsOk(T status) { | 
|  | return status.ok(); | 
|  | } | 
|  | template <> | 
|  | inline bool IsOk(bool status) { | 
|  | return status; | 
|  | } | 
|  |  | 
|  | }  // namespace internal | 
|  |  | 
|  | #define BAZEL_LOG(LEVEL)                                                      \ | 
|  | ::blaze_util::internal::LogFinisher() = ::blaze_util::internal::LogMessage( \ | 
|  | ::blaze_util::LOGLEVEL_##LEVEL, __FILE__, __LINE__) | 
|  | #define BAZEL_LOG_IF(LEVEL, CONDITION) !(CONDITION) ? (void)0 : BAZEL_LOG(LEVEL) | 
|  | #define BAZEL_DIE(EXIT_CODE)                                                  \ | 
|  | ::blaze_util::internal::LogFinisher() = ::blaze_util::internal::LogMessage( \ | 
|  | ::blaze_util::LOGLEVEL_FATAL, __FILE__, __LINE__, EXIT_CODE) | 
|  |  | 
|  | #define BAZEL_CHECK(EXPRESSION) \ | 
|  | BAZEL_LOG_IF(FATAL, !(EXPRESSION)) << "CHECK failed: " #EXPRESSION ": " | 
|  | #define BAZEL_CHECK_OK(A) BAZEL_CHECK(::blaze_util::internal::IsOk(A)) | 
|  | #define BAZEL_CHECK_EQ(A, B) BAZEL_CHECK((A) == (B)) | 
|  | #define BAZEL_CHECK_NE(A, B) BAZEL_CHECK((A) != (B)) | 
|  | #define BAZEL_CHECK_LT(A, B) BAZEL_CHECK((A) < (B)) | 
|  | #define BAZEL_CHECK_LE(A, B) BAZEL_CHECK((A) <= (B)) | 
|  | #define BAZEL_CHECK_GT(A, B) BAZEL_CHECK((A) > (B)) | 
|  | #define BAZEL_CHECK_GE(A, B) BAZEL_CHECK((A) >= (B)) | 
|  |  | 
|  | #ifdef NDEBUG | 
|  |  | 
|  | #define BAZEL_DLOG(LEVEL) BAZEL_LOG_IF(LEVEL, false) | 
|  |  | 
|  | #define BAZEL_DCHECK(EXPRESSION) \ | 
|  | while (false) BAZEL_CHECK(EXPRESSION) | 
|  | #define BAZEL_DCHECK_OK(E) BAZEL_DCHECK(::blaze::internal::IsOk(E)) | 
|  | #define BAZEL_DCHECK_EQ(A, B) BAZEL_DCHECK((A) == (B)) | 
|  | #define BAZEL_DCHECK_NE(A, B) BAZEL_DCHECK((A) != (B)) | 
|  | #define BAZEL_DCHECK_LT(A, B) BAZEL_DCHECK((A) < (B)) | 
|  | #define BAZEL_DCHECK_LE(A, B) BAZEL_DCHECK((A) <= (B)) | 
|  | #define BAZEL_DCHECK_GT(A, B) BAZEL_DCHECK((A) > (B)) | 
|  | #define BAZEL_DCHECK_GE(A, B) BAZEL_DCHECK((A) >= (B)) | 
|  |  | 
|  | #else  // NDEBUG | 
|  |  | 
|  | #define BAZEL_DLOG BAZEL_LOG | 
|  |  | 
|  | #define BAZEL_DCHECK BAZEL_CHECK | 
|  | #define BAZEL_DCHECK_OK BAZEL_CHECK_OK | 
|  | #define BAZEL_DCHECK_EQ BAZEL_CHECK_EQ | 
|  | #define BAZEL_DCHECK_NE BAZEL_CHECK_NE | 
|  | #define BAZEL_DCHECK_LT BAZEL_CHECK_LT | 
|  | #define BAZEL_DCHECK_LE BAZEL_CHECK_LE | 
|  | #define BAZEL_DCHECK_GT BAZEL_CHECK_GT | 
|  | #define BAZEL_DCHECK_GE BAZEL_CHECK_GE | 
|  |  | 
|  | #endif  // !NDEBUG | 
|  |  | 
|  | class LogHandler { | 
|  | public: | 
|  | virtual ~LogHandler() {} | 
|  | virtual void HandleMessage(LogLevel level, const std::string& filename, | 
|  | int line, const std::string& message, | 
|  | int exit_code) = 0; | 
|  |  | 
|  | virtual void SetOutputStream(std::unique_ptr<std::ostream> output_stream) = 0; | 
|  | virtual void SetOutputStreamToStderr() = 0; | 
|  | }; | 
|  |  | 
|  | // Sets the log handler that routes all log messages. | 
|  | // SetLogHandler is not thread-safe.  You should only call it | 
|  | // at initialization time, and probably not from library code. | 
|  | void SetLogHandler(std::unique_ptr<LogHandler> new_handler); | 
|  |  | 
|  | // Set the stream to which all log statements will be sent. | 
|  | void SetLoggingOutputStream(std::unique_ptr<std::ostream> output_stream); | 
|  | void SetLoggingOutputStreamToStderr(); | 
|  |  | 
|  | }  // namespace blaze_util | 
|  |  | 
|  | #endif  // BAZEL_SRC_MAIN_CPP_LOGGING_H_ |