/*============================================================================= Copyright (c) 2001-2011 Joel de Guzman Copyright (c) 2001-2011 Hartmut Kaiser Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) =============================================================================*/ #if !defined(BOOST_SPIRIT_CONJURE_ERROR_HANDLER_HPP) #define BOOST_SPIRIT_CONJURE_ERROR_HANDLER_HPP #include #include #include namespace client { /////////////////////////////////////////////////////////////////////////////// // The error handler /////////////////////////////////////////////////////////////////////////////// template struct error_handler { template struct result { typedef void type; }; error_handler(BaseIterator first, BaseIterator last) : first(first), last(last) {} template void operator()( Message const& message, What const& what, Iterator err_pos) const { // retrieve underlying iterator from current token BaseIterator err_pos_base = err_pos->matched().begin(); int line; BaseIterator line_start = get_pos(err_pos_base, line); if (err_pos_base != last) { std::cout << message << what << " line " << line << ':' << std::endl; std::cout << get_line(line_start) << std::endl; for (; line_start != err_pos_base; ++line_start) std::cout << ' '; std::cout << '^' << std::endl; } else { std::cout << "Unexpected end of file. "; std::cout << message << what << " line " << line << std::endl; } } BaseIterator get_pos(BaseIterator err_pos, int& line) const { line = 1; BaseIterator i = first; BaseIterator line_start = first; while (i != err_pos) { bool eol = false; if (i != err_pos && *i == '\r') // CR { eol = true; line_start = ++i; } if (i != err_pos && *i == '\n') // LF { eol = true; line_start = ++i; } if (eol) ++line; else ++i; } return line_start; } std::string get_line(BaseIterator err_pos) const { BaseIterator i = err_pos; // position i to the next EOL while (i != last && (*i != '\r' && *i != '\n')) ++i; return std::string(err_pos, i); } BaseIterator first; BaseIterator last; std::vector iters; }; } #endif