1 /*=============================================================================
2 Boost.Wave: A Standard compliant C++ preprocessor library
6 Copyright (c) 2001-2010 Hartmut Kaiser. Distributed under the Boost
7 Software License, Version 1.0. (See accompanying file
8 LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 =============================================================================*/
11 #if !defined(BOOST_CORRECT_TOKEN_POSITIONS_HK_061106_INCLUDED)
12 #define BOOST_CORRECT_TOKEN_POSITIONS_HK_061106_INCLUDED
14 #include <boost/iterator/transform_iterator.hpp>
16 ///////////////////////////////////////////////////////////////////////////////
19 // count the newlines in a C style comment
20 template <typename String>
21 unsigned count_newlines(String const& str)
23 unsigned newlines = 0;
24 typename String::size_type p = str.find_first_of('\n');
25 while (p != String::npos)
28 p = str.find_first_of('\n', p+1);
33 // return the length of the last line in a C style comment
34 template <typename String>
35 unsigned last_line_length(String const& str)
37 unsigned len = str.size();
38 typename String::size_type p = str.find_last_of('\n');
39 if (p != String::npos)
45 ///////////////////////////////////////////////////////////////////////////////
46 // This is the position correcting functor
47 template <typename Token>
48 struct correct_token_position
49 : public boost::wave::context_policies::eat_whitespace<Token>
51 correct_token_position(typename Token::string_type filename)
54 ///////////////////////////////////////////////////////////////////////////
56 // The function 'generated_token' will be called by the library whenever a
57 // token is about to be returned from the library.
59 // The parameter 'ctx' is a reference to the context object used for
60 // instantiating the preprocessing iterators by the user.
62 // The parameter 't' is the token about to be returned from the library.
63 // This function may alter the token, but in this case it must be
64 // implemented with a corresponding signature:
67 // generated_token(ContextT const& ctx, TokenT& t);
69 // which makes it possible to modify the token in place.
71 // The default behavior is to return the token passed as the parameter
72 // without modification.
74 ///////////////////////////////////////////////////////////////////////////
75 template <typename Context>
77 generated_token(Context const& ctx, Token& token)
79 typedef typename Token::string_type string_type;
80 typedef typename Token::position_type position_type;
82 using namespace boost::wave;
84 // adjust the current position
85 position_type current_pos(pos);
87 token_id id = token_id(token);
88 string_type const& v (token.get_value());
93 pos.set_line(current_pos.get_line()+1);
99 unsigned lines = detail::count_newlines(v);
101 pos.set_line(current_pos.get_line() + lines);
102 pos.set_column(detail::last_line_length(v));
105 pos.set_column(current_pos.get_column() +
106 detail::last_line_length(v));
112 pos.set_column(current_pos.get_column() + v.size());
116 // set the new position in the token to be returned
117 token.set_corrected_position(current_pos);
121 typename Token::position_type pos;
124 ///////////////////////////////////////////////////////////////////////////////