mirror of
https://github.com/ToruNiina/toml11.git
synced 2025-09-18 02:08:09 +08:00
add source_name to location/region to show filename
now error message prints the filename
This commit is contained in:
110
toml/region.hpp
110
toml/region.hpp
@@ -4,12 +4,26 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
namespace toml
|
namespace toml
|
||||||
{
|
{
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// helper function to avoid std::string(0, 'c')
|
||||||
|
template<typename Iterator>
|
||||||
|
std::string make_string(Iterator first, Iterator last)
|
||||||
|
{
|
||||||
|
if(first == last) {return "";}
|
||||||
|
return std::string(first, last);
|
||||||
|
}
|
||||||
|
inline std::string make_string(std::size_t len, char c)
|
||||||
|
{
|
||||||
|
if(len == 0) {return "";}
|
||||||
|
return std::string(len, c);
|
||||||
|
}
|
||||||
|
|
||||||
// location in a container, normally in a file content.
|
// location in a container, normally in a file content.
|
||||||
// shared_ptr points the resource that the iter points.
|
// shared_ptr points the resource that the iter points.
|
||||||
// it can be used not only for resource handling, but also error message.
|
// it can be used not only for resource handling, but also error message.
|
||||||
@@ -20,10 +34,10 @@ struct location
|
|||||||
using const_iterator = typename Container::const_iterator;
|
using const_iterator = typename Container::const_iterator;
|
||||||
using source_ptr = std::shared_ptr<const Container>;
|
using source_ptr = std::shared_ptr<const Container>;
|
||||||
|
|
||||||
location(Container cont)
|
location(std::string name, Container cont)
|
||||||
: source_(std::make_shared<Container>(std::move(cont))),
|
: source_(std::make_shared<Container>(std::move(cont))),
|
||||||
begin_(source_->cbegin()), iter_(source_->cbegin()),
|
source_name_(std::move(name)), begin_(source_->cbegin()),
|
||||||
end_(source_->cend())
|
iter_(source_->cbegin()), end_(source_->cend())
|
||||||
{}
|
{}
|
||||||
location(const location&) = default;
|
location(const location&) = default;
|
||||||
location(location&&) = default;
|
location(location&&) = default;
|
||||||
@@ -40,9 +54,12 @@ struct location
|
|||||||
source_ptr const& source() const& noexcept {return source_;}
|
source_ptr const& source() const& noexcept {return source_;}
|
||||||
source_ptr&& source() && noexcept {return std::move(source_);}
|
source_ptr&& source() && noexcept {return std::move(source_);}
|
||||||
|
|
||||||
|
std::string const& name() const noexcept {return source_name_;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
source_ptr source_;
|
source_ptr source_;
|
||||||
|
std::string source_name_;
|
||||||
const_iterator begin_, iter_, end_;
|
const_iterator begin_, iter_, end_;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -58,21 +75,23 @@ struct region
|
|||||||
using source_ptr = std::shared_ptr<const Container>;
|
using source_ptr = std::shared_ptr<const Container>;
|
||||||
|
|
||||||
region(const location<Container>& loc)
|
region(const location<Container>& loc)
|
||||||
: begin_(loc.begin()), first_(loc.iter()),
|
: source_(loc.source()), source_name_(loc.name()),
|
||||||
last_(loc.iter()), end_(loc.end()), source_(loc.source())
|
begin_(loc.begin()), first_(loc.iter()),
|
||||||
|
last_(loc.iter()), end_(loc.end())
|
||||||
{}
|
{}
|
||||||
region(location<Container>&& loc)
|
region(location<Container>&& loc)
|
||||||
: begin_(loc.begin()), first_(loc.iter()),
|
: source_(loc.source()), source_name_(loc.name()),
|
||||||
last_(loc.iter()), end_(loc.end()), source_(std::move(loc.source()))
|
begin_(loc.begin()), first_(loc.iter()),
|
||||||
|
last_(loc.iter()), end_(loc.end())
|
||||||
{}
|
{}
|
||||||
|
|
||||||
region(const location<Container>& loc, const_iterator f, const_iterator l)
|
region(const location<Container>& loc, const_iterator f, const_iterator l)
|
||||||
: begin_(loc.begin()), first_(f), last_(l), end_(loc.end()),
|
: source_(loc.source()), source_name_(loc.name()),
|
||||||
source_(loc.source())
|
begin_(loc.begin()), first_(f), last_(l), end_(loc.end())
|
||||||
{}
|
{}
|
||||||
region(location<Container>&& loc, const_iterator f, const_iterator l)
|
region(location<Container>&& loc, const_iterator f, const_iterator l)
|
||||||
: begin_(loc.begin()), first_(f), last_(l), end_(loc.end()),
|
: source_(loc.source()), source_name_(loc.name()),
|
||||||
source_(std::move(loc.source()))
|
begin_(loc.begin()), first_(f), last_(l), end_(loc.end())
|
||||||
{}
|
{}
|
||||||
|
|
||||||
region(const region&) = default;
|
region(const region&) = default;
|
||||||
@@ -92,7 +111,7 @@ struct region
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string str() const {return std::string(first_, last_);}
|
std::string str() const {return make_string(first_, last_);}
|
||||||
std::size_t size() const {return std::distance(first_, last_);}
|
std::size_t size() const {return std::distance(first_, last_);}
|
||||||
|
|
||||||
const_iterator begin() const noexcept {return begin_;}
|
const_iterator begin() const noexcept {return begin_;}
|
||||||
@@ -103,21 +122,24 @@ struct region
|
|||||||
source_ptr const& source() const& noexcept {return source_;}
|
source_ptr const& source() const& noexcept {return source_;}
|
||||||
source_ptr&& source() && noexcept {return std::move(source_);}
|
source_ptr&& source() && noexcept {return std::move(source_);}
|
||||||
|
|
||||||
|
std::string const& name() const noexcept {return source_name_;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
const_iterator begin_, first_, last_, end_;
|
|
||||||
source_ptr source_;
|
source_ptr source_;
|
||||||
|
std::string source_name_;
|
||||||
|
const_iterator begin_, first_, last_, end_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// to show a better error message.
|
// to show a better error message.
|
||||||
template<typename Container>
|
template<typename Container>
|
||||||
std::string
|
std::string
|
||||||
format_underline(const region<Container>& reg, const std::string& msg)
|
format_underline(const std::string& message, const region<Container>& reg,
|
||||||
|
const std::string& comment_for_underline)
|
||||||
{
|
{
|
||||||
using const_iterator = typename region<Container>::const_iterator;
|
using const_iterator = typename region<Container>::const_iterator;
|
||||||
using reverse_iterator = std::reverse_iterator<const_iterator>;
|
using reverse_iterator = std::reverse_iterator<const_iterator>;
|
||||||
const auto line_begin = std::find(
|
const auto line_begin = std::find(reverse_iterator(reg.first()),
|
||||||
reverse_iterator(reg.first()),
|
|
||||||
reverse_iterator(reg.begin()),
|
reverse_iterator(reg.begin()),
|
||||||
'\n').base();
|
'\n').base();
|
||||||
const auto line_end = std::find(reg.last(), reg.end(), '\n');
|
const auto line_end = std::find(reg.last(), reg.end(), '\n');
|
||||||
@@ -126,59 +148,55 @@ format_underline(const region<Container>& reg, const std::string& msg)
|
|||||||
1 + std::count(reg.begin(), reg.first(), '\n'));
|
1 + std::count(reg.begin(), reg.first(), '\n'));
|
||||||
|
|
||||||
std::string retval;
|
std::string retval;
|
||||||
retval += ' ';
|
retval += message;
|
||||||
|
retval += "\n --> ";
|
||||||
|
retval += reg.name();
|
||||||
|
retval += "\n ";
|
||||||
retval += line_number;
|
retval += line_number;
|
||||||
retval += " | ";
|
retval += " | ";
|
||||||
retval += std::string(line_begin, line_end);
|
retval += make_string(line_begin, line_end);
|
||||||
retval += '\n';
|
retval += '\n';
|
||||||
retval += std::string(line_number.size() + 1, ' ');
|
retval += make_string(line_number.size() + 1, ' ');
|
||||||
retval += " | ";
|
retval += " | ";
|
||||||
retval += std::string(std::distance(line_begin, reg.first()), ' ');
|
retval += make_string(std::distance(line_begin, reg.first()), ' ');
|
||||||
retval += std::string(std::distance(reg.first(), reg.last()), '~');
|
retval += make_string(std::distance(reg.first(), reg.last()), '~');
|
||||||
retval += ' ';
|
retval += ' ';
|
||||||
retval += msg;
|
retval += comment_for_underline;
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
// to show a better error message.
|
// to show a better error message.
|
||||||
template<typename Container>
|
template<typename Container>
|
||||||
std::string format_underline(const region<Container>& reg,
|
std::string
|
||||||
typename Container::const_iterator pos,
|
format_underline(const std::string& message, const location<Container>& loc,
|
||||||
const std::string& msg)
|
const std::string& comment_for_underline)
|
||||||
{
|
{
|
||||||
using const_iterator = typename region<Container>::const_iterator;
|
using const_iterator = typename location<Container>::const_iterator;
|
||||||
using reverse_iterator = std::reverse_iterator<const_iterator>;
|
using reverse_iterator = std::reverse_iterator<const_iterator>;
|
||||||
const auto line_begin = std::find(
|
const auto line_begin = std::find(reverse_iterator(loc.iter()),
|
||||||
reverse_iterator(reg.first()),
|
reverse_iterator(loc.begin()),
|
||||||
reverse_iterator(reg.begin()),
|
|
||||||
'\n').base();
|
'\n').base();
|
||||||
const auto line_end = std::find(reg.last(), reg.end(), '\n');
|
const auto line_end = std::find(loc.iter(), loc.end(), '\n');
|
||||||
|
|
||||||
const auto line_number = std::to_string(
|
const auto line_number = std::to_string(
|
||||||
1 + std::count(reg.begin(), reg.first(), '\n'));
|
1 + std::count(loc.begin(), loc.iter(), '\n'));
|
||||||
|
|
||||||
std::string retval;
|
std::string retval;
|
||||||
retval += ' ';
|
retval += message;
|
||||||
|
retval += "\n --> ";
|
||||||
|
retval += loc.name();
|
||||||
|
retval += "\n ";
|
||||||
retval += line_number;
|
retval += line_number;
|
||||||
retval += " | ";
|
retval += " | ";
|
||||||
retval += std::string(line_begin, line_end);
|
retval += make_string(line_begin, line_end);
|
||||||
retval += '\n';
|
retval += '\n';
|
||||||
retval += std::string(line_number.size() + 1, ' ');
|
retval += make_string(line_number.size() + 1, ' ');
|
||||||
retval += " | ";
|
retval += " | ";
|
||||||
retval += std::string(std::distance(line_begin, reg.first()), ' ');
|
retval += make_string(std::distance(line_begin, loc.iter()),' ');
|
||||||
|
|
||||||
if(std::distance(reg.first(), std::prev(pos)) > 0)
|
|
||||||
{
|
|
||||||
retval += std::string(std::distance(reg.first(), std::prev(pos)), '-');
|
|
||||||
}
|
|
||||||
retval += '^';
|
retval += '^';
|
||||||
if(std::distance(pos, reg.last()) > 0)
|
retval += make_string(std::distance(std::next(loc.iter()), line_end), '-');
|
||||||
{
|
|
||||||
retval += std::string(std::distance(std::next(pos), reg.last()), '-');
|
|
||||||
}
|
|
||||||
|
|
||||||
retval += ' ';
|
retval += ' ';
|
||||||
retval += msg;
|
retval += comment_for_underline;
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user