pax_global_header00006660000000000000000000000064137416236270014525gustar00rootroot0000000000000052 comment=854b3a1ec426e173383d2cf1d241c5626ec33715 rosconsole-1.14.3/000077500000000000000000000000001374162362700140015ustar00rootroot00000000000000rosconsole-1.14.3/.gitignore000066400000000000000000000000111374162362700157610ustar00rootroot00000000000000*~ *.pyc rosconsole-1.14.3/CHANGELOG.rst000066400000000000000000000163611374162362700160310ustar00rootroot00000000000000^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Changelog for package rosconsole ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 1.14.3 (2020-10-14) ------------------- * support NO_COLOR environment variable (`#46 `_) 1.14.2 (2020-08-06) ------------------- * check MSVC predefined macro (`#45 `_) 1.14.1 (2020-07-20) ------------------- * fix message in filter parameters (`#43 `_) 1.14.0 (2020-04-06) ------------------- * add timestamp formatting for rosconsole (`#22 `_) 1.13.15 (2020-02-12) -------------------- * export boost-regex-dev for now (`#38 `_) 1.13.14 (2020-02-12) -------------------- * add missing run dep for boost regex (`#37 `_) 1.13.13 (2020-02-11) -------------------- * bump minimum CMake version to avoid CMP0048 warning (`#36 `_) 1.13.12 (2020-02-11) -------------------- * declare specific boost dependencies (`#35 `_) * fix console printer to also print unknown levels (`#34 `_) * fix level comparison for compatibility with upstream log4cxx (`#33 `_) 1.13.11 (2019-10-03) -------------------- * direct WARN level messages to stderr (`#29 `_) 1.13.10 (2019-03-04) -------------------- * add missing declaration of deregister_appender in impl namespace (`#28 `_) * add deregistry declaration and base impl (`#23 `_) * dll import/export visibility macro update (`#26 `_) * fix long message causing program exit at exception (`#25 `_) 1.13.9 (2018-11-12) ------------------- * don't overlay variables in logging macro (`#21 `_) 1.13.8 (2018-11-09) ------------------- * fix double index increment in rosconsole_glog (`#15 `_) * trigger LOG_THROTTLE when time goes backwards (`#12 `_) * add deregistry function for LogAppender. (`#17 `_) * replaced zero for NULL for null pointer constants (`#14 `_) * fix rosconsole build issue when built on Windows (`#13 `_) 1.13.7 (2018-05-21) ------------------- * moved rosconsole into a separate repository (see `rosdistro#17919 `_) 1.13.6 (2018-02-05) ------------------- * rename log macro argument from rate to period (`#1318 `_) 1.13.5 (2017-11-09) ------------------- 1.13.4 (2017-11-02) ------------------- 1.13.3 (2017-10-25) ------------------- * replace 'while(0)' with 'while(false)' to avoid warnings (`#1179 `_) 1.13.2 (2017-08-15) ------------------- 1.13.1 (2017-07-27) ------------------- * remove extra semicolon in definition of macro ROSCONSOLE_PRINTF_ATTRIBUTE(a, b) (`#1056 `_) * add ROSCONSOLE_STDOUT_LINE_BUFFERED env var to force flushing stdout in Formatter::print (`#1012 `_) 1.13.0 (2017-02-22) ------------------- 1.12.7 (2017-02-17) ------------------- 1.12.6 (2016-10-26) ------------------- * add missing walltime to roscpp logging (`#879 `_) * fix building on GCC-6 (`#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 `_) 1.12.0 (2016-03-18) ------------------- * make LogAppender and Token destructor virtual (`#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 `_) 1.11.16 (2015-11-09) -------------------- 1.11.15 (2015-10-13) -------------------- 1.11.14 (2015-09-19) -------------------- * avoid redefining ROS_ASSERT_ENABLED (`#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 `_) 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 `_) 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 `_) * 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 `_) 1.9.47 (2013-07-03) ------------------- * force CMake policy before setting preprocessor definition to ensure correct escaping (`#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 `_) 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 rosconsole-1.14.3/CMakeLists.txt000066400000000000000000000122631374162362700165450ustar00rootroot00000000000000cmake_minimum_required(VERSION 3.0.2) 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} ${LOG4CXX_LIBRARIES}) 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} ${LOG4CXX_LIBRARIES}) endif() endif() rosconsole-1.14.3/cmake/000077500000000000000000000000001374162362700150615ustar00rootroot00000000000000rosconsole-1.14.3/cmake/rosconsole-extras.cmake.in000066400000000000000000000007641374162362700221710ustar00rootroot00000000000000# 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) rosconsole-1.14.3/config/000077500000000000000000000000001374162362700152465ustar00rootroot00000000000000rosconsole-1.14.3/config/rosconsole.config000066400000000000000000000004441374162362700206250ustar00rootroot00000000000000# # 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 rosconsole-1.14.3/env-hooks/000077500000000000000000000000001374162362700157125ustar00rootroot00000000000000rosconsole-1.14.3/env-hooks/10.rosconsole.bat.develspace.em000066400000000000000000000002311374162362700235150ustar00rootroot00000000000000REM generated from rosconsole/env-hooks/10.rosconsole.bat.develspace.em set ROSCONSOLE_CONFIG_FILE=@(CMAKE_CURRENT_SOURCE_DIR)/config/rosconsole.config rosconsole-1.14.3/env-hooks/10.rosconsole.sh.develspace.em000066400000000000000000000002331374162362700233630ustar00rootroot00000000000000# generated from rosconsole/env-hooks/10.rosconsole.sh.develspace.em export ROSCONSOLE_CONFIG_FILE="@(CMAKE_CURRENT_SOURCE_DIR)/config/rosconsole.config" rosconsole-1.14.3/examples/000077500000000000000000000000001374162362700156175ustar00rootroot00000000000000rosconsole-1.14.3/examples/example.cpp000066400000000000000000000101501374162362700177530ustar00rootroot00000000000000/********************************************************************* * 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 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; } rosconsole-1.14.3/include/000077500000000000000000000000001374162362700154245ustar00rootroot00000000000000rosconsole-1.14.3/include/ros/000077500000000000000000000000001374162362700162275ustar00rootroot00000000000000rosconsole-1.14.3/include/ros/assert.h000066400000000000000000000114271374162362700177060ustar00rootroot00000000000000/* * 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 #if defined(__MINGW32__) # define ROS_ISSUE_BREAK() DebugBreak(); #elif defined(_MSC_VER) # define ROS_ISSUE_BREAK() __debugbreak(); #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 # 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 rosconsole-1.14.3/include/ros/console.h000066400000000000000000000572571374162362700200620ustar00rootroot00000000000000/* * 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 #include #include #include #include #include #include #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 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& 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); ROSCONSOLE_DECL void deregister_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 TokenPtr; typedef std::vector 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 getTokenStrings( void *logger_handle, ::ros::console::Level level, const char *str, const char *file, const char *function, int line) const; 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 ( && filter->isEnabled()) { if (filter->isEnabled(params)) { } } \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& buffer, size_t& buffer_size, const char* fmt, va_list args); ROSCONSOLE_DECL void formatToBuffer(boost::shared_array& buffer, size_t& buffer_size, const char* fmt, ...); ROSCONSOLE_DECL std::string formatToString(const char* fmt, ...); } // namespace console } // namespace ros #if defined(_MSC_VER) #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(_MSC_VER) #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, NULL}; /* 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(NULL, __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(NULL, args) /** * \brief Used internally in throttle macros to determine if a new message should be logged. * \note If ROS time has moved backwards, will evaluate to true */ #define ROSCONSOLE_THROTTLE_CHECK(now, last, period) (ROS_UNLIKELY(last + period <= now) || ROS_UNLIKELY(now < last)) /** * \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.". 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.". 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.". 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.". 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.". Use ROSCONSOLE_DEFAULT_NAME if you would like to use the default name. * \param period The period it should actually trigger at most. If ROS time has moved backwards, it will trigger regardless. */ #define ROS_LOG_THROTTLE(period, level, name, ...) \ do \ { \ ROSCONSOLE_DEFINE_LOCATION(true, level, name); \ static double __ros_log_throttle_last_hit__ = 0.0; \ double __ros_log_throttle_now__ = ::ros::Time::now().toSec(); \ if (ROS_UNLIKELY(__rosconsole_define_location__enabled) && ROSCONSOLE_THROTTLE_CHECK(__ros_log_throttle_now__, __ros_log_throttle_last_hit__, period))\ { \ __ros_log_throttle_last_hit__ = __ros_log_throttle_now__; \ 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.". Use ROSCONSOLE_DEFAULT_NAME if you would like to use the default name. * \param period The period it should actually trigger at most. If ROS time has moved backwards, it will trigger regardless. */ #define ROS_LOG_STREAM_THROTTLE(period, level, name, args) \ do \ { \ ROSCONSOLE_DEFINE_LOCATION(true, level, name); \ static double __ros_log_stream_throttle__last_hit__ = 0.0; \ double __ros_log_stream_throttle__now__ = ::ros::Time::now().toSec(); \ if (ROS_UNLIKELY(__rosconsole_define_location__enabled) && \ ROSCONSOLE_THROTTLE_CHECK(__ros_log_stream_throttle__now__, __ros_log_stream_throttle__last_hit__, period))\ { \ __ros_log_stream_throttle__last_hit__ = __ros_log_stream_throttle__now__; \ 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.". Use ROSCONSOLE_DEFAULT_NAME if you would like to use the default name. * \param period The period it should actually trigger at most, and the delay before which no message will be shown. If ROS time has moved backwards, it will trigger regardless. */ #define ROS_LOG_DELAYED_THROTTLE(period, level, name, ...) \ do \ { \ ROSCONSOLE_DEFINE_LOCATION(true, level, name); \ double __ros_log_delayed_throttle__now__ = ::ros::Time::now().toSec(); \ static double __ros_log_delayed_throttle__last_hit__ = __ros_log_delayed_throttle__now__; \ if (ROS_UNLIKELY(__rosconsole_define_location__enabled) && \ ROSCONSOLE_THROTTLE_CHECK(__ros_log_delayed_throttle__now__, __ros_log_delayed_throttle__last_hit__, period))\ { \ __ros_log_delayed_throttle__last_hit__ = __ros_log_delayed_throttle__now__; \ 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.". Use ROSCONSOLE_DEFAULT_NAME if you would like to use the default name. * \param period The period it should actually trigger at most, and the delay before which no message will be shown. If ROS time has moved backwards, it will trigger regardless. */ #define ROS_LOG_STREAM_DELAYED_THROTTLE(period, level, name, args) \ do \ { \ ROSCONSOLE_DEFINE_LOCATION(true, level, name); \ double __ros_log_stream_delayed_throttle__now__ = ::ros::Time::now().toSec(); \ static double __ros_log_stream_delayed_throttle__last_hit__ = __ros_log_stream_delayed_throttle__now__; \ if (ROS_UNLIKELY(__rosconsole_define_location__enabled) && \ ROSCONSOLE_THROTTLE_CHECK(__ros_log_stream_delayed_throttle__now__, __ros_log_stream_delayed_throttle__last_hit__, period)) \ { \ __ros_log_stream_delayed_throttle__last_hit__ = __ros_log_stream_delayed_throttle__now__; \ 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.". 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.". 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.". 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.". 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 rosconsole-1.14.3/include/ros/console_backend.h000066400000000000000000000055361374162362700215220ustar00rootroot00000000000000/* * 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 #include // 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_backend_interface_EXPORTS // we are building a shared lib/dll #define ROSCONSOLE_BACKEND_DECL ROS_HELPER_EXPORT #else // we are using shared lib/dll #define ROSCONSOLE_BACKEND_DECL ROS_HELPER_IMPORT #endif #else // ros is being built around static libraries #define ROSCONSOLE_BACKEND_DECL #endif namespace ros { namespace console { namespace levels { enum Level { Debug, Info, Warn, Error, Fatal, Count }; } typedef levels::Level Level; namespace backend { ROSCONSOLE_BACKEND_DECL void notifyLoggerLevelsChanged(); ROSCONSOLE_BACKEND_DECL extern void (*function_notifyLoggerLevelsChanged)(); ROSCONSOLE_BACKEND_DECL void print(void* logger_handle, ::ros::console::Level level, const char* str, const char* file, const char* function, int line); ROSCONSOLE_BACKEND_DECL 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 rosconsole-1.14.3/include/ros/console_impl.h000066400000000000000000000067751374162362700211020ustar00rootroot00000000000000/* * 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_IMPL_H #define ROSCONSOLE_CONSOLE_IMPL_H #include #include "ros/console.h" // export interface functions shared by all impl instances in one single header // since CMake would not help define custome flag like ROSCONSOLE_CONSOLE_IMPL_EXPORTS, // the ROSCONSOLE_CONSOLE_IMPL_EXPORTS macro needs to be defined // in the impl code (e.g. rosconsole_log4css.cpp) before including this header // 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_CONSOLE_IMPL_EXPORTS // we are building a shared lib/dll #define ROSCONSOLE_CONSOLE_IMPL_DECL ROS_HELPER_EXPORT #else // we are using shared lib/dll #define ROSCONSOLE_CONSOLE_IMPL_DECL ROS_HELPER_IMPORT #endif #else // ros is being built around static libraries #define ROSCONSOLE_CONSOLE_IMPL_DECL #endif // declare interface for rosconsole implementations namespace ros { namespace console { namespace impl { ROSCONSOLE_CONSOLE_IMPL_DECL void initialize(); ROSCONSOLE_CONSOLE_IMPL_DECL void shutdown(); ROSCONSOLE_CONSOLE_IMPL_DECL void register_appender(LogAppender* appender); ROSCONSOLE_CONSOLE_IMPL_DECL void deregister_appender(LogAppender* appender); ROSCONSOLE_CONSOLE_IMPL_DECL void print(void* handle, ::ros::console::Level level, const char* str, const char* file, const char* function, int line); ROSCONSOLE_CONSOLE_IMPL_DECL bool isEnabledFor(void* handle, ::ros::console::Level level); ROSCONSOLE_CONSOLE_IMPL_DECL void* getHandle(const std::string& name); ROSCONSOLE_CONSOLE_IMPL_DECL std::string getName(void* handle); ROSCONSOLE_CONSOLE_IMPL_DECL bool get_loggers(std::map& loggers); ROSCONSOLE_CONSOLE_IMPL_DECL bool set_logger_level(const std::string& name, levels::Level level); } // namespace impl } // namespace console } // namespace ros #endif // ROSCONSOLE_CONSOLE_IMPL_H rosconsole-1.14.3/include/ros/static_assert.h000066400000000000000000000046361374162362700212610ustar00rootroot00000000000000/* * 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 /** * \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 rosconsole-1.14.3/include/rosconsole/000077500000000000000000000000001374162362700176125ustar00rootroot00000000000000rosconsole-1.14.3/include/rosconsole/macros_generated.h000066400000000000000000000605511374162362700232740ustar00rootroot00000000000000// !!!!!!!!!!!!!!!!!!!!!!! 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(period, ...) #define ROS_DEBUG_STREAM_THROTTLE(period, args) #define ROS_DEBUG_THROTTLE_NAMED(period, name, ...) #define ROS_DEBUG_STREAM_THROTTLE_NAMED(period, name, args) #define ROS_DEBUG_DELAYED_THROTTLE(period, ...) #define ROS_DEBUG_STREAM_DELAYED_THROTTLE(period, args) #define ROS_DEBUG_DELAYED_THROTTLE_NAMED(period, name, ...) #define ROS_DEBUG_STREAM_DELAYED_THROTTLE_NAMED(period, 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(period, ...) ROS_LOG_THROTTLE(period, ::ros::console::levels::Debug, ROSCONSOLE_DEFAULT_NAME, __VA_ARGS__) #define ROS_DEBUG_STREAM_THROTTLE(period, args) ROS_LOG_STREAM_THROTTLE(period, ::ros::console::levels::Debug, ROSCONSOLE_DEFAULT_NAME, args) #define ROS_DEBUG_THROTTLE_NAMED(period, name, ...) ROS_LOG_THROTTLE(period, ::ros::console::levels::Debug, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, __VA_ARGS__) #define ROS_DEBUG_STREAM_THROTTLE_NAMED(period, name, args) ROS_LOG_STREAM_THROTTLE(period, ::ros::console::levels::Debug, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, args) #define ROS_DEBUG_DELAYED_THROTTLE(period, ...) ROS_LOG_DELAYED_THROTTLE(period, ::ros::console::levels::Debug, ROSCONSOLE_DEFAULT_NAME, __VA_ARGS__) #define ROS_DEBUG_STREAM_DELAYED_THROTTLE(period, args) ROS_LOG_STREAM_DELAYED_THROTTLE(period, ::ros::console::levels::Debug, ROSCONSOLE_DEFAULT_NAME, args) #define ROS_DEBUG_DELAYED_THROTTLE_NAMED(period, name, ...) ROS_LOG_DELAYED_THROTTLE(period, ::ros::console::levels::Debug, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, __VA_ARGS__) #define ROS_DEBUG_STREAM_DELAYED_THROTTLE_NAMED(period, name, args) ROS_LOG_STREAM_DELAYED_THROTTLE(period, ::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(period, ...) #define ROS_INFO_STREAM_THROTTLE(period, args) #define ROS_INFO_THROTTLE_NAMED(period, name, ...) #define ROS_INFO_STREAM_THROTTLE_NAMED(period, name, args) #define ROS_INFO_DELAYED_THROTTLE(period, ...) #define ROS_INFO_STREAM_DELAYED_THROTTLE(period, args) #define ROS_INFO_DELAYED_THROTTLE_NAMED(period, name, ...) #define ROS_INFO_STREAM_DELAYED_THROTTLE_NAMED(period, 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(period, ...) ROS_LOG_THROTTLE(period, ::ros::console::levels::Info, ROSCONSOLE_DEFAULT_NAME, __VA_ARGS__) #define ROS_INFO_STREAM_THROTTLE(period, args) ROS_LOG_STREAM_THROTTLE(period, ::ros::console::levels::Info, ROSCONSOLE_DEFAULT_NAME, args) #define ROS_INFO_THROTTLE_NAMED(period, name, ...) ROS_LOG_THROTTLE(period, ::ros::console::levels::Info, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, __VA_ARGS__) #define ROS_INFO_STREAM_THROTTLE_NAMED(period, name, args) ROS_LOG_STREAM_THROTTLE(period, ::ros::console::levels::Info, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, args) #define ROS_INFO_DELAYED_THROTTLE(period, ...) ROS_LOG_DELAYED_THROTTLE(period, ::ros::console::levels::Info, ROSCONSOLE_DEFAULT_NAME, __VA_ARGS__) #define ROS_INFO_STREAM_DELAYED_THROTTLE(period, args) ROS_LOG_STREAM_DELAYED_THROTTLE(period, ::ros::console::levels::Info, ROSCONSOLE_DEFAULT_NAME, args) #define ROS_INFO_DELAYED_THROTTLE_NAMED(period, name, ...) ROS_LOG_DELAYED_THROTTLE(period, ::ros::console::levels::Info, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, __VA_ARGS__) #define ROS_INFO_STREAM_DELAYED_THROTTLE_NAMED(period, name, args) ROS_LOG_STREAM_DELAYED_THROTTLE(period, ::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(period, ...) #define ROS_WARN_STREAM_THROTTLE(period, args) #define ROS_WARN_THROTTLE_NAMED(period, name, ...) #define ROS_WARN_STREAM_THROTTLE_NAMED(period, name, args) #define ROS_WARN_DELAYED_THROTTLE(period, ...) #define ROS_WARN_STREAM_DELAYED_THROTTLE(period, args) #define ROS_WARN_DELAYED_THROTTLE_NAMED(period, name, ...) #define ROS_WARN_STREAM_DELAYED_THROTTLE_NAMED(period, 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(period, ...) ROS_LOG_THROTTLE(period, ::ros::console::levels::Warn, ROSCONSOLE_DEFAULT_NAME, __VA_ARGS__) #define ROS_WARN_STREAM_THROTTLE(period, args) ROS_LOG_STREAM_THROTTLE(period, ::ros::console::levels::Warn, ROSCONSOLE_DEFAULT_NAME, args) #define ROS_WARN_THROTTLE_NAMED(period, name, ...) ROS_LOG_THROTTLE(period, ::ros::console::levels::Warn, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, __VA_ARGS__) #define ROS_WARN_STREAM_THROTTLE_NAMED(period, name, args) ROS_LOG_STREAM_THROTTLE(period, ::ros::console::levels::Warn, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, args) #define ROS_WARN_DELAYED_THROTTLE(period, ...) ROS_LOG_DELAYED_THROTTLE(period, ::ros::console::levels::Warn, ROSCONSOLE_DEFAULT_NAME, __VA_ARGS__) #define ROS_WARN_STREAM_DELAYED_THROTTLE(period, args) ROS_LOG_STREAM_DELAYED_THROTTLE(period, ::ros::console::levels::Warn, ROSCONSOLE_DEFAULT_NAME, args) #define ROS_WARN_DELAYED_THROTTLE_NAMED(period, name, ...) ROS_LOG_DELAYED_THROTTLE(period, ::ros::console::levels::Warn, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, __VA_ARGS__) #define ROS_WARN_STREAM_DELAYED_THROTTLE_NAMED(period, name, args) ROS_LOG_STREAM_DELAYED_THROTTLE(period, ::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(period, ...) #define ROS_ERROR_STREAM_THROTTLE(period, args) #define ROS_ERROR_THROTTLE_NAMED(period, name, ...) #define ROS_ERROR_STREAM_THROTTLE_NAMED(period, name, args) #define ROS_ERROR_DELAYED_THROTTLE(period, ...) #define ROS_ERROR_STREAM_DELAYED_THROTTLE(period, args) #define ROS_ERROR_DELAYED_THROTTLE_NAMED(period, name, ...) #define ROS_ERROR_STREAM_DELAYED_THROTTLE_NAMED(period, 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(period, ...) ROS_LOG_THROTTLE(period, ::ros::console::levels::Error, ROSCONSOLE_DEFAULT_NAME, __VA_ARGS__) #define ROS_ERROR_STREAM_THROTTLE(period, args) ROS_LOG_STREAM_THROTTLE(period, ::ros::console::levels::Error, ROSCONSOLE_DEFAULT_NAME, args) #define ROS_ERROR_THROTTLE_NAMED(period, name, ...) ROS_LOG_THROTTLE(period, ::ros::console::levels::Error, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, __VA_ARGS__) #define ROS_ERROR_STREAM_THROTTLE_NAMED(period, name, args) ROS_LOG_STREAM_THROTTLE(period, ::ros::console::levels::Error, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, args) #define ROS_ERROR_DELAYED_THROTTLE(period, ...) ROS_LOG_DELAYED_THROTTLE(period, ::ros::console::levels::Error, ROSCONSOLE_DEFAULT_NAME, __VA_ARGS__) #define ROS_ERROR_STREAM_DELAYED_THROTTLE(period, args) ROS_LOG_STREAM_DELAYED_THROTTLE(period, ::ros::console::levels::Error, ROSCONSOLE_DEFAULT_NAME, args) #define ROS_ERROR_DELAYED_THROTTLE_NAMED(period, name, ...) ROS_LOG_DELAYED_THROTTLE(period, ::ros::console::levels::Error, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, __VA_ARGS__) #define ROS_ERROR_STREAM_DELAYED_THROTTLE_NAMED(period, name, args) ROS_LOG_STREAM_DELAYED_THROTTLE(period, ::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(period, ...) #define ROS_FATAL_STREAM_THROTTLE(period, args) #define ROS_FATAL_THROTTLE_NAMED(period, name, ...) #define ROS_FATAL_STREAM_THROTTLE_NAMED(period, name, args) #define ROS_FATAL_DELAYED_THROTTLE(period, ...) #define ROS_FATAL_STREAM_DELAYED_THROTTLE(period, args) #define ROS_FATAL_DELAYED_THROTTLE_NAMED(period, name, ...) #define ROS_FATAL_STREAM_DELAYED_THROTTLE_NAMED(period, 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(period, ...) ROS_LOG_THROTTLE(period, ::ros::console::levels::Fatal, ROSCONSOLE_DEFAULT_NAME, __VA_ARGS__) #define ROS_FATAL_STREAM_THROTTLE(period, args) ROS_LOG_STREAM_THROTTLE(period, ::ros::console::levels::Fatal, ROSCONSOLE_DEFAULT_NAME, args) #define ROS_FATAL_THROTTLE_NAMED(period, name, ...) ROS_LOG_THROTTLE(period, ::ros::console::levels::Fatal, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, __VA_ARGS__) #define ROS_FATAL_STREAM_THROTTLE_NAMED(period, name, args) ROS_LOG_STREAM_THROTTLE(period, ::ros::console::levels::Fatal, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, args) #define ROS_FATAL_DELAYED_THROTTLE(period, ...) ROS_LOG_DELAYED_THROTTLE(period, ::ros::console::levels::Fatal, ROSCONSOLE_DEFAULT_NAME, __VA_ARGS__) #define ROS_FATAL_STREAM_DELAYED_THROTTLE(period, args) ROS_LOG_STREAM_DELAYED_THROTTLE(period, ::ros::console::levels::Fatal, ROSCONSOLE_DEFAULT_NAME, args) #define ROS_FATAL_DELAYED_THROTTLE_NAMED(period, name, ...) ROS_LOG_DELAYED_THROTTLE(period, ::ros::console::levels::Fatal, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, __VA_ARGS__) #define ROS_FATAL_STREAM_DELAYED_THROTTLE_NAMED(period, name, args) ROS_LOG_STREAM_DELAYED_THROTTLE(period, ::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 rosconsole-1.14.3/mainpage.dox000066400000000000000000000005571374162362700163050ustar00rootroot00000000000000/** * \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. * */ rosconsole-1.14.3/package.xml000066400000000000000000000016351374162362700161230ustar00rootroot00000000000000 rosconsole 1.14.3 ROS console output library. Dirk Thomas BSD http://www.ros.org/wiki/rosconsole Josh Faust catkin apr libboost-regex-dev libboost-system-dev libboost-thread-dev cpp_common log4cxx rostime rosunit apr cpp_common libboost-regex-dev log4cxx rosbuild rostime rosconsole-1.14.3/scripts/000077500000000000000000000000001374162362700154705ustar00rootroot00000000000000rosconsole-1.14.3/scripts/generate_macros.py000077500000000000000000000237701374162362700212140ustar00rootroot00000000000000#!/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(period, ...)\n' %(caps_name)) f.write('#define ROS_%s_STREAM_THROTTLE(period, args)\n' %(caps_name)) f.write('#define ROS_%s_THROTTLE_NAMED(period, name, ...)\n' %(caps_name)) f.write('#define ROS_%s_STREAM_THROTTLE_NAMED(period, name, args)\n' %(caps_name)) f.write('#define ROS_%s_DELAYED_THROTTLE(period, ...)\n' %(caps_name)) f.write('#define ROS_%s_STREAM_DELAYED_THROTTLE(period, args)\n' %(caps_name)) f.write('#define ROS_%s_DELAYED_THROTTLE_NAMED(period, name, ...)\n' %(caps_name)) f.write('#define ROS_%s_STREAM_DELAYED_THROTTLE_NAMED(period, 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(period, ...) ROS_LOG_THROTTLE(period, ::ros::console::levels::%s, ROSCONSOLE_DEFAULT_NAME, __VA_ARGS__)\n' %(caps_name, enum_name)) f.write('#define ROS_%s_STREAM_THROTTLE(period, args) ROS_LOG_STREAM_THROTTLE(period, ::ros::console::levels::%s, ROSCONSOLE_DEFAULT_NAME, args)\n' %(caps_name, enum_name)) f.write('#define ROS_%s_THROTTLE_NAMED(period, name, ...) ROS_LOG_THROTTLE(period, ::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(period, name, args) ROS_LOG_STREAM_THROTTLE(period, ::ros::console::levels::%s, std::string(ROSCONSOLE_NAME_PREFIX) + "." + name, args)\n' %(caps_name, enum_name)) f.write('#define ROS_%s_DELAYED_THROTTLE(period, ...) ROS_LOG_DELAYED_THROTTLE(period, ::ros::console::levels::%s, ROSCONSOLE_DEFAULT_NAME, __VA_ARGS__)\n' %(caps_name, enum_name)) f.write('#define ROS_%s_STREAM_DELAYED_THROTTLE(period, args) ROS_LOG_STREAM_DELAYED_THROTTLE(period, ::ros::console::levels::%s, ROSCONSOLE_DEFAULT_NAME, args)\n' %(caps_name, enum_name)) f.write('#define ROS_%s_DELAYED_THROTTLE_NAMED(period, name, ...) ROS_LOG_DELAYED_THROTTLE(period, ::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(period, name, args) ROS_LOG_STREAM_DELAYED_THROTTLE(period, ::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") rosconsole-1.14.3/scripts/generate_speed_test.py000077500000000000000000000125301374162362700220570ustar00rootroot00000000000000#!/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') rosconsole-1.14.3/src/000077500000000000000000000000001374162362700145705ustar00rootroot00000000000000rosconsole-1.14.3/src/rosconsole/000077500000000000000000000000001374162362700167565ustar00rootroot00000000000000rosconsole-1.14.3/src/rosconsole/impl/000077500000000000000000000000001374162362700177175ustar00rootroot00000000000000rosconsole-1.14.3/src/rosconsole/impl/rosconsole_glog.cpp000066400000000000000000000061101374162362700236170ustar00rootroot00000000000000#include "ros/console.h" #define ROSCONSOLE_CONSOLE_IMPL_EXPORTS #include "ros/console_impl.h" #include namespace ros { namespace console { namespace impl { std::vector > rosconsole_glog_log_levels; LogAppender* rosconsole_glog_appender = 0; void initialize() { google::InitGoogleLogging("rosconsole"); } 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; } } // add unknown names on demand with default level rosconsole_glog_log_levels.push_back(std::pair(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 deregister_appender(LogAppender* appender) { if(rosconsole_glog_appender == appender) { rosconsole_glog_appender = 0; } } void shutdown() {} bool get_loggers(std::map& loggers) { for(std::vector >::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 >::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 rosconsole-1.14.3/src/rosconsole/impl/rosconsole_log4cxx.cpp000066400000000000000000000267241374162362700242740ustar00rootroot00000000000000/* * 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 #define ROSCONSOLE_CONSOLE_IMPL_EXPORTS #include "ros/console_impl.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 #include #include #include #include #include #include #include #include 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()->toInt() == log4cxx::Level::DEBUG_INT) { level = levels::Debug; } else if (event->getLevel()->toInt() == log4cxx::Level::INFO_INT) { level = levels::Info; } else if (event->getLevel()->toInt() == log4cxx::Level::WARN_INT) { level = levels::Warn; } else if (event->getLevel()->toInt() == log4cxx::Level::ERROR_INT) { level = levels::Error; } else if (event->getLevel()->toInt() == log4cxx::Level::FATAL_INT) { 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); } // 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& 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) { #ifdef _MSC_VER LOG4CXX_ENCODE_CHAR(tmpstr, (*it)->getName()); // has to handle LogString with wchar types. std::string name = tmpstr; #else std::string name = (*it)->getName(); #endif int log4cxx_level = (*it)->getEffectiveLevel()->toInt(); levels::Level level; if (log4cxx_level == log4cxx::Level::DEBUG_INT) { level = levels::Debug; } else if (log4cxx_level == log4cxx::Level::INFO_INT) { level = levels::Info; } else if (log4cxx_level == log4cxx::Level::WARN_INT) { level = levels::Warn; } else if (log4cxx_level == log4cxx::Level::ERROR_INT) { level = levels::Error; } else if (log4cxx_level == log4cxx::Level::FATAL_INT) { 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) {} const ros::console::LogAppender* getAppender() const { return appender_; } ~Log4cxxAppender() {} protected: virtual void append(const log4cxx::spi::LoggingEventPtr& event, log4cxx::helpers::Pool& pool) { (void)pool; levels::Level level; if (event->getLevel()->toInt() == log4cxx::Level::FATAL_INT) { level = levels::Fatal; } else if (event->getLevel()->toInt() == log4cxx::Level::ERROR_INT) { level = levels::Error; } else if (event->getLevel()->toInt() == log4cxx::Level::WARN_INT) { level = levels::Warn; } else if (event->getLevel()->toInt() == log4cxx::Level::INFO_INT) { level = levels::Info; } else if (event->getLevel()->toInt() == log4cxx::Level::DEBUG_INT) { 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 = 0; 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 deregister_appender(LogAppender* appender){ if(g_log4cxx_appender->getAppender() == appender) { const log4cxx::LoggerPtr& logger = log4cxx::Logger::getLogger(ROSCONSOLE_ROOT_LOGGER_NAME); logger->removeAppender(g_log4cxx_appender); delete g_log4cxx_appender; g_log4cxx_appender = 0; } } void shutdown() { if(g_log4cxx_appender) { 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 rosconsole-1.14.3/src/rosconsole/impl/rosconsole_print.cpp000066400000000000000000000054521374162362700240330ustar00rootroot00000000000000/* * 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" #define ROSCONSOLE_CONSOLE_IMPL_EXPORTS #include "ros/console_impl.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 deregister_appender(LogAppender* appender){ if(rosconsole_print_appender == appender) { rosconsole_print_appender = 0; } } void shutdown() {} bool get_loggers(std::map& loggers) { return true; } bool set_logger_level(const std::string& name, levels::Level level) { return false; } } // namespace impl } // namespace console } // namespace ros rosconsole-1.14.3/src/rosconsole/rosconsole.cpp000066400000000000000000000456741374162362700216700ustar00rootroot00000000000000/* * 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/console_impl.h" #include "ros/assert.h" #include #include #include #include #include #include #include #include #include #include #include #include // declare interface for rosconsole implementations namespace ros { namespace console { 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}"; bool g_force_stdout_line_buffered = false; bool g_stdout_flush_failure_reported = false; bool g_color = true; typedef std::map 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 { explicit TimeToken(const std::string &format) : format_(format) {}; virtual std::string getString(void*, ::ros::console::Level, const char*, const char*, const char*, int) { std::stringstream ss; if (format_.empty()) { ss << ros::WallTime::now(); } else { boost::posix_time::time_facet *facet = new boost::posix_time::time_facet(); facet->format(format_.c_str()); ss.imbue(std::locale(std::locale::classic(), facet)); ss << ros::WallTime::now().toBoost(); } if (ros::Time::isValid() && ros::Time::isSimTime()) { ss << ", "; if (format_.empty()) { ss << ros::Time::now(); } else { ss << ros::Time::now().toBoost(); } } return ss.str(); } const std::string format_; }; struct WallTimeToken : public Token { explicit WallTimeToken(const std::string &format) : format_(format) {}; virtual std::string getString(void*, ::ros::console::Level, const char*, const char*, const char*, int) { std::stringstream ss; if (format_.empty()) { ss << ros::WallTime::now(); } else { boost::posix_time::time_facet* facet = new boost::posix_time::time_facet(); facet->format(format_.c_str()); ss.imbue(std::locale(std::locale::classic(), facet)); ss << ros::WallTime::now().toBoost(); } return ss.str(); } const std::string format_; }; 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()); } else if (type == "message") { return TokenPtr(boost::make_shared()); } else if (type == "time" || strncmp(type.c_str(), std::string("time:").c_str(), std::string("time:").size()) == 0) { std::string format; std::size_t found = type.find(':'); if (found != std::string::npos) { format = type.substr(found + 1, type.size()); } return TokenPtr(boost::make_shared(format)); } else if (type == "walltime" || strncmp(type.c_str(), std::string("walltime:").c_str(), std::string("walltime:").size()) == 0) { std::string format; std::size_t found = type.find(':'); if (found != std::string::npos) { format = type.substr(found + 1, type.size()); } return TokenPtr(boost::make_shared(format)); } else if (type == "thread") { return TokenPtr(boost::make_shared()); } else if (type == "logger") { return TokenPtr(boost::make_shared()); } else if (type == "file") { return TokenPtr(boost::make_shared()); } else if (type == "line") { return TokenPtr(boost::make_shared()); } else if (type == "function") { return TokenPtr(boost::make_shared()); } return TokenPtr(boost::make_shared(type)); } void Formatter::init(const char* fmt) { format_ = fmt; boost::regex e("\\$\\{([^\\}]+)\\}"); boost::match_results 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(results.prefix()))); tokens_.push_back(createTokenFromType(token)); start = results[0].second; matched_once = true; } if (matched_once) { tokens_.push_back(TokenPtr(boost::make_shared(last_suffix))); } else { tokens_.push_back(TokenPtr(boost::make_shared(format_))); } } void Formatter::print(void* logger_handle, ::ros::console::Level level, const char* str, const char* file, const char* function, int line) { // print in red to stderr if level doesn't match any of the predefined ones const char* color = COLOR_RED; FILE* f = stderr; if (level == levels::Fatal) { color = COLOR_RED; } else if (level == levels::Error) { color = COLOR_RED; } else if (level == levels::Warn) { color = COLOR_YELLOW; } else if (level == levels::Info) { color = COLOR_NORMAL; f = stdout; } else if (level == levels::Debug) { color = COLOR_GREEN; f = stdout; } std::stringstream ss; if (g_color) { ss << color; } ss << getTokenStrings(logger_handle, level, str, file, function, line); if (g_color) { ss << COLOR_NORMAL; } fprintf(f, "%s\n", ss.str().c_str()); if (g_force_stdout_line_buffered && f == stdout) { int flush_result = fflush(f); if (flush_result != 0 && !g_stdout_flush_failure_reported) { g_stdout_flush_failure_reported = true; fprintf(stderr, "Error: failed to perform fflush on stdout, fflush return code is %d\n", flush_result); } } } std::string Formatter::getTokenStrings(void *logger_handle, ::ros::console::Level level, const char *str, const char *file, const char *function, int line) const { std::stringstream ss; for (V_Token::const_iterator it = tokens_.begin(); it != tokens_.end(); ++it) { ss << (*it)->getString(logger_handle, level, str, file, function, line); } return ss.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; std::string line_buffered; if (get_environment_variable(line_buffered, "ROSCONSOLE_STDOUT_LINE_BUFFERED")) { if (line_buffered == "1") { g_force_stdout_line_buffered = true; } else if (line_buffered != "0") { fprintf(stderr, "Warning: unexpected value %s specified for ROSCONSOLE_STDOUT_LINE_BUFFERED. Default value 0 " "will be used. Valid values are 1 or 0.\n", line_buffered.c_str()); } } std::string no_color; if (get_environment_variable(no_color, "NO_COLOR")) { g_color = false; } ::ros::console::impl::initialize(); g_initialized = true; } } void vformatToBuffer(boost::shared_array& buffer, size_t& buffer_size, const char* fmt, va_list args) { va_list arg_copy; va_copy(arg_copy, args); size_t total = vsnprintf(buffer.get(), buffer_size, fmt, args); if (total >= buffer_size) { buffer_size = total + 1; buffer.reset(new char[buffer_size]); vsnprintf(buffer.get(), buffer_size, fmt, arg_copy); } va_end(arg_copy); } void formatToBuffer(boost::shared_array& 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 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 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 = str.c_str(); 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 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 deregister_appender(LogAppender* appender) { ros::console::impl::deregister_appender(appender); } void shutdown() { g_shutting_down = true; ros::console::impl::shutdown(); } bool get_loggers(std::map& 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 rosconsole-1.14.3/src/rosconsole/rosconsole_backend.cpp000066400000000000000000000043701374162362700233230ustar00rootroot00000000000000/* * 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 rosconsole-1.14.3/test/000077500000000000000000000000001374162362700147605ustar00rootroot00000000000000rosconsole-1.14.3/test/assertion_test.cpp000066400000000000000000000044531374162362700205400ustar00rootroot00000000000000/* * 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 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(); } rosconsole-1.14.3/test/thread_test.cpp000066400000000000000000000070611374162362700177760ustar00rootroot00000000000000/* * 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 #include #include "log4cxx/appenderskeleton.h" #include "log4cxx/spi/loggingevent.h" #ifdef _MSC_VER // Have to be able to encode wchar LogStrings on windows. #include "log4cxx/helpers/transcoder.h" #endif #include class TestAppender : public log4cxx::AppenderSkeleton { public: struct Info { log4cxx::LevelPtr level_; std::string message_; std::string logger_name_; }; typedef std::vector V_Info; V_Info info_; protected: virtual void append(const log4cxx::spi::LoggingEventPtr& event, log4cxx::helpers::Pool&) { Info info; info.level_ = event->getLevel(); #ifdef _MSC_VER LOG4CXX_ENCODE_CHAR(msgstr, event->getMessage()); // has to handle LogString with wchar types. info.message_ = msgstr; // msgstr gets instantiated inside the LOG4CXX_ENCODE_CHAR macro LOG4CXX_ENCODE_CHAR(loggerstr, event->getLoggerName()); // has to handle LogString with wchar types. info.logger_name_ = loggerstr; // loggerstr gets instantiated inside the LOG4CXX_ENCODE_CHAR macro #else info.message_ = event->getMessage(); info.logger_name_ = event->getLoggerName(); #endif 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(); } rosconsole-1.14.3/test/utest.cpp000066400000000000000000001121031374162362700166260ustar00rootroot00000000000000/* * 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/appenderskeleton.h" #include "log4cxx/spi/loggingevent.h" #ifdef _MSC_VER // Have to be able to encode wchar LogStrings on windows. #include "log4cxx/helpers/transcoder.h" #endif #include #include #include #include #include class TestAppender : public log4cxx::AppenderSkeleton { public: struct Info { log4cxx::LevelPtr level_; std::string message_; std::string logger_name_; }; typedef std::vector V_Info; V_Info info_; protected: virtual void append(const log4cxx::spi::LoggingEventPtr& event, log4cxx::helpers::Pool&) { Info info; info.level_ = event->getLevel(); #ifdef _MSC_VER LOG4CXX_ENCODE_CHAR(msgstr, event->getMessage()); // has to handle LogString with wchar types. info.message_ = msgstr; // msgstr gets instantiated inside the LOG4CXX_ENCODE_CHAR macro LOG4CXX_ENCODE_CHAR(loggerstr, event->getLoggerName()); // has to handle LogString with wchar types. info.logger_name_ = loggerstr; // loggerstr gets instantiated inside the LOG4CXX_ENCODE_CHAR macro #else info.message_ = event->getMessage(); info.logger_name_ = event->getLoggerName(); #endif info_.push_back( info ); } virtual void close() { } virtual bool requiresLayout() const { return false; } }; class TestAppenderWithThrow : public log4cxx::AppenderSkeleton { protected: virtual void append(const log4cxx::spi::LoggingEventPtr&, log4cxx::helpers::Pool&) { throw std::runtime_error("This should be caught"); } virtual void close() { } virtual bool requiresLayout() const { return false; } }; struct BasicFilter : public ros::console::FilterBase { BasicFilter(bool enabled) : enabled_(enabled) {} inline virtual bool isEnabled() { return enabled_; }; bool enabled_; }; BasicFilter g_filter(true); #define DEFINE_COND_TESTS(name, macro_base, level, log4cxx_level) \ TEST(RosConsole, name##Cond) \ { \ TestAppender* appender = new TestAppender; \ log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME)->addAppender( appender ); \ macro_base##_COND(true, "Testing %d %d %d", 1, 2, 3); \ macro_base##_COND(false, "Testing %d %d %d", 1, 2, 3); \ ASSERT_EQ((int)appender->info_.size(), 1); \ EXPECT_STREQ(appender->info_[0].message_.c_str(), "Testing 1 2 3"); \ EXPECT_EQ(appender->info_[0].level_, log4cxx_level); \ log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME)->removeAppender( appender ); \ } \ TEST(RosConsole, name##NamedCond) \ { \ TestAppender* appender = new TestAppender; \ log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME)->addAppender( appender ); \ macro_base##_COND_NAMED(true, "test", "Testing %d %d %d", 1, 2, 3); \ macro_base##_COND_NAMED(false, "test", "Testing %d %d %d", 1, 2, 3); \ ASSERT_EQ((int)appender->info_.size(), 1); \ EXPECT_STREQ(appender->info_[0].message_.c_str(), "Testing 1 2 3"); \ EXPECT_EQ(appender->info_[0].level_, log4cxx_level); \ EXPECT_STREQ(appender->info_[0].logger_name_.c_str(), ROSCONSOLE_ROOT_LOGGER_NAME".rosconsole.test"); \ log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME)->removeAppender( appender ); \ } \ TEST(RosConsole, name##StreamCond) \ { \ TestAppender* appender = new TestAppender; \ log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME)->addAppender( appender ); \ macro_base##_STREAM_COND(true, "Testing " << 1 << " " << 2 << " " << 3); \ macro_base##_STREAM_COND(false, "Testing " << 1 << " " << 2 << " " << 3); \ ASSERT_EQ((int)appender->info_.size(), 1); \ EXPECT_STREQ(appender->info_[0].message_.c_str(), "Testing 1 2 3"); \ EXPECT_EQ(appender->info_[0].level_, log4cxx_level); \ log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME)->removeAppender( appender ); \ } \ TEST(RosConsole, name##StreamCondNamed) \ { \ TestAppender* appender = new TestAppender; \ log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME)->addAppender( appender ); \ macro_base##_STREAM_COND_NAMED(true, "test", "Testing " << 1 << " " << 2 << " " << 3); \ macro_base##_STREAM_COND_NAMED(false, "test", "Testing " << 1 << " " << 2 << " " << 3); \ ASSERT_EQ((int)appender->info_.size(), 1); \ EXPECT_STREQ(appender->info_[0].message_.c_str(), "Testing 1 2 3"); \ EXPECT_EQ(appender->info_[0].level_, log4cxx_level); \ EXPECT_STREQ(appender->info_[0].logger_name_.c_str(), ROSCONSOLE_ROOT_LOGGER_NAME".rosconsole.test"); \ log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME)->removeAppender( appender ); \ } #define DEFINE_ONCE_TESTS(name, macro_base, level, log4cxx_level) \ TEST(RosConsole, name##Once) \ { \ TestAppender* appender = new TestAppender; \ log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME)->addAppender( appender ); \ macro_base##_ONCE("Testing %d %d %d", 1, 2, 3); \ ASSERT_EQ((int)appender->info_.size(), 1); \ EXPECT_STREQ(appender->info_[0].message_.c_str(), "Testing 1 2 3"); \ EXPECT_EQ(appender->info_[0].level_, log4cxx_level); \ log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME)->removeAppender( appender ); \ } \ TEST(RosConsole, name##NamedOnce) \ { \ TestAppender* appender = new TestAppender; \ log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME)->addAppender( appender ); \ macro_base##_ONCE_NAMED("test", "Testing %d %d %d", 1, 2, 3); \ ASSERT_EQ((int)appender->info_.size(), 1); \ EXPECT_STREQ(appender->info_[0].message_.c_str(), "Testing 1 2 3"); \ EXPECT_EQ(appender->info_[0].level_, log4cxx_level); \ EXPECT_STREQ(appender->info_[0].logger_name_.c_str(), ROSCONSOLE_ROOT_LOGGER_NAME".rosconsole.test"); \ log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME)->removeAppender( appender ); \ } \ TEST(RosConsole, name##StreamOnce) \ { \ TestAppender* appender = new TestAppender; \ log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME)->addAppender( appender ); \ macro_base##_STREAM_ONCE("Testing " << 1 << " " << 2 << " " << 3); \ ASSERT_EQ((int)appender->info_.size(), 1); \ EXPECT_STREQ(appender->info_[0].message_.c_str(), "Testing 1 2 3"); \ EXPECT_EQ(appender->info_[0].level_, log4cxx_level); \ log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME)->removeAppender( appender ); \ } \ TEST(RosConsole, name##StreamOnceNamed) \ { \ TestAppender* appender = new TestAppender; \ log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME)->addAppender( appender ); \ macro_base##_STREAM_ONCE_NAMED("test", "Testing " << 1 << " " << 2 << " " << 3); \ ASSERT_EQ((int)appender->info_.size(), 1); \ EXPECT_STREQ(appender->info_[0].message_.c_str(), "Testing 1 2 3"); \ EXPECT_EQ(appender->info_[0].level_, log4cxx_level); \ EXPECT_STREQ(appender->info_[0].logger_name_.c_str(), ROSCONSOLE_ROOT_LOGGER_NAME".rosconsole.test"); \ log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME)->removeAppender( appender ); \ } #define DEFINE_THROTTLE_TESTS(name, macro_base, level, log4cxx_level) \ TEST(RosConsole, name##Throttle) \ { \ TestAppender* appender = new TestAppender; \ log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME)->addAppender( appender ); \ macro_base##_THROTTLE(0.5, "Testing %d %d %d", 1, 2, 3); \ ASSERT_EQ((int)appender->info_.size(), 1); \ EXPECT_STREQ(appender->info_[0].message_.c_str(), "Testing 1 2 3"); \ EXPECT_EQ(appender->info_[0].level_, log4cxx_level); \ log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME)->removeAppender( appender ); \ } \ TEST(RosConsole, name##NamedThrottle) \ { \ TestAppender* appender = new TestAppender; \ log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME)->addAppender( appender ); \ macro_base##_THROTTLE_NAMED(0.5, "test", "Testing %d %d %d", 1, 2, 3); \ ASSERT_EQ((int)appender->info_.size(), 1); \ EXPECT_STREQ(appender->info_[0].message_.c_str(), "Testing 1 2 3"); \ EXPECT_EQ(appender->info_[0].level_, log4cxx_level); \ EXPECT_STREQ(appender->info_[0].logger_name_.c_str(), ROSCONSOLE_ROOT_LOGGER_NAME".rosconsole.test"); \ log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME)->removeAppender( appender ); \ } \ TEST(RosConsole, name##StreamThrottle) \ { \ TestAppender* appender = new TestAppender; \ log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME)->addAppender( appender ); \ macro_base##_STREAM_THROTTLE(0.5, "Testing " << 1 << " " << 2 << " " << 3); \ ASSERT_EQ((int)appender->info_.size(), 1); \ EXPECT_STREQ(appender->info_[0].message_.c_str(), "Testing 1 2 3"); \ EXPECT_EQ(appender->info_[0].level_, log4cxx_level); \ log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME)->removeAppender( appender ); \ } \ TEST(RosConsole, name##StreamThrottleNamed) \ { \ TestAppender* appender = new TestAppender; \ log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME)->addAppender( appender ); \ macro_base##_STREAM_THROTTLE_NAMED(0.5, "test", "Testing " << 1 << " " << 2 << " " << 3); \ ASSERT_EQ((int)appender->info_.size(), 1); \ EXPECT_STREQ(appender->info_[0].message_.c_str(), "Testing 1 2 3"); \ EXPECT_EQ(appender->info_[0].level_, log4cxx_level); \ EXPECT_STREQ(appender->info_[0].logger_name_.c_str(), ROSCONSOLE_ROOT_LOGGER_NAME".rosconsole.test"); \ log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME)->removeAppender( appender ); \ } #define DEFINE_FILTER_TESTS(name, macro_base, level, log4cxx_level) \ TEST(RosConsole, name##Filter) \ { \ TestAppender* appender = new TestAppender; \ log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME)->addAppender( appender ); \ macro_base##_FILTER(&g_filter, "Testing %d %d %d", 1, 2, 3); \ ASSERT_EQ((int)appender->info_.size(), 1); \ EXPECT_STREQ(appender->info_[0].message_.c_str(), "Testing 1 2 3"); \ EXPECT_EQ(appender->info_[0].level_, log4cxx_level); \ log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME)->removeAppender( appender ); \ } \ TEST(RosConsole, name##NamedFilter) \ { \ TestAppender* appender = new TestAppender; \ log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME)->addAppender( appender ); \ macro_base##_FILTER_NAMED(&g_filter, "test", "Testing %d %d %d", 1, 2, 3); \ ASSERT_EQ((int)appender->info_.size(), 1); \ EXPECT_STREQ(appender->info_[0].message_.c_str(), "Testing 1 2 3"); \ EXPECT_EQ(appender->info_[0].level_, log4cxx_level); \ EXPECT_STREQ(appender->info_[0].logger_name_.c_str(), ROSCONSOLE_ROOT_LOGGER_NAME".rosconsole.test"); \ log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME)->removeAppender( appender ); \ } \ TEST(RosConsole, name##StreamFilter) \ { \ TestAppender* appender = new TestAppender; \ log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME)->addAppender( appender ); \ macro_base##_STREAM_FILTER(&g_filter, "Testing " << 1 << " " << 2 << " " << 3); \ ASSERT_EQ((int)appender->info_.size(), 1); \ EXPECT_STREQ(appender->info_[0].message_.c_str(), "Testing 1 2 3"); \ EXPECT_EQ(appender->info_[0].level_, log4cxx_level); \ log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME)->removeAppender( appender ); \ } \ TEST(RosConsole, name##StreamFilterNamed) \ { \ TestAppender* appender = new TestAppender; \ log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME)->addAppender( appender ); \ macro_base##_STREAM_FILTER_NAMED(&g_filter, "test", "Testing " << 1 << " " << 2 << " " << 3); \ ASSERT_EQ((int)appender->info_.size(), 1); \ EXPECT_STREQ(appender->info_[0].message_.c_str(), "Testing 1 2 3"); \ EXPECT_EQ(appender->info_[0].level_, log4cxx_level); \ EXPECT_STREQ(appender->info_[0].logger_name_.c_str(), ROSCONSOLE_ROOT_LOGGER_NAME".rosconsole.test"); \ log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME)->removeAppender( appender ); \ } #define DEFINE_LEVEL_TESTS(name, macro_base, level, log4cxx_level) \ TEST(RosConsole, name) \ { \ TestAppender* appender = new TestAppender; \ log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME)->addAppender( appender ); \ macro_base("Testing %d %d %d", 1, 2, 3); \ ASSERT_EQ((int)appender->info_.size(), 1); \ EXPECT_STREQ(appender->info_[0].message_.c_str(), "Testing 1 2 3"); \ EXPECT_EQ(appender->info_[0].level_, log4cxx_level); \ log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME)->removeAppender( appender ); \ } \ TEST(RosConsole, name##Named) \ { \ TestAppender* appender = new TestAppender; \ log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME)->addAppender( appender ); \ macro_base##_NAMED("test", "Testing %d %d %d", 1, 2, 3); \ ASSERT_EQ((int)appender->info_.size(), 1); \ EXPECT_STREQ(appender->info_[0].message_.c_str(), "Testing 1 2 3"); \ EXPECT_EQ(appender->info_[0].level_, log4cxx_level); \ EXPECT_STREQ(appender->info_[0].logger_name_.c_str(), ROSCONSOLE_ROOT_LOGGER_NAME".rosconsole.test"); \ log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME)->removeAppender( appender ); \ } \ TEST(RosConsole, name##Stream) \ { \ TestAppender* appender = new TestAppender; \ log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME)->addAppender( appender ); \ macro_base##_STREAM("Testing " << 1 << " " << 2 << " " << 3); \ ASSERT_EQ((int)appender->info_.size(), 1); \ EXPECT_STREQ(appender->info_[0].message_.c_str(), "Testing 1 2 3"); \ EXPECT_EQ(appender->info_[0].level_, log4cxx_level); \ log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME)->removeAppender( appender ); \ } \ TEST(RosConsole, name##StreamNamed) \ { \ TestAppender* appender = new TestAppender; \ log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME)->addAppender( appender ); \ macro_base##_STREAM_NAMED("test", "Testing " << 1 << " " << 2 << " " << 3); \ ASSERT_EQ((int)appender->info_.size(), 1); \ EXPECT_STREQ(appender->info_[0].message_.c_str(), "Testing 1 2 3"); \ EXPECT_EQ(appender->info_[0].level_, log4cxx_level); \ EXPECT_STREQ(appender->info_[0].logger_name_.c_str(), ROSCONSOLE_ROOT_LOGGER_NAME".rosconsole.test"); \ log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME)->removeAppender( appender ); \ } \ DEFINE_COND_TESTS(name, macro_base, level, log4cxx_level) \ DEFINE_ONCE_TESTS(name, macro_base, level, log4cxx_level) \ DEFINE_THROTTLE_TESTS(name, macro_base, level, log4cxx_level) \ DEFINE_FILTER_TESTS(name, macro_base, level, log4cxx_level) DEFINE_LEVEL_TESTS(debug, ROS_DEBUG, ros::console::levels::Debug, log4cxx::Level::getDebug()) DEFINE_LEVEL_TESTS(info, ROS_INFO, ros::console::levels::Info, log4cxx::Level::getInfo()) DEFINE_LEVEL_TESTS(warn, ROS_WARN, ros::console::levels::Warn, log4cxx::Level::getWarn()) DEFINE_LEVEL_TESTS(error, ROS_ERROR, ros::console::levels::Error, log4cxx::Level::getError()) DEFINE_LEVEL_TESTS(fatal, ROS_FATAL, ros::console::levels::Fatal, log4cxx::Level::getFatal()) TEST(RosConsole, loggingLevels) { log4cxx::LoggerPtr logger = log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME); TestAppender* appender = new TestAppender; logger->addAppender( appender ); int pre_count = 0; int post_count = 0; { logger->setLevel( log4cxx::Level::getInfo() ); pre_count = appender->info_.size(); ROS_DEBUG("test"); ROS_INFO("test"); ROS_WARN("test"); ROS_ERROR("test"); ROS_FATAL("test"); post_count = appender->info_.size(); EXPECT_EQ(post_count, pre_count + 4); logger->setLevel( log4cxx::Level::getWarn() ); pre_count = appender->info_.size(); ROS_DEBUG("test"); ROS_INFO("test"); ROS_WARN("test"); ROS_ERROR("test"); ROS_FATAL("test"); post_count = appender->info_.size(); EXPECT_EQ(post_count, pre_count + 3); logger->setLevel( log4cxx::Level::getError() ); pre_count = appender->info_.size(); ROS_DEBUG("test"); ROS_INFO("test"); ROS_WARN("test"); ROS_ERROR("test"); ROS_FATAL("test"); post_count = appender->info_.size(); EXPECT_EQ(post_count, pre_count + 2); logger->setLevel( log4cxx::Level::getFatal() ); pre_count = appender->info_.size(); ROS_DEBUG("test"); ROS_INFO("test"); ROS_WARN("test"); ROS_ERROR("test"); ROS_FATAL("test"); post_count = appender->info_.size(); EXPECT_EQ(post_count, pre_count + 1); logger->setLevel( log4cxx::Level::getOff() ); pre_count = appender->info_.size(); ROS_DEBUG("test"); ROS_INFO("test"); ROS_WARN("test"); ROS_ERROR("test"); ROS_FATAL("test"); post_count = appender->info_.size(); EXPECT_EQ(post_count, pre_count); } { logger->setLevel( log4cxx::Level::getInfo() ); pre_count = appender->info_.size(); ROS_DEBUG_STREAM("test"); ROS_INFO_STREAM("test"); ROS_WARN_STREAM("test"); ROS_ERROR_STREAM("test"); ROS_FATAL_STREAM("test"); post_count = appender->info_.size(); EXPECT_EQ(post_count, pre_count + 4); logger->setLevel( log4cxx::Level::getWarn() ); pre_count = appender->info_.size(); ROS_DEBUG_STREAM("test"); ROS_INFO_STREAM("test"); ROS_WARN_STREAM("test"); ROS_ERROR_STREAM("test"); ROS_FATAL_STREAM("test"); post_count = appender->info_.size(); EXPECT_EQ(post_count, pre_count + 3); logger->setLevel( log4cxx::Level::getError() ); pre_count = appender->info_.size(); ROS_DEBUG_STREAM("test"); ROS_INFO_STREAM("test"); ROS_WARN_STREAM("test"); ROS_ERROR_STREAM("test"); ROS_FATAL_STREAM("test"); post_count = appender->info_.size(); EXPECT_EQ(post_count, pre_count + 2); logger->setLevel( log4cxx::Level::getFatal() ); pre_count = appender->info_.size(); ROS_DEBUG_STREAM("test"); ROS_INFO_STREAM("test"); ROS_WARN_STREAM("test"); ROS_ERROR_STREAM("test"); ROS_FATAL_STREAM("test"); post_count = appender->info_.size(); EXPECT_EQ(post_count, pre_count + 1); logger->setLevel( log4cxx::Level::getOff() ); pre_count = appender->info_.size(); ROS_DEBUG_STREAM("test"); ROS_INFO_STREAM("test"); ROS_WARN_STREAM("test"); ROS_ERROR_STREAM("test"); ROS_FATAL_STREAM("test"); post_count = appender->info_.size(); EXPECT_EQ(post_count, pre_count); } { logger->setLevel( log4cxx::Level::getInfo() ); pre_count = appender->info_.size(); ROS_DEBUG_NAMED("test_name", "test"); ROS_INFO_NAMED("test_name", "test"); ROS_WARN_NAMED("test_name", "test"); ROS_ERROR_NAMED("test_name", "test"); ROS_FATAL_NAMED("test_name", "test"); post_count = appender->info_.size(); EXPECT_EQ(post_count, pre_count + 4); logger->setLevel( log4cxx::Level::getWarn() ); pre_count = appender->info_.size(); ROS_DEBUG_NAMED("test_name", "test"); ROS_INFO_NAMED("test_name", "test"); ROS_WARN_NAMED("test_name", "test"); ROS_ERROR_NAMED("test_name", "test"); ROS_FATAL_NAMED("test_name", "test"); post_count = appender->info_.size(); EXPECT_EQ(post_count, pre_count + 3); logger->setLevel( log4cxx::Level::getError() ); pre_count = appender->info_.size(); ROS_DEBUG_NAMED("test_name", "test"); ROS_INFO_NAMED("test_name", "test"); ROS_WARN_NAMED("test_name", "test"); ROS_ERROR_NAMED("test_name", "test"); ROS_FATAL_NAMED("test_name", "test"); post_count = appender->info_.size(); EXPECT_EQ(post_count, pre_count + 2); logger->setLevel( log4cxx::Level::getFatal() ); pre_count = appender->info_.size(); ROS_DEBUG_NAMED("test_name", "test"); ROS_INFO_NAMED("test_name", "test"); ROS_WARN_NAMED("test_name", "test"); ROS_ERROR_NAMED("test_name", "test"); ROS_FATAL_NAMED("test_name", "test"); post_count = appender->info_.size(); EXPECT_EQ(post_count, pre_count + 1); logger->setLevel( log4cxx::Level::getOff() ); pre_count = appender->info_.size(); ROS_DEBUG_NAMED("test_name", "test"); ROS_INFO_NAMED("test_name", "test"); ROS_WARN_NAMED("test_name", "test"); ROS_ERROR_NAMED("test_name", "test"); ROS_FATAL_NAMED("test_name", "test"); post_count = appender->info_.size(); EXPECT_EQ(post_count, pre_count); } { logger->setLevel( log4cxx::Level::getInfo() ); pre_count = appender->info_.size(); ROS_DEBUG_STREAM_NAMED("test_name", "test"); ROS_INFO_STREAM_NAMED("test_name", "test"); ROS_WARN_STREAM_NAMED("test_name", "test"); ROS_ERROR_STREAM_NAMED("test_name", "test"); ROS_FATAL_STREAM_NAMED("test_name", "test"); post_count = appender->info_.size(); EXPECT_EQ(post_count, pre_count + 4); logger->setLevel( log4cxx::Level::getWarn() ); pre_count = appender->info_.size(); ROS_DEBUG_STREAM_NAMED("test_name", "test"); ROS_INFO_STREAM_NAMED("test_name", "test"); ROS_WARN_STREAM_NAMED("test_name", "test"); ROS_ERROR_STREAM_NAMED("test_name", "test"); ROS_FATAL_STREAM_NAMED("test_name", "test"); post_count = appender->info_.size(); EXPECT_EQ(post_count, pre_count + 3); logger->setLevel( log4cxx::Level::getError() ); pre_count = appender->info_.size(); ROS_DEBUG_STREAM_NAMED("test_name", "test"); ROS_INFO_STREAM_NAMED("test_name", "test"); ROS_WARN_STREAM_NAMED("test_name", "test"); ROS_ERROR_STREAM_NAMED("test_name", "test"); ROS_FATAL_STREAM_NAMED("test_name", "test"); post_count = appender->info_.size(); EXPECT_EQ(post_count, pre_count + 2); logger->setLevel( log4cxx::Level::getFatal() ); pre_count = appender->info_.size(); ROS_DEBUG_STREAM_NAMED("test_name", "test"); ROS_INFO_STREAM_NAMED("test_name", "test"); ROS_WARN_STREAM_NAMED("test_name", "test"); ROS_ERROR_STREAM_NAMED("test_name", "test"); ROS_FATAL_STREAM_NAMED("test_name", "test"); post_count = appender->info_.size(); EXPECT_EQ(post_count, pre_count + 1); logger->setLevel( log4cxx::Level::getOff() ); pre_count = appender->info_.size(); ROS_DEBUG_STREAM_NAMED("test_name", "test"); ROS_INFO_STREAM_NAMED("test_name", "test"); ROS_WARN_STREAM_NAMED("test_name", "test"); ROS_ERROR_STREAM_NAMED("test_name", "test"); ROS_FATAL_STREAM_NAMED("test_name", "test"); post_count = appender->info_.size(); EXPECT_EQ(post_count, pre_count); } logger->removeAppender( appender ); } TEST(RosConsole, changingLevel) { log4cxx::LoggerPtr logger = log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME); TestAppender* appender = new TestAppender; logger->addAppender( appender ); logger->setLevel( log4cxx::Level::getError() ); for ( int i = ros::console::levels::Debug; i < ros::console::levels::Count; ++i ) { ROS_LOG((ros::console::Level)i, ROSCONSOLE_DEFAULT_NAME, "test"); } EXPECT_EQ((int)appender->info_.size(), 2); logger->removeAppender( appender ); logger->setLevel( log4cxx::Level::getDebug() ); } TEST(RosConsole, changingLoggerLevel) { log4cxx::LoggerPtr logger = log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME); TestAppender* appender = new TestAppender; logger->addAppender( appender ); logger->setLevel(log4cxx::Level::getDebug()); ros::console::notifyLoggerLevelsChanged(); ROS_LOG(ros::console::levels::Debug, ROSCONSOLE_DEFAULT_NAME, "test"); logger->setLevel(log4cxx::Level::getInfo()); ros::console::notifyLoggerLevelsChanged(); ROS_LOG(ros::console::levels::Info, ROSCONSOLE_DEFAULT_NAME, "test"); logger->setLevel(log4cxx::Level::getWarn()); ros::console::notifyLoggerLevelsChanged(); ROS_LOG(ros::console::levels::Warn, ROSCONSOLE_DEFAULT_NAME, "test"); logger->setLevel(log4cxx::Level::getError()); ros::console::notifyLoggerLevelsChanged(); ROS_LOG(ros::console::levels::Error, ROSCONSOLE_DEFAULT_NAME, "test"); logger->setLevel(log4cxx::Level::getFatal()); ros::console::notifyLoggerLevelsChanged(); ROS_LOG(ros::console::levels::Fatal, ROSCONSOLE_DEFAULT_NAME, "test"); EXPECT_EQ((int)appender->info_.size(), 5); logger->removeAppender( appender ); logger->setLevel( log4cxx::Level::getDebug() ); } TEST(RosConsole, longPrintfStyleOutput) { log4cxx::LoggerPtr logger = log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME); TestAppender* appender = new TestAppender; logger->addAppender( appender ); std::stringstream ss; for (int i = 0; i < 100000; ++i ) { ss << 'a'; } ROS_INFO("%s", ss.str().c_str()); ASSERT_EQ((int)appender->info_.size(), 1); EXPECT_STREQ(appender->info_[0].message_.c_str(), ss.str().c_str()); logger->removeAppender( appender ); logger->setLevel( log4cxx::Level::getDebug() ); } TEST(RosConsole, throwingAppender) { log4cxx::LoggerPtr logger = log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME); TestAppenderWithThrow* appender = new TestAppenderWithThrow; logger->addAppender( appender ); try { ROS_INFO("Hello there"); } catch (std::exception& e) { FAIL(); } logger->removeAppender( appender ); logger->setLevel( log4cxx::Level::getDebug() ); } void onceFunc() { ROS_LOG_ONCE(ros::console::levels::Info, ROSCONSOLE_DEFAULT_NAME, "Hello"); } TEST(RosConsole, once) { log4cxx::LoggerPtr logger = log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME); TestAppender* appender = new TestAppender; logger->addAppender(appender); onceFunc(); onceFunc(); EXPECT_EQ(appender->info_.size(), 1ULL); logger->removeAppender(appender); } void throttleFunc() { ROS_LOG_THROTTLE(0.5, ros::console::levels::Info, ROSCONSOLE_DEFAULT_NAME, "Hello"); } TEST(RosConsole, throttle) { log4cxx::LoggerPtr logger = log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME); TestAppender* appender = new TestAppender; logger->addAppender(appender); ros::Time start = ros::Time::now(); while (ros::Time::now() <= start + ros::Duration(0.5)) { throttleFunc(); ros::Duration(0.01).sleep(); } throttleFunc(); EXPECT_EQ(appender->info_.size(), 2ULL); logger->removeAppender(appender); } void delayedThrottleFunc() { ROS_LOG_DELAYED_THROTTLE(0.5, ros::console::levels::Info, ROSCONSOLE_DEFAULT_NAME, "Hello"); } void delayedThrottleFunc2() { ROS_LOG_DELAYED_THROTTLE(0.5, ros::console::levels::Info, ROSCONSOLE_DEFAULT_NAME, "Hello2"); } TEST(RosConsole, delayedThrottle) { log4cxx::LoggerPtr logger = log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME); TestAppender* appender = new TestAppender; logger->addAppender(appender); ros::Time start = ros::Time::now(); while (ros::Time::now() <= start + ros::Duration(0.4)) { delayedThrottleFunc(); ros::Duration(0.01).sleep(); } EXPECT_EQ(appender->info_.size(), 0ULL); const int pre_count = appender->info_.size(); start = ros::Time::now(); while (ros::Time::now() <= start + ros::Duration(0.6)) { delayedThrottleFunc2(); ros::Duration(0.01).sleep(); } const int post_count = appender->info_.size(); EXPECT_EQ(post_count, pre_count + 1); logger->removeAppender(appender); } void onceStreamFunc() { ROS_LOG_STREAM_ONCE(ros::console::levels::Info, ROSCONSOLE_DEFAULT_NAME, "Hello"); } TEST(RosConsole, onceStream) { log4cxx::LoggerPtr logger = log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME); TestAppender* appender = new TestAppender; logger->addAppender(appender); onceStreamFunc(); onceStreamFunc(); EXPECT_EQ(appender->info_.size(), 1ULL); logger->removeAppender(appender); } void throttleStreamFunc() { ROS_LOG_STREAM_THROTTLE(0.5, ros::console::levels::Info, ROSCONSOLE_DEFAULT_NAME, "Hello"); } TEST(RosConsole, throttleStream) { log4cxx::LoggerPtr logger = log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME); TestAppender* appender = new TestAppender; logger->addAppender(appender); ros::Time start = ros::Time::now(); while (ros::Time::now() <= start + ros::Duration(0.5)) { throttleStreamFunc(); ros::Duration(0.01).sleep(); } throttleStreamFunc(); EXPECT_EQ(appender->info_.size(), 2ULL); logger->removeAppender(appender); } void delayedThrottleStreamFunc() { ROS_LOG_STREAM_DELAYED_THROTTLE(0.5, ros::console::levels::Info, ROSCONSOLE_DEFAULT_NAME, "Hello"); } void delayedThrottleStreamFunc2() { ROS_LOG_STREAM_DELAYED_THROTTLE(0.5, ros::console::levels::Info, ROSCONSOLE_DEFAULT_NAME, "Hello2"); } TEST(RosConsole, delayedStreamThrottle) { log4cxx::LoggerPtr logger = log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME); TestAppender* appender = new TestAppender; logger->addAppender(appender); ros::Time start = ros::Time::now(); while (ros::Time::now() <= start + ros::Duration(0.4)) { delayedThrottleStreamFunc(); ros::Duration(0.01).sleep(); } EXPECT_EQ(appender->info_.size(), 0ULL); const int pre_count = appender->info_.size(); start = ros::Time::now(); while (ros::Time::now() <= start + ros::Duration(0.6)) { delayedThrottleStreamFunc2(); ros::Duration(0.01).sleep(); } const int post_count = appender->info_.size(); EXPECT_EQ(post_count, pre_count + 1); logger->removeAppender(appender); } TEST(RosConsole, basicFilter) { log4cxx::LoggerPtr logger = log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME); TestAppender* appender = new TestAppender; logger->addAppender(appender); BasicFilter trueFilter(true), falseFilter(false); ROS_LOG_FILTER(&trueFilter, ros::console::levels::Info, ROSCONSOLE_DEFAULT_NAME, "Hello"); ROS_LOG_FILTER(&falseFilter, ros::console::levels::Info, ROSCONSOLE_DEFAULT_NAME, "Hello2"); ASSERT_EQ(appender->info_.size(), 1ULL); EXPECT_STREQ(appender->info_[0].message_.c_str(), "Hello"); logger->removeAppender(appender); } TEST(RosConsole, basicFilterStream) { log4cxx::LoggerPtr logger = log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME); TestAppender* appender = new TestAppender; logger->addAppender(appender); BasicFilter trueFilter(true), falseFilter(false); ROS_LOG_STREAM_FILTER(&trueFilter, ros::console::levels::Info, ROSCONSOLE_DEFAULT_NAME, "Hello"); ROS_LOG_STREAM_FILTER(&falseFilter, ros::console::levels::Info, ROSCONSOLE_DEFAULT_NAME, "Hello2"); ASSERT_EQ(appender->info_.size(), 1ULL); EXPECT_STREQ(appender->info_[0].message_.c_str(), "Hello"); logger->removeAppender(appender); } struct AdvancedFilter : public ros::console::FilterBase { AdvancedFilter(bool enabled) : enabled_(enabled) , count_(0) {} using ros::console::FilterBase::isEnabled; inline virtual bool isEnabled(ros::console::FilterParams& params) { fprintf(stderr, "%s %s:%d:%s\n", params.message, params.file, params.line, params.function); ++count_; return enabled_; } bool enabled_; int count_; }; TEST(RosConsole, advancedFilter) { log4cxx::LoggerPtr logger = log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME); TestAppender* appender = new TestAppender; logger->addAppender(appender); AdvancedFilter trueFilter(true), falseFilter(false); ROS_LOG_FILTER(&trueFilter, ros::console::levels::Info, ROSCONSOLE_DEFAULT_NAME, "Hello"); ROS_LOG_FILTER(&falseFilter, ros::console::levels::Info, ROSCONSOLE_DEFAULT_NAME, "Hello2"); ASSERT_EQ(appender->info_.size(), 1ULL); EXPECT_STREQ(appender->info_[0].message_.c_str(), "Hello"); EXPECT_EQ(trueFilter.count_, 1); EXPECT_EQ(falseFilter.count_, 1); logger->removeAppender(appender); } TEST(RosConsole, advancedFilterStream) { log4cxx::LoggerPtr logger = log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME); TestAppender* appender = new TestAppender; logger->addAppender(appender); AdvancedFilter trueFilter(true), falseFilter(false); ROS_LOG_STREAM_FILTER(&trueFilter, ros::console::levels::Info, ROSCONSOLE_DEFAULT_NAME, "Hello"); ROS_LOG_STREAM_FILTER(&falseFilter, ros::console::levels::Info, ROSCONSOLE_DEFAULT_NAME, "Hello2"); ASSERT_EQ(appender->info_.size(), 1ULL); EXPECT_STREQ(appender->info_[0].message_.c_str(), "Hello"); EXPECT_EQ(trueFilter.count_, 1); EXPECT_EQ(falseFilter.count_, 1); logger->removeAppender(appender); } struct ChangeFilter : public ros::console::FilterBase { using ros::console::FilterBase::isEnabled; inline virtual bool isEnabled(ros::console::FilterParams& params) { params.out_message = "haha"; params.level = ros::console::levels::Error; return true; } }; TEST(RosConsole, changeFilter) { log4cxx::LoggerPtr logger = log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME); TestAppender* appender = new TestAppender; logger->addAppender(appender); ChangeFilter filter; ROS_LOG_FILTER(&filter, ros::console::levels::Info, ROSCONSOLE_DEFAULT_NAME, "Hello"); ASSERT_EQ(appender->info_.size(), 1ULL); EXPECT_STREQ(appender->info_[0].message_.c_str(), "haha"); EXPECT_EQ(appender->info_[0].level_, log4cxx::Level::getError()); logger->removeAppender(appender); } TEST(RosConsole, changeFilterStream) { log4cxx::LoggerPtr logger = log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME); TestAppender* appender = new TestAppender; logger->addAppender(appender); ChangeFilter filter; ROS_LOG_STREAM_FILTER(&filter, ros::console::levels::Info, ROSCONSOLE_DEFAULT_NAME, "Hello"); ASSERT_EQ(appender->info_.size(), 1ULL); EXPECT_STREQ(appender->info_[0].message_.c_str(), "haha"); EXPECT_EQ(appender->info_[0].level_, log4cxx::Level::getError()); logger->removeAppender(appender); } TEST(RosConsole, formatToBufferInitialZero) { boost::shared_array buffer; size_t size = 0; ros::console::formatToBuffer(buffer, size, "Hello World %d", 5); EXPECT_EQ(size, 14U); EXPECT_STREQ(buffer.get(), "Hello World 5"); } TEST(RosConsole, formatToBufferInitialLargerThanFormat) { boost::shared_array buffer(new char[30]); size_t size = 30; ros::console::formatToBuffer(buffer, size, "Hello World %d", 5); EXPECT_EQ(size, 30U); EXPECT_STREQ(buffer.get(), "Hello World 5"); } TEST(RosConsole, formatToString) { std::string str = ros::console::formatToString("Hello World %d", 5); EXPECT_STREQ(str.c_str(), "Hello World 5"); } TEST(RosConsole, formatter) { std::string format_string; ros::console::Level level = ros::console::levels::Info; char str[32]; char file[32]; char function[32]; std::string result; // default time { std::string format_string = "${time}"; ros::console::g_formatter.tokens_.clear(); ros::console::g_formatter.init(format_string.c_str()); result = ros::console::g_formatter.getTokenStrings( log4cxx::Logger::getLogger(ROSCONSOLE_ROOT_LOGGER_NAME), level, str, file, function, 0); boost::regex expr("([0-9]+)\\.([0-9]+)"); EXPECT_TRUE(boost::regex_match(result, expr)); } // time format { std::string format_string = "${time:%Y %H:%M:%S}"; ros::console::g_formatter.tokens_.clear(); ros::console::g_formatter.init(format_string.c_str()); result = ros::console::g_formatter.getTokenStrings( log4cxx::Logger::getLogger(ROSCONSOLE_ROOT_LOGGER_NAME), level, str, file, function, 0); boost::regex expr("([0-9]{4}) ([0-9]{2}:[0-9]{2}:[0-9]{2})"); EXPECT_TRUE(boost::regex_match(result, expr)); } // default walltime { std::string format_string = "${walltime}"; ros::console::g_formatter.tokens_.clear(); ros::console::g_formatter.init(format_string.c_str()); result = ros::console::g_formatter.getTokenStrings( log4cxx::Logger::getLogger(ROSCONSOLE_ROOT_LOGGER_NAME), level, str, file, function, 0); boost::regex expr("([0-9]+)\\.([0-9]+)"); EXPECT_TRUE(boost::regex_match(result, expr)); } // walltime format { std::string format_string = "${walltime:%Y %H:%M:%S}"; ros::console::g_formatter.tokens_.clear(); ros::console::g_formatter.init(format_string.c_str()); result = ros::console::g_formatter.getTokenStrings( log4cxx::Logger::getLogger(ROSCONSOLE_ROOT_LOGGER_NAME), level, str, file, function, 0); boost::regex expr("([0-9]{4}) ([0-9]{2}:[0-9]{2}:[0-9]{2})"); EXPECT_TRUE(boost::regex_match(result, expr)); } } int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv); ros::Time::init(); ROSCONSOLE_AUTOINIT; log4cxx::Logger::getLogger(ROSCONSOLE_ROOT_LOGGER_NAME)->removeAllAppenders(); log4cxx::Logger::getRootLogger()->setLevel(log4cxx::Level::getDebug()); log4cxx::Logger::getLogger(ROSCONSOLE_ROOT_LOGGER_NAME)->setLevel(log4cxx::Level::getDebug()); return RUN_ALL_TESTS(); }