1// Ceres Solver - A fast non-linear least squares minimizer 2// Copyright 2013 Google Inc. All rights reserved. 3// http://code.google.com/p/ceres-solver/ 4// 5// Redistribution and use in source and binary forms, with or without 6// modification, are permitted provided that the following conditions are met: 7// 8// * Redistributions of source code must retain the above copyright notice, 9// this list of conditions and the following disclaimer. 10// * Redistributions in binary form must reproduce the above copyright notice, 11// this list of conditions and the following disclaimer in the documentation 12// and/or other materials provided with the distribution. 13// * Neither the name of Google Inc. nor the names of its contributors may be 14// used to endorse or promote products derived from this software without 15// specific prior written permission. 16// 17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27// POSSIBILITY OF SUCH DAMAGE. 28// 29// Author: settinger@google.com (Scott Ettinger) 30// mierle@gmail.com (Keir Mierle) 31// 32// Simplified Glog style logging with Android support. Supported macros in 33// decreasing severity level per line: 34// 35// VLOG(2), VLOG(N) 36// VLOG(1), 37// LOG(INFO), VLOG(0), LG 38// LOG(WARNING), 39// LOG(ERROR), 40// LOG(FATAL), 41// 42// With VLOG(n), the output is directed to one of the 5 Android log levels: 43// 44// 2 - Verbose 45// 1 - Debug 46// 0 - Info 47// -1 - Warning 48// -2 - Error 49// -3 - Fatal 50// 51// Any logging of level 2 and above is directed to the Verbose level. All 52// Android log output is tagged with the string "native". 53// 54// If the symbol ANDROID is not defined, all output goes to std::cerr. 55// This allows code to be built on a different system for debug. 56// 57// Portions of this code are taken from the GLOG package. This code is only a 58// small subset of the GLOG functionality. Notable differences from GLOG 59// behavior include lack of support for displaying unprintable characters and 60// lack of stack trace information upon failure of the CHECK macros. On 61// non-Android systems, log output goes to std::cerr and is not written to a 62// file. 63// 64// CHECK macros are defined to test for conditions within code. Any CHECK that 65// fails will log the failure and terminate the application. 66// e.g. CHECK_GE(3, 2) will pass while CHECK_GE(3, 4) will fail after logging 67// "Check failed 3 >= 4". 68// 69// The following CHECK macros are defined: 70// 71// CHECK(condition) - fails if condition is false and logs condition. 72// CHECK_NOTNULL(variable) - fails if the variable is NULL. 73// 74// The following binary check macros are also defined : 75// 76// Macro Operator equivalent 77// -------------------- ------------------- 78// CHECK_EQ(val1, val2) val1 == val2 79// CHECK_NE(val1, val2) val1 != val2 80// CHECK_GT(val1, val2) val1 > val2 81// CHECK_GE(val1, val2) val1 >= val2 82// CHECK_LT(val1, val2) val1 < val2 83// CHECK_LE(val1, val2) val1 <= val2 84// 85// Debug only versions of all of the check macros are also defined. These 86// macros generate no code in a release build, but avoid unused variable 87// warnings / errors. 88// 89// To use the debug only versions, prepend a D to the normal check macros, e.g. 90// DCHECK_EQ(a, b). 91 92#ifndef CERCES_INTERNAL_MINIGLOG_GLOG_LOGGING_H_ 93#define CERCES_INTERNAL_MINIGLOG_GLOG_LOGGING_H_ 94 95#ifdef ANDROID 96# include <android/log.h> 97#endif // ANDROID 98 99#include <algorithm> 100#include <ctime> 101#include <fstream> 102#include <iostream> 103#include <set> 104#include <sstream> 105#include <string> 106#include <vector> 107 108// For appropriate definition of CERES_EXPORT macro. 109#include "ceres/internal/port.h" 110#include "ceres/internal/disable_warnings.h" 111 112// Log severity level constants. 113const int FATAL = -3; 114const int ERROR = -2; 115const int WARNING = -1; 116const int INFO = 0; 117 118// ------------------------- Glog compatibility ------------------------------ 119 120namespace google { 121 122typedef int LogSeverity; 123const int INFO = ::INFO; 124const int WARNING = ::WARNING; 125const int ERROR = ::ERROR; 126const int FATAL = ::FATAL; 127 128// Sink class used for integration with mock and test functions. If sinks are 129// added, all log output is also sent to each sink through the send function. 130// In this implementation, WaitTillSent() is called immediately after the send. 131// This implementation is not thread safe. 132class CERES_EXPORT LogSink { 133 public: 134 virtual ~LogSink() {} 135 virtual void send(LogSeverity severity, 136 const char* full_filename, 137 const char* base_filename, 138 int line, 139 const struct tm* tm_time, 140 const char* message, 141 size_t message_len) = 0; 142 virtual void WaitTillSent() = 0; 143}; 144 145// Global set of log sinks. The actual object is defined in logging.cc. 146extern CERES_EXPORT std::set<LogSink *> log_sinks_global; 147 148inline void InitGoogleLogging(char *argv) { 149 // Do nothing; this is ignored. 150} 151 152// Note: the Log sink functions are not thread safe. 153inline void AddLogSink(LogSink *sink) { 154 // TODO(settinger): Add locks for thread safety. 155 log_sinks_global.insert(sink); 156} 157inline void RemoveLogSink(LogSink *sink) { 158 log_sinks_global.erase(sink); 159} 160 161} // namespace google 162 163// ---------------------------- Logger Class -------------------------------- 164 165// Class created for each use of the logging macros. 166// The logger acts as a stream and routes the final stream contents to the 167// Android logcat output at the proper filter level. If ANDROID is not 168// defined, output is directed to std::cerr. This class should not 169// be directly instantiated in code, rather it should be invoked through the 170// use of the log macros LG, LOG, or VLOG. 171class CERES_EXPORT MessageLogger { 172 public: 173 MessageLogger(const char *file, int line, const char *tag, int severity) 174 : file_(file), line_(line), tag_(tag), severity_(severity) { 175 // Pre-pend the stream with the file and line number. 176 StripBasename(std::string(file), &filename_only_); 177 stream_ << filename_only_ << ":" << line << " "; 178 } 179 180 // Output the contents of the stream to the proper channel on destruction. 181 ~MessageLogger() { 182 stream_ << "\n"; 183 184#ifdef ANDROID 185 static const int android_log_levels[] = { 186 ANDROID_LOG_FATAL, // LOG(FATAL) 187 ANDROID_LOG_ERROR, // LOG(ERROR) 188 ANDROID_LOG_WARN, // LOG(WARNING) 189 ANDROID_LOG_INFO, // LOG(INFO), LG, VLOG(0) 190 ANDROID_LOG_DEBUG, // VLOG(1) 191 ANDROID_LOG_VERBOSE, // VLOG(2) .. VLOG(N) 192 }; 193 194 // Bound the logging level. 195 const int kMaxVerboseLevel = 2; 196 int android_level_index = std::min(std::max(FATAL, severity_), 197 kMaxVerboseLevel) - FATAL; 198 int android_log_level = android_log_levels[android_level_index]; 199 200 // Output the log string the Android log at the appropriate level. 201 __android_log_write(android_log_level, tag_.c_str(), stream_.str().c_str()); 202 203 // Indicate termination if needed. 204 if (severity_ == FATAL) { 205 __android_log_write(ANDROID_LOG_FATAL, 206 tag_.c_str(), 207 "terminating.\n"); 208 } 209#else 210 // If not building on Android, log all output to std::cerr. 211 std::cerr << stream_.str(); 212#endif // ANDROID 213 214 LogToSinks(severity_); 215 WaitForSinks(); 216 217 // Android logging at level FATAL does not terminate execution, so abort() 218 // is still required to stop the program. 219 if (severity_ == FATAL) { 220 abort(); 221 } 222 } 223 224 // Return the stream associated with the logger object. 225 std::stringstream &stream() { return stream_; } 226 227 private: 228 void LogToSinks(int severity) { 229 time_t rawtime; 230 time (&rawtime); 231 232 struct tm* timeinfo; 233#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) 234 // On Windows, use secure localtime_s not localtime. 235 struct tm windows_timeinfo; 236 timeinfo = &windows_timeinfo; 237 localtime_s(timeinfo, &rawtime); 238#else 239 timeinfo = localtime(&rawtime); 240#endif 241 242 std::set<google::LogSink*>::iterator iter; 243 // Send the log message to all sinks. 244 for (iter = google::log_sinks_global.begin(); 245 iter != google::log_sinks_global.end(); ++iter) { 246 (*iter)->send(severity, file_.c_str(), filename_only_.c_str(), line_, 247 timeinfo, stream_.str().c_str(), stream_.str().size()); 248 } 249 } 250 251 void WaitForSinks() { 252 // TODO(settinger): Add locks for thread safety. 253 std::set<google::LogSink *>::iterator iter; 254 255 // Call WaitTillSent() for all sinks. 256 for (iter = google::log_sinks_global.begin(); 257 iter != google::log_sinks_global.end(); ++iter) { 258 (*iter)->WaitTillSent(); 259 } 260 } 261 262 void StripBasename(const std::string &full_path, std::string *filename) { 263 // TODO(settinger): Add support for OSs with different path separators. 264 const char kSeparator = '/'; 265 size_t pos = full_path.rfind(kSeparator); 266 if (pos != std::string::npos) { 267 *filename = full_path.substr(pos + 1, std::string::npos); 268 } else { 269 *filename = full_path; 270 } 271 } 272 273 std::string file_; 274 std::string filename_only_; 275 int line_; 276 std::string tag_; 277 std::stringstream stream_; 278 int severity_; 279}; 280 281// ---------------------- Logging Macro definitions -------------------------- 282 283// This class is used to explicitly ignore values in the conditional 284// logging macros. This avoids compiler warnings like "value computed 285// is not used" and "statement has no effect". 286class CERES_EXPORT LoggerVoidify { 287 public: 288 LoggerVoidify() { } 289 // This has to be an operator with a precedence lower than << but 290 // higher than ?: 291 void operator&(const std::ostream &s) { } 292}; 293 294// Log only if condition is met. Otherwise evaluates to void. 295#define LOG_IF(severity, condition) \ 296 !(condition) ? (void) 0 : LoggerVoidify() & \ 297 MessageLogger((char *)__FILE__, __LINE__, "native", severity).stream() 298 299// Log only if condition is NOT met. Otherwise evaluates to void. 300#define LOG_IF_FALSE(severity, condition) LOG_IF(severity, !(condition)) 301 302// LG is a convenient shortcut for LOG(INFO). Its use is in new 303// google3 code is discouraged and the following shortcut exists for 304// backward compatibility with existing code. 305#ifdef MAX_LOG_LEVEL 306# define LOG(n) LOG_IF(n, n <= MAX_LOG_LEVEL) 307# define VLOG(n) LOG_IF(n, n <= MAX_LOG_LEVEL) 308# define LG LOG_IF(INFO, INFO <= MAX_LOG_LEVEL) 309# define VLOG_IF(n, condition) LOG_IF(n, (n <= MAX_LOG_LEVEL) && condition) 310#else 311# define LOG(n) MessageLogger((char *)__FILE__, __LINE__, "native", n).stream() // NOLINT 312# define VLOG(n) MessageLogger((char *)__FILE__, __LINE__, "native", n).stream() // NOLINT 313# define LG MessageLogger((char *)__FILE__, __LINE__, "native", INFO).stream() // NOLINT 314# define VLOG_IF(n, condition) LOG_IF(n, condition) 315#endif 316 317// Currently, VLOG is always on for levels below MAX_LOG_LEVEL. 318#ifndef MAX_LOG_LEVEL 319# define VLOG_IS_ON(x) (1) 320#else 321# define VLOG_IS_ON(x) (x <= MAX_LOG_LEVEL) 322#endif 323 324#ifndef NDEBUG 325# define DLOG LOG 326#else 327# define DLOG(severity) true ? (void) 0 : LoggerVoidify() & \ 328 MessageLogger((char *)__FILE__, __LINE__, "native", severity).stream() 329#endif 330 331 332// Log a message and terminate. 333template<class T> 334void LogMessageFatal(const char *file, int line, const T &message) { 335 MessageLogger((char *)__FILE__, __LINE__, "native", FATAL).stream() 336 << message; 337} 338 339// ---------------------------- CHECK macros --------------------------------- 340 341// Check for a given boolean condition. 342#define CHECK(condition) LOG_IF_FALSE(FATAL, condition) \ 343 << "Check failed: " #condition " " 344 345#ifndef NDEBUG 346// Debug only version of CHECK 347# define DCHECK(condition) LOG_IF_FALSE(FATAL, condition) \ 348 << "Check failed: " #condition " " 349#else 350// Optimized version - generates no code. 351# define DCHECK(condition) if (false) LOG_IF_FALSE(FATAL, condition) \ 352 << "Check failed: " #condition " " 353#endif // NDEBUG 354 355// ------------------------- CHECK_OP macros --------------------------------- 356 357// Generic binary operator check macro. This should not be directly invoked, 358// instead use the binary comparison macros defined below. 359#define CHECK_OP(val1, val2, op) LOG_IF_FALSE(FATAL, ((val1) op (val2))) \ 360 << "Check failed: " #val1 " " #op " " #val2 " " 361 362// Check_op macro definitions 363#define CHECK_EQ(val1, val2) CHECK_OP(val1, val2, ==) 364#define CHECK_NE(val1, val2) CHECK_OP(val1, val2, !=) 365#define CHECK_LE(val1, val2) CHECK_OP(val1, val2, <=) 366#define CHECK_LT(val1, val2) CHECK_OP(val1, val2, <) 367#define CHECK_GE(val1, val2) CHECK_OP(val1, val2, >=) 368#define CHECK_GT(val1, val2) CHECK_OP(val1, val2, >) 369 370#ifndef NDEBUG 371// Debug only versions of CHECK_OP macros. 372# define DCHECK_EQ(val1, val2) CHECK_OP(val1, val2, ==) 373# define DCHECK_NE(val1, val2) CHECK_OP(val1, val2, !=) 374# define DCHECK_LE(val1, val2) CHECK_OP(val1, val2, <=) 375# define DCHECK_LT(val1, val2) CHECK_OP(val1, val2, <) 376# define DCHECK_GE(val1, val2) CHECK_OP(val1, val2, >=) 377# define DCHECK_GT(val1, val2) CHECK_OP(val1, val2, >) 378#else 379// These versions generate no code in optimized mode. 380# define DCHECK_EQ(val1, val2) if (false) CHECK_OP(val1, val2, ==) 381# define DCHECK_NE(val1, val2) if (false) CHECK_OP(val1, val2, !=) 382# define DCHECK_LE(val1, val2) if (false) CHECK_OP(val1, val2, <=) 383# define DCHECK_LT(val1, val2) if (false) CHECK_OP(val1, val2, <) 384# define DCHECK_GE(val1, val2) if (false) CHECK_OP(val1, val2, >=) 385# define DCHECK_GT(val1, val2) if (false) CHECK_OP(val1, val2, >) 386#endif // NDEBUG 387 388// ---------------------------CHECK_NOTNULL macros --------------------------- 389 390// Helpers for CHECK_NOTNULL(). Two are necessary to support both raw pointers 391// and smart pointers. 392template <typename T> 393T& CheckNotNullCommon(const char *file, int line, const char *names, T& t) { 394 if (t == NULL) { 395 LogMessageFatal(file, line, std::string(names)); 396 } 397 return t; 398} 399 400template <typename T> 401T* CheckNotNull(const char *file, int line, const char *names, T* t) { 402 return CheckNotNullCommon(file, line, names, t); 403} 404 405template <typename T> 406T& CheckNotNull(const char *file, int line, const char *names, T& t) { 407 return CheckNotNullCommon(file, line, names, t); 408} 409 410// Check that a pointer is not null. 411#define CHECK_NOTNULL(val) \ 412 CheckNotNull(__FILE__, __LINE__, "'" #val "' Must be non NULL", (val)) 413 414#ifndef NDEBUG 415// Debug only version of CHECK_NOTNULL 416#define DCHECK_NOTNULL(val) \ 417 CheckNotNull(__FILE__, __LINE__, "'" #val "' Must be non NULL", (val)) 418#else 419// Optimized version - generates no code. 420#define DCHECK_NOTNULL(val) if (false)\ 421 CheckNotNull(__FILE__, __LINE__, "'" #val "' Must be non NULL", (val)) 422#endif // NDEBUG 423 424#include "ceres/internal/reenable_warnings.h" 425 426#endif // CERCES_INTERNAL_MINIGLOG_GLOG_LOGGING_H_ 427