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

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

adding function to set argument value in OptionArg?

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