diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 18:24:20 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 18:24:20 +0000 |
commit | 483eb2f56657e8e7f419ab1a4fab8dce9ade8609 (patch) | |
tree | e5d88d25d870d5dedacb6bbdbe2a966086a0a5cf /src/boost/libs/wave/samples/advanced_hooks | |
parent | Initial commit. (diff) | |
download | ceph-upstream.tar.xz ceph-upstream.zip |
Adding upstream version 14.2.21.upstream/14.2.21upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/boost/libs/wave/samples/advanced_hooks')
3 files changed, 308 insertions, 0 deletions
diff --git a/src/boost/libs/wave/samples/advanced_hooks/advanced_hooks.cpp b/src/boost/libs/wave/samples/advanced_hooks/advanced_hooks.cpp new file mode 100644 index 00000000..37fdbef2 --- /dev/null +++ b/src/boost/libs/wave/samples/advanced_hooks/advanced_hooks.cpp @@ -0,0 +1,124 @@ +/*============================================================================= + Boost.Wave: A Standard compliant C++ preprocessor library + Sample demonstrating the usage of advanced preprocessor hooks. + + http://www.boost.org/ + + Copyright (c) 2001-2010 Hartmut Kaiser. Distributed under the Boost + Software License, Version 1.0. (See accompanying file + LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ + +#include <iostream> +#include <fstream> +#include <string> +#include <vector> + +/////////////////////////////////////////////////////////////////////////////// +// Include Wave itself +#include <boost/wave.hpp> + +/////////////////////////////////////////////////////////////////////////////// +// Include the lexer stuff +#include <boost/wave/cpplexer/cpp_lex_token.hpp> // token class +#include <boost/wave/cpplexer/cpp_lex_iterator.hpp> // lexer class + +#include "advanced_hooks.hpp" + +/////////////////////////////////////////////////////////////////////////////// +// Main entry point +// +// This sample shows how to use the advanced hooks to output not only the +// preprocessed tokens but also the conditional directives found in the input +// file (these are commented out, tough) and the tokens from inside the +// conditional block which were not evaluated because the corresponding +// condition was false. These tokens are commented out as well. +// +int main(int argc, char *argv[]) +{ + if (2 != argc) { + std::cerr << "Usage: advanced_hooks infile" << std::endl; + return -1; + } + +// current file position is saved for exception handling +boost::wave::util::file_position_type current_position; + + try { + // Open and read in the specified input file. + std::ifstream instream(argv[1]); + std::string instring; + + if (!instream.is_open()) { + std::cerr << "Could not open input file: " << argv[1] << std::endl; + return -2; + } + instream.unsetf(std::ios::skipws); + instring = std::string(std::istreambuf_iterator<char>(instream.rdbuf()), + std::istreambuf_iterator<char>()); + + // The template boost::wave::cpplexer::lex_token<> is the token type to be + // used by the Wave library. + typedef boost::wave::cpplexer::lex_token<> token_type; + + // The template boost::wave::cpplexer::lex_iterator<> is the lexer type to + // be used by the Wave library. + typedef boost::wave::cpplexer::lex_iterator<token_type> lex_iterator_type; + + // This is the resulting context type to use. The first template parameter + // should match the iterator type to be used during construction of the + // corresponding context object (see below). + typedef boost::wave::context<std::string::iterator, lex_iterator_type, + boost::wave::iteration_context_policies::load_file_to_string, + advanced_preprocessing_hooks + > context_type; + + // The preprocessor iterator shouldn't be constructed directly. It is + // to be generated through a wave::context<> object. This wave:context<> + // object additionally may be used to initialize and define different + // parameters of the actual preprocessing (not done here). + // + // The preprocessing of the input stream is done on the fly behind the + // scenes during iteration over the context_type::iterator_type stream. + context_type ctx (instring.begin(), instring.end(), argv[1]); + + ctx.set_language(boost::wave::enable_long_long(ctx.get_language())); + ctx.set_language(boost::wave::enable_preserve_comments(ctx.get_language())); + ctx.set_language(boost::wave::enable_prefer_pp_numbers(ctx.get_language())); + + // analyze the input file, print out the preprocessed tokens + context_type::iterator_type first = ctx.begin(); + context_type::iterator_type last = ctx.end(); + + while (first != last) { + current_position = (*first).get_position(); + std::cout << (*first).get_value(); + ++first; + } + } + catch (boost::wave::cpp_exception const& e) { + // some preprocessing error + std::cerr + << e.file_name() << "(" << e.line_no() << "): " + << e.description() << std::endl; + return 2; + } + catch (std::exception const& e) { + // use last recognized token to retrieve the error position + std::cerr + << current_position.get_file() + << "(" << current_position.get_line() << "): " + << "exception caught: " << e.what() + << std::endl; + return 3; + } + catch (...) { + // use last recognized token to retrieve the error position + std::cerr + << current_position.get_file() + << "(" << current_position.get_line() << "): " + << "unexpected exception caught." << std::endl; + return 4; + } + return 0; +} diff --git a/src/boost/libs/wave/samples/advanced_hooks/advanced_hooks.hpp b/src/boost/libs/wave/samples/advanced_hooks/advanced_hooks.hpp new file mode 100644 index 00000000..c779c0a0 --- /dev/null +++ b/src/boost/libs/wave/samples/advanced_hooks/advanced_hooks.hpp @@ -0,0 +1,167 @@ +/*============================================================================= + Boost.Wave: A Standard compliant C++ preprocessor library + http://www.boost.org/ + + Copyright (c) 2001-2010 Hartmut Kaiser. Distributed under the Boost + Software License, Version 1.0. (See accompanying file + LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ + +#if !defined(BOOST_WAVE_ADVANCED_PREPROCESSING_HOOKS_INCLUDED) +#define BOOST_WAVE_ADVANCED_PREPROCESSING_HOOKS_INCLUDED + +#include <cstdio> +#include <ostream> +#include <string> + +#include <boost/assert.hpp> +#include <boost/config.hpp> + +#include <boost/wave/token_ids.hpp> +#include <boost/wave/util/macro_helpers.hpp> +#include <boost/wave/preprocessing_hooks.hpp> + +/////////////////////////////////////////////////////////////////////////////// +// +// The advanced_preprocessing_hooks policy class is used to register some +// of the more advanced (and probably more rarely used hooks with the Wave +// library. +// +// This policy type is used as a template parameter to the boost::wave::context<> +// object. +// +/////////////////////////////////////////////////////////////////////////////// +class advanced_preprocessing_hooks +: public boost::wave::context_policies::default_preprocessing_hooks +{ +public: + advanced_preprocessing_hooks() : need_comment(true) {} + + /////////////////////////////////////////////////////////////////////////// + // + // The function 'found_directive' is called, whenever a preprocessor + // directive was encountered, but before the corresponding action is + // executed. + // + // The parameter 'ctx' is a reference to the context object used for + // instantiating the preprocessing iterators by the user. + // + // The parameter 'directive' is a reference to the token holding the + // preprocessing directive. + // + /////////////////////////////////////////////////////////////////////////// +#if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS != 0 + template <typename TokenT> + void + found_directive(TokenT const& directive) +#else + template <typename ContextT, typename TokenT> + bool + found_directive(ContextT const& ctx, TokenT const& directive) +#endif + { + // print the commented conditional directives + using namespace boost::wave; + token_id id = token_id(directive); + switch (id) { + case T_PP_IFDEF: + case T_PP_IFNDEF: + case T_PP_IF: + case T_PP_ELIF: + std::cout << "// " << directive.get_value() << " "; + need_comment = false; + break; + + case T_PP_ELSE: + case T_PP_ENDIF: + std::cout << "// " << directive.get_value() << std::endl; + need_comment = true; + break; + + default: + break; + } + +#if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS == 0 + return false; +#endif + } + + /////////////////////////////////////////////////////////////////////////// + // + // The function 'evaluated_conditional_expression' is called, whenever a + // conditional preprocessing expression was evaluated (the expression + // given to a #if, #elif, #ifdef or #ifndef directive) + // + // The parameter 'ctx' is a reference to the context object used for + // instantiating the preprocessing iterators by the user. + // + // The parameter 'expression' holds the non-expanded token sequence + // comprising the evaluated expression. + // + // The parameter expression_value contains the result of the evaluation of + // the expression in the current preprocessing context. + // + // The return value defines, whether the given expression has to be + // evaluated again, allowing to decide which of the conditional branches + // should be expanded. You need to return 'true' from this hook function + // to force the expression to be re-evaluated. + // + /////////////////////////////////////////////////////////////////////////// +#if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS != 0 + template <typename ContainerT> + bool + evaluated_conditional_expression( + ContainerT const& expression, bool expression_value) +#else + template <typename ContextT, typename TokenT, typename ContainerT> + bool + evaluated_conditional_expression(ContextT const &ctx, + TokenT const& directive, ContainerT const& expression, + bool expression_value) +#endif + { + // print the conditional expressions + std::cout << boost::wave::util::impl::as_string(expression) << std::endl; + need_comment = true; + return false; // ok to continue, do not re-evaluate expression + } + + /////////////////////////////////////////////////////////////////////////// + // + // The function 'skipped_token' is called, whenever a token is about to be + // skipped due to a false preprocessor condition (code fragments to be + // skipped inside the not evaluated conditional #if/#else/#endif branches). + // + // The parameter 'ctx' is a reference to the context object used for + // instantiating the preprocessing iterators by the user. + // + // The parameter 'token' refers to the token to be skipped. + // + /////////////////////////////////////////////////////////////////////////// +#if BOOST_WAVE_USE_DEPRECIATED_PREPROCESSING_HOOKS != 0 + template <typename TokenT> + void + skipped_token(TokenT const& token) +#else + template <typename ContextT, typename TokenT> + void + skipped_token(ContextT const& ctx, TokenT const& token) +#endif + { + // prepend a comment at the beginning of all skipped lines + using namespace boost::wave; + if (need_comment && token_id(token) != T_SPACE) { + std::cout << "// "; + need_comment = false; + } + std::cout << token.get_value(); + if (token_id(token) == T_NEWLINE || token_id(token) == T_CPPCOMMENT) + need_comment = true; + } + +private: + bool need_comment; +}; + +#endif // !defined(BOOST_WAVE_ADVANCED_PREPROCESSING_HOOKS_INCLUDED) diff --git a/src/boost/libs/wave/samples/advanced_hooks/build/Jamfile.v2 b/src/boost/libs/wave/samples/advanced_hooks/build/Jamfile.v2 new file mode 100644 index 00000000..aa0204b2 --- /dev/null +++ b/src/boost/libs/wave/samples/advanced_hooks/build/Jamfile.v2 @@ -0,0 +1,17 @@ +# Boost.Wave: A Standard compliant C++ preprocessor library +# +# Boost Wave Library Sample Build Jamfile (advanced_hooks) +# +# http://www.boost.org/ +# +# Copyright (c) 2001-2010 Hartmut Kaiser. Distributed under the Boost +# Software License, Version 1.0. (See accompanying file +# LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +exe advanced_hooks + : ../advanced_hooks.cpp + /boost/wave//boost_wave + /boost/thread//boost_thread + /boost/date_time//boost_date_time + ; + |