From cca66b9ec4e494c1d919bff0f71a820d8afab1fa Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 20:24:48 +0200 Subject: Adding upstream version 1.2.2. Signed-off-by: Daniel Baumann --- src/debug/logger.cpp | 231 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 231 insertions(+) create mode 100644 src/debug/logger.cpp (limited to 'src/debug/logger.cpp') diff --git a/src/debug/logger.cpp b/src/debug/logger.cpp new file mode 100644 index 0000000..37b8221 --- /dev/null +++ b/src/debug/logger.cpp @@ -0,0 +1,231 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Inkscape::Debug::Logger - debug logging facility + * + * Authors: + * MenTaLguY + * + * Copyright (C) 2005 MenTaLguY + * + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + +#include +#include +#include +#include +#include +#include +#include "inkscape-version.h" +#include "debug/logger.h" +#include "debug/simple-event.h" + +namespace Inkscape { + +namespace Debug { + +bool Logger::_enabled=false; +bool Logger::_category_mask[Event::N_CATEGORIES]; + +namespace { + +static void write_escaped_value(std::ostream &os, char const *value) { + for ( char const *current=value ; *current ; ++current ) { + switch (*current) { + case '&': + os << "&"; + break; + case '"': + os << """; + break; + case '\'': + os << "'"; + break; + case '<': + os << "<"; + break; + case '>': + os << ">"; + break; + default: + os.put(*current); + } + } +} + +static void write_indent(std::ostream &os, unsigned depth) { + for ( unsigned i = 0 ; i < depth ; i++ ) { + os.write(" ", 2); + } +} + +static std::ofstream log_stream; +static bool empty_tag=false; +typedef std::vector> TagStack; +static TagStack &tag_stack() { + static TagStack stack; + return stack; +} + +static void do_shutdown() { + Debug::Logger::shutdown(); +} + +static bool equal_range(char const *c_string, + char const *start, char const *end) +{ + return !std::strncmp(start, c_string, end - start) && + !c_string[end - start]; +} + +static void set_category_mask(bool * const mask, char const *filter) { + if (!filter) { + for ( unsigned i = 0 ; i < Event::N_CATEGORIES ; i++ ) { + mask[i] = true; + } + return; + } else { + for ( unsigned i = 0 ; i < Event::N_CATEGORIES ; i++ ) { + mask[i] = false; + } + mask[Event::CORE] = true; + } + + char const *start; + char const *end; + start = end = filter; + while (*end) { + while ( *end && *end != ',' ) { end++; } + if ( start != end ) { + struct CategoryName { + char const *name; + Event::Category category; + }; + static const CategoryName category_names[] = { + { "CORE", Event::CORE }, + { "XML", Event::XML }, + { "SPOBJECT", Event::SPOBJECT }, + { "DOCUMENT", Event::DOCUMENT }, + { "REFCOUNT", Event::REFCOUNT }, + { "EXTENSION", Event::EXTENSION }, + { "FINALIZERS", Event::FINALIZERS }, + { "INTERACTION", Event::INTERACTION }, + { "CONFIGURATION", Event::CONFIGURATION }, + { "OTHER", Event::OTHER }, + { nullptr, Event::OTHER } + }; + CategoryName const *iter; + for ( iter = category_names ; iter->name ; iter++ ) { + if (equal_range(iter->name, start, end)) { + mask[iter->category] = true; + break; + } + } + if (!iter->name) { + g_warning("Unknown debugging category %*s", (int)(end - start), start); + } + } + if (*end) { + start = end = end + 1; + } + } +} + +typedef SimpleEvent CoreEvent; + +class SessionEvent : public CoreEvent { +public: + SessionEvent() : CoreEvent("session") { + _addProperty("inkscape-version", Inkscape::version_string); + } +}; + +} + +void Logger::init() { + if (!_enabled) { + char const *log_filename=std::getenv("INKSCAPE_DEBUG_LOG"); + if (log_filename) { + log_stream.open(log_filename); + if (log_stream.is_open()) { + char const *log_filter=std::getenv("INKSCAPE_DEBUG_FILTER"); + set_category_mask(_category_mask, log_filter); + log_stream << "\n"; + log_stream.flush(); + _enabled = true; + start(); + std::atexit(&do_shutdown); + } + } + } +} + +void Logger::_start(Event const &event) { + char const *name=event.name(); + + if (empty_tag) { + log_stream << ">\n"; + } + + write_indent(log_stream, tag_stack().size()); + + log_stream << "<" << name; + + unsigned property_count=event.propertyCount(); + for ( unsigned i = 0 ; i < property_count ; i++ ) { + Event::PropertyPair property=event.property(i); + log_stream << " " << property.name << "=\""; + write_escaped_value(log_stream, property.value->c_str()); + log_stream << "\""; + } + + log_stream.flush(); + + tag_stack().push_back(std::make_shared(name)); + empty_tag = true; + + event.generateChildEvents(); +} + +void Logger::_skip() { + tag_stack().push_back(nullptr); +} + +void Logger::_finish() { + if (tag_stack().back()) { + if (empty_tag) { + log_stream << "/>\n"; + } else { + write_indent(log_stream, tag_stack().size() - 1); + log_stream << "c_str() << ">\n"; + } + log_stream.flush(); + + empty_tag = false; + } + + tag_stack().pop_back(); +} + +void Logger::shutdown() { + if (_enabled) { + while (!tag_stack().empty()) { + finish(); + } + } +} + +} + +} + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : -- cgit v1.2.3