15c01a454c
[SVN r78634]
236 lines
8.0 KiB
C++
236 lines
8.0 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)
|
|
=============================================================================*/
|
|
|
|
#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)
|