123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235 |
- /*=============================================================================
- 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)
- =============================================================================*/
- #if !defined(BOOST_WAVE_LIBS_WAVE_TEST_CMD_LINE_UTILS_HPP)
- #define BOOST_WAVE_LIBS_WAVE_TEST_CMD_LINE_UTILS_HPP
- #include <string>
- #include <fstream>
- #include <vector>
- #include <boost/config.hpp>
- #include <boost/assert.hpp>
- #include <boost/any.hpp>
- ///////////////////////////////////////////////////////////////////////////////
- // forward declarations only
- namespace cmd_line_utils
- {
- class include_paths;
- }
- namespace boost { namespace program_options
- {
- void validate(boost::any &v, std::vector<std::string> const &s,
- cmd_line_utils::include_paths *, int);
- }} // boost::program_options
- ///////////////////////////////////////////////////////////////////////////////
- #include <boost/program_options.hpp>
- ///////////////////////////////////////////////////////////////////////////////
- namespace cmd_line_utils {
- namespace po = boost::program_options;
- ///////////////////////////////////////////////////////////////////////////
- // Additional command line parser which interprets '@something' as an
- // option "config-file" with the value "something".
- inline std::pair<std::string, std::string>
- at_option_parser(std::string const& s)
- {
- if ('@' == s[0])
- return std::make_pair(std::string("config-file"), s.substr(1));
- else
- return std::pair<std::string, std::string>();
- }
- ///////////////////////////////////////////////////////////////////////////
- // class, which keeps the include file information read from the options
- class include_paths
- {
- public:
- include_paths() : seen_separator(false) {}
- std::vector<std::string> paths; // stores user paths
- std::vector<std::string> syspaths; // stores system paths
- bool seen_separator; // options contain a '-I-' option
- // Function which validates additional tokens from the given option.
- static void
- validate(boost::any &v, std::vector<std::string> const &tokens)
- {
- if (v.empty())
- v = boost::any(include_paths());
- include_paths *p = boost::any_cast<include_paths>(&v);
- BOOST_ASSERT(NULL != p);
- // Assume only one path per '-I' occurrence.
- std::string const& t = po::validators::get_single_string(tokens);
- if (t == "-") {
- // found -I- option, so switch behaviour
- p->seen_separator = true;
- }
- else if (p->seen_separator) {
- // store this path as a system path
- p->syspaths.push_back(t);
- }
- else {
- // store this path as an user path
- p->paths.push_back(t);
- }
- }
- };
- ///////////////////////////////////////////////////////////////////////////
- // Read all options from a given config string, parse and add them to the
- // given variables_map
- inline void
- read_config_options(int debuglevel, std::string const &indata,
- po::options_description const &desc, po::variables_map &vm)
- {
- if (9 == debuglevel) {
- std::cerr << "read_config_options: reading config options"
- << std::endl;
- }
- std::istringstream istrm(indata);
-
- std::vector<std::string> options;
- std::string line;
- while (std::getline(istrm, line)) {
- // skip empty lines
- std::string::size_type pos = line.find_first_not_of(" \t");
- if (pos == std::string::npos)
- continue;
- // skip comment lines
- if ('#' != line[pos])
- options.push_back(line);
- }
- if (options.size() > 0) {
- if (9 == debuglevel) {
- std::cerr << "read_config_options: options size is: "
- << (int)options.size() << std::endl;
- }
- // (the (int) cast is to make the True64 compiler happy)
- using namespace boost::program_options::command_line_style;
- po::store(po::command_line_parser(options)
- .options(desc).style((int)unix_style).run(), vm);
- po::notify(vm);
- }
- if (9 == debuglevel) {
- std::cerr << "read_config_options: succeeded to read config options"
- << std::endl;
- }
- }
- ///////////////////////////////////////////////////////////////////////////
- // Read all options from a given config file, parse and add them to the
- // given variables_map
- inline bool
- read_config_file(int debuglevel, std::string const &filename,
- po::options_description const &desc, po::variables_map &vm)
- {
- if (9 == debuglevel) {
- std::cerr << "read_config_file: reading config options"
- << std::endl;
- }
- std::ifstream ifs(filename.c_str());
- if (!ifs.is_open()) {
- std::cerr
- << "testwave: " << filename
- << ": command line warning: config file not found"
- << std::endl;
- return false;
- }
- // parse the file and extract all given arguments and options
- std::vector<std::string> options;
- std::string line;
- while (std::getline(ifs, line)) {
- // skip empty lines
- std::string::size_type pos = line.find_first_not_of(" \t");
- if (pos == std::string::npos)
- continue;
- // skip comment lines
- if ('#' != line[pos])
- options.push_back(line);
- }
- if (options.size() > 0) {
- if (9 == debuglevel) {
- std::cerr << "read_config_file: options size is: "
- << (int)options.size() << std::endl;
- }
- // treat positional arguments as --input parameters
- po::positional_options_description p;
- p.add("input", -1);
- // parse the vector of lines and store the results into the given
- // variables map
- // (the (int) cast is to make the True64 compiler happy)
- using namespace boost::program_options::command_line_style;
- po::store(po::command_line_parser(options)
- .options(desc).positional(p).style((int)unix_style).run(), vm);
- po::notify(vm);
- }
- if (9 == debuglevel) {
- std::cerr << "read_config_file: succeeded to read config options"
- << std::endl;
- }
- return true;
- }
- ///////////////////////////////////////////////////////////////////////////
- // predicate to extract all positional arguments from the command line
- struct is_argument
- {
- bool operator()(po::option const &opt)
- {
- return (opt.position_key == -1) ? true : false;
- }
- };
- ///////////////////////////////////////////////////////////////////////////////
- } // namespace cmd_line_utils
- ///////////////////////////////////////////////////////////////////////////////
- //
- // Special validator overload, which allows to handle the -I- syntax for
- // switching the semantics of an -I option.
- //
- // This must be injected into the boost::program_options namespace
- //
- ///////////////////////////////////////////////////////////////////////////////
- namespace boost { namespace program_options {
- inline void
- validate(boost::any &v, std::vector<std::string> const &s,
- cmd_line_utils::include_paths *, int)
- {
- cmd_line_utils::include_paths::validate(v, s);
- }
- }} // namespace boost::program_options
- #endif // !defined(BOOST_WAVE_LIBS_WAVE_TEST_CMD_LINE_UTILS_HPP)
|