yat  0.10.4pre
OptionArg.h
1 #ifndef _theplu_yat_utility_option_arg_
2 #define _theplu_yat_utility_option_arg_
3 
4 // $Id: OptionArg.h 2384 2010-12-22 14:03:36Z peter $
5 
6 /*
7  Copyright (C) 2007, 2008 Jari Häkkinen, Peter Johansson
8  Copyright (C) 2009, 2010 Peter Johansson
9 
10  This file is part of the yat library, http://dev.thep.lu.se/yat
11 
12  The yat library is free software; you can redistribute it and/or
13  modify it under the terms of the GNU General Public License as
14  published by the Free Software Foundation; either version 3 of the
15  License, or (at your option) any later version.
16 
17  The yat library is distributed in the hope that it will be useful,
18  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20  General Public License for more details.
21 
22  You should have received a copy of the GNU General Public License
23  along with yat. If not, see <http://www.gnu.org/licenses/>.
24 */
25 
26 #include "Option.h"
27 #include "CommandLine.h"
28 #include "Exception.h"
29 #include "utility.h"
30 
31 #include <stdexcept>
32 #include <string>
33 #include <sstream>
34 
35 namespace theplu {
36 namespace yat {
37 namespace utility {
38 
39  class CommandLine;
50  template<typename T>
51  class OptionArg : public Option
52  {
53  public:
64  OptionArg(CommandLine& cmd, std::string name, std::string desc,
65  bool required=false)
66  : Option(cmd, name, desc), required_(required) {}
67 
74  void print_arg(std::string arg) { print_arg_ = arg; }
75 
79  T value(void) const
80  {
81  if (!cmd().parsed()) {
82  std::string s("OptionArg::value called before Commandline was parsed");
83  throw std::logic_error(s);
84  }
85  return value_;
86  }
87 
93  void value(T v) { value_ = v; }
94 
95  protected:
100  inline bool required(void) const { return required_; }
101 
102  private:
103  std::string print_arg_;
104  bool required_;
105  T value_;
106 
107  void do_parse(std::vector<std::string>::iterator& first,
108  const std::vector<std::string>::iterator& last)
109  {
110  if ( first->size()>2 && (*first)[0]=='-' && (*first)[1]!='-'){
111  std::stringstream ss;
112  ss << "option requires an argument -- " << short_name() << "\n"
113  << cmd().try_help();
114  throw cmd_error(ss.str());
115  }
116  if (first+1==last ) {
117  if (first->size()>2){
118  std::stringstream ss;
119  ss << "option `--" << long_name() << "' requires an argument\n"
120  << cmd().try_help();
121  throw cmd_error(ss.str());
122  }
123  else {
124  std::stringstream ss;
125  ss << "option requires an argument -- " << short_name() << "\n"
126  << cmd().try_help();
127  throw cmd_error(ss.str());
128  }
129  }
130 
131  if ( *(first+1)->begin() == '"' && *((first+1)->end()-1) == '"')
132  *(first+1) = (first+1)->substr(1, (first+1)->size()-2);
133  assign(value_, *(++first));
134  }
135 
136  void assign(std::string& lhs, const std::string& rhs )
137  {
138  lhs = rhs;
139  }
140 
141  template<class T1>
142  void assign(T1& lhs, const std::string& rhs )
143  {
144  try {
145  lhs = convert<T1>(rhs);
146  }
147  catch (runtime_error& e) {
148  std::stringstream sstr(rhs);
149  sstr << "invalid argument";
150  sstr << "`" << rhs << "' for `";
151  if (!long_name().empty())
152  sstr << "--" << long_name();
153  else
154  sstr << "-" << short_name();
155  sstr << "'";
156  throw cmd_error(sstr.str());
157  }
158  }
159 
162  void do_validate(void) const
163  {
164  if (required_ && !present()) {
165  std::stringstream ss;
166  ss << "mandatory option `";
167  if (long_name().size())
168  ss << long_name();
169  else
170  ss << short_name();
171  ss << "' not given\n";
172  ss << cmd().try_help();
173  throw cmd_error(ss.str());
174  }
175  do_validate2();
176  }
177 
178 
179  virtual void do_validate2(void) const {}
180 
181  virtual std::string print3(void) const
182  {
183  return print_arg_;
184  }
185 
186  };
187 
188 }}} // of namespace utility, yat, and theplu
189 
190 #endif

Generated on Mon Nov 11 2013 09:41:44 for yat by  doxygen 1.8.1