source: trunk/lib/OptionArg.h @ 791

Last change on this file since 791 was 705, checked in by Peter Johansson, 13 years ago

importing classes for commandline parsing from yat. This fixes #349 and #265

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 4.2 KB
Line 
1#ifndef _theplu_svndigest_option_arg_
2#define _theplu_svndigest_option_arg_
3
4// $Id: OptionArg.h 705 2008-11-25 23:33:26Z 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 svndigest, http://dev.thep.lu.se/svndigest
11
12  svndigest is free software; you can redistribute it and/or modify it
13  under the terms of the GNU General Public License as published by
14  the Free Software Foundation; either version 3 of the License, or
15  (at your option) any later version.
16
17  svndigest is distributed in the hope that it will be useful, but
18  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 svndigest. 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 svndigest {
36
37  class CommandLine;
38  /**
39     \brief Option with argument
40
41     If the option is present, argument is set during
42     parsing. Supported formats are both gnu-style
43     "--support-gnu=value", POSIX-like "--support-posix value", as
44     well as shorter "-s value". The argument of an parameter is
45     retrived by the value() function
46   */
47  template<typename T>
48  class OptionArg : public Option
49  {
50  public:
51    /**
52       \brief Constructor
53       
54       \param cmd Commandline Option is associated with
55       \param name string such as "help" for --help, "h" for -h or
56       "h,help" for having both short and long option name
57       \param desc string used in help display
58       \param required If true option must be found in commandline or
59       exception is thrown in validation
60    */
61    OptionArg(CommandLine& cmd, std::string name, std::string desc,
62              bool required=false)
63      : Option(cmd, name, desc), required_(required) {}
64
65    /**
66       \param arg string to be used in help output such as \verbatim
67       `=TARGET' \endverbatim in \verbatim `--target=TARGET'
68       \endvarbatim. See print3().
69     */
70    void print_arg(std::string arg) { print_arg_ = arg; }
71
72    /**
73       \return value
74    */
75    T value(void) const { return value_; }
76
77    /**
78       \brief set value
79    */
80    void value(T v) { value_ = v; }
81
82  protected:
83    /**
84       \return true if Option is required, i.e., if Option is not
85       found during parsing an exception will be thrown.
86     */
87    inline bool required(void) const { return required_; }
88
89  private:
90    std::string print_arg_;
91    bool required_;
92    T value_;
93
94    void do_parse(std::vector<std::string>::iterator& first, 
95                  const std::vector<std::string>::iterator& last) 
96    {
97      if ( first->size()>2 && (*first)[0]=='-' && (*first)[1]!='-'){
98        std::stringstream ss;
99        ss << "option requires an argument -- " << short_name() << "\n"
100           << cmd().try_help();
101        throw cmd_error(ss.str());
102      }
103      if (first+1==last ) {
104        if (first->size()>2){
105          std::stringstream ss;
106          ss << "option `--" << long_name() << "' requires an argument\n"
107             << cmd().try_help();
108          throw cmd_error(ss.str());
109        }
110        else {
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      }       
117       
118      if ( *(first+1)->begin() == '"' && *((first+1)->end()-1) == '"')
119        *(first+1) = (first+1)->substr(1, (first+1)->size()-2); 
120      assign(value_, *(++first));
121    }
122
123    void assign(std::string& lhs, std::string rhs )
124    { 
125      lhs = rhs;
126    }
127   
128    template<class T1>
129    void assign(T1& lhs, std::string rhs )
130    { 
131      try {
132        lhs = convert<T1>(rhs);
133      }
134      catch (std::runtime_error& e) {
135        std::stringstream sstr(rhs);
136        sstr << ": invalid argument";
137        throw cmd_error(sstr.str());
138      }
139    }
140
141    /**
142     */
143    void do_validate(void) const 
144    {
145      if (required_ && !present()) {
146        std::stringstream ss;
147        ss << "mandatory option `";
148        if (long_name().size())
149          ss << long_name();
150        else
151          ss << short_name();
152        ss << "' not given\n";
153        ss << cmd().try_help();
154        throw cmd_error(ss.str());
155      }
156      do_validate2();
157    }
158
159
160    virtual void do_validate2(void) const {}
161
162    virtual std::string print3(void) const 
163    { 
164      return print_arg_; 
165    }
166
167  };
168
169}} // of namespace svndigest and theplu
170
171#endif
Note: See TracBrowser for help on using the repository browser.