File indexing completed on 2025-01-30 10:02:23
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #if !defined(BOOST_WHITESPACE_HANDLING_HPP_INCLUDED)
0014 #define BOOST_WHITESPACE_HANDLING_HPP_INCLUDED
0015
0016 #include <boost/wave/wave_config.hpp>
0017 #include <boost/wave/token_ids.hpp>
0018 #include <boost/wave/preprocessing_hooks.hpp>
0019 #include <boost/wave/language_support.hpp>
0020
0021
0022 #ifdef BOOST_HAS_ABI_HEADERS
0023 #include BOOST_ABI_PREFIX
0024 #endif
0025
0026
0027 namespace boost {
0028 namespace wave {
0029 namespace context_policies {
0030
0031 namespace util {
0032
0033
0034
0035 template <typename TokenT>
0036 bool ccomment_has_newline(TokenT const& token)
0037 {
0038 using namespace boost::wave;
0039
0040 if (T_CCOMMENT == token_id(token) &&
0041 TokenT::string_type::npos != token.get_value().find_first_of("\n"))
0042 {
0043 return true;
0044 }
0045 return false;
0046 }
0047
0048
0049
0050
0051 template <typename TokenT>
0052 int ccomment_count_newlines(TokenT const& token)
0053 {
0054 using namespace boost::wave;
0055 int newlines = 0;
0056 if (T_CCOMMENT == token_id(token)) {
0057 typename TokenT::string_type const& value = token.get_value();
0058 typename TokenT::string_type::size_type p = value.find_first_of("\n");
0059
0060 while (TokenT::string_type::npos != p) {
0061 ++newlines;
0062 p = value.find_first_of("\n", p+1);
0063 }
0064 }
0065 return newlines;
0066 }
0067
0068 #if BOOST_WAVE_SUPPORT_CPP0X != 0
0069
0070
0071
0072 template <typename TokenT>
0073 int rawstring_count_newlines(TokenT const& token)
0074 {
0075 using namespace boost::wave;
0076 int newlines = 0;
0077 if (T_RAWSTRINGLIT == token_id(token)) {
0078 typename TokenT::string_type const& value = token.get_value();
0079 typename TokenT::string_type::size_type p = value.find_first_of("\n");
0080
0081 while (TokenT::string_type::npos != p) {
0082 ++newlines;
0083 p = value.find_first_of("\n", p+1);
0084 }
0085 }
0086 return newlines;
0087 }
0088 #endif
0089 }
0090
0091
0092 template <typename TokenT>
0093 class eat_whitespace
0094 : public default_preprocessing_hooks
0095 {
0096 public:
0097 eat_whitespace();
0098
0099 template <typename ContextT>
0100 bool may_skip_whitespace(ContextT const& ctx, TokenT &token,
0101 bool &skipped_newline);
0102 template <typename ContextT>
0103 bool may_skip_whitespace(ContextT const& ctx, TokenT &token,
0104 bool preserve_comments_, bool preserve_bol_whitespace_,
0105 bool &skipped_newline);
0106
0107 protected:
0108 bool skip_cppcomment(boost::wave::token_id id)
0109 {
0110 return !preserve_comments && T_CPPCOMMENT == id;
0111 }
0112
0113 private:
0114 typedef bool state_t(TokenT &token, bool &skipped_newline);
0115 state_t eat_whitespace::* state;
0116 state_t general, newline, newline_2nd, whitespace, bol_whitespace;
0117 bool preserve_comments;
0118 bool preserve_bol_whitespace;
0119 };
0120
0121 template <typename TokenT>
0122 inline
0123 eat_whitespace<TokenT>::eat_whitespace()
0124 : state(&eat_whitespace::newline), preserve_comments(false),
0125 preserve_bol_whitespace(false)
0126 {
0127 }
0128
0129 template <typename TokenT>
0130 template <typename ContextT>
0131 inline bool
0132 eat_whitespace<TokenT>::may_skip_whitespace(ContextT const& ctx, TokenT &token,
0133 bool &skipped_newline)
0134 {
0135
0136 preserve_comments = boost::wave::need_preserve_comments(ctx.get_language());
0137 return (this->*state)(token, skipped_newline);
0138 }
0139
0140 template <typename TokenT>
0141 template <typename ContextT>
0142 inline bool
0143 eat_whitespace<TokenT>::may_skip_whitespace(ContextT const& ctx, TokenT &token,
0144 bool preserve_comments_, bool preserve_bol_whitespace_,
0145 bool &skipped_newline)
0146 {
0147
0148 preserve_comments = preserve_comments_;
0149 preserve_bol_whitespace = preserve_bol_whitespace_;
0150 return (this->*state)(token, skipped_newline);
0151 }
0152
0153 template <typename TokenT>
0154 inline bool
0155 eat_whitespace<TokenT>::general(TokenT &token, bool &skipped_newline)
0156 {
0157 using namespace boost::wave;
0158
0159 token_id id = token_id(token);
0160 if (T_NEWLINE == id || T_CPPCOMMENT == id) {
0161 state = &eat_whitespace::newline;
0162 }
0163 else if (T_SPACE == id || T_SPACE2 == id || T_CCOMMENT == id) {
0164 state = &eat_whitespace::whitespace;
0165
0166 if (util::ccomment_has_newline(token))
0167 skipped_newline = true;
0168
0169 if ((!preserve_comments || T_CCOMMENT != id) &&
0170 token.get_value().size() > 1)
0171 {
0172 token.set_value(" ");
0173 }
0174 }
0175 else {
0176 state = &eat_whitespace::general;
0177 }
0178 return false;
0179 }
0180
0181 template <typename TokenT>
0182 inline bool
0183 eat_whitespace<TokenT>::newline(TokenT &token, bool &skipped_newline)
0184 {
0185 using namespace boost::wave;
0186
0187 token_id id = token_id(token);
0188 if (T_NEWLINE == id || T_CPPCOMMENT == id) {
0189 skipped_newline = true;
0190 state = &eat_whitespace::newline_2nd;
0191 return T_NEWLINE == id || skip_cppcomment(id);
0192 }
0193
0194 if (T_SPACE != id && T_SPACE2 != id && T_CCOMMENT != id)
0195 return general(token, skipped_newline);
0196
0197 if (T_CCOMMENT == id) {
0198 if (util::ccomment_has_newline(token)) {
0199 skipped_newline = true;
0200 state = &eat_whitespace::newline_2nd;
0201 }
0202 if (preserve_comments) {
0203 state = &eat_whitespace::general;
0204 return false;
0205 }
0206 return true;
0207 }
0208
0209 if (preserve_bol_whitespace) {
0210 state = &eat_whitespace::bol_whitespace;
0211 return false;
0212 }
0213
0214 return true;
0215 }
0216
0217 template <typename TokenT>
0218 inline bool
0219 eat_whitespace<TokenT>::newline_2nd(TokenT &token, bool &skipped_newline)
0220 {
0221 using namespace boost::wave;
0222
0223 token_id id = token_id(token);
0224 if (T_SPACE == id || T_SPACE2 == id) {
0225 if (preserve_bol_whitespace) {
0226 state = &eat_whitespace::bol_whitespace;
0227 return false;
0228 }
0229 return true;
0230 }
0231
0232 if (T_CCOMMENT == id) {
0233 if (util::ccomment_has_newline(token))
0234 skipped_newline = true;
0235
0236 if (preserve_comments) {
0237 state = &eat_whitespace::general;
0238 return false;
0239 }
0240 return true;
0241 }
0242
0243 if (T_NEWLINE != id && T_CPPCOMMENT != id)
0244 return general(token, skipped_newline);
0245
0246 skipped_newline = true;
0247 return T_NEWLINE == id || skip_cppcomment(id);
0248 }
0249
0250 template <typename TokenT>
0251 inline bool
0252 eat_whitespace<TokenT>::bol_whitespace(TokenT &token, bool &skipped_newline)
0253 {
0254 using namespace boost::wave;
0255
0256 token_id id = token_id(token);
0257 if (T_SPACE == id || T_SPACE2 == id)
0258 return !preserve_bol_whitespace;
0259
0260 return general(token, skipped_newline);
0261 }
0262
0263 template <typename TokenT>
0264 inline bool
0265 eat_whitespace<TokenT>::whitespace(TokenT &token, bool &skipped_newline)
0266 {
0267 using namespace boost::wave;
0268
0269 token_id id = token_id(token);
0270 if (T_SPACE != id && T_SPACE2 != id &&
0271 T_CCOMMENT != id && T_CPPCOMMENT != id)
0272 {
0273 return general(token, skipped_newline);
0274 }
0275
0276 if (T_CCOMMENT == id) {
0277 if (util::ccomment_has_newline(token))
0278 skipped_newline = true;
0279 return !preserve_comments;
0280 }
0281
0282 return T_SPACE == id || T_SPACE2 == id || skip_cppcomment(id);
0283 }
0284
0285
0286 }
0287 }
0288 }
0289
0290
0291 #ifdef BOOST_HAS_ABI_HEADERS
0292 #include BOOST_ABI_SUFFIX
0293 #endif
0294
0295 #endif
0296