source: trunk/yat/utility/OptionArg.h @ 1632

Last change on this file since 1632 was 1632, checked in by Peter, 13 years ago

move the setting of print_arg from constructor to function in order to allow usage also in daughter classes.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 4.2 KB
Line 
1#ifndef _theplu_yat_utility_option_arg_
2#define _theplu_yat_utility_option_arg_
3
4// $Id: OptionArg.h 1632 2008-11-19 16:20:49Z peter $
5
6/*
7  Copyright (C) 2007 Jari Häkkinen, Peter Johansson
8  Copyright (C) 2008 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 <string>
32#include <sstream>
33
34namespace theplu {
35namespace yat {
36namespace utility {
37
38  class CommandLine;
39  /**
40     \brief Option with argument
41
42     If the option is present, argument is set during
43     parsing. Supported formats are both gnu-style
44     "--support-gnu=value", POSIX-like "--support-posix value", as
45     well as shorter "-s value". The argument of an parameter is
46     retrived by the value() function
47   */
48  template<typename T>
49  class OptionArg : public Option
50  {
51  public:
52    /**
53       \brief Constructor
54       
55       \param cmd Commandline Option is associated with
56       \param name string such as "help" for --help, "h" for -h or
57       "h,help" for having both short and long option name
58       \param desc string used in help display
59       \param required If true option must be found in commandline or
60       exception is thrown in validation
61    */
62    OptionArg(CommandLine& cmd, std::string name, std::string desc,
63              bool required=false)
64      : Option(cmd, name, desc), required_(required) {}
65
66    /**
67       \param arg string to be used in help output such as `=TARGET'
68       in `--target=TARGET'. See print3().
69
70       \since New in yat 0.5.
71     */
72    void print_arg(std::string arg) { print_arg_ = arg; }
73
74    /**
75       \return value
76    */
77    T value(void) const { return value_; }
78
79    /**
80       \brief set value
81
82       \since new in yat 0.5
83    */
84    void value(T v) { value_ = v; }
85
86  protected:
87    /**
88       \return true if Option is required, i.e., if Option is not
89       found during parsing an exception will be thrown.
90     */
91    inline bool required(void) const { return required_; }
92
93  private:
94    std::string print_arg_;
95    bool required_;
96    T value_;
97
98    void do_parse(std::vector<std::string>::iterator& first, 
99                  const std::vector<std::string>::iterator& last) 
100    {
101      if ( first->size()>2 && (*first)[0]=='-' && (*first)[1]!='-'){
102        std::stringstream ss;
103        ss << "option requires an argument -- " << short_name() << "\n"
104           << cmd().try_help();
105        throw cmd_error(ss.str());
106      }
107      if (first+1==last ) {
108        if (first->size()>2){
109          std::stringstream ss;
110          ss << "option `--" << long_name() << "' requires an argument\n"
111             << cmd().try_help();
112          throw cmd_error(ss.str());
113        }
114        else {
115          std::stringstream ss;
116          ss << "option requires an argument -- " << short_name() << "\n"
117             << cmd().try_help();
118          throw cmd_error(ss.str());
119        }
120      }       
121       
122      if ( *(first+1)->begin() == '"' && *((first+1)->end()-1) == '"')
123        *(first+1) = (first+1)->substr(1, (first+1)->size()-2); 
124      assign(value_, *(++first));
125    }
126
127    void assign(std::string& lhs, std::string rhs )
128    { 
129      lhs = rhs;
130    }
131   
132    template<class T1>
133    void assign(T1& lhs, std::string rhs )
134    { 
135      try {
136        lhs = convert<T1>(rhs);
137      }
138      catch (std::runtime_error& e) {
139        std::stringstream sstr(rhs);
140        sstr << ": invalid argument";
141        throw cmd_error(sstr.str());
142      }
143    }
144
145    /**
146     */
147    void do_validate(void) const 
148    {
149      if (required_ && !present()) {
150        std::stringstream ss;
151        ss << "mandatory option `";
152        if (long_name().size())
153          ss << long_name();
154        else
155          ss << short_name();
156        ss << "' not given\n";
157        ss << cmd().try_help();
158        throw cmd_error(ss.str());
159      }
160      do_validate2();
161    }
162
163
164    virtual void do_validate2(void) const {}
165
166    virtual std::string print3(void) const 
167    { 
168      return print_arg_; 
169    }
170
171  };
172
173}}} // of namespace utility, yat, and theplu
174
175#endif
Note: See TracBrowser for help on using the repository browser.