File: Console.hh

package info (click to toggle)
sdformat 9.3.0%2Bds-3
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 5,708 kB
  • sloc: cpp: 42,166; python: 1,618; javascript: 704; ruby: 368; sh: 81; ansic: 37; makefile: 16
file content (179 lines) | stat: -rw-r--r-- 5,382 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
/*
 * Copyright 2011 Nate Koenig
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#ifndef SDF_CONSOLE_HH_
#define SDF_CONSOLE_HH_

#include <fstream>
#include <iostream>
#include <memory>
#include <string>

#include <sdf/sdf_config.h>
#include "sdf/system_util.hh"

#ifdef _WIN32
// Disable warning C4251 which is triggered by
// std::unique_ptr
#pragma warning(push)
#pragma warning(disable: 4251)
#endif

namespace sdf
{
  // Inline bracket to help doxygen filtering.
  inline namespace SDF_VERSION_NAMESPACE {
  //

  /// \addtogroup sdf SDF
  /// \{

  /// \brief Output a debug message
  #define sdfdbg (sdf::Console::Instance()->Log("Dbg", __FILE__, __LINE__))

  /// \brief Output a message
  #define sdfmsg (sdf::Console::Instance()->ColorMsg("Msg", \
                                                     __FILE__, __LINE__, 32))

  /// \brief Output a warning message
  #define sdfwarn (sdf::Console::Instance()->ColorMsg("Warning", \
                                                      __FILE__, __LINE__, 33))

  /// \brief Output an error message
  #define sdferr (sdf::Console::Instance()->ColorMsg("Error", \
                                                     __FILE__, __LINE__, 31))

  class ConsolePrivate;
  class Console;

  /// \def ConsolePtr
  /// \brief Shared pointer to a Console Element
  typedef std::shared_ptr<Console> ConsolePtr;

  /// \brief Message, error, warning, and logging functionality
  class SDFORMAT_VISIBLE Console
  {
    /// \brief An ostream-like class that we'll use for logging.
    public: class SDFORMAT_VISIBLE ConsoleStream
    {
      /// \brief Constructor.
      /// \param[in] _stream Pointer to an output stream operator. Can be
      /// NULL/nullptr.
      public: ConsoleStream(std::ostream *_stream) :
              stream(_stream) {}

      /// \brief Redirect whatever is passed in to both our ostream
      ///        (if non-NULL) and the log file (if open).
      /// \param[in] _rhs Content to be logged.
      /// \return Reference to myself.
      public: template <class T>
        ConsoleStream &operator<<(const T &_rhs);

      /// \brief Print a prefix to both terminal and log file.
      /// \param[in] _lbl Text label
      /// \param[in] _file File containing the error
      /// \param[in] _line Line containing the error
      /// \param[in] _color Color to make the label.  Used only on terminal.
      public: void Prefix(const std::string &_lbl,
                          const std::string &_file,
                          unsigned int _line, int _color);

      /// \brief The ostream to log to; can be NULL/nullptr.
      private: std::ostream *stream;
    };

    /// \brief Default constructor
    private: Console();

    /// \brief Destructor
    public: virtual ~Console();

    /// \brief Return an instance to this class.
    public: static ConsolePtr Instance();

    /// \brief Clear out the current console to make room for a new one.
    public: static void Clear();

    /// \brief Set quiet output
    /// \param[in] q True to prevent warning
    public: void SetQuiet(bool _q);

    /// \brief Use this to output a colored message to the terminal
    /// \param[in] _lbl Text label
    /// \param[in] _file File containing the error
    /// \param[in] _line Line containing the error
    /// \param[in] _color Color to make the label
    /// \return Reference to an output stream
    public: ConsoleStream &ColorMsg(const std::string &lbl,
                                    const std::string &file,
                                    unsigned int line, int color);

    /// \brief Use this to output a message to a log file
    /// \return Reference to output stream
    public: ConsoleStream &Log(const std::string &lbl,
                               const std::string &file,
                               unsigned int line);

    /// \internal
    /// \brief Pointer to private data.
    private: std::unique_ptr<ConsolePrivate> dataPtr;
  };

  /// \internal
  /// \brief Private data for Console
  class ConsolePrivate
  {
    /// \brief Constructor
    public: ConsolePrivate() : msgStream(&std::cerr), logStream(nullptr) {}

    /// \brief message stream
    public: Console::ConsoleStream msgStream;

    /// \brief log stream
    public: Console::ConsoleStream logStream;

    /// \brief logfile stream
    public: std::ofstream logFileStream;
  };

  ///////////////////////////////////////////////
  template <class T>
  Console::ConsoleStream &Console::ConsoleStream::operator<<(const T &_rhs)
  {
    if (this->stream)
    {
      *this->stream << _rhs;
    }

    if (Console::Instance()->dataPtr->logFileStream.is_open())
    {
      Console::Instance()->dataPtr->logFileStream << _rhs;
      Console::Instance()->dataPtr->logFileStream.flush();
    }

    return *this;
  }
  }

  /// \}
}

#ifdef _WIN32
#pragma warning(pop)
#endif

#endif