#ifndef _theplu_yat_utility_commandline_
#define _theplu_yat_utility_commandline_
//$Id: CommandLine.h 2817 2012-08-29 00:38:17Z peter $
/*
Copyright (C) 2007, 2008, 2009 Jari Häkkinen, Peter Johansson
Copyright (C) 2010, 2011, 2012 Peter Johansson
This file is part of the yat library, http://dev.thep.lu.se/yat
The yat library is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 3 of the
License, or (at your option) any later version.
The yat library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with yat. If not, see .
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
namespace theplu {
namespace yat {
namespace utility {
class Option;
/**
@brief Class for parsing the command line.
Provides parsing and storage of command line arguments. The class
is typically used by hooking a number of Option objects to
CommandLine, and then call the parse() function. Here is a short
example how the class may be used:
\code
CommandLine cmd;
OptionHelp help(cmd);
OptionFile in(cmd, "i,in",
"Read input from file (rather than standard input)",
false, true, "r");
OptionFile out(cmd, "o,out", "Place the output to file", false, false, "w");
OptionSwitch target(cmd, "T,target", "treat DEST as a normal file", true);
OptionSwitch verbose(cmd, "v,verbose", "explain what is being done");
OptionSwitch version(cmd, "version", "output version and exit");
std::stringstream copyright;
copyright << "example 1.0\n"
<< "Copyright (C) 2007 Peter Johansson\n\n"
<< "This is free software see the source for copying "
<< "conditions. There is NO\nwarranty; not even for "
<< "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n";
try {
cmd.parse(argc, argv);
}
catch (cmd_error& e){
if (version.present()){
std::cout << copyright.str();
return EXIT_SUCCESS;
}
std::cerr << e.what() << std::endl;
return EXIT_FAILURE;
}
if (version.present()){
std::cout << copyright.str();
return EXIT_SUCCESS;
}
StreamRedirect sr_out(std::cout, out.value(), out.present());
StreamRedirect sr_in(std::cin, in.value(), in.present());
...
\endcode
After creation a number of Option classes are hooked up to the
CommandLine object in their constructors.
Each parameter is associated to a one-character flag and/or a
longer string flag. The longer flag expects to be preceded by
'--' as e.g. '--help' for help. The shorter flag expects to be
preceded by '-' as e.g. '-h', and can also be concatenated like
"program -vf", which is equivalent to "program -v -f". or
its sibblings for different types.
*/
class CommandLine
{
public:
/**
\brief default constructor
\param str text preceeding the list of option in output
*/
CommandLine(std::string str="Available options are:");
/**
\brief Destructor
*/
virtual ~CommandLine(void);
/**
\brief Function to add an option.
*/
void add(Option&);
/**
\brief Allow at most \a n free arguments.
A free argument is an argument not associated with an Option,
allowing commandlines such as \code prog foo bar \endcode
*/
void allow_free_args(size_t n);
/**
\brief Arguments not associated with an Option
\see allow_free_args(size_t n)
*/
const std::vector& free_args(void) const;
/**
\brief parse the commandline
First the commandline is parsed to detect which options are
present, then each Option parses the its relevant part of
commandline (Option::parse()), and finally each Option is
validated (Option::validate()).
throw cmd_error if an error is detected.
*/
void parse(int argc, char* argv[]);
/**
\brief has the commandline been parsed already
\return true if parse function has already been called
\since New in yat 0.5
*/
bool parsed(void) const;
/**
@return Name of more; more specifically argv[0] is
stripped so only string after the last '/' remains.
*/
std::string program_name(void) const;
/**
\brief Sort Options how they will appear in (help) output.
This function will sort the Options in alphabetical order. If
the Option has a long_name, it is used for the sorting;
otherwise, the short_name is used.
\since New in yat 0.7
*/
void sort(void);
/**
Like sort(void) but using \a compare to sort Options.
The functor Compare must be a Binary
Predicate with both argument types \c const \c Option*.
\since New in yat 0.7
*/
template
void sort(Compare compare);
/**
\return something like "Try ` --help` for
more information."
*/
std::string try_help(void) const;
private:
friend std::ostream& operator<<(std::ostream& os, const CommandLine& cl);
bool is_long_option(std::string str) const;
bool is_short_option(std::string str) const;
void parse(std::vector::iterator& first,
std::vector::iterator& last);
void parse_long(std::vector::iterator& first,
std::vector::iterator& last);
void parse_short(std::vector::iterator& first,
std::vector::iterator& last);
void parse_free_arg(std::vector::iterator& first,
std::vector::iterator& last);
std::string description_;
std::vector free_arg_;
size_t free_arg_max_;
std::vector options_;
std::map short_options_;
std::map long_options_;
bool parsed_;
std::string program_name_;
// use cond to make doxygen ignore this privat class
/// \cond yat_ignore_this
struct OptionCompare
{
bool operator()(const Option*, const Option*) const;
};
/// \endcond
};
/**
\brief CommandLine output operator
A typical output may look like this
\verbatim
Available options are:
-h, --help display this help and exit
-v, --verbose explain what is being done
\endverbatim
The output starts with a descriptive line such as "Available
options are:" (default) that can be set in constructor. Then follows the
options described in the order they were added to
Commandline. Each Option is described according to
Option::print(void) function.
\see OptionHelp
\relates CommandLine
*/
std::ostream& operator<<(std::ostream&, const CommandLine&);
template
void CommandLine::sort(Compare compare)
{
std::sort(options_.begin(), options_.end(), compare);
}
}}} // end of namespace utility, yat, and theplu
#endif