Note: Goby version 1 (shown here) is now considered obsolete. Please use version 2 for new projects, and consider upgrading old projects.

Goby Underwater Autonomy Project  Series: 1.1, revision: 163, released on 2013-02-06 14:23:27 -0500
util/liblogger/flex_ostream.h
00001 // copyright 2009 t. schneider tes@mit.edu
00002 // 
00003 // this file is part of flex-ostream, a terminal display library
00004 // that provides an ostream with both terminal display and file logging
00005 //
00006 // This program is free software: you can redistribute it and/or modify
00007 // it under the terms of the GNU General Public License as published by
00008 // the Free Software Foundation, either version 3 of the License, or
00009 // (at your option) any later version.
00010 //
00011 // This software is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU General Public License
00017 // along with this software.  If not, see <http://www.gnu.org/licenses/>.
00018 
00019 #ifndef FlexOstream20091211H
00020 #define FlexOstream20091211H
00021 
00022 #include <iostream>
00023 #include <string>
00024 #include <iomanip>
00025 
00026 #include "flex_ostreambuf.h"
00027 #include "logger_manipulators.h"
00028 
00029 #include <google/protobuf/text_format.h>
00030 #include <google/protobuf/io/tokenizer.h>
00031 
00032 #include <boost/shared_ptr.hpp>
00033 
00034 namespace goby
00035 {
00036     namespace util
00037     {
00038         namespace logger_lock
00039         {
00041             enum LockAction { none, lock };
00042         }
00043 
00045         class FlexOstream : public std::ostream
00046         {
00047           public:
00049 
00050 
00051 
00052             void add_group(const std::string & name,
00053                            Colors::Color color = Colors::nocolor,
00054                            const std::string & description = "");
00055             
00057             void set_name(const std::string & s)
00058             {
00059                 sb_.name(s);
00060             }
00061 
00062             void add_stream(const std::string& verbosity, std::ostream* os = 0)
00063             {
00064                 if(verbosity == "scope" || verbosity == "gui")        
00065                     add_stream(goby::util::Logger::gui, os);
00066                 else if(verbosity == "quiet")        
00067                     add_stream(goby::util::Logger::quiet, os);
00068                 else if(verbosity == "terse" || verbosity == "warn")        
00069                     add_stream(goby::util::Logger::warn, os);
00070                 else if(verbosity == "debug")        
00071                     add_stream(goby::util::Logger::debug, os);
00072                 else
00073                     add_stream(goby::util::Logger::verbose, os);
00074             }
00075             
00076             
00078             void add_stream(Logger::Verbosity verbosity = Logger::verbose, std::ostream* os = 0)
00079             {
00080                 sb_.add_stream(verbosity, os);
00081             }            
00083 
00085 
00086             // overload this function so we can look for the die manipulator
00087             // and set the die_flag
00088             // to exit after this line
00089             std::ostream& operator<<(FlexOstream& (*pf) (FlexOstream&));
00090             std::ostream& operator<<(std::ostream & (*pf) (std::ostream &));
00091             
00092             //provide interfaces to the rest of the types
00093             std::ostream& operator<< (bool& val )
00094             { return std::ostream::operator<<(val); }
00095             std::ostream& operator<< (const short& val )
00096             { return std::ostream::operator<<(val); }
00097             std::ostream& operator<< (const unsigned short& val )
00098             { return std::ostream::operator<<(val); }
00099             std::ostream& operator<< (const int& val )
00100             { return std::ostream::operator<<(val); }
00101             std::ostream& operator<< (const unsigned int& val )
00102             { return std::ostream::operator<<(val); }
00103             std::ostream& operator<< (const long& val )
00104             { return std::ostream::operator<<(val); }
00105             std::ostream& operator<< (const unsigned long& val )
00106             { return std::ostream::operator<<(val); }
00107             std::ostream& operator<< (const float& val )
00108             { return std::ostream::operator<<(val); }
00109             std::ostream& operator<< (const double& val )
00110             { return std::ostream::operator<<(val); }
00111             std::ostream& operator<< (const long double& val )
00112             { return std::ostream::operator<<(val); }
00113             std::ostream& operator<< (std::streambuf* sb )
00114             { return std::ostream::operator<<(sb); }
00115             std::ostream& operator<< (std::ios& ( *pf )(std::ios&))
00116             { return std::ostream::operator<<(pf); }
00117             std::ostream& operator<< (std::ios_base& ( *pf )(std::ios_base&))
00118             { return std::ostream::operator<<(pf); }
00120 
00122 
00123 
00124             boost::mutex& mutex()
00125             { return Logger::mutex; }
00127 
00128             void refresh()
00129             {
00130                 sb_.refresh();
00131             }
00132             void set_group(const std::string & s)
00133             {
00134                 sb_.group_name(s);
00135             }            
00136             
00137           private:            
00138             bool quiet()
00139             { return (sb_.is_quiet()); }
00140             
00141             
00142             friend FlexOstream& glogger(logger_lock::LockAction lock_action);
00143 
00144             template<typename T>
00145                 friend void boost::checked_delete(T*);
00146             
00147             friend std::ostream& operator<< (FlexOstream& out, char c );
00148             friend std::ostream& operator<< (FlexOstream& out, signed char c );
00149             friend std::ostream& operator<< (FlexOstream& out, unsigned char c );
00150             friend std::ostream& operator<< (FlexOstream& out, const char *s );
00151             friend std::ostream& operator<< (FlexOstream& out, const signed char* s );
00152             friend std::ostream& operator<< (FlexOstream& out, const unsigned char* s );
00153 
00154           private:
00155           FlexOstream() : std::ostream(&sb_) {}
00156             ~FlexOstream() { }
00157             FlexOstream(const FlexOstream&);
00158             FlexOstream& operator = (const FlexOstream&);            
00159 
00160           private:
00161             static boost::shared_ptr<goby::util::FlexOstream> inst_;
00162             FlexOStreamBuf sb_;
00163         };        
00165 
00166 
00167 
00168 
00169 
00170 
00171 
00172 
00173 
00174 
00175 
00176 
00177 
00178 
00179 
00180 
00181 
00182 
00183 
00184         FlexOstream& glogger(logger_lock::LockAction lock_action = logger_lock::none);
00185         
00186         inline std::ostream& operator<< (FlexOstream& out, char c )
00187         { return std::operator<<(out, c); }
00188         inline std::ostream& operator<< (FlexOstream& out, signed char c )
00189         { return std::operator<<(out, c); }
00190         inline std::ostream& operator<< (FlexOstream& out, unsigned char c )
00191         { return std::operator<<(out, c); }        
00192         inline std::ostream& operator<< (FlexOstream& out, const char* s )
00193         { return std::operator<<(out, s); }        
00194         inline std::ostream& operator<< (FlexOstream& out, const signed char* s )
00195         { return std::operator<<(out, s); }        
00196         inline std::ostream& operator<< (FlexOstream& out, const unsigned char* s )
00197         { return std::operator<<(out, s); }                    
00199 
00200     }
00201 }
00202 
00203 
00205 inline std::ostream& unlock(std::ostream & os)
00206 {
00207     goby::util::Logger::mutex.unlock();    
00208     return os;
00209 }
00210 
00211 class FlexOStreamErrorCollector : public google::protobuf::io::ErrorCollector
00212 {
00213   public:
00214   FlexOStreamErrorCollector(const std::string& original)
00215       : original_(original),
00216         has_warnings_(false),
00217         has_errors_(false)
00218         { }
00219     
00220     void AddError(int line, int column, const std::string& message)
00221     {
00222         print_original(line, column);
00223         goby::util::glogger() << warn << "line: " << line << " col: " << column << " " << message << std::endl;
00224         has_errors_ = true;
00225     }
00226     void AddWarning(int line, int column, const std::string& message)
00227     {
00228         print_original(line, column);
00229         goby::util::glogger() << warn << "line: " << line << " col: " << column << " " << message << std::endl;
00230         has_warnings_ = true;
00231     }
00232     
00233     void print_original(int line, int column)
00234     {
00235         std::stringstream ss(original_ + "\n");
00236         std::string line_str;
00237 
00238         //for(int i = 0; i <= line; ++i)
00239         //    getline(ss, line_str);
00240 
00241         int i = 0;
00242         while(!getline(ss, line_str).eof())
00243         {
00244             if(i == line)
00245                 goby::util::glogger() << goby::util::tcolor::lt_red << "[line " << std::setw(3) << i++ << "]" << line_str << goby::util::tcolor::nocolor << std::endl;
00246             else
00247                 goby::util::glogger() << "[line " << std::setw(3) << i++ << "]" << line_str << std::endl;       
00248         }
00249     }
00250 
00251 
00252     bool has_errors() { return has_errors_; }
00253     bool has_warnings() { return has_warnings_; }
00254     
00255     
00256   private:
00257     const std::string& original_;
00258     bool has_warnings_;
00259     bool has_errors_;
00260 };
00261 
00262 
00263 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends