📄 testwave.cpp
字号:
/*============================================================================= Boost.Wave: A Standard compliant C++ preprocessor library http://www.boost.org/ Copyright (c) 2001-2008 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)=============================================================================*/// system headers#include <string>#include <iostream>#include <vector>// include boost#include <boost/config.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 = fs::complete( fs::path(*cit, fs::native), fs::current_path()); fs::path filepath = cfgpath.branch_path() / fs::path(*iit, fs::native); if (9 == app.get_debuglevel()) { std::cerr << std::string(79, '-') << std::endl; std::cerr << "executing test: " << filepath.native_file_string() << std::endl; } // execute this unit test case if (!app.test_a_file(filepath.native_file_string())) { if (9 == app.get_debuglevel()) { std::cerr << "failed to execute test: " << filepath.native_file_string() << std::endl; } ++error_count; } else if (9 == app.get_debuglevel()) { std::cerr << "succeeded to execute test: " << filepath.native_file_string() << 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((*arg).value[0], fs::native); if (9 == app.get_debuglevel()) { std::cerr << std::string(79, '-') << std::endl; std::cerr << "executing test: " << filepath.native_file_string() << std::endl; } if (!app.test_a_file(filepath.native_file_string())) { if (9 == app.get_debuglevel()) { std::cerr << "failed to execute test: " << filepath.native_file_string() << std::endl; } ++error_count; } else if (9 == app.get_debuglevel()) { std::cerr << "succeeded to execute test: " << filepath.native_file_string() << 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;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -