File: UTILS_DebugStream.hpp

package info (click to toggle)
otf2 3.1.1-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 28,980 kB
  • sloc: ansic: 92,997; python: 16,977; cpp: 9,057; sh: 6,299; makefile: 235; awk: 54
file content (235 lines) | stat: -rw-r--r-- 6,013 bytes parent folder | download | duplicates (3)
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
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
/*
 * This file is part of the Score-P software ecosystem (http://www.score-p.org)
 *
 * Copyright (c) 2016, 2022,
 * Forschungszentrum Juelich GmbH, Germany
 *
 * This software may be modified and distributed under the terms of
 * a BSD-style license.  See the COPYING file in the package base
 * directory for details.
 *
 */

#ifndef UTILS_DEBUG_H
#error "Do not include this header directly, use UTILS_Debug.h instead."
#endif


#ifndef UTILS_DEBUGSTREAM_HPP
#define UTILS_DEBUGSTREAM_HPP

/**
 * @file
 * @ingroup UTILS_Exception_module
 * @brief   Module for debug output handling in UTILS using C++ streams
 *
 * This header file provides the definition of preprocessor macros and helper
 * classes to allow printing debug messages using C++ output streams.  It is
 * not intended to be included directly, but only via <tt>UTILS_Debug.h</tt>.
 */

#include <string>
#include <sstream>

/**
 * @def     UTILS_DLOG
 * @ingroup UTILS_Exception_module
 * @brief   Debug logging stream for the default debug level
 *
 * The UTILS_DLOG preprocessor macro provides a C++ output stream for
 * printing debug messages.  It uses the default debug level specified
 * by the ${PACKAGE}_DEBUG_MODULE_NAME preprocessor define.  (To specify
 * a debug level explicitly, use the UTILS_DLOG_LEVEL macro instead.)
 *
 * @par Example:
 * @code
 *     #include <config.h>
 *
 *     #define EXAMPLE_DEBUG_MODULE_NAME CORE
 *     #include <UTILS_Debug.h>
 *
 *     int main( int argc, char** argv )
 *     {
 *         UTILS_DLOG << "Entering main() with argc=" << argc;
 *         return 0;
 *     }
 * @endcode
 *
 * @see UTILS_DLOG_LEVEL
 */
/**
 * @def     UTILS_DLOG_LEVEL
 * @ingroup UTILS_Exception_module
 * @brief   Debug logging stream for a specific debug level
 *
 * The UTILS_DLOG_LEVEL preprocessor macro provides a C++ output stream for
 * printing debug messages of a specific debug level.
 *
 * @par Example:
 * @code
 *     #include <config.h>
 *
 *     #include <UTILS_Debug.h>
 *
 *     int main( int argc, char** argv )
 *     {
 *         UTILS_DLOG_LEVEL( EXAMPLE_DEBUG_CORE )
 *             << "Entering main() with argc=" << argc;
 *         return 0;
 *     }
 * @endcode
 *
 * @see UTILS_DLOG
 */

#if HAVE( UTILS_DEBUG )

/* *INDENT-OFF* */

#define UTILS_DLOG \
    if ( UTILS_Debug_IsEnabled( UTILS_JOIN_SYMS( AFS_PACKAGE_NAME, \
                                    UTILS_JOIN_SYMS( _DEBUG_, \
                                        PACKAGE_MANGLE_NAME( DEBUG_MODULE_NAME ) ) ) ) ) \
        AFS_PACKAGE_name::utils::DebugStream( \
            __FILE__, \
            __LINE__, \
            UTILS_FUNCTION_NAME )

#define UTILS_DLOG_LEVEL( debugLevel ) \
    if ( UTILS_Debug_IsEnabled( debugLevel ) ) \
        AFS_PACKAGE_name::utils::DebugStream( \
            __FILE__, \
            __LINE__, \
            UTILS_FUNCTION_NAME )

/* *INDENT-ON* */


namespace AFS_PACKAGE_name
{
namespace utils
{
/**
 * @class   DebugStream
 * @ingroup UTILS_Exception_module
 * @brief   Helper class to concatenate C++ stream debug output
 *
 * This helper class buffers the C++ stream debugging output in a temporary
 * output string stream and flushes it during destruction to the default
 * debug output using UTILS_Debug_Printf().
 */
class DebugStream
{
public:
    /**
     * @brief Constructor
     *
     * Creates a new instance and stores the given parameters in member
     * variables.
     *
     * @param file      Source file name
     * @param line      Source line number
     * @param function  Function name
     */
    DebugStream( const char* file,
                 uint64_t    line,
                 const char* function )
        : m_file( file ),
        m_line( line ),
        m_function( function )
    {
    }

    /**
     * @brief Destructor
     *
     * Destroys the instance and prints the concatenated debugging output.
     */
    ~DebugStream()
    {
        UTILS_Debug_Printf( 0,
                            AFS_PACKAGE_SRCDIR,
                            m_file.c_str(),
                            m_line,
                            m_function.c_str(),
                            "%s",
                            m_buffer.str().c_str() );
    }

    /**
     * @brief Output operator
     *
     * Appends the textual representation of the given @a item to the internal
     * buffer using the value's stream output operator.
     *
     * @param   item  Item to be printed
     * @return  Reference to the instance
     */
    template <typename T>
    DebugStream&
    operator<<( const T& item )
    {
        m_buffer << item;
        return *this;
    }


private:
    std::string        m_file;     /**< Source file name */
    uint64_t           m_line;     /**< Source line number */
    std::string        m_function; /**< Function name */
    std::ostringstream m_buffer;   /**< Message construction buffer */
};
}                                  /* namespace utils */
}                                  /* namespace AFS_PACKAGE_name */

#else /* !HAVE( UTILS_DEBUG ) */

/*
 * The release versions of UTILS_DLOG and UTILS_DLOG_LEVEL rely on dead code
 * elimination by the compiler, as there is no good way to #ifdef the stream
 * expression itself.  In practice this works quite well with all compilers
 * if a decent optimization level is used (GNU/Cray/IBM: O0; Intel/Fujitsu: O1;
 * PGI: O2).
 */

#define UTILS_DLOG \
    if ( 0 ) \
        AFS_PACKAGE_name::utils::DebugStream()

#define UTILS_DLOG_LEVEL( debugLevel ) \
    if ( 0 ) \
        AFS_PACKAGE_name::utils::DebugStream()


namespace AFS_PACKAGE_name
{
namespace utils
{
/*
 * "Do nothing" version of class DebugStream used in release mode.
 */
class DebugStream
{
public:
    DebugStream()
    {
    }

    ~DebugStream()
    {
    }

    template <typename T>
    DebugStream&
    operator<<( const T& item )
    {
        return *this;
    }
};
}    /* namespace utils */
}    /* namespace AFS_PACKAGE_name */

#endif /* !HAVE( UTILS_DEBUG ) */

#endif /* UTILS_DEBUGSTREAM_HPP */