OpenFPGA/libs/EXTERNAL/libtatum/libtatumparse/tatumparse/tatumparse_error.cpp

70 lines
1.8 KiB
C++

#include <cstdarg>
#include <cassert>
#include "tatumparse_error.hpp"
#include "tatumparse.hpp"
namespace tatumparse {
std::string escape_string(const std::string& near_text);
//We wrap the actual tatum_error to issolate custom handlers from vaargs
void tatum_error_wrap(Callback& callback, const int line_no, const std::string& near_text, const char* fmt, ...) {
va_list args;
va_start(args, fmt);
//We need to copy the args so we don't change them before the true formating
va_list args_copy;
va_copy(args_copy, args);
//Determine the formatted length using a copy of the args
int len = std::vsnprintf(nullptr, 0, fmt, args_copy);
va_end(args_copy); //Clean-up
//Negative if there is a problem with the format string
assert(len >= 0 && "Problem decoding format string");
size_t buf_size = len + 1; //For terminator
//Allocate a buffer
// unique_ptr will free buffer automatically
std::unique_ptr<char[]> buf(new char[buf_size]);
//Format into the buffer using the original args
len = std::vsnprintf(buf.get(), buf_size, fmt, args);
va_end(args); //Clean-up
assert(len >= 0 && "Problem decoding format string");
assert(static_cast<size_t>(len) == buf_size - 1);
//Build the string from the buffer
std::string msg(buf.get(), len);
//TODO: escape near_text
std::string escaped_near_text = escape_string(near_text);
//Call the error handler
callback.parse_error(line_no, escaped_near_text, msg);
}
std::string escape_string(const std::string& near_text) {
std::string escaped_text;
for(char c : near_text) {
if(c == '\n') {
escaped_text += "\\n";
} else if(c == '\r') {
escaped_text += "\\r";
} else {
escaped_text += c;
}
}
return escaped_text;
}
}