yat  0.8.3pre
OptionArg.h
00001 #ifndef _theplu_yat_utility_option_arg_
00002 #define _theplu_yat_utility_option_arg_
00003 
00004 // $Id: OptionArg.h 2384 2010-12-22 14:03:36Z peter $
00005 
00006 /*
00007   Copyright (C) 2007, 2008 Jari Häkkinen, Peter Johansson
00008   Copyright (C) 2009, 2010 Peter Johansson
00009 
00010   This file is part of the yat library, http://dev.thep.lu.se/yat
00011 
00012   The yat library is free software; you can redistribute it and/or
00013   modify it under the terms of the GNU General Public License as
00014   published by the Free Software Foundation; either version 3 of the
00015   License, or (at your option) any later version.
00016 
00017   The yat library is distributed in the hope that it will be useful,
00018   but WITHOUT ANY WARRANTY; without even the implied warranty of
00019   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00020   General Public License for more details.
00021 
00022   You should have received a copy of the GNU General Public License
00023   along with yat. If not, see <http://www.gnu.org/licenses/>.
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 }}} // of namespace utility, yat, and theplu
00189 
00190 #endif

Generated on Thu Dec 20 2012 03:12:58 for yat by  doxygen 1.8.0-20120409