This commit is contained in:
Ivan
2022-04-05 11:42:28 +03:00
commit 6dc0eb0fcf
5565 changed files with 1200500 additions and 0 deletions

View File

@@ -0,0 +1,180 @@
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Changelog for package rosconsole
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1.12.14 (2018-08-23)
--------------------
1.12.13 (2018-02-21)
--------------------
1.12.12 (2017-11-16)
--------------------
1.12.11 (2017-11-07)
--------------------
1.12.10 (2017-11-06)
--------------------
1.12.9 (2017-11-06)
-------------------
1.12.8 (2017-11-06)
-------------------
* replace 'while(0)' with 'while(false)' to avoid warnings (`#1179 <https://github.com/ros/ros_comm/issues/1179>`_)
1.12.7 (2017-02-17)
-------------------
1.12.6 (2016-10-26)
-------------------
* add missing walltime to roscpp logging (`#879 <https://github.com/ros/ros_comm/pull/879>`_)
* fix building on GCC-6 (`#911 <https://github.com/ros/ros_comm/pull/911>`_)
1.12.5 (2016-09-30)
-------------------
1.12.4 (2016-09-19)
-------------------
1.12.3 (2016-09-17)
-------------------
1.12.2 (2016-06-03)
-------------------
1.12.1 (2016-04-18)
-------------------
* use directory specific compiler flags (`#785 <https://github.com/ros/ros_comm/pull/785>`_)
1.12.0 (2016-03-18)
-------------------
* make LogAppender and Token destructor virtual (`#729 <https://github.com/ros/ros_comm/issues/729>`_)
1.11.18 (2016-03-17)
--------------------
* fix compiler warnings
1.11.17 (2016-03-11)
--------------------
* use boost::make_shared instead of new for constructing boost::shared_ptr (`#740 <https://github.com/ros/ros_comm/issues/740>`_)
1.11.16 (2015-11-09)
--------------------
1.11.15 (2015-10-13)
--------------------
1.11.14 (2015-09-19)
--------------------
* avoid redefining ROS_ASSERT_ENABLED (`#628 <https://github.com/ros/ros_comm/pull/628>`_)
1.11.13 (2015-04-28)
--------------------
1.11.12 (2015-04-27)
--------------------
1.11.11 (2015-04-16)
--------------------
* add DELAYED_THROTTLE versions of log macros (`#571 <https://github.com/ros/ros_comm/issues/571>`_)
1.11.10 (2014-12-22)
--------------------
* fix various defects reported by coverity
1.11.9 (2014-08-18)
-------------------
1.11.8 (2014-08-04)
-------------------
1.11.7 (2014-07-18)
-------------------
1.11.6 (2014-07-10)
-------------------
1.11.5 (2014-06-24)
-------------------
* rename variables within rosconsole macros (`#442 <https://github.com/ros/ros_comm/issues/442>`_)
1.11.4 (2014-06-16)
-------------------
1.11.3 (2014-05-21)
-------------------
1.11.2 (2014-05-08)
-------------------
1.11.1 (2014-05-07)
-------------------
1.11.0 (2014-03-04)
-------------------
1.10.0 (2014-02-11)
-------------------
1.9.54 (2014-01-27)
-------------------
* fix rosconsole segfault when using ROSCONSOLE_FORMAT with (`#342 <https://github.com/ros/ros_comm/issues/342>`_)
* add missing run/test dependencies on rosbuild to get ROS_ROOT environment variable
1.9.53 (2014-01-14)
-------------------
* readd g_level_lockup symbol for backward compatibility when log4cxx is being used
1.9.52 (2014-01-08)
-------------------
* fix missing export of rosconsole backend interface library
1.9.51 (2014-01-07)
-------------------
* refactor rosconsole to not expose log4cxx, implement empty and log4cxx backends
1.9.50 (2013-10-04)
-------------------
1.9.49 (2013-09-16)
-------------------
1.9.48 (2013-08-21)
-------------------
* wrap condition in ROS_ASSERT_CMD in parenthesis (`#271 <https://github.com/ros/ros_comm/issues/271>`_)
1.9.47 (2013-07-03)
-------------------
* force CMake policy before setting preprocessor definition to ensure correct escaping (`#245 <https://github.com/ros/ros_comm/issues/245>`_)
* check for CATKIN_ENABLE_TESTING to enable configure without tests
1.9.46 (2013-06-18)
-------------------
1.9.45 (2013-06-06)
-------------------
1.9.44 (2013-03-21)
-------------------
* fix install destination for dll's under Windows
1.9.43 (2013-03-13)
-------------------
1.9.42 (2013-03-08)
-------------------
* fix handling spaces in folder names (`ros/catkin#375 <https://github.com/ros/catkin/issues/375>`_)
1.9.41 (2013-01-24)
-------------------
1.9.40 (2013-01-13)
-------------------
* fix dependent packages by pass LOG4CXX include dirs and libraries along
* fix usage of variable arguments in vFormatToBuffer() function
1.9.39 (2012-12-29)
-------------------
* first public release for Groovy

View File

@@ -0,0 +1,127 @@
cmake_minimum_required(VERSION 2.8.3)
project(rosconsole)
if(NOT WIN32)
set_directory_properties(PROPERTIES COMPILE_OPTIONS "-Wall;-Wextra")
endif()
find_package(catkin REQUIRED COMPONENTS cpp_common rostime rosunit)
find_package(Boost COMPONENTS regex system thread)
# select rosconsole backend
set(ROSCONSOLE_BACKEND "" CACHE STRING "Type of rosconsole backend, one of 'log4cxx', 'glog', 'print'")
set(rosconsole_backend_INCLUDE_DIRS)
set(rosconsole_backend_LIBRARIES)
if(ROSCONSOLE_BACKEND STREQUAL "" OR ROSCONSOLE_BACKEND STREQUAL "log4cxx")
find_package(Log4cxx QUIET)
if(NOT LOG4CXX_LIBRARIES)
# backup plan, hope it is in the system path
find_library(LOG4CXX_LIBRARIES log4cxx)
endif()
if(LOG4CXX_LIBRARIES)
list(APPEND rosconsole_backend_INCLUDE_DIRS ${LOG4CXX_INCLUDE_DIRS})
list(APPEND rosconsole_backend_LIBRARIES rosconsole_log4cxx rosconsole_backend_interface ${LOG4CXX_LIBRARIES})
set(ROSCONSOLE_BACKEND "log4cxx")
elseif(ROSCONSOLE_BACKEND STREQUAL "log4cxx")
message(FATAL_ERROR "Couldn't find log4cxx library")
endif()
endif()
if(ROSCONSOLE_BACKEND STREQUAL "" OR ROSCONSOLE_BACKEND STREQUAL "glog")
find_package(PkgConfig)
pkg_check_modules(GLOG QUIET libglog)
if(GLOG_FOUND)
list(APPEND rosconsole_backend_INCLUDE_DIRS ${GLOG_INCLUDE_DIRS})
list(APPEND rosconsole_backend_LIBRARIES rosconsole_glog rosconsole_backend_interface ${GLOG_LIBRARIES})
set(ROSCONSOLE_BACKEND "glog")
elseif(ROSCONSOLE_BACKEND STREQUAL "glog")
message(FATAL_ERROR "Couldn't find glog library")
endif()
endif()
if(ROSCONSOLE_BACKEND STREQUAL "" OR ROSCONSOLE_BACKEND STREQUAL "print")
list(APPEND rosconsole_backend_LIBRARIES rosconsole_print rosconsole_backend_interface)
set(ROSCONSOLE_BACKEND "print")
endif()
message(STATUS "rosconsole backend: ${ROSCONSOLE_BACKEND}")
catkin_package(
INCLUDE_DIRS include ${rosconsole_backend_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}
LIBRARIES rosconsole ${rosconsole_backend_LIBRARIES} ${Boost_LIBRARIES}
CATKIN_DEPENDS cpp_common rostime
CFG_EXTRAS rosconsole-extras.cmake
)
include(${CATKIN_DEVEL_PREFIX}/share/${PROJECT_NAME}/cmake/rosconsole-extras.cmake)
# See ticket: https://code.ros.org/trac/ros/ticket/3626
# On mac use g++-4.2
IF(${CMAKE_SYSTEM} MATCHES "Darwin-11.*")
IF(EXISTS "/usr/bin/g++-4.2")
set(CMAKE_CXX_COMPILER /usr/bin/g++-4.2)
ELSE(EXISTS "/usr/bin/g++-4.2")
# If there is no g++-4.2 use clang++
set(CMAKE_CXX_COMPILER /usr/bin/clang++)
ENDIF(EXISTS "/usr/bin/g++-4.2")
ENDIF(${CMAKE_SYSTEM} MATCHES "Darwin-11.*")
include_directories(include ${catkin_INCLUDE_DIRS} ${rosconsole_backend_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS})
add_library(rosconsole_backend_interface src/rosconsole/rosconsole_backend.cpp)
add_library(rosconsole src/rosconsole/rosconsole.cpp)
target_link_libraries(rosconsole ${rosconsole_backend_LIBRARIES} ${catkin_LIBRARIES} ${Boost_LIBRARIES})
if(ROSCONSOLE_BACKEND STREQUAL "log4cxx")
add_library(rosconsole_log4cxx src/rosconsole/impl/rosconsole_log4cxx.cpp)
target_link_libraries(rosconsole_log4cxx rosconsole_backend_interface ${LOG4CXX_LIBRARIES} ${Boost_LIBRARIES})
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test/speed_test.cpp")
add_executable(rosconsole_speed_test test/speed_test.cpp)
target_link_libraries(rosconsole_speed_test rosconsole ${rosconsole_backend_LIBRARIES} ${catkin_LIBRARIES} ${Boost_LIBRARIES})
endif()
elseif(ROSCONSOLE_BACKEND STREQUAL "glog")
add_library(rosconsole_glog src/rosconsole/impl/rosconsole_glog.cpp)
target_link_libraries(rosconsole_glog rosconsole_backend_interface ${GLOG_LIBRARIES})
elseif(ROSCONSOLE_BACKEND STREQUAL "print")
add_library(rosconsole_print src/rosconsole/impl/rosconsole_print.cpp)
target_link_libraries(rosconsole_print rosconsole_backend_interface)
else()
message(FATAL_ERROR "Unknown rosconsole backend '${ROSCONSOLE_BACKEND}'")
endif()
if(CMAKE_HOST_UNIX)
catkin_add_env_hooks(10.rosconsole SHELLS sh DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/env-hooks)
else()
catkin_add_env_hooks(10.rosconsole SHELLS bat DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/env-hooks)
endif()
install(TARGETS rosconsole rosconsole_${ROSCONSOLE_BACKEND} rosconsole_backend_interface
ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION})
install(FILES config/rosconsole.config
DESTINATION ${CATKIN_GLOBAL_SHARE_DESTINATION}/ros/config)
install(DIRECTORY include/
DESTINATION ${CATKIN_GLOBAL_INCLUDE_DESTINATION}
FILES_MATCHING PATTERN "*.h")
if(CATKIN_ENABLE_TESTING)
catkin_add_gtest(${PROJECT_NAME}-utest test/utest.cpp)
if(TARGET ${PROJECT_NAME}-utest)
target_link_libraries(${PROJECT_NAME}-utest ${PROJECT_NAME})
endif()
if(${CMAKE_SYSTEM_NAME} STREQUAL Linux)
catkin_add_gtest(${PROJECT_NAME}-assertion_test test/assertion_test.cpp)
if(TARGET ${PROJECT_NAME}-assertion_test)
target_link_libraries(${PROJECT_NAME}-assertion_test ${PROJECT_NAME})
endif()
endif()
catkin_add_gtest(${PROJECT_NAME}-thread_test test/thread_test.cpp)
if(TARGET ${PROJECT_NAME}-thread_test)
target_link_libraries(${PROJECT_NAME}-thread_test ${PROJECT_NAME})
endif()
endif()

View File

@@ -0,0 +1,15 @@
# ros_comm/tools/rosconsole/cmake/rosconsole-extras.cmake
# force automatic escaping of preprocessor definitions
cmake_policy(PUSH)
cmake_policy(SET CMP0005 NEW)
# add ROS_PACKAGE_NAME define required by the named logging macros
add_definitions(-DROS_PACKAGE_NAME=\"${PROJECT_NAME}\")
if("@ROSCONSOLE_BACKEND@" STREQUAL "log4cxx")
# add ROSCONSOLE_BACKEND_LOG4CXX define required for backward compatible log4cxx symbols
add_definitions(-DROSCONSOLE_BACKEND_LOG4CXX)
endif()
cmake_policy(POP)

View File

@@ -0,0 +1,8 @@
#
# rosconsole will find this file by default at $ROS_ROOT/config/rosconsole.config
#
# You can define your own by e.g. copying this file and setting
# ROSCONSOLE_CONFIG_FILE (in your environment) to point to the new file
#
log4j.logger.ros=INFO
log4j.logger.ros.roscpp.superdebug=WARN

View File

@@ -0,0 +1,3 @@
REM generated from rosconsole/env-hooks/10.rosconsole.bat.develspace.em
set ROSCONSOLE_CONFIG_FILE=@(CMAKE_CURRENT_SOURCE_DIR)/config/rosconsole.config

View File

@@ -0,0 +1,3 @@
# generated from rosconsole/env-hooks/10.rosconsole.sh.develspace.em
export ROSCONSOLE_CONFIG_FILE="@(CMAKE_CURRENT_SOURCE_DIR)/config/rosconsole.config"

View File

@@ -0,0 +1,86 @@
/*********************************************************************
* Software License Agreement (BSD License)
*
* Copyright (c) 2008, Willow Garage, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of Willow Garage, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
********************************************************************/
#include "ros/console.h"
#include <log4cxx/logger.h>
void print(ros::console::Level level, const std::string& s)
{
ROS_LOG(level, ROSCONSOLE_DEFAULT_NAME, "%s", s.c_str());
}
int main(int /*argc*/, char** /*argv*/)
{
// This needs to happen before we start fooling around with logger levels. Otherwise the level we set may be overwritten by
// a configuration file
ROSCONSOLE_AUTOINIT;
log4cxx::LoggerPtr my_logger = log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME);
// Set the logger for this package to output all statements
my_logger->setLevel(ros::console::g_level_lookup[ros::console::levels::Debug]);
// All these should print
ROS_DEBUG("This is a debug statement, and should print");
ROS_INFO("This is an info statement, and should print");
ROS_WARN("This is a warn statement, and should print");
ROS_ERROR("This is an error statement, and should print");
ROS_FATAL("This is a fatal statement, and should print");
// This should also print
print(ros::console::levels::Debug, "Hello, this should print");
my_logger->setLevel(ros::console::g_level_lookup[ros::console::levels::Error]);
// This will STILL print, because the logger's enabled state has been cached
print(ros::console::levels::Debug, "Hello, this will also print");
// Calling notifyLoggerLevelsChanged() will force a reevaluation of which logging statements are enabled
ros::console::notifyLoggerLevelsChanged();
// Which will cause this to not print
print(ros::console::levels::Debug, "Hello, this will NOT print");
log4cxx::LoggerPtr ros_logger = log4cxx::Logger::getLogger(ROSCONSOLE_ROOT_LOGGER_NAME);
my_logger->setLevel(ros::console::g_level_lookup[ros::console::levels::Debug]);
ros_logger->setLevel(ros::console::g_level_lookup[ros::console::levels::Error]);
ROS_DEBUG("This will still print, because the child logger's level overrides its ancestor loggers' levels");
log4cxx::LoggerPtr test_logger = log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME".test");
test_logger->setLevel(ros::console::g_level_lookup[ros::console::levels::Error]);
ROS_INFO_NAMED("test", "This will not print, because the ros.rosconsole.test logger has been set to Error verbosity");
test_logger->setLevel(ros::console::g_level_lookup[ros::console::levels::Debug]);
ROS_INFO_NAMED("test", "Now everything sent to the ros.rosconsole.test logger will be printed (including this)");
return 0;
}

