fix doc example typo
[boost.git] / boost / wave / whitespace_handling.hpp
blob9c2487b6f52bc0215c7f90819fb91e5af7e8c400
1 /*=============================================================================
2 Boost.Wave: A Standard compliant C++ preprocessor library
3 Whitespace eater
5 http://www.boost.org/
7 Copyright (c) 2003 Paul Mensonides
8 Copyright (c) 2001-2009 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 =============================================================================*/
13 #if !defined(WHITESPACE_HANDLING_HPP_INCLUDED)
14 #define WHITESPACE_HANDLING_HPP_INCLUDED
16 #include <boost/wave/wave_config.hpp>
17 #include <boost/wave/token_ids.hpp>
18 #include <boost/wave/preprocessing_hooks.hpp>
19 #include <boost/wave/language_support.hpp>
21 // this must occur after all of the includes and before any code appears
22 #ifdef BOOST_HAS_ABI_HEADERS
23 #include BOOST_ABI_PREFIX
24 #endif
26 ///////////////////////////////////////////////////////////////////////////////
27 namespace boost {
28 namespace wave {
29 namespace context_policies {
31 namespace util {
32 ///////////////////////////////////////////////////////////////////////////
33 // This function returns true if the given C style comment contains at
34 // least one newline
35 template <typename TokenT>
36 bool ccomment_has_newline(TokenT const& token)
38 using namespace boost::wave;
40 if (T_CCOMMENT == token_id(token) &&
41 TokenT::string_type::npos != token.get_value().find_first_of("\n"))
43 return true;
45 return false;
48 ///////////////////////////////////////////////////////////////////////////
49 // This function returns the number of newlines in the given C style
50 // comment
51 template <typename TokenT>
52 int ccomment_count_newlines(TokenT const& token)
54 using namespace boost::wave;
55 int newlines = 0;
56 if (T_CCOMMENT == token_id(token)) {
57 typename TokenT::string_type const& value = token.get_value();
58 typename TokenT::string_type::size_type p = value.find_first_of("\n");
60 while (TokenT::string_type::npos != p) {
61 ++newlines;
62 p = value.find_first_of("\n", p+1);
65 return newlines;
69 ///////////////////////////////////////////////////////////////////////////////
70 template <typename TokenT>
71 class eat_whitespace
72 : public default_preprocessing_hooks
74 public:
75 eat_whitespace();
77 template <typename ContextT>
78 bool may_skip_whitespace(ContextT const& ctx, TokenT &token,
79 bool &skipped_newline);
81 protected:
82 bool skip_cppcomment(boost::wave::token_id id)
84 return !preserve_comments && T_CPPCOMMENT == id;
87 private:
88 typedef bool state_t(TokenT &token, bool &skipped_newline);
89 state_t eat_whitespace::* state;
90 state_t general, newline, newline_2nd, whitespace;
91 bool preserve_comments;
94 template <typename TokenT>
95 inline
96 eat_whitespace<TokenT>::eat_whitespace()
97 : state(&eat_whitespace::newline), preserve_comments(false)
101 template <typename TokenT>
102 template <typename ContextT>
103 inline bool
104 eat_whitespace<TokenT>::may_skip_whitespace(ContextT const& ctx, TokenT &token,
105 bool &skipped_newline)
107 // re-initialize the preserve comments state
108 preserve_comments = boost::wave::need_preserve_comments(ctx.get_language());
109 return (this->*state)(token, skipped_newline);
112 template <typename TokenT>
113 inline bool
114 eat_whitespace<TokenT>::general(TokenT &token, bool &skipped_newline)
116 using namespace boost::wave;
118 token_id id = token_id(token);
119 if (T_NEWLINE == id || T_CPPCOMMENT == id) {
120 state = &eat_whitespace::newline;
122 else if (T_SPACE == id || T_SPACE2 == id || T_CCOMMENT == id) {
123 state = &eat_whitespace::whitespace;
125 if (util::ccomment_has_newline(token))
126 skipped_newline = true;
128 if ((!preserve_comments || T_CCOMMENT != id) &&
129 token.get_value().size() > 1)
131 token.set_value(" "); // replace with a single space
134 else {
135 state = &eat_whitespace::general;
137 return false;
140 template <typename TokenT>
141 inline bool
142 eat_whitespace<TokenT>::newline(TokenT &token, bool &skipped_newline)
144 using namespace boost::wave;
146 token_id id = token_id(token);
147 if (T_NEWLINE == id || T_CPPCOMMENT == id) {
148 skipped_newline = true;
149 state = &eat_whitespace::newline_2nd;
150 return T_NEWLINE == id || skip_cppcomment(id);
152 else if (T_SPACE != id && T_SPACE2 != id && T_CCOMMENT != id) {
153 return general(token, skipped_newline);
156 if (T_CCOMMENT == id) {
157 if (util::ccomment_has_newline(token)) {
158 skipped_newline = true;
159 state = &eat_whitespace::newline_2nd;
161 if (preserve_comments) {
162 state = &eat_whitespace::general;
163 return false;
165 // fall through...
167 return true;
170 template <typename TokenT>
171 inline bool
172 eat_whitespace<TokenT>::newline_2nd(TokenT &token, bool &skipped_newline)
174 using namespace boost::wave;
176 token_id id = token_id(token);
177 if (T_SPACE == id || T_SPACE2 == id)
178 return true;
179 if (T_CCOMMENT == id) {
180 if (util::ccomment_has_newline(token))
181 skipped_newline = true;
183 if (preserve_comments) {
184 state = &eat_whitespace::general;
185 return false;
187 return true;
189 if (T_NEWLINE != id && T_CPPCOMMENT != id)
190 return general(token, skipped_newline);
192 skipped_newline = true;
193 return T_NEWLINE == id || skip_cppcomment(id);
196 template <typename TokenT>
197 inline bool
198 eat_whitespace<TokenT>::whitespace(TokenT &token, bool &skipped_newline)
200 using namespace boost::wave;
202 token_id id = token_id(token);
203 if (T_SPACE != id && T_SPACE2 != id &&
204 T_CCOMMENT != id && T_CPPCOMMENT != id)
206 return general(token, skipped_newline);
209 if (T_CCOMMENT == id) {
210 if (util::ccomment_has_newline(token))
211 skipped_newline = true;
212 return !preserve_comments;
215 return T_SPACE == id || T_SPACE2 == id || skip_cppcomment(id);
218 ///////////////////////////////////////////////////////////////////////////////
219 } // namespace context_policies
220 } // namespace wave
221 } // namespace boost
223 // the suffix header occurs after all of the code
224 #ifdef BOOST_HAS_ABI_HEADERS
225 #include BOOST_ABI_SUFFIX
226 #endif
228 #endif // !defined(WHITESPACE_HANDLING_HPP_INCLUDED)