1 /*============================================================================= 2 Copyright (c) 2001-2011 Joel de Guzman 3 4 Distributed under the Boost Software License, Version 1.0. (See accompanying 5 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 =============================================================================*/ 7 #if !defined(BOOST_SPIRIT_CALC8_ERROR_HANDLER_HPP) 8 #define BOOST_SPIRIT_CALC8_ERROR_HANDLER_HPP 9 10 #include <iostream> 11 #include <string> 12 #include <vector> 13 14 namespace client 15 { 16 /////////////////////////////////////////////////////////////////////////////// 17 // The error handler 18 /////////////////////////////////////////////////////////////////////////////// 19 template <typename Iterator> 20 struct error_handler 21 { 22 template <typename, typename, typename> 23 struct result { typedef void type; }; 24 error_handlerclient::error_handler25 error_handler(Iterator first, Iterator last) 26 : first(first), last(last) {} 27 28 template <typename Message, typename What> operator ()client::error_handler29 void operator()( 30 Message const& message, 31 What const& what, 32 Iterator err_pos) const 33 { 34 int line; 35 Iterator line_start = get_pos(err_pos, line); 36 if (err_pos != last) 37 { 38 std::cout << message << what << " line " << line << ':' << std::endl; 39 std::cout << get_line(line_start) << std::endl; 40 for (; line_start != err_pos; ++line_start) 41 std::cout << ' '; 42 std::cout << '^' << std::endl; 43 } 44 else 45 { 46 std::cout << "Unexpected end of file. "; 47 std::cout << message << what << " line " << line << std::endl; 48 } 49 } 50 get_posclient::error_handler51 Iterator get_pos(Iterator err_pos, int& line) const 52 { 53 line = 1; 54 Iterator i = first; 55 Iterator line_start = first; 56 while (i != err_pos) 57 { 58 bool eol = false; 59 if (i != err_pos && *i == '\r') // CR 60 { 61 eol = true; 62 line_start = ++i; 63 } 64 if (i != err_pos && *i == '\n') // LF 65 { 66 eol = true; 67 line_start = ++i; 68 } 69 if (eol) 70 ++line; 71 else 72 ++i; 73 } 74 return line_start; 75 } 76 get_lineclient::error_handler77 std::string get_line(Iterator err_pos) const 78 { 79 Iterator i = err_pos; 80 // position i to the next EOL 81 while (i != last && (*i != '\r' && *i != '\n')) 82 ++i; 83 return std::string(err_pos, i); 84 } 85 86 Iterator first; 87 Iterator last; 88 std::vector<Iterator> iters; 89 }; 90 } 91 92 #endif 93 94