// system headers
#include <string>
-#include <iostream>
+#include <iosfwd>
#include <vector>
#include <ctime>
("skipped_token_hooks", "record skipped_token hook calls")
#if BOOST_WAVE_SUPPORT_CPP0X != 0
("c++11", "enable C++11 mode (implies --variadics and --long_long)")
+#endif
+#if BOOST_WAVE_SUPPORT_CPP1Z != 0
+ ("c++17", "enable C++17 mode (implies --variadics and --long_long, adds __has_include)")
+#endif
+#if BOOST_WAVE_SUPPORT_CPP2A != 0
+ ("c++20", "enable C++20 mode (implies --variadics and --long_long, adds __has_include and __VA_OPT__)")
#endif
("warning,W", po::value<std::vector<std::string> >()->composing(),
"Warning settings.")
bool
testwave_app::test_a_file(std::string filename)
{
-// read the input file into a string
+ // read the input file into a string
std::string instr;
if (!read_file(filename, instr))
return false; // error was reported already
std::string expected_cfg_macro;
extract_special_information(filename, instr, 'D', expected_cfg_macro);
-// extract expected output, preprocess the data and compare results
+ // extract expected output, preprocess the data and compare results
std::string expected, expected_hooks;
if (extract_expected_output(filename, instr, expected, expected_hooks)) {
bool retval = true; // assume success
retval = false;
}
else if (!got_expected_result(filename, result, expected)) {
- // no preprocessing error encountered
+ // no preprocessing error encountered
if (debuglevel > 2) {
std::cerr
<< filename << ": failed" << std::endl
retval = false;
}
else {
- // preprocessing succeeded, check hook information, if appropriate
+ // preprocessing succeeded, check hook information, if appropriate
if (test_hooks && !expected_hooks.empty() &&
!got_expected_result(filename, hooks, expected_hooks))
{
}
if (!pp_result) {
- // there was a preprocessing error, was it expected?
+ // there was a preprocessing error, was it expected?
std::string expected_error;
if (!extract_special_information(filename, instr, 'E', expected_error))
return false;
if (!got_expected_result(filename, error, expected_error)) {
- // the error was unexpected
+ // the error was unexpected
if (debuglevel > 2) {
std::cerr
<< filename << ": failed" << std::endl;
<< std::endl;
}
else if (debuglevel > 3) {
- // caught the expected error message
+ // caught the expected error message
std::cerr << filename << ": succeeded" << std::endl;
}
}
int
testwave_app::print_version()
{
-// get time of last compilation of this file
-boost::wave::util::time_conversion_helper compilation_time(__DATE__ " " __TIME__);
+ // get time of last compilation of this file
+ boost::wave::util::time_conversion_helper compilation_time(__DATE__ " " __TIME__);
-// calculate the number of days since Feb 12 2005
-// (the day the testwave project was started)
-std::tm first_day;
+ // calculate the number of days since Feb 12 2005
+ // (the day the testwave project was started)
+ std::tm first_day;
using namespace std; // some platforms have memset in namespace std
memset (&first_day, 0, sizeof(std::tm));
first_day.tm_mday = 12; // 12
first_day.tm_year = 105; // 2005
-long seconds = long(std::difftime(compilation_time.get_time(),
- std::mktime(&first_day)));
+ long seconds = long(std::difftime(compilation_time.get_time(),
+ std::mktime(&first_day)));
std::cout
<< TESTWAVE_VERSION_MAJOR << '.'
bool
testwave_app::read_file(std::string const& filename, std::string& instr)
{
-// open the given file and report error, if appropriate
+ // open the given file and report error, if appropriate
std::ifstream instream(filename.c_str());
if (!instream.is_open()) {
std::cerr << "testwave: could not open input file: "
}
instream.unsetf(std::ios::skipws);
-// read the input file into a string
+ // read the input file into a string
#if defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)
-// this is known to be very slow for large files on some systems
+ // this is known to be very slow for large files on some systems
std::copy (std::istream_iterator<char>(instream),
std::istream_iterator<char>(),
std::inserter(instr, instr.end()));
<< flag << "') from input file: " << filename << std::endl;
}
-// tokenize the input data into C++ tokens using the C++ lexer
+ // tokenize the input data into C++ tokens using the C++ lexer
typedef boost::wave::cpplexer::lex_token<> token_type;
typedef boost::wave::cpplexer::lex_iterator<token_type> lexer_type;
typedef token_type::position_type position_type;
lexer_type end = lexer_type();
try {
- // look for C or C++ comments starting with the special character
+ // look for C or C++ comments starting with the special character
for (/**/; it != end; ++it) {
using namespace boost::wave;
token_id id = token_id(*it);
}
}
catch (boost::wave::cpplexer::lexing_exception const &e) {
- // some lexing error
+ // some lexing error
std::cerr
<< e.file_name() << "(" << e.line_no() << "): "
<< e.description() << std::endl;
std::cerr << "extract_options: extracting options" << std::endl;
}
-// extract the required information from the comments flagged by a
-// capital 'O'
+ // extract the required information from the comments flagged by a
+ // capital 'O'
std::string options;
if (!extract_special_information(filename, instr, 'O', options))
return false;
try {
- // parse the configuration information into a program_options_description
- // object
+ // parse the configuration information into a program_options_description
+ // object
cmd_line_utils::read_config_options(debuglevel, options, desc_options, vm);
initialise_options(ctx, vm, single_line);
}
// initialize the given context from the parsed options
#if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0
-// enable C99 mode, if appropriate (implies variadics)
+ // enable C99 mode, if appropriate (implies variadics)
if (vm.count("c99")) {
if (9 == debuglevel) {
std::cerr << "initialise_options: option: c99" << std::endl;
));
}
else if (vm.count("variadics")) {
- // enable variadics and placemarkers, if appropriate
+ // enable variadics and placemarkers, if appropriate
if (9 == debuglevel) {
std::cerr << "initialise_options: option: variadics" << std::endl;
}
#if BOOST_WAVE_SUPPORT_CPP0X
if (vm.count("c++11")) {
+ ctx.set_language(
+ boost::wave::language_support(
+ boost::wave::support_cpp0x
+ | boost::wave::support_option_convert_trigraphs
+ | boost::wave::support_option_long_long
+ | boost::wave::support_option_emit_line_directives
+#if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
+ | boost::wave::support_option_include_guard_detection
+#endif
+#if BOOST_WAVE_EMIT_PRAGMA_DIRECTIVES != 0
+ | boost::wave::support_option_emit_pragma_directives
+#endif
+ | boost::wave::support_option_insert_whitespace
+ ));
+ } else {
if (9 == debuglevel) {
std::cerr << "initialise_options: option: c++11" << std::endl;
}
+ }
+#endif
+
+#if BOOST_WAVE_SUPPORT_CPP1Z
+ if (vm.count("c++17")) {
ctx.set_language(
boost::wave::language_support(
- boost::wave::support_cpp0x
+ boost::wave::support_cpp1z
+#if BOOST_WAVE_SUPPORT_HAS_INCLUDE != 0
+ | boost::wave::support_option_has_include
+#endif
| boost::wave::support_option_convert_trigraphs
| boost::wave::support_option_long_long
| boost::wave::support_option_emit_line_directives
#endif
| boost::wave::support_option_insert_whitespace
));
+ } else {
+ if (9 == debuglevel) {
+ std::cerr << "initialise_options: option: c++17" << std::endl;
+ }
+ }
+
+#endif
+
+#if BOOST_WAVE_SUPPORT_CPP2A
+ if (vm.count("c++20")) {
+ ctx.set_language(
+ boost::wave::language_support(
+ boost::wave::support_cpp2a
+#if BOOST_WAVE_SUPPORT_HAS_INCLUDE != 0
+ | boost::wave::support_option_has_include
+#endif
+#if BOOST_WAVE_SUPPORT_VA_OPT != 0
+ | boost::wave::support_option_va_opt
+#endif
+ | boost::wave::support_option_convert_trigraphs
+ | boost::wave::support_option_long_long
+ | boost::wave::support_option_emit_line_directives
+ #if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
+ | boost::wave::support_option_include_guard_detection
+ #endif
+ #if BOOST_WAVE_EMIT_PRAGMA_DIRECTIVES != 0
+ | boost::wave::support_option_emit_pragma_directives
+ #endif
+ | boost::wave::support_option_insert_whitespace
+ ));
+
+ if (9 == debuglevel) {
+ std::cerr << "initialise_options: option: c++20" << std::endl;
+ }
}
#endif
-// enable long_long mode, if appropriate
+ // enable long_long mode, if appropriate
if (vm.count("long_long")) {
if (9 == debuglevel) {
std::cerr << "initialise_options: option: long_long" << std::endl;
ctx.set_language(boost::wave::enable_long_long(ctx.get_language()));
}
-// enable preserving comments mode, if appropriate
+ // enable preserving comments mode, if appropriate
if (vm.count("preserve")) {
if (9 == debuglevel) {
std::cerr << "initialise_options: option: preserve" << std::endl;
boost::wave::enable_preserve_comments(ctx.get_language()));
}
-// disable automatic include guard detection
+ // disable automatic include guard detection
if (vm.count("noguard")) {
if (9 == debuglevel) {
std::cerr << "initialise_options: option: guard" << std::endl;
boost::wave::enable_include_guard_detection(ctx.get_language(), false));
}
-// enable trigraph conversion
+ // enable trigraph conversion
if (9 == debuglevel) {
std::cerr << "initialise_options: option: convert_trigraphs" << std::endl;
}
ctx.set_language(boost::wave::enable_convert_trigraphs(ctx.get_language()));
-// enable single_line mode
+ // enable single_line mode
if (single_line) {
if (9 == debuglevel) {
std::cerr << "initialise_options: option: single_line" << std::endl;
ctx.set_language(boost::wave::enable_emit_line_directives(ctx.get_language(), false));
}
-// add include directories to the system include search paths
+ // add include directories to the system include search paths
if (vm.count("sysinclude")) {
std::vector<std::string> const& syspaths =
variables_map_as(vm["sysinclude"], (std::vector<std::string> *)NULL);
}
}
-// add include directories to the user include search paths
+ // add include directories to the user include search paths
if (vm.count("include")) {
cmd_line_utils::include_paths const &ip =
variables_map_as(vm["include"], (cmd_line_utils::include_paths*)NULL);
ctx.add_include_path(full.c_str());
}
- // if on the command line was given -I- , this has to be propagated
+ // if on the command line was given -I- , this has to be propagated
if (ip.seen_separator) {
if (9 == debuglevel) {
std::cerr << "initialise_options: option: -I-" << std::endl;
ctx.set_sysinclude_delimiter();
}
- // add system include directories to the include path
+ // add system include directories to the include path
std::vector<std::string>::const_iterator sysend = ip.syspaths.end();
for (std::vector<std::string>::const_iterator syscit = ip.syspaths.begin();
syscit != sysend; ++syscit)
}
}
-// add additional defined macros
+ // add additional defined macros
if (vm.count("define")) {
std::vector<std::string> const ¯os =
variables_map_as(vm["define"], (std::vector<std::string>*)NULL);
}
}
-// add additional predefined macros
+ // add additional predefined macros
if (vm.count("predefine")) {
std::vector<std::string> const &predefmacros =
variables_map_as(vm["predefine"], (std::vector<std::string>*)NULL);
}
}
-// undefine specified macros
+ // undefine specified macros
if (vm.count("undefine")) {
std::vector<std::string> const &undefmacros =
variables_map_as(vm["undefine"], (std::vector<std::string>*)NULL);
}
}
-// maximal include nesting depth
+ // maximal include nesting depth
if (vm.count("nesting")) {
int max_depth = variables_map_as(vm["nesting"], (int*)NULL);
if (max_depth < 1 || max_depth > 100000) {
std::string& result, std::string& error, std::string& hooks,
std::string const& expected_cfg_macro, bool single_line)
{
-// create the wave::context object and initialize it from the file to
-// preprocess (may contain options inside of special comments)
+ // create the wave::context object and initialize it from the file to
+ // preprocess (may contain options inside of special comments)
typedef boost::wave::cpplexer::lex_token<> token_type;
typedef boost::wave::cpplexer::lex_iterator<token_type> lexer_type;
typedef boost::wave::context<
}
try {
- // create preprocessing context
+ // create preprocessing context
context_type ctx(instr.begin(), instr.end(), filename.c_str(),
collect_hooks_information<token_type>(hooks));
- // initialize the context from the options given on the command line
+ // initialize the context from the options given on the command line
if (!initialise_options(ctx, global_vm, single_line))
return false;
- // extract the options from the input data and initialize the context
+ // extract the options from the input data and initialize the context
boost::program_options::variables_map local_vm;
if (!extract_options(filename, instr, ctx, single_line, local_vm))
return false;
- // add special predefined macros
+ // add special predefined macros
if (!add_predefined_macros(ctx))
return false;
return false;
}
- // preprocess the input, loop over all generated tokens collecting the
- // generated text
+ // preprocess the input, loop over all generated tokens collecting the
+ // generated text
context_type::iterator_type it = ctx.begin();
context_type::iterator_type end = ctx.end();
if (local_vm.count("forceinclude")) {
- // add the filenames to force as include files in _reverse_ order
- // the second parameter 'is_last' of the force_include function should
- // be set to true for the last (first given) file.
- std::vector<std::string> const &force =
+ // add the filenames to force as include files in _reverse_ order
+ // the second parameter 'is_last' of the force_include function should
+ // be set to true for the last (first given) file.
+ std::vector<std::string> const& force =
local_vm["forceinclude"].as<std::vector<std::string> >();
std::vector<std::string>::const_reverse_iterator rend = force.rend();
for (std::vector<std::string>::const_reverse_iterator cit = force.rbegin();
}
}
- // perform actual preprocessing
+ // perform actual preprocessing
for (/**/; it != end; ++it)
{
using namespace boost::wave;
if (T_PP_LINE == token_id(*it)) {
- // special handling of the whole #line directive is required to
- // allow correct file name matching
+ // special handling of the whole #line directive is required to
+ // allow correct file name matching
if (!handle_line_directive(it, end, result))
return false; // unexpected eof
}
error.clear();
}
catch (boost::wave::cpplexer::lexing_exception const& e) {
- // some lexer error
+ // some lexer error
BOOST_WAVETEST_OSSTREAM strm;
std::string filename = e.file_name();
strm
return false;
}
catch (boost::wave::cpp_exception const& e) {
- // some preprocessing error
+ // some preprocessing error
BOOST_WAVETEST_OSSTREAM strm;
std::string filename = e.file_name();
strm
return true;
}
-