View File

@@ -0,0 +1,155 @@
/*
* Copyright (c) 2008, Willow Garage, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Willow Garage, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
// Author: Josh Faust
#ifndef ROSCONSOLE_ROSASSERT_H
#define ROSCONSOLE_ROSASSERT_H
#include "ros/console.h"
#include "ros/static_assert.h"
/** \file */
/** \def ROS_ASSERT(cond)
* \brief Asserts that the provided condition evaluates to true.
*
* If it is false, program execution will abort, with an informative
* statement about which assertion failed, in what file. Use ROS_ASSERT
* instead of assert() itself.
*
* If running inside a debugger, ROS_ASSERT will allow you to step past the assertion.
*/
/** \def ROS_ASSERT_MSG(cond, ...)
* \brief Asserts that the provided condition evaluates to true.
*
* If it is false, program execution will abort, with an informative
* statement about which assertion failed, in what file, and it will print out
* a printf-style message you define. Example usage:
@verbatim
ROS_ASSERT_MSG(x > 0, "Uh oh, x went negative. Value = %d", x);
@endverbatim
*
* If running inside a debugger, ROS_ASSERT will allow you to step past the assertion.
*/
/**
* \def ROS_ASSERT_CMD()
* \brief Runs a command if the provided condition is false
*
* For example:
\verbatim
ROS_ASSERT_CMD(x > 0, handleError(...));
\endverbatim
*/
/** \def ROS_BREAK()
* \brief Aborts program execution.
*
* Aborts program execution with an informative message stating what file and
* line it was called from. Use ROS_BREAK instead of calling assert(0) or
* ROS_ASSERT(0).
*
* If running inside a debugger, ROS_BREAK will allow you to step past the breakpoint.
*/
/** \def ROS_ISSUE_BREAK()
* \brief Always issues a breakpoint instruction.
*
* This define is mostly for internal use, but is useful if you want to simply issue a break
* instruction in a cross-platform way.
*
* Currently implemented for Windows (any platform), powerpc64, and x86
*/
#include <ros/platform.h>
#ifdef WIN32
# if defined (__MINGW32__)
# define ROS_ISSUE_BREAK() DebugBreak();
# else // MSVC
# define ROS_ISSUE_BREAK() __debugbreak();
# endif
#elif defined(__powerpc64__)
# define ROS_ISSUE_BREAK() asm volatile ("tw 31,1,1");
#elif defined(__i386__) || defined(__ia64__) || defined(__x86_64__)
# define ROS_ISSUE_BREAK() asm("int $3");
#else
# include <stdlib.h>
# define ROS_ISSUE_BREAK() abort();
#endif
#ifndef NDEBUG
#ifndef ROS_ASSERT_ENABLED
#define ROS_ASSERT_ENABLED
#endif
#endif
#ifdef ROS_ASSERT_ENABLED
#define ROS_BREAK() \
do { \
ROS_FATAL("BREAKPOINT HIT\n\tfile = %s\n\tline=%d\n", __FILE__, __LINE__); \
ROS_ISSUE_BREAK() \
} while (false)
#define ROS_ASSERT(cond) \
do { \
if (!(cond)) { \
ROS_FATAL("ASSERTION FAILED\n\tfile = %s\n\tline = %d\n\tcond = %s\n", __FILE__, __LINE__, #cond); \
ROS_ISSUE_BREAK() \
} \
} while (false)
#define ROS_ASSERT_MSG(cond, ...) \
do { \
if (!(cond)) { \
ROS_FATAL("ASSERTION FAILED\n\tfile = %s\n\tline = %d\n\tcond = %s\n\tmessage = ", __FILE__, __LINE__, #cond); \
ROS_FATAL(__VA_ARGS__); \
ROS_FATAL("\n"); \
ROS_ISSUE_BREAK(); \
} \
} while (false)
#define ROS_ASSERT_CMD(cond, cmd) \
do { \
if (!(cond)) { \
cmd; \
} \
} while (false)
#else
#define ROS_BREAK()
#define ROS_ASSERT(cond)
#define ROS_ASSERT_MSG(cond, ...)
#define ROS_ASSERT_CMD(cond, cmd)
#endif
#endif // ROSCONSOLE_ROSASSERT_H

View File

@@ -0,0 +1,572 @@
/*
* Copyright (c) 2008, Willow Garage, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Willow Garage, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
// Author: Josh Faust
#ifndef ROSCONSOLE_ROSCONSOLE_H
#define ROSCONSOLE_ROSCONSOLE_H
#include "console_backend.h"
#include <cstdio>
#include <sstream>
#include <ros/time.h>
#include <cstdarg>
#include <ros/macros.h>
#include <map>
#include <vector>
#ifdef ROSCONSOLE_BACKEND_LOG4CXX
#include "log4cxx/level.h"
#endif
// Import/export for windows dll's and visibility for gcc shared libraries.
#ifdef ROS_BUILD_SHARED_LIBS // ros is being built around shared libraries
#ifdef rosconsole_EXPORTS // we are building a shared lib/dll
#define ROSCONSOLE_DECL ROS_HELPER_EXPORT
#else // we are using shared lib/dll
#define ROSCONSOLE_DECL ROS_HELPER_IMPORT
#endif
#else // ros is being built around static libraries
#define ROSCONSOLE_DECL
#endif
#ifdef __GNUC__
#if __GNUC__ >= 3
#define ROSCONSOLE_PRINTF_ATTRIBUTE(a, b) __attribute__ ((__format__ (__printf__, a, b)));
#endif
#endif
#ifndef ROSCONSOLE_PRINTF_ATTRIBUTE
#define ROSCONSOLE_PRINTF_ATTRIBUTE(a, b)
#endif
namespace boost
{
template<typename T> class shared_array;
}
namespace ros
{
namespace console
{
ROSCONSOLE_DECL void shutdown();
#ifdef ROSCONSOLE_BACKEND_LOG4CXX
extern ROSCONSOLE_DECL log4cxx::LevelPtr g_level_lookup[];
#endif
extern ROSCONSOLE_DECL bool get_loggers(std::map<std::string, levels::Level>& loggers);
extern ROSCONSOLE_DECL bool set_logger_level(const std::string& name, levels::Level level);
/**
* \brief Only exported because the macros need it. Do not use directly.
*/
extern ROSCONSOLE_DECL bool g_initialized;
/**
* \brief Only exported because the TopicManager need it. Do not use directly.
*/
extern ROSCONSOLE_DECL std::string g_last_error_message;
class LogAppender
{
public:
virtual ~LogAppender() {}
virtual void log(::ros::console::Level level, const char* str, const char* file, const char* function, int line) = 0;
};
ROSCONSOLE_DECL void register_appender(LogAppender* appender);
struct Token
{
virtual ~Token() {}
/*
* @param level
* @param message
* @param file
* @param function
* @param line
*/
virtual std::string getString(void*, ::ros::console::Level, const char*, const char*, const char*, int) = 0;
};
typedef boost::shared_ptr<Token> TokenPtr;
typedef std::vector<TokenPtr> V_Token;
struct Formatter
{
void init(const char* fmt);
void print(void* logger_handle, ::ros::console::Level level, const char* str, const char* file, const char* function, int line);
std::string format_;
V_Token tokens_;
};
/**
* \brief Only exported because the implementation need it. Do not use directly.
*/
extern ROSCONSOLE_DECL Formatter g_formatter;
/**
* \brief Don't call this directly. Performs any required initialization/configuration. Happens automatically when using the macro API.
*
* If you're going to be using log4cxx or any of the ::ros::console functions, and need the system to be initialized, use the
* ROSCONSOLE_AUTOINIT macro.
*/
ROSCONSOLE_DECL void initialize();
class FilterBase;
/**
* \brief Don't call this directly. Use the ROS_LOG() macro instead.
* @param level Logging level
* @param file File this logging statement is from (usually generated with __FILE__)
* @param line Line of code this logging statement is from (usually generated with __LINE__)
* @param fmt Format string
*/
ROSCONSOLE_DECL void print(FilterBase* filter, void* logger, Level level,
const char* file, int line,
const char* function, const char* fmt, ...) ROSCONSOLE_PRINTF_ATTRIBUTE(7, 8);
ROSCONSOLE_DECL void print(FilterBase* filter, void* logger, Level level,
const std::stringstream& str, const char* file, int line, const char* function);
struct ROSCONSOLE_DECL LogLocation;
/**
* \brief Registers a logging location with the system.
*
* This is used for the case where a logger's verbosity level changes, and we need to reset the enabled status of
* all the logging statements.
* @param loc The location to add
*/
ROSCONSOLE_DECL void registerLogLocation(LogLocation* loc);
/**
* \brief Tells the system that a logger's level has changed
*
* This must be called if a log4cxx::Logger's level has been changed in the middle of an application run.
* Because of the way the static guard for enablement works, if a logger's level is changed and this
* function is not called, only logging statements which are first hit *after* the change will be correct wrt
* that logger.
*/
ROSCONSOLE_DECL void notifyLoggerLevelsChanged();
ROSCONSOLE_DECL void setFixedFilterToken(const std::string& key, const std::string& val);
/**
* \brief Parameter structure passed to FilterBase::isEnabled(...);. Includes both input and output parameters
*/
struct FilterParams
{
// input parameters
const char* file; ///< [input] File the message came from
int line; ///< [input] Line the message came from
const char* function; ///< [input] Function the message came from
const char* message; ///< [input] The formatted message that will be output
// input/output parameters
void* logger; ///< [input/output] Handle identifying logger that this message will be output to. If changed, uses the new logger
Level level; ///< [input/output] Severity level. If changed, uses the new level
// output parameters
std::string out_message; ///< [output] If set, writes this message instead of the original
};
/**
* \brief Base-class for filters. Filters allow full user-defined control over whether or not a message should print.
* The ROS_X_FILTER... macros provide the filtering functionality.
*
* Filters get a chance to veto the message from printing at two times: first before the message arguments are
* evaluated and the message is formatted, and then once the message is formatted before it is printed. It is also possible
* to change the message, logger and severity level at this stage (see the FilterParams struct for more details).
*
* When a ROS_X_FILTER... macro is called, here is the high-level view of how it uses the filter passed in:
\verbatim
if (<logging level is enabled> && filter->isEnabled())
{
<format message>
<fill out FilterParams>
if (filter->isEnabled(params))
{
<print message>
}
}
\endverbatim
*/
class FilterBase
{
public:
virtual ~FilterBase() {}
/**
* \brief Returns whether or not the log statement should be printed. Called before the log arguments are evaluated
* and the message is formatted.
*/
inline virtual bool isEnabled() { return true; }
/**
* \brief Returns whether or not the log statement should be printed. Called once the message has been formatted,
* and allows you to change the message, logger and severity level if necessary.
*/
inline virtual bool isEnabled(FilterParams&) { return true; }
};
struct ROSCONSOLE_DECL LogLocation;
/**
* \brief Internal
*/
ROSCONSOLE_DECL void initializeLogLocation(LogLocation* loc, const std::string& name, Level level);
/**
* \brief Internal
*/
ROSCONSOLE_DECL void setLogLocationLevel(LogLocation* loc, Level level);
/**
* \brief Internal
*/
ROSCONSOLE_DECL void checkLogLocationEnabled(LogLocation* loc);
/**
* \brief Internal
*/
struct LogLocation
{
bool initialized_;
bool logger_enabled_;
::ros::console::Level level_;
void* logger_;
};
ROSCONSOLE_DECL void vformatToBuffer(boost::shared_array<char>& buffer, size_t& buffer_size, const char* fmt, va_list args);
ROSCONSOLE_DECL void formatToBuffer(boost::shared_array<char>& buffer, size_t& buffer_size, const char* fmt, ...);
ROSCONSOLE_DECL std::string formatToString(const char* fmt, ...);
} // namespace console
} // namespace ros
#ifdef WIN32
#define ROS_LIKELY(x) (x)
#define ROS_UNLIKELY(x) (x)
#else
#define ROS_LIKELY(x) __builtin_expect((x),1)
#define ROS_UNLIKELY(x) __builtin_expect((x),0)
#endif
#if defined(MSVC)
#define __ROSCONSOLE_FUNCTION__ __FUNCSIG__
#elif defined(__GNUC__)
#define __ROSCONSOLE_FUNCTION__ __PRETTY_FUNCTION__
#else
#define __ROSCONSOLE_FUNCTION__ ""
#endif
#ifdef ROS_PACKAGE_NAME
#define ROSCONSOLE_PACKAGE_NAME ROS_PACKAGE_NAME
#else
#define ROSCONSOLE_PACKAGE_NAME "unknown_package"
#endif
#define ROSCONSOLE_ROOT_LOGGER_NAME "ros"
#define ROSCONSOLE_NAME_PREFIX ROSCONSOLE_ROOT_LOGGER_NAME "." ROSCONSOLE_PACKAGE_NAME
#define ROSCONSOLE_DEFAULT_NAME ROSCONSOLE_NAME_PREFIX
// These allow you to compile-out everything below a certain severity level if necessary
#define ROSCONSOLE_SEVERITY_DEBUG 0
#define ROSCONSOLE_SEVERITY_INFO 1
#define ROSCONSOLE_SEVERITY_WARN 2
#define ROSCONSOLE_SEVERITY_ERROR 3
#define ROSCONSOLE_SEVERITY_FATAL 4
#define ROSCONSOLE_SEVERITY_NONE 5
/**
* \def ROSCONSOLE_MIN_SEVERITY
*
* Define ROSCONSOLE_MIN_SEVERITY=ROSCONSOLE_SEVERITY_[DEBUG|INFO|WARN|ERROR|FATAL] in your build options to compile out anything below that severity
*/
#ifndef ROSCONSOLE_MIN_SEVERITY
#define ROSCONSOLE_MIN_SEVERITY ROSCONSOLE_SEVERITY_DEBUG
#endif
/**
* \def ROSCONSOLE_AUTOINIT
* \brief Initializes the rosconsole library. Usually unnecessary to call directly.
*/
#define ROSCONSOLE_AUTOINIT \
do \
{ \
if (ROS_UNLIKELY(!::ros::console::g_initialized)) \
{ \
::ros::console::initialize(); \
} \
} while(false)
#define ROSCONSOLE_DEFINE_LOCATION(cond, level, name) \
ROSCONSOLE_AUTOINIT; \
static ::ros::console::LogLocation __rosconsole_define_location__loc = {false, false, ::ros::console::levels::Count, 0}; /* Initialized at compile-time */ \
if (ROS_UNLIKELY(!__rosconsole_define_location__loc.initialized_)) \
{ \
initializeLogLocation(&__rosconsole_define_location__loc, name, level); \
} \
if (ROS_UNLIKELY(__rosconsole_define_location__loc.level_ != level)) \
{ \
setLogLocationLevel(&__rosconsole_define_location__loc, level); \
checkLogLocationEnabled(&__rosconsole_define_location__loc); \
} \
bool __rosconsole_define_location__enabled = __rosconsole_define_location__loc.logger_enabled_ && (cond);
#define ROSCONSOLE_PRINT_AT_LOCATION_WITH_FILTER(filter, ...) \
::ros::console::print(filter, __rosconsole_define_location__loc.logger_, __rosconsole_define_location__loc.level_, __FILE__, __LINE__, __ROSCONSOLE_FUNCTION__, __VA_ARGS__)
#define ROSCONSOLE_PRINT_AT_LOCATION(...) \
ROSCONSOLE_PRINT_AT_LOCATION_WITH_FILTER(0, __VA_ARGS__)
// inside a macro which uses args use only well namespaced variable names in order to not overlay variables coming in via args
#define ROSCONSOLE_PRINT_STREAM_AT_LOCATION_WITH_FILTER(filter, args) \
do \
{ \
std::stringstream __rosconsole_print_stream_at_location_with_filter__ss__; \
__rosconsole_print_stream_at_location_with_filter__ss__ << args; \
::ros::console::print(filter, __rosconsole_define_location__loc.logger_, __rosconsole_define_location__loc.level_, __rosconsole_print_stream_at_location_with_filter__ss__, __FILE__, __LINE__, __ROSCONSOLE_FUNCTION__); \
} while (0)
#define ROSCONSOLE_PRINT_STREAM_AT_LOCATION(args) \
ROSCONSOLE_PRINT_STREAM_AT_LOCATION_WITH_FILTER(0, args)
/**
* \brief Log to a given named logger at a given verbosity level, only if a given condition has been met, with printf-style formatting
*
* \note The condition will only be evaluated if this logging statement is enabled
*
* \param cond Boolean condition to be evaluated
* \param level One of the levels specified in ::ros::console::levels::Level
* \param name Name of the logger. Note that this is the fully qualified name, and does NOT include "ros.<package_name>". Use ROSCONSOLE_DEFAULT_NAME if you would like to use the default name.
*/
#define ROS_LOG_COND(cond, level, name, ...) \
do \
{ \
ROSCONSOLE_DEFINE_LOCATION(cond, level, name); \
\
if (ROS_UNLIKELY(__rosconsole_define_location__enabled)) \
{ \
ROSCONSOLE_PRINT_AT_LOCATION(__VA_ARGS__); \
} \
} while(false)
/**
* \brief Log to a given named logger at a given verbosity level, only if a given condition has been met, with stream-style formatting
*
* \note The condition will only be evaluated if this logging statement is enabled
*
* \param cond Boolean condition to be evaluated
* \param level One of the levels specified in ::ros::console::levels::Level
* \param name Name of the logger. Note that this is the fully qualified name, and does NOT include "ros.<package_name>". Use ROSCONSOLE_DEFAULT_NAME if you would like to use the default name.
*/
#define ROS_LOG_STREAM_COND(cond, level, name, args) \
do \
{ \
ROSCONSOLE_DEFINE_LOCATION(cond, level, name); \
if (ROS_UNLIKELY(__rosconsole_define_location__enabled)) \
{ \
ROSCONSOLE_PRINT_STREAM_AT_LOCATION(args); \
} \
} while(false)
/**
* \brief Log to a given named logger at a given verbosity level, only the first time it is hit when enabled, with printf-style formatting
*
* \param level One of the levels specified in ::ros::console::levels::Level
* \param name Name of the logger. Note that this is the fully qualified name, and does NOT include "ros.<package_name>". Use ROSCONSOLE_DEFAULT_NAME if you would like to use the default name.
*/
#define ROS_LOG_ONCE(level, name, ...) \
do \
{ \
ROSCONSOLE_DEFINE_LOCATION(true, level, name); \
static bool hit = false; \
if (ROS_UNLIKELY(__rosconsole_define_location__enabled) && ROS_UNLIKELY(!hit)) \
{ \
hit = true; \
ROSCONSOLE_PRINT_AT_LOCATION(__VA_ARGS__); \
} \
} while(false)
// inside a macro which uses args use only well namespaced variable names in order to not overlay variables coming in via args
/**
* \brief Log to a given named logger at a given verbosity level, only the first time it is hit when enabled, with printf-style formatting
*
* \param level One of the levels specified in ::ros::console::levels::Level
* \param name Name of the logger. Note that this is the fully qualified name, and does NOT include "ros.<package_name>". Use ROSCONSOLE_DEFAULT_NAME if you would like to use the default name.
*/
#define ROS_LOG_STREAM_ONCE(level, name, args) \
do \
{ \
ROSCONSOLE_DEFINE_LOCATION(true, level, name); \
static bool __ros_log_stream_once__hit__ = false; \
if (ROS_UNLIKELY(__rosconsole_define_location__enabled) && ROS_UNLIKELY(!__ros_log_stream_once__hit__)) \
{ \
__ros_log_stream_once__hit__ = true; \
ROSCONSOLE_PRINT_STREAM_AT_LOCATION(args); \
} \
} while(false)
/**
* \brief Log to a given named logger at a given verbosity level, limited to a specific rate of printing, with printf-style formatting
*
* \param level One of the levels specified in ::ros::console::levels::Level
* \param name Name of the logger. Note that this is the fully qualified name, and does NOT include "ros.<package_name>". Use ROSCONSOLE_DEFAULT_NAME if you would like to use the default name.
* \param rate The rate it should actually trigger at
*/
#define ROS_LOG_THROTTLE(rate, level, name, ...) \
do \
{ \
ROSCONSOLE_DEFINE_LOCATION(true, level, name); \
static double last_hit = 0.0; \
::ros::Time now = ::ros::Time::now(); \
if (ROS_UNLIKELY(__rosconsole_define_location__enabled) && ROS_UNLIKELY(last_hit + rate <= now.toSec())) \
{ \
last_hit = now.toSec(); \
ROSCONSOLE_PRINT_AT_LOCATION(__VA_ARGS__); \
} \
} while(false)
// inside a macro which uses args use only well namespaced variable names in order to not overlay variables coming in via args
/**
* \brief Log to a given named logger at a given verbosity level, limited to a specific rate of printing, with printf-style formatting
*
* \param level One of the levels specified in ::ros::console::levels::Level
* \param name Name of the logger. Note that this is the fully qualified name, and does NOT include "ros.<package_name>". Use ROSCONSOLE_DEFAULT_NAME if you would like to use the default name.
* \param rate The rate it should actually trigger at
*/
#define ROS_LOG_STREAM_THROTTLE(rate, level, name, args) \
do \
{ \
ROSCONSOLE_DEFINE_LOCATION(true, level, name); \
static double __ros_log_stream_throttle__last_hit__ = 0.0; \
::ros::Time __ros_log_stream_throttle__now__ = ::ros::Time::now(); \
if (ROS_UNLIKELY(__rosconsole_define_location__enabled) && ROS_UNLIKELY(__ros_log_stream_throttle__last_hit__ + rate <= __ros_log_stream_throttle__now__.toSec())) \
{ \
__ros_log_stream_throttle__last_hit__ = __ros_log_stream_throttle__now__.toSec(); \
ROSCONSOLE_PRINT_STREAM_AT_LOCATION(args); \
} \
} while(false)
/**
* \brief Log to a given named logger at a given verbosity level, limited to a specific rate of printing, with printf-style formatting
*
* \param level One of the levels specified in ::ros::console::levels::Level
* \param name Name of the logger. Note that this is the fully qualified name, and does NOT include "ros.<package_name>". Use ROSCONSOLE_DEFAULT_NAME if you would like to use the default name.
* \param rate The rate it should actually trigger at
*/
#define ROS_LOG_DELAYED_THROTTLE(rate, level, name, ...) \
do \
{ \
ROSCONSOLE_DEFINE_LOCATION(true, level, name); \
::ros::Time __ros_log_delayed_throttle__now__ = ::ros::Time::now(); \
static double __ros_log_delayed_throttle__last_hit__ = __ros_log_delayed_throttle__now__.toSec(); \
if (ROS_UNLIKELY(__rosconsole_define_location__enabled) && ROS_UNLIKELY(__ros_log_delayed_throttle__last_hit__ + rate <= __ros_log_delayed_throttle__now__.toSec())) \
{ \
__ros_log_delayed_throttle__last_hit__ = __ros_log_delayed_throttle__now__.toSec(); \
ROSCONSOLE_PRINT_AT_LOCATION(__VA_ARGS__); \
} \
} while(false)
// inside a macro which uses args use only well namespaced variable names in order to not overlay variables coming in via args
/**
* \brief Log to a given named logger at a given verbosity level, limited to a specific rate of printing and postponed first message
*
* \param level One of the levels specified in ::ros::console::levels::Level
* \param name Name of the logger. Note that this is the fully qualified name, and does NOT include "ros.<package_name>". Use ROSCONSOLE_DEFAULT_NAME if you would like to use the default name.
* \param rate The rate it should actually trigger at, and the delay before which no message will be shown.
*/
#define ROS_LOG_STREAM_DELAYED_THROTTLE(rate, level, name, args) \
do \
{ \
ROSCONSOLE_DEFINE_LOCATION(true, level, name); \
::ros::Time __ros_log_stream_delayed_throttle__now__ = ::ros::Time::now(); \
static double __ros_log_stream_delayed_throttle__last_hit__ = __ros_log_stream_delayed_throttle__now__.toSec(); \
if (ROS_UNLIKELY(__rosconsole_define_location__enabled) && ROS_UNLIKELY(__ros_log_stream_delayed_throttle__last_hit__ + rate <= __ros_log_stream_delayed_throttle__now__.toSec())) \
{ \
__ros_log_stream_delayed_throttle__last_hit__ = __ros_log_stream_delayed_throttle__now__.toSec(); \
ROSCONSOLE_PRINT_STREAM_AT_LOCATION(args); \
} \
} while(false)
/**
* \brief Log to a given named logger at a given verbosity level, with user-defined filtering, with printf-style formatting
*
* \param filter pointer to the filter to be used
* \param level One of the levels specified in ::ros::console::levels::Level
* \param name Name of the logger. Note that this is the fully qualified name, and does NOT include "ros.<package_name>". Use ROSCONSOLE_DEFAULT_NAME if you would like to use the default name.
*/
#define ROS_LOG_FILTER(filter, level, name, ...) \
do \
{ \
ROSCONSOLE_DEFINE_LOCATION(true, level, name); \
if (ROS_UNLIKELY(__rosconsole_define_location__enabled) && (filter)->isEnabled()) \
{ \
ROSCONSOLE_PRINT_AT_LOCATION_WITH_FILTER(filter, __VA_ARGS__); \
} \
} while(false)
/**
* \brief Log to a given named logger at a given verbosity level, with user-defined filtering, with stream-style formatting
*
* \param cond Boolean condition to be evaluated
* \param level One of the levels specified in ::ros::console::levels::Level
* \param name Name of the logger. Note that this is the fully qualified name, and does NOT include "ros.<package_name>". Use ROSCONSOLE_DEFAULT_NAME if you would like to use the default name.
*/
#define ROS_LOG_STREAM_FILTER(filter, level, name, args) \
do \
{ \
ROSCONSOLE_DEFINE_LOCATION(true, level, name); \
if (ROS_UNLIKELY(__rosconsole_define_location__enabled) && (filter)->isEnabled()) \
{ \
ROSCONSOLE_PRINT_STREAM_AT_LOCATION_WITH_FILTER(filter, args); \
} \
} while(false)
/**
* \brief Log to a given named logger at a given verbosity level, with printf-style formatting
*
* \param level One of the levels specified in ::ros::console::levels::Level
* \param name Name of the logger. Note that this is the fully qualified name, and does NOT include "ros.<package_name>". Use ROSCONSOLE_DEFAULT_NAME if you would like to use the default name.
*/
#define ROS_LOG(level, name, ...) ROS_LOG_COND(true, level, name, __VA_ARGS__)
/**
* \brief Log to a given named logger at a given verbosity level, with stream-style formatting
*
* \param level One of the levels specified in ::ros::console::levels::Level
* \param name Name of the logger. Note that this is the fully qualified name, and does NOT include "ros.<package_name>". Use ROSCONSOLE_DEFAULT_NAME if you would like to use the default name.
*/
#define ROS_LOG_STREAM(level, name, args) ROS_LOG_STREAM_COND(true, level, name, args)
#include "rosconsole/macros_generated.h"
#endif // ROSCONSOLE_ROSCONSOLE_H

