v01
This commit is contained in:
183
thirdparty/ros/console_bridge/src/console.cpp
vendored
Normal file
183
thirdparty/ros/console_bridge/src/console.cpp
vendored
Normal file
@@ -0,0 +1,183 @@
|
||||
/*********************************************************************
|
||||
* 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 the Willow Garage 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: Ryan Luna, Ioan Sucan */
|
||||
|
||||
#include "console_bridge/console.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
|
||||
#include <iostream>
|
||||
#include <mutex>
|
||||
|
||||
/// @cond IGNORE
|
||||
|
||||
struct DefaultOutputHandler
|
||||
{
|
||||
DefaultOutputHandler(void)
|
||||
{
|
||||
output_handler_ = static_cast<console_bridge::OutputHandler*>(&std_output_handler_);
|
||||
previous_output_handler_ = output_handler_;
|
||||
logLevel_ = console_bridge::CONSOLE_BRIDGE_LOG_WARN;
|
||||
}
|
||||
|
||||
console_bridge::OutputHandlerSTD std_output_handler_;
|
||||
console_bridge::OutputHandler *output_handler_;
|
||||
console_bridge::OutputHandler *previous_output_handler_;
|
||||
console_bridge::LogLevel logLevel_;
|
||||
std::mutex lock_; // it is likely the outputhandler does some I/O, so we serialize it
|
||||
};
|
||||
|
||||
// we use this function because we want to handle static initialization correctly
|
||||
// however, the first run of this function is not thread safe, due to the use of a static
|
||||
// variable inside the function. For this reason, we ensure the first call happens during
|
||||
// static initialization using a proxy class
|
||||
static DefaultOutputHandler* getDOH(void)
|
||||
{
|
||||
static DefaultOutputHandler DOH;
|
||||
return &DOH;
|
||||
}
|
||||
|
||||
#define USE_DOH \
|
||||
DefaultOutputHandler *doh = getDOH(); \
|
||||
std::lock_guard<std::mutex> lock_guard(doh->lock_)
|
||||
|
||||
#define MAX_BUFFER_SIZE 1024
|
||||
|
||||
/// @endcond
|
||||
|
||||
void console_bridge::noOutputHandler(void)
|
||||
{
|
||||
USE_DOH;
|
||||
doh->previous_output_handler_ = doh->output_handler_;
|
||||
doh->output_handler_ = NULL;
|
||||
}
|
||||
|
||||
void console_bridge::restorePreviousOutputHandler(void)
|
||||
{
|
||||
USE_DOH;
|
||||
std::swap(doh->previous_output_handler_, doh->output_handler_);
|
||||
}
|
||||
|
||||
void console_bridge::useOutputHandler(OutputHandler *oh)
|
||||
{
|
||||
USE_DOH;
|
||||
doh->previous_output_handler_ = doh->output_handler_;
|
||||
doh->output_handler_ = oh;
|
||||
}
|
||||
|
||||
console_bridge::OutputHandler* console_bridge::getOutputHandler(void)
|
||||
{
|
||||
return getDOH()->output_handler_;
|
||||
}
|
||||
|
||||
void console_bridge::log(const char *file, int line, LogLevel level, const char* m, ...)
|
||||
{
|
||||
USE_DOH;
|
||||
if (doh->output_handler_ && level >= doh->logLevel_)
|
||||
{
|
||||
va_list __ap;
|
||||
va_start(__ap, m);
|
||||
char buf[MAX_BUFFER_SIZE];
|
||||
#ifdef _MSC_VER
|
||||
vsnprintf_s(buf, sizeof(buf), _TRUNCATE, m, __ap);
|
||||
#else
|
||||
vsnprintf(buf, sizeof(buf), m, __ap);
|
||||
#endif
|
||||
va_end(__ap);
|
||||
buf[MAX_BUFFER_SIZE - 1] = '\0';
|
||||
|
||||
doh->output_handler_->log(buf, level, file, line);
|
||||
}
|
||||
}
|
||||
|
||||
void console_bridge::setLogLevel(LogLevel level)
|
||||
{
|
||||
USE_DOH;
|
||||
doh->logLevel_ = level;
|
||||
}
|
||||
|
||||
console_bridge::LogLevel console_bridge::getLogLevel(void)
|
||||
{
|
||||
USE_DOH;
|
||||
return doh->logLevel_;
|
||||
}
|
||||
|
||||
static const char* LogLevelString[4] = {"Debug: ", "Info: ", "Warning: ", "Error: "};
|
||||
|
||||
void console_bridge::OutputHandlerSTD::log(const std::string &text, LogLevel level, const char *filename, int line)
|
||||
{
|
||||
if (level >= CONSOLE_BRIDGE_LOG_WARN)
|
||||
{
|
||||
std::cerr << LogLevelString[level] << text << std::endl;
|
||||
std::cerr << " at line " << line << " in " << filename << std::endl;
|
||||
std::cerr.flush();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << LogLevelString[level] << text << std::endl;
|
||||
std::cout.flush();
|
||||
}
|
||||
}
|
||||
|
||||
console_bridge::OutputHandlerFile::OutputHandlerFile(const char *filename) : OutputHandler()
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
errno_t err = fopen_s(&file_, filename, "a");
|
||||
if (err != 0 || !file_)
|
||||
#else
|
||||
file_ = fopen(filename, "a");
|
||||
if (!file_)
|
||||
#endif
|
||||
std::cerr << "Unable to open log file: '" << filename << "'" << std::endl;
|
||||
}
|
||||
|
||||
console_bridge::OutputHandlerFile::~OutputHandlerFile(void)
|
||||
{
|
||||
if (file_)
|
||||
if (fclose(file_) != 0)
|
||||
std::cerr << "Error closing logfile" << std::endl;
|
||||
}
|
||||
|
||||
void console_bridge::OutputHandlerFile::log(const std::string &text, LogLevel level, const char *filename, int line)
|
||||
{
|
||||
if (file_)
|
||||
{
|
||||
fprintf(file_, "%s%s\n", LogLevelString[level], text.c_str());
|
||||
if(level >= CONSOLE_BRIDGE_LOG_WARN)
|
||||
fprintf(file_, " at line %d in %s\n", line, filename);
|
||||
fflush(file_);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user