#ifndef _theplu_yat_utility_option_arg_
#define _theplu_yat_utility_option_arg_
// $Id: OptionArg.h 2384 2010-12-22 14:03:36Z peter $
/*
Copyright (C) 2007, 2008 Jari Häkkinen, Peter Johansson
Copyright (C) 2009, 2010 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 "Option.h"
#include "CommandLine.h"
#include "Exception.h"
#include "utility.h"
#include
#include
#include
namespace theplu {
namespace yat {
namespace utility {
class CommandLine;
/**
\brief Option with argument
If the option is present, argument is set during
parsing. Supported formats are both gnu-style
"--support-gnu=value", POSIX-like "--support-posix value", as
well as shorter "-s value". The argument of an parameter is
retrived by the value() function. The type \c T should be either
a string or a type supported by function convert().
*/
template
class OptionArg : public Option
{
public:
/**
\brief Constructor
\param cmd Commandline Option is associated with
\param name string such as "help" for --help, "h" for -h or
"h,help" for having both short and long option name
\param desc string used in help display
\param required If true option must be found in commandline or
exception is thrown in validation
*/
OptionArg(CommandLine& cmd, std::string name, std::string desc,
bool required=false)
: Option(cmd, name, desc), required_(required) {}
/**
\param arg string to be used in help output such as `=TARGET'
in `--target=TARGET'. See print3().
\since New in yat 0.5.
*/
void print_arg(std::string arg) { print_arg_ = arg; }
/**
\return value
*/
T value(void) const
{
if (!cmd().parsed()) {
std::string s("OptionArg::value called before Commandline was parsed");
throw std::logic_error(s);
}
return value_;
}
/**
\brief set value
\since new in yat 0.5
*/
void value(T v) { value_ = v; }
protected:
/**
\return true if Option is required, i.e., if Option is not
found during parsing an exception will be thrown.
*/
inline bool required(void) const { return required_; }
private:
std::string print_arg_;
bool required_;
T value_;
void do_parse(std::vector::iterator& first,
const std::vector::iterator& last)
{
if ( first->size()>2 && (*first)[0]=='-' && (*first)[1]!='-'){
std::stringstream ss;
ss << "option requires an argument -- " << short_name() << "\n"
<< cmd().try_help();
throw cmd_error(ss.str());
}
if (first+1==last ) {
if (first->size()>2){
std::stringstream ss;
ss << "option `--" << long_name() << "' requires an argument\n"
<< cmd().try_help();
throw cmd_error(ss.str());
}
else {
std::stringstream ss;
ss << "option requires an argument -- " << short_name() << "\n"
<< cmd().try_help();
throw cmd_error(ss.str());
}
}
if ( *(first+1)->begin() == '"' && *((first+1)->end()-1) == '"')
*(first+1) = (first+1)->substr(1, (first+1)->size()-2);
assign(value_, *(++first));
}
void assign(std::string& lhs, const std::string& rhs )
{
lhs = rhs;
}
template
void assign(T1& lhs, const std::string& rhs )
{
try {
lhs = convert(rhs);
}
catch (runtime_error& e) {
std::stringstream sstr(rhs);
sstr << "invalid argument";
sstr << "`" << rhs << "' for `";
if (!long_name().empty())
sstr << "--" << long_name();
else
sstr << "-" << short_name();
sstr << "'";
throw cmd_error(sstr.str());
}
}
/**
*/
void do_validate(void) const
{
if (required_ && !present()) {
std::stringstream ss;
ss << "mandatory option `";
if (long_name().size())
ss << long_name();
else
ss << short_name();
ss << "' not given\n";
ss << cmd().try_help();
throw cmd_error(ss.str());
}
do_validate2();
}
virtual void do_validate2(void) const {}
virtual std::string print3(void) const
{
return print_arg_;
}
};
}}} // of namespace utility, yat, and theplu
#endif