00001 #ifndef _theplu_yat_utility_option_arg_
00002 #define _theplu_yat_utility_option_arg_
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "Option.h"
00027 #include "CommandLine.h"
00028 #include "Exception.h"
00029 #include "utility.h"
00030
00031 #include <stdexcept>
00032 #include <string>
00033 #include <sstream>
00034
00035 namespace theplu {
00036 namespace yat {
00037 namespace utility {
00038
00039 class CommandLine;
00050 template<typename T>
00051 class OptionArg : public Option
00052 {
00053 public:
00064 OptionArg(CommandLine& cmd, std::string name, std::string desc,
00065 bool required=false)
00066 : Option(cmd, name, desc), required_(required) {}
00067
00074 void print_arg(std::string arg) { print_arg_ = arg; }
00075
00079 T value(void) const
00080 {
00081 if (!cmd().parsed()) {
00082 std::string s("OptionArg::value called before Commandline was parsed");
00083 throw std::logic_error(s);
00084 }
00085 return value_;
00086 }
00087
00093 void value(T v) { value_ = v; }
00094
00095 protected:
00100 inline bool required(void) const { return required_; }
00101
00102 private:
00103 std::string print_arg_;
00104 bool required_;
00105 T value_;
00106
00107 void do_parse(std::vector<std::string>::iterator& first,
00108 const std::vector<std::string>::iterator& last)
00109 {
00110 if ( first->size()>2 && (*first)[0]=='-' && (*first)[1]!='-'){
00111 std::stringstream ss;
00112 ss << "option requires an argument -- " << short_name() << "\n"
00113 << cmd().try_help();
00114 throw cmd_error(ss.str());
00115 }
00116 if (first+1==last ) {
00117 if (first->size()>2){
00118 std::stringstream ss;
00119 ss << "option `--" << long_name() << "' requires an argument\n"
00120 << cmd().try_help();
00121 throw cmd_error(ss.str());
00122 }
00123 else {
00124 std::stringstream ss;
00125 ss << "option requires an argument -- " << short_name() << "\n"
00126 << cmd().try_help();
00127 throw cmd_error(ss.str());
00128 }
00129 }
00130
00131 if ( *(first+1)->begin() == '"' && *((first+1)->end()-1) == '"')
00132 *(first+1) = (first+1)->substr(1, (first+1)->size()-2);
00133 assign(value_, *(++first));
00134 }
00135
00136 void assign(std::string& lhs, const std::string& rhs )
00137 {
00138 lhs = rhs;
00139 }
00140
00141 template<class T1>
00142 void assign(T1& lhs, const std::string& rhs )
00143 {
00144 try {
00145 lhs = convert<T1>(rhs);
00146 }
00147 catch (runtime_error& e) {
00148 std::stringstream sstr(rhs);
00149 sstr << "invalid argument";
00150 sstr << "`" << rhs << "' for `";
00151 if (!long_name().empty())
00152 sstr << "--" << long_name();
00153 else
00154 sstr << "-" << short_name();
00155 sstr << "'";
00156 throw cmd_error(sstr.str());
00157 }
00158 }
00159
00162 void do_validate(void) const
00163 {
00164 if (required_ && !present()) {
00165 std::stringstream ss;
00166 ss << "mandatory option `";
00167 if (long_name().size())
00168 ss << long_name();
00169 else
00170 ss << short_name();
00171 ss << "' not given\n";
00172 ss << cmd().try_help();
00173 throw cmd_error(ss.str());
00174 }
00175 do_validate2();
00176 }
00177
00178
00179 virtual void do_validate2(void) const {}
00180
00181 virtual std::string print3(void) const
00182 {
00183 return print_arg_;
00184 }
00185
00186 };
00187
00188 }}}
00189
00190 #endif