os/ossrv/ossrv_pub/boost_apis/boost/wave/whitespace_handling.hpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
/*=============================================================================
sl@0
     2
    Boost.Wave: A Standard compliant C++ preprocessor library
sl@0
     3
    Whitespace eater
sl@0
     4
    
sl@0
     5
    http://www.boost.org/
sl@0
     6
sl@0
     7
    Copyright (c) 2003 Paul Mensonides
sl@0
     8
    Copyright (c) 2001-2007 Hartmut Kaiser. 
sl@0
     9
    Distributed under the Boost Software License, Version 1.0. (See accompanying 
sl@0
    10
    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
sl@0
    11
=============================================================================*/
sl@0
    12
sl@0
    13
#if !defined(WHITESPACE_HANDLING_HPP_INCLUDED)
sl@0
    14
#define WHITESPACE_HANDLING_HPP_INCLUDED
sl@0
    15
sl@0
    16
#include <boost/wave/wave_config.hpp>   
sl@0
    17
#include <boost/wave/token_ids.hpp>   
sl@0
    18
#include <boost/wave/preprocessing_hooks.hpp>
sl@0
    19
sl@0
    20
// this must occur after all of the includes and before any code appears
sl@0
    21
#ifdef BOOST_HAS_ABI_HEADERS
sl@0
    22
#include BOOST_ABI_PREFIX
sl@0
    23
#endif
sl@0
    24
sl@0
    25
///////////////////////////////////////////////////////////////////////////////
sl@0
    26
