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