1// Ceres Solver - A fast non-linear least squares minimizer 2// Copyright 2011, 2012 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// keir@google.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 <iostream> 101#include <string> 102#include <fstream> 103#include <set> 104#include <sstream> 105#include <vector> 106 107// Log severity level constants. 108const int FATAL = -3; 109const int ERROR = -2; 110const int WARNING = -1; 111const int INFO = 0; 112 113// ------------------------- Glog compatibility ------------------------------ 114 115namespace google { 116 117typedef int LogSeverity; 118const int INFO = ::INFO; 119const int WARNING = ::WARNING; 120const int ERROR = ::ERROR; 121const int FATAL = ::FATAL; 122 123// Sink class used for integration with mock and test functions. If sinks are 124// added, all log output is also sent to each sink through the send function. 125// In this implementation, WaitTillSent() is called immediately after the send. 126// This implementation is not thread safe. 127class LogSink { 128 public: 129 virtual ~LogSink() {} 130 virtual void send(LogSeverity severity, 131 const char* full_filename, 132 const char* base_filename, 133 int line, 134 const struct tm* tm_time, 135 const char* message, 136 size_t message_len) = 0; 137 virtual void WaitTillSent() = 0; 138}; 139 140// Global set of log sinks. The actual object is defined in logging.cc. 141extern std::set<LogSink *> log_sinks_global; 142 143inline void InitGoogleLogging(char *argv) { 144 // Do nothing; this is ignored. 145} 146 147// Note: the Log sink functions are not thread safe. 148inline void AddLogSink(LogSink *sink) { 149 // TODO(settinger): Add locks for thread safety. 150 log_sinks_global.insert(sink); 151} 152inline void RemoveLogSink(LogSink *sink) { 153 log_sinks_global.erase(sink); 154} 155 156} // namespace google 157 158// ---------------------------- Logger Class -------------------------------- 159 160// Class created for each use of the logging macros. 161// The logger acts as a stream and routes the final stream contents to the 162// Android logcat output at the proper filter level. If ANDROID is not 163// defined, output is directed to std::cerr. This class should not 164// be directly instantiated in code, rather it should be invoked through the 165// use of the log macros LG, LOG, or VLOG. 166class MessageLogger { 167 public: 168 MessageLogger(const char *file, int line, const char *tag, int severity) 169 : file_(file), line_(line), tag_(tag), severity_(severity) { 170 // Pre-pend the stream with the file and line number. 171 StripBasename(std::string(file), &filename_only_); 172 stream_ << filename_only_ << ":" << line << " "; 173 } 174 175 // Output the contents of the stream to the proper channel on destruction. 176 ~MessageLogger() { 177 stream_ << "\n"; 178 179#ifdef ANDROID 180 static const int android_log_levels[] = { 181 ANDROID_LOG_FATAL, // LOG(FATAL) 182 ANDROID_LOG_ERROR, // LOG(ERROR) 183 ANDROID_LOG_WARN, // LOG(WARNING) 184 ANDROID_LOG_INFO, // LOG(INFO), LG, VLOG(0) 185 ANDROID_LOG_DEBUG, // VLOG(1) 186 ANDROID_LOG_VERBOSE, // VLOG(2) .. VLOG(N) 187 }; 188 189 // Bound the logging level. 190 const int kMaxVerboseLevel = 2; 191 int android_level_index = std::min(std::max(FATAL, severity_), 192 kMaxVerboseLevel) - FATAL; 193 int android_log_level = android_log_levels[android_level_index]; 194 195 // Output the log string the Android log at the appropriate level. 196 __android_log_print(android_log_level, tag_.c_str(), stream_.str().c_str()); 197 198 // Indicate termination if needed. 199 if (severity_ == FATAL) { 200 __android_log_print(ANDROID_LOG_FATAL, 201 tag_.c_str(), 202 "terminating.\n"); 203 } 204#else 205 // If not building on Android, log all output to std::cerr. 206 std::cerr << stream_.str(); 207#endif // ANDROID 208 209 LogToSinks(severity_); 210 WaitForSinks(); 211 212 // Android logging at level FATAL does not terminate execution, so abort() 213 // is still required to stop the program. 214 if (severity_ == FATAL) { 215 abort(); 216 } 217 } 218 219 // Return the stream associated with the logger object. 220 std::stringstream &stream() { return stream_; } 221 222 private: 223 void LogToSinks(int severity) { 224 time_t rawtime; 225 struct tm* timeinfo; 226 227 time (&rawtime); 228 timeinfo = localtime(&rawtime); 229 std::set<google::LogSink*>::iterator iter; 230 // Send the log message to all sinks. 231 for (iter = google::log_sinks_global.begin(); 232 iter != google::log_sinks_global.end(); ++iter) { 233 (*iter)->send(severity, file_.c_str(), filename_only_.c_str(), line_, 234 timeinfo, stream_.str().c_str(), stream_.str().size()); 235 } 236 } 237 238 void WaitForSinks() { 239 // TODO(settinger): Add locks for thread safety. 240 std::set<google::LogSink *>::iterator iter; 241 242 // Call WaitTillSent() for all sinks. 243 for (iter = google::log_sinks_global.begin(); 244 iter != google::log_sinks_global.end(); ++iter) { 245 (*iter)->WaitTillSent(); 246 } 247 } 248 249 void StripBasename(const std::string &full_path, std::string *filename) { 250 // TODO(settinger): add support for OS with different path separators. 251 const char kSeparator = '/'; 252 size_t pos = full_path.rfind(kSeparator); 253 if (pos != std::string::npos) { 254 *filename = full_path.substr(pos + 1, std::string::npos); 255 } else { 256 *filename = full_path; 257 } 258 } 259 260 std::string file_; 261 std::string filename_only_; 262 int line_; 263 std::string tag_; 264 std::stringstream stream_; 265 int severity_; 266}; 267 268// ---------------------- Logging Macro definitions -------------------------- 269 270#define LG MessageLogger((char *)__FILE__, __LINE__, "native", \ 271 INFO).stream() 272 273#define LOG(n) MessageLogger((char *)__FILE__, __LINE__, "native", \ 274 n).stream() 275 276#define VLOG(n) MessageLogger((char *)__FILE__, __LINE__, "native", \ 277 n).stream() 278 279// Currently, VLOG is always on. 280#define VLOG_IS_ON(x) true 281 282// ---------------------------- CHECK helpers -------------------------------- 283 284// This class is used to explicitly ignore values in the conditional 285// logging macros. This avoids compiler warnings like "value computed 286// is not used" and "statement has no effect". 287class LoggerVoidify { 288 public: 289 LoggerVoidify() { } 290 // This has to be an operator with a precedence lower than << but 291 // higher than ?: 292 void operator&(const std::ostream &s) { } 293}; 294 295// Log only if condition is met. Otherwise evaluates to void. 296#define LOG_IF(severity, condition) \ 297 condition ? (void) 0 : LoggerVoidify() & LOG(severity) 298 299// Log a message and terminate. 300template<class T> 301void LogMessageFatal(const char *file, int line, const T &message) { 302 MessageLogger((char *)__FILE__, __LINE__, "native", FATAL).stream() 303 << message; 304} 305 306// ---------------------------- CHECK macros --------------------------------- 307 308// Check for a given boolean condition. 309#define CHECK(condition) LOG_IF(FATAL, condition) \ 310 << "Check failed: " #condition " " 311 312#ifndef NDEBUG 313// Debug only version of CHECK 314#define DCHECK(condition) LOG_IF(FATAL, condition) \ 315 << "Check failed: " #condition " " 316#else 317// Optimized version - generates no code. 318#define DCHECK(condition) if (false) LOG_IF(FATAL, condition) \ 319 << "Check failed: " #condition " " 320#endif // NDEBUG 321 322// ------------------------- CHECK_OP macros --------------------------------- 323 324// Generic binary operator check macro. This should not be directly invoked, 325// instead use the binary comparison macros defined below. 326#define CHECK_OP(val1, val2, op) LOG_IF(FATAL, (val1 op val2)) \ 327 << "Check failed: " #val1 " " #op " " #val2 " " 328 329// Check_op macro definitions 330#define CHECK_EQ(val1, val2) CHECK_OP(val1, val2, ==) 331#define CHECK_NE(val1, val2) CHECK_OP(val1, val2, !=) 332#define CHECK_LE(val1, val2) CHECK_OP(val1, val2, <=) 333#define CHECK_LT(val1, val2) CHECK_OP(val1, val2, <) 334#define CHECK_GE(val1, val2) CHECK_OP(val1, val2, >=) 335#define CHECK_GT(val1, val2) CHECK_OP(val1, val2, >) 336 337#ifndef NDEBUG 338// Debug only versions of CHECK_OP macros. 339#define DCHECK_EQ(val1, val2) CHECK_OP(val1, val2, ==) 340#define DCHECK_NE(val1, val2) CHECK_OP(val1, val2, !=) 341#define DCHECK_LE(val1, val2) CHECK_OP(val1, val2, <=) 342#define DCHECK_LT(val1, val2) CHECK_OP(val1, val2, <) 343#define DCHECK_GE(val1, val2) CHECK_OP(val1, val2, >=) 344#define DCHECK_GT(val1, val2) CHECK_OP(val1, val2, >) 345#else 346// These versions generate no code in optimized mode. 347#define DCHECK_EQ(val1, val2) if (false) CHECK_OP(val1, val2, ==) 348#define DCHECK_NE(val1, val2) if (false) CHECK_OP(val1, val2, !=) 349#define DCHECK_LE(val1, val2) if (false) CHECK_OP(val1, val2, <=) 350#define DCHECK_LT(val1, val2) if (false) CHECK_OP(val1, val2, <) 351#define DCHECK_GE(val1, val2) if (false) CHECK_OP(val1, val2, >=) 352#define DCHECK_GT(val1, val2) if (false) CHECK_OP(val1, val2, >) 353#endif // NDEBUG 354 355// ---------------------------CHECK_NOTNULL macros --------------------------- 356 357// Helpers for CHECK_NOTNULL(). Two are necessary to support both raw pointers 358// and smart pointers. 359template <typename T> 360T& CheckNotNullCommon(const char *file, int line, const char *names, T& t) { 361 if (t == NULL) { 362 LogMessageFatal(file, line, std::string(names)); 363 } 364 return t; 365} 366 367template <typename T> 368T* CheckNotNull(const char *file, int line, const char *names, T* t) { 369 return CheckNotNullCommon(file, line, names, t); 370} 371 372template <typename T> 373T& CheckNotNull(const char *file, int line, const char *names, T& t) { 374 return CheckNotNullCommon(file, line, names, t); 375} 376 377// Check that a pointer is not null. 378#define CHECK_NOTNULL(val) \ 379 CheckNotNull(__FILE__, __LINE__, "'" #val "' Must be non NULL", (val)) 380 381#ifndef NDEBUG 382// Debug only version of CHECK_NOTNULL 383#define DCHECK_NOTNULL(val) \ 384 CheckNotNull(__FILE__, __LINE__, "'" #val "' Must be non NULL", (val)) 385#else 386// Optimized version - generates no code. 387#define DCHECK_NOTNULL(val) if (false)\ 388 CheckNotNull(__FILE__, __LINE__, "'" #val "' Must be non NULL", (val)) 389#endif // NDEBUG 390 391#endif // CERCES_INTERNAL_MINIGLOG_GLOG_LOGGING_H_ 392