metaforce/hecl/lib/Frontend/Diagnostics.cpp

105 lines
3.1 KiB
C++
Raw Normal View History

2016-03-04 23:02:44 +00:00
#include "hecl/hecl.hpp"
#include "hecl/Frontend.hpp"
2015-10-09 02:08:10 +00:00
2017-12-29 07:56:31 +00:00
#include <cstdarg>
2015-10-09 02:08:10 +00:00
/* ANSI sequences */
#define RED "\x1b[1;31m"
#define YELLOW "\x1b[1;33m"
#define GREEN "\x1b[1;32m"
#define MAGENTA "\x1b[1;35m"
#define CYAN "\x1b[1;36m"
#define BOLD "\x1b[1m"
#define NORMAL "\x1b[0m"
2018-12-08 05:18:42 +00:00
namespace hecl::Frontend {
2015-10-09 02:08:10 +00:00
2018-12-08 05:18:42 +00:00
std::string Diagnostics::sourceDiagString(const SourceLocation& l, bool ansi) const {
std::string::const_iterator it = m_source.begin();
for (int i = 1; i < l.line; ++i) {
2015-10-14 23:06:47 +00:00
while (*it != '\n' && it != m_source.end())
2018-12-08 05:18:42 +00:00
++it;
if (*it == '\n')
++it;
}
std::string::const_iterator begin = it;
while (*it != '\n' && it != m_source.end())
++it;
std::string::const_iterator end = it;
2015-10-14 23:06:47 +00:00
2018-12-08 05:18:42 +00:00
std::string retval(begin, end);
retval += '\n';
for (int i = 1; i < l.col; ++i)
retval += ' ';
if (ansi)
retval += GREEN "^" NORMAL;
else
retval += '^';
return retval;
2015-10-14 23:06:47 +00:00
}
2018-12-08 05:18:42 +00:00
void Diagnostics::reportScannerErr(const SourceLocation& l, const char* fmt, ...) {
va_list ap;
va_start(ap, fmt);
char* result = nullptr;
2015-10-09 02:08:10 +00:00
#ifdef _WIN32
2018-12-08 05:18:42 +00:00
int length = _vscprintf(fmt, ap);
result = (char*)malloc(length);
vsnprintf(result, length, fmt, ap);
2015-10-09 02:08:10 +00:00
#else
2018-12-08 05:18:42 +00:00
vasprintf(&result, fmt, ap);
2015-10-09 02:08:10 +00:00
#endif
2018-12-08 05:18:42 +00:00
va_end(ap);
if (logvisor::XtermColor)
LogModule.report(logvisor::Fatal, CYAN "[Scanner]" NORMAL " %s " YELLOW "@%d:%d " NORMAL "\n%s\n%s", m_name.c_str(),
l.line, l.col, result, sourceDiagString(l, true).c_str());
else
LogModule.report(logvisor::Fatal, "[Scanner] %s @%d:%d\n%s\n%s", m_name.c_str(), l.line, l.col, result,
sourceDiagString(l, false).c_str());
free(result);
2015-10-09 02:08:10 +00:00
}
2018-12-08 05:18:42 +00:00
void Diagnostics::reportParserErr(const SourceLocation& l, const char* fmt, ...) {
va_list ap;
va_start(ap, fmt);
char* result = nullptr;
2015-10-14 02:16:21 +00:00
#ifdef _WIN32
2018-12-08 05:18:42 +00:00
int length = _vscprintf(fmt, ap);
result = (char*)malloc(length);
vsnprintf(result, length, fmt, ap);
2015-10-14 02:16:21 +00:00
#else
2018-12-08 05:18:42 +00:00
vasprintf(&result, fmt, ap);
2015-10-14 02:16:21 +00:00
#endif
2018-12-08 05:18:42 +00:00
va_end(ap);
if (logvisor::XtermColor)
LogModule.report(logvisor::Fatal, CYAN "[Parser]" NORMAL " %s " YELLOW "@%d:%d " NORMAL "\n%s\n%s", m_name.c_str(),
l.line, l.col, result, sourceDiagString(l, true).c_str());
else
LogModule.report(logvisor::Fatal, "[Parser] %s @%d:%d\n%s\n%s", m_name.c_str(), l.line, l.col, result,
sourceDiagString(l, false).c_str());
free(result);
2015-10-14 02:16:21 +00:00
}
2018-12-08 05:18:42 +00:00
void Diagnostics::reportBackendErr(const SourceLocation& l, const char* fmt, ...) {
va_list ap;
va_start(ap, fmt);
char* result = nullptr;
2015-10-14 02:16:21 +00:00
#ifdef _WIN32
2018-12-08 05:18:42 +00:00
int length = _vscprintf(fmt, ap);
result = (char*)malloc(length);
vsnprintf(result, length, fmt, ap);
2015-10-14 02:16:21 +00:00
#else
2018-12-08 05:18:42 +00:00
vasprintf(&result, fmt, ap);
2015-10-14 02:16:21 +00:00
#endif
2018-12-08 05:18:42 +00:00
va_end(ap);
if (logvisor::XtermColor)
LogModule.report(logvisor::Fatal, CYAN "[%s]" NORMAL " %s " YELLOW "@%d:%d " NORMAL "\n%s\n%s", m_backend.c_str(),
m_name.c_str(), l.line, l.col, result, sourceDiagString(l, true).c_str());
else
LogModule.report(logvisor::Fatal, "[%s] %s @%d:%d\n%s\n%s", m_backend.c_str(), m_name.c_str(), l.line, l.col,
result, sourceDiagString(l, false).c_str());
free(result);
2015-10-14 02:16:21 +00:00
}
2018-12-08 05:18:42 +00:00
} // namespace hecl::Frontend