(Originated from this question.)
I unsuccesfully tried to make use of this example.
My attempt was to copy and slighly edit the code at the link. The result is this (I leave the comment from Boost website to make comparing my edits with the original easier):
#include <boost/wave.hpp>
#include <boost/wave/cpplexer/cpp_lex_iterator.hpp>
int main() {
// The following preprocesses a given input file.
// Open the file and read it into a string variable
std::string input("int main() { std::cout << \"Hello world\"; }");
// 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(), "preproc.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;
}
}
I can successfully compile with
g++ -std=c++17 -lboost_thread -lboost_filesystem -lboost_wave source.cpp
But upon running the executable I get this error
terminate called after throwing an instance of 'boost::wrapexcept<boost::wave::preprocess_exception>'
what(): boost::wave::preprocess_exception
Aborted (core dumped)
As suggested in the comment, upon changing std::cout << (*first).get_value();
to std::cout << (*first).get_value() << '\n';
made apparent that the exception is thrown at the EOF. By pure guess, I tried adding \n
at the end of input
and the program run just fine, with no exeception.
However, when I reverted the code to what is the linked example, so that the input
is read from file rather than being hardcoded,
//std::string input("int main() { std::cout << \"Hello world\"; }");
std::ifstream instream("somefile.cpp");
std::string input(
std::istreambuf_iterator<char>(instream.rdbuf()),
std::istreambuf_iterator<char>());
then I got the same error.
One problem seems to be related to the missing \n
at the end of the string, so changing this
std::string input("int main() { std::cout << \"Hello world\"; }");
to this
std::string input("int main() { std::cout << \"Hello world\"; }\n");
seems to solve the problem. Except that the problem is more extensive than this. Indeed, if I add an header to the string:
std::string input("#include<iostream>\nint main() { std::cout << \"Hello world\"; }\n");
then I get the same failure. Most surprisingly, if I comment that header:
std::string input("//#include<iostream>\nint main() { std::cout << \"Hello world\"; }\n");
then the program runs, but the ouptut is:
#line 2 "/home/enrico/preproc.cpp"
int main() { std::cout << "Hello world"; }
and I have absolutely no idea how the #include<iostream>
is turned into #line 2 "/home/enrico/preproc.cpp"
.