console.h
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2008, Willow Garage, Inc.
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions are met:
00007  *
00008  *     * Redistributions of source code must retain the above copyright
00009  *       notice, this list of conditions and the following disclaimer.
00010  *     * Redistributions in binary form must reproduce the above copyright
00011  *       notice, this list of conditions and the following disclaimer in the
00012  *       documentation and/or other materials provided with the distribution.
00013  *     * Neither the name of Willow Garage, Inc. nor the names of its
00014  *       contributors may be used to endorse or promote products derived from
00015  *       this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00021  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00022  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00023  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00024  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00025  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00026  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00027  * POSSIBILITY OF SUCH DAMAGE.
00028  */
00029 
00030 // Author: Josh Faust
00031 
00032 #ifndef ROSCONSOLE_ROSCONSOLE_H
00033 #define ROSCONSOLE_ROSCONSOLE_H
00034 
00035 #include <cstdio>
00036 #include <sstream>
00037 #include <ros/time.h>
00038 #include <cstdarg>
00039 #include <ros/macros.h>
00040 
00041 // Import/export for windows dll's and visibility for gcc shared libraries.
00042 
00043 #ifdef ROS_BUILD_SHARED_LIBS // ros is being built around shared libraries
00044   #ifdef rosconsole_EXPORTS // we are building a shared lib/dll
00045     #define ROSCONSOLE_DECL ROS_HELPER_EXPORT
00046   #else // we are using shared lib/dll
00047     #define ROSCONSOLE_DECL ROS_HELPER_IMPORT
00048   #endif
00049 #else // ros is being built around static libraries
00050   #define ROSCONSOLE_DECL
00051 #endif
00052 
00053 // TODO: this header is no longer needed to be included here, but removing it will break various code that incorrectly does not itself include log4cxx/logger.h
00054 // We should vet all the code using log4cxx directly and make sure the includes/link flags are used in those packages, and then we can remove this include
00055 #include <log4cxx/logger.h>
00056 
00057 #ifdef __GNUC__
00058 #if __GNUC__ >= 3
00059 #define ROSCONSOLE_PRINTF_ATTRIBUTE(a, b) __attribute__ ((__format__ (__printf__, a, b)));
00060 #endif
00061 #endif
00062 
00063 #ifndef ROSCONSOLE_PRINTF_ATTRIBUTE
00064 #define ROSCONSOLE_PRINTF_ATTRIBUTE(a, b)
00065 #endif
00066 
00067 // log4cxx forward declarations
00068 namespace log4cxx
00069 {
00070 namespace helpers
00071 {
00072 template<typename T> class ObjectPtrT;
00073 } // namespace helpers
00074 
00075 class Level;
00076 typedef helpers::ObjectPtrT<Level> LevelPtr;
00077 
00078 class Logger;
00079 typedef helpers::ObjectPtrT<Logger> LoggerPtr;
00080 } // namespace log4cxx
00081 
00082 namespace boost
00083 {
00084 template<typename T> class shared_array;
00085 }
00086 
00087 namespace ros
00088 {
00089 namespace console
00090 {
00091 
00092 ROSCONSOLE_DECL void shutdown();
00093 
00094 namespace levels
00095 {
00096 enum Level
00097 {
00098   Debug,
00099   Info,
00100   Warn,
00101   Error,
00102   Fatal,
00103 
00104   Count
00105 };
00106 }
00107 typedef levels::Level Level;
00108 
00109 extern ROSCONSOLE_DECL log4cxx::LevelPtr g_level_lookup[];
00110 
00114 extern ROSCONSOLE_DECL bool g_initialized;
00115 
00122 ROSCONSOLE_DECL void initialize();
00123 
00124 class FilterBase;
00132 ROSCONSOLE_DECL void print(FilterBase* filter, log4cxx::Logger* logger, Level level,
00133            const char* file, int line, 
00134            const char* function, const char* fmt, ...) ROSCONSOLE_PRINTF_ATTRIBUTE(7, 8);
00135 
00136 ROSCONSOLE_DECL void print(FilterBase* filter, log4cxx::Logger* logger, Level level,
00137            const std::stringstream& str, const char* file, int line, const char* function);
00138 
00139 struct ROSCONSOLE_DECL LogLocation;
00140 
00148 ROSCONSOLE_DECL void registerLogLocation(LogLocation* loc);
00149 
00158 ROSCONSOLE_DECL void notifyLoggerLevelsChanged();
00159 
00160 ROSCONSOLE_DECL void setFixedFilterToken(const std::string& key, const std::string& val);
00161 
00165 struct FilterParams
00166 {
00167   // input parameters
00168   const char* file;                         
00169   int line;                                 
00170   const char* function;                     
00171   const char* message;                      
00172 
00173   // input/output parameters
00174   log4cxx::LoggerPtr logger;                
00175   Level level;                              
00176 
00177   // output parameters
00178   std::string out_message;                  
00179 };
00180 
00202 class FilterBase
00203 {
00204 public:
00205   virtual ~FilterBase() {}
00210   inline virtual bool isEnabled() { return true; }
00215   inline virtual bool isEnabled(FilterParams&) { return true; }
00216 };
00217 
00218 struct ROSCONSOLE_DECL LogLocation;
00222 ROSCONSOLE_DECL void initializeLogLocation(LogLocation* loc, const std::string& name, Level level);
00226 ROSCONSOLE_DECL void setLogLocationLevel(LogLocation* loc, Level level);
00230 ROSCONSOLE_DECL void checkLogLocationEnabled(LogLocation* loc);
00231 
00235 struct LogLocation
00236 {
00237   bool initialized_;
00238   bool logger_enabled_;
00239   ::ros::console::Level level_;
00240   log4cxx::Logger* logger_;
00241 };
00242 
00243 ROSCONSOLE_DECL void vformatToBuffer(boost::shared_array<char>& buffer, size_t& buffer_size, const char* fmt, va_list args);
00244 ROSCONSOLE_DECL void formatToBuffer(boost::shared_array<char>& buffer, size_t& buffer_size, const char* fmt, ...);
00245 ROSCONSOLE_DECL std::string formatToString(const char* fmt, ...);
00246 
00247 } // namespace console
00248 } // namespace ros
00249 
00250 #ifdef WIN32
00251 #define ROS_LIKELY(x)       (x)
00252 #define ROS_UNLIKELY(x)     (x)
00253 #else
00254 #define ROS_LIKELY(x)       __builtin_expect((x),1)
00255 #define ROS_UNLIKELY(x)     __builtin_expect((x),0)
00256 #endif
00257 
00258 #if defined(MSVC)
00259   #define __ROSCONSOLE_FUNCTION__ __FUNCSIG__
00260 #elif defined(__GNUC__)
00261   #define __ROSCONSOLE_FUNCTION__ __PRETTY_FUNCTION__
00262 #else
00263   #define __ROSCONSOLE_FUNCTION__ ""
00264 #endif
00265 
00266 
00267 #ifdef ROS_PACKAGE_NAME
00268 #define ROSCONSOLE_PACKAGE_NAME ROS_PACKAGE_NAME
00269 #else
00270 #define ROSCONSOLE_PACKAGE_NAME "unknown_package"
00271 #endif
00272 
00273 #define ROSCONSOLE_ROOT_LOGGER_NAME "ros"
00274 #define ROSCONSOLE_NAME_PREFIX ROSCONSOLE_ROOT_LOGGER_NAME "." ROSCONSOLE_PACKAGE_NAME
00275 #define ROSCONSOLE_DEFAULT_NAME ROSCONSOLE_NAME_PREFIX
00276 
00277 // These allow you to compile-out everything below a certain severity level if necessary
00278 #define ROSCONSOLE_SEVERITY_DEBUG 0
00279 #define ROSCONSOLE_SEVERITY_INFO 1
00280 #define ROSCONSOLE_SEVERITY_WARN 2
00281 #define ROSCONSOLE_SEVERITY_ERROR 3
00282 #define ROSCONSOLE_SEVERITY_FATAL 4
00283 #define ROSCONSOLE_SEVERITY_NONE 5
00284 
00290 #ifndef ROSCONSOLE_MIN_SEVERITY
00291 #define ROSCONSOLE_MIN_SEVERITY ROSCONSOLE_SEVERITY_DEBUG
00292 #endif
00293 
00298 #define ROSCONSOLE_AUTOINIT \
00299   do \
00300   { \
00301     if (ROS_UNLIKELY(!::ros::console::g_initialized)) \
00302     { \
00303       ::ros::console::initialize(); \
00304     } \
00305   } while(0)
00306 
00307 #define ROSCONSOLE_DEFINE_LOCATION(cond, level, name) \
00308   ROSCONSOLE_AUTOINIT; \
00309   static ::ros::console::LogLocation loc = {false, false, ::ros::console::levels::Count, 0}; /* Initialized at compile-time */ \
00310   if (ROS_UNLIKELY(!loc.initialized_)) \
00311   { \
00312     initializeLogLocation(&loc, name, level); \
00313   } \
00314   if (ROS_UNLIKELY(loc.level_ != level)) \
00315   { \
00316     setLogLocationLevel(&loc, level); \
00317     checkLogLocationEnabled(&loc); \
00318   } \
00319   bool enabled = loc.logger_enabled_ && (cond);
00320 
00321 #define ROSCONSOLE_PRINT_AT_LOCATION_WITH_FILTER(filter, ...) \
00322     ::ros::console::print(filter, loc.logger_, loc.level_, __FILE__, __LINE__, __ROSCONSOLE_FUNCTION__, __VA_ARGS__)
00323 
00324 #define ROSCONSOLE_PRINT_AT_LOCATION(...) \
00325     ROSCONSOLE_PRINT_AT_LOCATION_WITH_FILTER(0, __VA_ARGS__)
00326 
00327 // inside a macro which uses args use only well namespaced variable names in order to not overlay variables coming in via args
00328 #define ROSCONSOLE_PRINT_STREAM_AT_LOCATION_WITH_FILTER(filter, args) \
00329   do \
00330   { \
00331     std::stringstream __rosconsole_print_stream_at_location_with_filter__ss__; \
00332     __rosconsole_print_stream_at_location_with_filter__ss__ << args; \
00333     ::ros::console::print(filter, loc.logger_, loc.level_, __rosconsole_print_stream_at_location_with_filter__ss__, __FILE__, __LINE__, __ROSCONSOLE_FUNCTION__); \
00334   } while (0)
00335 
00336 #define ROSCONSOLE_PRINT_STREAM_AT_LOCATION(args) \
00337     ROSCONSOLE_PRINT_STREAM_AT_LOCATION_WITH_FILTER(0, args)
00338 
00348 #define ROS_LOG_COND(cond, level, name, ...) \
00349   do \
00350   { \
00351     ROSCONSOLE_DEFINE_LOCATION(cond, level, name); \
00352     \
00353     if (ROS_UNLIKELY(enabled)) \
00354     { \
00355       ROSCONSOLE_PRINT_AT_LOCATION(__VA_ARGS__); \
00356     } \
00357   } while(0)
00358 
00368 #define ROS_LOG_STREAM_COND(cond, level, name, args) \
00369   do \
00370   { \
00371     ROSCONSOLE_DEFINE_LOCATION(cond, level, name); \
00372     if (ROS_UNLIKELY(enabled)) \
00373     { \
00374       ROSCONSOLE_PRINT_STREAM_AT_LOCATION(args); \
00375     } \
00376   } while(0)
00377 
00384 #define ROS_LOG_ONCE(level, name, ...) \
00385   do \
00386   { \
00387     ROSCONSOLE_DEFINE_LOCATION(true, level, name); \
00388     static bool hit = false; \
00389     if (ROS_UNLIKELY(enabled) && ROS_UNLIKELY(!hit)) \
00390     { \
00391       hit = true; \
00392       ROSCONSOLE_PRINT_AT_LOCATION(__VA_ARGS__); \
00393     } \
00394   } while(0)
00395 
00396 // inside a macro which uses args use only well namespaced variable names in order to not overlay variables coming in via args
00403 #define ROS_LOG_STREAM_ONCE(level, name, args) \
00404   do \
00405   { \
00406     ROSCONSOLE_DEFINE_LOCATION(true, level, name); \
00407     static bool __ros_log_stream_once__hit__ = false; \
00408     if (ROS_UNLIKELY(enabled) && ROS_UNLIKELY(!__ros_log_stream_once__hit__)) \
00409     { \
00410       __ros_log_stream_once__hit__ = true; \
00411       ROSCONSOLE_PRINT_STREAM_AT_LOCATION(args); \
00412     } \
00413   } while(0)
00414 
00422 #define ROS_LOG_THROTTLE(rate, level, name, ...) \
00423   do \
00424   { \
00425     ROSCONSOLE_DEFINE_LOCATION(true, level, name); \
00426     static double last_hit = 0.0; \
00427     ::ros::Time now = ::ros::Time::now(); \
00428     if (ROS_UNLIKELY(enabled) && ROS_UNLIKELY(last_hit + rate <= now.toSec())) \
00429     { \
00430       last_hit = now.toSec(); \
00431       ROSCONSOLE_PRINT_AT_LOCATION(__VA_ARGS__); \
00432     } \
00433   } while(0)
00434 
00435 // inside a macro which uses args use only well namespaced variable names in order to not overlay variables coming in via args
00443 #define ROS_LOG_STREAM_THROTTLE(rate, level, name, args) \
00444   do \
00445   { \
00446     ROSCONSOLE_DEFINE_LOCATION(true, level, name); \
00447     static double __ros_log_stream_throttle__last_hit__ = 0.0; \
00448     ::ros::Time __ros_log_stream_throttle__now__ = ::ros::Time::now(); \
00449     if (ROS_UNLIKELY(enabled) && ROS_UNLIKELY(__ros_log_stream_throttle__last_hit__ + rate <= __ros_log_stream_throttle__now__.toSec())) \
00450     { \
00451       __ros_log_stream_throttle__last_hit__ = __ros_log_stream_throttle__now__.toSec(); \
00452       ROSCONSOLE_PRINT_STREAM_AT_LOCATION(args); \
00453     } \
00454   } while(0)
00455 
00463 #define ROS_LOG_FILTER(filter, level, name, ...) \
00464   do \
00465   { \
00466     ROSCONSOLE_DEFINE_LOCATION(true, level, name); \
00467     if (ROS_UNLIKELY(enabled) && (filter)->isEnabled()) \
00468     { \
00469       ROSCONSOLE_PRINT_AT_LOCATION_WITH_FILTER(filter, __VA_ARGS__); \
00470     } \
00471   } while(0)
00472 
00480 #define ROS_LOG_STREAM_FILTER(filter, level, name, args) \
00481   do \
00482   { \
00483     ROSCONSOLE_DEFINE_LOCATION(true, level, name); \
00484     if (ROS_UNLIKELY(enabled) && (filter)->isEnabled()) \
00485     { \
00486       ROSCONSOLE_PRINT_STREAM_AT_LOCATION_WITH_FILTER(filter, args); \
00487     } \
00488   } while(0)
00489 
00496 #define ROS_LOG(level, name, ...) ROS_LOG_COND(true, level, name, __VA_ARGS__)
00497 
00503 #define ROS_LOG_STREAM(level, name, args) ROS_LOG_STREAM_COND(true, level, name, args)
00504 
00505 #include "rosconsole/macros_generated.h"
00506 
00507 #endif // ROSCONSOLE_ROSCONSOLE_H


rosconsole
Author(s): Josh Faust
autogenerated on Sat Dec 28 2013 17:35:45