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;
00049 template<typename T>
00050 class OptionArg : public Option
00051 {
00052 public:
00063 OptionArg(CommandLine& cmd, std::string name, std::string desc,
00064 bool required=false)
00065 : Option(cmd, name, desc), required_(required) {}
00066
00073 void print_arg(std::string arg) { print_arg_ = arg; }
00074
00078 T value(void) const
00079 {
00080 if (!cmd().parsed()) {
00081 std::string s("OptionArg::value called before Commandline was parsed");
00082 throw std::logic_error(s);
00083 }
00084 return value_;
00085 }
00086
00092 void value(T v) { value_ = v; }
00093
00094 protected:
00099 inline bool required(void) const { return required_; }
00100
00101 private:
00102 std::string print_arg_;
00103 bool required_;
00104 T value_;
00105
00106 void do_parse(std::vector<std::string>::iterator& first,
00107 const std::vector<std::string>::iterator& last)
00108 {
00109 if ( first->size()>2 && (*first)[0]=='-' && (*first)[1]!='-'){
00110 std::stringstream ss;
00111 ss << "option requires an argument -- " << short_name() << "\n"
00112 << cmd().try_help();
00113 throw cmd_error(ss.str());
00114 }
00115 if (first+1==last ) {
00116 if (first->size()>2){
00117 std::stringstream ss;
00118 ss << "option `--" << long_name() << "' requires an argument\n"
00119 << cmd().try_help();
00120 throw cmd_error(ss.str());
00121 }
00122 else {
00123 std::stringstream ss;
00124 ss << "option requires an argument -- " << short_name() << "\n"
00125 << cmd().try_help();
00126 throw cmd_error(ss.str());
00127 }
00128 }
00129
00130 if ( *(first+1)->begin() == '"' && *((first+1)->end()-1) == '"')
00131 *(first+1) = (first+1)->substr(1, (first+1)->size()-2);
00132 assign(value_, *(++first));
00133 }
00134
00135 void assign(std::string& lhs, std::string rhs )
00136 {
00137 lhs = rhs;
00138 }
00139
00140 template<class T1>
00141 void assign(T1& lhs, std::string rhs )
00142 {
00143 try {
00144 lhs = convert<T1>(rhs);
00145 }
00146 catch (std::runtime_error& e) {
00147 std::stringstream sstr(rhs);
00148 sstr << ": invalid argument";
00149 throw cmd_error(sstr.str());
00150 }
00151 }
00152
00155 void do_validate(void) const
00156 {
00157 if (required_ && !present()) {
00158 std::stringstream ss;
00159 ss << "mandatory option `";
00160 if (long_name().size())
00161 ss << long_name();
00162 else
00163 ss << short_name();
00164 ss << "' not given\n";
00165 ss << cmd().try_help();
00166 throw cmd_error(ss.str());
00167 }
00168 do_validate2();
00169 }
00170
00171
00172 virtual void do_validate2(void) const {}
00173
00174 virtual std::string print3(void) const
00175 {
00176 return print_arg_;
00177 }
00178
00179 };
00180
00181 }}}
00182
00183 #endif