From aa05858de368b8eb5e9efbbbdb0072b965f8d339 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Wed, 5 Dec 2018 16:55:31 +0900 Subject: [PATCH] add source_name to location/region to show filename now error message prints the filename --- toml/region.hpp | 120 ++++++++++++++++++++++++++++-------------------- 1 file changed, 69 insertions(+), 51 deletions(-) diff --git a/toml/region.hpp b/toml/region.hpp index 20bdda8..709ce98 100644 --- a/toml/region.hpp +++ b/toml/region.hpp @@ -4,12 +4,26 @@ #include #include #include +#include namespace toml { namespace detail { +// helper function to avoid std::string(0, 'c') +template +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. // shared_ptr points the resource that the iter points. // 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 source_ptr = std::shared_ptr; - location(Container cont) + location(std::string name, Container cont) : source_(std::make_shared(std::move(cont))), - begin_(source_->cbegin()), iter_(source_->cbegin()), - end_(source_->cend()) + source_name_(std::move(name)), begin_(source_->cbegin()), + iter_(source_->cbegin()), end_(source_->cend()) {} location(const location&) = default; location(location&&) = default; @@ -40,9 +54,12 @@ struct location source_ptr const& source() const& noexcept {return source_;} source_ptr&& source() && noexcept {return std::move(source_);} + std::string const& name() const noexcept {return source_name_;} + private: - source_ptr source_; + source_ptr source_; + std::string source_name_; const_iterator begin_, iter_, end_; }; @@ -58,21 +75,23 @@ struct region using source_ptr = std::shared_ptr; region(const location& loc) - : begin_(loc.begin()), first_(loc.iter()), - last_(loc.iter()), end_(loc.end()), source_(loc.source()) + : source_(loc.source()), source_name_(loc.name()), + begin_(loc.begin()), first_(loc.iter()), + last_(loc.iter()), end_(loc.end()) {} region(location&& loc) - : begin_(loc.begin()), first_(loc.iter()), - last_(loc.iter()), end_(loc.end()), source_(std::move(loc.source())) + : source_(loc.source()), source_name_(loc.name()), + begin_(loc.begin()), first_(loc.iter()), + last_(loc.iter()), end_(loc.end()) {} region(const location& loc, const_iterator f, const_iterator l) - : begin_(loc.begin()), first_(f), last_(l), end_(loc.end()), - source_(loc.source()) + : source_(loc.source()), source_name_(loc.name()), + begin_(loc.begin()), first_(f), last_(l), end_(loc.end()) {} region(location&& loc, const_iterator f, const_iterator l) - : begin_(loc.begin()), first_(f), last_(l), end_(loc.end()), - source_(std::move(loc.source())) + : source_(loc.source()), source_name_(loc.name()), + begin_(loc.begin()), first_(f), last_(l), end_(loc.end()) {} region(const region&) = default; @@ -92,7 +111,7 @@ struct region 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_);} const_iterator begin() const noexcept {return begin_;} @@ -103,82 +122,81 @@ struct region source_ptr const& source() const& noexcept {return source_;} source_ptr&& source() && noexcept {return std::move(source_);} + std::string const& name() const noexcept {return source_name_;} + private: + source_ptr source_; + std::string source_name_; const_iterator begin_, first_, last_, end_; - source_ptr source_; }; // to show a better error message. template std::string -format_underline(const region& reg, const std::string& msg) +format_underline(const std::string& message, const region& reg, + const std::string& comment_for_underline) { using const_iterator = typename region::const_iterator; using reverse_iterator = std::reverse_iterator; - const auto line_begin = std::find( - reverse_iterator(reg.first()), - reverse_iterator(reg.begin()), - '\n').base(); - const auto line_end = std::find(reg.last(), reg.end(), '\n'); + const auto line_begin = std::find(reverse_iterator(reg.first()), + reverse_iterator(reg.begin()), + '\n').base(); + const auto line_end = std::find(reg.last(), reg.end(), '\n'); const auto line_number = std::to_string( 1 + std::count(reg.begin(), reg.first(), '\n')); std::string retval; - retval += ' '; + retval += message; + retval += "\n --> "; + retval += reg.name(); + retval += "\n "; retval += line_number; retval += " | "; - retval += std::string(line_begin, line_end); + retval += make_string(line_begin, line_end); retval += '\n'; - retval += std::string(line_number.size() + 1, ' '); + retval += make_string(line_number.size() + 1, ' '); retval += " | "; - retval += std::string(std::distance(line_begin, reg.first()), ' '); - retval += std::string(std::distance(reg.first(), reg.last()), '~'); + retval += make_string(std::distance(line_begin, reg.first()), ' '); + retval += make_string(std::distance(reg.first(), reg.last()), '~'); retval += ' '; - retval += msg; + retval += comment_for_underline; return retval; } // to show a better error message. template -std::string format_underline(const region& reg, - typename Container::const_iterator pos, - const std::string& msg) +std::string +format_underline(const std::string& message, const location& loc, + const std::string& comment_for_underline) { - using const_iterator = typename region::const_iterator; + using const_iterator = typename location::const_iterator; using reverse_iterator = std::reverse_iterator; - const auto line_begin = std::find( - reverse_iterator(reg.first()), - reverse_iterator(reg.begin()), - '\n').base(); - const auto line_end = std::find(reg.last(), reg.end(), '\n'); + const auto line_begin = std::find(reverse_iterator(loc.iter()), + reverse_iterator(loc.begin()), + '\n').base(); + const auto line_end = std::find(loc.iter(), loc.end(), '\n'); 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; - retval += ' '; + retval += message; + retval += "\n --> "; + retval += loc.name(); + retval += "\n "; retval += line_number; retval += " | "; - retval += std::string(line_begin, line_end); + retval += make_string(line_begin, line_end); retval += '\n'; - retval += std::string(line_number.size() + 1, ' '); + retval += make_string(line_number.size() + 1, ' '); retval += " | "; - retval += std::string(std::distance(line_begin, reg.first()), ' '); - - if(std::distance(reg.first(), std::prev(pos)) > 0) - { - retval += std::string(std::distance(reg.first(), std::prev(pos)), '-'); - } + retval += make_string(std::distance(line_begin, loc.iter()),' '); retval += '^'; - if(std::distance(pos, reg.last()) > 0) - { - retval += std::string(std::distance(std::next(pos), reg.last()), '-'); - } - + retval += make_string(std::distance(std::next(loc.iter()), line_end), '-'); retval += ' '; - retval += msg; + retval += comment_for_underline; return retval; }