/*=============================================================================
    Boost.Wave: A Standard compliant C++ preprocessor library
    Whitespace eater
    
    http://www.boost.org/

    Copyright (c) 2003 Paul Mensonides
    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(WHITESPACE_HANDLING_HPP_INCLUDED)
#define WHITESPACE_HANDLING_HPP_INCLUDED

#include <boost/wave/wave_config.hpp>   
#include <boost/wave/token_ids.hpp>   
#include <boost/wave/preprocessing_hooks.hpp>
#include <boost/wave/language_support.hpp>

// this must occur after all of the includes and before any code appears
#ifdef BOOST_HAS_ABI_HEADERS
#include BOOST_ABI_PREFIX
#endif

///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
namespace context_policies {

namespace util {
    ///////////////////////////////////////////////////////////////////////////
    //  This function returns true if the given C style comment contains at 
    //  least one newline
    template <typename TokenT>
    bool ccomment_has_newline(TokenT const& token)
    {
        using namespace boost::wave;

        if (T_CCOMMENT == token_id(token) &&
            TokenT::string_type::npos != token.get_value().find_first_of("\n"))
        {
            return true;
        }
        return false;
    }

    ///////////////////////////////////////////////////////////////////////////
    //  This function returns the number of newlines in the given C style 
    //  comment 
    template <typename TokenT>
    int ccomment_count_newlines(TokenT const& token)
    {
        using namespace boost::wave;
        int newlines = 0;
        if (T_CCOMMENT == token_id(token)) {
        typename TokenT::string_type const& value = token.get_value();
        typename TokenT::string_type::size_type p = value.find_first_of("\n");

            while (TokenT::string_type::npos != p) {
                ++newlines;
                p = value.find_first_of("\n", p+1);
            } 
        }
        return newlines;
    }
}

///////////////////////////////////////////////////////////////////////////////
template <typename TokenT>
class eat_whitespace 
:   public default_preprocessing_hooks
{
public:
    eat_whitespace();

    template <typename ContextT>
    bool may_skip_whitespace(ContextT const& ctx, TokenT &token, 
        bool &skipped_newline);

protected:
    bool skip_cppcomment(boost::wave::token_id id)
    {
        return !preserve_comments && T_CPPCOMMENT == id;
    }

private:
    typedef bool state_t(TokenT &token, bool &skipped_newline);
    state_t eat_whitespace::* state;
    state_t general, newline, newline_2nd, whitespace;
    bool preserve_comments;
};

template <typename TokenT>
inline 
eat_whitespace<TokenT>::eat_whitespace()
:   state(&eat_whitespace::newline), preserve_comments(false)
{
}

template <typename TokenT>
template <typename ContextT>
inline bool 
eat_whitespace<TokenT>::may_skip_whitespace(ContextT const& ctx, TokenT &token, 
    bool &skipped_newline) 
{
    // re-initialize the preserve comments state
    preserve_comments = boost::wave::need_preserve_comments(ctx.get_language());
    return (this->*state)(token, skipped_newline);
}

template <typename TokenT>
inline bool 
eat_whitespace<TokenT>::general(TokenT &token, bool &skipped_newline) 
{
    using namespace boost::wave;

    token_id id = token_id(token);
    if (T_NEWLINE == id || T_CPPCOMMENT == id) {
        state = &eat_whitespace::newline;
    }
    else if (T_SPACE == id || T_SPACE2 == id || T_CCOMMENT == id) {
        state = &eat_whitespace::whitespace;

        if (util::ccomment_has_newline(token)) 
            skipped_newline = true;

        if ((!preserve_comments || T_CCOMMENT != id) && 
            token.get_value().size() > 1)
        {
            token.set_value(" ");   // replace with a single space
        }
    }
    else {
        state = &eat_whitespace::general;
    }
    return false;
}

template <typename TokenT>
inline bool 
eat_whitespace<TokenT>::newline(TokenT &token, bool &skipped_newline) 
{
    using namespace boost::wave;
    
    token_id id = token_id(token);
    if (T_NEWLINE == id || T_CPPCOMMENT == id) {
        skipped_newline = true;
        state = &eat_whitespace::newline_2nd;
        return T_NEWLINE == id || skip_cppcomment(id);
    }
    else if (T_SPACE != id && T_SPACE2 != id && T_CCOMMENT != id) {
        return general(token, skipped_newline);
    }

    if (T_CCOMMENT == id) {
        if (util::ccomment_has_newline(token)) {
            skipped_newline = true;
            state = &eat_whitespace::newline_2nd;
        }
        if (preserve_comments) {
            state = &eat_whitespace::general;
            return false;
        }
        // fall through...
    }
    return true;
}

template <typename TokenT>
inline bool 
eat_whitespace<TokenT>::newline_2nd(TokenT &token, bool &skipped_newline) 
{
    using namespace boost::wave;

    token_id id = token_id(token);
    if (T_SPACE == id || T_SPACE2 == id)
        return true;
    if (T_CCOMMENT == id) {
        if (util::ccomment_has_newline(token))
            skipped_newline = true;

        if (preserve_comments) {
            state = &eat_whitespace::general;
            return false;
        }
        return  true;
    }
    if (T_NEWLINE != id && T_CPPCOMMENT != id) 
        return general(token, skipped_newline);

    skipped_newline = true;
    return T_NEWLINE == id || skip_cppcomment(id);
}

template <typename TokenT>
inline bool 
eat_whitespace<TokenT>::whitespace(TokenT &token, bool &skipped_newline) 
{
    using namespace boost::wave;

    token_id id = token_id(token);
    if (T_SPACE != id && T_SPACE2 != id && 
        T_CCOMMENT != id && T_CPPCOMMENT != id) 
    {
        return general(token, skipped_newline);
    }

    if (T_CCOMMENT == id) {
        if (util::ccomment_has_newline(token))
            skipped_newline = true;
        return !preserve_comments;
    }

    return T_SPACE == id || T_SPACE2 == id || skip_cppcomment(id);
}

///////////////////////////////////////////////////////////////////////////////
}   // namespace context_policies
}   // namespace wave
}   // namespace boost

// the suffix header occurs after all of the code
#ifdef BOOST_HAS_ABI_HEADERS
#include BOOST_ABI_SUFFIX
#endif

#endif // !defined(WHITESPACE_HANDLING_HPP_INCLUDED)

