Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/astcenc/astcenc_diagnostic_trace.cpp
9896 views
1
// SPDX-License-Identifier: Apache-2.0
2
// ----------------------------------------------------------------------------
3
// Copyright 2021-2023 Arm Limited
4
//
5
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
6
// use this file except in compliance with the License. You may obtain a copy
7
// of the License at:
8
//
9
// http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing, software
12
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14
// License for the specific language governing permissions and limitations
15
// under the License.
16
// ----------------------------------------------------------------------------
17
18
/**
19
* @brief Functions for the library entrypoint.
20
*/
21
22
#if defined(ASTCENC_DIAGNOSTICS)
23
24
#include <cassert>
25
#include <cstdarg>
26
#include <cstdio>
27
#include <cmath>
28
#include <limits>
29
#include <string>
30
31
#include "astcenc_diagnostic_trace.h"
32
33
/** @brief The global trace logger. */
34
static TraceLog* g_TraceLog = nullptr;
35
36
/** @brief The JSON indentation level. */
37
static const size_t g_trace_indent = 2;
38
39
TraceLog::TraceLog(
40
const char* file_name):
41
m_file(file_name, std::ofstream::out | std::ofstream::binary)
42
{
43
assert(!g_TraceLog);
44
g_TraceLog = this;
45
m_root = new TraceNode("root");
46
}
47
48
/* See header for documentation. */
49
TraceNode* TraceLog::get_current_leaf()
50
{
51
if (m_stack.size())
52
{
53
return m_stack.back();
54
}
55
56
return nullptr;
57
}
58
59
/* See header for documentation. */
60
size_t TraceLog::get_depth()
61
{
62
return m_stack.size();
63
}
64
65
/* See header for documentation. */
66
TraceLog::~TraceLog()
67
{
68
assert(g_TraceLog == this);
69
delete m_root;
70
g_TraceLog = nullptr;
71
}
72
73
/* See header for documentation. */
74
TraceNode::TraceNode(
75
const char* format,
76
...
77
) {
78
// Format the name string
79
constexpr size_t bufsz = 256;
80
char buffer[bufsz];
81
82
va_list args;
83
va_start (args, format);
84
vsnprintf (buffer, bufsz, format, args);
85
va_end (args);
86
87
// Guarantee there is a nul terminator
88
buffer[bufsz - 1] = 0;
89
90
// Generate the node
91
TraceNode* parent = g_TraceLog->get_current_leaf();
92
size_t depth = g_TraceLog->get_depth();
93
g_TraceLog->m_stack.push_back(this);
94
95
bool comma = parent && parent->m_attrib_count;
96
auto& out = g_TraceLog->m_file;
97
98
if (parent)
99
{
100
parent->m_attrib_count++;
101
}
102
103
if (comma)
104
{
105
out << ',';
106
}
107
108
if (depth)
109
{
110
out << '\n';
111
}
112
113
size_t out_indent = (depth * 2) * g_trace_indent;
114
size_t in_indent = (depth * 2 + 1) * g_trace_indent;
115
116
std::string out_indents("");
117
if (out_indent)
118
{
119
out_indents = std::string(out_indent, ' ');
120
}
121
122
std::string in_indents(in_indent, ' ');
123
124
out << out_indents << "[ \"node\", \"" << buffer << "\",\n";
125
out << in_indents << "[";
126
}
127
128
/* See header for documentation. */
129
void TraceNode::add_attrib(
130
std::string type,
131
std::string key,
132
std::string value
133
) {
134
(void)type;
135
136
size_t depth = g_TraceLog->get_depth();
137
size_t indent = (depth * 2) * g_trace_indent;
138
auto& out = g_TraceLog->m_file;
139
bool comma = m_attrib_count;
140
m_attrib_count++;
141
142
if (comma)
143
{
144
out << ',';
145
}
146
147
out << '\n';
148
out << std::string(indent, ' ') << "[ "
149
<< "\"" << key << "\", "
150
<< value << " ]";
151
}
152
153
/* See header for documentation. */
154
TraceNode::~TraceNode()
155
{
156
g_TraceLog->m_stack.pop_back();
157
158
auto& out = g_TraceLog->m_file;
159
size_t depth = g_TraceLog->get_depth();
160
size_t out_indent = (depth * 2) * g_trace_indent;
161
size_t in_indent = (depth * 2 + 1) * g_trace_indent;
162
163
std::string out_indents("");
164
if (out_indent)
165
{
166
out_indents = std::string(out_indent, ' ');
167
}
168
169
std::string in_indents(in_indent, ' ');
170
171
if (m_attrib_count)
172
{
173
out << "\n" << in_indents;
174
}
175
out << "]\n";
176
177
out << out_indents << "]";
178
}
179
180
/* See header for documentation. */
181
void trace_add_data(
182
const char* key,
183
const char* format,
184
...
185
) {
186
constexpr size_t bufsz = 256;
187
char buffer[bufsz];
188
189
va_list args;
190
va_start (args, format);
191
vsnprintf (buffer, bufsz, format, args);
192
va_end (args);
193
194
// Guarantee there is a nul terminator
195
buffer[bufsz - 1] = 0;
196
197
std::string value = "\"" + std::string(buffer) + "\"";
198
199
TraceNode* node = g_TraceLog->get_current_leaf();
200
node->add_attrib("str", key, value);
201
}
202
203
/* See header for documentation. */
204
void trace_add_data(
205
const char* key,
206
float value
207
) {
208
// Turn infinities into parseable values
209
if (std::isinf(value))
210
{
211
if (value > 0.0f)
212
{
213
value = std::numeric_limits<float>::max();
214
}
215
else
216
{
217
value = -std::numeric_limits<float>::max();
218
}
219
}
220
221
char buffer[256];
222
sprintf(buffer, "%.20g", (double)value);
223
TraceNode* node = g_TraceLog->get_current_leaf();
224
node->add_attrib("float", key, buffer);
225
}
226
227
/* See header for documentation. */
228
void trace_add_data(
229
const char* key,
230
int value
231
) {
232
TraceNode* node = g_TraceLog->get_current_leaf();
233
node->add_attrib("int", key, std::to_string(value));
234
}
235
236
/* See header for documentation. */
237
void trace_add_data(
238
const char* key,
239
unsigned int value
240
) {
241
TraceNode* node = g_TraceLog->get_current_leaf();
242
node->add_attrib("int", key, std::to_string(value));
243
}
244
245
#endif
246
247