mirror of
https://github.com/boostorg/program_options.git
synced 2026-01-24 18:12:37 +00:00
Compare commits
4 Commits
develop
...
boost-1.33
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c8f95dbda3 | ||
|
|
81aff160d0 | ||
|
|
705e79b5ee | ||
|
|
3ae92db179 |
@@ -398,13 +398,49 @@ $ export LC_CTYPE=ru_RU.KOI8-R
|
|||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<title>Allowing Unknown Options</title>
|
||||||
|
|
||||||
|
<para>Usually, the library throws an exception on unknown option names. This
|
||||||
|
behaviour can be changed. For example, only some part of your application uses
|
||||||
|
<libraryname>Program_options</libraryname>, and you wish to pass unrecognized options to another part of
|
||||||
|
the program, or even to another application.</para>
|
||||||
|
|
||||||
|
<para>To allow unregistered options on the command line, you need to use
|
||||||
|
the &basic_command_line_parser; class for parsing (not &parse_command_line;)
|
||||||
|
and call the <methodname alt="boost::program_options::basic_command_line_parser::allow_unregistered">allow_unregistered</methodname>
|
||||||
|
method of that class:
|
||||||
|
<programlisting>
|
||||||
|
parsed_options parsed =
|
||||||
|
command_line_parser(argv, argc).options(desc).allow_unregistered().run();
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
For each token that looks like an option, but does not have a known name,
|
||||||
|
an instance of &basic_option; will be added to the result.
|
||||||
|
The <code>string_key</code> and <code>value</code> fields of the instance will contain results
|
||||||
|
of syntactic parsing of the token, the <code>unregistered</code> field will be set to <code>true</code>,
|
||||||
|
and the <code>original_tokens</code> field will contain the token as it appeared on the command line.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>If you want to pass the unrecognized options further, the
|
||||||
|
<functionname alt="boost::program_options::collect_unrecognized">collect_unrecognized</functionname> function can be used.
|
||||||
|
The function will collect original tokens for all unrecognized values, and optionally, all found positional options.
|
||||||
|
Say, if your code handles a few options, but does not handles positional options at all, you can use the function like this:
|
||||||
|
<programlisting>
|
||||||
|
vector<string> to_pass_further = collect_arguments(parsed.option, include_positional);
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
</para>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Local Variables:
|
Local Variables:
|
||||||
mode: xml
|
mode: nxml
|
||||||
sgml-indent-data: t
|
sgml-indent-data: t
|
||||||
sgml-parent-document: ("program_options.xml" "section")
|
sgml-parent-document: ("userman.xml" "chapter")
|
||||||
sgml-set-face: t
|
sgml-set-face: t
|
||||||
End:
|
End:
|
||||||
-->
|
-->
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta http-equiv="refresh" content="0; URL=../../../doc/html/program_option.html">
|
<meta http-equiv="refresh" content="0; URL=../../../doc/html/program_options.html">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
Automatic redirection failed, please go to
|
Automatic redirection failed, please go to
|
||||||
|
|||||||
@@ -37,3 +37,10 @@
|
|||||||
<!ENTITY command_line_parser
|
<!ENTITY command_line_parser
|
||||||
"<classname alt='boost::program_options::command_line_parser'>command_line_parser</classname>">
|
"<classname alt='boost::program_options::command_line_parser'>command_line_parser</classname>">
|
||||||
|
|
||||||
|
<!ENTITY basic_command_line_parser
|
||||||
|
"<classname alt='boost::program_options::basic_command_line_parser'>basic_command_line_parser</classname>">
|
||||||
|
|
||||||
|
|
||||||
|
<!ENTITY basic_option
|
||||||
|
"<classname alt='boost::program_options::basic_option'>basic_option</classname>">
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
|
|
||||||
|
Make parse_config_file("foo.cfg", desc) work.
|
||||||
|
|
||||||
Document handling of positional options which depends on precedding options.
|
Document handling of positional options which depends on precedding options.
|
||||||
I.e scanning the parsed options and creating new variables_map when we see
|
I.e scanning the parsed options and creating new variables_map when we see
|
||||||
a positional option. (Email from Tony).
|
a positional option. (Email from Tony).
|
||||||
|
|||||||
@@ -76,6 +76,24 @@ namespace boost { namespace program_options {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class charT>
|
||||||
|
basic_command_line_parser<charT>&
|
||||||
|
basic_command_line_parser<charT>::allow_unregistered()
|
||||||
|
{
|
||||||
|
detail::cmdline::allow_unregistered();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class charT>
|
||||||
|
basic_command_line_parser<charT>&
|
||||||
|
basic_command_line_parser<charT>::extra_style_parser(style_parser s)
|
||||||
|
{
|
||||||
|
detail::cmdline::extra_style_parser(s);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template<class charT>
|
template<class charT>
|
||||||
basic_parsed_options<charT>
|
basic_parsed_options<charT>
|
||||||
basic_command_line_parser<charT>::run()
|
basic_command_line_parser<charT>::run()
|
||||||
@@ -101,6 +119,26 @@ namespace boost { namespace program_options {
|
|||||||
style(style).extra_parser(ext).run();
|
style(style).extra_parser(ext).run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class charT>
|
||||||
|
std::vector< std::basic_string<charT> >
|
||||||
|
collect_unrecognized(const std::vector< basic_option<charT> >& options,
|
||||||
|
enum collect_unrecognized_mode mode)
|
||||||
|
{
|
||||||
|
std::vector< std::basic_string<charT> > result;
|
||||||
|
for(unsigned i = 0; i < options.size(); ++i)
|
||||||
|
{
|
||||||
|
if (options[i].unregistered ||
|
||||||
|
(mode == include_positional && options[i].position_key != -1))
|
||||||
|
{
|
||||||
|
copy(options[i].original_tokens.begin(),
|
||||||
|
options[i].original_tokens.end(),
|
||||||
|
back_inserter(result));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -41,10 +41,16 @@ namespace boost { namespace program_options {
|
|||||||
int position_key;
|
int position_key;
|
||||||
/** Option's value */
|
/** Option's value */
|
||||||
std::vector< std::basic_string<charT> > value;
|
std::vector< std::basic_string<charT> > value;
|
||||||
|
/** The original unchanged tokens this option was
|
||||||
|
created from. */
|
||||||
|
std::vector< std::basic_string<charT> > original_tokens;
|
||||||
/** True if option was not recognized. In that case,
|
/** True if option was not recognized. In that case,
|
||||||
'string_key' and 'value' are results of purely
|
'string_key' and 'value' are results of purely
|
||||||
syntactic parsing of source. */
|
syntactic parsing of source. The original tokens can be
|
||||||
|
recovered from the "original_tokens" member.
|
||||||
|
*/
|
||||||
bool unregistered;
|
bool unregistered;
|
||||||
|
|
||||||
};
|
};
|
||||||
typedef basic_option<char> option;
|
typedef basic_option<char> option;
|
||||||
typedef basic_option<wchar_t> woption;
|
typedef basic_option<wchar_t> woption;
|
||||||
|
|||||||
@@ -73,13 +73,16 @@ namespace boost { namespace program_options {
|
|||||||
/** Command line parser.
|
/** Command line parser.
|
||||||
|
|
||||||
The class allows one to specify all the information needed for parsing
|
The class allows one to specify all the information needed for parsing
|
||||||
and to parser the parse the command line. It is primarily needed to
|
and to parse the command line. It is primarily needed to
|
||||||
emulate named function parameters -- a regular function with 5
|
emulate named function parameters -- a regular function with 5
|
||||||
parameters will be hard to use and creating overloads with a smaller
|
parameters will be hard to use and creating overloads with a smaller
|
||||||
nuber of parameters will be confusing.
|
nuber of parameters will be confusing.
|
||||||
|
|
||||||
For the most common case, the function parse_command_line is a better
|
For the most common case, the function parse_command_line is a better
|
||||||
alternative.
|
alternative.
|
||||||
|
|
||||||
|
There are two typedefs -- command_line_parser and wcommand_line_parser,
|
||||||
|
for charT == char and charT == wchar_t cases.
|
||||||
*/
|
*/
|
||||||
template<class charT>
|
template<class charT>
|
||||||
class basic_command_line_parser : private detail::cmdline {
|
class basic_command_line_parser : private detail::cmdline {
|
||||||
@@ -90,7 +93,7 @@ namespace boost { namespace program_options {
|
|||||||
basic_command_line_parser(const std::vector<
|
basic_command_line_parser(const std::vector<
|
||||||
std::basic_string<charT> >& args);
|
std::basic_string<charT> >& args);
|
||||||
/** Creates a command line parser for the specified arguments
|
/** Creates a command line parser for the specified arguments
|
||||||
list. The parameter should be the same as passes to 'main'.
|
list. The parameters should be the same as passed to 'main'.
|
||||||
*/
|
*/
|
||||||
basic_command_line_parser(int argc, charT* argv[]);
|
basic_command_line_parser(int argc, charT* argv[]);
|
||||||
|
|
||||||
@@ -104,8 +107,26 @@ namespace boost { namespace program_options {
|
|||||||
basic_command_line_parser& style(int);
|
basic_command_line_parser& style(int);
|
||||||
/** Sets the extra parsers. */
|
/** Sets the extra parsers. */
|
||||||
basic_command_line_parser& extra_parser(ext_parser);
|
basic_command_line_parser& extra_parser(ext_parser);
|
||||||
|
|
||||||
|
/** Parses the options and returns the result of parsing.
|
||||||
|
Throws on error.
|
||||||
|
*/
|
||||||
basic_parsed_options<charT> run();
|
basic_parsed_options<charT> run();
|
||||||
|
|
||||||
|
/** Specifies that unregistered options are allowed and should
|
||||||
|
be passed though. For each command like token that looks
|
||||||
|
like an option but does not contain a recognized name, an
|
||||||
|
instance of basic_option<charT> will be added to result,
|
||||||
|
with 'unrecognized' field set to 'true'. It's possible to
|
||||||
|
collect all unrecognized options with the 'collect_unrecognized'
|
||||||
|
funciton.
|
||||||
|
*/
|
||||||
|
basic_command_line_parser& allow_unregistered();
|
||||||
|
|
||||||
|
using detail::cmdline::style_parser;
|
||||||
|
|
||||||
|
basic_command_line_parser& extra_style_parser(style_parser s);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const options_description* m_desc;
|
const options_description* m_desc;
|
||||||
};
|
};
|
||||||
@@ -134,6 +155,22 @@ namespace boost { namespace program_options {
|
|||||||
basic_parsed_options<charT>
|
basic_parsed_options<charT>
|
||||||
parse_config_file(std::basic_istream<charT>&, const options_description&);
|
parse_config_file(std::basic_istream<charT>&, const options_description&);
|
||||||
|
|
||||||
|
/** Controls if the 'collect_unregistered' function should
|
||||||
|
include positional options, or not. */
|
||||||
|
enum collect_unrecognized_mode
|
||||||
|
{ include_positional, exclude_positional };
|
||||||
|
|
||||||
|
/** Collects the original tokens for all named options with
|
||||||
|
'unregistered' flag set. If 'mode' is 'include_positional'
|
||||||
|
also collects all positional options.
|
||||||
|
Returns the vector of origianl tokens for all collected
|
||||||
|
options.
|
||||||
|
*/
|
||||||
|
template<class charT>
|
||||||
|
std::vector< std::basic_string<charT> >
|
||||||
|
collect_unrecognized(const std::vector< basic_option<charT> >& options,
|
||||||
|
enum collect_unrecognized_mode mode);
|
||||||
|
|
||||||
/** Parse environment.
|
/** Parse environment.
|
||||||
|
|
||||||
For each environment variable, the 'name_mapper' function is called to
|
For each environment variable, the 'name_mapper' function is called to
|
||||||
@@ -180,6 +217,7 @@ namespace boost { namespace program_options {
|
|||||||
split_winmain(const std::wstring& cmdline);
|
split_winmain(const std::wstring& cmdline);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ namespace boost { namespace program_options {
|
|||||||
namespace boost { namespace program_options { namespace detail {
|
namespace boost { namespace program_options { namespace detail {
|
||||||
|
|
||||||
// vc6 needs this, but borland chokes when this is added.
|
// vc6 needs this, but borland chokes when this is added.
|
||||||
#if BOOST_WORKAROUND(_MSC_VER, <= 1200)
|
#if BOOST_WORKAROUND(_MSC_VER, < 1300)
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace program_options;
|
using namespace program_options;
|
||||||
#endif
|
#endif
|
||||||
@@ -248,6 +248,7 @@ namespace boost { namespace program_options { namespace detail {
|
|||||||
if (!ok) {
|
if (!ok) {
|
||||||
option opt;
|
option opt;
|
||||||
opt.value.push_back(args[0]);
|
opt.value.push_back(args[0]);
|
||||||
|
opt.original_tokens.push_back(args[0]);
|
||||||
result.push_back(opt);
|
result.push_back(opt);
|
||||||
args.erase(args.begin());
|
args.erase(args.begin());
|
||||||
}
|
}
|
||||||
@@ -331,6 +332,7 @@ namespace boost { namespace program_options { namespace detail {
|
|||||||
// Everything's OK, move the values to the result.
|
// Everything's OK, move the values to the result.
|
||||||
for(;!other_tokens.empty() && max_tokens--; ) {
|
for(;!other_tokens.empty() && max_tokens--; ) {
|
||||||
opt.value.push_back(other_tokens[0]);
|
opt.value.push_back(other_tokens[0]);
|
||||||
|
opt.original_tokens.push_back(other_tokens[0]);
|
||||||
other_tokens.erase(other_tokens.begin());
|
other_tokens.erase(other_tokens.begin());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -368,6 +370,7 @@ namespace boost { namespace program_options { namespace detail {
|
|||||||
opt.string_key = name;
|
opt.string_key = name;
|
||||||
if (!adjacent.empty())
|
if (!adjacent.empty())
|
||||||
opt.value.push_back(adjacent);
|
opt.value.push_back(adjacent);
|
||||||
|
opt.original_tokens.push_back(tok);
|
||||||
result.push_back(opt);
|
result.push_back(opt);
|
||||||
args.erase(args.begin());
|
args.erase(args.begin());
|
||||||
}
|
}
|
||||||
@@ -416,6 +419,7 @@ namespace boost { namespace program_options { namespace detail {
|
|||||||
|
|
||||||
option opt;
|
option opt;
|
||||||
opt.string_key = name;
|
opt.string_key = name;
|
||||||
|
opt.original_tokens.push_back(tok);
|
||||||
if (!adjacent.empty())
|
if (!adjacent.empty())
|
||||||
opt.value.push_back(adjacent);
|
opt.value.push_back(adjacent);
|
||||||
result.push_back(opt);
|
result.push_back(opt);
|
||||||
@@ -442,6 +446,7 @@ namespace boost { namespace program_options { namespace detail {
|
|||||||
opt.string_key = name;
|
opt.string_key = name;
|
||||||
if (!adjacent.empty())
|
if (!adjacent.empty())
|
||||||
opt.value.push_back(adjacent);
|
opt.value.push_back(adjacent);
|
||||||
|
opt.original_tokens.push_back(tok);
|
||||||
result.push_back(opt);
|
result.push_back(opt);
|
||||||
args.erase(args.begin());
|
args.erase(args.begin());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -190,6 +190,38 @@ void test_environment()
|
|||||||
|
|
||||||
//TODO: since 'bar' does not allow a value, it cannot appear in environemt,
|
//TODO: since 'bar' does not allow a value, it cannot appear in environemt,
|
||||||
// which already has a value.
|
// which already has a value.
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_unregistered()
|
||||||
|
{
|
||||||
|
options_description desc;
|
||||||
|
|
||||||
|
char* cmdline1_[] = { "--foo=12", "--bar", "1"};
|
||||||
|
vector<string> cmdline1 = sv(cmdline1_,
|
||||||
|
sizeof(cmdline1_)/sizeof(cmdline1_[0]));
|
||||||
|
vector<option> a1 =
|
||||||
|
command_line_parser(cmdline1).options(desc).allow_unregistered().run()
|
||||||
|
.options;
|
||||||
|
|
||||||
|
BOOST_REQUIRE(a1.size() == 3);
|
||||||
|
BOOST_CHECK(a1[0].string_key == "foo");
|
||||||
|
BOOST_CHECK(a1[0].unregistered == true);
|
||||||
|
BOOST_REQUIRE(a1[0].value.size() == 1);
|
||||||
|
BOOST_CHECK(a1[0].value[0] == "12");
|
||||||
|
BOOST_CHECK(a1[1].string_key == "bar");
|
||||||
|
BOOST_CHECK(a1[1].unregistered == true);
|
||||||
|
BOOST_CHECK(a1[2].string_key == "");
|
||||||
|
BOOST_CHECK(a1[2].unregistered == false);
|
||||||
|
|
||||||
|
|
||||||
|
vector<string> a2 = collect_unrecognized(a1, include_positional);
|
||||||
|
BOOST_CHECK(a2[0] == "--foo=12");
|
||||||
|
BOOST_CHECK(a2[1] == "--bar");
|
||||||
|
BOOST_CHECK(a2[2] == "1");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int test_main(int, char* [])
|
int test_main(int, char* [])
|
||||||
@@ -197,6 +229,7 @@ int test_main(int, char* [])
|
|||||||
test_command_line();
|
test_command_line();
|
||||||
test_config_file();
|
test_config_file();
|
||||||
test_environment();
|
test_environment();
|
||||||
|
test_unregistered();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user