libcwdversion 2.0.0
The C++ Debugging Support Library
Loading...
Searching...
No Matches
DebugObject.inl.h
1// SPDX-FileCopyrightText: 2001-2004, 2007, 2018-2021, 2026 Carlo Wood
2// SPDX-License-Identifier: MIT
3
4#pragma once
5
6#ifndef LIBCWD_CLASS_DEBUG_INL
7#define LIBCWD_CLASS_DEBUG_INL
8
9#include "Channel.inl.h"
10#include "DebugString.inl.h"
11#include "FatalChannel.inl.h"
12#include "Channel.h"
13#include "DebugObject.h"
14#include "FatalChannel.h"
15#include "core_dump.h"
16
17#include <ostream>
18
19namespace libcwd {
20
23
25{
26 LIBCWD_TSD_DECLARATION;
27 return LIBCWD_TSD_MEMBER(color_on);
28}
29
30inline DebugString const& DebugObject::color_on() const
31{
32 LIBCWD_TSD_DECLARATION;
33 return LIBCWD_TSD_MEMBER(color_on);
34}
35
37{
38 LIBCWD_TSD_DECLARATION;
39 return LIBCWD_TSD_MEMBER(color_off);
40}
41
42inline DebugString const& DebugObject::color_off() const
43{
44 LIBCWD_TSD_DECLARATION;
45 return LIBCWD_TSD_MEMBER(color_off);
46}
47
49{
50 LIBCWD_TSD_DECLARATION;
51 return LIBCWD_TSD_MEMBER(margin);
52}
53
54inline DebugString const& DebugObject::margin() const
55{
56 LIBCWD_TSD_DECLARATION;
57 return LIBCWD_TSD_MEMBER(margin);
58}
59
61{
62 LIBCWD_TSD_DECLARATION;
63 return LIBCWD_TSD_MEMBER(marker);
64}
65
66inline DebugString const& DebugObject::marker() const
67{
68 LIBCWD_TSD_DECLARATION;
69 return LIBCWD_TSD_MEMBER(marker);
70}
71
75inline void DebugObject::set_indent(unsigned short i)
76{
77 LIBCWD_TSD_DECLARATION;
78 LIBCWD_TSD_MEMBER(indent) = i;
79}
80
84inline void DebugObject::inc_indent(unsigned short i)
85{
86 LIBCWD_TSD_DECLARATION;
87 LIBCWD_TSD_MEMBER(indent) += i;
88}
89
93inline void DebugObject::dec_indent(unsigned short i)
94{
95 LIBCWD_TSD_DECLARATION;
96 int prev_indent = LIBCWD_TSD_MEMBER(indent);
97 LIBCWD_TSD_MEMBER(indent) = (i > prev_indent) ? 0 : (prev_indent - i);
98}
99
103inline unsigned short DebugObject::get_indent() const
104{
105 LIBCWD_TSD_DECLARATION;
106 return LIBCWD_TSD_MEMBER(indent);
107}
108
110
113
117inline std::ostream* DebugObject::get_ostream() const
118{
119 std::ostream* real_os_ptr;
120 real_os_ptr = ostream_state_.read_real_os();
121 return real_os_ptr;
122}
123
124inline bool DebugObject::has_mutex() const
125{
126 bool has_mutex;
127 has_mutex = ostream_state_.has_mutex();
128 return has_mutex;
129}
130
131#ifndef HIDE_FROM_DOXYGEN
132namespace _private_ {
133inline LockInterfaceBase* OstreamState::replace_with(std::ostream* os,
134 LockInterfaceBase* new_mutex)
135{
136 std::lock_guard<std::mutex> lock(state_mutex_);
137 LockInterfaceBase* old_mutex = mutex_;
138 mutex_ = new_mutex;
139 real_os_ = os;
140 if (old_mutex)
141 {
142 // LOCK ORDER: state_mutex_ -> LockInterfaceBase
143 old_mutex->lock(); // Make sure all other threads left this critical area.
144 old_mutex->unlock();
145 }
146 return old_mutex;
147}
148
149inline void OstreamState::set_ostream(std::ostream* os)
150{
151 std::lock_guard<std::mutex> lock(state_mutex_);
152 LockInterfaceBase* old_mutex = mutex_;
153 real_os_ = os;
154 if (old_mutex)
155 {
156 // LOCK ORDER: state_mutex_ -> LockInterfaceBase
157 old_mutex->lock(); // Make sure all other threads left this critical area.
158 old_mutex->unlock();
159 }
160}
161
162inline std::ostream* OstreamState::read_real_os() const
163{
164 std::lock_guard<std::mutex> lock(state_mutex_);
165 return real_os_;
166}
167
168inline bool OstreamState::has_mutex() const
169{
170 std::lock_guard<std::mutex> lock(state_mutex_);
171 return mutex_ != nullptr;
172}
173
174inline std::ostream* OstreamState::get_locked_os(std::ostream* os,
175 LockInterfaceBase** locked_mutex_out) const
176{
177 std::lock_guard<std::mutex> lock(state_mutex_);
178 std::ostream* locked_os = os ? os : real_os_;
179 *locked_mutex_out = mutex_;
180 if (mutex_)
181 {
182 // LOCK ORDER: state_mutex_ -> LockInterfaceBase
183 mutex_->lock();
184 }
185 return locked_os;
186}
187
188inline bool OstreamState::try_lock_os(std::ostream* os, std::ostream** locked_os_out,
189 LockInterfaceBase** locked_mutex_out) const
190{
191 std::lock_guard<std::mutex> lock(state_mutex_);
192 // LOCK ORDER: state_mutex_ -> LockInterfaceBase
193 if (mutex_ && mutex_->try_lock())
194 return false;
195 *locked_os_out = os ? os : real_os_;
196 *locked_mutex_out = mutex_;
197 return true;
198}
199
200inline void OstreamState::write_color_off_newline(std::ostream* os, char const* color_off,
201 std::size_t color_off_size) const
202{
203 std::lock_guard<std::mutex> lock(state_mutex_);
204 std::ostream* target_os = os ? os : real_os_;
205 if (color_off_size > 0)
206 target_os->write(color_off, color_off_size);
207 target_os->put('\n');
208}
209
210} // namespace _private_
211#endif // HIDE_FROM_DOXYGEN
212
214
224{
225 LIBCWD_TSD_DECLARATION;
226#if CWDEBUG_DEBUG
227 if (!NS_init(LIBCWD_TSD))
228 core_dump();
229#else
230 [[maybe_unused]] bool success = NS_init(LIBCWD_TSD);
231#endif
232}
233
237inline void DebugObject::off()
238{
239 LIBCWD_TSD_DECLARATION;
240 ++LIBCWD_TSD_MEMBER_OFF;
241}
242
266inline void DebugObject::on()
267{
268 LIBCWD_TSD_DECLARATION;
269#if CWDEBUG_DEBUGOUTPUT
270 if (LIBCWD_TSD_MEMBER(first_time) && LIBCWD_TSD_MEMBER_OFF == -1)
271 LIBCWD_TSD_MEMBER(first_time) = false;
272 else
273 --LIBCWD_TSD_MEMBER_OFF;
274#else
275 --LIBCWD_TSD_MEMBER_OFF;
276#endif
277}
278
279inline bool DebugObject::is_on(LIBCWD_TSD_PARAM) const
280{
281 return __libcwd_tsd.debug_object_off_array[index_] == -1;
282}
283
288{
289 ++always_flush_;
290}
291
307{
308#if CWDEBUG_DEBUG
309 if (always_flush_ <= 0)
310 core_dump();
311#endif
312 --always_flush_;
313}
314
315inline bool DebugObject::always_flush_is_on() const
316{
317 return always_flush_ > 0; // 0 means off.
318}
319
320inline ChannelSet& ChannelSetBootstrap::operator|(Channel const& dc)
321{
322 mask = 0;
323 label = dc.get_label();
324 on = dc.is_on();
325 return *reinterpret_cast<ChannelSet*>(this);
326}
327
328inline ChannelSet& FatalChannelSetBootstrap::operator|(FatalChannel const& fdc)
329{
330 mask = fdc.get_maskbit();
331 label = fdc.get_label();
332 on = true;
333 return *reinterpret_cast<ChannelSet*>(this);
334}
335
336} // namespace libcwd
337
338#endif // LIBCWD_CLASS_DEBUG_INL
This object represents a debug channel, it has a fixed label. A debug channel can be viewed upon as a...
Definition Channel.h:74
char const * get_label() const
Pointer to the label of the debug channel.
Definition Channel.inl.h:44
bool is_on() const
Returns true if the channel is active.
Definition Channel.inl.h:35
void always_flush_on()
Turn always-flush for this debug object on.
Definition DebugObject.inl.h:287
void on()
Cancel last call to off().
Definition DebugObject.inl.h:266
DebugObject()
Constructor.
Definition DebugObject.inl.h:223
void off()
Turn this debug object off.
Definition DebugObject.inl.h:237
void always_flush_off()
Cancel last call to always_flush_on().
Definition DebugObject.inl.h:306
A string class used for the debug output margin and marker.
Definition DebugString.h:34
void inc_indent(unsigned short indentation)
Increment number of spaces to indent.
Definition DebugObject.inl.h:84
DebugString & marker()
The marker.
Definition DebugObject.inl.h:60
DebugString & color_off()
Turn colorization off.
Definition DebugObject.inl.h:36
DebugString & margin()
The margin.
Definition DebugObject.inl.h:48
unsigned short get_indent() const
Get the current indentation.
Definition DebugObject.inl.h:103
void set_indent(unsigned short indentation)
Set number of spaces to indent.
Definition DebugObject.inl.h:75
DebugString & color_on()
Colorization code.
Definition DebugObject.inl.h:24
void dec_indent(unsigned short indentation)
Decrement number of spaces to indent.
Definition DebugObject.inl.h:93
void core_dump()
Dump core of current thread.
Definition debug.cxx:697
std::ostream * get_ostream() const
Get the ostream device as set with set_ostream().
Definition DebugObject.inl.h:117
namespace for libcwd.