Skip to content

Commit ebe6429

Browse files
committed
Improve Wave preprocess diagnostics
1 parent 48aa7a7 commit ebe6429

1 file changed

Lines changed: 101 additions & 6 deletions

File tree

src/nbl/asset/utils/CWaveStringResolver.cpp

Lines changed: 101 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,85 @@
3838
*/
3939

4040
#include "nabla.h"
41+
#include <boost/exception/diagnostic_information.hpp>
4142

4243
using namespace nbl;
4344
using namespace nbl::asset;
4445

4546
#include "nbl/asset/utils/waveContext.h"
4647

48+
namespace
49+
{
50+
std::string getLineSnippet(std::string_view text, const int lineNo)
51+
{
52+
if (lineNo <= 0)
53+
return {};
54+
55+
int currentLine = 1;
56+
size_t lineStart = 0ull;
57+
while (lineStart <= text.size())
58+
{
59+
const auto lineEnd = text.find('\n', lineStart);
60+
if (currentLine == lineNo)
61+
{
62+
const auto count = lineEnd == std::string_view::npos ? text.size() - lineStart : lineEnd - lineStart;
63+
auto line = std::string(text.substr(lineStart, count));
64+
if (!line.empty() && line.back() == '\r')
65+
line.pop_back();
66+
return line;
67+
}
68+
69+
if (lineEnd == std::string_view::npos)
70+
break;
71+
lineStart = lineEnd + 1ull;
72+
currentLine++;
73+
}
74+
75+
return {};
76+
}
77+
78+
std::string makeCaretLine(const int columnNo)
79+
{
80+
if (columnNo <= 0)
81+
return {};
82+
83+
return std::string(static_cast<size_t>(columnNo - 1), ' ') + '^';
84+
}
85+
86+
std::string makeWaveFailureContext(
87+
const nbl::asset::IShaderCompiler::SPreprocessorOptions& preprocessOptions,
88+
const std::string_view code,
89+
const char* const phase,
90+
const std::string_view activeMacroDefinition,
91+
const char* const fileName,
92+
const int lineNo,
93+
const int columnNo)
94+
{
95+
std::ostringstream stream;
96+
stream << "Wave preprocessing context:";
97+
if (!preprocessOptions.sourceIdentifier.empty())
98+
stream << "\n source: " << preprocessOptions.sourceIdentifier;
99+
stream << "\n phase: " << phase;
100+
stream << "\n extra_define_count: " << preprocessOptions.extraDefines.size();
101+
stream << "\n source_has_trailing_newline: " << ((!code.empty() && code.back() == '\n') ? "yes" : "no");
102+
if (!activeMacroDefinition.empty())
103+
stream << "\n active_macro_definition: " << activeMacroDefinition;
104+
if (fileName && fileName[0] != '\0')
105+
stream << "\n location: " << fileName << ':' << lineNo << ':' << columnNo;
106+
107+
const auto snippet = getLineSnippet(code, lineNo);
108+
if (!snippet.empty() && fileName && preprocessOptions.sourceIdentifier == fileName)
109+
{
110+
stream << "\n snippet: " << snippet;
111+
const auto caret = makeCaretLine(columnNo);
112+
if (!caret.empty())
113+
stream << "\n " << caret;
114+
}
115+
116+
return stream.str();
117+
}
118+
}
119+
47120
namespace nbl::wave
48121
{
49122
std::string preprocess(std::string& code, const nbl::asset::IShaderCompiler::SPreprocessorOptions& preprocessOptions, bool withCaching, std::function<void(nbl::wave::context&)> post)
@@ -61,29 +134,51 @@ namespace nbl::wave
61134

62135
// preprocess
63136
core::string resolvedString;
137+
const char* phase = "registering built-in macros";
138+
std::string activeMacroDefinition;
64139
try
65140
{
141+
phase = "registering extra macro definitions";
66142
for (const auto& define : preprocessOptions.extraDefines)
67143
{
68-
std::string macroDefinition(define.identifier);
69-
macroDefinition.push_back('=');
70-
macroDefinition.append(define.definition);
71-
context.add_macro_definition(macroDefinition);
144+
activeMacroDefinition = define.identifier;
145+
activeMacroDefinition.push_back('=');
146+
activeMacroDefinition.append(define.definition);
147+
context.add_macro_definition(activeMacroDefinition);
72148
}
149+
activeMacroDefinition.clear();
73150

151+
phase = "expanding translation unit";
74152
auto stream = std::stringstream();
75153
for (auto i = context.begin(); i != context.end(); i++)
76154
stream << i->get_value();
77155
resolvedString = stream.str();
78156
}
79157
catch (boost::wave::preprocess_exception& e)
80158
{
81-
preprocessOptions.logger.log("%s exception caught. %s [%s:%d:%d]",system::ILogger::ELL_ERROR,e.what(),e.description(),e.file_name(),e.line_no(),e.column_no());
159+
const auto failureContext = makeWaveFailureContext(preprocessOptions, code, phase, activeMacroDefinition, e.file_name(), e.line_no(), e.column_no());
160+
preprocessOptions.logger.log("%s exception caught. %s [%s:%d:%d]\n%s", system::ILogger::ELL_ERROR, e.what(), e.description(), e.file_name(), e.line_no(), e.column_no(), failureContext.c_str());
161+
preprocessOptions.logger.log("Boost diagnostic information:\n%s", system::ILogger::ELL_ERROR, boost::diagnostic_information(e).c_str());
162+
return {};
163+
}
164+
catch (const boost::exception& e)
165+
{
166+
const auto failureContext = makeWaveFailureContext(preprocessOptions, code, phase, activeMacroDefinition, preprocessOptions.sourceIdentifier.data(), 0, 0);
167+
preprocessOptions.logger.log("Boost exception caught during Wave preprocessing.\n%s", system::ILogger::ELL_ERROR, failureContext.c_str());
168+
preprocessOptions.logger.log("Boost diagnostic information:\n%s", system::ILogger::ELL_ERROR, boost::diagnostic_information(e).c_str());
169+
return {};
170+
}
171+
catch (const std::exception& e)
172+
{
173+
const auto failureContext = makeWaveFailureContext(preprocessOptions, code, phase, activeMacroDefinition, preprocessOptions.sourceIdentifier.data(), 0, 0);
174+
preprocessOptions.logger.log("std::exception caught during Wave preprocessing. %s\n%s", system::ILogger::ELL_ERROR, e.what(), failureContext.c_str());
82175
return {};
83176
}
84177
catch (...)
85178
{
86-
preprocessOptions.logger.log("Unknown exception caught!",system::ILogger::ELL_ERROR);
179+
const auto failureContext = makeWaveFailureContext(preprocessOptions, code, phase, activeMacroDefinition, preprocessOptions.sourceIdentifier.data(), 0, 0);
180+
preprocessOptions.logger.log("Unknown exception caught during Wave preprocessing.\n%s", system::ILogger::ELL_ERROR, failureContext.c_str());
181+
preprocessOptions.logger.log("Current exception diagnostic information:\n%s", system::ILogger::ELL_ERROR, boost::current_exception_diagnostic_information().c_str());
87182
return {};
88183
}
89184

0 commit comments

Comments
 (0)