mirror of
https://github.com/boostorg/program_options.git
synced 2026-01-20 04:42:24 +00:00
Compare commits
47 Commits
svn-branch
...
boost-1.41
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eb768cb326 | ||
|
|
5820ee9f7f | ||
|
|
67ba23b8d9 | ||
|
|
c3cb7cf05d | ||
|
|
bdbd3dfc42 | ||
|
|
15c990b7af | ||
|
|
1a884cef74 | ||
|
|
3c6401b19a | ||
|
|
ed4847e0a7 | ||
|
|
6eef67f5ba | ||
|
|
91d9cabb51 | ||
|
|
22e8d11888 | ||
|
|
b55001a061 | ||
|
|
2a16575f98 | ||
|
|
f14a369077 | ||
|
|
9df5124fed | ||
|
|
86487c7b63 | ||
|
|
6cd68a2fd9 | ||
|
|
f0eae2ccfe | ||
|
|
b2a01d9405 | ||
|
|
2d0c627d34 | ||
|
|
2cc29f6dfa | ||
|
|
198b29d107 | ||
|
|
f407b6ce47 | ||
|
|
87938cfa8e | ||
|
|
9a73a1c412 | ||
|
|
37143a449d | ||
|
|
2e0e9fd30b | ||
|
|
1bd588d677 | ||
|
|
d83e0dea37 | ||
|
|
54daca4c09 | ||
|
|
f4eac99310 | ||
|
|
a367a1b021 | ||
|
|
720d0455dd | ||
|
|
aad1a60172 | ||
|
|
1e4d1dee3d | ||
|
|
e718d0a8a5 | ||
|
|
ab30ec28eb | ||
|
|
682f1b7670 | ||
|
|
43577d0ca8 | ||
|
|
d05b400b13 | ||
|
|
4863727509 | ||
|
|
7d90a1b1b2 | ||
|
|
ac9830625b | ||
|
|
252a3f9ebd | ||
|
|
b1dc87da3c | ||
|
|
1fbf955272 |
@@ -17,12 +17,4 @@ lib boost_program_options
|
||||
<link>shared:<define>BOOST_PROGRAM_OPTIONS_DYN_LINK=1 # tell source we're building dll's
|
||||
;
|
||||
|
||||
install dist-lib
|
||||
:
|
||||
boost_program_options
|
||||
:
|
||||
<install-type>LIB
|
||||
<location>../../../dist/lib
|
||||
;
|
||||
|
||||
explicit dist-lib ;
|
||||
boost-install boost_program_options ;
|
||||
@@ -5,6 +5,7 @@ toolset.using doxygen ;
|
||||
boostbook program_option
|
||||
: program_options.xml
|
||||
: <implicit-dependency>autodoc
|
||||
<format>pdf:<xsl:param>boost.url.prefix=http://www.boost.org/doc/libs/release/doc/html
|
||||
;
|
||||
|
||||
doxygen autodoc
|
||||
|
||||
@@ -77,7 +77,7 @@ int main(int ac, char* av[])
|
||||
|
||||
cout << "Listen port is " << portnum << "\n";
|
||||
}
|
||||
catch(exception& e)
|
||||
catch(std::exception& e)
|
||||
{
|
||||
cout << e.what() << "\n";
|
||||
return 1;
|
||||
|
||||
@@ -94,7 +94,7 @@ int main(int ac, char* av[])
|
||||
<< vm["magic"].as<magic_number>().n << "\"\n";
|
||||
}
|
||||
}
|
||||
catch(exception& e)
|
||||
catch(std::exception& e)
|
||||
{
|
||||
cout << e.what() << "\n";
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See www.boost.org/libs/program_options for documentation.
|
||||
|
||||
#ifndef PROGRAM_OPTIONS_VP_2003_05_19
|
||||
#define PROGRAM_OPTIONS_VP_2003_05_19
|
||||
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
|
||||
#include <boost/program_options/detail/convert.hpp>
|
||||
|
||||
#include <iterator>
|
||||
|
||||
namespace boost { namespace program_options {
|
||||
|
||||
namespace detail {
|
||||
@@ -38,7 +40,7 @@ namespace boost { namespace program_options {
|
||||
: 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, charT**>(argv+1, argv+argc)))
|
||||
to_internal(detail::make_vector<charT, charT**>(argv+1, argv+argc+!argc)))
|
||||
{}
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright © 2001 Ronald Garcia, Indiana University (garcia@osl.iu.edu)
|
||||
// Copyright (c) 2001 Ronald Garcia, Indiana University (garcia@osl.iu.edu)
|
||||
// Andrew Lumsdaine, Indiana University (lums@osl.iu.edu). Permission to copy,
|
||||
// use, modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided "as is"
|
||||
|
||||
@@ -55,13 +55,12 @@ namespace boost { namespace program_options {
|
||||
{
|
||||
static std::basic_string<charT> empty;
|
||||
if (v.size() > 1)
|
||||
throw validation_error("multiple values not allowed");
|
||||
if (v.size() == 1)
|
||||
boost::throw_exception(validation_error("multiple values not allowed"));
|
||||
else if (v.size() == 1)
|
||||
return v.front();
|
||||
else if (allow_empty)
|
||||
return empty;
|
||||
else
|
||||
throw validation_error("at least one value required");
|
||||
else if (!allow_empty)
|
||||
boost::throw_exception(validation_error("at least one value required"));
|
||||
return empty;
|
||||
}
|
||||
|
||||
/* Throws multiple_occurrences if 'value' is not empty. */
|
||||
|
||||
@@ -41,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;
|
||||
|
||||
|
||||
121
src/cmdline.cpp
121
src/cmdline.cpp
@@ -23,6 +23,7 @@
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <cctype>
|
||||
#include <climits>
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
@@ -98,10 +99,10 @@ namespace boost { namespace program_options { namespace detail {
|
||||
{
|
||||
#if defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)
|
||||
vector<string> args;
|
||||
copy(argv+1, argv+argc, inserter(args, args.end()));
|
||||
copy(argv+1, argv+argc+!argc, inserter(args, args.end()));
|
||||
init(args);
|
||||
#else
|
||||
init(vector<string>(argv+1, argv+argc));
|
||||
init(vector<string>(argv+1, argv+argc+!argc));
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -151,7 +152,7 @@ namespace boost { namespace program_options { namespace detail {
|
||||
error = "style disallows all characters for short options";
|
||||
|
||||
if (error)
|
||||
throw invalid_command_line_style(error);
|
||||
boost::throw_exception(invalid_command_line_style(error));
|
||||
|
||||
// Need to check that if guessing and long disguise are enabled
|
||||
// -f will mean the same as -foo
|
||||
@@ -195,24 +196,24 @@ namespace boost { namespace program_options { namespace detail {
|
||||
|
||||
if (m_additional_parser)
|
||||
style_parsers.push_back(
|
||||
bind(&cmdline::handle_additional_parser, this, _1));
|
||||
boost::bind(&cmdline::handle_additional_parser, this, _1));
|
||||
|
||||
if (m_style & allow_long)
|
||||
style_parsers.push_back(
|
||||
bind(&cmdline::parse_long_option, this, _1));
|
||||
boost::bind(&cmdline::parse_long_option, this, _1));
|
||||
|
||||
if ((m_style & allow_long_disguise))
|
||||
style_parsers.push_back(
|
||||
bind(&cmdline::parse_disguised_long_option, this, _1));
|
||||
boost::bind(&cmdline::parse_disguised_long_option, this, _1));
|
||||
|
||||
if ((m_style & allow_short) && (m_style & allow_dash_for_short))
|
||||
style_parsers.push_back(
|
||||
bind(&cmdline::parse_short_option, this, _1));
|
||||
boost::bind(&cmdline::parse_short_option, this, _1));
|
||||
|
||||
if ((m_style & allow_short) && (m_style & allow_slash_for_short))
|
||||
style_parsers.push_back(bind(&cmdline::parse_dos_option, this, _1));
|
||||
style_parsers.push_back(boost::bind(&cmdline::parse_dos_option, this, _1));
|
||||
|
||||
style_parsers.push_back(bind(&cmdline::parse_terminator, this, _1));
|
||||
style_parsers.push_back(boost::bind(&cmdline::parse_terminator, this, _1));
|
||||
|
||||
vector<option> result;
|
||||
while(!args.empty())
|
||||
@@ -254,6 +255,62 @@ 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,
|
||||
(m_style & allow_guessing));
|
||||
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) {
|
||||
@@ -269,8 +326,8 @@ namespace boost { namespace program_options { namespace detail {
|
||||
if (opt.position_key != -1) {
|
||||
if (position >= m_positional->max_total_count())
|
||||
{
|
||||
throw too_many_positional_options_error(
|
||||
"too many positional options");
|
||||
boost::throw_exception(too_many_positional_options_error(
|
||||
"too many positional options"));
|
||||
}
|
||||
opt.string_key = m_positional->name_for_position(position);
|
||||
++position;
|
||||
@@ -290,8 +347,8 @@ namespace boost { namespace program_options { namespace detail {
|
||||
|
||||
// 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, (m_style & allow_guessing));
|
||||
const option_description* xd = m_desc->find_nothrow(opt.string_key,
|
||||
(m_style & allow_guessing) ? true : false);
|
||||
|
||||
if (!xd)
|
||||
{
|
||||
@@ -323,22 +380,25 @@ namespace boost { namespace program_options { namespace detail {
|
||||
if (present_tokens >= min_tokens)
|
||||
{
|
||||
if (!opt.value.empty() && max_tokens == 0) {
|
||||
throw invalid_command_line_syntax(opt.string_key,
|
||||
invalid_command_line_syntax::extra_parameter);
|
||||
boost::throw_exception(invalid_command_line_syntax(opt.string_key,
|
||||
invalid_command_line_syntax::extra_parameter));
|
||||
}
|
||||
|
||||
max_tokens -= opt.value.size();
|
||||
// If an option wants, at minimum, N tokens, we grab them
|
||||
// there and don't care if they look syntactically like an
|
||||
// option.
|
||||
|
||||
// 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;
|
||||
if (opt.value.size() <= min_tokens)
|
||||
{
|
||||
min_tokens -= opt.value.size();
|
||||
}
|
||||
else
|
||||
{
|
||||
min_tokens = 0;
|
||||
}
|
||||
|
||||
// Everything's OK, move the values to the result.
|
||||
for(;!other_tokens.empty() && max_tokens--; ) {
|
||||
for(;!other_tokens.empty() && min_tokens--; ) {
|
||||
opt.value.push_back(other_tokens[0]);
|
||||
opt.original_tokens.push_back(other_tokens[0]);
|
||||
other_tokens.erase(other_tokens.begin());
|
||||
@@ -346,8 +406,8 @@ namespace boost { namespace program_options { namespace detail {
|
||||
}
|
||||
else
|
||||
{
|
||||
throw invalid_command_line_syntax(opt.string_key,
|
||||
invalid_command_line_syntax::missing_parameter);
|
||||
boost::throw_exception(invalid_command_line_syntax(opt.string_key,
|
||||
invalid_command_line_syntax::missing_parameter));
|
||||
|
||||
}
|
||||
}
|
||||
@@ -367,8 +427,8 @@ namespace boost { namespace program_options { namespace detail {
|
||||
name = tok.substr(2, p-2);
|
||||
adjacent = tok.substr(p+1);
|
||||
if (adjacent.empty())
|
||||
throw invalid_command_line_syntax(name,
|
||||
invalid_command_line_syntax::empty_adjacent_parameter);
|
||||
boost::throw_exception( invalid_command_line_syntax(name,
|
||||
invalid_command_line_syntax::empty_adjacent_parameter));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -470,7 +530,8 @@ namespace boost { namespace program_options { namespace detail {
|
||||
((m_style & allow_slash_for_short) && tok[0] == '/')))
|
||||
{
|
||||
if (m_desc->find_nothrow(tok.substr(1, tok.find('=')-1),
|
||||
m_style & allow_guessing)) {
|
||||
(m_style & allow_guessing) ? true : false))
|
||||
{
|
||||
args[0].insert(0, "-");
|
||||
if (args[0][1] == '/')
|
||||
args[0][1] = '-';
|
||||
@@ -491,6 +552,8 @@ namespace boost { namespace program_options { namespace detail {
|
||||
{
|
||||
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();
|
||||
|
||||
@@ -408,7 +408,7 @@ namespace boost { namespace program_options {
|
||||
{
|
||||
// is last_space within the second half ot the
|
||||
// current line
|
||||
if (unsigned(distance(last_space, line_end)) <
|
||||
if ((unsigned)distance(last_space, line_end) <
|
||||
(line_length - indent) / 2)
|
||||
{
|
||||
line_end = last_space;
|
||||
|
||||
@@ -67,10 +67,16 @@ 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),
|
||||
bind(from_utf8, _1));
|
||||
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));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,11 +74,13 @@ 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;
|
||||
}
|
||||
#endif
|
||||
v.m_value_semantic = d.semantic();
|
||||
|
||||
// The option is not composing, and the value is explicitly
|
||||
@@ -133,7 +135,16 @@ namespace boost { namespace program_options {
|
||||
k != vm.end();
|
||||
++k)
|
||||
{
|
||||
k->second.m_value_semantic->notify(k->second.value());
|
||||
/* 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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
project
|
||||
: requirements
|
||||
<library>../build//boost_program_options
|
||||
<library>/boost/test//boost_test_exec_monitor/<link>static
|
||||
<link>static
|
||||
<variant>debug
|
||||
|
||||
# <define>_GLIBCXX_CONCEPT_CHECKS
|
||||
# <define>_GLIBCXX_DEBUG
|
||||
|
||||
@@ -9,15 +9,14 @@
|
||||
using namespace boost::program_options;
|
||||
using boost::program_options::detail::cmdline;
|
||||
|
||||
|
||||
#include <boost/test/test_tools.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <cassert>
|
||||
using namespace std;
|
||||
|
||||
#include "minitest.hpp"
|
||||
|
||||
/* To facilitate testing, declare a number of error codes. Otherwise,
|
||||
we'd have to specify the type of exception that should be thrown.
|
||||
*/
|
||||
@@ -600,7 +599,7 @@ void test_unregistered()
|
||||
// It's not clear yet, so I'm leaving the decision till later.
|
||||
}
|
||||
|
||||
int test_main(int ac, char* av[])
|
||||
int main(int ac, char* av[])
|
||||
{
|
||||
test_long_options();
|
||||
test_short_options();
|
||||
|
||||
25
test/minitest.hpp
Normal file
25
test/minitest.hpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#ifndef BOOST_PROGRAM_OPTIONS_MINITEST
|
||||
#define BOOST_PROGRAM_OPTIONS_MINITEST
|
||||
|
||||
#include <assert.h>
|
||||
#include <iostream>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define BOOST_REQUIRE(b) assert(b)
|
||||
#define BOOST_CHECK(b) assert(b)
|
||||
#define BOOST_CHECK_EQUAL(a, b) assert(a == b)
|
||||
#define BOOST_ERROR(description) std::cerr << description; std::cerr << "\n"; abort();
|
||||
#define BOOST_CHECK_THROW(expression, exception) \
|
||||
try \
|
||||
{ \
|
||||
expression; \
|
||||
BOOST_ERROR("expected exception not thrown");\
|
||||
throw 10; \
|
||||
} \
|
||||
catch(exception &) \
|
||||
{ \
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
@@ -10,14 +10,13 @@ using namespace boost::program_options;
|
||||
#include <boost/function.hpp>
|
||||
using namespace boost;
|
||||
|
||||
#define BOOST_INCLUDE_MAIN // for testing, include rather than link
|
||||
#include <boost/test/test_tools.hpp>
|
||||
|
||||
#include <utility>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
using namespace std;
|
||||
|
||||
#include "minitest.hpp"
|
||||
|
||||
void test_type()
|
||||
{
|
||||
options_description desc;
|
||||
@@ -77,7 +76,7 @@ void test_formatting()
|
||||
ss << desc;
|
||||
}
|
||||
|
||||
int test_main(int, char* [])
|
||||
int main(int, char* [])
|
||||
{
|
||||
test_type();
|
||||
test_approximation();
|
||||
|
||||
@@ -14,9 +14,6 @@ namespace po = boost::program_options;
|
||||
#include <boost/function.hpp>
|
||||
using namespace boost;
|
||||
|
||||
#define BOOST_INCLUDE_MAIN // for testing, include rather than link
|
||||
#include <boost/test/test_tools.hpp>
|
||||
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
@@ -27,6 +24,8 @@ using namespace std;
|
||||
#include <cstdlib> // for putenv
|
||||
#endif
|
||||
|
||||
#include "minitest.hpp"
|
||||
|
||||
#define TEST_CHECK_THROW(expression, exception, description) \
|
||||
try \
|
||||
{ \
|
||||
@@ -147,8 +146,52 @@ void test_command_line()
|
||||
variables_map vm;
|
||||
po::store(po::parse_command_line(3, cmdline4, desc2), vm);
|
||||
|
||||
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(7, 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::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 );
|
||||
|
||||
char* cmdline6[] = {"", "-m", "token1", "token2", "--", "some_file"};
|
||||
vector<option> a6 =
|
||||
command_line_parser(6, 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()
|
||||
@@ -259,7 +302,7 @@ void test_unregistered()
|
||||
check_value(a3[1], "m1.v1", "1");
|
||||
}
|
||||
|
||||
int test_main(int, char* [])
|
||||
int main(int, char* [])
|
||||
{
|
||||
test_command_line();
|
||||
test_config_file();
|
||||
|
||||
@@ -12,7 +12,8 @@ namespace po = boost::program_options;
|
||||
|
||||
|
||||
#include <boost/limits.hpp>
|
||||
#include <boost/test/test_tools.hpp>
|
||||
|
||||
#include "minitest.hpp"
|
||||
|
||||
#include <vector>
|
||||
using namespace std;
|
||||
@@ -81,7 +82,7 @@ void test_parsing()
|
||||
too_many_positional_options_error);
|
||||
}
|
||||
|
||||
int test_main(int, char* [])
|
||||
int main(int, char* [])
|
||||
{
|
||||
test_positional_options();
|
||||
test_parsing();
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#include <boost/program_options/detail/convert.hpp>
|
||||
#include <boost/program_options/detail/utf8_codecvt_facet.hpp>
|
||||
|
||||
#include <boost/test/test_tools.hpp>
|
||||
#include "minitest.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -121,7 +121,7 @@ void test_convert(const std::string& input,
|
||||
BOOST_CHECK(ref == input);
|
||||
}
|
||||
|
||||
int test_main(int ac, char* av[])
|
||||
int main(int ac, char* av[])
|
||||
{
|
||||
std::string input = file_content("utf8.txt");
|
||||
std::string expected = file_content("ucs2.txt");
|
||||
|
||||
@@ -15,12 +15,11 @@ namespace po = boost::program_options;
|
||||
#include <boost/function.hpp>
|
||||
using namespace boost;
|
||||
|
||||
#define BOOST_INCLUDE_MAIN // for testing, include rather than link
|
||||
#include <boost/test/test_tools.hpp>
|
||||
|
||||
#include <sstream>
|
||||
using namespace std;
|
||||
|
||||
#include "minitest.hpp"
|
||||
|
||||
// Test that unicode input is forwarded to unicode option without
|
||||
// problems.
|
||||
void test_unicode_to_unicode()
|
||||
@@ -35,9 +34,13 @@ void test_unicode_to_unicode()
|
||||
args.push_back(L"--foo=\x044F");
|
||||
|
||||
variables_map vm;
|
||||
store(wcommand_line_parser(args).options(desc).run(), vm);
|
||||
basic_parsed_options<wchar_t> parsed =
|
||||
wcommand_line_parser(args).options(desc).run();
|
||||
store(parsed, vm);
|
||||
|
||||
BOOST_CHECK(vm["foo"].as<wstring>() == L"\x044F");
|
||||
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");
|
||||
}
|
||||
|
||||
// Test that unicode input is property converted into
|
||||
@@ -149,7 +152,7 @@ void test_config_file()
|
||||
BOOST_CHECK(vm["foo"].as<string>() == "\xD1\x8F");
|
||||
}
|
||||
|
||||
int test_main(int, char* [])
|
||||
int main(int, char* [])
|
||||
{
|
||||
test_unicode_to_unicode();
|
||||
test_unicode_to_native();
|
||||
|
||||
@@ -15,22 +15,10 @@ namespace po = boost::program_options;
|
||||
#include <boost/function.hpp>
|
||||
using namespace boost;
|
||||
|
||||
#define BOOST_INCLUDE_MAIN // for testing, include rather than link
|
||||
#include <boost/test/test_tools.hpp>
|
||||
|
||||
#include <sstream>
|
||||
using namespace std;
|
||||
|
||||
#define TEST_CHECK_THROW(expression, exception, description) \
|
||||
try \
|
||||
{ \
|
||||
expression; \
|
||||
BOOST_ERROR(description);\
|
||||
throw 10; \
|
||||
} \
|
||||
catch(exception &) \
|
||||
{ \
|
||||
}
|
||||
#include "minitest.hpp"
|
||||
|
||||
vector<string> sv(char* array[], unsigned size)
|
||||
{
|
||||
@@ -108,8 +96,11 @@ 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>())
|
||||
;
|
||||
char* cmdline6_[] = { "--imp=1", "-m" };
|
||||
/* The -m option is implicit. It does not have value in inside the token,
|
||||
and we should not grab the next token. */
|
||||
char* cmdline6_[] = { "--imp=1", "-m", "--foo=1" };
|
||||
vector<string> cmdline6 = sv(cmdline6_,
|
||||
sizeof(cmdline6_)/sizeof(cmdline6_[0]));
|
||||
parsed_options a6 = command_line_parser(cmdline6).options(desc3).run();
|
||||
@@ -117,7 +108,7 @@ void test_variable_map()
|
||||
variables_map vm4;
|
||||
store(a6, vm4);
|
||||
notify(vm4);
|
||||
BOOST_REQUIRE(vm4.size() == 3);
|
||||
BOOST_REQUIRE(vm4.size() == 4);
|
||||
BOOST_CHECK(vm4["imp"].as<int>() == 1);
|
||||
BOOST_CHECK(vm4["iim"].as<int>() == 201);
|
||||
BOOST_CHECK(vm4["mmp"].as<int>() == 123);
|
||||
@@ -288,7 +279,7 @@ void test_multiple_assignments_with_different_option_description()
|
||||
|
||||
}
|
||||
|
||||
int test_main(int, char* [])
|
||||
int main(int, char* [])
|
||||
{
|
||||
test_variable_map();
|
||||
test_semantic_values();
|
||||
|
||||
@@ -7,26 +7,42 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <cctype>
|
||||
#include <iostream>
|
||||
#include <stdlib.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include <boost/program_options/parsers.hpp>
|
||||
using namespace boost::program_options;
|
||||
|
||||
#include <boost/test/test_tools.hpp>
|
||||
void check_equal(const std::vector<string>& actual, char **expected, int n)
|
||||
{
|
||||
if (actual.size() != n)
|
||||
{
|
||||
std::cerr << "Size mismatch between expected and actual data\n";
|
||||
abort();
|
||||
}
|
||||
for (int i = 0; i < n; ++i)
|
||||
{
|
||||
if (actual[i] != expected[i])
|
||||
{
|
||||
std::cerr << "Unexpected content\n";
|
||||
abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
|
||||
void test_winmain()
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
#define C ,
|
||||
#define TEST(input, expected) \
|
||||
char* BOOST_PP_CAT(e, __LINE__)[] = expected;\
|
||||
vector<string> BOOST_PP_CAT(v, __LINE__) = split_winmain(input);\
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS(BOOST_PP_CAT(v, __LINE__).begin(),\
|
||||
BOOST_PP_CAT(v, __LINE__).end(),\
|
||||
BOOST_PP_CAT(e, __LINE__),\
|
||||
BOOST_PP_CAT(e, __LINE__) + \
|
||||
sizeof(BOOST_PP_CAT(e, __LINE__))/sizeof(char*));
|
||||
check_equal(BOOST_PP_CAT(v, __LINE__), BOOST_PP_CAT(e, __LINE__),\
|
||||
sizeof(BOOST_PP_CAT(e, __LINE__))/sizeof(char*));
|
||||
|
||||
// The following expectations were obtained in Win2000 shell:
|
||||
TEST("1 ", {"1"});
|
||||
@@ -45,13 +61,13 @@ void test_winmain()
|
||||
TEST("1\\\\1 ", {"1\\\\1"});
|
||||
}
|
||||
|
||||
int test_main(int, char*[])
|
||||
int main(int, char*[])
|
||||
{
|
||||
test_winmain();
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
int test_main(int, char*[])
|
||||
int main(int, char*[])
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user