View File

@@ -0,0 +1,68 @@
/*
* Copyright (c) 2013, Open Source Robotics Foundation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the Willow Garage, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ROSCONSOLE_CONSOLE_BACKEND_H
#define ROSCONSOLE_CONSOLE_BACKEND_H
namespace ros
{
namespace console
{
namespace levels
{
enum Level
{
Debug,
Info,
Warn,
Error,
Fatal,
Count
};
}
typedef levels::Level Level;
namespace backend
{
void notifyLoggerLevelsChanged();
extern void (*function_notifyLoggerLevelsChanged)();
void print(void* logger_handle, ::ros::console::Level level, const char* str, const char* file, const char* function, int line);
extern void (*function_print)(void*, ::ros::console::Level, const char*, const char*, const char*, int);
} // namespace backend
} // namespace console
} // namespace ros
#endif // ROSCONSOLE_CONSOLE_BACKEND_H

View File

@@ -0,0 +1,70 @@
/*
* Copyright (c) 2008, Willow Garage, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Willow Garage, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
// Author: Josh Faust
#ifndef ROSCONSOLE_STATIC_ASSERT_H
#define ROSCONSOLE_STATIC_ASSERT_H
// boost's static assert provides better errors messages in the failure case when using
// in templated situations
#include <boost/static_assert.hpp>
/**
* \def ROS_COMPILE_ASSERT(cond)
* \brief Compile-time assert.
*
* Only works with compile time statements, ie:
@verbatim
struct A
{
uint32_t a;
};
ROS_COMPILE_ASSERT(sizeof(A) == 4);
@endverbatim
*/
#define ROS_COMPILE_ASSERT(cond) BOOST_STATIC_ASSERT(cond)
/**
* \def ROS_STATIC_ASSERT(cond)
* \brief Compile-time assert.
*
* Only works with compile time statements, ie:
@verbatim
struct A
{
uint32_t a;
};
ROS_STATIC_ASSERT(sizeof(A) == 4);
@endverbatim
*/
#define ROS_STATIC_ASSERT(cond) BOOST_STATIC_ASSERT(cond)
#endif // ROSCONSOLE_STATIC_ASSERT_H

View File

