source: trunk/lib/yat/OptionArg.h @ 1027

Last change on this file since 1027 was 983, checked in by Peter Johansson, 12 years ago

fetch yat files. refs #429

  • Property svn:eol-style set to native
File size: 4.5 KB
Line 
1#ifndef _theplu_yat_utility_option_arg_
2#define _theplu_yat_utility_option_arg_
3
4// $Id: OptionArg.h 2119 2009-12-12 23:11:43Z peter $
5
6/*
7  Copyright (C) 2007, 2008 Jari Häkkinen, Peter Johansson
8  Copyright (C) 2009 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
35namespace theplu {
36namespace yat {
37namespace utility {
38
39  class CommandLine;
40  /**
41     \brief Option with argument
42
43     If the option is present, argument is set during
44     parsing. Supported formats are both gnu-style
45     "--support-gnu=value", POSIX-like "--support-posix value", as
46     well as shorter "-s value". The argument of an parameter is
47     retrived by the value() function. The type \c T should be either
48     a string or a type supported by function convert().
49   */
50  template<typename T>
51  class OptionArg : public Option
52  {
53  public:
54    /**
55       \brief Constructor
56       
57       \param cmd Commandline Option is associated with
58       \param name string such as "help" for --help, "h" for -h or
59       "h,help" for having both short and long option name
60       \param desc string used in help display
61       \param required If true option must be found in commandline or
62       exception is thrown in validation
63    */
64    OptionArg(CommandLine& cmd, std::string name, std::string desc,
65              bool required=false)
66      : Option(cmd, name, desc), required_(required) {}
67
68    /**
69       \param arg string to be used in help output such as `=TARGET'
70       in `--target=TARGET'. See print3().
71
72       \since New in yat 0.5.
73     */
74    void print_arg(std::string arg) { print_arg_ = arg; }
75
76    /**
77       \return value
78    */
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
88    /**
89       \brief set value
90
91       \since new in yat 0.5
92    */
93    void value(T v) { value_ = v; }
94
95  protected:
96    /**
97       \return true if Option is required, i.e., if Option is not
98       found during parsing an exception will be thrown.
99     */
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, std::string rhs )
137    { 
138      lhs = rhs;
139    }
140   
141    template<class T1>
142    void assign(T1& lhs, std::string rhs )
143    { 
144      try {
145        lhs = convert<T1>(rhs);
146      }
147      catch (std::runtime_error& e) {
148        std::stringstream sstr(rhs);
149        sstr << ": invalid argument";
150        throw cmd_error(sstr.str());
151      }
152    }
153
154    /**
155     */
156    void do_validate(void) const 
157    {
158      if (required_ && !present()) {
159        std::stringstream ss;
160        ss << "mandatory option `";
161        if (long_name().size())
162          ss << long_name();
163        else
164          ss << short_name();
165        ss << "' not given\n";
166        ss << cmd().try_help();
167        throw cmd_error(ss.str());
168      }
169      do_validate2();
170    }
171
172
173    virtual void do_validate2(void) const {}
174
175    virtual std::string print3(void) const 
176    { 
177      return print_arg_; 
178    }
179
180  };
181
182}}} // of namespace utility, yat, and theplu
183
184#endif
Note: See TracBrowser for help on using the repository browser.