Goby3  3.1.5a
2024.05.23
flex_ostream.h
Go to the documentation of this file.
1 // Copyright 2012-2023:
2 // GobySoft, LLC (2013-)
3 // Massachusetts Institute of Technology (2007-2014)
4 // Community contributors (see AUTHORS file)
5 // File authors:
6 // Toby Schneider <toby@gobysoft.org>
7 //
8 //
9 // This file is part of the Goby Underwater Autonomy Project Libraries
10 // ("The Goby Libraries").
11 //
12 // The Goby Libraries are free software: you can redistribute them and/or modify
13 // them under the terms of the GNU Lesser General Public License as published by
14 // the Free Software Foundation, either version 2.1 of the License, or
15 // (at your option) any later version.
16 //
17 // The Goby Libraries are distributed in the hope that they will be useful,
18 // but WITHOUT ANY WARRANTY; without even the implied warranty of
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 // GNU Lesser General Public License for more details.
21 //
22 // You should have received a copy of the GNU Lesser General Public License
23 // along with Goby. If not, see <http://www.gnu.org/licenses/>.
24 
25 #ifndef GOBY_UTIL_DEBUG_LOGGER_FLEX_OSTREAM_H
26 #define GOBY_UTIL_DEBUG_LOGGER_FLEX_OSTREAM_H
27 
28 #include <iomanip>
29 #include <iostream>
30 #include <string>
31 
32 #include <google/protobuf/io/tokenizer.h>
33 #include <google/protobuf/text_format.h>
34 
36 #include "logger_manipulators.h"
37 
38 namespace goby
39 {
40 namespace util
41 {
43 class FlexOstream : public std::ostream
44 {
45  public:
46  FlexOstream() : std::ostream(&sb_), sb_(this)
47  {
48  ++instances_;
49  if (instances_ > 1)
50  {
51  std::cerr << "Fatal error: cannot create more than one instance of FlexOstream. Use "
52  "global object goby::glog to access the Goby Logger. Do not instantiate "
53  "the FlexOstream directly."
54  << std::endl;
55  exit(EXIT_FAILURE);
56  }
57  }
58  ~FlexOstream() override = default;
59 
61 
62  void add_group(const std::string& name, Colors::Color color = Colors::nocolor,
64  const std::string& description = "");
65 
67  void set_name(const std::string& s)
68  {
69  std::lock_guard<std::recursive_mutex> l(goby::util::logger::mutex);
70  sb_.name(s);
71  }
72 
73  void enable_gui()
74  {
75  std::lock_guard<std::recursive_mutex> l(goby::util::logger::mutex);
76  sb_.enable_gui();
77  }
78 
79  bool is(goby::util::logger::Verbosity verbosity);
80 
81  bool is_die() { return is(goby::util::logger::DIE); }
82  bool is_warn() { return is(goby::util::logger::WARN); }
87 
89  void add_stream(logger::Verbosity verbosity = logger::VERBOSE, std::ostream* os = nullptr)
90  {
91  std::lock_guard<std::recursive_mutex> l(goby::util::logger::mutex);
92  sb_.add_stream(verbosity, os);
93  }
94 
97  std::ostream* os = nullptr)
98  {
99  std::lock_guard<std::recursive_mutex> l(goby::util::logger::mutex);
100  sb_.add_stream(static_cast<logger::Verbosity>(verbosity), os);
101  }
102 
103  void remove_stream(std::ostream* os = nullptr)
104  {
105  std::lock_guard<std::recursive_mutex> l(goby::util::logger::mutex);
106  sb_.remove_stream(os);
107  }
108 
109  const FlexOStreamBuf& buf() { return sb_; }
110 
112 
114 
115  // overload this function so we can look for the die manipulator
116  // and set the die_flag
117  // to exit after this line
118  std::ostream& operator<<(FlexOstream& (*pf)(FlexOstream&));
119  std::ostream& operator<<(std::ostream& (*pf)(std::ostream&));
120 
121  //provide interfaces to the rest of the types
122  std::ostream& operator<<(bool& val) { return std::ostream::operator<<(val); }
123  std::ostream& operator<<(const short& val) { return std::ostream::operator<<(val); }
124  std::ostream& operator<<(const unsigned short& val) { return std::ostream::operator<<(val); }
125  std::ostream& operator<<(const int& val) { return std::ostream::operator<<(val); }
126  std::ostream& operator<<(const unsigned int& val) { return std::ostream::operator<<(val); }
127  std::ostream& operator<<(const long& val) { return std::ostream::operator<<(val); }
128  std::ostream& operator<<(const long long& val) { return std::ostream::operator<<(val); }
129  std::ostream& operator<<(const unsigned long& val) { return std::ostream::operator<<(val); }
130  std::ostream& operator<<(const float& val) { return std::ostream::operator<<(val); }
131  std::ostream& operator<<(const double& val) { return std::ostream::operator<<(val); }
132  std::ostream& operator<<(const long double& val) { return std::ostream::operator<<(val); }
133  std::ostream& operator<<(std::streambuf* sb) { return std::ostream::operator<<(sb); }
134  std::ostream& operator<<(std::ios& (*pf)(std::ios&)) { return std::ostream::operator<<(pf); }
135  std::ostream& operator<<(std::ios_base& (*pf)(std::ios_base&))
136  {
137  return std::ostream::operator<<(pf);
138  }
139 
141 
143 
144  std::recursive_mutex& mutex() { return logger::mutex; }
146 
147  void set_lock_action(logger_lock::LockAction lock_action) { sb_.set_lock_action(lock_action); }
149 
150  void refresh() { sb_.refresh(); }
151  void set_group(const std::string& s) { sb_.group_name(s); }
152 
153  // void set_unset_verbosity()
154  // {
155  // if (sb_.verbosity_depth() == goby::util::logger::UNKNOWN)
156  // this->is(goby::util::logger::VERBOSE);
157  // }
158 
159  private:
160  FlexOstream(const FlexOstream&);
161  FlexOstream& operator=(const FlexOstream&);
162 
163  bool quiet() { return (sb_.is_quiet()); }
164 
165  friend std::ostream& operator<<(FlexOstream& out, char c);
166  friend std::ostream& operator<<(FlexOstream& out, signed char c);
167  friend std::ostream& operator<<(FlexOstream& out, unsigned char c);
168  friend std::ostream& operator<<(FlexOstream& out, const char* s);
169  friend std::ostream& operator<<(FlexOstream& out, const signed char* s);
170  friend std::ostream& operator<<(FlexOstream& out, const unsigned char* s);
171 
172  private:
173  static int instances_;
174 
175  private:
176  FlexOStreamBuf sb_;
178 };
179 
180 inline std::ostream& operator<<(FlexOstream& out, char c) { return std::operator<<(out, c); }
181 inline std::ostream& operator<<(FlexOstream& out, signed char c) { return std::operator<<(out, c); }
182 inline std::ostream& operator<<(FlexOstream& out, unsigned char c)
183 {
184  return std::operator<<(out, c);
185 }
186 inline std::ostream& operator<<(FlexOstream& out, const char* s) { return std::operator<<(out, s); }
187 inline std::ostream& operator<<(FlexOstream& out, const signed char* s)
188 {
189  return std::operator<<(out, s);
190 }
191 inline std::ostream& operator<<(FlexOstream& out, const unsigned char* s)
192 {
193  return std::operator<<(out, s);
194 }
196 
197 template <typename _CharT, typename _Traits, typename _Alloc>
198 inline std::ostream& operator<<(FlexOstream& out,
199  const std::basic_string<_CharT, _Traits, _Alloc>& s)
200 {
201  return std::operator<<(out, s);
202 }
203 
204 } // namespace util
205 
207 
208 extern util::FlexOstream glog;
211 namespace util
212 {
213 // for compatibility with Goby1
214 [[deprecated("Use goby::glog")]] inline util::FlexOstream& glogger() { return goby::glog; }
215 
217 {
218  public:
219  FlexOStreamErrorCollector(const std::string& original)
220  : original_(original), has_warnings_(false), has_errors_(false)
221  {
222  }
223 
224  void AddError(int line, int column, const std::string& message) override
225  {
227 
228  print_original(line, column);
229  goby::glog.is(WARN) && goby::glog << "line: " << line << " col: " << column << " "
230  << message << std::endl;
231  has_errors_ = true;
232  }
233  void AddWarning(int line, int column, const std::string& message) override
234  {
236 
237  print_original(line, column);
238  goby::glog.is(WARN) && goby::glog << "line: " << line << " col: " << column << " "
239  << message << std::endl;
240 
241  has_warnings_ = true;
242  }
243 
244  void print_original(int line, int /*column*/)
245  {
247 
248  std::stringstream ss(original_ + "\n");
249  std::string line_str;
250 
251  //for(int i = 0; i <= line; ++i)
252  // getline(ss, line_str);
253 
254  int i = 0;
255  while (!getline(ss, line_str).eof())
256  {
257  if (i == line)
259  << std::setw(3) << i++ << "]" << line_str
260  << goby::util::tcolor::nocolor << std::endl;
261  else
262  goby::glog.is(WARN) && goby::glog << "[line " << std::setw(3) << i++ << "]"
263  << line_str << std::endl;
264  }
265  }
266 
267  bool has_errors() { return has_errors_; }
268  bool has_warnings() { return has_warnings_; }
269 
270  private:
271  const std::string& original_;
272  bool has_warnings_;
273  bool has_errors_;
274 };
275 } // namespace util
276 } // namespace goby
277 
278 #endif
goby::util::FlexOstream::operator<<
std::ostream & operator<<(const unsigned short &val)
Definition: flex_ostream.h:124
goby::util::protobuf::GLogConfig::VERBOSE
static const Verbosity VERBOSE
Definition: debug_logger.pb.h:526
goby::util::Colors::Color
Color
The eight terminal colors (and bold or "light" variants)
Definition: term_color.h:111
goby::util::FlexOstream::operator<<
std::ostream & operator<<(const float &val)
Definition: flex_ostream.h:130
goby::util::FlexOstream::is
bool is(goby::util::logger::Verbosity verbosity)
goby::util::FlexOstream
Forms the basis of the Goby logger: std::ostream derived class for holding the FlexOStreamBuf.
Definition: flex_ostream.h:43
goby::util::FlexOStreamErrorCollector::has_errors
bool has_errors()
Definition: flex_ostream.h:267
goby
The global namespace for the Goby project.
Definition: acomms_constants.h:33
goby::util::logger::DEBUG2
@ DEBUG2
Definition: flex_ostreambuf.h:78
goby::util::FlexOstream::is_warn
bool is_warn()
Definition: flex_ostream.h:82
goby::util::FlexOStreamBuf::is_quiet
bool is_quiet() const
do all attached streams have Verbosity == quiet?
Definition: flex_ostreambuf.h:109
goby::util::FlexOStreamErrorCollector::print_original
void print_original(int line, int)
Definition: flex_ostream.h:244
goby::util::FlexOstream::enable_gui
void enable_gui()
Definition: flex_ostream.h:73
goby::util::FlexOstream::set_group
void set_group(const std::string &s)
Definition: flex_ostream.h:151
goby::util::FlexOstream::operator<<
std::ostream & operator<<(FlexOstream &(*pf)(FlexOstream &))
goby::util::FlexOstream::is_debug3
bool is_debug3()
Definition: flex_ostream.h:86
goby::util::logger::mutex
std::recursive_mutex mutex
goby::util::logger::WARN
@ WARN
Definition: flex_ostreambuf.h:74
goby::util::FlexOstream::~FlexOstream
~FlexOstream() override=default
goby::util::FlexOstream::operator<<
std::ostream & operator<<(const unsigned long &val)
Definition: flex_ostream.h:129
goby::util::FlexOstream::operator<<
std::ostream & operator<<(const long double &val)
Definition: flex_ostream.h:132
goby::util::FlexOStreamBuf::name
void name(const std::string &s)
name of the application being served
Definition: flex_ostreambuf.h:100
goby::util::logger_lock::none
@ none
Definition: flex_ostreambuf.h:61
goby::util::logger_lock::LockAction
LockAction
Mutex actions available to the Goby logger (glogger)
Definition: flex_ostreambuf.h:59
flex_ostreambuf.h
goby::util::FlexOstream::FlexOstream
FlexOstream()
Definition: flex_ostream.h:46
goby::util::glogger
util::FlexOstream & glogger()
Definition: flex_ostream.h:214
goby::util::logger::VERBOSE
@ VERBOSE
Definition: flex_ostreambuf.h:75
goby::util::FlexOstream::is_debug2
bool is_debug2()
Definition: flex_ostream.h:85
goby::util::FlexOstream::add_stream
void add_stream(logger::Verbosity verbosity=logger::VERBOSE, std::ostream *os=nullptr)
Attach a stream object (e.g. std::cout, std::ofstream, ...) to the logger with desired verbosity.
Definition: flex_ostream.h:89
goby::util::FlexOstream::add_group
void add_group(const std::string &name, Colors::Color color=Colors::nocolor, const std::string &description="")
Add another group to the logger. A group provides related manipulator for categorizing log messages.
goby::util::Colors::nocolor
@ nocolor
Definition: term_color.h:113
goby::util::FlexOStreamBuf
Definition: flex_ostreambuf.h:87
goby::util::FlexOstream::is_debug1
bool is_debug1()
Definition: flex_ostream.h:84
goby::util::FlexOstream::remove_stream
void remove_stream(std::ostream *os=nullptr)
Definition: flex_ostream.h:103
goby::util::protobuf::GLogConfig_Verbosity
GLogConfig_Verbosity
Definition: debug_logger.pb.h:83
goby::util::FlexOStreamBuf::refresh
void refresh()
refresh the display (does nothing if !is_gui())
goby::util::FlexOstream::operator<<
std::ostream & operator<<(const long long &val)
Definition: flex_ostream.h:128
goby::util::FlexOstream::is_verbose
bool is_verbose()
Definition: flex_ostream.h:83
goby::util::FlexOstream::operator<<
std::ostream & operator<<(const long &val)
Definition: flex_ostream.h:127
goby::util::logger::DIE
@ DIE
Definition: flex_ostreambuf.h:80
goby::util::FlexOstream::mutex
std::recursive_mutex & mutex()
Get a reference to the Goby logger mutex for scoped locking.
Definition: flex_ostream.h:145
goby::util::FlexOstream::operator<<
std::ostream & operator<<(const short &val)
Definition: flex_ostream.h:123
goby::util::FlexOStreamBuf::enable_gui
void enable_gui()
goby::util::logger::DEBUG3
@ DEBUG3
Definition: flex_ostreambuf.h:79
goby::util::logger::Verbosity
Verbosity
Definition: flex_ostreambuf.h:70
goby::util::FlexOStreamErrorCollector
Definition: flex_ostream.h:216
goby::util::FlexOstream::buf
const FlexOStreamBuf & buf()
Definition: flex_ostream.h:109
goby::util::FlexOStreamBuf::add_stream
void add_stream(logger::Verbosity verbosity, std::ostream *os)
add a stream to the logger
goby::util::FlexOStreamErrorCollector::AddWarning
void AddWarning(int line, int column, const std::string &message) override
Definition: flex_ostream.h:233
goby::util::FlexOstream::is_die
bool is_die()
Definition: flex_ostream.h:81
goby::util::FlexOStreamBuf::group_name
void group_name(const std::string &s)
current group name (last insertion of group("") into the stream)
Definition: flex_ostreambuf.h:119
goby::util::FlexOstream::operator<<
std::ostream & operator<<(bool &val)
Definition: flex_ostream.h:122
logger_manipulators.h
goby::util::tcolor::nocolor
std::ostream & nocolor(std::ostream &os)
All text following this manipulator is uncolored (e.g. std::cout << green << "green" << nocolor << "u...
Definition: term_color.h:104
ErrorCollector
goby::util::FlexOstream::refresh
void refresh()
Definition: flex_ostream.h:150
goby::util::FlexOstream::operator<<
std::ostream & operator<<(const int &val)
Definition: flex_ostream.h:125
goby::util::FlexOstream::operator<<
std::ostream & operator<<(std::streambuf *sb)
Definition: flex_ostream.h:133
goby::util::FlexOstream::add_stream
void add_stream(goby::util::protobuf::GLogConfig::Verbosity verbosity=goby::util::protobuf::GLogConfig::VERBOSE, std::ostream *os=nullptr)
Definition: flex_ostream.h:95
goby::util::FlexOStreamBuf::set_lock_action
void set_lock_action(logger_lock::LockAction lock_action)
Definition: flex_ostreambuf.h:134
goby::util::FlexOStreamErrorCollector::FlexOStreamErrorCollector
FlexOStreamErrorCollector(const std::string &original)
Definition: flex_ostream.h:219
goby::util::logger::DEBUG1
@ DEBUG1
Definition: flex_ostreambuf.h:77
goby::util::FlexOstream::operator<<
std::ostream & operator<<(std::ios_base &(*pf)(std::ios_base &))
Definition: flex_ostream.h:135
goby::util::FlexOstream::operator<<
std::ostream & operator<<(std::ios &(*pf)(std::ios &))
Definition: flex_ostream.h:134
goby::glog
util::FlexOstream glog
Access the Goby logger through this object.
goby::util::operator<<
std::ostream & operator<<(FlexOstream &out, char c)
Definition: flex_ostream.h:180
goby::util::operator<<
std::ostream & operator<<(FlexOstream &out, const std::basic_string< _CharT, _Traits, _Alloc > &s)
Definition: flex_ostream.h:198
goby::util::FlexOstream::operator<<
std::ostream & operator<<(const unsigned int &val)
Definition: flex_ostream.h:126
goby::util::FlexOstream::operator<<
std::ostream & operator<<(const double &val)
Definition: flex_ostream.h:131
goby::util::FlexOstream::set_name
void set_name(const std::string &s)
Set the name of the application that the logger is serving.
Definition: flex_ostream.h:67
goby::util::FlexOStreamErrorCollector::AddError
void AddError(int line, int column, const std::string &message) override
Definition: flex_ostream.h:224
goby::util::FlexOstream::set_lock_action
void set_lock_action(logger_lock::LockAction lock_action)
Definition: flex_ostream.h:147
goby::util::FlexOStreamBuf::remove_stream
void remove_stream(std::ostream *os)
remove a stream from the logger
goby::util::FlexOStreamErrorCollector::has_warnings
bool has_warnings()
Definition: flex_ostream.h:268
goby::util::tcolor::lt_red
std::ostream & lt_red(std::ostream &os)
All text following this manipulator is light red (e.g. std::cout << lt_red << "text";)
Definition: term_color.h:65