@@ -0,0 +1,291 @@
// !!!!!!!!!!!!!!!!!!!!!!! This is a generated file, do not edit manually
/*
* Copyright (c) 2008, Willow Garage, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Willow Garage, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#if (ROSCONSOLE_MIN_SEVERITY > ROSCONSOLE_SEVERITY_DEBUG)
#define ROS_DEBUG(...)
#define ROS_DEBUG_STREAM(args)
#define ROS_DEBUG_NAMED(name, ...)
#define ROS_DEBUG_STREAM_NAMED(name, args)
#define ROS_DEBUG_COND(cond, ...)
#define ROS_DEBUG_STREAM_COND(cond, args)
#define ROS_DEBUG_COND_NAMED(cond, name, ...)
#define ROS_DEBUG_STREAM_COND_NAMED(cond, name, args)
#define ROS_DEBUG_ONCE(...)
#define ROS_DEBUG_STREAM_ONCE(args)
#define ROS_DEBUG_ONCE_NAMED(name, ...)
#define ROS_DEBUG_STREAM_ONCE_NAMED(name, args)
#define ROS_DEBUG_THROTTLE(rate, ...)
#define ROS_DEBUG_STREAM_THROTTLE(rate, args)
#define ROS_DEBUG_THROTTLE_NAMED(rate, name, ...)
#define ROS_DEBUG_STREAM_THROTTLE_NAMED(rate, name, args)
#define ROS_DEBUG_DELAYED_THROTTLE(rate, ...)
#define ROS_DEBUG_STREAM_DELAYED_THROTTLE(rate, args)
#define ROS_DEBUG_DELAYED_THROTTLE_NAMED(rate, name, ...)
#define ROS_DEBUG_STREAM_DELAYED_THROTTLE_NAMED(rate, name, args)
#define ROS_DEBUG_FILTER(filter, ...)
#define ROS_DEBUG_STREAM_FILTER(filter, args)
#define ROS_DEBUG_FILTER_NAMED(filter, name, ...)
#define ROS_DEBUG_STREAM_FILTER_NAMED(filter, name, args)
#else
#define ROS_DEBUG(...) ROS_LOG(::ros::console::levels::Debug, ROSCONSOLE_DEFAULT_NAME, __VA_ARGS__)
#define ROS_DEBUG_STREAM(args) ROS_LOG_STREAM(::ros::console::levels::Debug, ROSCONSOLE_DEFAULT_NAME, args)
#define ROS_DEBUG_NAMED(name, ...) ROS_LOG(::ros::console::levels::Debug, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, __VA_ARGS__)
#define ROS_DEBUG_STREAM_NAMED(name, args) ROS_LOG_STREAM(::ros::console::levels::Debug, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, args)
#define ROS_DEBUG_COND(cond, ...) ROS_LOG_COND(cond, ::ros::console::levels::Debug, ROSCONSOLE_DEFAULT_NAME, __VA_ARGS__)
#define ROS_DEBUG_STREAM_COND(cond, args) ROS_LOG_STREAM_COND(cond, ::ros::console::levels::Debug, ROSCONSOLE_DEFAULT_NAME, args)
#define ROS_DEBUG_COND_NAMED(cond, name, ...) ROS_LOG_COND(cond, ::ros::console::levels::Debug, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, __VA_ARGS__)
#define ROS_DEBUG_STREAM_COND_NAMED(cond, name, args) ROS_LOG_STREAM_COND(cond, ::ros::console::levels::Debug, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, args)
#define ROS_DEBUG_ONCE(...) ROS_LOG_ONCE(::ros::console::levels::Debug, ROSCONSOLE_DEFAULT_NAME, __VA_ARGS__)
#define ROS_DEBUG_STREAM_ONCE(args) ROS_LOG_STREAM_ONCE(::ros::console::levels::Debug, ROSCONSOLE_DEFAULT_NAME, args)
#define ROS_DEBUG_ONCE_NAMED(name, ...) ROS_LOG_ONCE(::ros::console::levels::Debug, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, __VA_ARGS__)
#define ROS_DEBUG_STREAM_ONCE_NAMED(name, args) ROS_LOG_STREAM_ONCE(::ros::console::levels::Debug, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, args)
#define ROS_DEBUG_THROTTLE(rate, ...) ROS_LOG_THROTTLE(rate, ::ros::console::levels::Debug, ROSCONSOLE_DEFAULT_NAME, __VA_ARGS__)
#define ROS_DEBUG_STREAM_THROTTLE(rate, args) ROS_LOG_STREAM_THROTTLE(rate, ::ros::console::levels::Debug, ROSCONSOLE_DEFAULT_NAME, args)
#define ROS_DEBUG_THROTTLE_NAMED(rate, name, ...) ROS_LOG_THROTTLE(rate, ::ros::console::levels::Debug, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, __VA_ARGS__)
#define ROS_DEBUG_STREAM_THROTTLE_NAMED(rate, name, args) ROS_LOG_STREAM_THROTTLE(rate, ::ros::console::levels::Debug, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, args)
#define ROS_DEBUG_DELAYED_THROTTLE(rate, ...) ROS_LOG_DELAYED_THROTTLE(rate, ::ros::console::levels::Debug, ROSCONSOLE_DEFAULT_NAME, __VA_ARGS__)
#define ROS_DEBUG_STREAM_DELAYED_THROTTLE(rate, args) ROS_LOG_STREAM_DELAYED_THROTTLE(rate, ::ros::console::levels::Debug, ROSCONSOLE_DEFAULT_NAME, args)
#define ROS_DEBUG_DELAYED_THROTTLE_NAMED(rate, name, ...) ROS_LOG_DELAYED_THROTTLE(rate, ::ros::console::levels::Debug, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, __VA_ARGS__)
#define ROS_DEBUG_STREAM_DELAYED_THROTTLE_NAMED(rate, name, args) ROS_LOG_STREAM_DELAYED_THROTTLE(rate, ::ros::console::levels::Debug, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, args)
#define ROS_DEBUG_FILTER(filter, ...) ROS_LOG_FILTER(filter, ::ros::console::levels::Debug, ROSCONSOLE_DEFAULT_NAME, __VA_ARGS__)
#define ROS_DEBUG_STREAM_FILTER(filter, args) ROS_LOG_STREAM_FILTER(filter, ::ros::console::levels::Debug, ROSCONSOLE_DEFAULT_NAME, args)
#define ROS_DEBUG_FILTER_NAMED(filter, name, ...) ROS_LOG_FILTER(filter, ::ros::console::levels::Debug, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, __VA_ARGS__)
#define ROS_DEBUG_STREAM_FILTER_NAMED(filter, name, args) ROS_LOG_STREAM_FILTER(filter, ::ros::console::levels::Debug, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, args)
#endif
#if (ROSCONSOLE_MIN_SEVERITY > ROSCONSOLE_SEVERITY_INFO)
#define ROS_INFO(...)
#define ROS_INFO_STREAM(args)
#define ROS_INFO_NAMED(name, ...)
#define ROS_INFO_STREAM_NAMED(name, args)
#define ROS_INFO_COND(cond, ...)
#define ROS_INFO_STREAM_COND(cond, args)
#define ROS_INFO_COND_NAMED(cond, name, ...)
#define ROS_INFO_STREAM_COND_NAMED(cond, name, args)
#define ROS_INFO_ONCE(...)
#define ROS_INFO_STREAM_ONCE(args)
#define ROS_INFO_ONCE_NAMED(name, ...)
#define ROS_INFO_STREAM_ONCE_NAMED(name, args)
#define ROS_INFO_THROTTLE(rate, ...)
#define ROS_INFO_STREAM_THROTTLE(rate, args)
#define ROS_INFO_THROTTLE_NAMED(rate, name, ...)
#define ROS_INFO_STREAM_THROTTLE_NAMED(rate, name, args)
#define ROS_INFO_DELAYED_THROTTLE(rate, ...)
#define ROS_INFO_STREAM_DELAYED_THROTTLE(rate, args)
#define ROS_INFO_DELAYED_THROTTLE_NAMED(rate, name, ...)
#define ROS_INFO_STREAM_DELAYED_THROTTLE_NAMED(rate, name, args)
#define ROS_INFO_FILTER(filter, ...)
#define ROS_INFO_STREAM_FILTER(filter, args)
#define ROS_INFO_FILTER_NAMED(filter, name, ...)
#define ROS_INFO_STREAM_FILTER_NAMED(filter, name, args)
#else
#define ROS_INFO(...) ROS_LOG(::ros::console::levels::Info, ROSCONSOLE_DEFAULT_NAME, __VA_ARGS__)
#define ROS_INFO_STREAM(args) ROS_LOG_STREAM(::ros::console::levels::Info, ROSCONSOLE_DEFAULT_NAME, args)
#define ROS_INFO_NAMED(name, ...) ROS_LOG(::ros::console::levels::Info, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, __VA_ARGS__)
#define ROS_INFO_STREAM_NAMED(name, args) ROS_LOG_STREAM(::ros::console::levels::Info, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, args)
#define ROS_INFO_COND(cond, ...) ROS_LOG_COND(cond, ::ros::console::levels::Info, ROSCONSOLE_DEFAULT_NAME, __VA_ARGS__)
#define ROS_INFO_STREAM_COND(cond, args) ROS_LOG_STREAM_COND(cond, ::ros::console::levels::Info, ROSCONSOLE_DEFAULT_NAME, args)
#define ROS_INFO_COND_NAMED(cond, name, ...) ROS_LOG_COND(cond, ::ros::console::levels::Info, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, __VA_ARGS__)
#define ROS_INFO_STREAM_COND_NAMED(cond, name, args) ROS_LOG_STREAM_COND(cond, ::ros::console::levels::Info, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, args)
#define ROS_INFO_ONCE(...) ROS_LOG_ONCE(::ros::console::levels::Info, ROSCONSOLE_DEFAULT_NAME, __VA_ARGS__)
#define ROS_INFO_STREAM_ONCE(args) ROS_LOG_STREAM_ONCE(::ros::console::levels::Info, ROSCONSOLE_DEFAULT_NAME, args)
#define ROS_INFO_ONCE_NAMED(name, ...) ROS_LOG_ONCE(::ros::console::levels::Info, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, __VA_ARGS__)
#define ROS_INFO_STREAM_ONCE_NAMED(name, args) ROS_LOG_STREAM_ONCE(::ros::console::levels::Info, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, args)
#define ROS_INFO_THROTTLE(rate, ...) ROS_LOG_THROTTLE(rate, ::ros::console::levels::Info, ROSCONSOLE_DEFAULT_NAME, __VA_ARGS__)
#define ROS_INFO_STREAM_THROTTLE(rate, args) ROS_LOG_STREAM_THROTTLE(rate, ::ros::console::levels::Info, ROSCONSOLE_DEFAULT_NAME, args)
#define ROS_INFO_THROTTLE_NAMED(rate, name, ...) ROS_LOG_THROTTLE(rate, ::ros::console::levels::Info, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, __VA_ARGS__)
#define ROS_INFO_STREAM_THROTTLE_NAMED(rate, name, args) ROS_LOG_STREAM_THROTTLE(rate, ::ros::console::levels::Info, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, args)
#define ROS_INFO_DELAYED_THROTTLE(rate, ...) ROS_LOG_DELAYED_THROTTLE(rate, ::ros::console::levels::Info, ROSCONSOLE_DEFAULT_NAME, __VA_ARGS__)
#define ROS_INFO_STREAM_DELAYED_THROTTLE(rate, args) ROS_LOG_STREAM_DELAYED_THROTTLE(rate, ::ros::console::levels::Info, ROSCONSOLE_DEFAULT_NAME, args)
#define ROS_INFO_DELAYED_THROTTLE_NAMED(rate, name, ...) ROS_LOG_DELAYED_THROTTLE(rate, ::ros::console::levels::Info, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, __VA_ARGS__)
#define ROS_INFO_STREAM_DELAYED_THROTTLE_NAMED(rate, name, args) ROS_LOG_STREAM_DELAYED_THROTTLE(rate, ::ros::console::levels::Info, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, args)
#define ROS_INFO_FILTER(filter, ...) ROS_LOG_FILTER(filter, ::ros::console::levels::Info, ROSCONSOLE_DEFAULT_NAME, __VA_ARGS__)
#define ROS_INFO_STREAM_FILTER(filter, args) ROS_LOG_STREAM_FILTER(filter, ::ros::console::levels::Info, ROSCONSOLE_DEFAULT_NAME, args)
#define ROS_INFO_FILTER_NAMED(filter, name, ...) ROS_LOG_FILTER(filter, ::ros::console::levels::Info, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, __VA_ARGS__)
#define ROS_INFO_STREAM_FILTER_NAMED(filter, name, args) ROS_LOG_STREAM_FILTER(filter, ::ros::console::levels::Info, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, args)
#endif
#if (ROSCONSOLE_MIN_SEVERITY > ROSCONSOLE_SEVERITY_WARN)
#define ROS_WARN(...)
#define ROS_WARN_STREAM(args)
#define ROS_WARN_NAMED(name, ...)
#define ROS_WARN_STREAM_NAMED(name, args)
#define ROS_WARN_COND(cond, ...)
#define ROS_WARN_STREAM_COND(cond, args)
#define ROS_WARN_COND_NAMED(cond, name, ...)
#define ROS_WARN_STREAM_COND_NAMED(cond, name, args)
#define ROS_WARN_ONCE(...)
#define ROS_WARN_STREAM_ONCE(args)
#define ROS_WARN_ONCE_NAMED(name, ...)
#define ROS_WARN_STREAM_ONCE_NAMED(name, args)
#define ROS_WARN_THROTTLE(rate, ...)
#define ROS_WARN_STREAM_THROTTLE(rate, args)
#define ROS_WARN_THROTTLE_NAMED(rate, name, ...)
#define ROS_WARN_STREAM_THROTTLE_NAMED(rate, name, args)
#define ROS_WARN_DELAYED_THROTTLE(rate, ...)
#define ROS_WARN_STREAM_DELAYED_THROTTLE(rate, args)
#define ROS_WARN_DELAYED_THROTTLE_NAMED(rate, name, ...)
#define ROS_WARN_STREAM_DELAYED_THROTTLE_NAMED(rate, name, args)
#define ROS_WARN_FILTER(filter, ...)
#define ROS_WARN_STREAM_FILTER(filter, args)
#define ROS_WARN_FILTER_NAMED(filter, name, ...)
#define ROS_WARN_STREAM_FILTER_NAMED(filter, name, args)
#else
#define ROS_WARN(...) ROS_LOG(::ros::console::levels::Warn, ROSCONSOLE_DEFAULT_NAME, __VA_ARGS__)
#define ROS_WARN_STREAM(args) ROS_LOG_STREAM(::ros::console::levels::Warn, ROSCONSOLE_DEFAULT_NAME, args)
#define ROS_WARN_NAMED(name, ...) ROS_LOG(::ros::console::levels::Warn, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, __VA_ARGS__)
#define ROS_WARN_STREAM_NAMED(name, args) ROS_LOG_STREAM(::ros::console::levels::Warn, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, args)
#define ROS_WARN_COND(cond, ...) ROS_LOG_COND(cond, ::ros::console::levels::Warn, ROSCONSOLE_DEFAULT_NAME, __VA_ARGS__)
#define ROS_WARN_STREAM_COND(cond, args) ROS_LOG_STREAM_COND(cond, ::ros::console::levels::Warn, ROSCONSOLE_DEFAULT_NAME, args)
#define ROS_WARN_COND_NAMED(cond, name, ...) ROS_LOG_COND(cond, ::ros::console::levels::Warn, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, __VA_ARGS__)
#define ROS_WARN_STREAM_COND_NAMED(cond, name, args) ROS_LOG_STREAM_COND(cond, ::ros::console::levels::Warn, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, args)
#define ROS_WARN_ONCE(...) ROS_LOG_ONCE(::ros::console::levels::Warn, ROSCONSOLE_DEFAULT_NAME, __VA_ARGS__)
#define ROS_WARN_STREAM_ONCE(args) ROS_LOG_STREAM_ONCE(::ros::console::levels::Warn, ROSCONSOLE_DEFAULT_NAME, args)
#define ROS_WARN_ONCE_NAMED(name, ...) ROS_LOG_ONCE(::ros::console::levels::Warn, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, __VA_ARGS__)
#define ROS_WARN_STREAM_ONCE_NAMED(name, args) ROS_LOG_STREAM_ONCE(::ros::console::levels::Warn, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, args)
#define ROS_WARN_THROTTLE(rate, ...) ROS_LOG_THROTTLE(rate, ::ros::console::levels::Warn, ROSCONSOLE_DEFAULT_NAME, __VA_ARGS__)
#define ROS_WARN_STREAM_THROTTLE(rate, args) ROS_LOG_STREAM_THROTTLE(rate, ::ros::console::levels::Warn, ROSCONSOLE_DEFAULT_NAME, args)
#define ROS_WARN_THROTTLE_NAMED(rate, name, ...) ROS_LOG_THROTTLE(rate, ::ros::console::levels::Warn, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, __VA_ARGS__)
#define ROS_WARN_STREAM_THROTTLE_NAMED(rate, name, args) ROS_LOG_STREAM_THROTTLE(rate, ::ros::console::levels::Warn, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, args)
#define ROS_WARN_DELAYED_THROTTLE(rate, ...) ROS_LOG_DELAYED_THROTTLE(rate, ::ros::console::levels::Warn, ROSCONSOLE_DEFAULT_NAME, __VA_ARGS__)
#define ROS_WARN_STREAM_DELAYED_THROTTLE(rate, args) ROS_LOG_STREAM_DELAYED_THROTTLE(rate, ::ros::console::levels::Warn, ROSCONSOLE_DEFAULT_NAME, args)
#define ROS_WARN_DELAYED_THROTTLE_NAMED(rate, name, ...) ROS_LOG_DELAYED_THROTTLE(rate, ::ros::console::levels::Warn, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, __VA_ARGS__)
#define ROS_WARN_STREAM_DELAYED_THROTTLE_NAMED(rate, name, args) ROS_LOG_STREAM_DELAYED_THROTTLE(rate, ::ros::console::levels::Warn, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, args)
#define ROS_WARN_FILTER(filter, ...) ROS_LOG_FILTER(filter, ::ros::console::levels::Warn, ROSCONSOLE_DEFAULT_NAME, __VA_ARGS__)
#define ROS_WARN_STREAM_FILTER(filter, args) ROS_LOG_STREAM_FILTER(filter, ::ros::console::levels::Warn, ROSCONSOLE_DEFAULT_NAME, args)
#define ROS_WARN_FILTER_NAMED(filter, name, ...) ROS_LOG_FILTER(filter, ::ros::console::levels::Warn, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, __VA_ARGS__)
#define ROS_WARN_STREAM_FILTER_NAMED(filter, name, args) ROS_LOG_STREAM_FILTER(filter, ::ros::console::levels::Warn, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, args)
#endif
#if (ROSCONSOLE_MIN_SEVERITY > ROSCONSOLE_SEVERITY_ERROR)
#define ROS_ERROR(...)
#define ROS_ERROR_STREAM(args)
#define ROS_ERROR_NAMED(name, ...)
#define ROS_ERROR_STREAM_NAMED(name, args)
#define ROS_ERROR_COND(cond, ...)
#define ROS_ERROR_STREAM_COND(cond, args)
#define ROS_ERROR_COND_NAMED(cond, name, ...)
#define ROS_ERROR_STREAM_COND_NAMED(cond, name, args)
#define ROS_ERROR_ONCE(...)
#define ROS_ERROR_STREAM_ONCE(args)
#define ROS_ERROR_ONCE_NAMED(name, ...)
#define ROS_ERROR_STREAM_ONCE_NAMED(name, args)
#define ROS_ERROR_THROTTLE(rate, ...)
#define ROS_ERROR_STREAM_THROTTLE(rate, args)
#define ROS_ERROR_THROTTLE_NAMED(rate, name, ...)
#define ROS_ERROR_STREAM_THROTTLE_NAMED(rate, name, args)
#define ROS_ERROR_DELAYED_THROTTLE(rate, ...)
#define ROS_ERROR_STREAM_DELAYED_THROTTLE(rate, args)
#define ROS_ERROR_DELAYED_THROTTLE_NAMED(rate, name, ...)
#define ROS_ERROR_STREAM_DELAYED_THROTTLE_NAMED(rate, name, args)
#define ROS_ERROR_FILTER(filter, ...)
#define ROS_ERROR_STREAM_FILTER(filter, args)
#define ROS_ERROR_FILTER_NAMED(filter, name, ...)
#define ROS_ERROR_STREAM_FILTER_NAMED(filter, name, args)
#else
#define ROS_ERROR(...) ROS_LOG(::ros::console::levels::Error, ROSCONSOLE_DEFAULT_NAME, __VA_ARGS__)
#define ROS_ERROR_STREAM(args) ROS_LOG_STREAM(::ros::console::levels::Error, ROSCONSOLE_DEFAULT_NAME, args)
#define ROS_ERROR_NAMED(name, ...) ROS_LOG(::ros::console::levels::Error, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, __VA_ARGS__)
#define ROS_ERROR_STREAM_NAMED(name, args) ROS_LOG_STREAM(::ros::console::levels::Error, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, args)
#define ROS_ERROR_COND(cond, ...) ROS_LOG_COND(cond, ::ros::console::levels::Error, ROSCONSOLE_DEFAULT_NAME, __VA_ARGS__)
#define ROS_ERROR_STREAM_COND(cond, args) ROS_LOG_STREAM_COND(cond, ::ros::console::levels::Error, ROSCONSOLE_DEFAULT_NAME, args)
#define ROS_ERROR_COND_NAMED(cond, name, ...) ROS_LOG_COND(cond, ::ros::console::levels::Error, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, __VA_ARGS__)
#define ROS_ERROR_STREAM_COND_NAMED(cond, name, args) ROS_LOG_STREAM_COND(cond, ::ros::console::levels::Error, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, args)
#define ROS_ERROR_ONCE(...) ROS_LOG_ONCE(::ros::console::levels::Error, ROSCONSOLE_DEFAULT_NAME, __VA_ARGS__)
#define ROS_ERROR_STREAM_ONCE(args) ROS_LOG_STREAM_ONCE(::ros::console::levels::Error, ROSCONSOLE_DEFAULT_NAME, args)
#define ROS_ERROR_ONCE_NAMED(name, ...) ROS_LOG_ONCE(::ros::console::levels::Error, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, __VA_ARGS__)
#define ROS_ERROR_STREAM_ONCE_NAMED(name, args) ROS_LOG_STREAM_ONCE(::ros::console::levels::Error, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, args)
#define ROS_ERROR_THROTTLE(rate, ...) ROS_LOG_THROTTLE(rate, ::ros::console::levels::Error, ROSCONSOLE_DEFAULT_NAME, __VA_ARGS__)
#define ROS_ERROR_STREAM_THROTTLE(rate, args) ROS_LOG_STREAM_THROTTLE(rate, ::ros::console::levels::Error, ROSCONSOLE_DEFAULT_NAME, args)
#define ROS_ERROR_THROTTLE_NAMED(rate, name, ...) ROS_LOG_THROTTLE(rate, ::ros::console::levels::Error, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, __VA_ARGS__)
#define ROS_ERROR_STREAM_THROTTLE_NAMED(rate, name, args) ROS_LOG_STREAM_THROTTLE(rate, ::ros::console::levels::Error, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, args)
#define ROS_ERROR_DELAYED_THROTTLE(rate, ...) ROS_LOG_DELAYED_THROTTLE(rate, ::ros::console::levels::Error, ROSCONSOLE_DEFAULT_NAME, __VA_ARGS__)
#define ROS_ERROR_STREAM_DELAYED_THROTTLE(rate, args) ROS_LOG_STREAM_DELAYED_THROTTLE(rate, ::ros::console::levels::Error, ROSCONSOLE_DEFAULT_NAME, args)
#define ROS_ERROR_DELAYED_THROTTLE_NAMED(rate, name, ...) ROS_LOG_DELAYED_THROTTLE(rate, ::ros::console::levels::Error, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, __VA_ARGS__)
#define ROS_ERROR_STREAM_DELAYED_THROTTLE_NAMED(rate, name, args) ROS_LOG_STREAM_DELAYED_THROTTLE(rate, ::ros::console::levels::Error, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, args)
#define ROS_ERROR_FILTER(filter, ...) ROS_LOG_FILTER(filter, ::ros::console::levels::Error, ROSCONSOLE_DEFAULT_NAME, __VA_ARGS__)
#define ROS_ERROR_STREAM_FILTER(filter, args) ROS_LOG_STREAM_FILTER(filter, ::ros::console::levels::Error, ROSCONSOLE_DEFAULT_NAME, args)
#define ROS_ERROR_FILTER_NAMED(filter, name, ...) ROS_LOG_FILTER(filter, ::ros::console::levels::Error, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, __VA_ARGS__)
#define ROS_ERROR_STREAM_FILTER_NAMED(filter, name, args) ROS_LOG_STREAM_FILTER(filter, ::ros::console::levels::Error, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, args)
#endif
#if (ROSCONSOLE_MIN_SEVERITY > ROSCONSOLE_SEVERITY_FATAL)
#define ROS_FATAL(...)
#define ROS_FATAL_STREAM(args)
#define ROS_FATAL_NAMED(name, ...)
#define ROS_FATAL_STREAM_NAMED(name, args)
#define ROS_FATAL_COND(cond, ...)
#define ROS_FATAL_STREAM_COND(cond, args)
#define ROS_FATAL_COND_NAMED(cond, name, ...)
#define ROS_FATAL_STREAM_COND_NAMED(cond, name, args)
#define ROS_FATAL_ONCE(...)
#define ROS_FATAL_STREAM_ONCE(args)
#define ROS_FATAL_ONCE_NAMED(name, ...)
#define ROS_FATAL_STREAM_ONCE_NAMED(name, args)
#define ROS_FATAL_THROTTLE(rate, ...)
#define ROS_FATAL_STREAM_THROTTLE(rate, args)
#define ROS_FATAL_THROTTLE_NAMED(rate, name, ...)
#define ROS_FATAL_STREAM_THROTTLE_NAMED(rate, name, args)
#define ROS_FATAL_DELAYED_THROTTLE(rate, ...)
#define ROS_FATAL_STREAM_DELAYED_THROTTLE(rate, args)
#define ROS_FATAL_DELAYED_THROTTLE_NAMED(rate, name, ...)
#define ROS_FATAL_STREAM_DELAYED_THROTTLE_NAMED(rate, name, args)
#define ROS_FATAL_FILTER(filter, ...)
#define ROS_FATAL_STREAM_FILTER(filter, args)
#define ROS_FATAL_FILTER_NAMED(filter, name, ...)
#define ROS_FATAL_STREAM_FILTER_NAMED(filter, name, args)
#else
#define ROS_FATAL(...) ROS_LOG(::ros::console::levels::Fatal, ROSCONSOLE_DEFAULT_NAME, __VA_ARGS__)
#define ROS_FATAL_STREAM(args) ROS_LOG_STREAM(::ros::console::levels::Fatal, ROSCONSOLE_DEFAULT_NAME, args)
#define ROS_FATAL_NAMED(name, ...) ROS_LOG(::ros::console::levels::Fatal, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, __VA_ARGS__)
#define ROS_FATAL_STREAM_NAMED(name, args) ROS_LOG_STREAM(::ros::console::levels::Fatal, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, args)
#define ROS_FATAL_COND(cond, ...) ROS_LOG_COND(cond, ::ros::console::levels::Fatal, ROSCONSOLE_DEFAULT_NAME, __VA_ARGS__)
#define ROS_FATAL_STREAM_COND(cond, args) ROS_LOG_STREAM_COND(cond, ::ros::console::levels::Fatal, ROSCONSOLE_DEFAULT_NAME, args)
#define ROS_FATAL_COND_NAMED(cond, name, ...) ROS_LOG_COND(cond, ::ros::console::levels::Fatal, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, __VA_ARGS__)
#define ROS_FATAL_STREAM_COND_NAMED(cond, name, args) ROS_LOG_STREAM_COND(cond, ::ros::console::levels::Fatal, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, args)
#define ROS_FATAL_ONCE(...) ROS_LOG_ONCE(::ros::console::levels::Fatal, ROSCONSOLE_DEFAULT_NAME, __VA_ARGS__)
#define ROS_FATAL_STREAM_ONCE(args) ROS_LOG_STREAM_ONCE(::ros::console::levels::Fatal, ROSCONSOLE_DEFAULT_NAME, args)
#define ROS_FATAL_ONCE_NAMED(name, ...) ROS_LOG_ONCE(::ros::console::levels::Fatal, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, __VA_ARGS__)
#define ROS_FATAL_STREAM_ONCE_NAMED(name, args) ROS_LOG_STREAM_ONCE(::ros::console::levels::Fatal, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, args)
#define ROS_FATAL_THROTTLE(rate, ...) ROS_LOG_THROTTLE(rate, ::ros::console::levels::Fatal, ROSCONSOLE_DEFAULT_NAME, __VA_ARGS__)
#define ROS_FATAL_STREAM_THROTTLE(rate, args) ROS_LOG_STREAM_THROTTLE(rate, ::ros::console::levels::Fatal, ROSCONSOLE_DEFAULT_NAME, args)
#define ROS_FATAL_THROTTLE_NAMED(rate, name, ...) ROS_LOG_THROTTLE(rate, ::ros::console::levels::Fatal, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, __VA_ARGS__)
#define ROS_FATAL_STREAM_THROTTLE_NAMED(rate, name, args) ROS_LOG_STREAM_THROTTLE(rate, ::ros::console::levels::Fatal, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, args)
#define ROS_FATAL_DELAYED_THROTTLE(rate, ...) ROS_LOG_DELAYED_THROTTLE(rate, ::ros::console::levels::Fatal, ROSCONSOLE_DEFAULT_NAME, __VA_ARGS__)
#define ROS_FATAL_STREAM_DELAYED_THROTTLE(rate, args) ROS_LOG_STREAM_DELAYED_THROTTLE(rate, ::ros::console::levels::Fatal, ROSCONSOLE_DEFAULT_NAME, args)
#define ROS_FATAL_DELAYED_THROTTLE_NAMED(rate, name, ...) ROS_LOG_DELAYED_THROTTLE(rate, ::ros::console::levels::Fatal, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, __VA_ARGS__)
#define ROS_FATAL_STREAM_DELAYED_THROTTLE_NAMED(rate, name, args) ROS_LOG_STREAM_DELAYED_THROTTLE(rate, ::ros::console::levels::Fatal, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, args)
#define ROS_FATAL_FILTER(filter, ...) ROS_LOG_FILTER(filter, ::ros::console::levels::Fatal, ROSCONSOLE_DEFAULT_NAME, __VA_ARGS__)
#define ROS_FATAL_STREAM_FILTER(filter, args) ROS_LOG_STREAM_FILTER(filter, ::ros::console::levels::Fatal, ROSCONSOLE_DEFAULT_NAME, args)
#define ROS_FATAL_FILTER_NAMED(filter, name, ...) ROS_LOG_FILTER(filter, ::ros::console::levels::Fatal, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, __VA_ARGS__)
#define ROS_FATAL_STREAM_FILTER_NAMED(filter, name, args) ROS_LOG_STREAM_FILTER(filter, ::ros::console::levels::Fatal, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, args)
#endif

View File

@@ -0,0 +1,11 @@
/**
* \mainpage
*
* \htmlinclude manifest.html
*
* \b rosconsole is a package for console output and logging. It provides a macro-based interface
* which allows both printf- and stream-style output. It also wraps log4cxx (http://logging.apache.org/log4cxx/index.html),
* which supports hierarchical loggers, verbosity levels and configuration-files.
*
*/

View File

@@ -0,0 +1,25 @@
<package>
<name>rosconsole</name>
<version>1.12.14</version>
<description>ROS console output library.</description>
<maintainer email="dthomas@osrfoundation.org">Dirk Thomas</maintainer>
<license>BSD</license>
<url>http://www.ros.org/wiki/rosconsole</url>
<author>Josh Faust</author>
<buildtool_depend>catkin</buildtool_depend>
<build_depend>apr</build_depend>
<build_depend>boost</build_depend>
<build_depend>cpp_common</build_depend>
<build_depend>log4cxx</build_depend>
<build_depend>rostime</build_depend>
<build_depend>rosunit</build_depend>
<run_depend>apr</run_depend>
<run_depend>cpp_common</run_depend>
<run_depend>log4cxx</run_depend>
<run_depend>rosbuild</run_depend>
<run_depend>rostime</run_depend>
</package>

View File

@@ -0,0 +1,137 @@
#!/usr/bin/python
# Software License Agreement (BSD License)
#
# Copyright (c) 2008, Willow Garage, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials provided
# with the distribution.
# * Neither the name of Willow Garage, Inc. nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
import os
import sys
def add_macro(f, caps_name, enum_name):
f.write('#if (ROSCONSOLE_MIN_SEVERITY > ROSCONSOLE_SEVERITY_%s)\n' %(caps_name))
f.write('#define ROS_%s(...)\n' %(caps_name))
f.write('#define ROS_%s_STREAM(args)\n' %(caps_name))
f.write('#define ROS_%s_NAMED(name, ...)\n' %(caps_name))
f.write('#define ROS_%s_STREAM_NAMED(name, args)\n' %(caps_name))
f.write('#define ROS_%s_COND(cond, ...)\n' %(caps_name))
f.write('#define ROS_%s_STREAM_COND(cond, args)\n' %(caps_name))
f.write('#define ROS_%s_COND_NAMED(cond, name, ...)\n' %(caps_name))
f.write('#define ROS_%s_STREAM_COND_NAMED(cond, name, args)\n' %(caps_name))
f.write('#define ROS_%s_ONCE(...)\n' %(caps_name))
f.write('#define ROS_%s_STREAM_ONCE(args)\n' %(caps_name))
f.write('#define ROS_%s_ONCE_NAMED(name, ...)\n' %(caps_name))
f.write('#define ROS_%s_STREAM_ONCE_NAMED(name, args)\n' %(caps_name))
f.write('#define ROS_%s_THROTTLE(rate, ...)\n' %(caps_name))
f.write('#define ROS_%s_STREAM_THROTTLE(rate, args)\n' %(caps_name))
f.write('#define ROS_%s_THROTTLE_NAMED(rate, name, ...)\n' %(caps_name))
f.write('#define ROS_%s_STREAM_THROTTLE_NAMED(rate, name, args)\n' %(caps_name))
f.write('#define ROS_%s_DELAYED_THROTTLE(rate, ...)\n' %(caps_name))
f.write('#define ROS_%s_STREAM_DELAYED_THROTTLE(rate, args)\n' %(caps_name))
f.write('#define ROS_%s_DELAYED_THROTTLE_NAMED(rate, name, ...)\n' %(caps_name))
f.write('#define ROS_%s_STREAM_DELAYED_THROTTLE_NAMED(rate, name, args)\n' %(caps_name))
f.write('#define ROS_%s_FILTER(filter, ...)\n' %(caps_name))
f.write('#define ROS_%s_STREAM_FILTER(filter, args)\n' %(caps_name))
f.write('#define ROS_%s_FILTER_NAMED(filter, name, ...)\n' %(caps_name))
f.write('#define ROS_%s_STREAM_FILTER_NAMED(filter, name, args)\n' %(caps_name))
f.write('#else\n')
f.write('#define ROS_%s(...) ROS_LOG(::ros::console::levels::%s, ROSCONSOLE_DEFAULT_NAME, __VA_ARGS__)\n' %(caps_name, enum_name))
f.write('#define ROS_%s_STREAM(args) ROS_LOG_STREAM(::ros::console::levels::%s, ROSCONSOLE_DEFAULT_NAME, args)\n' %(caps_name, enum_name))
f.write('#define ROS_%s_NAMED(name, ...) ROS_LOG(::ros::console::levels::%s, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, __VA_ARGS__)\n' %(caps_name, enum_name))
f.write('#define ROS_%s_STREAM_NAMED(name, args) ROS_LOG_STREAM(::ros::console::levels::%s, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, args)\n' %(caps_name, enum_name))
f.write('#define ROS_%s_COND(cond, ...) ROS_LOG_COND(cond, ::ros::console::levels::%s, ROSCONSOLE_DEFAULT_NAME, __VA_ARGS__)\n' %(caps_name, enum_name))
f.write('#define ROS_%s_STREAM_COND(cond, args) ROS_LOG_STREAM_COND(cond, ::ros::console::levels::%s, ROSCONSOLE_DEFAULT_NAME, args)\n' %(caps_name, enum_name))
f.write('#define ROS_%s_COND_NAMED(cond, name, ...) ROS_LOG_COND(cond, ::ros::console::levels::%s, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, __VA_ARGS__)\n' %(caps_name, enum_name))
f.write('#define ROS_%s_STREAM_COND_NAMED(cond, name, args) ROS_LOG_STREAM_COND(cond, ::ros::console::levels::%s, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, args)\n' %(caps_name, enum_name))
f.write('#define ROS_%s_ONCE(...) ROS_LOG_ONCE(::ros::console::levels::%s, ROSCONSOLE_DEFAULT_NAME, __VA_ARGS__)\n' %(caps_name, enum_name))
f.write('#define ROS_%s_STREAM_ONCE(args) ROS_LOG_STREAM_ONCE(::ros::console::levels::%s, ROSCONSOLE_DEFAULT_NAME, args)\n' %(caps_name, enum_name))
f.write('#define ROS_%s_ONCE_NAMED(name, ...) ROS_LOG_ONCE(::ros::console::levels::%s, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, __VA_ARGS__)\n' %(caps_name, enum_name))
f.write('#define ROS_%s_STREAM_ONCE_NAMED(name, args) ROS_LOG_STREAM_ONCE(::ros::console::levels::%s, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, args)\n' %(caps_name, enum_name))
f.write('#define ROS_%s_THROTTLE(rate, ...) ROS_LOG_THROTTLE(rate, ::ros::console::levels::%s, ROSCONSOLE_DEFAULT_NAME, __VA_ARGS__)\n' %(caps_name, enum_name))
f.write('#define ROS_%s_STREAM_THROTTLE(rate, args) ROS_LOG_STREAM_THROTTLE(rate, ::ros::console::levels::%s, ROSCONSOLE_DEFAULT_NAME, args)\n' %(caps_name, enum_name))
f.write('#define ROS_%s_THROTTLE_NAMED(rate, name, ...) ROS_LOG_THROTTLE(rate, ::ros::console::levels::%s, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, __VA_ARGS__)\n' %(caps_name, enum_name))
f.write('#define ROS_%s_STREAM_THROTTLE_NAMED(rate, name, args) ROS_LOG_STREAM_THROTTLE(rate, ::ros::console::levels::%s, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, args)\n' %(caps_name, enum_name))
f.write('#define ROS_%s_DELAYED_THROTTLE(rate, ...) ROS_LOG_DELAYED_THROTTLE(rate, ::ros::console::levels::%s, ROSCONSOLE_DEFAULT_NAME, __VA_ARGS__)\n' %(caps_name, enum_name))
f.write('#define ROS_%s_STREAM_DELAYED_THROTTLE(rate, args) ROS_LOG_STREAM_DELAYED_THROTTLE(rate, ::ros::console::levels::%s, ROSCONSOLE_DEFAULT_NAME, args)\n' %(caps_name, enum_name))
f.write('#define ROS_%s_DELAYED_THROTTLE_NAMED(rate, name, ...) ROS_LOG_DELAYED_THROTTLE(rate, ::ros::console::levels::%s, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, __VA_ARGS__)\n' %(caps_name, enum_name))
f.write('#define ROS_%s_STREAM_DELAYED_THROTTLE_NAMED(rate, name, args) ROS_LOG_STREAM_DELAYED_THROTTLE(rate, ::ros::console::levels::%s, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, args)\n' %(caps_name, enum_name))
f.write('#define ROS_%s_FILTER(filter, ...) ROS_LOG_FILTER(filter, ::ros::console::levels::%s, ROSCONSOLE_DEFAULT_NAME, __VA_ARGS__)\n' %(caps_name, enum_name))
f.write('#define ROS_%s_STREAM_FILTER(filter, args) ROS_LOG_STREAM_FILTER(filter, ::ros::console::levels::%s, ROSCONSOLE_DEFAULT_NAME, args)\n' %(caps_name, enum_name))
f.write('#define ROS_%s_FILTER_NAMED(filter, name, ...) ROS_LOG_FILTER(filter, ::ros::console::levels::%s, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, __VA_ARGS__)\n' %(caps_name, enum_name))
f.write('#define ROS_%s_STREAM_FILTER_NAMED(filter, name, args) ROS_LOG_STREAM_FILTER(filter, ::ros::console::levels::%s, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, args)\n' %(caps_name, enum_name))
f.write('#endif\n\n')
f = open('%s/../include/rosconsole/macros_generated.h' %(os.path.dirname(__file__)), 'w')
f.write("// !!!!!!!!!!!!!!!!!!!!!!! This is a generated file, do not edit manually\n\n")
f.write('/*\n')
f.write(' * Copyright (c) 2008, Willow Garage, Inc.\n')
f.write(' * All rights reserved.\n')
f.write(' *\n')
f.write(' * Redistribution and use in source and binary forms, with or without\n')
f.write(' * modification, are permitted provided that the following conditions are met:\n')
f.write(' *\n')
f.write(' * * Redistributions of source code must retain the above copyright\n')
f.write(' * notice, this list of conditions and the following disclaimer.\n')
f.write(' * * Redistributions in binary form must reproduce the above copyright\n')
f.write(' * notice, this list of conditions and the following disclaimer in the\n')
f.write(' * documentation and/or other materials provided with the distribution.\n')
f.write(' * * Neither the name of Willow Garage, Inc. nor the names of its\n')
f.write(' * contributors may be used to endorse or promote products derived from\n')
f.write(' * this software without specific prior written permission.\n')
f.write(' *\n')
f.write(' * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\n')
f.write(' * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n')
f.write(' * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n')
f.write(' * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n')
f.write(' * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n')
f.write(' * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n')
f.write(' * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n')
f.write(' * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n')
f.write(' * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n')
f.write(' * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n')
f.write(' * POSSIBILITY OF SUCH DAMAGE.\n')
f.write(' */\n\n')
add_macro(f, "DEBUG", "Debug")
add_macro(f, "INFO", "Info")
add_macro(f, "WARN", "Warn")
add_macro(f, "ERROR", "Error")
add_macro(f, "FATAL", "Fatal")

