2
0
mirror of https://github.com/boostorg/wave.git synced 2026-01-19 04:42:16 +00:00
Files
wave/test/testwave/testwave.cpp
Jeff Trull f1ec8fd22c Make indentation consistent with code nesting
These changes, a subset of what clang-format generates, ensure code
and comments are aligned properly for the level of the code. There
were a number of places where comments (many) and code (some) were
four spaces to the left of where they should be. This will make the
code easier to read.

One advantage of separating out these changes is they can be verified
to be whitespace-only with a simple diff.
2020-10-23 15:05:00 -07:00

302 lines
12 KiB
C++

/*=============================================================================
Boost.Wave: A Standard compliant C++ preprocessor library
http://www.boost.org/
Copyright (c) 2001-2012 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)
=============================================================================*/
// disable stupid compiler warnings
#include <boost/config/warning_disable.hpp>
// system headers
#include <string>
#include <iostream>
#include <vector>
// include boost
#include <boost/config.hpp>
#include <boost/wave.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/operations.hpp>
// test application related headers
#include "cmd_line_utils.hpp"
#include "testwave_app.hpp"
namespace po = boost::program_options;
namespace fs = boost::filesystem;
///////////////////////////////////////////////////////////////////////////////
//
// The debuglevel command line parameter is used to control the amount of text
// printed by the testwave application.
//
// level 0: prints nothing except serious failures preventing the testwave
// executable from running, the return value of the executable is
// equal to the number of failed tests
// level 1: prints a short summary only
// level 2: prints the names of the failed tests only
// level 3: prints the expected and real result for failed tests
// level 4: prints the outcome of every test
// level 5: prints the real result even for succeeded tests
// level 6: prints the real hooks information recorded, even for succeeded
// tests
//
// level 9: prints information about almost everything
//
// The default debug level is 1.
//
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
int
main(int argc, char *argv[])
{
int error_count = 0;
int config_file_error_count = 0;
try {
// analyze the command line options and arguments
po::options_description desc_cmdline ("Options allowed on the command line");
desc_cmdline.add_options()
("help,h", "print out program usage (this message)")
("version,v", "print the version number")
("copyright,c", "print out the copyright statement")
("config-file", po::value<std::vector<std::string> >()->composing(),
"specify a config file (alternatively: @arg)")
("hooks", po::value<bool>()->default_value(true),
"test preprocessing hooks")
("debug,d", po::value<int>(), "set the debug level (0...9)")
;
// Hidden options, will be used in in config file analysis to allow to
// recognize positional arguments, will not be shown to the user.
po::options_description desc_hidden("Hidden options");
desc_hidden.add_options()
("input", po::value<std::vector<std::string> >()->composing(),
"inputfile")
;
// this is the test application object
po::variables_map vm;
testwave_app app(vm);
// all command line and config file options
po::options_description cmdline_options;
cmdline_options.add(desc_cmdline).add(app.common_options());
// parse command line
// (the (int) cast is to make the True64 compiler happy)
using namespace boost::program_options::command_line_style;
po::parsed_options opts(po::parse_command_line(argc, argv,
cmdline_options, (int)unix_style, cmd_line_utils::at_option_parser));
po::store(opts, vm);
po::notify(vm);
// ... act as required
if (vm.count("help")) {
po::options_description desc_help (
"Usage: testwave [options] [@config-file(s)] file(s)");
desc_help.add(desc_cmdline).add(app.common_options());
std::cout << desc_help << std::endl;
return 0;
}
// debug flag
if (vm.count("debug")) {
int debug_level = vm["debug"].as<int>();
if (debug_level < 0 || debug_level > 9) {
std::cerr
<< "testwave: please use an integer in the range [0..9] "
<< "as the parameter to the debug option!"
<< std::endl;
}
else {
app.set_debuglevel(debug_level);
}
}
if (vm.count("version")) {
return app.print_version();
}
if (vm.count("copyright")) {
return app.print_copyright();
}
// If there is specified at least one config file, parse it and add the
// options to the main variables_map
// Each of the config files is parsed into a separate variables_map to
// allow correct paths handling.
int input_count = 0;
if (vm.count("config-file")) {
std::vector<std::string> const &cfg_files =
vm["config-file"].as<std::vector<std::string> >();
if (9 == app.get_debuglevel()) {
std::cerr << "found " << (unsigned)cfg_files.size()
<< " config-file arguments" << std::endl;
}
std::vector<std::string>::const_iterator end = cfg_files.end();
for (std::vector<std::string>::const_iterator cit = cfg_files.begin();
cit != end; ++cit)
{
if (9 == app.get_debuglevel()) {
std::cerr << "reading config_file: " << *cit << std::endl;
}
// parse a single config file and store the results, config files
// may only contain --input and positional arguments
po::variables_map cvm;
if (!cmd_line_utils::read_config_file(app.get_debuglevel(),
*cit, desc_hidden, cvm))
{
if (9 == app.get_debuglevel()) {
std::cerr << "failed to read config_file: " << *cit
<< std::endl;
}
++config_file_error_count;
}
if (9 == app.get_debuglevel()) {
std::cerr << "succeeded to read config_file: " << *cit
<< std::endl;
}
// correct the paths parsed into this variables_map
if (cvm.count("input")) {
std::vector<std::string> const &infiles =
cvm["input"].as<std::vector<std::string> >();
if (9 == app.get_debuglevel()) {
std::cerr << "found " << (unsigned)infiles.size()
<< " entries" << std::endl;
}
std::vector<std::string>::const_iterator iend = infiles.end();
for (std::vector<std::string>::const_iterator iit = infiles.begin();
iit != iend; ++iit)
{
// correct the file name (pre-pend the config file path)
fs::path cfgpath = boost::wave::util::complete_path(
boost::wave::util::create_path(*cit),
boost::wave::util::current_path());
fs::path filepath =
boost::wave::util::branch_path(cfgpath) /
boost::wave::util::create_path(*iit);
if (9 == app.get_debuglevel()) {
std::cerr << std::string(79, '-') << std::endl;
std::cerr << "executing test: "
<< boost::wave::util::native_file_string(filepath)
<< std::endl;
}
// execute this unit test case
if (!app.test_a_file(
boost::wave::util::native_file_string(filepath)))
{
if (9 == app.get_debuglevel()) {
std::cerr << "failed to execute test: "
<< boost::wave::util::native_file_string(filepath)
<< std::endl;
}
++error_count;
}
else if (9 == app.get_debuglevel()) {
std::cerr << "succeeded to execute test: "
<< boost::wave::util::native_file_string(filepath)
<< std::endl;
}
++input_count;
if (9 == app.get_debuglevel()) {
std::cerr << std::string(79, '-') << std::endl;
}
}
}
else if (9 == app.get_debuglevel()) {
std::cerr << "no entries found" << std::endl;
}
}
}
// extract the arguments from the parsed command line
std::vector<po::option> arguments;
std::remove_copy_if(opts.options.begin(), opts.options.end(),
std::back_inserter(arguments), cmd_line_utils::is_argument());
if (9 == app.get_debuglevel()) {
std::cerr << "found " << (unsigned)arguments.size()
<< " arguments" << std::endl;
}
// iterate over remaining arguments
std::vector<po::option>::const_iterator arg_end = arguments.end();
for (std::vector<po::option>::const_iterator arg = arguments.begin();
arg != arg_end; ++arg)
{
fs::path filepath(boost::wave::util::create_path((*arg).value[0]));
if (9 == app.get_debuglevel()) {
std::cerr << std::string(79, '-') << std::endl;
std::cerr << "executing test: "
<< boost::wave::util::native_file_string(filepath)
<< std::endl;
}
if (!app.test_a_file(boost::wave::util::native_file_string(filepath)))
{
if (9 == app.get_debuglevel()) {
std::cerr << "failed to execute test: "
<< boost::wave::util::native_file_string(filepath)
<< std::endl;
}
++error_count;
}
else if (9 == app.get_debuglevel()) {
std::cerr << "succeeded to execute test: "
<< boost::wave::util::native_file_string(filepath)
<< std::endl;
}
if (9 == app.get_debuglevel()) {
std::cerr << std::string(79, '-') << std::endl;
}
++input_count;
}
// print a message if no input is given
if (0 == input_count) {
std::cerr
<< "testwave: no input file specified, "
<< "try --help to get a hint."
<< std::endl;
return (std::numeric_limits<int>::max)() - 3;
}
else if (app.get_debuglevel() > 0) {
std::cout
<< "testwave: " << input_count-error_count
<< " of " << input_count << " test(s) succeeded";
if (0 != error_count) {
std::cout
<< " (" << error_count << " test(s) failed)";
}
std::cout << "." << std::endl;
}
}
catch (std::exception const& e) {
std::cerr << "testwave: exception caught: " << e.what() << std::endl;
return (std::numeric_limits<int>::max)() - 1;
}
catch (...) {
std::cerr << "testwave: unexpected exception caught." << std::endl;
return (std::numeric_limits<int>::max)() - 2;
}
return error_count + config_file_error_count;
}