libcwdversion 2.0.0
The C++ Debugging Support Library
Loading...
Searching...
No Matches
macro_Libcwd_macros.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2000-2005, 2007, 2017-2020, 2023-2026 Carlo Wood
2// SPDX-License-Identifier: MIT
3
4#pragma once
5
9
10#ifndef LIBCWD_MACRO_LIBCWD_MACROS_H
11#define LIBCWD_MACRO_LIBCWD_MACROS_H
12
13#include "libcwd/config.h"
14
15#include <cstddef> // Needed for size_t
16
17#define LIBCWD_ASSERT_NOT_INTERNAL
18
19//===================================================================================================
20// Macro LibcwDebug
21//
22
31#define LibcwDebug(dc_namespace, ...) \
32 do \
33 { \
34 using namespace ::libcwd; \
35 using namespace ::dc_namespace; \
36 { \
37 __VA_ARGS__; \
38 } \
39 } while (0)
40
41//===================================================================================================
42// Macro LibcwDout
43//
44
45// This is debugging libcwd itself.
46#ifndef LIBCWD_LibcwDoutScopeBegin_MARKER
47#if CWDEBUG_DEBUGOUTPUT
48#include <sys/types.h>
49extern "C" ssize_t write(int fd, void const* buf, size_t count);
50#define LIBCWD_STR1(x) #x
51#define LIBCWD_STR2(x) LIBCWD_STR1(x)
52#define LIBCWD_STR3 "LibcwDout at " __FILE__ ":" LIBCWD_STR2(__LINE__) "\n"
53#define LIBCWD_LibcwDoutScopeBegin_MARKER \
54 do \
55 { \
56 [[maybe_unused]] size_t __libcwd_len = ::write(2, LIBCWD_STR3, sizeof(LIBCWD_STR3) - 1); \
57 } while (0)
58#else // !CWDEBUG_DEBUGOUTPUT
59#define LIBCWD_LibcwDoutScopeBegin_MARKER
60#endif // !CWDEBUG_DEBUGOUTPUT
61#endif // !LIBCWD_LibcwDoutScopeBegin_MARKER
62
63// If this macro is defined, it is prepended immediately before any `os << ...stuff...` code that writes debug output.
64// This can be used to add operator<<'s that are exclusively for debugging (most notably those that print things
65// defined in namespace std).
66#ifndef LIBCWD_USING_OSTREAM_PRELUDE
67#define LIBCWD_USING_OSTREAM_PRELUDE
68#endif
69
78#define LibcwDout(dc_namespace, debug_obj, cntrl, ...) \
79 LibcwDoutScopeBegin(dc_namespace, debug_obj, cntrl) LibcwDoutStream << __VA_ARGS__; \
80 LibcwDoutScopeEnd
81
82#define LibcwDoutScopeBegin(dc_namespace, debug_obj, cntrl) \
83 do \
84 { \
85 LIBCWD_TSD_DECLARATION; \
86 LIBCWD_ASSERT_NOT_INTERNAL; \
87 LIBCWD_LibcwDoutScopeBegin_MARKER; \
88 if (LIBCWD_DO_TSD_MEMBER_OFF(debug_obj) < 0) \
89 { \
90 using namespace ::libcwd; \
91 ::libcwd::ChannelSetBootstrap __libcwd_channel_set(LIBCWD_DO_TSD(debug_obj), LIBCWD_TSD); \
92 bool on; \
93 { \
94 using namespace ::dc_namespace; \
95 on = (__libcwd_channel_set | cntrl).on; \
96 } \
97 if (on) \
98 { \
99 ::libcwd::DebugObject& __libcwd_debug_object(debug_obj); \
100 LIBCWD_DO_TSD(__libcwd_debug_object).start(__libcwd_debug_object, __libcwd_channel_set, LIBCWD_TSD); \
101 LIBCWD_USING_OSTREAM_PRELUDE
102
103// Note: LibcwDoutStream is *not* equal to the ostream that was set with set_ostream. It is a temporary stringstream.
104#define LibcwDoutStream (*LIBCWD_DO_TSD_MEMBER(__libcwd_debug_object, current_bufferstream))
105
106#define LibcwDoutScopeEnd \
107 LIBCWD_DO_TSD(__libcwd_debug_object).finish(__libcwd_debug_object, __libcwd_channel_set, LIBCWD_TSD); \
108 } \
109 } \
110 } \
111 while (0)
112
113//===================================================================================================
114// Macro LibcwDoutFatal
115//
116
117// This is debugging libcwd itself.
118#ifndef LIBCWD_LibcwDoutFatalScopeBegin_MARKER
119#if CWDEBUG_DEBUGOUTPUT
120#define LIBCWD_STR4 "LibcwDoutFatal at " __FILE__ ":" LIBCWD_STR2(__LINE__) "\n"
121#define LIBCWD_LibcwDoutFatalScopeBegin_MARKER \
122 do \
123 { \
124 [[maybe_unused]] size_t __libcwd_len = ::write(2, LIBCWD_STR4, sizeof(LIBCWD_STR4) - 1); \
125 } while (0)
126#else
127#define LIBCWD_LibcwDoutFatalScopeBegin_MARKER
128#endif
129#endif // !LIBCWD_LibcwDoutFatalScopeBegin_MARKER
130
139#define LibcwDoutFatal(dc_namespace, debug_obj, cntrl, ...) \
140 LibcwDoutFatalScopeBegin(dc_namespace, debug_obj, cntrl) LibcwDoutFatalStream << __VA_ARGS__; \
141 LibcwDoutFatalScopeEnd
142
143#define LibcwDoutFatalScopeBegin(dc_namespace, debug_obj, cntrl) \
144 do \
145 { \
146 LIBCWD_TSD_DECLARATION; \
147 LIBCWD_LibcwDoutFatalScopeBegin_MARKER; \
148 using namespace ::libcwd; \
149 ::libcwd::FatalChannelSetBootstrap __libcwd_channel_set(LIBCWD_DO_TSD(debug_obj), LIBCWD_TSD); \
150 { \
151 using namespace ::dc_namespace; \
152 __libcwd_channel_set | cntrl; \
153 } \
154 ::libcwd::DebugObject& __libcwd_debug_object(debug_obj); \
155 LIBCWD_DO_TSD(__libcwd_debug_object).start(__libcwd_debug_object, __libcwd_channel_set, LIBCWD_TSD); \
156 LIBCWD_USING_OSTREAM_PRELUDE
157
158#define LibcwDoutFatalStream LibcwDoutStream
159
160#define LibcwDoutFatalScopeEnd \
161 LIBCWD_DO_TSD(__libcwd_debug_object).fatal_finish(__libcwd_debug_object, __libcwd_channel_set, LIBCWD_TSD); \
162 } \
163 while (0)
164
165#endif // LIBCWD_MACRO_LIBCWD_MACROS_H