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, std::string rhs )
00137 {
00138 lhs = rhs;
00139 }
00140
00141 template<class T1>
00142 void assign(T1& lhs, std::string rhs )
00143 {
00144 try {
00145 lhs = convert<T1>(rhs);
00146 }
00147 catch (std::runtime_error& e) {
00148 std::stringstream sstr(rhs);
00149 sstr << ": invalid argument";
00150 throw cmd_error(sstr.str());
00151 }
00152 }
00153
00156 void do_validate(void) const
00157 {
00158 if (required_ && !present()) {
00159 std::stringstream ss;
00160 ss << "mandatory option `";
00161 if (long_name().size())
00162 ss << long_name();
00163 else
00164 ss << short_name();
00165 ss << "' not given\n";
00166 ss << cmd().try_help();
00167 throw cmd_error(ss.str());
00168 }
00169 do_validate2();
00170 }
00171
00172
00173 virtual void do_validate2(void) const {}
00174
00175 virtual std::string print3(void) const
00176 {
00177 return print_arg_;
00178 }
00179
00180 };
00181
00182 }}}
00183
00184 #endif