Skip to content

Commit b2a01d9

Browse files
committed
Full merge from trunk at revision 41356 of entire boost-root tree.
[SVN r41370]
1 parent 2d0c627 commit b2a01d9

22 files changed

+222
-96
lines changed

build/Jamfile.v2

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,4 @@ lib boost_program_options
1717
<link>shared:<define>BOOST_PROGRAM_OPTIONS_DYN_LINK=1 # tell source we're building dll's
1818
;
1919

20-
install dist-lib
21-
:
22-
boost_program_options
23-
:
24-
<install-type>LIB
25-
<location>../../../dist/lib
26-
;
27-
28-
explicit dist-lib ;
20+
boost-install boost_program_options ;

doc/Jamfile.v2

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22
import toolset ;
33
toolset.using doxygen ;
44

5-
boostbook program_option : program_options.xml ;
5+
boostbook program_option
6+
: program_options.xml
7+
: <implicit-dependency>autodoc
8+
;
69

710
doxygen autodoc
811
: [ glob ../../../boost/program_options/*.hpp ] ;

doc/howto.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -412,7 +412,7 @@ $ export LC_CTYPE=ru_RU.KOI8-R
412412
method of that class:
413413
<programlisting>
414414
parsed_options parsed =
415-
command_line_parser(argv, argc).options(desc).allow_unregistered().run();
415+
command_line_parser(argc, argv).options(desc).allow_unregistered().run();
416416
</programlisting>
417417

418418
For each token that looks like an option, but does not have a known name,
@@ -427,7 +427,7 @@ parsed_options parsed =
427427
The function will collect original tokens for all unrecognized values, and optionally, all found positional options.
428428
Say, if your code handles a few options, but does not handles positional options at all, you can use the function like this:
429429
<programlisting>
430-
vector&lt;string&gt; to_pass_further = collect_arguments(parsed.option, include_positional);
430+
vector&lt;string&gt; to_pass_further = collect_unrecognized(parsed.options, include_positional);
431431
</programlisting>
432432

433433
</para>

doc/overview.xml

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ options_description desc;
181181
desc.add_options()
182182
("help", "produce help message")
183183
("compression", value&lt;string&gt;(), "compression level")
184-
("verbose", value&lt;string&gt;()->zero_token(), "verbosity level")
184+
("verbose", value&lt;string&gt;()->zero_tokens(), "verbosity level")
185185
("email", value&lt;string&gt;()->multitoken(), "email to send to")
186186
;
187187
</programlisting>
@@ -478,7 +478,45 @@ notify(vm);
478478
<title>Specific parsers</title>
479479

480480
<section>
481-
<title>Environment variables</title>
481+
<title>Configuration file parser</title>
482+
483+
<para>The &parse_config_file; function implements parsing
484+
of simple INI-like configuration files. Configuration file
485+
syntax is line based:
486+
</para>
487+
<itemizedlist>
488+
<listitem><para>A line in the form:</para>
489+
<screen>
490+
<replaceable>name</replaceable>=<replaceable>value</replaceable>
491+
</screen>
492+
<para>gives a value to an option.</para>
493+
</listitem>
494+
<listitem><para>A line in the form:</para>
495+
<screen>
496+
[<replaceable>section name</replaceable>]
497+
</screen>
498+
<para>introduces a new section in the configuration file.</para>
499+
</listitem>
500+
<listitem><para>The <literal>#</literal> character introduces a
501+
comment that spans until the end of the line.</para>
502+
</listitem>
503+
</itemizedlist>
504+
505+
<para>The option names are relative to the section names, so
506+
the following configuration file part:</para>
507+
<screen>
508+
[gui.accessibility]
509+
visual_bell=yes
510+
</screen>
511+
<para>is equivalent to</para>
512+
<screen>
513+
gui.accessibility.visual_bell=yes
514+
</screen>
515+
516+
</section>
517+
518+
<section>
519+
<title>Environment variables parser</title>
482520

483521
<para><firstterm>Environment variables</firstterm> are string variables
484522
which are available to all programs via the <code>getenv</code> function

doc/program_options.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,5 +83,5 @@
8383
<xi:include href="design.xml"/>
8484
<xi:include href="acknowledgements.xml"/>
8585

86-
<xi:include href="autodoc.boostbook"/>
86+
<xi:include href="autodoc.xml"/>
8787
</library>

doc/todo.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11

2+
Say that variables_map is actually derived from std::map.
3+
24
Make parse_config_file("foo.cfg", desc) work.
35

46
Document handling of positional options which depends on precedding options.

example/options_description.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,17 @@ int main(int ac, char* av[])
2626
{
2727
try {
2828
int opt;
29+
int portnum;
2930
po::options_description desc("Allowed options");
3031
desc.add_options()
3132
("help", "produce help message")
3233
("optimization", po::value<int>(&opt)->default_value(10),
3334
"optimization level")
35+
("verbose,v", po::value<int>()->implicit_value(1),
36+
"enable verbosity (optionally specify level)")
37+
("listen,l", po::value<int>(&portnum)->implicit_value(1001)
38+
->default_value(0,"no"),
39+
"listen on a port.")
3440
("include-path,I", po::value< vector<string> >(),
3541
"include path")
3642
("input-file", po::value< vector<string> >(), "input file")
@@ -62,7 +68,14 @@ int main(int ac, char* av[])
6268
<< vm["input-file"].as< vector<string> >() << "\n";
6369
}
6470

71+
if (vm.count("verbose")) {
72+
cout << "Verbosity enabled. Level is " << vm["verbose"].as<int>()
73+
<< "\n";
74+
}
75+
6576
cout << "Optimization level is " << opt << "\n";
77+
78+
cout << "Listen port is " << portnum << "\n";
6679
}
6780
catch(exception& e)
6881
{

src/cmdline.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -290,8 +290,8 @@ namespace boost { namespace program_options { namespace detail {
290290

291291
// First check that the option is valid, and get its description.
292292
// TODO: case-sensitivity.
293-
const option_description* xd =
294-
m_desc->find_nothrow(opt.string_key, (m_style & allow_guessing));
293+
const option_description* xd = m_desc->find_nothrow(opt.string_key,
294+
(m_style & allow_guessing) ? true : false);
295295

296296
if (!xd)
297297
{
@@ -329,6 +329,14 @@ namespace boost { namespace program_options { namespace detail {
329329

330330
max_tokens -= opt.value.size();
331331

332+
// A value is optional if min_tokens == 0, but max_tokens > 0.
333+
// If a value is optional, it must appear in opt.value (because
334+
// it was 'adjacent'. Otherwise, remove the expectation of a
335+
// non-adjacent value. (For now, we just check max_tokens == 1,
336+
// as there is no current support for max_tokens>1)
337+
if (min_tokens == 0 && max_tokens == 1 && opt.value.empty())
338+
--max_tokens;
339+
332340
// Everything's OK, move the values to the result.
333341
for(;!other_tokens.empty() && max_tokens--; ) {
334342
opt.value.push_back(other_tokens[0]);
@@ -462,7 +470,8 @@ namespace boost { namespace program_options { namespace detail {
462470
((m_style & allow_slash_for_short) && tok[0] == '/')))
463471
{
464472
if (m_desc->find_nothrow(tok.substr(1, tok.find('=')-1),
465-
m_style & allow_guessing)) {
473+
(m_style & allow_guessing) ? true : false))
474+
{
466475
args[0].insert(0, "-");
467476
if (args[0][1] == '/')
468477
args[0][1] = '-';

src/config_file.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@ namespace boost { namespace program_options { namespace detail {
2121
using namespace std;
2222

2323
common_config_file_iterator::common_config_file_iterator(
24-
const std::set<std::string>& allowed_options)
25-
: allowed_options(allowed_options)
24+
const std::set<std::string>& allowed_options,
25+
bool allow_unregistered)
26+
: allowed_options(allowed_options),
27+
m_allow_unregistered(allow_unregistered)
2628
{
2729
for(std::set<std::string>::const_iterator i = allowed_options.begin();
2830
i != allowed_options.end();
@@ -100,7 +102,8 @@ namespace boost { namespace program_options { namespace detail {
100102
string name = m_prefix + trim_ws(s.substr(0, n));
101103
string value = trim_ws(s.substr(n+1));
102104

103-
if (!allowed_option(name))
105+
bool registered = allowed_option(name);
106+
if (!registered && !m_allow_unregistered)
104107
boost::throw_exception(unknown_option(name));
105108

106109
if (value.empty())
@@ -110,6 +113,7 @@ namespace boost { namespace program_options { namespace detail {
110113
this->value().string_key = name;
111114
this->value().value.clear();
112115
this->value().value.push_back(value);
116+
this->value().unregistered = !registered;
113117
break;
114118

115119
} else {

src/options_description.cpp

Lines changed: 18 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,8 @@ namespace boost { namespace program_options {
201201
return *this;
202202
}
203203

204+
const unsigned options_description::m_default_line_length = 80;
205+
204206
options_description::options_description(unsigned line_length)
205207
: m_line_length(line_length)
206208
{}
@@ -252,11 +254,12 @@ namespace boost { namespace program_options {
252254
return m_options;
253255
}
254256

255-
const option_description*
257+
const option_description*
256258
options_description::find_nothrow(const std::string& name,
257259
bool approx) const
258260
{
259-
int found = -1;
261+
shared_ptr<option_description> found;
262+
vector<string> approximate_matches;
260263
// We use linear search because matching specified option
261264
// name with the declared option name need to take care about
262265
// case sensitivity and trailing '*' and so we can't use simple map.
@@ -276,31 +279,22 @@ namespace boost { namespace program_options {
276279
//
277280
// For now, we don't check the situation when there are
278281
// two full matches.
279-
282+
280283
if (r == option_description::full_match)
281284
{
282-
return m_options[i].get();
285+
return m_options[i].get();
283286
}
284287

285-
if (found != -1)
286-
{
287-
vector<string> alts;
288-
// FIXME: the use of 'key' here might not
289-
// be the best approach.
290-
alts.push_back(m_options[found]->key(name));
291-
alts.push_back(m_options[i]->key(name));
292-
boost::throw_exception(ambiguous_option(name, alts));
293-
}
294-
else
295-
{
296-
found = i;
297-
}
298-
}
299-
if (found != -1) {
300-
return m_options[found].get();
301-
} else {
302-
return 0;
288+
found = m_options[i];
289+
// FIXME: the use of 'key' here might not
290+
// be the best approach.
291+
approximate_matches.push_back(m_options[i]->key(name));
303292
}
293+
if (approximate_matches.size() > 1)
294+
boost::throw_exception(
295+
ambiguous_option(name, approximate_matches));
296+
297+
return found.get();
304298
}
305299

306300
BOOST_PROGRAM_OPTIONS_DECL
@@ -412,9 +406,9 @@ namespace boost { namespace program_options {
412406

413407
if (last_space != line_begin)
414408
{
415-
// is last_space within the second half of the
409+
// is last_space within the second half ot the
416410
// current line
417-
if ((unsigned)std::distance(last_space, line_end) <
411+
if ((unsigned)distance(last_space, line_end) <
418412
(line_length - indent) / 2)
419413
{
420414
line_end = last_space;

0 commit comments

Comments
 (0)