|
Packit |
58578d |
/*=============================================================================
|
|
Packit |
58578d |
Boost.Wave: A Standard compliant C++ preprocessor library
|
|
Packit |
58578d |
Whitespace eater
|
|
Packit |
58578d |
|
|
Packit |
58578d |
http://www.boost.org/
|
|
Packit |
58578d |
|
|
Packit |
58578d |
Copyright (c) 2003 Paul Mensonides
|
|
Packit |
58578d |
Copyright (c) 2001-2012 Hartmut Kaiser.
|
|
Packit |
58578d |
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
Packit |
58578d |
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
Packit |
58578d |
=============================================================================*/
|
|
Packit |
58578d |
|
|
Packit |
58578d |
#if !defined(WHITESPACE_HANDLING_HPP_INCLUDED)
|
|
Packit |
58578d |
#define WHITESPACE_HANDLING_HPP_INCLUDED
|
|
Packit |
58578d |
|
|
Packit |
58578d |
#include <boost/wave/wave_config.hpp>
|
|
Packit |
58578d |
#include <boost/wave/token_ids.hpp>
|
|
Packit |
58578d |
#include <boost/wave/preprocessing_hooks.hpp>
|
|
Packit |
58578d |
#include <boost/wave/language_support.hpp>
|
|
Packit |
58578d |
|
|
Packit |
58578d |
// this must occur after all of the includes and before any code appears
|
|
Packit |
58578d |
#ifdef BOOST_HAS_ABI_HEADERS
|
|
Packit |
58578d |
#include BOOST_ABI_PREFIX
|
|
Packit |
58578d |
#endif
|
|
Packit |
58578d |
|
|
Packit |
58578d |
///////////////////////////////////////////////////////////////////////////////
|
|
Packit |
58578d |
namespace boost {
|
|
Packit |
58578d |
namespace wave {
|
|
Packit |
58578d |
namespace context_policies {
|
|
Packit |
58578d |
|
|
Packit |
58578d |
namespace util {
|
|
Packit |
58578d |
///////////////////////////////////////////////////////////////////////////
|
|
Packit |
58578d |
// This function returns true if the given C style comment contains at
|
|
Packit |
58578d |
// least one newline
|
|
Packit |
58578d |
template <typename TokenT>
|
|
Packit |
58578d |
bool ccomment_has_newline(TokenT const& token)
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
using namespace boost::wave;
|
|
Packit |
58578d |
|
|
Packit |
58578d |
if (T_CCOMMENT == token_id(token) &&
|
|
Packit |
58578d |
TokenT::string_type::npos != token.get_value().find_first_of("\n"))
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
return true;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
return false;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
///////////////////////////////////////////////////////////////////////////
|
|
Packit |
58578d |
// This function returns the number of newlines in the given C style
|
|
Packit |
58578d |
// comment
|
|
Packit |
58578d |
template <typename TokenT>
|
|
Packit |
58578d |
int ccomment_count_newlines(TokenT const& token)
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
using namespace boost::wave;
|
|
Packit |
58578d |
int newlines = 0;
|
|
Packit |
58578d |
if (T_CCOMMENT == token_id(token)) {
|
|
Packit |
58578d |
typename TokenT::string_type const& value = token.get_value();
|
|
Packit |
58578d |
typename TokenT::string_type::size_type p = value.find_first_of("\n");
|
|
Packit |
58578d |
|
|
Packit |
58578d |
while (TokenT::string_type::npos != p) {
|
|
Packit |
58578d |
++newlines;
|
|
Packit |
58578d |
p = value.find_first_of("\n", p+1);
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
return newlines;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
#if BOOST_WAVE_SUPPORT_CPP0X != 0
|
|
Packit |
58578d |
///////////////////////////////////////////////////////////////////////////
|
|
Packit |
58578d |
// This function returns the number of newlines in the given C++11 style
|
|
Packit |
58578d |
// raw string
|
|
Packit |
58578d |
template <typename TokenT>
|
|
Packit |
58578d |
int rawstring_count_newlines(TokenT const& token)
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
using namespace boost::wave;
|
|
Packit |
58578d |
int newlines = 0;
|
|
Packit |
58578d |
if (T_RAWSTRINGLIT == token_id(token)) {
|
|
Packit |
58578d |
typename TokenT::string_type const& value = token.get_value();
|
|
Packit |
58578d |
typename TokenT::string_type::size_type p = value.find_first_of("\n");
|
|
Packit |
58578d |
|
|
Packit |
58578d |
while (TokenT::string_type::npos != p) {
|
|
Packit |
58578d |
++newlines;
|
|
Packit |
58578d |
p = value.find_first_of("\n", p+1);
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
return newlines;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
#endif
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
///////////////////////////////////////////////////////////////////////////////
|
|
Packit |
58578d |
template <typename TokenT>
|
|
Packit |
58578d |
class eat_whitespace
|
|
Packit |
58578d |
: public default_preprocessing_hooks
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
public:
|
|
Packit |
58578d |
eat_whitespace();
|
|
Packit |
58578d |
|
|
Packit |
58578d |
template <typename ContextT>
|
|
Packit |
58578d |
bool may_skip_whitespace(ContextT const& ctx, TokenT &token,
|
|
Packit |
58578d |
bool &skipped_newline);
|
|
Packit |
58578d |
template <typename ContextT>
|
|
Packit |
58578d |
bool may_skip_whitespace(ContextT const& ctx, TokenT &token,
|
|
Packit |
58578d |
bool preserve_comments_, bool preserve_bol_whitespace_,
|
|
Packit |
58578d |
bool &skipped_newline);
|
|
Packit |
58578d |
|
|
Packit |
58578d |
protected:
|
|
Packit |
58578d |
bool skip_cppcomment(boost::wave::token_id id)
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
return !preserve_comments && T_CPPCOMMENT == id;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
private:
|
|
Packit |
58578d |
typedef bool state_t(TokenT &token, bool &skipped_newline);
|
|
Packit |
58578d |
state_t eat_whitespace::* state;
|
|
Packit |
58578d |
state_t general, newline, newline_2nd, whitespace, bol_whitespace;
|
|
Packit |
58578d |
bool preserve_comments;
|
|
Packit |
58578d |
bool preserve_bol_whitespace;
|
|
Packit |
58578d |
};
|
|
Packit |
58578d |
|
|
Packit |
58578d |
template <typename TokenT>
|
|
Packit |
58578d |
inline
|
|
Packit |
58578d |
eat_whitespace<TokenT>::eat_whitespace()
|
|
Packit |
58578d |
: state(&eat_whitespace::newline), preserve_comments(false),
|
|
Packit |
58578d |
preserve_bol_whitespace(false)
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
template <typename TokenT>
|
|
Packit |
58578d |
template <typename ContextT>
|
|
Packit |
58578d |
inline bool
|
|
Packit |
58578d |
eat_whitespace<TokenT>::may_skip_whitespace(ContextT const& ctx, TokenT &token,
|
|
Packit |
58578d |
bool &skipped_newline)
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
// re-initialize the preserve comments state
|
|
Packit |
58578d |
preserve_comments = boost::wave::need_preserve_comments(ctx.get_language());
|
|
Packit |
58578d |
return (this->*state)(token, skipped_newline);
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
template <typename TokenT>
|
|
Packit |
58578d |
template <typename ContextT>
|
|
Packit |
58578d |
inline bool
|
|
Packit |
58578d |
eat_whitespace<TokenT>::may_skip_whitespace(ContextT const& ctx, TokenT &token,
|
|
Packit |
58578d |
bool preserve_comments_, bool preserve_bol_whitespace_,
|
|
Packit |
58578d |
bool &skipped_newline)
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
// re-initialize the preserve comments state
|
|
Packit |
58578d |
preserve_comments = preserve_comments_;
|
|
Packit |
58578d |
preserve_bol_whitespace = preserve_bol_whitespace_;
|
|
Packit |
58578d |
return (this->*state)(token, skipped_newline);
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
template <typename TokenT>
|
|
Packit |
58578d |
inline bool
|
|
Packit |
58578d |
eat_whitespace<TokenT>::general(TokenT &token, bool &skipped_newline)
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
using namespace boost::wave;
|
|
Packit |
58578d |
|
|
Packit |
58578d |
token_id id = token_id(token);
|
|
Packit |
58578d |
if (T_NEWLINE == id || T_CPPCOMMENT == id) {
|
|
Packit |
58578d |
state = &eat_whitespace::newline;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
else if (T_SPACE == id || T_SPACE2 == id || T_CCOMMENT == id) {
|
|
Packit |
58578d |
state = &eat_whitespace::whitespace;
|
|
Packit |
58578d |
|
|
Packit |
58578d |
if (util::ccomment_has_newline(token))
|
|
Packit |
58578d |
skipped_newline = true;
|
|
Packit |
58578d |
|
|
Packit |
58578d |
if ((!preserve_comments || T_CCOMMENT != id) &&
|
|
Packit |
58578d |
token.get_value().size() > 1)
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
token.set_value(" "); // replace with a single space
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
else {
|
|
Packit |
58578d |
state = &eat_whitespace::general;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
return false;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
template <typename TokenT>
|
|
Packit |
58578d |
inline bool
|
|
Packit |
58578d |
eat_whitespace<TokenT>::newline(TokenT &token, bool &skipped_newline)
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
using namespace boost::wave;
|
|
Packit |
58578d |
|
|
Packit |
58578d |
token_id id = token_id(token);
|
|
Packit |
58578d |
if (T_NEWLINE == id || T_CPPCOMMENT == id) {
|
|
Packit |
58578d |
skipped_newline = true;
|
|
Packit |
58578d |
state = &eat_whitespace::newline_2nd;
|
|
Packit |
58578d |
return T_NEWLINE == id || skip_cppcomment(id);
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
if (T_SPACE != id && T_SPACE2 != id && T_CCOMMENT != id)
|
|
Packit |
58578d |
return general(token, skipped_newline);
|
|
Packit |
58578d |
|
|
Packit |
58578d |
if (T_CCOMMENT == id) {
|
|
Packit |
58578d |
if (util::ccomment_has_newline(token)) {
|
|
Packit |
58578d |
skipped_newline = true;
|
|
Packit |
58578d |
state = &eat_whitespace::newline_2nd;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
if (preserve_comments) {
|
|
Packit |
58578d |
state = &eat_whitespace::general;
|
|
Packit |
58578d |
return false;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
return true;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
if (preserve_bol_whitespace) {
|
|
Packit |
58578d |
state = &eat_whitespace::bol_whitespace;
|
|
Packit |
58578d |
return false;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
return true;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
template <typename TokenT>
|
|
Packit |
58578d |
inline bool
|
|
Packit |
58578d |
eat_whitespace<TokenT>::newline_2nd(TokenT &token, bool &skipped_newline)
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
using namespace boost::wave;
|
|
Packit |
58578d |
|
|
Packit |
58578d |
token_id id = token_id(token);
|
|
Packit |
58578d |
if (T_SPACE == id || T_SPACE2 == id) {
|
|
Packit |
58578d |
if (preserve_bol_whitespace) {
|
|
Packit |
58578d |
state = &eat_whitespace::bol_whitespace;
|
|
Packit |
58578d |
return false;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
return true;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
if (T_CCOMMENT == id) {
|
|
Packit |
58578d |
if (util::ccomment_has_newline(token))
|
|
Packit |
58578d |
skipped_newline = true;
|
|
Packit |
58578d |
|
|
Packit |
58578d |
if (preserve_comments) {
|
|
Packit |
58578d |
state = &eat_whitespace::general;
|
|
Packit |
58578d |
return false;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
return true;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
if (T_NEWLINE != id && T_CPPCOMMENT != id)
|
|
Packit |
58578d |
return general(token, skipped_newline);
|
|
Packit |
58578d |
|
|
Packit |
58578d |
skipped_newline = true;
|
|
Packit |
58578d |
return T_NEWLINE == id || skip_cppcomment(id);
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
template <typename TokenT>
|
|
Packit |
58578d |
inline bool
|
|
Packit |
58578d |
eat_whitespace<TokenT>::bol_whitespace(TokenT &token, bool &skipped_newline)
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
using namespace boost::wave;
|
|
Packit |
58578d |
|
|
Packit |
58578d |
token_id id = token_id(token);
|
|
Packit |
58578d |
if (T_SPACE == id || T_SPACE2 == id)
|
|
Packit |
58578d |
return !preserve_bol_whitespace;
|
|
Packit |
58578d |
|
|
Packit |
58578d |
return general(token, skipped_newline);
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
template <typename TokenT>
|
|
Packit |
58578d |
inline bool
|
|
Packit |
58578d |
eat_whitespace<TokenT>::whitespace(TokenT &token, bool &skipped_newline)
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
using namespace boost::wave;
|
|
Packit |
58578d |
|
|
Packit |
58578d |
token_id id = token_id(token);
|
|
Packit |
58578d |
if (T_SPACE != id && T_SPACE2 != id &&
|
|
Packit |
58578d |
T_CCOMMENT != id && T_CPPCOMMENT != id)
|
|
Packit |
58578d |
{
|
|
Packit |
58578d |
return general(token, skipped_newline);
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
if (T_CCOMMENT == id) {
|
|
Packit |
58578d |
if (util::ccomment_has_newline(token))
|
|
Packit |
58578d |
skipped_newline = true;
|
|
Packit |
58578d |
return !preserve_comments;
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
return T_SPACE == id || T_SPACE2 == id || skip_cppcomment(id);
|
|
Packit |
58578d |
}
|
|
Packit |
58578d |
|
|
Packit |
58578d |
///////////////////////////////////////////////////////////////////////////////
|
|
Packit |
58578d |
} // namespace context_policies
|
|
Packit |
58578d |
} // namespace wave
|
|
Packit |
58578d |
} // namespace boost
|
|
Packit |
58578d |
|
|
Packit |
58578d |
// the suffix header occurs after all of the code
|
|
Packit |
58578d |
#ifdef BOOST_HAS_ABI_HEADERS
|
|
Packit |
58578d |
#include BOOST_ABI_SUFFIX
|
|
Packit |
58578d |
#endif
|
|
Packit |
58578d |
|
|
Packit |
58578d |
#endif // !defined(WHITESPACE_HANDLING_HPP_INCLUDED)
|
|
Packit |
58578d |
|