Added a group name feature to the command line parser. Now it is possible to

make print_options() print related options so that they are grouped together.
This commit is contained in:
Davis King 2012-12-12 20:53:50 -05:00
parent 34f28d4ad6
commit 251266dce8
4 changed files with 110 additions and 12 deletions

View File

@ -3,6 +3,7 @@
#ifndef DLIB_CMD_LINE_PARSER_KERNEl_1_
#define DLIB_CMD_LINE_PARSER_KERNEl_1_
#include "cmd_line_parser_kernel_abstract.h"
#include "../algs.h"
#include <string>
#include <sstream>
@ -148,6 +149,9 @@ namespace dlib
const std::basic_string<charT>& name (
) const { return name_; }
const std::basic_string<charT>& group_name (
) const { return group_name_; }
const std::basic_string<charT>& description (
) const { return description_; }
@ -207,6 +211,7 @@ namespace dlib
// data members
std::basic_string<charT> name_;
std::basic_string<charT> group_name_;
std::basic_string<charT> description_;
sequence2 options;
unsigned long number_of_arguments_;
@ -258,6 +263,13 @@ namespace dlib
unsigned long number_of_arguments = 0
);
void set_group_name (
const string_type& group_name
);
string_type get_group_name (
) const { return group_name; }
const cmd_line_parser_option<charT>& option (
const string_type& name
) const;
@ -301,6 +313,7 @@ namespace dlib
map options;
sequence argv;
bool have_parsed_line;
string_type group_name;
// restricted functions
cmd_line_parser_kernel_1(cmd_line_parser_kernel_1&); // copy constructor
@ -668,6 +681,22 @@ namespace dlib
return options.is_in_domain(name);
}
// ----------------------------------------------------------------------------------------
template <
typename charT,
typename map,
typename sequence,
typename sequence2
>
void cmd_line_parser_kernel_1<charT,map,sequence,sequence2>::
set_group_name (
const string_type& group_name_
)
{
group_name = group_name_;
}
// ----------------------------------------------------------------------------------------
template <
@ -687,6 +716,7 @@ namespace dlib
try
{
temp->name_ = name;
temp->group_name_ = group_name;
temp->description_ = description;
temp->number_of_arguments_ = number_of_arguments;
void* t = temp;

View File

@ -24,8 +24,9 @@ namespace dlib
or wchar_t)
INITIAL VALUE
parsed_line() == false
option_is_defined(x) == false, for all values of x
- parsed_line() == false
- option_is_defined(x) == false, for all values of x
- get_group_name() == ""
ENUMERATION ORDER
The enumerator will enumerate over all the options defined in *this
@ -243,6 +244,7 @@ namespace dlib
- #option(name).count() == 0
- #option(name).description() == description
- #option(name).number_of_arguments() == number_of_arguments
- #option(name).group_name() == get_group_name()
throws
- std::bad_alloc
if this exception is thrown then the add_option() function has no
@ -314,6 +316,28 @@ namespace dlib
it will have no effect on the state of #*this.
!*/
string_type get_group_name (
) const;
/*!
ensures
- returns the current group name. This is the group new options will be
added into when added via add_option().
- The group name of an option is used by print_options(). In particular,
it groups all options with the same group name together and displays them
under a title containing the text of the group name. This allows you to
group similar options together in the output of print_options().
- A group name of "" (i.e. the empty string) means that no group name is
set.
!*/
void set_group_name (
const string_type& group_name
);
/*!
ensures
- #get_group_name() == group_name
!*/
// -------------------------------------------------------------
// Input Validation Tools
// -------------------------------------------------------------

View File

@ -9,6 +9,8 @@
#include <iostream>
#include <string>
#include <sstream>
#include <map>
#include "../smart_pointers.h"
namespace dlib
{
@ -59,10 +61,11 @@ namespace dlib
typedef std::basic_string<ct> string;
typedef typename string::size_type size_type;
typedef std::basic_ostringstream<ct> ostringstream;
try
{
out << _dT(ct,"Options:");
size_type max_len = 0;
this->reset();
@ -99,6 +102,16 @@ namespace dlib
}
// Make a separate ostringstream for each option group. We are going to write
// the output for each group to a separate ostringstream so that we can keep
// them grouped together in the final output.
std::map<string,shared_ptr<ostringstream> > groups;
this->reset();
while(this->move_next())
{
if (!groups[this->element().group_name()])
groups[this->element().group_name()].reset(new ostringstream);
}
@ -107,49 +120,72 @@ namespace dlib
while (this->move_next())
{
ostringstream& sout = *groups[this->element().group_name()];
size_type len = 0;
out << _dT(ct,"\n -");
sout << _dT(ct,"\n -");
len += 3;
if (this->element().name().size() > 1)
{
out << _dT(ct,"-");
sout << _dT(ct,"-");
++len;
}
out << this->element().name();
sout << this->element().name();
len += this->element().name().size();
if (this->element().number_of_arguments() == 1)
{
out << _dT(ct," <arg>");
sout << _dT(ct," <arg>");
len += 6;
}
else
{
for (unsigned long i = 0; i < this->element().number_of_arguments(); ++i)
{
out << _dT(ct," <arg") << i+1 << _dT(ct,">");
sout << _dT(ct," <arg") << i+1 << _dT(ct,">");
len += 7;
if (i+1 > 9)
++len;
}
}
out << " ";
sout << _dT(ct," ");
len += 3;
while (len < max_len)
{
++len;
out << " ";
sout << _dT(ct," ");
}
const unsigned long ml = static_cast<unsigned long>(max_len);
// now print the description but make it wrap around nicely if it
// is to long to fit on one line.
if (len <= max_len)
out << wrap_string(this->element().description(),0,ml);
sout << wrap_string(this->element().description(),0,ml);
else
out << "\n" << wrap_string(this->element().description(),ml,ml);
sout << _dT(ct,"\n") << wrap_string(this->element().description(),ml,ml);
}
// Only print out a generic Options: group name if there is an unnamed option
// present.
if (groups.count(string()) == 1)
out << _dT(ct,"Options:");
// Now print everything out
typename std::map<string,shared_ptr<ostringstream> >::iterator i;
for (i = groups.begin(); i != groups.end(); ++i)
{
// print the group name if we have one
if (i->first.size() != 0)
{
if (i != groups.begin())
out << _dT(ct,"\n\n");
out << i->first << _dT(ct,":");
}
// print the options in the group
out << i->second->str();
}
out << _dT(ct,"\n\n");
this->reset();

View File

@ -39,6 +39,14 @@ namespace dlib
- returns the name of this option
!*/
virtual const string_type& group_name (
) const = 0;
/*!
ensures
- returns the name of the group this option is in. If no group was set for
this option then this function returns "".
!*/
virtual const string_type& description (
) const = 0;
/*!