123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- /*=============================================================================
- Boost.Wave: A Standard compliant C++ preprocessor library
-
- http://www.boost.org/
- Copyright (c) 2001-2010 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(CORRECT_TOKEN_POSITIONS_HK_061106_INCLUDED)
- #define CORRECT_TOKEN_POSITIONS_HK_061106_INCLUDED
- #include <boost/iterator/transform_iterator.hpp>
- ///////////////////////////////////////////////////////////////////////////////
- namespace detail
- {
- // count the newlines in a C style comment
- template <typename String>
- unsigned count_newlines(String const& str)
- {
- unsigned newlines = 0;
- typename String::size_type p = str.find_first_of('\n');
- while (p != String::npos)
- {
- ++newlines;
- p = str.find_first_of('\n', p+1);
- }
- return newlines;
- }
- // return the length of the last line in a C style comment
- template <typename String>
- unsigned last_line_length(String const& str)
- {
- unsigned len = str.size();
- typename String::size_type p = str.find_last_of('\n');
- if (p != String::npos)
- len -= p;
- return len;
- }
- }
- ///////////////////////////////////////////////////////////////////////////////
- // This is the position correcting functor
- template <typename Token>
- struct correct_token_position
- : public boost::wave::context_policies::eat_whitespace<Token>
- {
- correct_token_position(typename Token::string_type filename)
- : pos(filename) {}
- ///////////////////////////////////////////////////////////////////////////
- //
- // The function 'generated_token' will be called by the library whenever a
- // token is about to be returned from the library.
- //
- // The parameter 'ctx' is a reference to the context object used for
- // instantiating the preprocessing iterators by the user.
- //
- // The parameter 't' is the token about to be returned from the library.
- // This function may alter the token, but in this case it must be
- // implemented with a corresponding signature:
- //
- // TokenT const&
- // generated_token(ContextT const& ctx, TokenT& t);
- //
- // which makes it possible to modify the token in place.
- //
- // The default behavior is to return the token passed as the parameter
- // without modification.
- //
- ///////////////////////////////////////////////////////////////////////////
- template <typename Context>
- Token const&
- generated_token(Context const& ctx, Token& token)
- {
- typedef typename Token::string_type string_type;
- typedef typename Token::position_type position_type;
- using namespace boost::wave;
- // adjust the current position
- position_type current_pos(pos);
- token_id id = token_id(token);
- string_type const& v (token.get_value());
- switch (id) {
- case T_NEWLINE:
- case T_CPPCOMMENT:
- pos.set_line(current_pos.get_line()+1);
- pos.set_column(1);
- break;
- case T_CCOMMENT:
- {
- unsigned lines = detail::count_newlines(v);
- if (lines > 0) {
- pos.set_line(current_pos.get_line() + lines);
- pos.set_column(detail::last_line_length(v));
- }
- else {
- pos.set_column(current_pos.get_column() +
- detail::last_line_length(v));
- }
- }
- break;
- default:
- pos.set_column(current_pos.get_column() + v.size());
- break;
- }
- // set the new position in the token to be returned
- token.set_corrected_position(current_pos);
- return token;
- }
- typename Token::position_type pos;
- };
- ///////////////////////////////////////////////////////////////////////////////
- #endif
|