Patrick Kelley 8fd444092b initial
2025-05-07 15:35:15 -04:00

126 lines
4.6 KiB
C++

// Copyright (c) 2020-now by the Zeek Project. See LICENSE for details.
#pragma once
#include <string_view>
#include <utility>
#include <hilti/rt/debug-logger.h>
#include <hilti/rt/global-state.h>
#include <hilti/rt/types/string.h>
#include <hilti/rt/util.h>
namespace hilti::rt {
struct TypeInfo;
/**
* Reports a fatal error and immediately aborts execution. This skips all
* cleanup and should be used only for catastrophic library issues; not for
* anything that can happen during "normal" operation (which is almost
* everything).
*/
void fatalError(std::string_view msg) __attribute__((noreturn));
/** Reports a warning. */
void warning(std::string_view msg);
/**
* Prints a string, or a runtime value, to a specific debug stream. This is a
* macro wrapper around `debug::detail::print(*)` that avoids evaluation of
* the arguments if nothing is going to get logged.
*/
#define HILTI_RT_DEBUG(stream, msg) \
{ \
if ( ::hilti::rt::detail::unsafeGlobalState()->debug_logger && \
::hilti::rt::detail::unsafeGlobalState()->debug_logger->isEnabled(stream) ) \
::hilti::rt::debug::detail::print(stream, msg); \
}
/** Shortcut to `hilti::rt::debug::setLocation`. */
#define __location__(x) ::hilti::rt::debug::setLocation(x);
namespace debug {
namespace detail {
/** Prints a debug message to a specific debug stream. */
inline void print(std::string_view stream, const char* msg) {
if ( ::hilti::rt::detail::globalState()->debug_logger )
::hilti::rt::detail::globalState()->debug_logger->print(stream, msg);
}
/** Print a string to a specific debug stream with proper escaping. */
inline void print(std::string_view stream, std::string_view s) {
if ( ::hilti::rt::detail::globalState()->debug_logger )
::hilti::rt::detail::globalState()->debug_logger->print(stream, hilti::rt::escapeBytes(s));
}
template<typename T, typename std::enable_if_t<not std::is_convertible_v<T, std::string_view>>* = nullptr>
/** Prints the string representastion of a HILTI runtime value to a specific debug stream. */
inline void print(std::string_view stream, const T& t) {
if ( ::hilti::rt::detail::globalState()->debug_logger )
::hilti::rt::detail::globalState()->debug_logger->print(stream, hilti::rt::to_string_for_print(t));
}
} // namespace detail
/** Returns true if debug logging is enabled for a given stream. */
inline bool isEnabled(std::string_view stream) {
return ::hilti::rt::detail::globalState()->debug_logger &&
::hilti::rt::detail::globalState()->debug_logger->isEnabled(stream);
}
/** Increases the indentation level for a debug stream. */
inline void indent(std::string_view stream) {
if ( ::hilti::rt::detail::globalState()->debug_logger )
::hilti::rt::detail::globalState()->debug_logger->indent(stream);
}
/** Decreases the indentation level for a debug stream. */
inline void dedent(const std::string_view stream) {
if ( ::hilti::rt::detail::globalState()->debug_logger )
::hilti::rt::detail::globalState()->debug_logger->dedent(stream);
}
/**
* Returns the current source code location if set, or null if not.
*/
inline const char* location() {
if ( auto* ctx = ::hilti::rt::context::detail::current() ) {
if ( auto* r = ctx->resumable )
return r->location();
else
return ctx->location;
}
else
return nullptr;
}
/**
* Sets the current source code location, or unsets it if argument is null.
*
* @param l pointer to a statically allocated string that won't go out of scope.
*/
inline void setLocation(const char* l = nullptr) {
if ( auto* ctx = ::hilti::rt::context::detail::current() ) {
if ( auto* r = ctx->resumable )
r->setLocation(l);
else
ctx->location = l;
}
}
/**
* Prints a string, or a runtime value, to a specific debug stream. This is a
* wrapper around `debug::detail::print(*)` that avoids evaluation of the
* arguments if nothing is going to get logged.
*/
template<typename T>
inline void print(std::string_view stream, T&& msg, const TypeInfo* /* type */) {
if ( ::hilti::rt::detail::globalState()->debug_logger &&
::hilti::rt::detail::globalState()->debug_logger->isEnabled(stream) )
::hilti::rt::debug::detail::print(stream, std::forward<T>(msg));
}
} // namespace debug
} // namespace hilti::rt