Path: blob/master/thirdparty/astcenc/astcenc_diagnostic_trace.cpp
9896 views
// SPDX-License-Identifier: Apache-2.01// ----------------------------------------------------------------------------2// Copyright 2021-2023 Arm Limited3//4// Licensed under the Apache License, Version 2.0 (the "License"); you may not5// use this file except in compliance with the License. You may obtain a copy6// of the License at:7//8// http://www.apache.org/licenses/LICENSE-2.09//10// Unless required by applicable law or agreed to in writing, software11// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT12// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the13// License for the specific language governing permissions and limitations14// under the License.15// ----------------------------------------------------------------------------1617/**18* @brief Functions for the library entrypoint.19*/2021#if defined(ASTCENC_DIAGNOSTICS)2223#include <cassert>24#include <cstdarg>25#include <cstdio>26#include <cmath>27#include <limits>28#include <string>2930#include "astcenc_diagnostic_trace.h"3132/** @brief The global trace logger. */33static TraceLog* g_TraceLog = nullptr;3435/** @brief The JSON indentation level. */36static const size_t g_trace_indent = 2;3738TraceLog::TraceLog(39const char* file_name):40m_file(file_name, std::ofstream::out | std::ofstream::binary)41{42assert(!g_TraceLog);43g_TraceLog = this;44m_root = new TraceNode("root");45}4647/* See header for documentation. */48TraceNode* TraceLog::get_current_leaf()49{50if (m_stack.size())51{52return m_stack.back();53}5455return nullptr;56}5758/* See header for documentation. */59size_t TraceLog::get_depth()60{61return m_stack.size();62}6364/* See header for documentation. */65TraceLog::~TraceLog()66{67assert(g_TraceLog == this);68delete m_root;69g_TraceLog = nullptr;70}7172/* See header for documentation. */73TraceNode::TraceNode(74const char* format,75...76) {77// Format the name string78constexpr size_t bufsz = 256;79char buffer[bufsz];8081va_list args;82va_start (args, format);83vsnprintf (buffer, bufsz, format, args);84va_end (args);8586// Guarantee there is a nul terminator87buffer[bufsz - 1] = 0;8889// Generate the node90TraceNode* parent = g_TraceLog->get_current_leaf();91size_t depth = g_TraceLog->get_depth();92g_TraceLog->m_stack.push_back(this);9394bool comma = parent && parent->m_attrib_count;95auto& out = g_TraceLog->m_file;9697if (parent)98{99parent->m_attrib_count++;100}101102if (comma)103{104out << ',';105}106107if (depth)108{109out << '\n';110}111112size_t out_indent = (depth * 2) * g_trace_indent;113size_t in_indent = (depth * 2 + 1) * g_trace_indent;114115std::string out_indents("");116if (out_indent)117{118out_indents = std::string(out_indent, ' ');119}120121std::string in_indents(in_indent, ' ');122123out << out_indents << "[ \"node\", \"" << buffer << "\",\n";124out << in_indents << "[";125}126127/* See header for documentation. */128void TraceNode::add_attrib(129std::string type,130std::string key,131std::string value132) {133(void)type;134135size_t depth = g_TraceLog->get_depth();136size_t indent = (depth * 2) * g_trace_indent;137auto& out = g_TraceLog->m_file;138bool comma = m_attrib_count;139m_attrib_count++;140141if (comma)142{143out << ',';144}145146out << '\n';147out << std::string(indent, ' ') << "[ "148<< "\"" << key << "\", "149<< value << " ]";150}151152/* See header for documentation. */153TraceNode::~TraceNode()154{155g_TraceLog->m_stack.pop_back();156157auto& out = g_TraceLog->m_file;158size_t depth = g_TraceLog->get_depth();159size_t out_indent = (depth * 2) * g_trace_indent;160size_t in_indent = (depth * 2 + 1) * g_trace_indent;161162std::string out_indents("");163if (out_indent)164{165out_indents = std::string(out_indent, ' ');166}167168std::string in_indents(in_indent, ' ');169170if (m_attrib_count)171{172out << "\n" << in_indents;173}174out << "]\n";175176out << out_indents << "]";177}178179/* See header for documentation. */180void trace_add_data(181const char* key,182const char* format,183...184) {185constexpr size_t bufsz = 256;186char buffer[bufsz];187188va_list args;189va_start (args, format);190vsnprintf (buffer, bufsz, format, args);191va_end (args);192193// Guarantee there is a nul terminator194buffer[bufsz - 1] = 0;195196std::string value = "\"" + std::string(buffer) + "\"";197198TraceNode* node = g_TraceLog->get_current_leaf();199node->add_attrib("str", key, value);200}201202/* See header for documentation. */203void trace_add_data(204const char* key,205float value206) {207// Turn infinities into parseable values208if (std::isinf(value))209{210if (value > 0.0f)211{212value = std::numeric_limits<float>::max();213}214else215{216value = -std::numeric_limits<float>::max();217}218}219220char buffer[256];221sprintf(buffer, "%.20g", (double)value);222TraceNode* node = g_TraceLog->get_current_leaf();223node->add_attrib("float", key, buffer);224}225226/* See header for documentation. */227void trace_add_data(228const char* key,229int value230) {231TraceNode* node = g_TraceLog->get_current_leaf();232node->add_attrib("int", key, std::to_string(value));233}234235/* See header for documentation. */236void trace_add_data(237const char* key,238unsigned int value239) {240TraceNode* node = g_TraceLog->get_current_leaf();241node->add_attrib("int", key, std::to_string(value));242}243244#endif245246247