mirror of
https://github.com/boostorg/program_options.git
synced 2026-01-20 16:52:14 +00:00
Compare commits
44 Commits
boost-1.46
...
svn-branch
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2f701645b5 | ||
|
|
4dcce9efce | ||
|
|
316e2fabe4 | ||
|
|
152fbd8384 | ||
|
|
80361c6b8f | ||
|
|
a3d19d354a | ||
|
|
86aeaf478d | ||
|
|
7ba4ac9c14 | ||
|
|
d343dda27e | ||
|
|
8329c28a1a | ||
|
|
73cf706164 | ||
|
|
e51a3ae742 | ||
|
|
a0a661e4ec | ||
|
|
c25408f6d2 | ||
|
|
63fca63679 | ||
|
|
8c39e5aa8d | ||
|
|
d0aa5abee5 | ||
|
|
90dc6b94d0 | ||
|
|
2320c07267 | ||
|
|
cd647f785a | ||
|
|
4223d3231d | ||
|
|
d1d5636365 | ||
|
|
c00c4a57db | ||
|
|
8ad16ee97c | ||
|
|
0c3e43f2ce | ||
|
|
e42f028278 | ||
|
|
a29728e679 | ||
|
|
232894cb3d | ||
|
|
d39f2b5979 | ||
|
|
8c68a478c9 | ||
|
|
5d1345c5a9 | ||
|
|
a560d767fb | ||
|
|
8c1982de82 | ||
|
|
928d7806f7 | ||
|
|
b99ae04040 | ||
|
|
dc334deea7 | ||
|
|
de66d37405 | ||
|
|
a4375600a2 | ||
|
|
bec34dd1b9 | ||
|
|
7b73b2e84c | ||
|
|
2625de2dd0 | ||
|
|
ac6de20f85 | ||
|
|
3765e8e8e9 | ||
|
|
026c527d8d |
@@ -1,19 +1,20 @@
|
||||
|
||||
project boost/program_options
|
||||
: source-location ../src
|
||||
:
|
||||
source-location ../src
|
||||
;
|
||||
|
||||
SOURCES =
|
||||
cmdline config_file options_description parsers variables_map
|
||||
value_semantic positional_options utf8_codecvt_facet
|
||||
convert winmain split
|
||||
convert winmain
|
||||
;
|
||||
|
||||
lib boost_program_options
|
||||
: $(SOURCES).cpp
|
||||
: <link>shared:<define>BOOST_PROGRAM_OPTIONS_DYN_LINK=1 # tell source we're building dll's
|
||||
:
|
||||
: <link>shared:<define>BOOST_PROGRAM_OPTIONS_DYN_LINK=1
|
||||
$(SOURCES).cpp
|
||||
:
|
||||
<link>shared:<define>BOOST_PROGRAM_OPTIONS_DYN_LINK=1 # tell source we're building dll's
|
||||
;
|
||||
|
||||
boost-install boost_program_options ;
|
||||
boost-install boost_program_options ;
|
||||
@@ -5,8 +5,6 @@ toolset.using doxygen ;
|
||||
boostbook program_option
|
||||
: program_options.xml
|
||||
: <implicit-dependency>autodoc
|
||||
<xsl:param>boost.root=../../../..
|
||||
<format>pdf:<xsl:param>boost.url.prefix=http://www.boost.org/doc/libs/release/doc/html
|
||||
;
|
||||
|
||||
doxygen autodoc
|
||||
|
||||
@@ -107,7 +107,7 @@ if (vm.count("response-file")) {
|
||||
// Load the file and tokenize it
|
||||
ifstream ifs(vm["response-file"].as<string>().c_str());
|
||||
if (!ifs) {
|
||||
cout << "Could not open the response file\n";
|
||||
cout << "Could no open the response file\n";
|
||||
return 1;
|
||||
}
|
||||
// Read the whole file into a string
|
||||
@@ -115,8 +115,7 @@ if (vm.count("response-file")) {
|
||||
ss << ifs.rdbuf();
|
||||
// Split the file content
|
||||
char_separator<char> sep(" \n\r");
|
||||
std::string ResponsefileContents( ss.str() );
|
||||
tokenizer<char_separator<char> > tok(ResponsefileContents, sep);
|
||||
tokenizer<char_separator<char> > tok(ss.str(), sep);
|
||||
vector<string> args;
|
||||
copy(tok.begin(), tok.end(), back_inserter(args));
|
||||
// Parse the file and store the options
|
||||
@@ -147,7 +146,7 @@ if (vm.count("response-file")) {
|
||||
vector<string> args = split_winmain(lpCmdLine);
|
||||
store(command_line_parser(args).options(desc).run(), vm);
|
||||
</programlisting>
|
||||
The <code>split_winmain</code> function is overloaded for <code>wchar_t</code> strings, so can
|
||||
The function is an overload for <code>wchar_t</code> strings, so can
|
||||
also be used in Unicode applications.
|
||||
</para>
|
||||
|
||||
@@ -296,7 +295,7 @@ void validate(boost::any& v,
|
||||
if (regex_match(s, match, r)) {
|
||||
v = any(magic_number(lexical_cast<int>(match[1])));
|
||||
} else {
|
||||
throw validation_error(validation_error::invalid_option_value);
|
||||
throw validation_error("invalid value");
|
||||
}
|
||||
}
|
||||
]]>
|
||||
|
||||
@@ -77,13 +77,13 @@ if (vm.count("compression")) {
|
||||
<para>It's now a good time to try compiling the code yourself, but if
|
||||
you're not yet ready, here's an example session:
|
||||
<screen>
|
||||
$ <userinput>bin/gcc/debug/first</userinput>
|
||||
$<userinput>bin/gcc/debug/first</userinput>
|
||||
Compression level was not set.
|
||||
$ <userinput>bin/gcc/debug/first --help</userinput>
|
||||
$<userinput>bin/gcc/debug/first --help</userinput>
|
||||
Allowed options:
|
||||
--help : produce help message
|
||||
--compression arg : set compression level
|
||||
$ <userinput>bin/gcc/debug/first --compression 10</userinput>
|
||||
$<userinput>bin/gcc/debug/first --compression 10</userinput>
|
||||
Compression level was set to 10.
|
||||
</screen>
|
||||
</para>
|
||||
@@ -199,16 +199,16 @@ cout << "Optimization level is " << opt << "\n&
|
||||
|
||||
<para>Here's an example session:
|
||||
<screen>
|
||||
$ <userinput>bin/gcc/debug/options_description --help</userinput>
|
||||
$<userinput>bin/gcc/debug/options_description --help</userinput>
|
||||
Usage: options_description [options]
|
||||
Allowed options:
|
||||
--help : produce help message
|
||||
--optimization arg : optimization level
|
||||
-I [ --include-path ] arg : include path
|
||||
--input-file arg : input file
|
||||
$ <userinput>bin/gcc/debug/options_description</userinput>
|
||||
$bin/gcc/debug/options_description
|
||||
Optimization level is 10
|
||||
$ <userinput>bin/gcc/debug/options_description --optimization 4 -I foo a.cpp</userinput>
|
||||
$<userinput>bin/gcc/debug/options_description --optimization 4 -I foo a.cpp</userinput>
|
||||
Include paths are: foo
|
||||
Input files are: a.cpp
|
||||
Optimization level is 4
|
||||
@@ -308,10 +308,10 @@ visible.add(generic).add(config);
|
||||
|
||||
<para>Here's an example session:
|
||||
<screen>
|
||||
$ <userinput>bin/gcc/debug/multiple_sources</userinput>
|
||||
$<userinput>bin/gcc/debug/multiple_sources</userinput>
|
||||
Include paths are: /opt
|
||||
Optimization level is 1
|
||||
$ <userinput>bin/gcc/debug/multiple_sources --help</userinput>
|
||||
$<userinput>bin/gcc/debug/multiple_sources --help</userinput>
|
||||
Allows options:
|
||||
|
||||
Generic options:
|
||||
@@ -322,7 +322,7 @@ Configuration:
|
||||
--optimization n : optimization level
|
||||
-I [ --include-path ] path : include path
|
||||
|
||||
$ <userinput>bin/gcc/debug/multiple_sources --optimization=4 -I foo a.cpp b.cpp</userinput>
|
||||
$<userinput>bin/gcc/debug/multiple_sources --optimization=4 -I foo a.cpp b.cpp</userinput>
|
||||
Include paths are: foo /opt
|
||||
Input files are: a.cpp b.cpp
|
||||
Optimization level is 4
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
project
|
||||
: requirements <library>../build//boost_program_options
|
||||
<hardcode-dll-paths>true
|
||||
<link>static
|
||||
;
|
||||
|
||||
exe first : first.cpp ;
|
||||
|
||||
@@ -27,16 +27,13 @@ int main(int ac, char* av[])
|
||||
{
|
||||
try {
|
||||
int opt;
|
||||
string config_file;
|
||||
|
||||
// Declare a group of options that will be
|
||||
// allowed only on command line
|
||||
po::options_description generic("Generic options");
|
||||
generic.add_options()
|
||||
("version,v", "print version string")
|
||||
("help", "produce help message")
|
||||
("config,c", po::value<string>(&config_file)->default_value("multiple_sources.cfg"),
|
||||
"name of a file of a configuration.")
|
||||
("help", "produce help message")
|
||||
;
|
||||
|
||||
// Declare a group of options that will be
|
||||
@@ -74,19 +71,10 @@ int main(int ac, char* av[])
|
||||
po::variables_map vm;
|
||||
store(po::command_line_parser(ac, av).
|
||||
options(cmdline_options).positional(p).run(), vm);
|
||||
|
||||
ifstream ifs("multiple_sources.cfg");
|
||||
store(parse_config_file(ifs, config_file_options), vm);
|
||||
notify(vm);
|
||||
|
||||
ifstream ifs(config_file.c_str());
|
||||
if (!ifs)
|
||||
{
|
||||
cout << "can not open config file: " << config_file << "\n";
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
store(parse_config_file(ifs, config_file_options), vm);
|
||||
notify(vm);
|
||||
}
|
||||
|
||||
if (vm.count("help")) {
|
||||
cout << visible << "\n";
|
||||
|
||||
@@ -77,7 +77,7 @@ int main(int ac, char* av[])
|
||||
|
||||
cout << "Listen port is " << portnum << "\n";
|
||||
}
|
||||
catch(std::exception& e)
|
||||
catch(exception& e)
|
||||
{
|
||||
cout << e.what() << "\n";
|
||||
return 1;
|
||||
|
||||
@@ -43,7 +43,7 @@ public:
|
||||
*/
|
||||
void validate(boost::any& v,
|
||||
const std::vector<std::string>& values,
|
||||
magic_number*, int)
|
||||
magic_number* target_type, int)
|
||||
{
|
||||
static regex r("\\d\\d\\d-(\\d\\d\\d)");
|
||||
|
||||
@@ -61,7 +61,7 @@ void validate(boost::any& v,
|
||||
if (regex_match(s, match, r)) {
|
||||
v = any(magic_number(lexical_cast<int>(match[1])));
|
||||
} else {
|
||||
throw validation_error(validation_error::invalid_option_value);
|
||||
throw validation_error("invalid value");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ int main(int ac, char* av[])
|
||||
<< vm["magic"].as<magic_number>().n << "\"\n";
|
||||
}
|
||||
}
|
||||
catch(std::exception& e)
|
||||
catch(exception& e)
|
||||
{
|
||||
cout << e.what() << "\n";
|
||||
}
|
||||
|
||||
@@ -70,8 +70,7 @@ int main(int ac, char* av[])
|
||||
ss << ifs.rdbuf();
|
||||
// Split the file content
|
||||
char_separator<char> sep(" \n\r");
|
||||
string sstr = ss.str();
|
||||
tokenizer<char_separator<char> > tok(sstr, sep);
|
||||
tokenizer<char_separator<char> > tok(ss.str(), sep);
|
||||
vector<string> args;
|
||||
copy(tok.begin(), tok.end(), back_inserter(args));
|
||||
// Parse the file and store the options
|
||||
@@ -88,7 +87,7 @@ int main(int ac, char* av[])
|
||||
cout << "Magic value: " << vm["magic"].as<int>() << "\n";
|
||||
}
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
catch(exception& e) {
|
||||
cout << e.what() << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace boost { namespace program_options { namespace command_line_style {
|
||||
enum style_t {
|
||||
/// Allow "--long_name" style
|
||||
allow_long = 1,
|
||||
/// Allow "-<single character" style
|
||||
/// Alow "-<single character" style
|
||||
allow_short = allow_long << 1,
|
||||
/// Allow "-" in short options
|
||||
allow_dash_for_short = allow_short << 1,
|
||||
@@ -62,19 +62,14 @@ namespace boost { namespace program_options { namespace command_line_style {
|
||||
long option name if guessing is in effect.
|
||||
*/
|
||||
allow_guessing = allow_sticky << 1,
|
||||
/** Ignore the difference in case for long options.
|
||||
/** Ignore the difference in case for options.
|
||||
@todo Should this apply to long options only?
|
||||
*/
|
||||
long_case_insensitive = allow_guessing << 1,
|
||||
/** Ignore the difference in case for short options.
|
||||
*/
|
||||
short_case_insensitive = long_case_insensitive << 1,
|
||||
/** Ignore the difference in case for all options.
|
||||
*/
|
||||
case_insensitive = (long_case_insensitive | short_case_insensitive),
|
||||
case_insensitive = allow_guessing << 1,
|
||||
/** Allow long options with single option starting character,
|
||||
e.g <tt>-foo=10</tt>
|
||||
*/
|
||||
allow_long_disguise = short_case_insensitive << 1,
|
||||
allow_long_disguise = case_insensitive << 1,
|
||||
/** The more-or-less traditional unix style. */
|
||||
unix_style = (allow_short | short_allow_adjacent | short_allow_next
|
||||
| allow_long | long_allow_adjacent | long_allow_next
|
||||
|
||||
@@ -22,11 +22,6 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
# pragma warning (push)
|
||||
# pragma warning (disable:4251) // class 'std::vector<_Ty>' needs to have dll-interface to be used by clients of class 'boost::program_options::positional_options_description'
|
||||
#endif
|
||||
|
||||
namespace boost { namespace program_options { namespace detail {
|
||||
|
||||
/** Command line parser class. Main requirements were:
|
||||
@@ -113,15 +108,13 @@ namespace boost { namespace program_options { namespace detail {
|
||||
void extra_style_parser(style_parser s);
|
||||
|
||||
void check_style(int style) const;
|
||||
|
||||
bool is_style_active(style_t style) const;
|
||||
|
||||
|
||||
void init(const std::vector<std::string>& args);
|
||||
|
||||
void
|
||||
finish_option(option& opt,
|
||||
std::vector<std::string>& other_tokens,
|
||||
const std::vector<style_parser>& style_parsers);
|
||||
std::vector<std::string>& other_tokens);
|
||||
|
||||
// Copies of input.
|
||||
std::vector<std::string> args;
|
||||
@@ -139,9 +132,5 @@ namespace boost { namespace program_options { namespace detail {
|
||||
|
||||
}}}
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
# pragma warning (pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
|
||||
#include <boost/program_options/detail/convert.hpp>
|
||||
|
||||
#include <iterator>
|
||||
|
||||
namespace boost { namespace program_options {
|
||||
|
||||
namespace detail {
|
||||
@@ -29,18 +27,18 @@ namespace boost { namespace program_options {
|
||||
template<class charT>
|
||||
basic_command_line_parser<charT>::
|
||||
basic_command_line_parser(const std::vector<
|
||||
std::basic_string<charT> >& xargs)
|
||||
: detail::cmdline(to_internal(xargs))
|
||||
std::basic_string<charT> >& args)
|
||||
: detail::cmdline(to_internal(args))
|
||||
{}
|
||||
|
||||
|
||||
template<class charT>
|
||||
basic_command_line_parser<charT>::
|
||||
basic_command_line_parser(int argc, const charT* const argv[])
|
||||
basic_command_line_parser(int argc, charT* argv[])
|
||||
: detail::cmdline(
|
||||
// Explicit template arguments are required by gcc 3.3.1
|
||||
// (at least mingw version), and do no harm on other compilers.
|
||||
to_internal(detail::make_vector<charT, const charT* const*>(argv+1, argv+argc+!argc)))
|
||||
to_internal(detail::make_vector<charT, charT**>(argv+1, argv+argc+!argc)))
|
||||
{}
|
||||
|
||||
|
||||
@@ -64,9 +62,9 @@ namespace boost { namespace program_options {
|
||||
|
||||
template<class charT>
|
||||
basic_command_line_parser<charT>&
|
||||
basic_command_line_parser<charT>::style(int xstyle)
|
||||
basic_command_line_parser<charT>::style(int style)
|
||||
{
|
||||
detail::cmdline::style(xstyle);
|
||||
detail::cmdline::style(style);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -111,7 +109,7 @@ namespace boost { namespace program_options {
|
||||
|
||||
template<class charT>
|
||||
basic_parsed_options<charT>
|
||||
parse_command_line(int argc, const charT* const argv[],
|
||||
parse_command_line(int argc, charT* argv[],
|
||||
const options_description& desc,
|
||||
int style,
|
||||
function1<std::pair<std::string, std::string>,
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace boost { namespace program_options {
|
||||
void
|
||||
typed_value<T, charT>::notify(const boost::any& value_store) const
|
||||
{
|
||||
const T* value = boost::any_cast<T>(&value_store);
|
||||
const T* value = boost::any_cast<const T>(&value_store);
|
||||
if (m_store_to) {
|
||||
*m_store_to = *value;
|
||||
}
|
||||
@@ -55,12 +55,13 @@ namespace boost { namespace program_options {
|
||||
{
|
||||
static std::basic_string<charT> empty;
|
||||
if (v.size() > 1)
|
||||
boost::throw_exception(validation_error(validation_error::multiple_values_not_allowed));
|
||||
else if (v.size() == 1)
|
||||
throw validation_error("multiple values not allowed");
|
||||
if (v.size() == 1)
|
||||
return v.front();
|
||||
else if (!allow_empty)
|
||||
boost::throw_exception(validation_error(validation_error::at_least_one_value_required));
|
||||
return empty;
|
||||
else if (allow_empty)
|
||||
return empty;
|
||||
else
|
||||
throw validation_error("at least one value required");
|
||||
}
|
||||
|
||||
/* Throws multiple_occurrences if 'value' is not empty. */
|
||||
@@ -143,9 +144,9 @@ namespace boost { namespace program_options {
|
||||
a validator for class T, we use it even
|
||||
when parsing vector<T>. */
|
||||
boost::any a;
|
||||
std::vector<std::basic_string<charT> > cv;
|
||||
cv.push_back(s[i]);
|
||||
validate(a, cv, (T*)0, 0);
|
||||
std::vector<std::basic_string<charT> > v;
|
||||
v.push_back(s[i]);
|
||||
validate(a, v, (T*)0, 0);
|
||||
tv->push_back(boost::any_cast<T>(a));
|
||||
}
|
||||
catch(const bad_lexical_cast& /*e*/) {
|
||||
|
||||
@@ -13,110 +13,59 @@
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
# pragma warning (push)
|
||||
# pragma warning (disable:4275) // non dll-interface class 'std::logic_error' used as base for dll-interface class 'boost::program_options::error'
|
||||
# pragma warning (disable:4251) // class 'std::vector<_Ty>' needs to have dll-interface to be used by clients of class 'boost::program_options::ambiguous_option'
|
||||
#endif
|
||||
|
||||
|
||||
namespace boost { namespace program_options {
|
||||
|
||||
/** Base class for all errors in the library. */
|
||||
class BOOST_PROGRAM_OPTIONS_DECL error : public std::logic_error {
|
||||
public:
|
||||
error(const std::string& xwhat) : std::logic_error(xwhat) {}
|
||||
error(const std::string& what) : std::logic_error(what) {}
|
||||
};
|
||||
|
||||
class BOOST_PROGRAM_OPTIONS_DECL invalid_syntax : public error {
|
||||
public:
|
||||
enum kind_t {
|
||||
long_not_allowed = 30,
|
||||
long_adjacent_not_allowed,
|
||||
short_adjacent_not_allowed,
|
||||
empty_adjacent_parameter,
|
||||
missing_parameter,
|
||||
extra_parameter,
|
||||
unrecognized_line
|
||||
};
|
||||
|
||||
invalid_syntax(const std::string& tokens, kind_t kind);
|
||||
invalid_syntax(const std::string& tokens, const std::string& msg)
|
||||
: error(std::string(msg).append(" in '").append(tokens).append("'")),
|
||||
tokens(tokens), msg(msg)
|
||||
{}
|
||||
|
||||
// gcc says that throw specification on dtor is loosened
|
||||
// without this line
|
||||
~invalid_syntax() throw() {}
|
||||
|
||||
kind_t kind() const;
|
||||
|
||||
const std::string& tokens() const;
|
||||
|
||||
protected:
|
||||
/** Used to convert kind_t to a related error text */
|
||||
static std::string error_message(kind_t kind);
|
||||
|
||||
private:
|
||||
// TODO: copy ctor might throw
|
||||
std::string m_tokens;
|
||||
|
||||
kind_t m_kind;
|
||||
std::string tokens, msg;
|
||||
};
|
||||
|
||||
/** Class thrown when option name is not recognized. */
|
||||
class BOOST_PROGRAM_OPTIONS_DECL unknown_option : public error {
|
||||
public:
|
||||
unknown_option(const std::string& name)
|
||||
: error(std::string("unknown option ").append(name)),
|
||||
m_option_name(name)
|
||||
: error(std::string("unknown option ").append(name))
|
||||
{}
|
||||
|
||||
// gcc says that throw specification on dtor is loosened
|
||||
// without this line
|
||||
~unknown_option() throw() {}
|
||||
|
||||
const std::string& get_option_name() const throw();
|
||||
|
||||
private:
|
||||
std::string m_option_name;
|
||||
};
|
||||
|
||||
/** Class thrown when there's ambiguity amoung several possible options. */
|
||||
class BOOST_PROGRAM_OPTIONS_DECL ambiguous_option : public error {
|
||||
public:
|
||||
ambiguous_option(const std::string& name,
|
||||
const std::vector<std::string>& xalternatives)
|
||||
: error(std::string("ambiguous option ").append(name))
|
||||
, m_alternatives(xalternatives)
|
||||
, m_option_name(name)
|
||||
const std::vector<std::string>& alternatives)
|
||||
: error(std::string("ambiguous option ").append(name)),
|
||||
alternatives(alternatives)
|
||||
{}
|
||||
|
||||
~ambiguous_option() throw() {}
|
||||
|
||||
const std::string& get_option_name() const throw();
|
||||
|
||||
const std::vector<std::string>& alternatives() const throw();
|
||||
|
||||
private:
|
||||
// TODO: copy ctor might throw
|
||||
std::vector<std::string> m_alternatives;
|
||||
std::string m_option_name;
|
||||
std::vector<std::string> alternatives;
|
||||
};
|
||||
|
||||
/** Class thrown when there are several option values, but
|
||||
user called a method which cannot return them all. */
|
||||
class BOOST_PROGRAM_OPTIONS_DECL multiple_values : public error {
|
||||
public:
|
||||
multiple_values()
|
||||
: error("multiple values")
|
||||
, m_option_name() {}
|
||||
|
||||
~multiple_values() throw() {}
|
||||
|
||||
void set_option_name(const std::string& option);
|
||||
|
||||
const std::string& get_option_name() const throw();
|
||||
|
||||
private:
|
||||
std::string m_option_name; // The name of the option which
|
||||
// caused the exception.
|
||||
multiple_values(const std::string& what) : error(what) {}
|
||||
};
|
||||
|
||||
/** Class thrown when there are several occurrences of an
|
||||
@@ -124,58 +73,23 @@ namespace boost { namespace program_options {
|
||||
them all. */
|
||||
class BOOST_PROGRAM_OPTIONS_DECL multiple_occurrences : public error {
|
||||
public:
|
||||
multiple_occurrences()
|
||||
: error("multiple occurrences")
|
||||
, m_option_name() {}
|
||||
|
||||
~multiple_occurrences() throw() {}
|
||||
|
||||
void set_option_name(const std::string& option);
|
||||
|
||||
const std::string& get_option_name() const throw();
|
||||
|
||||
private:
|
||||
std::string m_option_name; // The name of the option which
|
||||
// caused the exception.
|
||||
multiple_occurrences(const std::string& what) : error(what) {}
|
||||
};
|
||||
|
||||
/** Class thrown when value of option is incorrect. */
|
||||
class BOOST_PROGRAM_OPTIONS_DECL validation_error : public error {
|
||||
public:
|
||||
enum kind_t {
|
||||
multiple_values_not_allowed = 30,
|
||||
at_least_one_value_required,
|
||||
invalid_bool_value,
|
||||
invalid_option_value,
|
||||
invalid_option
|
||||
};
|
||||
|
||||
validation_error(kind_t kind,
|
||||
const std::string& option_value = "",
|
||||
const std::string& option_name = "");
|
||||
|
||||
validation_error(const std::string& what) : error(what) {}
|
||||
~validation_error() throw() {}
|
||||
|
||||
void set_option_name(const std::string& option);
|
||||
|
||||
const std::string& get_option_name() const throw();
|
||||
|
||||
const char* what() const throw();
|
||||
|
||||
protected:
|
||||
/** Used to convert kind_t to a related error text */
|
||||
static std::string error_message(kind_t kind);
|
||||
|
||||
const char* what() const throw();
|
||||
private:
|
||||
kind_t m_kind;
|
||||
mutable std::string m_message; // For on-demand formatting in 'what'
|
||||
std::string m_option_name; // The name of the option which
|
||||
// caused the exception.
|
||||
std::string m_option_value; // Optional: value of the option m_options_name
|
||||
mutable std::string m_message; // For on-demand formatting in 'what'
|
||||
|
||||
};
|
||||
|
||||
/** Class thrown if there is an invalid option value givenn */
|
||||
class BOOST_PROGRAM_OPTIONS_DECL invalid_option_value
|
||||
: public validation_error
|
||||
{
|
||||
@@ -186,23 +100,39 @@ namespace boost { namespace program_options {
|
||||
#endif
|
||||
};
|
||||
|
||||
/** Class thrown when there are too many positional options.
|
||||
This is a programming error.
|
||||
*/
|
||||
/** Class thrown when there are too many positional options. */
|
||||
class BOOST_PROGRAM_OPTIONS_DECL too_many_positional_options_error : public error {
|
||||
public:
|
||||
too_many_positional_options_error()
|
||||
: error("too many positional options")
|
||||
{}
|
||||
too_many_positional_options_error(const std::string& what)
|
||||
: error(what) {}
|
||||
};
|
||||
|
||||
/** Class thrown when there are too few positional options. */
|
||||
class BOOST_PROGRAM_OPTIONS_DECL too_few_positional_options_error : public error {
|
||||
public:
|
||||
too_few_positional_options_error(const std::string& what)
|
||||
: error(what) {}
|
||||
};
|
||||
|
||||
/** Class thrown when there are syntax errors in given command line */
|
||||
class BOOST_PROGRAM_OPTIONS_DECL invalid_command_line_syntax : public invalid_syntax {
|
||||
public:
|
||||
enum kind_t {
|
||||
long_not_allowed = 30,
|
||||
long_adjacent_not_allowed,
|
||||
short_adjacent_not_allowed,
|
||||
empty_adjacent_parameter,
|
||||
missing_parameter,
|
||||
extra_parameter
|
||||
};
|
||||
|
||||
invalid_command_line_syntax(const std::string& tokens, kind_t kind);
|
||||
kind_t kind() const;
|
||||
protected:
|
||||
static std::string error_message(kind_t kind);
|
||||
private:
|
||||
kind_t m_kind;
|
||||
};
|
||||
|
||||
/** Class thrown when there are programming error related to style */
|
||||
class BOOST_PROGRAM_OPTIONS_DECL invalid_command_line_style : public error {
|
||||
public:
|
||||
invalid_command_line_style(const std::string& msg)
|
||||
@@ -210,34 +140,7 @@ namespace boost { namespace program_options {
|
||||
{}
|
||||
};
|
||||
|
||||
/** Class thrown if config file can not be read */
|
||||
class BOOST_PROGRAM_OPTIONS_DECL reading_file : public error {
|
||||
public:
|
||||
reading_file(const char* filename)
|
||||
: error(std::string("can not read file ").append(filename))
|
||||
{}
|
||||
};
|
||||
|
||||
/** Class thrown when a required/mandatory option is missing */
|
||||
class BOOST_PROGRAM_OPTIONS_DECL required_option : public error {
|
||||
public:
|
||||
required_option(const std::string& name)
|
||||
: error(std::string("missing required option ").append(name))
|
||||
, m_option_name(name)
|
||||
{}
|
||||
|
||||
~required_option() throw() {}
|
||||
|
||||
const std::string& get_option_name() const throw();
|
||||
|
||||
private:
|
||||
std::string m_option_name; // The name of the option which
|
||||
// caused the exception.
|
||||
};
|
||||
}}
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
# pragma warning (pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -23,17 +23,10 @@ namespace boost { namespace program_options {
|
||||
template<class charT>
|
||||
class basic_option {
|
||||
public:
|
||||
basic_option()
|
||||
: position_key(-1)
|
||||
, unregistered(false)
|
||||
, case_insensitive(false)
|
||||
{}
|
||||
basic_option(const std::string& xstring_key,
|
||||
const std::vector< std::string> &xvalue)
|
||||
: string_key(xstring_key)
|
||||
, value(xvalue)
|
||||
, unregistered(false)
|
||||
, case_insensitive(false)
|
||||
basic_option() : position_key(-1), unregistered(false) {}
|
||||
basic_option(const std::string& string_key,
|
||||
const std::vector< std::string> &value)
|
||||
: string_key(string_key), value(value), unregistered(false)
|
||||
{}
|
||||
|
||||
/** String key of this option. Intentionally independent of the template
|
||||
@@ -57,10 +50,7 @@ namespace boost { namespace program_options {
|
||||
recovered from the "original_tokens" member.
|
||||
*/
|
||||
bool unregistered;
|
||||
/** True if string_key has to be handled
|
||||
case insensitive.
|
||||
*/
|
||||
bool case_insensitive;
|
||||
|
||||
};
|
||||
typedef basic_option<char> option;
|
||||
typedef basic_option<wchar_t> woption;
|
||||
|
||||
@@ -25,12 +25,6 @@
|
||||
|
||||
#include <iosfwd>
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
# pragma warning (push)
|
||||
# pragma warning (disable:4251) // class 'boost::shared_ptr<T>' needs to have dll-interface to be used by clients of class 'boost::program_options::option_description'
|
||||
#endif
|
||||
|
||||
|
||||
/** Boost namespace */
|
||||
namespace boost {
|
||||
/** Namespace for the library. */
|
||||
@@ -71,7 +65,7 @@ namespace program_options {
|
||||
The 'name' parameter is interpreted by the following rules:
|
||||
- if there's no "," character in 'name', it specifies long name
|
||||
- otherwise, the part before "," specifies long name and the part
|
||||
after -- short name.
|
||||
after -- long name.
|
||||
*/
|
||||
option_description(const char* name,
|
||||
const value_semantic* s);
|
||||
@@ -87,12 +81,11 @@ namespace program_options {
|
||||
enum match_result { no_match, full_match, approximate_match };
|
||||
|
||||
/** Given 'option', specified in the input source,
|
||||
returns 'true' if 'option' specifies *this.
|
||||
return 'true' is 'option' specifies *this.
|
||||
*/
|
||||
match_result match(const std::string& option, bool approx,
|
||||
bool long_ignore_case, bool short_ignore_case) const;
|
||||
match_result match(const std::string& option, bool approx) const;
|
||||
|
||||
/** Returns the key that should identify the option, in
|
||||
/** Return the key that should identify the option, in
|
||||
particular in the variables_map class.
|
||||
The 'option' parameter is the option spelling from the
|
||||
input source.
|
||||
@@ -113,7 +106,7 @@ namespace program_options {
|
||||
/// Returns the option name, formatted suitably for usage message.
|
||||
std::string format_name() const;
|
||||
|
||||
/** Returns the parameter name and properties, formatted suitably for
|
||||
/** Return the parameter name and properties, formatted suitably for
|
||||
usage message. */
|
||||
std::string format_parameter() const;
|
||||
|
||||
@@ -165,18 +158,12 @@ namespace program_options {
|
||||
static const unsigned m_default_line_length;
|
||||
|
||||
/** Creates the instance. */
|
||||
options_description(unsigned line_length = m_default_line_length,
|
||||
unsigned min_description_length = m_default_line_length / 2);
|
||||
options_description(unsigned line_length = m_default_line_length);
|
||||
/** Creates the instance. The 'caption' parameter gives the name of
|
||||
this 'options_description' instance. Primarily useful for output.
|
||||
The 'description_length' specifies the number of columns that
|
||||
should be reserved for the description text; if the option text
|
||||
encroaches into this, then the description will start on the next
|
||||
line.
|
||||
*/
|
||||
options_description(const std::string& caption,
|
||||
unsigned line_length = m_default_line_length,
|
||||
unsigned min_description_length = m_default_line_length / 2);
|
||||
unsigned line_length = m_default_line_length);
|
||||
/** Adds new variable description. Throws duplicate_variable_error if
|
||||
either short or long name matches that of already present one.
|
||||
*/
|
||||
@@ -198,15 +185,11 @@ namespace program_options {
|
||||
*/
|
||||
options_description_easy_init add_options();
|
||||
|
||||
const option_description& find(const std::string& name,
|
||||
bool approx,
|
||||
bool long_ignore_case = false,
|
||||
bool short_ignore_case = false) const;
|
||||
const option_description& find(const std::string& name, bool approx)
|
||||
const;
|
||||
|
||||
const option_description* find_nothrow(const std::string& name,
|
||||
bool approx,
|
||||
bool long_ignore_case = false,
|
||||
bool short_ignore_case = false) const;
|
||||
bool approx) const;
|
||||
|
||||
|
||||
const std::vector< shared_ptr<option_description> >& options() const;
|
||||
@@ -217,7 +200,7 @@ namespace program_options {
|
||||
friend BOOST_PROGRAM_OPTIONS_DECL std::ostream& operator<<(std::ostream& os,
|
||||
const options_description& desc);
|
||||
|
||||
/** Outputs 'desc' to the specified stream, calling 'f' to output each
|
||||
/** Output 'desc' to the specified stream, calling 'f' to output each
|
||||
option_description element. */
|
||||
void print(std::ostream& os) const;
|
||||
|
||||
@@ -230,8 +213,6 @@ namespace program_options {
|
||||
|
||||
std::string m_caption;
|
||||
const unsigned m_line_length;
|
||||
const unsigned m_min_description_length;
|
||||
|
||||
// Data organization is chosen because:
|
||||
// - there could be two names for one option
|
||||
// - option_add_proxy needs to know the last added option
|
||||
@@ -253,12 +234,8 @@ namespace program_options {
|
||||
/** Class thrown when duplicate option description is found. */
|
||||
class BOOST_PROGRAM_OPTIONS_DECL duplicate_option_error : public error {
|
||||
public:
|
||||
duplicate_option_error(const std::string& xwhat) : error(xwhat) {}
|
||||
duplicate_option_error(const std::string& what) : error(what) {}
|
||||
};
|
||||
}}
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
# pragma warning (pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -17,11 +17,6 @@
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
# pragma warning (push)
|
||||
# pragma warning (disable:4251) // class 'std::vector<_Ty>' needs to have dll-interface to be used by clients of class 'boost::program_options::basic_parsed_options<wchar_t>'
|
||||
#endif
|
||||
|
||||
namespace boost { namespace program_options {
|
||||
|
||||
class options_description;
|
||||
@@ -36,8 +31,8 @@ namespace boost { namespace program_options {
|
||||
template<class charT>
|
||||
class basic_parsed_options {
|
||||
public:
|
||||
explicit basic_parsed_options(const options_description* xdescription)
|
||||
: description(xdescription) {}
|
||||
explicit basic_parsed_options(const options_description* description)
|
||||
: description(description) {}
|
||||
/** Options found in the source. */
|
||||
std::vector< basic_option<charT> > options;
|
||||
/** Options description that was used for parsing.
|
||||
@@ -100,7 +95,7 @@ namespace boost { namespace program_options {
|
||||
/** Creates a command line parser for the specified arguments
|
||||
list. The parameters should be the same as passed to 'main'.
|
||||
*/
|
||||
basic_command_line_parser(int argc, const charT* const argv[]);
|
||||
basic_command_line_parser(int argc, charT* argv[]);
|
||||
|
||||
/** Sets options descriptions to use. */
|
||||
basic_command_line_parser& options(const options_description& desc);
|
||||
@@ -144,7 +139,7 @@ namespace boost { namespace program_options {
|
||||
*/
|
||||
template<class charT>
|
||||
basic_parsed_options<charT>
|
||||
parse_command_line(int argc, const charT* const argv[],
|
||||
parse_command_line(int argc, charT* argv[],
|
||||
const options_description&,
|
||||
int style = 0,
|
||||
function1<std::pair<std::string, std::string>,
|
||||
@@ -152,8 +147,6 @@ namespace boost { namespace program_options {
|
||||
= ext_parser());
|
||||
|
||||
/** Parse a config file.
|
||||
|
||||
Read from given stream.
|
||||
*/
|
||||
template<class charT>
|
||||
#if ! BOOST_WORKAROUND(__ICL, BOOST_TESTED_AT(700))
|
||||
@@ -163,19 +156,6 @@ namespace boost { namespace program_options {
|
||||
parse_config_file(std::basic_istream<charT>&, const options_description&,
|
||||
bool allow_unregistered = false);
|
||||
|
||||
/** Parse a config file.
|
||||
|
||||
Read from file with the given name. The character type is
|
||||
passed to the file stream.
|
||||
*/
|
||||
template<class charT>
|
||||
#if ! BOOST_WORKAROUND(__ICL, BOOST_TESTED_AT(700))
|
||||
BOOST_PROGRAM_OPTIONS_DECL
|
||||
#endif
|
||||
basic_parsed_options<charT>
|
||||
parse_config_file(const char* filename, const options_description&,
|
||||
bool allow_unregistered = false);
|
||||
|
||||
/** Controls if the 'collect_unregistered' function should
|
||||
include positional options, or not. */
|
||||
enum collect_unrecognized_mode
|
||||
@@ -222,24 +202,6 @@ namespace boost { namespace program_options {
|
||||
BOOST_PROGRAM_OPTIONS_DECL parsed_options
|
||||
parse_environment(const options_description&, const char* prefix);
|
||||
|
||||
/** Splits a given string to a collection of single strings which
|
||||
can be passed to command_line_parser. The second parameter is
|
||||
used to specify a collection of possible seperator chars used
|
||||
for splitting. The seperator is defaulted to space " ".
|
||||
Splitting is done in a unix style way, with respect to quotes '"'
|
||||
and escape characters '\'
|
||||
*/
|
||||
BOOST_PROGRAM_OPTIONS_DECL std::vector<std::string>
|
||||
split_unix(const std::string& cmdline, const std::string& seperator = " \t",
|
||||
const std::string& quote = "'\"", const std::string& escape = "\\");
|
||||
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
/** @overload */
|
||||
BOOST_PROGRAM_OPTIONS_DECL std::vector<std::wstring>
|
||||
split_unix(const std::wstring& cmdline, const std::wstring& seperator = L" \t",
|
||||
const std::wstring& quote = L"'\"", const std::wstring& escape = L"\\");
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
/** Parses the char* string which is passed to WinMain function on
|
||||
windows. This function is provided for convenience, and because it's
|
||||
|
||||
@@ -11,11 +11,6 @@
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
# pragma warning (push)
|
||||
# pragma warning (disable:4251) // class 'std::vector<_Ty>' needs to have dll-interface to be used by clients of class 'boost::program_options::positional_options_description'
|
||||
#endif
|
||||
|
||||
namespace boost { namespace program_options {
|
||||
|
||||
/** Describes positional options.
|
||||
@@ -46,7 +41,7 @@ namespace boost { namespace program_options {
|
||||
add(const char* name, int max_count);
|
||||
|
||||
/** Returns the maximum number of positional options that can
|
||||
be present. Can return (numeric_limits<unsigned>::max)() to
|
||||
be present. Can return numeric_limits<unsigned>::max() to
|
||||
indicate unlimited number. */
|
||||
unsigned max_total_count() const;
|
||||
|
||||
@@ -66,9 +61,5 @@ namespace boost { namespace program_options {
|
||||
|
||||
}}
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
# pragma warning (pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -43,11 +43,6 @@ namespace boost { namespace program_options {
|
||||
other sources are discarded.
|
||||
*/
|
||||
virtual bool is_composing() const = 0;
|
||||
|
||||
/** Returns true if value must be given. Non-optional value
|
||||
|
||||
*/
|
||||
virtual bool is_required() const = 0;
|
||||
|
||||
/** Parses a group of tokens that specify a value of option.
|
||||
Stores the result in 'value_store', using whatever representation
|
||||
@@ -136,8 +131,6 @@ namespace boost { namespace program_options {
|
||||
unsigned max_tokens() const;
|
||||
|
||||
bool is_composing() const { return false; }
|
||||
|
||||
bool is_required() const { return false; }
|
||||
|
||||
/** If 'value_store' is already initialized, or new_tokens
|
||||
has more than one elements, throws. Otherwise, assigns
|
||||
@@ -184,8 +177,7 @@ namespace boost { namespace program_options {
|
||||
the value when it's known. The parameter can be NULL. */
|
||||
typed_value(T* store_to)
|
||||
: m_store_to(store_to), m_composing(false),
|
||||
m_multitoken(false), m_zero_tokens(false),
|
||||
m_required(false)
|
||||
m_multitoken(false), m_zero_tokens(false)
|
||||
{}
|
||||
|
||||
/** Specifies default value, which will be used
|
||||
@@ -274,12 +266,6 @@ namespace boost { namespace program_options {
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Specifies that the value must occur. */
|
||||
typed_value* required()
|
||||
{
|
||||
m_required = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public: // value semantic overrides
|
||||
|
||||
@@ -306,7 +292,6 @@ namespace boost { namespace program_options {
|
||||
}
|
||||
}
|
||||
|
||||
bool is_required() const { return m_required; }
|
||||
|
||||
/** Creates an instance of the 'validator' class and calls
|
||||
its operator() to perform the actual conversion. */
|
||||
@@ -350,7 +335,7 @@ namespace boost { namespace program_options {
|
||||
std::string m_default_value_as_text;
|
||||
boost::any m_implicit_value;
|
||||
std::string m_implicit_value_as_text;
|
||||
bool m_composing, m_implicit, m_multitoken, m_zero_tokens, m_required;
|
||||
bool m_composing, m_implicit, m_multitoken, m_zero_tokens;
|
||||
boost::function1<void, const T&> m_notifier;
|
||||
};
|
||||
|
||||
|
||||
@@ -16,11 +16,6 @@
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
# pragma warning (push)
|
||||
# pragma warning (disable:4251) // 'boost::program_options::variable_value::v' : class 'boost::any' needs to have dll-interface to be used by clients of class 'boost::program_options::variable_value
|
||||
#endif
|
||||
|
||||
namespace boost { namespace program_options {
|
||||
|
||||
template<class charT>
|
||||
@@ -58,8 +53,8 @@ namespace boost { namespace program_options {
|
||||
class BOOST_PROGRAM_OPTIONS_DECL variable_value {
|
||||
public:
|
||||
variable_value() : m_defaulted(false) {}
|
||||
variable_value(const boost::any& xv, bool xdefaulted)
|
||||
: v(xv), m_defaulted(xdefaulted)
|
||||
variable_value(const boost::any& v, bool defaulted)
|
||||
: v(v), m_defaulted(defaulted)
|
||||
{}
|
||||
|
||||
/** If stored value if of type T, returns that value. Otherwise,
|
||||
@@ -97,8 +92,7 @@ namespace boost { namespace program_options {
|
||||
friend BOOST_PROGRAM_OPTIONS_DECL
|
||||
void store(const basic_parsed_options<char>& options,
|
||||
variables_map& m, bool);
|
||||
|
||||
friend BOOST_PROGRAM_OPTIONS_DECL class variables_map;
|
||||
friend BOOST_PROGRAM_OPTIONS_DECL void notify(variables_map& m);
|
||||
};
|
||||
|
||||
/** Implements string->string mapping with convenient value casting
|
||||
@@ -153,8 +147,6 @@ namespace boost { namespace program_options {
|
||||
// Resolve conflict between inherited operators.
|
||||
const variable_value& operator[](const std::string& name) const
|
||||
{ return abstract_variables_map::operator[](name); }
|
||||
|
||||
void notify();
|
||||
|
||||
private:
|
||||
/** Implementation of abstract_variables_map::get
|
||||
@@ -169,10 +161,6 @@ namespace boost { namespace program_options {
|
||||
void store(const basic_parsed_options<char>& options,
|
||||
variables_map& xm,
|
||||
bool utf8);
|
||||
|
||||
/** Names of required options, filled by parser which has
|
||||
access to options_description. */
|
||||
std::set<std::string> m_required;
|
||||
};
|
||||
|
||||
|
||||
|
||||
250
src/cmdline.cpp
250
src/cmdline.cpp
@@ -23,7 +23,6 @@
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <cctype>
|
||||
#include <climits>
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
@@ -34,18 +33,16 @@ namespace boost { namespace program_options {
|
||||
using namespace std;
|
||||
using namespace boost::program_options::command_line_style;
|
||||
|
||||
invalid_syntax::
|
||||
invalid_syntax(const string& tokens, kind_t kind)
|
||||
: error(error_message(kind).append(" in '").append(tokens).append("'"))
|
||||
, m_tokens(tokens)
|
||||
, m_kind(kind)
|
||||
invalid_command_line_syntax::
|
||||
invalid_command_line_syntax(const std::string& tokens, kind_t kind)
|
||||
: invalid_syntax(tokens, error_message(kind)), m_kind(kind)
|
||||
{}
|
||||
|
||||
string
|
||||
invalid_syntax::error_message(kind_t kind)
|
||||
|
||||
std::string
|
||||
invalid_command_line_syntax::error_message(kind_t kind)
|
||||
{
|
||||
// Initially, store the message in 'const char*' variable,
|
||||
// to avoid conversion to string in all cases.
|
||||
// to avoid conversion to std::string in all cases.
|
||||
const char* msg;
|
||||
switch(kind)
|
||||
{
|
||||
@@ -67,31 +64,18 @@ namespace boost { namespace program_options {
|
||||
case extra_parameter:
|
||||
msg = "extra parameter";
|
||||
break;
|
||||
case unrecognized_line:
|
||||
msg = "unrecognized line";
|
||||
break;
|
||||
default:
|
||||
msg = "unknown error";
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
invalid_syntax::kind_t
|
||||
invalid_syntax::kind() const
|
||||
invalid_command_line_syntax::kind_t
|
||||
invalid_command_line_syntax::kind() const
|
||||
{
|
||||
return m_kind;
|
||||
}
|
||||
|
||||
const string&
|
||||
invalid_syntax::tokens() const
|
||||
{
|
||||
return m_tokens;
|
||||
}
|
||||
|
||||
invalid_command_line_syntax::
|
||||
invalid_command_line_syntax(const string& tokens, kind_t kind)
|
||||
: invalid_syntax(tokens, kind)
|
||||
{}
|
||||
|
||||
}}
|
||||
|
||||
@@ -105,7 +89,7 @@ namespace boost { namespace program_options { namespace detail {
|
||||
#endif
|
||||
|
||||
|
||||
cmdline::cmdline(const vector<string>& args)
|
||||
cmdline::cmdline(const std::vector<std::string>& args)
|
||||
{
|
||||
init(args);
|
||||
}
|
||||
@@ -122,7 +106,7 @@ namespace boost { namespace program_options { namespace detail {
|
||||
}
|
||||
|
||||
void
|
||||
cmdline::init(const vector<string>& args)
|
||||
cmdline::init(const std::vector<std::string>& args)
|
||||
{
|
||||
this->args = args;
|
||||
m_style = command_line_style::default_style;
|
||||
@@ -167,17 +151,11 @@ namespace boost { namespace program_options { namespace detail {
|
||||
error = "style disallows all characters for short options";
|
||||
|
||||
if (error)
|
||||
boost::throw_exception(invalid_command_line_style(error));
|
||||
throw invalid_command_line_style(error);
|
||||
|
||||
// Need to check that if guessing and long disguise are enabled
|
||||
// -f will mean the same as -foo
|
||||
}
|
||||
|
||||
bool
|
||||
cmdline::is_style_active(style_t style) const
|
||||
{
|
||||
return ((m_style & style) ? true : false);
|
||||
}
|
||||
|
||||
void
|
||||
cmdline::set_options_description(const options_description& desc)
|
||||
@@ -217,24 +195,24 @@ namespace boost { namespace program_options { namespace detail {
|
||||
|
||||
if (m_additional_parser)
|
||||
style_parsers.push_back(
|
||||
boost::bind(&cmdline::handle_additional_parser, this, _1));
|
||||
bind(&cmdline::handle_additional_parser, this, _1));
|
||||
|
||||
if (m_style & allow_long)
|
||||
style_parsers.push_back(
|
||||
boost::bind(&cmdline::parse_long_option, this, _1));
|
||||
bind(&cmdline::parse_long_option, this, _1));
|
||||
|
||||
if ((m_style & allow_long_disguise))
|
||||
style_parsers.push_back(
|
||||
boost::bind(&cmdline::parse_disguised_long_option, this, _1));
|
||||
bind(&cmdline::parse_disguised_long_option, this, _1));
|
||||
|
||||
if ((m_style & allow_short) && (m_style & allow_dash_for_short))
|
||||
style_parsers.push_back(
|
||||
boost::bind(&cmdline::parse_short_option, this, _1));
|
||||
bind(&cmdline::parse_short_option, this, _1));
|
||||
|
||||
if ((m_style & allow_short) && (m_style & allow_slash_for_short))
|
||||
style_parsers.push_back(boost::bind(&cmdline::parse_dos_option, this, _1));
|
||||
style_parsers.push_back(bind(&cmdline::parse_dos_option, this, _1));
|
||||
|
||||
style_parsers.push_back(boost::bind(&cmdline::parse_terminator, this, _1));
|
||||
style_parsers.push_back(bind(&cmdline::parse_terminator, this, _1));
|
||||
|
||||
vector<option> result;
|
||||
while(!args.empty())
|
||||
@@ -251,12 +229,12 @@ namespace boost { namespace program_options { namespace detail {
|
||||
{
|
||||
vector<string> e;
|
||||
for(unsigned k = 0; k < next.size()-1; ++k) {
|
||||
finish_option(next[k], e, style_parsers);
|
||||
finish_option(next[k], e);
|
||||
}
|
||||
// For the last option, pass the unparsed tokens
|
||||
// so that they can be added to next.back()'s values
|
||||
// if appropriate.
|
||||
finish_option(next.back(), args, style_parsers);
|
||||
finish_option(next.back(), args);
|
||||
for (unsigned j = 0; j < next.size(); ++j)
|
||||
result.push_back(next[j]);
|
||||
}
|
||||
@@ -276,64 +254,6 @@ namespace boost { namespace program_options { namespace detail {
|
||||
}
|
||||
}
|
||||
|
||||
/* If an key option is followed by a positional option,
|
||||
can can consume more tokens (e.g. it's multitoke option),
|
||||
give those tokens to it. */
|
||||
vector<option> result2;
|
||||
for (unsigned i = 0; i < result.size(); ++i)
|
||||
{
|
||||
result2.push_back(result[i]);
|
||||
option& opt = result2.back();
|
||||
|
||||
if (opt.string_key.empty())
|
||||
continue;
|
||||
|
||||
const option_description* xd =
|
||||
m_desc->find_nothrow(opt.string_key,
|
||||
is_style_active(allow_guessing),
|
||||
is_style_active(long_case_insensitive),
|
||||
is_style_active(short_case_insensitive));
|
||||
if (!xd)
|
||||
continue;
|
||||
|
||||
unsigned min_tokens = xd->semantic()->min_tokens();
|
||||
unsigned max_tokens = xd->semantic()->max_tokens();
|
||||
if (min_tokens < max_tokens && opt.value.size() < max_tokens)
|
||||
{
|
||||
// This option may grab some more tokens.
|
||||
// We only allow to grab tokens that are not already
|
||||
// recognized as key options.
|
||||
|
||||
int can_take_more = max_tokens - opt.value.size();
|
||||
unsigned j = i+1;
|
||||
for (; can_take_more && j < result.size(); --can_take_more, ++j)
|
||||
{
|
||||
option& opt2 = result[j];
|
||||
if (!opt2.string_key.empty())
|
||||
break;
|
||||
|
||||
if (opt2.position_key == INT_MAX)
|
||||
{
|
||||
// We use INT_MAX to mark positional options that
|
||||
// were found after the '--' terminator and therefore
|
||||
// should stay positional forever.
|
||||
break;
|
||||
}
|
||||
|
||||
assert(opt2.value.size() == 1);
|
||||
|
||||
opt.value.push_back(opt2.value[0]);
|
||||
|
||||
assert(opt2.original_tokens.size() == 1);
|
||||
|
||||
opt.original_tokens.push_back(opt2.original_tokens[0]);
|
||||
}
|
||||
i = j-1;
|
||||
}
|
||||
}
|
||||
result.swap(result2);
|
||||
|
||||
|
||||
// Assign position keys to positional options.
|
||||
int position_key = 0;
|
||||
for(unsigned i = 0; i < result.size(); ++i) {
|
||||
@@ -349,45 +269,29 @@ namespace boost { namespace program_options { namespace detail {
|
||||
if (opt.position_key != -1) {
|
||||
if (position >= m_positional->max_total_count())
|
||||
{
|
||||
boost::throw_exception(too_many_positional_options_error());
|
||||
throw too_many_positional_options_error(
|
||||
"too many positional options");
|
||||
}
|
||||
opt.string_key = m_positional->name_for_position(position);
|
||||
++position;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// set case sensitive flag
|
||||
for (unsigned i = 0; i < result.size(); ++i) {
|
||||
if (result[i].string_key.size() > 2 ||
|
||||
(result[i].string_key.size() > 1 && result[i].string_key[0] != '-'))
|
||||
{
|
||||
// it is a long option
|
||||
result[i].case_insensitive = is_style_active(long_case_insensitive);
|
||||
}
|
||||
else
|
||||
{
|
||||
// it is a short option
|
||||
result[i].case_insensitive = is_style_active(short_case_insensitive);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
cmdline::finish_option(option& opt,
|
||||
vector<string>& other_tokens,
|
||||
const vector<style_parser>& style_parsers)
|
||||
{
|
||||
vector<string>& other_tokens)
|
||||
{
|
||||
if (opt.string_key.empty())
|
||||
return;
|
||||
|
||||
// First check that the option is valid, and get its description.
|
||||
// TODO: case-sensitivity.
|
||||
const option_description* xd = m_desc->find_nothrow(opt.string_key,
|
||||
is_style_active(allow_guessing),
|
||||
is_style_active(long_case_insensitive),
|
||||
is_style_active(short_case_insensitive));
|
||||
(m_style & allow_guessing) ? true : false);
|
||||
|
||||
if (!xd)
|
||||
{
|
||||
@@ -418,46 +322,23 @@ namespace boost { namespace program_options { namespace detail {
|
||||
|
||||
if (present_tokens >= min_tokens)
|
||||
{
|
||||
if (!opt.value.empty() && max_tokens == 0)
|
||||
{
|
||||
boost::throw_exception(invalid_command_line_syntax(opt.string_key,
|
||||
invalid_command_line_syntax::extra_parameter));
|
||||
if (!opt.value.empty() && max_tokens == 0) {
|
||||
throw invalid_command_line_syntax(opt.string_key,
|
||||
invalid_command_line_syntax::extra_parameter);
|
||||
}
|
||||
|
||||
// If an option wants, at minimum, N tokens, we grab them there,
|
||||
// when adding these tokens as values to current option we check
|
||||
// if they look like options
|
||||
if (opt.value.size() <= min_tokens)
|
||||
{
|
||||
min_tokens -= opt.value.size();
|
||||
}
|
||||
else
|
||||
{
|
||||
min_tokens = 0;
|
||||
}
|
||||
max_tokens -= opt.value.size();
|
||||
|
||||
// A value is optional if min_tokens == 0, but max_tokens > 0.
|
||||
// If a value is optional, it must appear in opt.value (because
|
||||
// it was 'adjacent'. Otherwise, remove the expectation of a
|
||||
// non-adjacent value. (For now, we just check max_tokens == 1,
|
||||
// as there is no current support for max_tokens>1)
|
||||
if (min_tokens == 0 && max_tokens == 1 && opt.value.empty())
|
||||
--max_tokens;
|
||||
|
||||
// Everything's OK, move the values to the result.
|
||||
for(;!other_tokens.empty() && min_tokens--; )
|
||||
{
|
||||
// check if extra parameter looks like a known option
|
||||
// we use style parsers to check if it is syntactically an option,
|
||||
// additionally we check if an option_description exists
|
||||
vector<option> followed_option;
|
||||
vector<string> next_token(1, other_tokens[0]);
|
||||
for (unsigned i = 0; followed_option.empty() && i < style_parsers.size(); ++i)
|
||||
{
|
||||
followed_option = style_parsers[i](next_token);
|
||||
}
|
||||
if (!followed_option.empty())
|
||||
{
|
||||
const option_description* od = m_desc->find_nothrow(other_tokens[0],
|
||||
is_style_active(allow_guessing),
|
||||
is_style_active(long_case_insensitive),
|
||||
is_style_active(short_case_insensitive));
|
||||
if (od)
|
||||
boost::throw_exception(invalid_command_line_syntax(opt.string_key,
|
||||
invalid_command_line_syntax::missing_parameter));
|
||||
}
|
||||
for(;!other_tokens.empty() && max_tokens--; ) {
|
||||
opt.value.push_back(other_tokens[0]);
|
||||
opt.original_tokens.push_back(other_tokens[0]);
|
||||
other_tokens.erase(other_tokens.begin());
|
||||
@@ -465,17 +346,17 @@ namespace boost { namespace program_options { namespace detail {
|
||||
}
|
||||
else
|
||||
{
|
||||
boost::throw_exception(invalid_command_line_syntax(opt.string_key,
|
||||
invalid_command_line_syntax::missing_parameter));
|
||||
throw invalid_command_line_syntax(opt.string_key,
|
||||
invalid_command_line_syntax::missing_parameter);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
vector<option>
|
||||
cmdline::parse_long_option(vector<string>& args)
|
||||
std::vector<option>
|
||||
cmdline::parse_long_option(std::vector<string>& args)
|
||||
{
|
||||
vector<option> result;
|
||||
const string& tok = args[0];
|
||||
const std::string& tok = args[0];
|
||||
if (tok.size() >= 3 && tok[0] == '-' && tok[1] == '-')
|
||||
{
|
||||
string name, adjacent;
|
||||
@@ -486,8 +367,8 @@ namespace boost { namespace program_options { namespace detail {
|
||||
name = tok.substr(2, p-2);
|
||||
adjacent = tok.substr(p+1);
|
||||
if (adjacent.empty())
|
||||
boost::throw_exception( invalid_command_line_syntax(name,
|
||||
invalid_command_line_syntax::empty_adjacent_parameter) );
|
||||
throw invalid_command_line_syntax(name,
|
||||
invalid_command_line_syntax::empty_adjacent_parameter);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -505,10 +386,10 @@ namespace boost { namespace program_options { namespace detail {
|
||||
}
|
||||
|
||||
|
||||
vector<option>
|
||||
cmdline::parse_short_option(vector<string>& args)
|
||||
std::vector<option>
|
||||
cmdline::parse_short_option(std::vector<string>& args)
|
||||
{
|
||||
const string& tok = args[0];
|
||||
const std::string& tok = args[0];
|
||||
if (tok.size() >= 2 && tok[0] == '-' && tok[1] != '-')
|
||||
{
|
||||
vector<option> result;
|
||||
@@ -524,8 +405,7 @@ namespace boost { namespace program_options { namespace detail {
|
||||
// option.
|
||||
for(;;) {
|
||||
const option_description* d
|
||||
= m_desc->find_nothrow(name, false, false,
|
||||
is_style_active(short_case_insensitive));
|
||||
= m_desc->find_nothrow(name, false);
|
||||
|
||||
// FIXME: check for 'allow_sticky'.
|
||||
if (d && (m_style & allow_sticky) &&
|
||||
@@ -557,14 +437,14 @@ namespace boost { namespace program_options { namespace detail {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return vector<option>();
|
||||
return std::vector<option>();
|
||||
}
|
||||
|
||||
vector<option>
|
||||
cmdline::parse_dos_option(vector<string>& args)
|
||||
std::vector<option>
|
||||
cmdline::parse_dos_option(std::vector<string>& args)
|
||||
{
|
||||
vector<option> result;
|
||||
const string& tok = args[0];
|
||||
const std::string& tok = args[0];
|
||||
if (tok.size() >= 2 && tok[0] == '/')
|
||||
{
|
||||
string name = "-" + tok.substr(1,1);
|
||||
@@ -581,18 +461,16 @@ namespace boost { namespace program_options { namespace detail {
|
||||
return result;
|
||||
}
|
||||
|
||||
vector<option>
|
||||
cmdline::parse_disguised_long_option(vector<string>& args)
|
||||
std::vector<option>
|
||||
cmdline::parse_disguised_long_option(std::vector<string>& args)
|
||||
{
|
||||
const string& tok = args[0];
|
||||
const std::string& tok = args[0];
|
||||
if (tok.size() >= 2 &&
|
||||
((tok[0] == '-' && tok[1] != '-') ||
|
||||
((m_style & allow_slash_for_short) && tok[0] == '/')))
|
||||
{
|
||||
if (m_desc->find_nothrow(tok.substr(1, tok.find('=')-1),
|
||||
is_style_active(allow_guessing),
|
||||
is_style_active(long_case_insensitive),
|
||||
is_style_active(short_case_insensitive)))
|
||||
(m_style & allow_guessing) ? true : false))
|
||||
{
|
||||
args[0].insert(0, "-");
|
||||
if (args[0][1] == '/')
|
||||
@@ -603,19 +481,17 @@ namespace boost { namespace program_options { namespace detail {
|
||||
return vector<option>();
|
||||
}
|
||||
|
||||
vector<option>
|
||||
cmdline::parse_terminator(vector<string>& args)
|
||||
std::vector<option>
|
||||
cmdline::parse_terminator(std::vector<std::string>& args)
|
||||
{
|
||||
vector<option> result;
|
||||
const string& tok = args[0];
|
||||
const std::string& tok = args[0];
|
||||
if (tok == "--")
|
||||
{
|
||||
for(unsigned i = 1; i < args.size(); ++i)
|
||||
{
|
||||
option opt;
|
||||
opt.value.push_back(args[i]);
|
||||
opt.original_tokens.push_back(args[i]);
|
||||
opt.position_key = INT_MAX;
|
||||
result.push_back(opt);
|
||||
}
|
||||
args.clear();
|
||||
@@ -623,8 +499,8 @@ namespace boost { namespace program_options { namespace detail {
|
||||
return result;
|
||||
}
|
||||
|
||||
vector<option>
|
||||
cmdline::handle_additional_parser(vector<string>& args)
|
||||
std::vector<option>
|
||||
cmdline::handle_additional_parser(std::vector<std::string>& args)
|
||||
{
|
||||
vector<option> result;
|
||||
pair<string, string> r = m_additional_parser(args[0]);
|
||||
|
||||
@@ -105,19 +105,19 @@ namespace boost { namespace program_options { namespace detail {
|
||||
bool registered = allowed_option(name);
|
||||
if (!registered && !m_allow_unregistered)
|
||||
boost::throw_exception(unknown_option(name));
|
||||
|
||||
|
||||
if (value.empty())
|
||||
boost::throw_exception(invalid_syntax(s, "no value given"));
|
||||
|
||||
found = true;
|
||||
this->value().string_key = name;
|
||||
this->value().value.clear();
|
||||
this->value().value.push_back(value);
|
||||
this->value().unregistered = !registered;
|
||||
this->value().original_tokens.clear();
|
||||
this->value().original_tokens.push_back(name);
|
||||
this->value().original_tokens.push_back(value);
|
||||
break;
|
||||
|
||||
} else {
|
||||
boost::throw_exception(invalid_syntax(s, invalid_syntax::unrecognized_line));
|
||||
boost::throw_exception(invalid_syntax(s, "unrecognized line"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace boost { namespace detail {
|
||||
{
|
||||
std::basic_string<ToChar> result;
|
||||
|
||||
std::mbstate_t state = std::mbstate_t();
|
||||
std::mbstate_t state = {0};
|
||||
|
||||
const FromChar* from = s.data();
|
||||
const FromChar* from_end = s.data() + s.size();
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#define BOOST_PROGRAM_OPTIONS_SOURCE
|
||||
#include <boost/program_options/config.hpp>
|
||||
#include <boost/program_options/options_description.hpp>
|
||||
// FIXME: this is only to get multiple_occurences class
|
||||
// FIXME: this is only to get multiple_occureces class
|
||||
// should move that to a separate headers.
|
||||
#include <boost/program_options/parsers.hpp>
|
||||
|
||||
@@ -28,22 +28,6 @@ using namespace std;
|
||||
|
||||
namespace boost { namespace program_options {
|
||||
|
||||
namespace {
|
||||
|
||||
template< class charT >
|
||||
std::basic_string< charT > tolower_(const std::basic_string< charT >& str)
|
||||
{
|
||||
std::basic_string< charT > result;
|
||||
for (typename std::basic_string< charT >::size_type i = 0; i < str.size(); ++i)
|
||||
{
|
||||
result.append(1, static_cast< charT >(std::tolower(str[i])));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
} // unnamed namespace
|
||||
|
||||
|
||||
option_description::option_description()
|
||||
{
|
||||
}
|
||||
@@ -71,51 +55,37 @@ namespace boost { namespace program_options {
|
||||
}
|
||||
|
||||
option_description::match_result
|
||||
option_description::match(const std::string& option,
|
||||
bool approx,
|
||||
bool long_ignore_case,
|
||||
bool short_ignore_case) const
|
||||
option_description::match(const std::string& option, bool approx) const
|
||||
{
|
||||
match_result result = no_match;
|
||||
|
||||
std::string local_long_name((long_ignore_case ? tolower_(m_long_name) : m_long_name));
|
||||
|
||||
if (!local_long_name.empty()) {
|
||||
|
||||
std::string local_option = (long_ignore_case ? tolower_(option) : option);
|
||||
match_result result = no_match;
|
||||
if (!m_long_name.empty()) {
|
||||
|
||||
if (*local_long_name.rbegin() == '*')
|
||||
if (*m_long_name.rbegin() == '*')
|
||||
{
|
||||
// The name ends with '*'. Any specified name with the given
|
||||
// prefix is OK.
|
||||
if (local_option.find(local_long_name.substr(0, local_long_name.length()-1))
|
||||
if (option.find(m_long_name.substr(0, m_long_name.length()-1))
|
||||
== 0)
|
||||
result = approximate_match;
|
||||
}
|
||||
|
||||
if (local_long_name == local_option)
|
||||
if (approx)
|
||||
{
|
||||
result = full_match;
|
||||
if (m_long_name.find(option) == 0)
|
||||
if (m_long_name == option)
|
||||
result = full_match;
|
||||
else
|
||||
result = approximate_match;
|
||||
}
|
||||
else if (approx)
|
||||
else
|
||||
{
|
||||
if (local_long_name.find(local_option) == 0)
|
||||
{
|
||||
result = approximate_match;
|
||||
}
|
||||
if (m_long_name == option)
|
||||
result = full_match;
|
||||
}
|
||||
}
|
||||
|
||||
if (result != full_match)
|
||||
{
|
||||
std::string local_option(short_ignore_case ? tolower_(option) : option);
|
||||
std::string local_short_name(short_ignore_case ? tolower_(m_short_name) : m_short_name);
|
||||
|
||||
if (local_short_name == local_option)
|
||||
{
|
||||
result = full_match;
|
||||
}
|
||||
}
|
||||
if (m_short_name == option)
|
||||
result = full_match;
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -233,26 +203,15 @@ namespace boost { namespace program_options {
|
||||
|
||||
const unsigned options_description::m_default_line_length = 80;
|
||||
|
||||
options_description::options_description(unsigned line_length,
|
||||
unsigned min_description_length)
|
||||
options_description::options_description(unsigned line_length)
|
||||
: m_line_length(line_length)
|
||||
, m_min_description_length(min_description_length)
|
||||
{
|
||||
// we require a space between the option and description parts, so add 1.
|
||||
assert(m_min_description_length < m_line_length - 1);
|
||||
}
|
||||
{}
|
||||
|
||||
options_description::options_description(const string& caption,
|
||||
unsigned line_length)
|
||||
: m_caption(caption), m_line_length(line_length)
|
||||
{}
|
||||
|
||||
options_description::options_description(const std::string& caption,
|
||||
unsigned line_length,
|
||||
unsigned min_description_length)
|
||||
: m_caption(caption)
|
||||
, m_line_length(line_length)
|
||||
, m_min_description_length(min_description_length)
|
||||
{
|
||||
// we require a space between the option and description parts, so add 1.
|
||||
assert(m_min_description_length < m_line_length - 1);
|
||||
}
|
||||
|
||||
void
|
||||
options_description::add(shared_ptr<option_description> desc)
|
||||
{
|
||||
@@ -281,13 +240,9 @@ namespace boost { namespace program_options {
|
||||
}
|
||||
|
||||
const option_description&
|
||||
options_description::find(const std::string& name,
|
||||
bool approx,
|
||||
bool long_ignore_case,
|
||||
bool short_ignore_case) const
|
||||
options_description::find(const std::string& name, bool approx) const
|
||||
{
|
||||
const option_description* d = find_nothrow(name, approx,
|
||||
long_ignore_case, short_ignore_case);
|
||||
const option_description* d = find_nothrow(name, approx);
|
||||
if (!d)
|
||||
boost::throw_exception(unknown_option(name));
|
||||
return *d;
|
||||
@@ -301,51 +256,41 @@ namespace boost { namespace program_options {
|
||||
|
||||
const option_description*
|
||||
options_description::find_nothrow(const std::string& name,
|
||||
bool approx,
|
||||
bool long_ignore_case,
|
||||
bool short_ignore_case) const
|
||||
bool approx) const
|
||||
{
|
||||
shared_ptr<option_description> found;
|
||||
bool had_full_match = false;
|
||||
vector<string> approximate_matches;
|
||||
vector<string> full_matches;
|
||||
|
||||
// We use linear search because matching specified option
|
||||
// name with the declared option name need to take care about
|
||||
// case sensitivity and trailing '*' and so we can't use simple map.
|
||||
for(unsigned i = 0; i < m_options.size(); ++i)
|
||||
{
|
||||
option_description::match_result r =
|
||||
m_options[i]->match(name, approx, long_ignore_case, short_ignore_case);
|
||||
m_options[i]->match(name, approx);
|
||||
|
||||
if (r == option_description::no_match)
|
||||
continue;
|
||||
|
||||
// If we have a full patch, and an approximate match,
|
||||
// ignore approximate match instead of reporting error.
|
||||
// Say, if we have options "all" and "all-chroots", then
|
||||
// "--all" on the command line should select the first one,
|
||||
// without ambiguity.
|
||||
//
|
||||
// For now, we don't check the situation when there are
|
||||
// two full matches.
|
||||
|
||||
if (r == option_description::full_match)
|
||||
{
|
||||
full_matches.push_back(m_options[i]->key(name));
|
||||
found = m_options[i];
|
||||
had_full_match = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// FIXME: the use of 'key' here might not
|
||||
// be the best approach.
|
||||
approximate_matches.push_back(m_options[i]->key(name));
|
||||
if (!had_full_match)
|
||||
found = m_options[i];
|
||||
{
|
||||
return m_options[i].get();
|
||||
}
|
||||
|
||||
found = m_options[i];
|
||||
// FIXME: the use of 'key' here might not
|
||||
// be the best approach.
|
||||
approximate_matches.push_back(m_options[i]->key(name));
|
||||
}
|
||||
if (full_matches.size() > 1)
|
||||
boost::throw_exception(
|
||||
ambiguous_option(name, full_matches));
|
||||
|
||||
// If we have a full match, and an approximate match,
|
||||
// ignore approximate match instead of reporting error.
|
||||
// Say, if we have options "all" and "all-chroots", then
|
||||
// "--all" on the command line should select the first one,
|
||||
// without ambiguity.
|
||||
if (full_matches.empty() && approximate_matches.size() > 1)
|
||||
if (approximate_matches.size() > 1)
|
||||
boost::throw_exception(
|
||||
ambiguous_option(name, approximate_matches));
|
||||
|
||||
@@ -463,8 +408,8 @@ namespace boost { namespace program_options {
|
||||
{
|
||||
// is last_space within the second half ot the
|
||||
// current line
|
||||
if (static_cast<unsigned>(distance(last_space, line_end)) <
|
||||
(line_length / 2))
|
||||
if ((unsigned)distance(last_space, line_end) <
|
||||
(line_length - indent) / 2)
|
||||
{
|
||||
line_end = last_space;
|
||||
}
|
||||
@@ -477,7 +422,6 @@ namespace boost { namespace program_options {
|
||||
if (first_line)
|
||||
{
|
||||
indent += par_indent;
|
||||
line_length -= par_indent; // there's less to work with now
|
||||
first_line = false;
|
||||
}
|
||||
|
||||
@@ -558,18 +502,11 @@ namespace boost { namespace program_options {
|
||||
|
||||
if (!opt.description().empty())
|
||||
{
|
||||
if (ss.str().size() >= first_column_width)
|
||||
for(unsigned pad = first_column_width - ss.str().size();
|
||||
pad > 0;
|
||||
--pad)
|
||||
{
|
||||
os.put('\n'); // first column is too long, lets put description in new line
|
||||
for (unsigned pad = first_column_width; pad > 0; --pad)
|
||||
{
|
||||
os.put(' ');
|
||||
}
|
||||
} else {
|
||||
for(unsigned pad = first_column_width - ss.str().size(); pad > 0; --pad)
|
||||
{
|
||||
os.put(' ');
|
||||
}
|
||||
os.put(' ');
|
||||
}
|
||||
|
||||
format_description(os, opt.description(),
|
||||
@@ -594,11 +531,6 @@ namespace boost { namespace program_options {
|
||||
ss << " " << opt.format_name() << ' ' << opt.format_parameter();
|
||||
width = (max)(width, static_cast<unsigned>(ss.str().size()));
|
||||
}
|
||||
/* this is the column were description should start, if first
|
||||
column is longer, we go to a new line */
|
||||
const unsigned start_of_description_column = m_line_length - m_min_description_length;
|
||||
|
||||
width = (min)(width, start_of_description_column-1);
|
||||
|
||||
/* add an additional space to improve readability */
|
||||
++width;
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
#include <boost/throw_exception.hpp>
|
||||
|
||||
#include <cctype>
|
||||
#include <fstream>
|
||||
|
||||
#if !defined(__GNUC__) || __GNUC__ < 3
|
||||
#include <iostream>
|
||||
@@ -68,16 +67,10 @@ namespace boost { namespace program_options {
|
||||
woption result;
|
||||
result.string_key = opt.string_key;
|
||||
result.position_key = opt.position_key;
|
||||
result.unregistered = opt.unregistered;
|
||||
|
||||
std::transform(opt.value.begin(), opt.value.end(),
|
||||
back_inserter(result.value),
|
||||
boost::bind(from_utf8, _1));
|
||||
|
||||
std::transform(opt.original_tokens.begin(),
|
||||
opt.original_tokens.end(),
|
||||
back_inserter(result.original_tokens),
|
||||
boost::bind(from_utf8, _1));
|
||||
bind(from_utf8, _1));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -135,36 +128,6 @@ namespace boost { namespace program_options {
|
||||
const options_description& desc,
|
||||
bool allow_unregistered);
|
||||
#endif
|
||||
|
||||
template<class charT>
|
||||
basic_parsed_options<charT>
|
||||
parse_config_file(const char* filename,
|
||||
const options_description& desc,
|
||||
bool allow_unregistered)
|
||||
{
|
||||
// Parser return char strings
|
||||
std::basic_ifstream< charT > strm(filename);
|
||||
if (!strm)
|
||||
{
|
||||
boost::throw_exception(reading_file(filename));
|
||||
}
|
||||
return parse_config_file(strm, desc, allow_unregistered);
|
||||
}
|
||||
|
||||
template
|
||||
BOOST_PROGRAM_OPTIONS_DECL basic_parsed_options<char>
|
||||
parse_config_file(const char* filename,
|
||||
const options_description& desc,
|
||||
bool allow_unregistered);
|
||||
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
template
|
||||
BOOST_PROGRAM_OPTIONS_DECL basic_parsed_options<wchar_t>
|
||||
parse_config_file(const char* filename,
|
||||
const options_description& desc,
|
||||
bool allow_unregistered);
|
||||
#endif
|
||||
|
||||
|
||||
// This versio, which accepts any options without validation, is disabled,
|
||||
// in the hope that nobody will need it and we cant drop it altogether.
|
||||
@@ -201,7 +164,7 @@ namespace boost { namespace program_options {
|
||||
return result;
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
namespace {
|
||||
class prefix_name_mapper {
|
||||
public:
|
||||
prefix_name_mapper(const std::string& prefix)
|
||||
@@ -230,7 +193,7 @@ namespace boost { namespace program_options {
|
||||
parse_environment(const options_description& desc,
|
||||
const std::string& prefix)
|
||||
{
|
||||
return parse_environment(desc, detail::prefix_name_mapper(prefix));
|
||||
return parse_environment(desc, prefix_name_mapper(prefix));
|
||||
}
|
||||
|
||||
BOOST_PROGRAM_OPTIONS_DECL parsed_options
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
// Copyright Sascha Ochsenknecht 2009.
|
||||
// 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)
|
||||
|
||||
#define BOOST_PROGRAM_OPTIONS_SOURCE
|
||||
|
||||
#include <boost/program_options/parsers.hpp>
|
||||
#include <boost/tokenizer.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace boost { namespace program_options { namespace detail {
|
||||
|
||||
template< class charT >
|
||||
std::vector<std::basic_string<charT> >
|
||||
split_unix(
|
||||
const std::basic_string<charT>& cmdline,
|
||||
const std::basic_string<charT>& seperator,
|
||||
const std::basic_string<charT>& quote,
|
||||
const std::basic_string<charT>& escape)
|
||||
{
|
||||
typedef boost::tokenizer< boost::escaped_list_separator<charT>,
|
||||
typename std::basic_string<charT>::const_iterator,
|
||||
std::basic_string<charT> > tokenizerT;
|
||||
|
||||
tokenizerT tok(cmdline.begin(), cmdline.end(),
|
||||
boost::escaped_list_separator< charT >(escape, seperator, quote));
|
||||
|
||||
std::vector< std::basic_string<charT> > result;
|
||||
for (typename tokenizerT::iterator cur_token(tok.begin()), end_token(tok.end()); cur_token != end_token; ++cur_token) {
|
||||
if (!cur_token->empty())
|
||||
result.push_back(*cur_token);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}}} // namespace
|
||||
|
||||
namespace boost { namespace program_options {
|
||||
|
||||
// Take a command line string and splits in into tokens, according
|
||||
// to the given collection of seperators chars.
|
||||
BOOST_PROGRAM_OPTIONS_DECL std::vector<std::string>
|
||||
split_unix(const std::string& cmdline, const std::string& seperator,
|
||||
const std::string& quote, const std::string& escape)
|
||||
{
|
||||
return detail::split_unix< char >(cmdline, seperator, quote, escape);
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
BOOST_PROGRAM_OPTIONS_DECL std::vector<std::wstring>
|
||||
split_unix(const std::wstring& cmdline, const std::wstring& seperator,
|
||||
const std::wstring& quote, const std::wstring& escape)
|
||||
{
|
||||
return detail::split_unix< wchar_t >(cmdline, seperator, quote, escape);
|
||||
}
|
||||
#endif
|
||||
|
||||
}} // namespace
|
||||
|
||||
@@ -97,9 +97,9 @@ namespace boost { namespace program_options {
|
||||
{
|
||||
if (!value_store.empty())
|
||||
boost::throw_exception(
|
||||
multiple_occurrences());
|
||||
multiple_occurrences("multiple_occurrences"));
|
||||
if (new_tokens.size() > 1)
|
||||
boost::throw_exception(multiple_values());
|
||||
boost::throw_exception(multiple_values("multiple_values"));
|
||||
value_store = new_tokens.empty() ? std::string("") : new_tokens.front();
|
||||
}
|
||||
|
||||
@@ -139,7 +139,8 @@ namespace boost { namespace program_options {
|
||||
else if (s == "off" || s == "no" || s == "0" || s == "false")
|
||||
v = any(false);
|
||||
else
|
||||
boost::throw_exception(validation_error(validation_error::invalid_bool_value, s));
|
||||
boost::throw_exception(validation_error(
|
||||
"'" + s + "' doesn't look like a bool value."));
|
||||
}
|
||||
|
||||
// This is blatant copy-paste. However, templating this will cause a problem,
|
||||
@@ -161,14 +162,22 @@ namespace boost { namespace program_options {
|
||||
else if (s == L"off" || s == L"no" || s == L"0" || s == L"false")
|
||||
v = any(false);
|
||||
else
|
||||
boost::throw_exception(validation_error(validation_error::invalid_bool_value));
|
||||
boost::throw_exception(validation_error("invalid bool value"));
|
||||
}
|
||||
#endif
|
||||
BOOST_PROGRAM_OPTIONS_DECL
|
||||
void validate(any& v, const vector<string>& xs, std::string*, int)
|
||||
{
|
||||
check_first_occurrence(v);
|
||||
v = any(get_single_string(xs));
|
||||
string s(get_single_string(xs));
|
||||
if (!s.empty() && (
|
||||
(*s.begin() == '\'' && *s.rbegin() == '\'' ||
|
||||
*s.begin() == '"' && *s.rbegin() == '"')))
|
||||
{
|
||||
v = any(s.substr(1, s.size()-2));
|
||||
}
|
||||
else
|
||||
v = any(s);
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_STD_WSTRING)
|
||||
@@ -176,7 +185,12 @@ namespace boost { namespace program_options {
|
||||
void validate(any& v, const vector<wstring>& xs, std::string*, int)
|
||||
{
|
||||
check_first_occurrence(v);
|
||||
v = any(get_single_string(xs));
|
||||
wstring s(get_single_string(xs));
|
||||
if (*s.begin() == L'\'' && *s.rbegin() == L'\'' ||
|
||||
*s.begin() == L'"' && *s.rbegin() == L'"')
|
||||
v = any(s.substr(1, s.size()-2));
|
||||
else
|
||||
v = any(s);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -187,17 +201,19 @@ namespace boost { namespace program_options {
|
||||
{
|
||||
if (!value.empty())
|
||||
boost::throw_exception(
|
||||
multiple_occurrences());
|
||||
multiple_occurrences("multiple_occurrences"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
invalid_option_value::
|
||||
invalid_option_value(const std::string& bad_value)
|
||||
: validation_error(validation_error::invalid_option_value, bad_value)
|
||||
: validation_error(string("invalid option value '")
|
||||
.append(bad_value).append("'"))
|
||||
{}
|
||||
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
|
||||
namespace
|
||||
{
|
||||
std::string convert_value(const std::wstring& s)
|
||||
@@ -213,123 +229,35 @@ namespace boost { namespace program_options {
|
||||
|
||||
invalid_option_value::
|
||||
invalid_option_value(const std::wstring& bad_value)
|
||||
: validation_error(validation_error::invalid_option_value, convert_value(bad_value))
|
||||
: validation_error(string("invalid option value '")
|
||||
.append(convert_value(bad_value))
|
||||
.append("'"))
|
||||
{}
|
||||
#endif
|
||||
const std::string&
|
||||
unknown_option::get_option_name() const throw()
|
||||
{
|
||||
return m_option_name;
|
||||
}
|
||||
#endif
|
||||
|
||||
const std::string&
|
||||
ambiguous_option::get_option_name() const throw()
|
||||
{
|
||||
return m_option_name;
|
||||
}
|
||||
|
||||
const std::vector<std::string>&
|
||||
ambiguous_option::alternatives() const throw()
|
||||
{
|
||||
return m_alternatives;
|
||||
}
|
||||
|
||||
void
|
||||
multiple_values::set_option_name(const std::string& option_name)
|
||||
|
||||
void validation_error::set_option_name(const std::string& option_name)
|
||||
{
|
||||
m_option_name = option_name;
|
||||
}
|
||||
|
||||
const std::string&
|
||||
multiple_values::get_option_name() const throw()
|
||||
{
|
||||
return m_option_name;
|
||||
}
|
||||
|
||||
void
|
||||
multiple_occurrences::set_option_name(const std::string& option_name)
|
||||
{
|
||||
m_option_name = option_name;
|
||||
}
|
||||
|
||||
const std::string&
|
||||
multiple_occurrences::get_option_name() const throw()
|
||||
{
|
||||
return m_option_name;
|
||||
}
|
||||
|
||||
validation_error::
|
||||
validation_error(kind_t kind,
|
||||
const std::string& option_value,
|
||||
const std::string& option_name)
|
||||
: error("")
|
||||
, m_kind(kind)
|
||||
, m_option_name(option_name)
|
||||
, m_option_value(option_value)
|
||||
, m_message(error_message(kind))
|
||||
{
|
||||
if (!option_value.empty())
|
||||
{
|
||||
m_message.append(std::string("'") + option_value + std::string("'"));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
validation_error::set_option_name(const std::string& option_name)
|
||||
{
|
||||
m_option_name = option_name;
|
||||
}
|
||||
|
||||
const std::string&
|
||||
validation_error::get_option_name() const throw()
|
||||
{
|
||||
return m_option_name;
|
||||
}
|
||||
|
||||
std::string
|
||||
validation_error::error_message(kind_t kind)
|
||||
{
|
||||
// Initially, store the message in 'const char*' variable,
|
||||
// to avoid conversion to std::string in all cases.
|
||||
const char* msg;
|
||||
switch(kind)
|
||||
{
|
||||
case multiple_values_not_allowed:
|
||||
msg = "multiple values not allowed";
|
||||
break;
|
||||
case at_least_one_value_required:
|
||||
msg = "at least one value required";
|
||||
break;
|
||||
case invalid_bool_value:
|
||||
msg = "invalid bool value";
|
||||
break;
|
||||
case invalid_option_value:
|
||||
msg = "invalid option value";
|
||||
break;
|
||||
case invalid_option:
|
||||
msg = "invalid option";
|
||||
break;
|
||||
default:
|
||||
msg = "unknown error";
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
const char*
|
||||
validation_error::what() const throw()
|
||||
const char* validation_error::what() const throw()
|
||||
{
|
||||
if (!m_option_name.empty())
|
||||
{
|
||||
m_message = "in option '" + m_option_name + "': "
|
||||
+ error_message(m_kind);
|
||||
+ logic_error::what();
|
||||
return m_message.c_str();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
return logic_error::what();
|
||||
}
|
||||
return m_message.c_str();
|
||||
}
|
||||
|
||||
const std::string&
|
||||
required_option::get_option_name() const throw()
|
||||
{
|
||||
return m_option_name;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}}
|
||||
|
||||
@@ -58,8 +58,12 @@ namespace boost { namespace program_options {
|
||||
if (xm.m_final.count(name))
|
||||
continue;
|
||||
|
||||
const option_description& d = desc.find(name, false,
|
||||
false, false);
|
||||
// Ignore options which are not described
|
||||
//TODO: consider this.
|
||||
//if (desc.count(name) == 0)
|
||||
// continue;
|
||||
|
||||
const option_description& d = desc.find(name, false);
|
||||
|
||||
variable_value& v = m[name];
|
||||
if (v.defaulted()) {
|
||||
@@ -70,23 +74,11 @@ namespace boost { namespace program_options {
|
||||
try {
|
||||
d.semantic()->parse(v.value(), options.options[i].value, utf8);
|
||||
}
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
catch(validation_error& e)
|
||||
{
|
||||
e.set_option_name(name);
|
||||
throw;
|
||||
}
|
||||
catch(multiple_occurrences& e)
|
||||
{
|
||||
e.set_option_name(name);
|
||||
throw;
|
||||
}
|
||||
catch(multiple_values& e)
|
||||
{
|
||||
e.set_option_name(name);
|
||||
throw;
|
||||
}
|
||||
#endif
|
||||
v.m_value_semantic = d.semantic();
|
||||
|
||||
// The option is not composing, and the value is explicitly
|
||||
@@ -101,7 +93,7 @@ namespace boost { namespace program_options {
|
||||
|
||||
|
||||
|
||||
// Second, apply default values and store required options.
|
||||
// Second, apply default values.
|
||||
const vector<shared_ptr<option_description> >& all = desc.options();
|
||||
for(i = 0; i < all.size(); ++i)
|
||||
{
|
||||
@@ -123,12 +115,7 @@ namespace boost { namespace program_options {
|
||||
m[key] = variable_value(def, true);
|
||||
m[key].m_value_semantic = d.semantic();
|
||||
}
|
||||
}
|
||||
|
||||
// add empty value if this is an required option
|
||||
if (d.semantic()->is_required()) {
|
||||
xm.m_required.insert(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,7 +128,13 @@ namespace boost { namespace program_options {
|
||||
BOOST_PROGRAM_OPTIONS_DECL
|
||||
void notify(variables_map& vm)
|
||||
{
|
||||
vm.notify();
|
||||
// Lastly, run notify actions.
|
||||
for (map<string, variable_value>::iterator k = vm.begin();
|
||||
k != vm.end();
|
||||
++k)
|
||||
{
|
||||
k->second.m_value_semantic->notify(k->second.value());
|
||||
}
|
||||
}
|
||||
|
||||
abstract_variables_map::abstract_variables_map()
|
||||
@@ -192,40 +185,4 @@ namespace boost { namespace program_options {
|
||||
else
|
||||
return i->second;
|
||||
}
|
||||
|
||||
void
|
||||
variables_map::notify()
|
||||
{
|
||||
// This checks if all required options occur
|
||||
for (set<string>::const_iterator r = m_required.begin();
|
||||
r != m_required.end();
|
||||
++r)
|
||||
{
|
||||
const string& opt = *r;
|
||||
map<string, variable_value>::const_iterator iter = find(opt);
|
||||
if (iter == end() || iter->second.empty())
|
||||
{
|
||||
boost::throw_exception(required_option(opt));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Lastly, run notify actions.
|
||||
for (map<string, variable_value>::iterator k = begin();
|
||||
k != end();
|
||||
++k)
|
||||
{
|
||||
/* Users might wish to use variables_map to store their own values
|
||||
that are not parsed, and therefore will not have value_semantics
|
||||
defined. Do no crash on such values. In multi-module programs,
|
||||
one module might add custom values, and the 'notify' function
|
||||
will be called after that, so we check that value_sematics is
|
||||
not NULL. See:
|
||||
https://svn.boost.org/trac/boost/ticket/2782
|
||||
*/
|
||||
if (k->second.m_value_semantic)
|
||||
k->second.m_value_semantic->notify(k->second.value());
|
||||
}
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
#ifdef _WIN32
|
||||
namespace boost { namespace program_options {
|
||||
|
||||
using namespace std;
|
||||
|
||||
// Take a command line string and splits in into tokens, according
|
||||
// to the rules windows command line processor uses.
|
||||
//
|
||||
@@ -21,7 +23,7 @@ namespace boost { namespace program_options {
|
||||
{
|
||||
std::vector<std::string> result;
|
||||
|
||||
std::string::const_iterator i = input.begin(), e = input.end();
|
||||
string::const_iterator i = input.begin(), e = input.end();
|
||||
for(;i != e; ++i)
|
||||
if (!isspace((unsigned char)*i))
|
||||
break;
|
||||
@@ -30,7 +32,6 @@ namespace boost { namespace program_options {
|
||||
|
||||
std::string current;
|
||||
bool inside_quoted = false;
|
||||
bool empty_quote = false;
|
||||
int backslash_count = 0;
|
||||
|
||||
for(; i != e; ++i) {
|
||||
@@ -39,7 +40,6 @@ namespace boost { namespace program_options {
|
||||
// n/2 backslashes and is a quoted block delimiter
|
||||
if (backslash_count % 2 == 0) {
|
||||
current.append(backslash_count / 2, '\\');
|
||||
empty_quote = inside_quoted && current.empty();
|
||||
inside_quoted = !inside_quoted;
|
||||
// '"' preceded by odd number (n) of backslashes generates
|
||||
// (n-1)/2 backslashes and is literal quote.
|
||||
@@ -61,7 +61,6 @@ namespace boost { namespace program_options {
|
||||
// Space outside quoted section terminate the current argument
|
||||
result.push_back(current);
|
||||
current.resize(0);
|
||||
empty_quote = false;
|
||||
for(;i != e && isspace((unsigned char)*i); ++i)
|
||||
;
|
||||
--i;
|
||||
@@ -77,7 +76,7 @@ namespace boost { namespace program_options {
|
||||
|
||||
// If we have non-empty 'current' or we're still in quoted
|
||||
// section (even if 'current' is empty), add the last token.
|
||||
if (!current.empty() || inside_quoted || empty_quote)
|
||||
if (!current.empty() || inside_quoted)
|
||||
result.push_back(current);
|
||||
}
|
||||
return result;
|
||||
@@ -87,8 +86,8 @@ namespace boost { namespace program_options {
|
||||
BOOST_PROGRAM_OPTIONS_DECL std::vector<std::wstring>
|
||||
split_winmain(const std::wstring& cmdline)
|
||||
{
|
||||
std::vector<std::wstring> result;
|
||||
std::vector<std::string> aux = split_winmain(to_internal(cmdline));
|
||||
vector<wstring> result;
|
||||
vector<string> aux = split_winmain(to_internal(cmdline));
|
||||
for (unsigned i = 0, e = aux.size(); i < e; ++i)
|
||||
result.push_back(from_utf8(aux[i]));
|
||||
return result;
|
||||
@@ -97,4 +96,3 @@ namespace boost { namespace program_options {
|
||||
|
||||
}}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -9,29 +9,24 @@ project
|
||||
# <define>_GLIBCXX_DEBUG
|
||||
;
|
||||
|
||||
rule po-test ( source : input-file ? )
|
||||
rule po-test ( source )
|
||||
{
|
||||
return
|
||||
[ run $(source) : : $(input-file) ]
|
||||
[ run $(source) : : $(input-file)
|
||||
: <link>shared <define>BOOST_PROGRAM_OPTIONS_DYN_LINK=1
|
||||
: $(source:B)_dll ]
|
||||
;
|
||||
[ run $(source) ]
|
||||
[ run $(source) : : : <link>shared <define>BOOST_PROGRAM_OPTIONS_DYN_LINK=1
|
||||
: $(source:B)_dll ]
|
||||
;
|
||||
}
|
||||
|
||||
test-suite program_options :
|
||||
|
||||
[ po-test options_description_test.cpp ]
|
||||
[ po-test parsers_test.cpp : config_test.cfg ]
|
||||
[ po-test parsers_test.cpp ]
|
||||
[ po-test variable_map_test.cpp ]
|
||||
[ po-test cmdline_test.cpp ]
|
||||
[ po-test positional_options_test.cpp ]
|
||||
[ po-test unicode_test.cpp ]
|
||||
[ po-test winmain.cpp ]
|
||||
[ po-test exception_test.cpp ]
|
||||
[ po-test split_test.cpp ]
|
||||
[ po-test unrecognized_test.cpp ]
|
||||
[ po-test required_test.cpp : required_test.cfg ]
|
||||
;
|
||||
|
||||
exe test_convert : test_convert.cpp ;
|
||||
|
||||
@@ -30,7 +30,6 @@ const int s_short_adjacent_not_allowed = 5;
|
||||
const int s_empty_adjacent_parameter = 6;
|
||||
const int s_missing_parameter = 7;
|
||||
const int s_extra_parameter = 8;
|
||||
const int s_unrecognized_line = 9;
|
||||
|
||||
int translate_syntax_error_kind(invalid_command_line_syntax::kind_t k)
|
||||
{
|
||||
@@ -41,7 +40,6 @@ int translate_syntax_error_kind(invalid_command_line_syntax::kind_t k)
|
||||
invalid_command_line_syntax::empty_adjacent_parameter,
|
||||
invalid_command_line_syntax::missing_parameter,
|
||||
invalid_command_line_syntax::extra_parameter,
|
||||
invalid_command_line_syntax::unrecognized_line
|
||||
};
|
||||
invalid_command_line_syntax::kind_t *b, *e, *i;
|
||||
b = table;
|
||||
@@ -185,7 +183,7 @@ void test_long_options()
|
||||
{"--bar", s_missing_parameter, ""},
|
||||
|
||||
{"--bar=123", s_success, "bar:123"},
|
||||
{0, 0, 0}
|
||||
{0}
|
||||
};
|
||||
test_cmdline("foo bar=", style, test_cases1);
|
||||
|
||||
@@ -200,7 +198,7 @@ void test_long_options()
|
||||
// considered a value, even though it looks like
|
||||
// an option.
|
||||
{"--bar --foo", s_success, "bar:--foo"},
|
||||
{0, 0, 0}
|
||||
{0}
|
||||
};
|
||||
test_cmdline("foo bar=", style, test_cases2);
|
||||
style = cmdline::style_t(
|
||||
@@ -210,7 +208,7 @@ void test_long_options()
|
||||
test_case test_cases3[] = {
|
||||
{"--bar=10", s_success, "bar:10"},
|
||||
{"--bar 11", s_success, "bar:11"},
|
||||
{0, 0, 0}
|
||||
{0}
|
||||
};
|
||||
test_cmdline("foo bar=", style, test_cases3);
|
||||
|
||||
@@ -218,6 +216,8 @@ void test_long_options()
|
||||
allow_long | long_allow_adjacent
|
||||
| long_allow_next | case_insensitive);
|
||||
|
||||
// FIXME: restore
|
||||
#if 0
|
||||
// Test case insensitive style.
|
||||
// Note that option names are normalized to lower case.
|
||||
test_case test_cases4[] = {
|
||||
@@ -226,9 +226,10 @@ void test_long_options()
|
||||
{"--bar=Ab", s_success, "bar:Ab"},
|
||||
{"--Bar=ab", s_success, "bar:ab"},
|
||||
{"--giz", s_success, "Giz:"},
|
||||
{0, 0, 0}
|
||||
{0}
|
||||
};
|
||||
test_cmdline("foo bar= baz? Giz", style, test_cases4);
|
||||
#endif
|
||||
}
|
||||
|
||||
void test_short_options()
|
||||
@@ -248,7 +249,7 @@ void test_short_options()
|
||||
{"-f14", s_success, "-f:14"},
|
||||
{"-g -f1", s_success, "-g: -f:1"},
|
||||
{"-f", s_missing_parameter, ""},
|
||||
{0, 0, 0}
|
||||
{0}
|
||||
};
|
||||
test_cmdline(",d ,f= ,g", style, test_cases1);
|
||||
|
||||
@@ -261,8 +262,8 @@ void test_short_options()
|
||||
{"-f -13", s_success, "-f:-13"},
|
||||
{"-f", s_missing_parameter, ""},
|
||||
{"-f /foo", s_success, "-f:/foo"},
|
||||
{"-f -d", s_missing_parameter, ""},
|
||||
{0, 0, 0}
|
||||
{"-f -d", s_success, "-f:-d"},
|
||||
{0}
|
||||
};
|
||||
test_cmdline(",d ,f=", style, test_cases2);
|
||||
|
||||
@@ -273,8 +274,8 @@ void test_short_options()
|
||||
test_case test_cases3[] = {
|
||||
{"-f10", s_success, "-f:10"},
|
||||
{"-f 10", s_success, "-f:10"},
|
||||
{"-f -d", s_missing_parameter, ""},
|
||||
{0, 0, 0}
|
||||
{"-f -d", s_success, "-f:-d"},
|
||||
{0}
|
||||
};
|
||||
test_cmdline(",d ,f=", style, test_cases3);
|
||||
|
||||
@@ -290,7 +291,7 @@ void test_short_options()
|
||||
//{"-d12", s_extra_parameter, ""},
|
||||
{"-f12", s_success, "-f:12"},
|
||||
{"-fe", s_success, "-f:e"},
|
||||
{0, 0, 0}
|
||||
{0}
|
||||
};
|
||||
test_cmdline(",d ,f= ,e", style, test_cases4);
|
||||
|
||||
@@ -312,7 +313,7 @@ void test_dos_options()
|
||||
{"/d13", s_extra_parameter, ""},
|
||||
{"/f14", s_success, "-f:14"},
|
||||
{"/f", s_missing_parameter, ""},
|
||||
{0, 0, 0}
|
||||
{0}
|
||||
};
|
||||
test_cmdline(",d ,f=", style, test_cases1);
|
||||
|
||||
@@ -324,7 +325,7 @@ void test_dos_options()
|
||||
test_case test_cases2[] = {
|
||||
{"/de", s_extra_parameter, ""},
|
||||
{"/fe", s_success, "-f:e"},
|
||||
{0, 0, 0}
|
||||
{0}
|
||||
};
|
||||
test_cmdline(",d ,f= ,e", style, test_cases2);
|
||||
|
||||
@@ -346,7 +347,7 @@ void test_disguised_long()
|
||||
{"-foo -f", s_success, "foo: foo:"},
|
||||
{"-goo=x -gy", s_success, "goo:x goo:y"},
|
||||
{"-bee=x -by", s_success, "bee:x bee:y"},
|
||||
{0, 0, 0}
|
||||
{0}
|
||||
};
|
||||
test_cmdline("foo,f goo,g= bee,b?", style, test_cases1);
|
||||
|
||||
@@ -354,7 +355,7 @@ void test_disguised_long()
|
||||
test_case test_cases2[] = {
|
||||
{"/foo -f", s_success, "foo: foo:"},
|
||||
{"/goo=x", s_success, "goo:x"},
|
||||
{0, 0, 0}
|
||||
{0}
|
||||
};
|
||||
test_cmdline("foo,f goo,g= bee,b?", style, test_cases2);
|
||||
}
|
||||
@@ -375,7 +376,7 @@ void test_guessing()
|
||||
{"--opt", s_ambiguous_option, ""},
|
||||
{"--f=1", s_success, "foo:1"},
|
||||
{"-far", s_success, "foo:ar"},
|
||||
{0, 0, 0}
|
||||
{0}
|
||||
};
|
||||
test_cmdline("opt123 opt56 foo,f=", style, test_cases1);
|
||||
}
|
||||
@@ -393,7 +394,7 @@ void test_arguments()
|
||||
test_case test_cases1[] = {
|
||||
{"-f file -gx file2", s_success, "-f: file -g:x file2"},
|
||||
{"-f - -gx - -- -e", s_success, "-f: - -g:x - -e"},
|
||||
{0, 0, 0}
|
||||
{0}
|
||||
};
|
||||
test_cmdline(",f ,g= ,e", style, test_cases1);
|
||||
|
||||
@@ -406,7 +407,7 @@ void test_arguments()
|
||||
|
||||
test_case test_cases2[] = {
|
||||
{"-f - -gx - -- -e", s_success, "-f: - -g:x - -e"},
|
||||
{0, 0, 0}
|
||||
{0}
|
||||
};
|
||||
test_cmdline(",f ,g= ,e", style, test_cases2);
|
||||
}
|
||||
@@ -424,7 +425,7 @@ void test_prefix()
|
||||
|
||||
test_case test_cases1[] = {
|
||||
{"--foo.bar=12", s_success, "foo.bar:12"},
|
||||
{0, 0, 0}
|
||||
{0}
|
||||
};
|
||||
|
||||
test_cmdline("foo*=", style, test_cases1);
|
||||
@@ -598,7 +599,7 @@ void test_unregistered()
|
||||
// It's not clear yet, so I'm leaving the decision till later.
|
||||
}
|
||||
|
||||
int main(int /*ac*/, char** /*av*/)
|
||||
int main(int ac, char* av[])
|
||||
{
|
||||
test_long_options();
|
||||
test_short_options();
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
gv1 = 0#asd
|
||||
empty_value =
|
||||
plug3 = 7
|
||||
b = true
|
||||
|
||||
[m1]
|
||||
v1 = 1
|
||||
|
||||
v2 = 2
|
||||
@@ -1,164 +0,0 @@
|
||||
// Copyright Sascha Ochsenknecht 2009.
|
||||
// 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)
|
||||
|
||||
|
||||
#include <boost/program_options/parsers.hpp>
|
||||
#include <boost/program_options/options_description.hpp>
|
||||
#include <boost/program_options/variables_map.hpp>
|
||||
#include <boost/program_options/cmdline.hpp>
|
||||
using namespace boost::program_options;
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <cassert>
|
||||
using namespace std;
|
||||
|
||||
#include "minitest.hpp"
|
||||
|
||||
|
||||
void test_ambiguous()
|
||||
{
|
||||
options_description desc;
|
||||
desc.add_options()
|
||||
("cfgfile,c", value<string>()->multitoken(), "the config file")
|
||||
("output,c", value<string>(), "the output file")
|
||||
("output,o", value<string>(), "the output file")
|
||||
;
|
||||
|
||||
const char* cmdline[] = {"program", "-c", "file", "-o", "anotherfile"};
|
||||
|
||||
variables_map vm;
|
||||
try {
|
||||
store(parse_command_line(sizeof(cmdline)/sizeof(const char*),
|
||||
const_cast<char**>(cmdline), desc), vm);
|
||||
}
|
||||
catch (ambiguous_option& e)
|
||||
{
|
||||
BOOST_CHECK_EQUAL(e.alternatives().size(), 2);
|
||||
BOOST_CHECK_EQUAL(e.get_option_name(), "-c");
|
||||
BOOST_CHECK_EQUAL(e.alternatives()[0], "cfgfile");
|
||||
BOOST_CHECK_EQUAL(e.alternatives()[1], "output");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void test_unknown_option()
|
||||
{
|
||||
options_description desc;
|
||||
desc.add_options()
|
||||
("cfgfile,c", value<string>(), "the configfile")
|
||||
;
|
||||
|
||||
const char* cmdline[] = {"program", "-c", "file", "-f", "anotherfile"};
|
||||
|
||||
variables_map vm;
|
||||
try {
|
||||
store(parse_command_line(sizeof(cmdline)/sizeof(const char*),
|
||||
const_cast<char**>(cmdline), desc), vm);
|
||||
}
|
||||
catch (unknown_option& e)
|
||||
{
|
||||
BOOST_CHECK_EQUAL(e.get_option_name(), "-f");
|
||||
BOOST_CHECK_EQUAL(string(e.what()), "unknown option -f");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void test_multiple_values()
|
||||
{
|
||||
options_description desc;
|
||||
desc.add_options()
|
||||
("cfgfile,c", value<string>()->multitoken(), "the config file")
|
||||
("output,o", value<string>(), "the output file")
|
||||
;
|
||||
|
||||
const char* cmdline[] = { "program", "-o", "fritz", "hugo", "--cfgfile", "file", "c", "-o", "text.out" };
|
||||
|
||||
variables_map vm;
|
||||
try {
|
||||
store(parse_command_line(sizeof(cmdline)/sizeof(const char*),
|
||||
const_cast<char**>(cmdline), desc), vm);
|
||||
notify(vm);
|
||||
}
|
||||
catch (validation_error& e)
|
||||
{
|
||||
// TODO: this is currently validation_error, shouldn't it be multiple_values ???
|
||||
//
|
||||
// multiple_values is thrown only at one place untyped_value::xparse(),
|
||||
// but I think this can never be reached
|
||||
// because: untyped_value always has one value and this is filtered before reach specific
|
||||
// validation and parsing
|
||||
//
|
||||
BOOST_CHECK_EQUAL(e.get_option_name(), "cfgfile");
|
||||
BOOST_CHECK_EQUAL(string(e.what()), "in option 'cfgfile': multiple values not allowed");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void test_multiple_occurrences()
|
||||
{
|
||||
options_description desc;
|
||||
desc.add_options()
|
||||
("cfgfile,c", value<string>(), "the configfile")
|
||||
;
|
||||
|
||||
const char* cmdline[] = {"program", "--cfgfile", "file", "-c", "anotherfile"};
|
||||
|
||||
variables_map vm;
|
||||
try {
|
||||
store(parse_command_line(sizeof(cmdline)/sizeof(const char*),
|
||||
const_cast<char**>(cmdline), desc), vm);
|
||||
notify(vm);
|
||||
}
|
||||
catch (multiple_occurrences& e)
|
||||
{
|
||||
BOOST_CHECK_EQUAL(e.get_option_name(), "cfgfile");
|
||||
BOOST_CHECK_EQUAL(string(e.what()), "multiple occurrences");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void test_missing_value()
|
||||
{
|
||||
options_description desc;
|
||||
desc.add_options()
|
||||
("cfgfile,c", value<string>()->multitoken(), "the config file")
|
||||
("output,o", value<string>(), "the output file")
|
||||
;
|
||||
// missing value for option '-c'
|
||||
const char* cmdline[] = { "program", "-c", "-c", "output.txt"};
|
||||
|
||||
variables_map vm;
|
||||
|
||||
try {
|
||||
store(parse_command_line(sizeof(cmdline)/sizeof(const char*),
|
||||
const_cast<char**>(cmdline), desc), vm);
|
||||
notify(vm);
|
||||
}
|
||||
catch (invalid_command_line_syntax& e)
|
||||
{
|
||||
BOOST_CHECK_EQUAL(e.kind(), invalid_syntax::missing_parameter);
|
||||
BOOST_CHECK_EQUAL(e.tokens(), "cfgfile");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main(int /*ac*/, char** /*av*/)
|
||||
{
|
||||
test_ambiguous();
|
||||
test_unknown_option();
|
||||
test_multiple_values();
|
||||
test_multiple_occurrences();
|
||||
test_missing_value();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ void test_type()
|
||||
options_description desc;
|
||||
desc.add_options()
|
||||
("foo", value<int>(), "")
|
||||
("bar", value<string>(), "")
|
||||
("bar", value<std::string>(), "")
|
||||
;
|
||||
|
||||
const typed_value_base* b = dynamic_cast<const typed_value_base*>
|
||||
@@ -33,7 +33,7 @@ void test_type()
|
||||
const typed_value_base* b2 = dynamic_cast<const typed_value_base*>
|
||||
(desc.find("bar", false).semantic().get());
|
||||
BOOST_CHECK(b2);
|
||||
BOOST_CHECK(b2->value_type() == typeid(string));
|
||||
BOOST_CHECK(b2->value_type() == typeid(std::string));
|
||||
}
|
||||
|
||||
void test_approximation()
|
||||
@@ -53,17 +53,6 @@ void test_approximation()
|
||||
BOOST_CHECK_EQUAL(desc.find("all", true).long_name(), "all");
|
||||
BOOST_CHECK_EQUAL(desc.find("all-ch", true).long_name(), "all-chroots");
|
||||
|
||||
options_description desc2;
|
||||
desc2.add_options()
|
||||
("help", "display this message")
|
||||
("config", value<string>(), "config file name")
|
||||
("config-value", value<string>(), "single config value")
|
||||
;
|
||||
|
||||
BOOST_CHECK_EQUAL(desc2.find("config", true).long_name(), "config");
|
||||
BOOST_CHECK_EQUAL(desc2.find("config-value", true).long_name(),
|
||||
"config-value");
|
||||
|
||||
|
||||
// BOOST_CHECK(desc.count_approx("foo") == 1);
|
||||
// set<string> a = desc.approximations("f");
|
||||
@@ -81,163 +70,16 @@ void test_formatting()
|
||||
"foo foo foo foo foo foo foo foo foo foo foo foo foo foo"
|
||||
"foo foo foo foo foo foo foo foo foo foo foo foo foo foo"
|
||||
"foo foo foo foo foo foo foo foo foo foo foo foo foo foo"
|
||||
"foo foo foo foo foo foo foo foo foo foo foo foo foo foo")
|
||||
("list", new untyped_value(),
|
||||
"a list:\n \t"
|
||||
"item1, item2, item3, item4, item5, item6, item7, item8, item9, "
|
||||
"item10, item11, item12, item13, item14, item15, item16, item17, item18")
|
||||
("well_formated", new untyped_value(),
|
||||
"As you can see this is a very well formatted option description.\n"
|
||||
"You can do this for example:\n\n"
|
||||
"Values:\n"
|
||||
" Value1: \tdoes this and that, bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla\n"
|
||||
" Value2: \tdoes something else, bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla\n\n"
|
||||
" This paragraph has a first line indent only, bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla")
|
||||
;
|
||||
"foo foo foo foo foo foo foo foo foo foo foo foo foo foo");
|
||||
|
||||
stringstream ss;
|
||||
ss << desc;
|
||||
BOOST_CHECK_EQUAL(ss.str(),
|
||||
" --test arg foo foo foo foo foo foo foo foo foo foo foo foo foo \n"
|
||||
" foofoo foo foo foo foo foo foo foo foo foo foo foo foo \n"
|
||||
" foofoo foo foo foo foo foo foo foo foo foo foo foo foo \n"
|
||||
" foofoo foo foo foo foo foo foo foo foo foo foo foo foo \n"
|
||||
" foo\n"
|
||||
" --list arg a list:\n"
|
||||
" item1, item2, item3, item4, item5, item6, item7, \n"
|
||||
" item8, item9, item10, item11, item12, item13, \n"
|
||||
" item14, item15, item16, item17, item18\n"
|
||||
" --well_formated arg As you can see this is a very well formatted option \n"
|
||||
" description.\n"
|
||||
" You can do this for example:\n"
|
||||
" \n"
|
||||
" Values:\n"
|
||||
" Value1: does this and that, bla bla bla bla bla bla \n"
|
||||
" bla bla bla bla bla bla bla bla bla\n"
|
||||
" Value2: does something else, bla bla bla bla bla bla \n"
|
||||
" bla bla bla bla bla bla bla bla bla\n"
|
||||
" \n"
|
||||
" This paragraph has a first line indent only, bla \n"
|
||||
" bla bla bla bla bla bla bla bla bla bla bla bla bla bla\n"
|
||||
);
|
||||
}
|
||||
|
||||
void test_formatting_description_length()
|
||||
{
|
||||
{
|
||||
options_description desc("",
|
||||
options_description::m_default_line_length,
|
||||
options_description::m_default_line_length / 2U);
|
||||
desc.add_options()
|
||||
("an-option-that-sets-the-max", new untyped_value(), // > 40 available for desc
|
||||
"this description sits on the same line, but wrapping should still work correctly")
|
||||
("a-long-option-that-would-leave-very-little-space-for-description", new untyped_value(),
|
||||
"the description of the long opt, but placed on the next line\n"
|
||||
" \talso ensure that the tabulation works correctly when a"
|
||||
" description size has been set");
|
||||
|
||||
stringstream ss;
|
||||
ss << desc;
|
||||
BOOST_CHECK_EQUAL(ss.str(),
|
||||
" --an-option-that-sets-the-max arg this description sits on the same line,\n"
|
||||
" but wrapping should still work \n"
|
||||
" correctly\n"
|
||||
" --a-long-option-that-would-leave-very-little-space-for-description arg\n"
|
||||
" the description of the long opt, but \n"
|
||||
" placed on the next line\n"
|
||||
" also ensure that the tabulation \n"
|
||||
" works correctly when a description \n"
|
||||
" size has been set\n");
|
||||
}
|
||||
{
|
||||
// the default behaviour reserves 23 (+1 space) characters for the
|
||||
// option column; this shows that the min_description_length does not
|
||||
// breach that.
|
||||
options_description desc("",
|
||||
options_description::m_default_line_length,
|
||||
options_description::m_default_line_length - 10U); // leaves < 23 (default option space)
|
||||
desc.add_options()
|
||||
("an-option-that-encroaches-description", new untyped_value(),
|
||||
"this description should always be placed on the next line, and wrapping should continue as normal");
|
||||
|
||||
stringstream ss;
|
||||
ss << desc;
|
||||
BOOST_CHECK_EQUAL(ss.str(),
|
||||
" --an-option-that-encroaches-description arg\n"
|
||||
//123456789_123456789_
|
||||
" this description should always be placed on the next line, and \n"
|
||||
" wrapping should continue as normal\n");
|
||||
}
|
||||
}
|
||||
|
||||
void test_long_default_value()
|
||||
{
|
||||
options_description desc;
|
||||
desc.add_options()
|
||||
("cfgfile,c",
|
||||
value<string>()->default_value("/usr/local/etc/myprogramXXXXXXXXX/configuration.conf"),
|
||||
"the configfile")
|
||||
;
|
||||
|
||||
stringstream ss;
|
||||
ss << desc;
|
||||
BOOST_CHECK_EQUAL(ss.str(),
|
||||
" -c [ --cfgfile ] arg (=/usr/local/etc/myprogramXXXXXXXXX/configuration.conf)\n"
|
||||
" the configfile\n"
|
||||
);
|
||||
}
|
||||
|
||||
void test_word_wrapping()
|
||||
{
|
||||
options_description desc("Supported options");
|
||||
desc.add_options()
|
||||
("help", "this is a sufficiently long text to require word-wrapping")
|
||||
("prefix", value<string>()->default_value("/h/proj/tmp/dispatch"), "root path of the dispatch installation")
|
||||
("opt1", "this_is_a_sufficiently_long_text_to_require_word-wrapping_but_cannot_be_wrapped")
|
||||
("opt2", "this_is_a_sufficiently long_text_to_require_word-wrapping")
|
||||
("opt3", "this_is_a sufficiently_long_text_to_require_word-wrapping_but_will_not_be_wrapped")
|
||||
;
|
||||
stringstream ss;
|
||||
ss << desc;
|
||||
BOOST_CHECK_EQUAL(ss.str(),
|
||||
"Supported options:\n"
|
||||
" --help this is a sufficiently long text to \n"
|
||||
" require word-wrapping\n"
|
||||
" --prefix arg (=/h/proj/tmp/dispatch) root path of the dispatch installation\n"
|
||||
" --opt1 this_is_a_sufficiently_long_text_to_requ\n"
|
||||
" ire_word-wrapping_but_cannot_be_wrapped\n"
|
||||
" --opt2 this_is_a_sufficiently \n"
|
||||
" long_text_to_require_word-wrapping\n"
|
||||
" --opt3 this_is_a sufficiently_long_text_to_requ\n"
|
||||
" ire_word-wrapping_but_will_not_be_wrappe\n"
|
||||
" d\n"
|
||||
);
|
||||
}
|
||||
|
||||
void test_default_values()
|
||||
{
|
||||
options_description desc("Supported options");
|
||||
desc.add_options()
|
||||
("maxlength", value<double>()->default_value(.1, "0.1"), "Maximum edge length to keep.")
|
||||
;
|
||||
stringstream ss;
|
||||
ss << desc;
|
||||
BOOST_CHECK_EQUAL(ss.str(),
|
||||
"Supported options:\n"
|
||||
" --maxlength arg (=0.1) Maximum edge length to keep.\n"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
int main(int, char* [])
|
||||
{
|
||||
test_type();
|
||||
test_approximation();
|
||||
test_formatting();
|
||||
test_formatting_description_length();
|
||||
test_long_default_value();
|
||||
test_word_wrapping();
|
||||
test_default_values();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ void check_value(const option& option, const char* name, const char* value)
|
||||
BOOST_CHECK(option.value.front() == value);
|
||||
}
|
||||
|
||||
vector<string> sv(const char* array[], unsigned size)
|
||||
vector<string> sv(char* array[], unsigned size)
|
||||
{
|
||||
vector<string> r;
|
||||
for (unsigned i = 0; i < size; ++i)
|
||||
@@ -113,10 +113,10 @@ void test_command_line()
|
||||
("baz", new untyped_value())
|
||||
("plug*", new untyped_value())
|
||||
;
|
||||
const char* cmdline3_[] = { "--foo=12", "-f4", "--bar=11", "-b4",
|
||||
char* cmdline3_[] = { "--foo=12", "-f4", "--bar=11", "-b4",
|
||||
"--plug3=10"};
|
||||
vector<string> cmdline3 = sv(cmdline3_,
|
||||
sizeof(cmdline3_)/sizeof(const char*));
|
||||
sizeof(cmdline3_)/sizeof(cmdline3_[0]));
|
||||
vector<option> a3 =
|
||||
command_line_parser(cmdline3).options(desc).run().options;
|
||||
|
||||
@@ -131,78 +131,31 @@ void test_command_line()
|
||||
// Regression test: check that '0' as style is interpreted as
|
||||
// 'default_style'
|
||||
vector<option> a4 =
|
||||
parse_command_line(sizeof(cmdline3_)/sizeof(const char*), cmdline3_,
|
||||
desc, 0, additional_parser).options;
|
||||
parse_command_line(5, cmdline3_, desc, 0, additional_parser).options;
|
||||
|
||||
BOOST_CHECK_EQUAL(a4.size(), 4u);
|
||||
check_value(a4[0], "foo", "4");
|
||||
check_value(a4[1], "bar", "11");
|
||||
|
||||
// Check that we don't crash on empty values of type 'string'
|
||||
const char* cmdline4[] = {"", "--open", ""};
|
||||
char* cmdline4[] = {"", "--open", ""};
|
||||
options_description desc2;
|
||||
desc2.add_options()
|
||||
("open", po::value<string>())
|
||||
;
|
||||
variables_map vm;
|
||||
po::store(po::parse_command_line(sizeof(cmdline4)/sizeof(const char*), const_cast<char**>(cmdline4), desc2), vm);
|
||||
|
||||
const char* cmdline5[] = {"", "-p7", "-o", "1", "2", "3", "-x8"};
|
||||
options_description desc3;
|
||||
desc3.add_options()
|
||||
(",p", po::value<string>())
|
||||
(",o", po::value<string>()->multitoken())
|
||||
(",x", po::value<string>())
|
||||
;
|
||||
vector<option> a5 =
|
||||
parse_command_line(sizeof(cmdline5)/sizeof(const char*), const_cast<char**>(cmdline5),
|
||||
desc3, 0, additional_parser).options;
|
||||
BOOST_CHECK_EQUAL(a5.size(), 3u);
|
||||
check_value(a5[0], "-p", "7");
|
||||
BOOST_REQUIRE(a5[1].value.size() == 3);
|
||||
BOOST_CHECK_EQUAL(a5[1].string_key, "-o");
|
||||
BOOST_CHECK_EQUAL(a5[1].value[0], "1");
|
||||
BOOST_CHECK_EQUAL(a5[1].value[1], "2");
|
||||
BOOST_CHECK_EQUAL(a5[1].value[2], "3");
|
||||
check_value(a5[2], "-x", "8");
|
||||
po::store(po::parse_command_line(3, cmdline4, desc2), vm);
|
||||
|
||||
|
||||
po::options_description desc4( "" );
|
||||
desc4.add_options()
|
||||
( "multitoken,m",
|
||||
po::value< std::vector< std::string > >()->multitoken(),
|
||||
"values"
|
||||
)
|
||||
( "file",
|
||||
po::value< std::string >(),
|
||||
"the file to process"
|
||||
)
|
||||
;
|
||||
|
||||
po::positional_options_description p;
|
||||
p.add( "file", 1 );
|
||||
|
||||
const char* cmdline6[] = {"", "-m", "token1", "token2", "--", "some_file"};
|
||||
vector<option> a6 =
|
||||
command_line_parser(sizeof(cmdline6)/sizeof(const char*), const_cast<char**>(cmdline6)).options(desc4).positional(p)
|
||||
.run().options;
|
||||
BOOST_CHECK_EQUAL(a6.size(), 2u);
|
||||
BOOST_REQUIRE(a6[0].value.size() == 2);
|
||||
BOOST_CHECK_EQUAL(a6[0].string_key, "multitoken");
|
||||
BOOST_CHECK_EQUAL(a6[0].value[0], "token1");
|
||||
BOOST_CHECK_EQUAL(a6[0].value[1], "token2");
|
||||
BOOST_CHECK_EQUAL(a6[1].string_key, "file");
|
||||
BOOST_REQUIRE(a6[1].value.size() == 1);
|
||||
BOOST_CHECK_EQUAL(a6[1].value[0], "some_file");
|
||||
}
|
||||
|
||||
void test_config_file(const char* config_file)
|
||||
void test_config_file()
|
||||
{
|
||||
options_description desc;
|
||||
desc.add_options()
|
||||
("gv1", new untyped_value)
|
||||
("gv2", new untyped_value)
|
||||
("empty_value", new untyped_value)
|
||||
("plug*", new untyped_value)
|
||||
("m1.v1", new untyped_value)
|
||||
("m1.v2", new untyped_value)
|
||||
@@ -211,7 +164,6 @@ void test_config_file(const char* config_file)
|
||||
|
||||
const char content1[] =
|
||||
" gv1 = 0#asd\n"
|
||||
"empty_value = \n"
|
||||
"plug3 = 7\n"
|
||||
"b = true\n"
|
||||
"[m1]\n"
|
||||
@@ -222,23 +174,13 @@ void test_config_file(const char* config_file)
|
||||
|
||||
stringstream ss(content1);
|
||||
vector<option> a1 = parse_config_file(ss, desc).options;
|
||||
BOOST_REQUIRE(a1.size() == 6);
|
||||
BOOST_REQUIRE(a1.size() == 5);
|
||||
check_value(a1[0], "gv1", "0");
|
||||
check_value(a1[1], "empty_value", "");
|
||||
check_value(a1[2], "plug3", "7");
|
||||
check_value(a1[3], "b", "true");
|
||||
check_value(a1[4], "m1.v1", "1");
|
||||
check_value(a1[5], "m1.v2", "2");
|
||||
|
||||
// same test, but now options come from file
|
||||
vector<option> a2 = parse_config_file<char>(config_file, desc).options;
|
||||
BOOST_REQUIRE(a2.size() == 6);
|
||||
check_value(a2[0], "gv1", "0");
|
||||
check_value(a2[1], "empty_value", "");
|
||||
check_value(a2[2], "plug3", "7");
|
||||
check_value(a2[3], "b", "true");
|
||||
check_value(a2[4], "m1.v1", "1");
|
||||
check_value(a2[5], "m1.v2", "2");
|
||||
check_value(a1[1], "plug3", "7");
|
||||
check_value(a1[2], "b", "true");
|
||||
check_value(a1[3], "m1.v1", "1");
|
||||
check_value(a1[4], "m1.v2", "2");
|
||||
|
||||
}
|
||||
|
||||
void test_environment()
|
||||
@@ -252,7 +194,7 @@ void test_environment()
|
||||
#if defined(_WIN32) && ! defined(__BORLANDC__)
|
||||
_putenv("PO_TEST_FOO=1");
|
||||
#else
|
||||
putenv(const_cast<char*>("PO_TEST_FOO=1"));
|
||||
putenv("PO_TEST_FOO=1");
|
||||
#endif
|
||||
parsed_options p = parse_environment(desc, "PO_TEST_");
|
||||
|
||||
@@ -269,9 +211,9 @@ void test_unregistered()
|
||||
{
|
||||
options_description desc;
|
||||
|
||||
const char* cmdline1_[] = { "--foo=12", "--bar", "1"};
|
||||
char* cmdline1_[] = { "--foo=12", "--bar", "1"};
|
||||
vector<string> cmdline1 = sv(cmdline1_,
|
||||
sizeof(cmdline1_)/sizeof(const char*));
|
||||
sizeof(cmdline1_)/sizeof(cmdline1_[0]));
|
||||
vector<option> a1 =
|
||||
command_line_parser(cmdline1).options(desc).allow_unregistered().run()
|
||||
.options;
|
||||
@@ -316,10 +258,10 @@ void test_unregistered()
|
||||
check_value(a3[1], "m1.v1", "1");
|
||||
}
|
||||
|
||||
int main(int, char* av[])
|
||||
int main(int, char* [])
|
||||
{
|
||||
test_command_line();
|
||||
test_config_file(av[1]);
|
||||
test_config_file();
|
||||
test_environment();
|
||||
test_unregistered();
|
||||
return 0;
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
cfgfile = file.cfg
|
||||
@@ -1,97 +0,0 @@
|
||||
// Copyright Sascha Ochsenknecht 2009.
|
||||
// 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)
|
||||
|
||||
#include <boost/program_options.hpp>
|
||||
using namespace boost::program_options;
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
using namespace std;
|
||||
|
||||
#include "minitest.hpp"
|
||||
|
||||
|
||||
void required_throw_test()
|
||||
{
|
||||
options_description opts;
|
||||
opts.add_options()
|
||||
("cfgfile,c", value<string>()->required(), "the configfile")
|
||||
("fritz,f", value<string>()->required(), "the output file")
|
||||
;
|
||||
|
||||
variables_map vm;
|
||||
bool throwed = false;
|
||||
{
|
||||
// This test must throw exception
|
||||
string cmdline = "prg -f file.txt";
|
||||
vector< string > tokens = split_unix(cmdline);
|
||||
throwed = false;
|
||||
try {
|
||||
store(command_line_parser(tokens).options(opts).run(), vm);
|
||||
notify(vm);
|
||||
}
|
||||
catch (required_option& e) {
|
||||
throwed = true;
|
||||
}
|
||||
BOOST_CHECK(throwed);
|
||||
}
|
||||
|
||||
{
|
||||
// This test mustn't throw exception
|
||||
string cmdline = "prg -c config.txt";
|
||||
vector< string > tokens = split_unix(cmdline);
|
||||
throwed = false;
|
||||
try {
|
||||
store(command_line_parser(tokens).options(opts).run(), vm);
|
||||
notify(vm);
|
||||
}
|
||||
catch (required_option& e) {
|
||||
throwed = true;
|
||||
}
|
||||
BOOST_CHECK(!throwed);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void simple_required_test(const char* config_file)
|
||||
{
|
||||
options_description opts;
|
||||
opts.add_options()
|
||||
("cfgfile,c", value<string>()->required(), "the configfile")
|
||||
("fritz,f", value<string>()->required(), "the output file")
|
||||
;
|
||||
|
||||
variables_map vm;
|
||||
bool throwed = false;
|
||||
{
|
||||
// This test must throw exception
|
||||
string cmdline = "prg -f file.txt";
|
||||
vector< string > tokens = split_unix(cmdline);
|
||||
throwed = false;
|
||||
try {
|
||||
// options coming from different sources
|
||||
store(command_line_parser(tokens).options(opts).run(), vm);
|
||||
store(parse_config_file<char>(config_file, opts), vm);
|
||||
notify(vm);
|
||||
}
|
||||
catch (required_option& e) {
|
||||
throwed = true;
|
||||
}
|
||||
BOOST_CHECK(!throwed);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main(int /*argc*/, char* av[])
|
||||
{
|
||||
required_throw_test();
|
||||
simple_required_test(av[1]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,189 +0,0 @@
|
||||
// Copyright Sascha Ochsenknecht 2009.
|
||||
// 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)
|
||||
|
||||
|
||||
#include <boost/program_options/parsers.hpp>
|
||||
#include <boost/program_options/options_description.hpp>
|
||||
#include <boost/program_options/variables_map.hpp>
|
||||
#include <boost/program_options/cmdline.hpp>
|
||||
using namespace boost::program_options;
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <cassert>
|
||||
using namespace std;
|
||||
|
||||
#include "minitest.hpp"
|
||||
|
||||
void check_value(const string& option, const string& value)
|
||||
{
|
||||
BOOST_CHECK(option == value);
|
||||
}
|
||||
|
||||
void split_whitespace(const options_description& description)
|
||||
{
|
||||
|
||||
const char* cmdline = "prg --input input.txt \r --optimization 4 \t --opt \n option";
|
||||
|
||||
vector< string > tokens = split_unix(cmdline, " \t\n\r");
|
||||
|
||||
BOOST_REQUIRE(tokens.size() == 7);
|
||||
|
||||
check_value(tokens[0], "prg");
|
||||
check_value(tokens[1], "--input");
|
||||
check_value(tokens[2], "input.txt");
|
||||
check_value(tokens[3], "--optimization");
|
||||
check_value(tokens[4], "4");
|
||||
check_value(tokens[5], "--opt");
|
||||
check_value(tokens[6], "option");
|
||||
|
||||
variables_map vm;
|
||||
store(command_line_parser(tokens).options(description).run(), vm);
|
||||
notify(vm);
|
||||
}
|
||||
|
||||
void split_equalsign(const options_description& description)
|
||||
{
|
||||
|
||||
const char* cmdline = "prg --input=input.txt --optimization=4 --opt=option";
|
||||
|
||||
vector< string > tokens = split_unix(cmdline, "= ");
|
||||
|
||||
BOOST_REQUIRE(tokens.size() == 7);
|
||||
check_value(tokens[0], "prg");
|
||||
check_value(tokens[1], "--input");
|
||||
check_value(tokens[2], "input.txt");
|
||||
check_value(tokens[3], "--optimization");
|
||||
check_value(tokens[4], "4");
|
||||
check_value(tokens[5], "--opt");
|
||||
check_value(tokens[6], "option");
|
||||
|
||||
variables_map vm;
|
||||
store(command_line_parser(tokens).options(description).run(), vm);
|
||||
notify(vm);
|
||||
}
|
||||
|
||||
void split_semi(const options_description& description)
|
||||
{
|
||||
|
||||
const char* cmdline = "prg;--input input.txt;--optimization 4;--opt option";
|
||||
|
||||
vector< string > tokens = split_unix(cmdline, "; ");
|
||||
|
||||
BOOST_REQUIRE(tokens.size() == 7);
|
||||
check_value(tokens[0], "prg");
|
||||
check_value(tokens[1], "--input");
|
||||
check_value(tokens[2], "input.txt");
|
||||
check_value(tokens[3], "--optimization");
|
||||
check_value(tokens[4], "4");
|
||||
check_value(tokens[5], "--opt");
|
||||
check_value(tokens[6], "option");
|
||||
|
||||
variables_map vm;
|
||||
store(command_line_parser(tokens).options(description).run(), vm);
|
||||
notify(vm);
|
||||
}
|
||||
|
||||
void split_quotes(const options_description& description)
|
||||
{
|
||||
const char* cmdline = "prg --input \"input.txt input.txt\" --optimization 4 --opt \"option1 option2\"";
|
||||
|
||||
vector< string > tokens = split_unix(cmdline, " ");
|
||||
|
||||
BOOST_REQUIRE(tokens.size() == 7);
|
||||
check_value(tokens[0], "prg");
|
||||
check_value(tokens[1], "--input");
|
||||
check_value(tokens[2], "input.txt input.txt");
|
||||
check_value(tokens[3], "--optimization");
|
||||
check_value(tokens[4], "4");
|
||||
check_value(tokens[5], "--opt");
|
||||
check_value(tokens[6], "option1 option2");
|
||||
|
||||
variables_map vm;
|
||||
store(command_line_parser(tokens).options(description).run(), vm);
|
||||
notify(vm);
|
||||
}
|
||||
|
||||
void split_escape(const options_description& description)
|
||||
{
|
||||
const char* cmdline = "prg --input \\\"input.txt\\\" --optimization 4 --opt \\\"option1\\ option2\\\"";
|
||||
|
||||
vector< string > tokens = split_unix(cmdline, " ");
|
||||
|
||||
BOOST_REQUIRE(tokens.size() == 7);
|
||||
check_value(tokens[0], "prg");
|
||||
check_value(tokens[1], "--input");
|
||||
check_value(tokens[2], "\"input.txt\"");
|
||||
check_value(tokens[3], "--optimization");
|
||||
check_value(tokens[4], "4");
|
||||
check_value(tokens[5], "--opt");
|
||||
check_value(tokens[6], "\"option1 option2\"");
|
||||
|
||||
variables_map vm;
|
||||
store(command_line_parser(tokens).options(description).run(), vm);
|
||||
notify(vm);
|
||||
}
|
||||
|
||||
|
||||
void split_single_quote(const options_description& description)
|
||||
{
|
||||
const char* cmdline = "prg --input 'input.txt input.txt' --optimization 4 --opt 'option1 option2'";
|
||||
|
||||
vector< string > tokens = split_unix(cmdline, " ", "'");
|
||||
|
||||
BOOST_REQUIRE(tokens.size() == 7);
|
||||
check_value(tokens[0], "prg");
|
||||
check_value(tokens[1], "--input");
|
||||
check_value(tokens[2], "input.txt input.txt");
|
||||
check_value(tokens[3], "--optimization");
|
||||
check_value(tokens[4], "4");
|
||||
check_value(tokens[5], "--opt");
|
||||
check_value(tokens[6], "option1 option2");
|
||||
|
||||
variables_map vm;
|
||||
store(command_line_parser(tokens).options(description).run(), vm);
|
||||
notify(vm);
|
||||
}
|
||||
|
||||
void split_defaults(const options_description& description)
|
||||
{
|
||||
const char* cmdline = "prg --input \t \'input file.txt\' \t --optimization 4 --opt \\\"option1\\ option2\\\"";
|
||||
|
||||
vector< string > tokens = split_unix(cmdline);
|
||||
|
||||
BOOST_REQUIRE(tokens.size() == 7);
|
||||
check_value(tokens[0], "prg");
|
||||
check_value(tokens[1], "--input");
|
||||
check_value(tokens[2], "input file.txt");
|
||||
check_value(tokens[3], "--optimization");
|
||||
check_value(tokens[4], "4");
|
||||
check_value(tokens[5], "--opt");
|
||||
check_value(tokens[6], "\"option1 option2\"");
|
||||
|
||||
variables_map vm;
|
||||
store(command_line_parser(tokens).options(description).run(), vm);
|
||||
notify(vm);
|
||||
}
|
||||
|
||||
int main(int /*ac*/, char** /*av*/)
|
||||
{
|
||||
options_description desc;
|
||||
desc.add_options()
|
||||
("input,i", value<string>(), "the input file")
|
||||
("optimization,O", value<unsigned>(), "optimization level")
|
||||
("opt,o", value<string>(), "misc option")
|
||||
;
|
||||
|
||||
split_whitespace(desc);
|
||||
split_equalsign(desc);
|
||||
split_semi(desc);
|
||||
split_quotes(desc);
|
||||
split_escape(desc);
|
||||
split_single_quote(desc);
|
||||
split_defaults(desc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -3,7 +3,6 @@
|
||||
// (See accompanying file LICENSE_1_0.txt
|
||||
// or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <cstring>
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
@@ -39,8 +38,8 @@ std::wstring from_8_bit_2(const std::string& s,
|
||||
std::wstring result;
|
||||
|
||||
|
||||
std::mbstate_t state = std::mbstate_t();
|
||||
|
||||
std::mbstate_t state = {0};
|
||||
|
||||
const char* from = s.data();
|
||||
const char* from_end = s.data() + s.size();
|
||||
// The interace of cvt is not really iterator-like, and it's
|
||||
|
||||
@@ -34,13 +34,9 @@ void test_unicode_to_unicode()
|
||||
args.push_back(L"--foo=\x044F");
|
||||
|
||||
variables_map vm;
|
||||
basic_parsed_options<wchar_t> parsed =
|
||||
wcommand_line_parser(args).options(desc).run();
|
||||
store(parsed, vm);
|
||||
store(wcommand_line_parser(args).options(desc).run(), vm);
|
||||
|
||||
BOOST_CHECK(vm["foo"].as<wstring>() == L"\x044F");
|
||||
BOOST_CHECK(parsed.options[0].original_tokens.size() == 1);
|
||||
BOOST_CHECK(parsed.options[0].original_tokens[0] == L"--foo=\x044F");
|
||||
BOOST_CHECK(vm["foo"].as<wstring>() == L"\x044F");
|
||||
}
|
||||
|
||||
// Test that unicode input is property converted into
|
||||
@@ -88,7 +84,8 @@ void test_native_to_unicode()
|
||||
BOOST_CHECK(vm["foo"].as<wstring>() == L"\x044F");
|
||||
}
|
||||
|
||||
vector<wstring> sv(const wchar_t* array[], unsigned size)
|
||||
|
||||
vector<wstring> sv(wchar_t* array[], unsigned size)
|
||||
{
|
||||
vector<wstring> r;
|
||||
for (unsigned i = 0; i < size; ++i)
|
||||
@@ -114,7 +111,7 @@ void test_command_line()
|
||||
("plug*", new untyped_value())
|
||||
;
|
||||
|
||||
const wchar_t* cmdline4_[] = { L"--foo=1\u0FF52", L"-f4", L"--bar=11",
|
||||
wchar_t* cmdline4_[] = { L"--foo=1\u0FF52", L"-f4", L"--bar=11",
|
||||
L"-b4", L"--plug3=10"};
|
||||
vector<wstring> cmdline4 = sv(cmdline4_,
|
||||
sizeof(cmdline4_)/sizeof(cmdline4_[0]));
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
// Copyright Sascha Ochsenknecht 2009.
|
||||
// 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)
|
||||
|
||||
|
||||
#include <boost/program_options/cmdline.hpp>
|
||||
#include <boost/program_options/options_description.hpp>
|
||||
#include <boost/program_options/parsers.hpp>
|
||||
#include <boost/program_options/detail/cmdline.hpp>
|
||||
using namespace boost::program_options;
|
||||
using boost::program_options::detail::cmdline;
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <cassert>
|
||||
using namespace std;
|
||||
|
||||
#include "minitest.hpp"
|
||||
|
||||
|
||||
// Test free function collect_unrecognized()
|
||||
//
|
||||
// it collects the tokens of all not registered options. It can be used
|
||||
// to pass them to an own parser implementation
|
||||
|
||||
|
||||
|
||||
void test_unrecognize_cmdline()
|
||||
{
|
||||
options_description desc;
|
||||
|
||||
string content = "prg --input input.txt --optimization 4 --opt option";
|
||||
vector< string > tokens = split_unix(content);
|
||||
|
||||
cmdline cmd(tokens);
|
||||
cmd.set_options_description(desc);
|
||||
cmd.allow_unregistered();
|
||||
|
||||
vector< option > opts = cmd.run();
|
||||
vector< string > result = collect_unrecognized(opts, include_positional);
|
||||
|
||||
BOOST_CHECK_EQUAL(result.size(), 7);
|
||||
BOOST_CHECK_EQUAL(result[0], "prg");
|
||||
BOOST_CHECK_EQUAL(result[1], "--input");
|
||||
BOOST_CHECK_EQUAL(result[2], "input.txt");
|
||||
BOOST_CHECK_EQUAL(result[3], "--optimization");
|
||||
BOOST_CHECK_EQUAL(result[4], "4");
|
||||
BOOST_CHECK_EQUAL(result[5], "--opt");
|
||||
BOOST_CHECK_EQUAL(result[6], "option");
|
||||
}
|
||||
|
||||
|
||||
|
||||
void test_unrecognize_config()
|
||||
{
|
||||
|
||||
options_description desc;
|
||||
|
||||
string content =
|
||||
" input = input.txt\n"
|
||||
" optimization = 4\n"
|
||||
" opt = option\n"
|
||||
;
|
||||
|
||||
stringstream ss(content);
|
||||
vector< option > opts = parse_config_file(ss, desc, true).options;
|
||||
vector< string > result = collect_unrecognized(opts, include_positional);
|
||||
|
||||
BOOST_CHECK_EQUAL(result.size(), 6);
|
||||
BOOST_CHECK_EQUAL(result[0], "input");
|
||||
BOOST_CHECK_EQUAL(result[1], "input.txt");
|
||||
BOOST_CHECK_EQUAL(result[2], "optimization");
|
||||
BOOST_CHECK_EQUAL(result[3], "4");
|
||||
BOOST_CHECK_EQUAL(result[4], "opt");
|
||||
BOOST_CHECK_EQUAL(result[5], "option");
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main(int /*ac*/, char** /*av*/)
|
||||
{
|
||||
test_unrecognize_cmdline();
|
||||
test_unrecognize_config();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -20,7 +20,7 @@ using namespace std;
|
||||
|
||||
#include "minitest.hpp"
|
||||
|
||||
vector<string> sv(const char* array[], unsigned size)
|
||||
vector<string> sv(char* array[], unsigned size)
|
||||
{
|
||||
vector<string> r;
|
||||
for (unsigned i = 0; i < size; ++i)
|
||||
@@ -38,9 +38,9 @@ void test_variable_map()
|
||||
("baz", new untyped_value())
|
||||
("output,o", new untyped_value(), "")
|
||||
;
|
||||
const char* cmdline3_[] = { "--foo='12'", "--bar=11", "-z3", "-ofoo" };
|
||||
char* cmdline3_[] = { "--foo='12'", "--bar=11", "-z3", "-ofoo" };
|
||||
vector<string> cmdline3 = sv(cmdline3_,
|
||||
sizeof(cmdline3_)/sizeof(const char*));
|
||||
sizeof(cmdline3_)/sizeof(cmdline3_[0]));
|
||||
parsed_options a3 = command_line_parser(cmdline3).options(desc).run();
|
||||
variables_map vm;
|
||||
store(a3, vm);
|
||||
@@ -58,9 +58,9 @@ void test_variable_map()
|
||||
("zak", po::value<int>(&i), "")
|
||||
("opt", bool_switch(), "");
|
||||
|
||||
const char* cmdline4_[] = { "--zee", "--zak=13" };
|
||||
char* cmdline4_[] = { "--zee", "--zak=13" };
|
||||
vector<string> cmdline4 = sv(cmdline4_,
|
||||
sizeof(cmdline4_)/sizeof(const char*));
|
||||
sizeof(cmdline4_)/sizeof(cmdline4_[0]));
|
||||
parsed_options a4 = command_line_parser(cmdline4).options(desc).run();
|
||||
|
||||
variables_map vm2;
|
||||
@@ -78,9 +78,9 @@ void test_variable_map()
|
||||
("voo", po::value<string>())
|
||||
("iii", po::value<int>()->default_value(123))
|
||||
;
|
||||
const char* cmdline5_[] = { "--voo=1" };
|
||||
char* cmdline5_[] = { "--voo=1" };
|
||||
vector<string> cmdline5 = sv(cmdline5_,
|
||||
sizeof(cmdline5_)/sizeof(const char*));
|
||||
sizeof(cmdline5_)/sizeof(cmdline5_[0]));
|
||||
parsed_options a5 = command_line_parser(cmdline5).options(desc2).run();
|
||||
|
||||
variables_map vm3;
|
||||
@@ -96,19 +96,16 @@ void test_variable_map()
|
||||
("imp", po::value<int>()->implicit_value(100))
|
||||
("iim", po::value<int>()->implicit_value(200)->default_value(201))
|
||||
("mmp,m", po::value<int>()->implicit_value(123)->default_value(124))
|
||||
("foo", po::value<int>())
|
||||
;
|
||||
/* The -m option is implicit. It does not have value in inside the token,
|
||||
and we should not grab the next token. */
|
||||
const char* cmdline6_[] = { "--imp=1", "-m", "--foo=1" };
|
||||
char* cmdline6_[] = { "--imp=1", "-m" };
|
||||
vector<string> cmdline6 = sv(cmdline6_,
|
||||
sizeof(cmdline6_)/sizeof(const char*));
|
||||
sizeof(cmdline6_)/sizeof(cmdline6_[0]));
|
||||
parsed_options a6 = command_line_parser(cmdline6).options(desc3).run();
|
||||
|
||||
variables_map vm4;
|
||||
store(a6, vm4);
|
||||
notify(vm4);
|
||||
BOOST_REQUIRE(vm4.size() == 4);
|
||||
BOOST_REQUIRE(vm4.size() == 3);
|
||||
BOOST_CHECK(vm4["imp"].as<int>() == 1);
|
||||
BOOST_CHECK(vm4["iim"].as<int>() == 201);
|
||||
BOOST_CHECK(vm4["mmp"].as<int>() == 123);
|
||||
@@ -194,15 +191,15 @@ void test_priority()
|
||||
("include", po::value< vector<int> >()->composing())
|
||||
;
|
||||
|
||||
const char* cmdline1_[] = { "--first=1", "--aux=10", "--first=3", "--include=1" };
|
||||
char* cmdline1_[] = { "--first=1", "--aux=10", "--first=3", "--include=1" };
|
||||
vector<string> cmdline1 = sv(cmdline1_,
|
||||
sizeof(cmdline1_)/sizeof(const char*));
|
||||
sizeof(cmdline1_)/sizeof(cmdline1_[0]));
|
||||
|
||||
parsed_options p1 = command_line_parser(cmdline1).options(desc).run();
|
||||
|
||||
const char* cmdline2_[] = { "--first=12", "--second=7", "--include=7" };
|
||||
char* cmdline2_[] = { "--first=12", "--second=7", "--include=7" };
|
||||
vector<string> cmdline2 = sv(cmdline2_,
|
||||
sizeof(cmdline2_)/sizeof(const char*));
|
||||
sizeof(cmdline2_)/sizeof(cmdline2_[0]));
|
||||
|
||||
parsed_options p2 = command_line_parser(cmdline2).options(desc).run();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user