Quick Start |
Preprocessing with Wave is highly configurable. You must define a few options to control it. Here are a few of the options you can define:
include search paths defining where to search for files to be included with #include <...> and #include "..." directives
which macros to predefine and which of the predefined macros to undefine
whether to enable any of several extensions to the C++ Standard (such as for variadics and placemarkers)
You can access all these processing parameters through the boost::wave::context object. So you must instantiate one object instance of this type to use the Wave library. (For more information about the context template class, please refer to the class reference here.) To instantiate the boost::wave::context object you have to supply at least two template parameters: the iterator type of the underlying input stream to use and the type of the lexer iterator to be used as the token source for the preprocessing engine.
Do not instantiate the main preprocessing iterators yourself. Get them from the boost::wave::context object instead. The following code snippet is taken from the quick_start sample, which shows a minimal usage scenario for Wave.
// The following preprocesses a given input file. // Open the file and read it into a string variable std::ifstream instream("input.cpp"); std::string input( 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. // This token type is one of the central types throughout // the library, because it is a template parameter to some // of the public classes and templates and it is returned // from the iterators. // The template boost::wave::cpplexer::lex_iterator<> is // the lexer iterator to use as the token source for the // preprocessing engine. In this case this is parameterized // with the token type. typedef boost::wave::cpplexer::lex_iterator< boost::wave::cpplexer::lex_token<> > lex_iterator_type; typedef boost::wave::context< std::string::iterator, lex_iterator_type> context_type; context_type ctx(input.begin(), input.end(), "input.cpp"); // At this point you may want to set the parameters of the // preprocessing as include paths and/or predefined macros. ctx.add_include_path("..."); ctx.add_macro_definition(...); // Get the preprocessor iterators and use them to generate // the token sequence. context_type::iterator_type first = ctx.begin(); context_type::iterator_type last = ctx.end(); // The input stream is preprocessed for you during iteration
// over [first, last)
while (first != last) { std::cout << (*first).get_value(); ++first; }
The constructor of the boost::wave::context object can take a pair of arbitrary iterator types (at least input_iterator type iterators) to the input stream, which must supply the data to be processed. The third parameter supplies a filename, which is reported in the preprocessor output to indicate the current context. Note though, that this filename is used only as long as no #include or #line directives are encountered, which in turn will alter the current reported filename.
The iteration over the preprocessed tokens is relatively straightforward. Just get the starting and the ending iterators from the context object (maybe after initializing some include search paths) and you are done! Dereferencing the iterator will return the preprocessed tokens generated on the fly from the input stream. (To get further information about the token type, you may want to look here.)
Copyright © 2003-2011 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)
Last updated: Tuesday, July 29, 2008 20:34