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

Last change on this file since 1566 was 1487, checked in by Jari Häkkinen, 13 years ago

Addresses #436. GPL license copy reference should also be updated.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 3.9 KB
Line 
1#ifndef _theplu_yat_utility_option_arg_
2#define _theplu_yat_utility_option_arg_
3
4// $Id: OptionArg.h 1487 2008-09-10 08:41:36Z jari $
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
30#include <string>
31#include <sstream>
32
33namespace theplu {
34namespace yat {
35namespace utility {
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       \return value
67    */
68    T value(void) const { return value_; }
69
70  protected:
71    /**
72       \return true if Option is required, i.e., if Option is not
73       found during parsing an exception will be thrown.
74     */
75    inline bool required(void) const { return required_; }
76
77  private:
78    bool required_;
79    T value_;
80
81    void do_parse(std::vector<std::string>::iterator& first, 
82                  const std::vector<std::string>::iterator& last) 
83    {
84      if ( first->size()>2 && (*first)[0]=='-' && (*first)[1]!='-'){
85        std::stringstream ss;
86        ss << "option requires an argument -- " << short_name() << "\n"
87           << cmd().try_help();
88        throw cmd_error(ss.str());
89      }
90      if (first+1==last ) {
91        if (first->size()>2){
92          std::stringstream ss;
93          ss << "option `--" << long_name() << "' requires an argument\n"
94             << cmd().try_help();
95          throw cmd_error(ss.str());
96        }
97        else {
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      }       
104       
105      if ( *(first+1)->begin() == '"' && *((first+1)->end()-1) == '"')
106        *(first+1) = (first+1)->substr(1, (first+1)->size()-2); 
107      assign(value_, *(++first));
108    }
109
110    void assign(std::string& lhs, std::string rhs )
111    { 
112      lhs = rhs;
113    }
114   
115    template<class T1>
116    void assign(T1& lhs, std::string rhs )
117    { 
118      std::stringstream ss(rhs);
119      ss >> lhs;
120      bool fail = ss.fail();
121      std::string str;
122      ss >> str;
123      if (fail || str.size()) {
124        std::stringstream sstr(rhs);
125        sstr << ": invalid argument";
126        throw cmd_error(sstr.str());
127      }
128    }
129
130    /**
131     */
132    void do_validate(void) const 
133    {
134      if (required_ && !present()) {
135        std::stringstream ss;
136        ss << "mandatory option `";
137        if (long_name().size())
138          ss << long_name();
139        else
140          ss << short_name();
141        ss << "' not given\n";
142        ss << cmd().try_help();
143        throw cmd_error(ss.str());
144      }
145      do_validate2();
146    }
147
148
149    virtual void do_validate2(void) const {}
150  };
151
152}}} // of namespace utility, yat, and theplu
153
154#endif
Note: See TracBrowser for help on using the repository browser.