View File

@@ -0,0 +1,106 @@
#!/usr/bin/python
# Software License Agreement (BSD License)
#
# Copyright (c) 2008, Willow Garage, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials provided
# with the distribution.
# * Neither the name of Willow Garage, Inc. nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
import os
import sys
f = open('%s/../test/speed_test.cpp' % (os.path.dirname(__file__)), 'w')
f.write("// !!!!!!!!!!!!!!!!!!!!!!! This is a generated file, do not edit manually\n\n")
f.write('/*\n')
f.write(' * Copyright (c) 2008, Willow Garage, Inc.\n')
f.write(' * All rights reserved.\n')
f.write(' *\n')
f.write(' * Redistribution and use in source and binary forms, with or without\n')
f.write(' * modification, are permitted provided that the following conditions are met:\n')
f.write(' *\n')
f.write(' * * Redistributions of source code must retain the above copyright\n')
f.write(' * notice, this list of conditions and the following disclaimer.\n')
f.write(' * * Redistributions in binary form must reproduce the above copyright\n')
f.write(' * notice, this list of conditions and the following disclaimer in the\n')
f.write(' * documentation and/or other materials provided with the distribution.\n')
f.write(' * * Neither the name of Willow Garage, Inc. nor the names of its\n')
f.write(' * contributors may be used to endorse or promote products derived from\n')
f.write(' * this software without specific prior written permission.\n')
f.write(' *\n')
f.write(' * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\n')
f.write(' * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n')
f.write(' * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n')
f.write(' * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n')
f.write(' * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n')
f.write(' * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n')
f.write(' * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n')
f.write(' * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n')
f.write(' * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n')
f.write(' * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n')
f.write(' * POSSIBILITY OF SUCH DAMAGE.\n')
f.write(' */\n\n')
f.write('#include "ros/console.h"\n')
f.write('#include "log4cxx/appenderskeleton.h"\n')
#for i in range(0,int(sys.argv[1])):
# f.write('void info%s(int i) { ROS_INFO("Info%s: %%d", i); }\n' %(i,i))
# f.write('void warn%s(int i) { ROS_WARN("Warn%s: %%d", i); }\n' %(i,i))
# f.write('void error%s(int i) { ROS_ERROR("Error%s: %%d", i); }\n' %(i,i))
# f.write('void debug%s(int i) { ROS_DEBUG("Debug%s: %%d", i); }\n' %(i,i))
# f.write('void errorr%s(int i) { ROS_ERROR("Error2%s: %%d", i); }\n' %(i,i))
f.write('class NullAppender : public log4cxx::AppenderSkeleton {\n')
f.write('protected:\n')
f.write('virtual void append(const log4cxx::spi::LoggingEventPtr& event, log4cxx::helpers::Pool& pool){printf("blah\\n");}\n')
f.write('virtual void close() {}\n')
f.write('virtual bool requiresLayout() const { return false; } };\n')
f.write('int main(int argc, char** argv)\n{\n')
f.write('ROSCONSOLE_AUTOINIT; \nlog4cxx::Logger::getLogger(ROSCONSOLE_ROOT_LOGGER_NAME)->removeAllAppenders();\n')
f.write('log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME)->addAppender(new NullAppender);\n')
f.write('log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME)->setLevel(log4cxx::Level::getFatal());\n')
f.write('for (int i = 0;i < %s; ++i)\n{\n' %(sys.argv[2]))
for i in range(0,int(sys.argv[1])):
#f.write('info%s(i);\n' %(i))
#f.write('warn%s(i);\n' %(i))
#f.write('error%s(i);\n' %(i))
#f.write('debug%s(i);\n' %(i))
#f.write('errorr%s(i);\n' %(i))
f.write('ROS_INFO("test");')
f.write('ROS_WARN("test");')
f.write('ROS_ERROR("test");')
f.write('ROS_DEBUG("test");')
f.write('ROS_ERROR("test");')
f.write('}\n')
f.write('}\n')

View File

@@ -0,0 +1,127 @@
#include "ros/console.h"
#include <glog/logging.h>
namespace ros
{
namespace console
{
namespace impl
{
std::vector<std::pair<std::string, levels::Level> > rosconsole_glog_log_levels;
LogAppender* rosconsole_glog_appender = 0;
void initialize()
{
google::InitGoogleLogging("rosconsole");
}
std::string getName(void* handle);
void print(void* handle, ::ros::console::Level level, const char* str, const char* file, const char* function, int line)
{
// still printing to console
::ros::console::backend::print(0, level, str, file, function, line);
// pass log message to appender
if(rosconsole_glog_appender)
{
rosconsole_glog_appender->log(level, str, file, function, line);
}
google::LogSeverity glog_level;
if(level == ::ros::console::levels::Info)
{
glog_level = google::GLOG_INFO;
}
else if(level == ::ros::console::levels::Warn)
{
glog_level = google::GLOG_WARNING;
}
else if(level == ::ros::console::levels::Error)
{
glog_level = google::GLOG_ERROR;
}
else if(level == ::ros::console::levels::Fatal)
{
glog_level = google::GLOG_FATAL;
}
else
{
// ignore debug
return;
}
std::string name = getName(handle);
google::LogMessage(file, line, glog_level).stream() << name << ": " << str;
}
bool isEnabledFor(void* handle, ::ros::console::Level level)
{
size_t index = (size_t)handle;
if(index < rosconsole_glog_log_levels.size())
{
return level >= rosconsole_glog_log_levels[index].second;
}
return false;
}
void* getHandle(const std::string& name)
{
size_t count = rosconsole_glog_log_levels.size();
for(size_t index = 0; index < count; index++)
{
if(name == rosconsole_glog_log_levels[index].first)
{
return (void*)index;
}
index++;
}
// add unknown names on demand with default level
rosconsole_glog_log_levels.push_back(std::pair<std::string, levels::Level>(name, ::ros::console::levels::Info));
return (void*)(rosconsole_glog_log_levels.size() - 1);
}
std::string getName(void* handle)
{
size_t index = (size_t)handle;
if(index < rosconsole_glog_log_levels.size())
{
return rosconsole_glog_log_levels[index].first;
}
return "";
}
void register_appender(LogAppender* appender)
{
rosconsole_glog_appender = appender;
}
void shutdown()
{}
bool get_loggers(std::map<std::string, levels::Level>& loggers)
{
for(std::vector<std::pair<std::string, levels::Level> >::const_iterator it = rosconsole_glog_log_levels.begin(); it != rosconsole_glog_log_levels.end(); it++)
{
loggers[it->first] = it->second;
}
return true;
}
bool set_logger_level(const std::string& name, levels::Level level)
{
for(std::vector<std::pair<std::string, levels::Level> >::iterator it = rosconsole_glog_log_levels.begin(); it != rosconsole_glog_log_levels.end(); it++)
{
if(name == it->first)
{
it->second = level;
return true;
}
}
return false;
}
} // namespace impl
} // namespace console
} // namespace ros

