| // Copyright 2015 The Cobalt 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. |
| |
| // Module Overview: Starboard Logging module |
| // |
| // Implements a set of convenience functions and macros built on top of the core |
| // Starboard logging API. |
| |
| #ifndef STARBOARD_COMMON_LOG_H_ |
| #define STARBOARD_COMMON_LOG_H_ |
| |
| #include "starboard/configuration.h" |
| #include "starboard/log.h" |
| #include "starboard/system.h" |
| |
| #ifdef __cplusplus |
| |
| extern "C++" { |
| |
| #include <sstream> |
| #include <string> |
| |
| #if defined(COBALT_BUILD_TYPE_GOLD) |
| #define SB_LOGGING_IS_OFFICIAL_BUILD 1 |
| #else |
| #define SB_LOGGING_IS_OFFICIAL_BUILD 0 |
| #endif |
| |
| // This file provides a selected subset of the //base/logging/ macros and |
| // assertions. See those files for more comments and details. |
| |
| namespace starboard { |
| namespace logging { |
| |
| void SetMinLogLevel(SbLogPriority level); |
| SbLogPriority GetMinLogLevel(); |
| SbLogPriority StringToLogLevel(const std::string& log_level); |
| void Break(); |
| |
| // An object which will dumps the stack to the given ostream, without adding any |
| // frames of its own. |skip_frames| is the number of frames to skip in the dump. |
| struct Stack { |
| explicit Stack(int skip_frames); |
| int skip_frames; |
| }; |
| std::ostream& operator<<(std::ostream& out, const Stack& stack); |
| |
| std::ostream& operator<<(std::ostream& out, const wchar_t* wstr); |
| std::ostream& operator<<(std::ostream& out, const std::wstring& wstr); |
| |
| #if defined(__cplusplus_winrt) |
| inline std::ostream& operator<<(std::ostream& out, ::Platform::String ^ str); |
| #endif |
| |
| const SbLogPriority SB_LOG_INFO = kSbLogPriorityInfo; |
| const SbLogPriority SB_LOG_WARNING = kSbLogPriorityWarning; |
| const SbLogPriority SB_LOG_ERROR = kSbLogPriorityError; |
| const SbLogPriority SB_LOG_FATAL = kSbLogPriorityFatal; |
| const SbLogPriority SB_LOG_0 = SB_LOG_ERROR; |
| |
| // TODO: Export this, e.g. by wrapping in straight-C functions which can then be |
| // SB_EXPORT'd. Using SB_EXPORT here directly causes issues on Windows because |
| // it uses std classes which also need to be exported. |
| class LogMessage { |
| public: |
| LogMessage(const char* file, int line, SbLogPriority priority); |
| ~LogMessage(); |
| |
| std::ostream& stream(); |
| |
| private: |
| void Init(const char* file, int line); |
| |
| SbLogPriority priority_; |
| std::ostringstream stream_; |
| size_t message_start_; // Offset of the start of the message (past prefix |
| // info). |
| // The file and line information passed in to the constructor. |
| const char* file_; |
| const int line_; |
| }; |
| |
| class LogMessageVoidify { |
| public: |
| LogMessageVoidify(); |
| // This has to be an operator with a precedence lower than << but |
| // higher than ?: |
| void operator&(std::ostream&); |
| }; |
| |
| } // namespace logging |
| } // namespace starboard |
| |
| #define SB_LOG_MESSAGE_INFO \ |
| ::starboard::logging::LogMessage(__FILE__, __LINE__, \ |
| ::starboard::logging::SB_LOG_INFO) |
| #define SB_LOG_MESSAGE_WARNING \ |
| ::starboard::logging::LogMessage(__FILE__, __LINE__, \ |
| ::starboard::logging::SB_LOG_WARNING) |
| #define SB_LOG_MESSAGE_ERROR \ |
| ::starboard::logging::LogMessage(__FILE__, __LINE__, \ |
| ::starboard::logging::SB_LOG_ERROR) |
| #define SB_LOG_MESSAGE_FATAL \ |
| ::starboard::logging::LogMessage(__FILE__, __LINE__, \ |
| ::starboard::logging::SB_LOG_FATAL) |
| |
| // Compatibility with base/logging.h which defines ERROR to be 0 to workaround |
| // some system header defines that do the same thing. |
| #define SB_LOG_MESSAGE_0 SB_LOG_MESSAGE_ERROR |
| |
| #define SB_LOG_STREAM(severity) SB_LOG_MESSAGE_##severity.stream() |
| #define SB_LAZY_STREAM(stream, condition) \ |
| !(condition) ? (void)0 : ::starboard::logging::LogMessageVoidify() & (stream) |
| |
| #if SB_LOGGING_IS_OFFICIAL_BUILD && !SB_IS(MODULAR) && \ |
| !SB_IS(EVERGREEN_COMPATIBLE) |
| #define SB_LOG_IS_ON(severity) \ |
| ((::starboard::logging::SB_LOG_##severity >= \ |
| ::starboard::logging::SB_LOG_FATAL) \ |
| ? ((::starboard::logging::SB_LOG_##severity) >= \ |
| ::starboard::logging::GetMinLogLevel()) \ |
| : false) |
| #else // SB_LOGGING_IS_OFFICIAL_BUILD |
| #define SB_LOG_IS_ON(severity) \ |
| ((::starboard::logging::SB_LOG_##severity) >= \ |
| ::starboard::logging::GetMinLogLevel()) |
| #endif // SB_LOGGING_IS_OFFICIAL_BUILD |
| |
| #define SB_LOG_IF(severity, condition) \ |
| SB_LAZY_STREAM(SB_LOG_STREAM(severity), SB_LOG_IS_ON(severity) && (condition)) |
| #define SB_LOG(severity) SB_LOG_IF(severity, true) |
| #define SB_EAT_STREAM_PARAMETERS SB_LOG_IF(INFO, false) |
| #define SB_STACK_IF(severity, condition) \ |
| SB_LOG_IF(severity, condition) << "\n" << ::starboard::logging::Stack(0) |
| #define SB_STACK(severity) SB_STACK_IF(severity, true) |
| |
| #if SB_LOGGING_IS_OFFICIAL_BUILD |
| #define SB_CHECK(condition) \ |
| !(condition) ? ::starboard::logging::Break() : SB_EAT_STREAM_PARAMETERS |
| #elif defined(_PREFAST_) |
| #define SB_CHECK(condition) \ |
| __analysis_assume(condition), SB_EAT_STREAM_PARAMETERS |
| #else |
| #define SB_CHECK(condition) \ |
| SB_LOG_IF(FATAL, !(condition)) << "Check failed: " #condition ". " |
| #endif // SB_LOGGING_IS_OFFICIAL_BUILD |
| |
| #if SB_LOGGING_IS_OFFICIAL_BUILD || \ |
| (defined(NDEBUG) && !defined(COBALT_LOGGING_ENABLED)) |
| #define SB_DLOG_IS_ON(severity) false |
| #define SB_DLOG_IF(severity, condition) SB_EAT_STREAM_PARAMETERS |
| #else |
| #define SB_DLOG_IS_ON(severity) SB_LOG_IS_ON(severity) |
| #define SB_DLOG_IF(severity, condition) SB_LOG_IF(severity, condition) |
| #endif |
| |
| #if SB_LOGGING_IS_OFFICIAL_BUILD || \ |
| (defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)) |
| #define SB_DCHECK(condition) SB_EAT_STREAM_PARAMETERS |
| #define SB_DCHECK_ENABLED 0 |
| #else |
| #define SB_DCHECK(condition) SB_CHECK(condition) |
| #define SB_DCHECK_ENABLED 1 |
| #endif |
| |
| #define SB_DLOG(severity) SB_DLOG_IF(severity, SB_DLOG_IS_ON(severity)) |
| #define SB_DSTACK(severity) SB_STACK_IF(severity, SB_DLOG_IS_ON(severity)) |
| #define SB_NOTREACHED() SB_DCHECK(false) |
| |
| #define SB_NOTIMPLEMENTED_MSG "Not implemented reached in " << SB_FUNCTION |
| |
| #if !defined(SB_NOTIMPLEMENTED_POLICY) |
| #if SB_LOGGING_IS_OFFICIAL_BUILD |
| #define SB_NOTIMPLEMENTED_POLICY 0 |
| #else |
| #define SB_NOTIMPLEMENTED_POLICY 5 |
| #endif |
| #endif // !defined(SB_NOTIMPLEMENTED_POLICY) |
| |
| #if SB_NOTIMPLEMENTED_POLICY == 0 |
| #define SB_NOTIMPLEMENTED() SB_EAT_STREAM_PARAMETERS |
| #elif SB_NOTIMPLEMENTED_POLICY == 1 |
| #define SB_NOTIMPLEMENTED() SB_COMPILE_ASSERT(false, NOT_IMPLEMENTED) |
| #elif SB_NOTIMPLEMENTED_POLICY == 2 |
| #define SB_NOTIMPLEMENTED() SB_COMPILE_ASSERT(false, NOT_IMPLEMENTED) |
| #elif SB_NOTIMPLEMENTED_POLICY == 3 |
| #define SB_NOTIMPLEMENTED() SB_NOTREACHED() |
| #elif SB_NOTIMPLEMENTED_POLICY == 4 |
| #define SB_NOTIMPLEMENTED() SB_LOG(ERROR) << SB_NOTIMPLEMENTED_MSG |
| #elif SB_NOTIMPLEMENTED_POLICY == 5 |
| #define SB_NOTIMPLEMENTED() \ |
| do { \ |
| static int count = 0; \ |
| SB_LOG_IF(ERROR, 0 == count++) << SB_NOTIMPLEMENTED_MSG; \ |
| } while (0); \ |
| SB_EAT_STREAM_PARAMETERS |
| #endif |
| |
| } // extern "C++" |
| |
| #else // !__cplusplus |
| |
| // Provide a very small subset for straight-C users. |
| #define SB_NOTIMPLEMENTED_IN(X) "Not implemented reached in " #X |
| #define SB_NOTIMPLEMENTED_MSG SB_NOTIMPLEMENTED_IN(SB_FUNCTION) |
| |
| #define SB_CHECK(condition) \ |
| do { \ |
| if (!(condition)) { \ |
| SbLog(kSbLogPriorityError, "Check failed: " #condition "."); \ |
| SbSystemBreakIntoDebugger(); \ |
| } \ |
| } while (0) |
| |
| #if SB_LOGGING_IS_OFFICIAL_BUILD |
| #define SB_NOTIMPLEMENTED() |
| #define SB_DCHECK(condition) |
| #define SB_DCHECK_ENABLED 0 |
| #else |
| #define SB_DCHECK(condition) SB_CHECK(condition) |
| #define SB_DCHECK_ENABLED 1 |
| #define SB_NOTIMPLEMENTED() \ |
| do { \ |
| static int count = 0; \ |
| if (0 == count++) { \ |
| SbLog(kSbLogPriorityError, SB_NOTIMPLEMENTED_MSG); \ |
| } \ |
| } while (0) |
| #endif |
| |
| #define SB_NOTREACHED() SB_DCHECK(false) |
| #endif // __cplusplus |
| |
| #endif // STARBOARD_COMMON_LOG_H_ |