32 #if defined(__APPLE__) && defined(__GNUC__) && defined(__llvm__) && !defined(__clang__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 2) 33 #error This code is known to provoke a compiler crash with llvm-gcc 4.2. You will have better luck with clang++. See code.ros.org/trac/ros/ticket/3626 40 #include <boost/thread.hpp> 41 #include <boost/shared_array.hpp> 42 #include <boost/regex.hpp> 43 #include <boost/make_shared.hpp> 66 void print(
void* handle, ::
ros::console::Level level,
const char* str,
const char* file,
const char*
function,
int line);
72 std::string
getName(
void* handle);
74 bool get_loggers(std::map<std::string, levels::Level>& loggers);
85 #ifdef ROSCONSOLE_BACKEND_LOG4CXX 88 log4cxx::Level::getDebug(),
89 log4cxx::Level::getInfo(),
90 log4cxx::Level::getWarn(),
91 log4cxx::Level::getError(),
92 log4cxx::Level::getFatal(),
98 #define COLOR_NORMAL "" 100 #define COLOR_GREEN "" 101 #define COLOR_YELLOW "" 103 #define COLOR_NORMAL "\033[0m" 104 #define COLOR_RED "\033[31m" 105 #define COLOR_GREEN "\033[32m" 106 #define COLOR_YELLOW "\033[33m" 110 typedef std::map<std::string, std::string>
M_string;
115 g_extra_fixed_tokens[key] = val;
140 M_string::iterator it = g_extra_fixed_tokens.find(str_);
141 if (it == g_extra_fixed_tokens.end())
143 return (
"${" + str_ +
"}").c_str();
146 return it->second.c_str();
156 return "PLACEHOLDER";
205 std::stringstream ss;
219 std::stringstream ss;
229 std::stringstream ss;
230 ss << boost::this_thread::get_id();
268 std::stringstream ss;
276 if (type ==
"severity")
278 return TokenPtr(boost::make_shared<SeverityToken>());
280 else if (type ==
"message")
282 return TokenPtr(boost::make_shared<MessageToken>());
284 else if (type ==
"time")
286 return TokenPtr(boost::make_shared<TimeToken>());
288 else if (type ==
"walltime")
290 return TokenPtr(boost::make_shared<WallTimeToken>());
292 else if (type ==
"thread")
294 return TokenPtr(boost::make_shared<ThreadToken>());
296 else if (type ==
"logger")
298 return TokenPtr(boost::make_shared<LoggerToken>());
300 else if (type ==
"file")
302 return TokenPtr(boost::make_shared<FileToken>());
304 else if (type ==
"line")
306 return TokenPtr(boost::make_shared<LineToken>());
308 else if (type ==
"function")
310 return TokenPtr(boost::make_shared<FunctionToken>());
313 return TokenPtr(boost::make_shared<FixedMapToken>(type));
320 boost::regex e(
"\\$\\{([a-z|A-Z]+)\\}");
321 boost::match_results<std::string::const_iterator> results;
322 std::string::const_iterator start, end;
323 start = format_.begin();
325 bool matched_once =
false;
326 std::string last_suffix;
327 while (boost::regex_search(start, end, results, e))
330 for (
size_t i = 0; i < results.size(); ++i)
332 std::cout << i <<
"|" << results.prefix() <<
"|" << results[i] <<
"|" << results.suffix() << std::endl;
336 std::string token = results[1];
337 last_suffix = results.suffix();
338 tokens_.push_back(
TokenPtr(boost::make_shared<FixedToken>(results.prefix())));
341 start = results[0].second;
347 tokens_.push_back(
TokenPtr(boost::make_shared<FixedToken>(last_suffix)));
351 tokens_.push_back(
TokenPtr(boost::make_shared<FixedToken>(format_)));
357 const char* color = NULL;
385 std::stringstream ss;
387 V_Token::iterator it = tokens_.begin();
388 V_Token::iterator end = tokens_.end();
389 for (; it != end; ++it)
391 ss << (*it)->getString(logger_handle, level, str, file,
function, line);
395 fprintf(f,
"%s\n", ss.str().c_str());
403 g_formatter.
print(logger_handle, level, str, file,
function, line);
408 boost::mutex::scoped_lock lock(g_init_mutex);
413 char* format_string = NULL;
415 _dupenv_s(&format_string, NULL,
"ROSCONSOLE_FORMAT");
417 format_string = getenv(
"ROSCONSOLE_FORMAT");
421 g_format_string = format_string;
424 g_formatter.
init(g_format_string);
429 g_initialized =
true;
436 va_list arg_copy = args;
439 va_copy(arg_copy, args);
442 size_t total = vsnprintf_s(buffer.get(), buffer_size, buffer_size, fmt, args);
444 size_t total = vsnprintf(buffer.get(), buffer_size, fmt, args);
446 if (total >= buffer_size)
448 buffer_size = total + 1;
449 buffer.reset(
new char[buffer_size]);
452 vsnprintf_s(buffer.get(), buffer_size, buffer_size, fmt, arg_copy);
454 vsnprintf(buffer.get(), buffer_size, fmt, arg_copy);
482 return std::string(buffer.get(), size);
485 #define INITIAL_BUFFER_SIZE 4096 491 const char* file,
int line,
const char*
function,
const char* fmt, ...)
496 if (g_printing_thread_id == boost::this_thread::get_id())
498 fprintf(stderr,
"Warning: recursive print statement has occurred. Throwing out recursive print.\n");
502 boost::mutex::scoped_lock lock(g_print_mutex);
504 g_printing_thread_id = boost::this_thread::get_id();
521 params.
level = level;
522 params.
logger = logger_handle;
525 level = params.
level;
530 if (g_print_buffer_size <= msg_size)
532 g_print_buffer_size = msg_size + 1;
550 catch (std::exception& e)
552 fprintf(stderr,
"Caught exception while logging: [%s]\n", e.what());
556 g_printing_thread_id = boost::thread::id();
560 const std::stringstream& ss,
const char* file,
int line,
const char*
function)
565 if (g_printing_thread_id == boost::this_thread::get_id())
567 fprintf(stderr,
"Warning: recursive print statement has occurred. Throwing out recursive print.\n");
571 boost::mutex::scoped_lock lock(g_print_mutex);
573 g_printing_thread_id = boost::this_thread::get_id();
576 std::string str = ss.str();
584 params.
level = level;
585 params.
logger = logger_handle;
588 level = params.
level;
600 g_last_error_message = str;
606 catch (std::exception& e)
608 fprintf(stderr,
"Caught exception while logging: [%s]\n", e.what());
612 g_printing_thread_id = boost::thread::id();
620 boost::mutex::scoped_lock lock(g_locations_mutex);
622 g_log_locations.push_back(loc);
632 boost::mutex::scoped_lock lock(g_locations_mutex);
642 g_log_locations.push_back(loc);
651 boost::mutex::scoped_lock lock(g_locations_mutex);
657 boost::mutex::scoped_lock lock(g_locations_mutex);
663 boost::mutex::scoped_lock lock(g_locations_mutex);
665 V_LogLocation::iterator it = g_log_locations.begin();
666 V_LogLocation::iterator end = g_log_locations.end();
667 for ( ; it != end; ++it )
692 g_shutting_down =
true;
V_LogLocation g_log_locations
ROSCONSOLE_DECL void registerLogLocation(LogLocation *loc)
Registers a logging location with the system.
static boost::mutex g_print_mutex
log4cxx::LevelPtr g_level_lookup[levels::Count]
virtual bool isEnabled()
Returns whether or not the log statement should be printed. Called before the log arguments are evalu...
void print(void *handle,::ros::console::Level level, const char *str, const char *file, const char *function, int line)
void(* function_print)(void *,::ros::console::Level, const char *, const char *, const char *, int)
M_string g_extra_fixed_tokens
ROSCONSOLE_DECL void notifyLoggerLevelsChanged()
Tells the system that a logger's level has changed.
Base-class for filters. Filters allow full user-defined control over whether or not a message should ...
virtual std::string getString(void *,::ros::console::Level, const char *, const char *, const char *, int)
const char * g_format_string
Parameter structure passed to FilterBase::isEnabled(...);. Includes both input and output parameters...
virtual std::string getString(void *,::ros::console::Level, const char *, const char *, const char *, int)
::ros::console::Level level_
TokenPtr createTokenFromType(const std::string &type)
ROSCONSOLE_DECL void initialize()
Don't call this directly. Performs any required initialization/configuration. Happens automatically w...
virtual std::string getString(void *,::ros::console::Level, const char *, const char *, const char *, int line)
void * logger
[input/output] Handle identifying logger that this message will be output to. If changed, uses the new logger
virtual std::string getString(void *,::ros::console::Level, const char *, const char *file, const char *, int)
ROSCONSOLE_DECL void setFixedFilterToken(const std::string &key, const std::string &val)
std::string getName(void *handle)
virtual std::string getString(void *,::ros::console::Level, const char *, const char *, const char *, int)
std::vector< LogLocation * > V_LogLocation
const char * message
[input] The formatted message that will be output
virtual std::string getString(void *,::ros::console::Level level, const char *str, const char *file, const char *function, int line)
#define ROSCONSOLE_AUTOINIT
Initializes the rosconsole library. Usually unnecessary to call directly.
ROSCONSOLE_DECL bool g_initialized
Only exported because the macros need it. Do not use directly.
ROSCONSOLE_DECL std::string formatToString(const char *fmt,...)
void(* function_notifyLoggerLevelsChanged)()
virtual std::string getString(void *,::ros::console::Level, const char *, const char *, const char *, int)
ROSCONSOLE_DECL void checkLogLocationEnabled(LogLocation *loc)
Internal.
std::string out_message
[output] If set, writes this message instead of the original
virtual std::string getString(void *,::ros::console::Level, const char *str, const char *, const char *, int)
void register_appender(LogAppender *appender)
boost::shared_ptr< Token > TokenPtr
Level level
[input/output] Severity level. If changed, uses the new level
bool get_loggers(std::map< std::string, levels::Level > &loggers)
std::map< std::string, std::string > M_string
ROSCONSOLE_DECL void vformatToBuffer(boost::shared_array< char > &buffer, size_t &buffer_size, const char *fmt, va_list args)
FixedMapToken(const std::string &str)
const char * file
[input] File the message came from
bool set_logger_level(const std::string &name, levels::Level level)
const char * function
[input] Function the message came from
virtual std::string getString(void *,::ros::console::Level, const char *, const char *, const char *function, int)
#define INITIAL_BUFFER_SIZE
ROSCONSOLE_DECL void initializeLogLocation(LogLocation *loc, const std::string &name, Level level)
Internal.
virtual std::string getString(void *,::ros::console::Level, const char *, const char *, const char *, int)
static size_t g_print_buffer_size
static boost::thread::id g_printing_thread_id
void _print(void *logger_handle,::ros::console::Level level, const char *str, const char *file, const char *function, int line)
void checkLogLocationEnabledNoLock(LogLocation *loc)
boost::mutex g_init_mutex
bool isEnabledFor(void *handle,::ros::console::Level level)
int line
[input] Line the message came from
static boost::shared_array< char > g_print_buffer(new char[INITIAL_BUFFER_SIZE])
void * getHandle(const std::string &name)
virtual std::string getString(void *logger_handle,::ros::console::Level level, const char *str, const char *file, const char *function, int line)
boost::mutex g_locations_mutex
ROSCONSOLE_DECL std::string g_last_error_message
Only exported because the TopicManager need it. Do not use directly.
#define ROS_ASSERT(cond)
Asserts that the provided condition evaluates to true.
ROSCONSOLE_DECL Formatter g_formatter
Only exported because the implementation need it. Do not use directly.
ROSCONSOLE_DECL void setLogLocationLevel(LogLocation *loc, Level level)
Internal.
virtual std::string getString(void *,::ros::console::Level, const char *, const char *, const char *, int)
FixedToken(const std::string &str)
void print(ros::console::Level level, const std::string &s)
ROSCONSOLE_DECL void formatToBuffer(boost::shared_array< char > &buffer, size_t &buffer_size, const char *fmt,...)