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