mirror of
https://github.com/ashaduri/gsmartcontrol.git
synced 2026-09-29 15:15:42 +00:00
160 lines
3.1 KiB
C++
160 lines
3.1 KiB
C++
/******************************************************************************
|
|
License: Zlib
|
|
Copyright:
|
|
(C) 2008 - 2021 Alexander Shaduri <ashaduri@gmail.com>
|
|
******************************************************************************/
|
|
/// \file
|
|
/// \author Alexander Shaduri
|
|
/// \ingroup libdebug
|
|
/// \weakgroup libdebug
|
|
/// @{
|
|
|
|
#include <string>
|
|
#include <iosfwd> // std::ostream definition
|
|
#include <sstream>
|
|
#include <cstdarg> // std::va_start, va_list macro and friends
|
|
|
|
#include "hz/string_sprintf.h" // string_vsprintf()
|
|
|
|
#include "dout.h"
|
|
#include "dflags.h"
|
|
#include "dstate.h"
|
|
#include "dexcept.h"
|
|
|
|
|
|
|
|
|
|
// This may throw for invalid domain or level.
|
|
std::ostream& debug_out(debug_level::flag level, const std::string& domain)
|
|
{
|
|
auto& dm = debug_internal::get_debug_state_ref().get_domain_map_ref();
|
|
|
|
auto level_map = dm.find(domain);
|
|
if (level_map == dm.end()) { // no such domain
|
|
// this is an internal error
|
|
std::string msg = "debug_out(): Debug state doesn't contain the requested domain: \"" + domain + "\".";
|
|
throw debug_internal_error(msg.c_str());
|
|
}
|
|
|
|
auto os = level_map->second.find(level);
|
|
if (level_map == dm.end()) {
|
|
std::string msg = std::string("debug_out(): Debug state doesn't contain the requested level ") +
|
|
debug_level::get_name(level) + " in domain: \"" + domain + "\".";
|
|
|
|
// this is an internal error
|
|
throw debug_internal_error(msg.c_str());
|
|
}
|
|
|
|
return *(os->second);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void debug_print(debug_level::flag level, const std::string& domain, const char* format, ...)
|
|
{
|
|
std::va_list ap;
|
|
va_start(ap, format);
|
|
|
|
std::string s = hz::string_vsprintf(format, ap);
|
|
|
|
va_end(ap);
|
|
debug_out(level, domain) << s;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Start / stop prefix printing. Useful for large dumps
|
|
|
|
void debug_begin()
|
|
{
|
|
debug_internal::get_debug_state_ref().push_inside_begin();
|
|
}
|
|
|
|
|
|
void debug_end()
|
|
{
|
|
debug_internal::get_debug_state_ref().pop_inside_begin();
|
|
// this is needed because else the contents won't be written until next write.
|
|
debug_internal::get_debug_state_ref().force_output();
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
namespace debug_internal {
|
|
|
|
|
|
std::string DebugSourcePos::str() const
|
|
{
|
|
std::ostringstream os;
|
|
os << "(";
|
|
|
|
if (enabled_types.test(debug_pos::func_name)) {
|
|
os << "function: " << func_name;
|
|
|
|
} else if (enabled_types.test(debug_pos::func)) {
|
|
os << "function: " << func << "()";
|
|
}
|
|
|
|
if (enabled_types.test(debug_pos::file)) {
|
|
if (os.str() != "(")
|
|
os << ", ";
|
|
os << "file: " << file;
|
|
}
|
|
|
|
if (enabled_types.test(debug_pos::line)) {
|
|
if (os.str() != "(")
|
|
os << ", ";
|
|
os << "line: " << line;
|
|
}
|
|
|
|
os << ")";
|
|
|
|
return os.str();
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// ------------------ Indentation and manipulators
|
|
|
|
|
|
// increase indentation level for all debug levels
|
|
void debug_indent_inc(int by)
|
|
{
|
|
int curr = debug_internal::get_debug_state_ref().get_indent_level();
|
|
debug_internal::get_debug_state_ref().set_indent_level(curr + by);
|
|
}
|
|
|
|
|
|
void debug_indent_dec(int by)
|
|
{
|
|
int curr = debug_internal::get_debug_state_ref().get_indent_level();
|
|
curr -= by;
|
|
if (curr < 0)
|
|
curr = 0;
|
|
debug_internal::get_debug_state_ref().set_indent_level(curr);
|
|
}
|
|
|
|
|
|
void debug_indent_reset()
|
|
{
|
|
debug_internal::get_debug_state_ref().set_indent_level(0);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// @}
|