All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator
Console.cpp
00001 /*********************************************************************
00002 * Software License Agreement (BSD License)
00003 *
00004 *  Copyright (c) 2008, Willow Garage, Inc.
00005 *  All rights reserved.
00006 *
00007 *  Redistribution and use in source and binary forms, with or without
00008 *  modification, are permitted provided that the following conditions
00009 *  are met:
00010 *
00011 *   * Redistributions of source code must retain the above copyright
00012 *     notice, this list of conditions and the following disclaimer.
00013 *   * Redistributions in binary form must reproduce the above
00014 *     copyright notice, this list of conditions and the following
00015 *     disclaimer in the documentation and/or other materials provided
00016 *     with the distribution.
00017 *   * Neither the name of the Willow Garage nor the names of its
00018 *     contributors may be used to endorse or promote products derived
00019 *     from this software without specific prior written permission.
00020 *
00021 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032 *  POSSIBILITY OF SUCH DAMAGE.
00033 *********************************************************************/
00034 
00035 /* Author: Ioan Sucan */
00036 
00037 #include "ompl/util/Console.h"
00038 #include <boost/thread/mutex.hpp>
00039 #include <iostream>
00040 #include <cstdlib>
00041 #include <cstdio>
00042 #include <cstdarg>
00043 
00044 static ompl::msg::OutputHandlerSTD DEFAULT_OUTPUT_HANDLER;
00045 static ompl::msg::OutputHandler   *OUTPUT_HANDLER = static_cast<ompl::msg::OutputHandler*>(&DEFAULT_OUTPUT_HANDLER);
00046 static ompl::msg::OutputHandler   *PREVIOUS_OH = OUTPUT_HANDLER;
00047 static boost::mutex                LOCK; // it is likely the outputhandler does some I/O, so we serialize it
00048 
00049 void ompl::msg::noOutputHandler(void)
00050 {
00051     LOCK.lock();
00052     PREVIOUS_OH = OUTPUT_HANDLER;
00053     OUTPUT_HANDLER = NULL;
00054     LOCK.unlock();
00055 }
00056 
00057 void ompl::msg::restorePreviousOutputHandler(void)
00058 {
00059     LOCK.lock();
00060     std::swap(PREVIOUS_OH, OUTPUT_HANDLER);
00061     LOCK.unlock();
00062 }
00063 
00064 void ompl::msg::useOutputHandler(OutputHandler *oh)
00065 {
00066     LOCK.lock();
00067     PREVIOUS_OH = OUTPUT_HANDLER;
00068     OUTPUT_HANDLER = oh;
00069     LOCK.unlock();
00070 }
00071 
00072 ompl::msg::OutputHandler* ompl::msg::getOutputHandler(void)
00073 {
00074     return OUTPUT_HANDLER;
00075 }
00076 
00077 ompl::msg::Interface::Interface(const std::string &prefix)
00078 {
00079     setPrefix(prefix);
00080 }
00081 
00082 ompl::msg::Interface::~Interface(void)
00083 {
00084 }
00085 
00086 const std::string& ompl::msg::Interface::getPrefix(void) const
00087 {
00088     return prefix_;
00089 }
00090 
00091 void ompl::msg::Interface::setPrefix(const std::string &prefix)
00092 {
00093     prefix_ = prefix;
00094     if (!prefix_.empty())
00095         prefix_ += ": ";
00096 }
00097 
00098 // the maximum buffer size to use when printing a message
00099 #define MAX_BUFFER_SIZE 1024
00100 
00101 // macro that combines the set of arguments into a single string
00102 #define COMBINE(m, buf, size)                                                \
00103     va_list __ap;                                                        \
00104     va_start(__ap, m);                                                        \
00105     char buf##_chr[size];                                                \
00106     vsnprintf(buf##_chr, sizeof(buf##_chr), m, __ap);                        \
00107     va_end(__ap);                                                        \
00108     buf##_chr[size - 1] = '\0';                                                \
00109     std::string buf(buf##_chr)
00110 
00111 void ompl::msg::Interface::debug(const std::string &text) const
00112 {
00113     if (OUTPUT_HANDLER)
00114     {
00115         LOCK.lock();
00116         OUTPUT_HANDLER->debug(prefix_ + text);
00117         LOCK.unlock();
00118     }
00119 }
00120 
00121 void ompl::msg::Interface::debug(const char *msg, ...) const
00122 {
00123     COMBINE(msg, buf, MAX_BUFFER_SIZE);
00124     debug(buf);
00125 }
00126 
00127 void ompl::msg::Interface::inform(const std::string &text) const
00128 {
00129     if (OUTPUT_HANDLER)
00130     {
00131         LOCK.lock();
00132         OUTPUT_HANDLER->inform(prefix_ + text);
00133         LOCK.unlock();
00134     }
00135 }
00136 
00137 void ompl::msg::Interface::inform(const char *msg, ...) const
00138 {
00139     COMBINE(msg, buf, MAX_BUFFER_SIZE);
00140     inform(buf);
00141 }
00142 
00143 void ompl::msg::Interface::warn(const std::string &text) const
00144 {
00145     if (OUTPUT_HANDLER)
00146     {
00147         LOCK.lock();
00148         OUTPUT_HANDLER->warn(prefix_ + text);
00149         LOCK.unlock();
00150     }
00151 }
00152 
00153 void ompl::msg::Interface::warn(const char *msg, ...) const
00154 {
00155     COMBINE(msg, buf, MAX_BUFFER_SIZE);
00156     warn(buf);
00157 }
00158 
00159 void ompl::msg::Interface::error(const std::string &text) const
00160 {
00161     if (OUTPUT_HANDLER)
00162     {
00163         LOCK.lock();
00164         OUTPUT_HANDLER->error(prefix_ + text);
00165         LOCK.unlock();
00166     }
00167 }
00168 
00169 void ompl::msg::Interface::error(const char *msg, ...) const
00170 {
00171     COMBINE(msg, buf, MAX_BUFFER_SIZE);
00172     error(buf);
00173 }
00174 
00175 void ompl::msg::OutputHandlerSTD::error(const std::string &text)
00176 {
00177     std::cerr << "Error:   " << text << std::endl;
00178     std::cerr.flush();
00179 }
00180 
00181 void ompl::msg::OutputHandlerSTD::warn(const std::string &text)
00182 {
00183     std::cerr << "Warning: " << text << std::endl;
00184     std::cerr.flush();
00185 }
00186 
00187 void ompl::msg::OutputHandlerSTD::inform(const std::string &text)
00188 {
00189     std::cout << "Info:    " << text << std::endl;
00190     std::cout.flush();
00191 }
00192 
00193 void ompl::msg::OutputHandlerSTD::debug(const std::string &text)
00194 {
00195     std::cout << "Debug:   " << text << std::endl;
00196     std::cout.flush();
00197 }
00198 
00199 ompl::msg::OutputHandlerFile::OutputHandlerFile(const char *filename) : OutputHandler()
00200 {
00201     file_ = fopen(filename, "a");
00202     if (!file_)
00203         std::cerr << "Unable to open log file: '" << filename << "'" << std::endl;
00204 }
00205 
00206 ompl::msg::OutputHandlerFile::~OutputHandlerFile(void)
00207 {
00208     if (file_)
00209         if (fclose(file_) != 0)
00210             std::cerr << "Error closing logfile" << std::endl;
00211 }
00212 
00213 void ompl::msg::OutputHandlerFile::error(const std::string &text)
00214 {
00215     if (file_)
00216     {
00217         fprintf(file_, "Error:   %s\n", text.c_str());
00218         fflush(file_);
00219     }
00220 }
00221 
00222 void ompl::msg::OutputHandlerFile::warn(const std::string &text)
00223 {
00224     if (file_)
00225     {
00226         fprintf(file_, "Warning: %s\n", text.c_str());
00227         fflush(file_);
00228     }
00229 }
00230 
00231 void ompl::msg::OutputHandlerFile::inform(const std::string &text)
00232 {
00233     if (file_)
00234     {
00235         fprintf(file_, "Info:    %s\n", text.c_str());
00236         fflush(file_);
00237     }
00238 }
00239 
00240 void ompl::msg::OutputHandlerFile::debug(const std::string &text)
00241 {
00242     if (file_)
00243     {
00244         fprintf(file_, "Debug:   %s\n", text.c_str());
00245         fflush(file_);
00246     }
00247 }