namespace boost {
sl@0
    27
namespace wave {
sl@0
    28
namespace context_policies {
sl@0
    29
sl@0
    30
namespace util {
sl@0
    31
    ///////////////////////////////////////////////////////////////////////////
sl@0
    32
    //  This function returns true if the given C style comment contains at 
sl@0
    33
    //  least one newline
sl@0
    34
    template <typename TokenT>
sl@0
    35
    bool ccomment_has_newline(TokenT const& token)
sl@0
    36
    {
sl@0
    37
        using namespace boost::wave;
sl@0
    38
sl@0
    39
        if (T_CCOMMENT == token_id(token) &&
sl@0
    40
            TokenT::string_type::npos != token.get_value().find_first_of("\n"))
sl@0
    41
        {
sl@0
    42
            return true;
sl@0
    43
        }
sl@0
    44
        return false;
sl@0
    45
    }
sl@0
    46
sl@0
    47
    ///////////////////////////////////////////////////////////////////////////
sl@0
    48
    //  This function returns the number of newlines in the given C style 
sl@0
    49
    //  comment 
sl@0
    50
    template <typename TokenT>
sl@0
    51
    int ccomment_count_newlines(TokenT const& token)
sl@0
    52
    {
sl@0
    53
        using namespace boost::wave;
sl@0
    54
        int newlines = 0;
sl@0
    55
        if (T_CCOMMENT == token_id(token)) {
sl@0
    56
        typename TokenT::string_type const& value = token.get_value();
sl@0
    57
        typename TokenT::string_type::size_type p = value.find_first_of("\n");
sl@0
    58
sl@0
    59
            while (TokenT::string_type::npos != p) {
sl@0
    60
                ++newlines;
sl@0
    61
                p = value.find_first_of("\n", p+1);
sl@0
    62
            } 
sl@0
    63
        }
sl@0
    64
        return newlines;
sl@0
    65
    }
sl@0
    66
}
sl@0
    67
sl@0
    68
///////////////////////////////////////////////////////////////////////////////
sl@0
    69
template <typename TokenT>
sl@0
    70
class eat_whitespace 
sl@0
    71
:   public default_preprocessing_hooks
sl@0
    72
{
sl@0
    73
public:
sl@0
    74
    eat_whitespace();
sl@0
    75
    
sl@0
    76
    template <typename ContextT>
sl@0
    77
    bool may_skip_whitespace(ContextT const& ctx, TokenT &token, 
sl@0
    78
        bool &skipped_newline);
sl@0
    79
sl@0
    80
protected:
sl@0
    81
    bool skip_cppcomment(boost::wave::token_id id)
sl@0
    82
    {
sl@0
    83
        return !preserve_comments && T_CPPCOMMENT == id;
sl@0
    84
    }
sl@0
    85
    
sl@0
    86
private:
sl@0
    87
    typedef bool state_t(TokenT &token, bool &skipped_newline);
sl@0
    88
    state_t eat_whitespace::* state;
sl@0
    89
    state_t general, newline, newline_2nd, whitespace;
sl@0
    90
    bool preserve_comments;
sl@0
    91
};
sl@0
    92
sl@0
    93
template <typename TokenT>
sl@0
    94
inline 
sl@0
    95
eat_whitespace<TokenT>::eat_whitespace()
sl@0
    96
:   state(&eat_whitespace::newline), preserve_comments(false)
sl@0
    97
{
sl@0
    98
}
sl@0
    99
sl@0
   100
template <typename TokenT>
sl@0
   101
template <typename ContextT>
sl@0
   102
inline bool 
sl@0
   103
eat_whitespace<TokenT>::may_skip_whitespace(ContextT const& ctx, TokenT &token, 
sl@0
   104
    bool &skipped_newline) 
sl@0
   105
{
sl@0
   106
    // re-initialize the preserve comments state
sl@0
   107
    preserve_comments = boost::wave::need_preserve_comments(ctx.get_language());
sl@0
   108
    return (this->*state)(token, skipped_newline);
sl@0
   109
}
sl@0
   110
sl@0
   111
template <typename TokenT>
sl@0
   112
inline bool 
sl@0
   113
eat_whitespace<TokenT>::general(TokenT &token, bool &skipped_newline) 
sl@0
   114
{
sl@0
   115
    using namespace boost::wave;
sl@0
   116
sl@0
   117
    token_id id = token_id(token);
sl@0
   118
    if (T_NEWLINE == id || T_CPPCOMMENT == id) {
sl@0
   119
        state = &eat_whitespace::newline;
sl@0
   120
    }
sl@0
   121
    else if (T_SPACE == id || T_SPACE2 == id || T_CCOMMENT == id) {
sl@0
   122
        state = &eat_whitespace::whitespace;
sl@0
   123
sl@0
   124
        if (util::ccomment_has_newline(token)) 
sl@0
   125
            skipped_newline = true;
sl@0
   126
sl@0
   127
        if ((!preserve_comments || T_CCOMMENT != id) && 
sl@0
   128
            token.get_value().size() > 1)
sl@0
   129
        {
sl@0
   130
            token.set_value(" ");   // replace with a single space
sl@0
   131
        }
sl@0
   132
    }
sl@0
   133
    else {
sl@0
   134
        state = &eat_whitespace::general;
sl@0
   135
    }
sl@0
   136
    return false;
sl@0
   137
}
sl@0
   138
sl@0
   139
template <typename TokenT>
sl@0
   140
inline bool 
sl@0
   141
eat_whitespace<TokenT>::newline(TokenT &token, bool &skipped_newline) 
sl@0
   142
{
sl@0
   143
    using namespace boost::wave;
sl@0
   144
    
sl@0
   145
    token_id id = token_id(token);
sl@0
   146
    if (T_NEWLINE == id || T_CPPCOMMENT == id) {
sl@0
   147
        skipped_newline = true;
sl@0
   148
        state = &eat_whitespace::newline_2nd;
sl@0
   149
        return T_NEWLINE == id || skip_cppcomment(id);
sl@0
   150
    }
sl@0
   151
    else if (T_SPACE != id && T_SPACE2 != id && T_CCOMMENT != id) {
sl@0
   152
        return general(token, skipped_newline);
sl@0
   153
    }
sl@0
   154
sl@0
   155
    if (T_CCOMMENT == id) {
sl@0
   156
        if (util::ccomment_has_newline(token)) {
sl@0
   157
            skipped_newline = true;
sl@0
   158
            state = &eat_whitespace::newline_2nd;
sl@0
   159
        }
sl@0
   160
        if (preserve_comments) {
sl@0
   161
            state = &eat_whitespace::general;
sl@0
   162
            return false;
sl@0
   163
        }
sl@0
   164
        // fall through...
sl@0
   165
    }
sl@0
   166
    return true;
sl@0
   167
}
sl@0
   168
sl@0
   169
template <typename TokenT>
sl@0
   170
inline bool 
sl@0
   171
eat_whitespace<TokenT>::newline_2nd(TokenT &token, bool &skipped_newline) 
sl@0
   172
{
sl@0
   173
    using namespace boost::wave;
sl@0
   174
    
sl@0
   175
    token_id id = token_id(token);
sl@0
   176
    if (T_SPACE == id || T_SPACE2 == id)
sl@0
   177
        return true;
sl@0
   178
    if (T_CCOMMENT == id) {
sl@0
   179
        if (util::ccomment_has_newline(token))
sl@0
   180
            skipped_newline = true;
sl@0
   181
sl@0
   182
        if (preserve_comments) {
sl@0
   183
            state = &eat_whitespace::general;
sl@0
   184
            return false;
sl@0
   185
        }
sl@0
   186
        return  true;
sl@0
   187
    }
sl@0
   188
    if (T_NEWLINE != id && T_CPPCOMMENT != id) 
sl@0
   189
        return general(token, skipped_newline);
sl@0
   190
sl@0
   191
    skipped_newline = true;
sl@0
   192
    return T_NEWLINE == id || skip_cppcomment(id);
sl@0
   193
}
sl@0
   194
sl@0
   195
template <typename TokenT>
sl@0
   196
inline bool 
sl@0
   197
eat_whitespace<TokenT>::whitespace(TokenT &token, bool &skipped_newline) 
sl@0
   198
{
sl@0
   199
    using namespace boost::wave;
sl@0
   200
    
sl@0
   201
    token_id id = token_id(token);
sl@0
   202
    if (T_SPACE != id && T_SPACE2 != id && 
sl@0
   203
        T_CCOMMENT != id && T_CPPCOMMENT != id) 
sl@0
   204
    {
sl@0
   205
        return general(token, skipped_newline);
sl@0
   206
    }
sl@0
   207
    
sl@0
   208
    if (T_CCOMMENT == id) {
sl@0
   209
        if (util::ccomment_has_newline(token))
sl@0
   210
            skipped_newline = true;
sl@0
   211
        return !preserve_comments;
sl@0
   212
    }
sl@0
   213
sl@0
   214
    return T_SPACE == id || T_SPACE2 == id || skip_cppcomment(id);
sl@0
   215
}
sl@0
   216
sl@0
   217
///////////////////////////////////////////////////////////////////////////////
sl@0
   218
}   // namespace context_policies
sl@0
   219
}   // namespace wave
sl@0
   220
}   // namespace boost
sl@0
   221
sl@0
   222
// the suffix header occurs after all of the code
sl@0
   223
#ifdef BOOST_HAS_ABI_HEADERS
sl@0
   224
#include BOOST_ABI_SUFFIX
sl@0
   225
#endif
sl@0
   226
sl@0
   227
#endif // !defined(WHITESPACE_HANDLING_HPP_INCLUDED)
sl@0
   228