View File

@@ -0,0 +1,375 @@
/*
* Copyright (c) 2008, Willow Garage, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the Willow Garage, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
// Author: Josh Faust
#if defined(__APPLE__) && defined(__GNUC__) && defined(__llvm__) && !defined(__clang__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 2)
#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
#endif
#include "ros/console.h"
#include "ros/assert.h"
#include <ros/time.h>
#include "log4cxx/appenderskeleton.h"
#include "log4cxx/spi/loggingevent.h"
#include "log4cxx/level.h"
#include "log4cxx/propertyconfigurator.h"
#ifdef _MSC_VER
// Have to be able to encode wchar LogStrings on windows.
#include "log4cxx/helpers/transcoder.h"
#endif
#include <boost/thread.hpp>
#include <boost/shared_array.hpp>
#include <boost/regex.hpp>
#include <cstdarg>
#include <cstdlib>
#include <cstdio>
#include <memory>
#include <cstring>
#include <stdexcept>
namespace ros
{
namespace console
{
namespace impl
{
log4cxx::LevelPtr g_level_lookup[ levels::Count ] =
{
log4cxx::Level::getDebug(),
log4cxx::Level::getInfo(),
log4cxx::Level::getWarn(),
log4cxx::Level::getError(),
log4cxx::Level::getFatal(),
};
class ROSConsoleStdioAppender : public log4cxx::AppenderSkeleton
{
public:
~ROSConsoleStdioAppender()
{
}
protected:
virtual void append(const log4cxx::spi::LoggingEventPtr& event,
log4cxx::helpers::Pool&)
{
levels::Level level = levels::Count;
if (event->getLevel() == log4cxx::Level::getDebug())
{
level = levels::Debug;
}
else if (event->getLevel() == log4cxx::Level::getInfo())
{
level = levels::Info;
}
else if (event->getLevel() == log4cxx::Level::getWarn())
{
level = levels::Warn;
}
else if (event->getLevel() == log4cxx::Level::getError())
{
level = levels::Error;
}
else if (event->getLevel() == log4cxx::Level::getFatal())
{
level = levels::Fatal;
}
#ifdef _MSC_VER
LOG4CXX_ENCODE_CHAR(tmpstr, event->getMessage()); // has to handle LogString with wchar types.
std::string msg = tmpstr // tmpstr gets instantiated inside the LOG4CXX_ENCODE_CHAR macro
#else
std::string msg = event->getMessage();
#endif
const log4cxx::spi::LocationInfo& location_info = event->getLocationInformation();
::ros::console::backend::print(event.operator->(), level, msg.c_str(), location_info.getFileName(), location_info.getMethodName().c_str(), location_info.getLineNumber());
}
virtual void close()
{
}
virtual bool requiresLayout() const
{
return false;
}
};
void initialize()
{
// First set up some sane defaults programmatically.
log4cxx::LoggerPtr ros_logger = log4cxx::Logger::getLogger(ROSCONSOLE_ROOT_LOGGER_NAME);
ros_logger->setLevel(log4cxx::Level::getInfo());
log4cxx::LoggerPtr roscpp_superdebug = log4cxx::Logger::getLogger("ros.roscpp.superdebug");
roscpp_superdebug->setLevel(log4cxx::Level::getWarn());
// Next try to load the default config file from ROS_ROOT/config/rosconsole.config
char* ros_root_cstr = NULL;
#ifdef _MSC_VER
_dupenv_s(&ros_root_cstr, NULL, "ROS_ROOT");
#else
ros_root_cstr = getenv("ROS_ROOT");
#endif
if (ros_root_cstr)
{
std::string config_file = std::string(ros_root_cstr) + "/config/rosconsole.config";
FILE* config_file_ptr = fopen( config_file.c_str(), "r" );
if( config_file_ptr ) // only load it if the file exists, to avoid a warning message getting printed.
{
fclose( config_file_ptr );
log4cxx::PropertyConfigurator::configure(config_file);
}
}
char* config_file_cstr = NULL;
#ifdef _MSC_VER
_dupenv_s(&config_file_cstr, NULL, "ROSCONSOLE_CONFIG_FILE");
#else
config_file_cstr = getenv("ROSCONSOLE_CONFIG_FILE");
#endif
if ( config_file_cstr )
{
std::string config_file = config_file_cstr;
log4cxx::PropertyConfigurator::configure(config_file);
}
log4cxx::LoggerPtr logger = log4cxx::Logger::getLogger(ROSCONSOLE_ROOT_LOGGER_NAME);
logger->addAppender(new ROSConsoleStdioAppender);
#ifdef _MSC_VER
if ( ros_root_cstr != NULL ) {
free(ros_root_cstr);
}
if ( config_file_cstr != NULL ) {
free(config_file_cstr);
}
if ( format_string != NULL ) {
free(format_string);
}
// getenv implementations don't need free'ing.
#endif
}
void print(void* handle, ::ros::console::Level level, const char* str, const char* file, const char* function, int line)
{
log4cxx::Logger* logger = (log4cxx::Logger*)handle;
try
{
logger->forcedLog(g_level_lookup[level], str, log4cxx::spi::LocationInfo(file, function, line));
}
catch (std::exception& e)
{
fprintf(stderr, "Caught exception while logging: [%s]\n", e.what());
}
}
bool isEnabledFor(void* handle, ::ros::console::Level level)
{
log4cxx::Logger* logger = (log4cxx::Logger*)handle;
return logger->isEnabledFor(g_level_lookup[level]);
}
void* getHandle(const std::string& name)
{
return log4cxx::Logger::getLogger(name);
}
std::string getName(void* handle)
{
const log4cxx::spi::LoggingEvent* event = (const log4cxx::spi::LoggingEvent*)handle;
#ifdef _MSC_VER
LOG4CXX_ENCODE_CHAR(tmpstr, event->getLoggerName()); // has to handle LogString with wchar types.
return tmpstr // tmpstr gets instantiated inside the LOG4CXX_ENCODE_CHAR macro
#else
return event->getLoggerName();
#endif
}
bool get_loggers(std::map<std::string, levels::Level>& loggers)
{
log4cxx::spi::LoggerRepositoryPtr repo = log4cxx::Logger::getLogger(ROSCONSOLE_ROOT_LOGGER_NAME)->getLoggerRepository();
log4cxx::LoggerList current_loggers = repo->getCurrentLoggers();
log4cxx::LoggerList::iterator it = current_loggers.begin();
log4cxx::LoggerList::iterator end = current_loggers.end();
for (; it != end; ++it)
{
std::string name;
#ifdef _MSC_VER
LOG4CXX_ENCODE_CHAR(name, (*it)->getName()); // has to handle LogString with wchar types.
#else
name = (*it)->getName();
#endif
const log4cxx::LevelPtr& log4cxx_level = (*it)->getEffectiveLevel();
levels::Level level;
if (log4cxx_level == log4cxx::Level::getDebug())
{
level = levels::Debug;
}
else if (log4cxx_level == log4cxx::Level::getInfo())
{
level = levels::Info;
}
else if (log4cxx_level == log4cxx::Level::getWarn())
{
level = levels::Warn;
}
else if (log4cxx_level == log4cxx::Level::getError())
{
level = levels::Error;
}
else if (log4cxx_level == log4cxx::Level::getFatal())
{
level = levels::Fatal;
}
else
{
return false;
}
loggers[name] = level;
}
return true;
}
bool set_logger_level(const std::string& name, levels::Level level)
{
log4cxx::LevelPtr log4cxx_level;
if (level == levels::Debug)
{
log4cxx_level = log4cxx::Level::getDebug();
}
else if (level == levels::Info)
{
log4cxx_level = log4cxx::Level::getInfo();
}
else if (level == levels::Warn)
{
log4cxx_level = log4cxx::Level::getWarn();
}
else if (level == levels::Error)
{
log4cxx_level = log4cxx::Level::getError();
}
else if (level == levels::Fatal)
{
log4cxx_level = log4cxx::Level::getFatal();
}
else
{
return false;
}
log4cxx::LoggerPtr logger = log4cxx::Logger::getLogger(name);
logger->setLevel(log4cxx_level);
::ros::console::backend::notifyLoggerLevelsChanged();
return true;
}
class Log4cxxAppender : public log4cxx::AppenderSkeleton
{
public:
Log4cxxAppender(ros::console::LogAppender* appender) : appender_(appender) {}
~Log4cxxAppender() {}
protected:
virtual void append(const log4cxx::spi::LoggingEventPtr& event, log4cxx::helpers::Pool& pool)
{
(void)pool;
levels::Level level;
if (event->getLevel() == log4cxx::Level::getFatal())
{
level = levels::Fatal;
}
else if (event->getLevel() == log4cxx::Level::getError())
{
level = levels::Error;
}
else if (event->getLevel() == log4cxx::Level::getWarn())
{
level = levels::Warn;
}
else if (event->getLevel() == log4cxx::Level::getInfo())
{
level = levels::Info;
}
else if (event->getLevel() == log4cxx::Level::getDebug())
{
level = levels::Debug;
}
else
{
return;
}
#ifdef _MSC_VER
LOG4CXX_ENCODE_CHAR(tmpstr, event->getMessage()); // has to handle LogString with wchar types.
std::string msg = tmpstr // tmpstr gets instantiated inside the LOG4CXX_ENCODE_CHAR macro
#else
std::string msg = event->getMessage();
#endif
const log4cxx::spi::LocationInfo& info = event->getLocationInformation();
appender_->log(level, msg.c_str(), info.getFileName(), info.getMethodName().c_str(), info.getLineNumber());
}
virtual void close() {}
virtual bool requiresLayout() const { return false; }
ros::console::LogAppender* appender_;
};
Log4cxxAppender* g_log4cxx_appender;
void register_appender(LogAppender* appender)
{
g_log4cxx_appender = new Log4cxxAppender(appender);
const log4cxx::LoggerPtr& logger = log4cxx::Logger::getLogger(ROSCONSOLE_ROOT_LOGGER_NAME);
logger->addAppender(g_log4cxx_appender);
}
void shutdown()
{
const log4cxx::LoggerPtr& logger = log4cxx::Logger::getLogger(ROSCONSOLE_ROOT_LOGGER_NAME);
logger->removeAppender(g_log4cxx_appender);
g_log4cxx_appender = 0;
// reset this so that the logger doesn't get crashily destroyed
// again during global destruction.
//
// See https://code.ros.org/trac/ros/ticket/3271
//
log4cxx::Logger::getRootLogger()->getLoggerRepository()->shutdown();
}
} // namespace impl
} // namespace console
} // namespace ros

View File

@@ -0,0 +1,88 @@
/*
* Copyright (c) 2013, Open Source Robotics Foundation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the Willow Garage, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "ros/console.h"
namespace ros
{
namespace console
{
namespace impl
{
LogAppender* rosconsole_print_appender = 0;
void initialize()
{}
void print(void* handle, ::ros::console::Level level, const char* str, const char* file, const char* function, int line)
{
::ros::console::backend::print(0, level, str, file, function, line);
if(rosconsole_print_appender)
{
rosconsole_print_appender->log(level, str, file, function, line);
}
}
bool isEnabledFor(void* handle, ::ros::console::Level level)
{
return level != ::ros::console::levels::Debug;
}
void* getHandle(const std::string& name)
{
return 0;
}
std::string getName(void* handle)
{
return "";
}
void register_appender(LogAppender* appender)
{
rosconsole_print_appender = appender;
}
void shutdown()
{}
bool get_loggers(std::map<std::string, levels::Level>& loggers)
{
return true;
}
bool set_logger_level(const std::string& name, levels::Level level)
{
return false;
}
} // namespace impl
} // namespace console
} // namespace ros

View File

@@ -0,0 +1,707 @@
/*
* Copyright (c) 2008, Willow Garage, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the Willow Garage, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
// Author: Josh Faust
#if defined(__APPLE__) && defined(__GNUC__) && defined(__llvm__) && !defined(__clang__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 2)
#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
#endif
#include "ros/console.h"
#include "ros/assert.h"
#include <ros/time.h>
#include <boost/thread.hpp>
#include <boost/shared_array.hpp>
#include <boost/regex.hpp>
#include <boost/make_shared.hpp>
#include <cstdarg>
#include <cstdlib>
#include <cstdio>
#include <memory>
#include <cstring>
#include <stdexcept>
// declare interface for rosconsole implementations
namespace ros
{
namespace console
{
namespace impl
{
void initialize();
void shutdown();
void register_appender(LogAppender* appender);
void print(void* handle, ::ros::console::Level level, const char* str, const char* file, const char* function, int line);
bool isEnabledFor(void* handle, ::ros::console::Level level);
void* getHandle(const std::string& name);
std::string getName(void* handle);
bool get_loggers(std::map<std::string, levels::Level>& loggers);
bool set_logger_level(const std::string& name, levels::Level level);
} // namespace impl
bool g_initialized = false;
bool g_shutting_down = false;
boost::mutex g_init_mutex;
#ifdef ROSCONSOLE_BACKEND_LOG4CXX
log4cxx::LevelPtr g_level_lookup[levels::Count] =
{
log4cxx::Level::getDebug(),
log4cxx::Level::getInfo(),
log4cxx::Level::getWarn(),
log4cxx::Level::getError(),
log4cxx::Level::getFatal(),
};
#endif
std::string g_last_error_message = "Unknown Error";
#ifdef WIN32
#define COLOR_NORMAL ""
#define COLOR_RED ""
#define COLOR_GREEN ""
#define COLOR_YELLOW ""
#else
#define COLOR_NORMAL "\033[0m"
#define COLOR_RED "\033[31m"
#define COLOR_GREEN "\033[32m"
#define COLOR_YELLOW "\033[33m"
#endif
const char* g_format_string = "[${severity}] [${time}]: ${message}";
typedef std::map<std::string, std::string> M_string;
M_string g_extra_fixed_tokens;
void setFixedFilterToken(const std::string& key, const std::string& val)
{
g_extra_fixed_tokens[key] = val;
}
struct FixedToken : public Token
{
FixedToken(const std::string& str)
: str_(str)
{}
virtual std::string getString(void*, ::ros::console::Level, const char*, const char*, const char*, int)
{
return str_.c_str();
}
std::string str_;
};
struct FixedMapToken : public Token
{
FixedMapToken(const std::string& str)
: str_(str)
{}
virtual std::string getString(void*, ::ros::console::Level, const char*, const char*, const char*, int)
{
M_string::iterator it = g_extra_fixed_tokens.find(str_);
if (it == g_extra_fixed_tokens.end())
{
return ("${" + str_ + "}").c_str();
}
return it->second.c_str();
}
std::string str_;
};
struct PlaceHolderToken : public Token
{
virtual std::string getString(void*, ::ros::console::Level, const char*, const char*, const char*, int)
{
return "PLACEHOLDER";
}
};
struct SeverityToken : public Token
{
virtual std::string getString(void*, ::ros::console::Level level, const char* str, const char* file, const char* function, int line)
{
(void)str;
(void)file;
(void)function;
(void)line;
if (level == levels::Fatal)
{
return "FATAL";
}
else if (level == levels::Error)
{
return "ERROR";
}
else if (level == levels::Warn)
{
return " WARN";
}
else if (level == levels::Info)
{
return " INFO";
}
else if (level == levels::Debug)
{
return "DEBUG";
}
return "UNKNO";
}
};
struct MessageToken : public Token
{
virtual std::string getString(void*, ::ros::console::Level, const char* str, const char*, const char*, int)
{
return str;
}
};
struct TimeToken : public Token
{
virtual std::string getString(void*, ::ros::console::Level, const char*, const char*, const char*, int)
{
std::stringstream ss;
ss << ros::WallTime::now();
if (ros::Time::isValid() && ros::Time::isSimTime())
{
ss << ", " << ros::Time::now();
}
return ss.str();
}
};
struct WallTimeToken : public Token
{
virtual std::string getString(void*, ::ros::console::Level, const char*, const char*, const char*, int)
{
std::stringstream ss;
ss << ros::WallTime::now();
return ss.str();
}
};
struct ThreadToken : public Token
{
virtual std::string getString(void*, ::ros::console::Level, const char*, const char*, const char*, int)
{
std::stringstream ss;
ss << boost::this_thread::get_id();
return ss.str();
}
};
struct LoggerToken : public Token
{
virtual std::string getString(void* logger_handle, ::ros::console::Level level, const char* str, const char* file, const char* function, int line)
{
(void)level;
(void)str;
(void)file;
(void)function;
(void)line;
return ::ros::console::impl::getName(logger_handle);
}
};
struct FileToken : public Token
{
virtual std::string getString(void*, ::ros::console::Level, const char*, const char* file, const char*, int)
{
return file;
}
};
struct FunctionToken : public Token
{
virtual std::string getString(void*, ::ros::console::Level, const char*, const char*, const char* function, int)
{
return function;
}
};
struct LineToken : public Token
{
virtual std::string getString(void*, ::ros::console::Level, const char*, const char*, const char*, int line)
{
std::stringstream ss;
ss << line;
return ss.str();
}
};
TokenPtr createTokenFromType(const std::string& type)
{
if (type == "severity")
{
return TokenPtr(boost::make_shared<SeverityToken>());
}
else if (type == "message")
{
return TokenPtr(boost::make_shared<MessageToken>());
}
else if (type == "time")
{
return TokenPtr(boost::make_shared<TimeToken>());
}
else if (type == "walltime")
{
return TokenPtr(boost::make_shared<WallTimeToken>());
}
else if (type == "thread")
{
return TokenPtr(boost::make_shared<ThreadToken>());
}
else if (type == "logger")
{
return TokenPtr(boost::make_shared<LoggerToken>());
}
else if (type == "file")
{
return TokenPtr(boost::make_shared<FileToken>());
}
else if (type == "line")
{
return TokenPtr(boost::make_shared<LineToken>());
}
else if (type == "function")
{
return TokenPtr(boost::make_shared<FunctionToken>());
}
return TokenPtr(boost::make_shared<FixedMapToken>(type));
}
void Formatter::init(const char* fmt)
{
format_ = fmt;
boost::regex e("\\$\\{([a-z|A-Z]+)\\}");
boost::match_results<std::string::const_iterator> results;
std::string::const_iterator start, end;
start = format_.begin();
end = format_.end();
bool matched_once = false;
std::string last_suffix;
while (boost::regex_search(start, end, results, e))
{
#if 0
for (size_t i = 0; i < results.size(); ++i)
{
std::cout << i << "|" << results.prefix() << "|" << results[i] << "|" << results.suffix() << std::endl;
}
#endif
std::string token = results[1];
last_suffix = results.suffix();
tokens_.push_back(TokenPtr(boost::make_shared<FixedToken>(results.prefix())));
tokens_.push_back(createTokenFromType(token));
start = results[0].second;
matched_once = true;
}
if (matched_once)
{
tokens_.push_back(TokenPtr(boost::make_shared<FixedToken>(last_suffix)));
}
else
{
tokens_.push_back(TokenPtr(boost::make_shared<FixedToken>(format_)));
}
}
void Formatter::print(void* logger_handle, ::ros::console::Level level, const char* str, const char* file, const char* function, int line)
{
const char* color = NULL;
FILE* f = stdout;
if (level == levels::Fatal)
{
color = COLOR_RED;
f = stderr;
}
else if (level == levels::Error)
{
color = COLOR_RED;
f = stderr;
}
else if (level == levels::Warn)
{
color = COLOR_YELLOW;
}
else if (level == levels::Info)
{
color = COLOR_NORMAL;
}
else if (level == levels::Debug)
{
color = COLOR_GREEN;
}
ROS_ASSERT(color != NULL);
std::stringstream ss;
ss << color;
V_Token::iterator it = tokens_.begin();
V_Token::iterator end = tokens_.end();
for (; it != end; ++it)
{
ss << (*it)->getString(logger_handle, level, str, file, function, line);
}
ss << COLOR_NORMAL;
fprintf(f, "%s\n", ss.str().c_str());
}
Formatter g_formatter;
void _print(void* logger_handle, ::ros::console::Level level, const char* str, const char* file, const char* function, int line)
{
g_formatter.print(logger_handle, level, str, file, function, line);
}
void initialize()
{
boost::mutex::scoped_lock lock(g_init_mutex);
if (!g_initialized)
{
// Check for the format string environment variable
char* format_string = NULL;
#ifdef _MSC_VER
_dupenv_s(&format_string, NULL, "ROSCONSOLE_FORMAT");
#else
format_string = getenv("ROSCONSOLE_FORMAT");
#endif
if (format_string)
{
g_format_string = format_string;
}
g_formatter.init(g_format_string);
backend::function_notifyLoggerLevelsChanged = notifyLoggerLevelsChanged;
backend::function_print = _print;
::ros::console::impl::initialize();
g_initialized = true;
}
}
void vformatToBuffer(boost::shared_array<char>& buffer, size_t& buffer_size, const char* fmt, va_list args)
{
#ifdef _MSC_VER
va_list arg_copy = args; // dangerous?
#else
va_list arg_copy;
va_copy(arg_copy, args);
#endif
#ifdef _MSC_VER
size_t total = vsnprintf_s(buffer.get(), buffer_size, buffer_size, fmt, args);
#else
size_t total = vsnprintf(buffer.get(), buffer_size, fmt, args);
#endif
if (total >= buffer_size)
{
buffer_size = total + 1;
buffer.reset(new char[buffer_size]);
#ifdef _MSC_VER
vsnprintf_s(buffer.get(), buffer_size, buffer_size, fmt, arg_copy);
#else
vsnprintf(buffer.get(), buffer_size, fmt, arg_copy);
#endif
}
va_end(arg_copy);
}
void formatToBuffer(boost::shared_array<char>& buffer, size_t& buffer_size, const char* fmt, ...)
{
va_list args;
va_start(args, fmt);
vformatToBuffer(buffer, buffer_size, fmt, args);
va_end(args);
}
std::string formatToString(const char* fmt, ...)
{
boost::shared_array<char> buffer;
size_t size = 0;
va_list args;
va_start(args, fmt);
vformatToBuffer(buffer, size, fmt, args);
va_end(args);
return std::string(buffer.get(), size);
}
#define INITIAL_BUFFER_SIZE 4096
static boost::mutex g_print_mutex;
static boost::shared_array<char> g_print_buffer(new char[INITIAL_BUFFER_SIZE]);
static size_t g_print_buffer_size = INITIAL_BUFFER_SIZE;
static boost::thread::id g_printing_thread_id;
void print(FilterBase* filter, void* logger_handle, Level level,
const char* file, int line, const char* function, const char* fmt, ...)
{
if (g_shutting_down)
return;
if (g_printing_thread_id == boost::this_thread::get_id())
{
fprintf(stderr, "Warning: recursive print statement has occurred. Throwing out recursive print.\n");
return;
}
boost::mutex::scoped_lock lock(g_print_mutex);
g_printing_thread_id = boost::this_thread::get_id();
va_list args;
va_start(args, fmt);
vformatToBuffer(g_print_buffer, g_print_buffer_size, fmt, args);
va_end(args);
bool enabled = true;
if (filter)
{
FilterParams params;
params.file = file;
params.function = function;
params.line = line;
params.level = level;
params.logger = logger_handle;
params.message = g_print_buffer.get();
enabled = filter->isEnabled(params);
level = params.level;
if (!params.out_message.empty())
{
size_t msg_size = params.out_message.size();
if (g_print_buffer_size <= msg_size)
{
g_print_buffer_size = msg_size + 1;
g_print_buffer.reset(new char[g_print_buffer_size]);
}
memcpy(g_print_buffer.get(), params.out_message.c_str(), msg_size + 1);
}
}
if (enabled)
{
if (level == levels::Error)
{
g_last_error_message = g_print_buffer.get();
}
try
{
::ros::console::impl::print(logger_handle, level, g_print_buffer.get(), file, function, line);
}
catch (std::exception& e)
{
fprintf(stderr, "Caught exception while logging: [%s]\n", e.what());
}
}
g_printing_thread_id = boost::thread::id();
}
void print(FilterBase* filter, void* logger_handle, Level level,
const std::stringstream& ss, const char* file, int line, const char* function)
{
if (g_shutting_down)
return;
if (g_printing_thread_id == boost::this_thread::get_id())
{
fprintf(stderr, "Warning: recursive print statement has occurred. Throwing out recursive print.\n");
return;
}
boost::mutex::scoped_lock lock(g_print_mutex);
g_printing_thread_id = boost::this_thread::get_id();
bool enabled = true;
std::string str = ss.str();
if (filter)
{
FilterParams params;
params.file = file;
params.function = function;
params.line = line;
params.level = level;
params.logger = logger_handle;
params.message = g_print_buffer.get();
enabled = filter->isEnabled(params);
level = params.level;
if (!params.out_message.empty())
{
str = params.out_message;
}
}
if (enabled)
{
if (level == levels::Error)
{
g_last_error_message = str;
}
try
{
::ros::console::impl::print(logger_handle, level, str.c_str(), file, function, line);
}
catch (std::exception& e)
{
fprintf(stderr, "Caught exception while logging: [%s]\n", e.what());
}
}
g_printing_thread_id = boost::thread::id();
}
typedef std::vector<LogLocation*> V_LogLocation;
V_LogLocation g_log_locations;
boost::mutex g_locations_mutex;
void registerLogLocation(LogLocation* loc)
{
boost::mutex::scoped_lock lock(g_locations_mutex);
g_log_locations.push_back(loc);
}
void checkLogLocationEnabledNoLock(LogLocation* loc)
{
loc->logger_enabled_ = ::ros::console::impl::isEnabledFor(loc->logger_, loc->level_);
}
void initializeLogLocation(LogLocation* loc, const std::string& name, Level level)
{
boost::mutex::scoped_lock lock(g_locations_mutex);
if (loc->initialized_)
{
return;
}
loc->logger_ = ::ros::console::impl::getHandle(name);
loc->level_ = level;
g_log_locations.push_back(loc);
checkLogLocationEnabledNoLock(loc);
loc->initialized_ = true;
}
void setLogLocationLevel(LogLocation* loc, Level level)
{
boost::mutex::scoped_lock lock(g_locations_mutex);
loc->level_ = level;
}
void checkLogLocationEnabled(LogLocation* loc)
{
boost::mutex::scoped_lock lock(g_locations_mutex);
checkLogLocationEnabledNoLock(loc);
}
void notifyLoggerLevelsChanged()
{
boost::mutex::scoped_lock lock(g_locations_mutex);
V_LogLocation::iterator it = g_log_locations.begin();
V_LogLocation::iterator end = g_log_locations.end();
for ( ; it != end; ++it )
{
LogLocation* loc = *it;
checkLogLocationEnabledNoLock(loc);
}
}
class StaticInit
{
public:
StaticInit()
{
ROSCONSOLE_AUTOINIT;
}
};
StaticInit g_static_init;
void register_appender(LogAppender* appender)
{
ros::console::impl::register_appender(appender);
}
void shutdown()
{
g_shutting_down = true;
ros::console::impl::shutdown();
}
bool get_loggers(std::map<std::string, levels::Level>& loggers)
{
return ros::console::impl::get_loggers(loggers);
}
bool set_logger_level(const std::string& name, levels::Level level)
{
return ros::console::impl::set_logger_level(name, level);
}
} // namespace console
} // namespace ros

View File

@@ -0,0 +1,61 @@
/*
* Copyright (c) 2013, Open Source Robotics Foundation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the Willow Garage, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "ros/console_backend.h"
namespace ros
{
namespace console
{
namespace backend
{
void notifyLoggerLevelsChanged()
{
if (function_notifyLoggerLevelsChanged)
{
function_notifyLoggerLevelsChanged();
}
}
void (*function_notifyLoggerLevelsChanged)() = 0;
void print(void* logger_handle, ::ros::console::Level level, const char* str, const char* file, const char* function, int line)
{
if (function_print)
{
function_print(logger_handle, level, str, file, function, line);
}
}
void (*function_print)(void*, ::ros::console::Level, const char*, const char*, const char*, int) = 0;
} // namespace backend
} // namespace console
} // namespace ros

View File

@@ -0,0 +1,76 @@
/*
* Copyright (c) 2008, Willow Garage, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Willow Garage, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#define ROS_ASSERT_ENABLED
#include "ros/assert.h"
#include <gtest/gtest.h>
void doAssert()
{
ROS_ASSERT(false);
}
void doBreak()
{
ROS_BREAK();
}
void doAssertMessage()
{
ROS_ASSERT_MSG(false, "Testing %d %d %d", 1, 2, 3);
}
TEST(RosAssert, assert)
{
ROS_ASSERT(true);
EXPECT_DEATH(doAssert(), "ASSERTION FAILED");
}
TEST(RosAssert, breakpoint)
{
EXPECT_DEATH(doBreak(), "BREAKPOINT HIT");
}
TEST(RosAssert, assertWithMessage)
{
ROS_ASSERT_MSG(true, "Testing %d %d %d", 1, 2, 3);
EXPECT_DEATH(doAssertMessage(), "Testing 1 2 3");
}
int main(int argc, char **argv)
{
testing::InitGoogleTest(&argc, argv);
ros::Time::init();
testing::FLAGS_gtest_death_test_style = "threadsafe";
return RUN_ALL_TESTS();
}

View File

@@ -0,0 +1,108 @@
/*
* Copyright (c) 2008, Willow Garage, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Willow Garage, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "ros/console.h"
#include <gtest/gtest.h>
#include <boost/thread.hpp>
#include "log4cxx/appenderskeleton.h"
#include "log4cxx/spi/loggingevent.h"
#include <vector>
class TestAppender : public log4cxx::AppenderSkeleton
{
public:
struct Info
{
log4cxx::LevelPtr level_;
std::string message_;
std::string logger_name_;
};
typedef std::vector<Info> V_Info;
V_Info info_;
protected:
virtual void append(const log4cxx::spi::LoggingEventPtr& event, log4cxx::helpers::Pool&)
{
Info info;
info.level_ = event->getLevel();
info.message_ = event->getMessage();
info.logger_name_ = event->getLoggerName();
info_.push_back( info );
}
virtual void close()
{
}
virtual bool requiresLayout() const
{
return false;
}
};
void threadFunc(boost::barrier* b)
{
b->wait();
ROS_INFO("Hello");
}
// Ensure all threaded calls go out
TEST(Rosconsole, threadedCalls)
{
log4cxx::LoggerPtr logger = log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME);
TestAppender* appender = new TestAppender;
logger->addAppender( appender );
boost::thread_group tg;
boost::barrier b(10);
for (uint32_t i = 0; i < 10; ++i)
{
tg.create_thread(boost::bind(threadFunc, &b));
}
tg.join_all();
ASSERT_EQ(appender->info_.size(), 10ULL);
logger->removeAppender(appender);
}
int main(int argc, char **argv)
{
testing::InitGoogleTest(&argc, argv);
ros::Time::init();
return RUN_ALL_TESTS();
}

File diff suppressed because it is too large Load Diff