summaryrefslogtreecommitdiff
path: root/thirdparty/astcenc/astcenc_diagnostic_trace.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/astcenc/astcenc_diagnostic_trace.cpp')
-rw-r--r--thirdparty/astcenc/astcenc_diagnostic_trace.cpp230
1 files changed, 230 insertions, 0 deletions
diff --git a/thirdparty/astcenc/astcenc_diagnostic_trace.cpp b/thirdparty/astcenc/astcenc_diagnostic_trace.cpp
new file mode 100644
index 0000000000..7fa7ab1a8b
--- /dev/null
+++ b/thirdparty/astcenc/astcenc_diagnostic_trace.cpp
@@ -0,0 +1,230 @@
+// SPDX-License-Identifier: Apache-2.0
+// ----------------------------------------------------------------------------
+// Copyright 2021-2022 Arm Limited
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at:
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+// ----------------------------------------------------------------------------
+
+/**
+ * @brief Functions for the library entrypoint.
+ */
+
+#if defined(ASTCENC_DIAGNOSTICS)
+
+#include <cassert>
+#include <cstdarg>
+#include <cstdio>
+#include <string>
+
+#include "astcenc_diagnostic_trace.h"
+
+/** @brief The global trace logger. */
+static TraceLog* g_TraceLog = nullptr;
+
+/** @brief The JSON indentation level. */
+static const size_t g_trace_indent = 2;
+
+TraceLog::TraceLog(
+ const char* file_name):
+ m_file(file_name, std::ofstream::out | std::ofstream::binary)
+{
+ assert(!g_TraceLog);
+ g_TraceLog = this;
+ m_root = new TraceNode("root");
+}
+
+/* See header for documentation. */
+TraceNode* TraceLog::get_current_leaf()
+{
+ if (m_stack.size())
+ {
+ return m_stack.back();
+ }
+
+ return nullptr;
+}
+
+/* See header for documentation. */
+size_t TraceLog::get_depth()
+{
+ return m_stack.size();
+}
+
+/* See header for documentation. */
+TraceLog::~TraceLog()
+{
+ assert(g_TraceLog == this);
+ delete m_root;
+ g_TraceLog = nullptr;
+}
+
+/* See header for documentation. */
+TraceNode::TraceNode(
+ const char* format,
+ ...
+) {
+ // Format the name string
+ constexpr size_t bufsz = 256;
+ char buffer[bufsz];
+
+ va_list args;
+ va_start (args, format);
+ vsnprintf (buffer, bufsz, format, args);
+ va_end (args);
+
+ // Guarantee there is a nul terminator
+ buffer[bufsz - 1] = 0;
+
+ // Generate the node
+ TraceNode* parent = g_TraceLog->get_current_leaf();
+ size_t depth = g_TraceLog->get_depth();
+ g_TraceLog->m_stack.push_back(this);
+
+ bool comma = parent && parent->m_attrib_count;
+ auto& out = g_TraceLog->m_file;
+
+ if (parent)
+ {
+ parent->m_attrib_count++;
+ }
+
+ if (comma)
+ {
+ out << ',';
+ }
+
+ if (depth)
+ {
+ out << '\n';
+ }
+
+ size_t out_indent = (depth * 2) * g_trace_indent;
+ size_t in_indent = (depth * 2 + 1) * g_trace_indent;
+
+ std::string out_indents("");
+ if (out_indent)
+ {
+ out_indents = std::string(out_indent, ' ');
+ }
+
+ std::string in_indents(in_indent, ' ');
+
+ out << out_indents << "[ \"node\", \"" << buffer << "\",\n";
+ out << in_indents << "[";
+}
+
+/* See header for documentation. */
+void TraceNode::add_attrib(
+ std::string type,
+ std::string key,
+ std::string value
+) {
+ (void)type;
+
+ size_t depth = g_TraceLog->get_depth();
+ size_t indent = (depth * 2) * g_trace_indent;
+ auto& out = g_TraceLog->m_file;
+ bool comma = m_attrib_count;
+ m_attrib_count++;
+
+ if (comma)
+ {
+ out << ',';
+ }
+
+ out << '\n';
+ out << std::string(indent, ' ') << "[ "
+ << "\"" << key << "\", "
+ << value << " ]";
+}
+
+/* See header for documentation. */
+TraceNode::~TraceNode()
+{
+ g_TraceLog->m_stack.pop_back();
+
+ auto& out = g_TraceLog->m_file;
+ size_t depth = g_TraceLog->get_depth();
+ size_t out_indent = (depth * 2) * g_trace_indent;
+ size_t in_indent = (depth * 2 + 1) * g_trace_indent;
+
+ std::string out_indents("");
+ if (out_indent)
+ {
+ out_indents = std::string(out_indent, ' ');
+ }
+
+ std::string in_indents(in_indent, ' ');
+
+ if (m_attrib_count)
+ {
+ out << "\n" << in_indents;
+ }
+ out << "]\n";
+
+ out << out_indents << "]";
+}
+
+/* See header for documentation. */
+void trace_add_data(
+ const char* key,
+ const char* format,
+ ...
+) {
+ constexpr size_t bufsz = 256;
+ char buffer[bufsz];
+
+ va_list args;
+ va_start (args, format);
+ vsnprintf (buffer, bufsz, format, args);
+ va_end (args);
+
+ // Guarantee there is a nul terminator
+ buffer[bufsz - 1] = 0;
+
+ std::string value = "\"" + std::string(buffer) + "\"";
+
+ TraceNode* node = g_TraceLog->get_current_leaf();
+ node->add_attrib("str", key, value);
+}
+
+/* See header for documentation. */
+void trace_add_data(
+ const char* key,
+ float value
+) {
+ char buffer[256];
+ sprintf(buffer, "%.20g", (double)value);
+ TraceNode* node = g_TraceLog->get_current_leaf();
+ node->add_attrib("float", key, buffer);
+}
+
+/* See header for documentation. */
+void trace_add_data(
+ const char* key,
+ int value
+) {
+ TraceNode* node = g_TraceLog->get_current_leaf();
+ node->add_attrib("int", key, std::to_string(value));
+}
+
+/* See header for documentation. */
+void trace_add_data(
+ const char* key,
+ unsigned int value
+) {
+ TraceNode* node = g_TraceLog->get_current_leaf();
+ node->add_attrib("int", key, std::to_string(value));
+}
+
+#endif