/*============================================================================= 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 /////////////////////////////////////////////////////////////////////////////// namespace detail { // count the newlines in a C style comment template 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 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 struct correct_token_position : public boost::wave::context_policies::eat_whitespace { 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 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