Merge pull request #1664 from SChernykh/dev

Improved JSON config error reporting
This commit is contained in:
xmrig
2020-04-29 16:23:49 +07:00
committed by GitHub
5 changed files with 99 additions and 1 deletions

View File

@ -191,6 +191,37 @@ rapidjson::Value xmrig::Json::normalize(double value, bool zero)
}
bool xmrig::Json::convertOffset(std::ifstream& ifs, size_t offset, size_t& line, size_t& pos, std::vector<std::string>& s)
{
std::string prev_t;
std::string t;
line = 0;
pos = 0;
size_t k = 0;
while (!ifs.eof()) {
prev_t = t;
std::getline(ifs, t);
k += t.length() + 1;
++line;
if (k > offset) {
pos = offset + t.length() + 1 - k + 1;
s.clear();
if (!prev_t.empty()) {
s.emplace_back(prev_t);
}
s.emplace_back(t);
return true;
}
}
return false;
}
bool xmrig::JsonReader::isEmpty() const
{
return Json::isEmpty(m_obj);

View File

@ -28,6 +28,9 @@
#include "base/kernel/interfaces/IJsonReader.h"
#include "rapidjson/fwd.h"
#include <string>
#include <vector>
#include <fstream>
namespace xmrig {
@ -50,7 +53,12 @@ public:
static bool get(const char *fileName, rapidjson::Document &doc);
static bool save(const char *fileName, const rapidjson::Document &doc);
static bool convertOffset(const char *fileName, size_t offset, size_t &line, size_t &pos, std::vector<std::string>& s);
static rapidjson::Value normalize(double value, bool zero);
private:
static bool convertOffset(std::ifstream& ifs, size_t offset, size_t& line, size_t& pos, std::vector<std::string>& s);
};

View File

@ -64,7 +64,27 @@ bool xmrig::JsonChain::addFile(const char *fileName)
}
if (doc.HasParseError()) {
LOG_ERR("%s<offset:%zu>: \"%s\"", fileName, doc.GetErrorOffset(), GetParseError_En(doc.GetParseError()));
const size_t offset = doc.GetErrorOffset();
size_t line, pos;
std::vector<std::string> s;
if (Json::convertOffset(fileName, offset, line, pos, s)) {
for (const auto& t : s) {
LOG_ERR("%s", t.c_str());
}
std::string t;
if (pos > 0) {
t.assign(pos - 1, ' ');
}
t += '^';
LOG_ERR("%s", t.c_str());
LOG_ERR("%s<line:%zu, position:%zu>: \"%s\"", fileName, line, pos, GetParseError_En(doc.GetParseError()));
}
else {
LOG_ERR("%s<offset:%zu>: \"%s\"", fileName, offset, GetParseError_En(doc.GetParseError()));
}
}
else {
LOG_ERR("unable to open \"%s\".", fileName);

View File

@ -62,3 +62,14 @@ bool xmrig::Json::save(const char *fileName, const rapidjson::Document &doc)
return true;
}
bool xmrig::Json::convertOffset(const char* fileName, size_t offset, size_t& line, size_t& pos, std::vector<std::string>& s)
{
std::ifstream ifs(fileName, std::ios_base::in | std::ios_base::binary);
if (!ifs.is_open()) {
return false;
}
return convertOffset(ifs, offset, line, pos, s);
}

View File

@ -125,3 +125,31 @@ bool xmrig::Json::save(const char *fileName, const rapidjson::Document &doc)
return true;
}
bool xmrig::Json::convertOffset(const char* fileName, size_t offset, size_t& line, size_t& pos, std::vector<std::string>& s)
{
constexpr const std::ios_base::openmode mode = std::ios_base::in | std::ios_base::binary;
# if defined(_MSC_VER)
std::ifstream ifs(toUtf16(fileName), mode);
if (!ifs.is_open()) {
return false;
}
# elif defined(__GNUC__)
const int fd = _wopen(toUtf16(fileName).c_str(), _O_RDONLY | _O_BINARY);
if (fd == -1) {
return false;
}
__gnu_cxx::stdio_filebuf<char> buf(fd, mode);
std::istream ifs(&buf);
# else
std::ifstream ifs(fileName, mode);
if (!ifs.is_open()) {
return false;
}
# endif
return convertOffset(ifs, offset, line, pos, s);
}