add source_name to location/region to show filename

now error message prints the filename
This commit is contained in:
ToruNiina
2018-12-05 16:55:31 +09:00
parent 2b3c8887d6
commit aa05858de3

View File

@@ -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;
} }