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

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

made help output more flexible

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 4.3 KB
Line 
1#ifndef _theplu_yat_utility_option_arg_
2#define _theplu_yat_utility_option_arg_
3
4// $Id: OptionArg.h 1629 2008-11-17 21:53:16Z 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 \param name
55       string such as "help" for --help, "h" for -h or "h,help" for
56       having both short and long option name \param desc string used
57       in help display \param required If true option must be found in
58       commandline or exception is thrown in validation \param arg
59       string to be used in help output such as `TARGET' in
60       `--target=TARGET'. See print3().
61    */
62    OptionArg(CommandLine& cmd, std::string name, std::string desc,
63              bool required=false, std::string arg="")
64      : Option(cmd, name, desc), print_arg_(arg), required_(required) {}
65
66    /**
67       \return value
68    */
69    T value(void) const { return value_; }
70
71    /**
72       \brief set value
73
74       \since new in yat 0.5
75    */
76    void value(T v) { value_ = v; }
77
78  protected:
79    /**
80       \return true if Option is required, i.e., if Option is not
81       found during parsing an exception will be thrown.
82     */
83    inline bool required(void) const { return required_; }
84
85  private:
86    std::string print_arg_;
87    bool required_;
88    T value_;
89
90    void do_parse(std::vector<std::string>::iterator& first, 
91                  const std::vector<std::string>::iterator& last) 
92    {
93      if ( first->size()>2 && (*first)[0]=='-' && (*first)[1]!='-'){
94        std::stringstream ss;
95        ss << "option requires an argument -- " << short_name() << "\n"
96           << cmd().try_help();
97        throw cmd_error(ss.str());
98      }
99      if (first+1==last ) {
100        if (first->size()>2){
101          std::stringstream ss;
102          ss << "option `--" << long_name() << "' requires an argument\n"
103             << cmd().try_help();
104          throw cmd_error(ss.str());
105        }
106        else {
107          std::stringstream ss;
108          ss << "option requires an argument -- " << short_name() << "\n"
109             << cmd().try_help();
110          throw cmd_error(ss.str());
111        }
112      }       
113       
114      if ( *(first+1)->begin() == '"' && *((first+1)->end()-1) == '"')
115        *(first+1) = (first+1)->substr(1, (first+1)->size()-2); 
116      assign(value_, *(++first));
117    }
118
119    void assign(std::string& lhs, std::string rhs )
120    { 
121      lhs = rhs;
122    }
123   
124    template<class T1>
125    void assign(T1& lhs, std::string rhs )
126    { 
127      std::stringstream ss(rhs);
128      ss >> lhs;
129      bool fail = ss.fail();
130      std::string str;
131      ss >> str;
132      if (fail || str.size()) {
133        std::stringstream sstr(rhs);
134        sstr << ": invalid argument";
135        throw cmd_error(sstr.str());
136      }
137    }
138
139    /**
140     */
141    void do_validate(void) const 
142    {
143      if (required_ && !present()) {
144        std::stringstream ss;
145        ss << "mandatory option `";
146        if (long_name().size())
147          ss << long_name();
148        else
149          ss << short_name();
150        ss << "' not given\n";
151        ss << cmd().try_help();
152        throw cmd_error(ss.str());
153      }
154      do_validate2();
155    }
156
157
158    virtual void do_validate2(void) const {}
159
160    virtual std::string print3(void) const 
161    { 
162      if (print_arg_.empty())
163        return std::string("");
164      return std::string("=")+print_arg_; 
165    }
166
167  };
168
169}}} // of namespace utility, yat, and theplu
170
171#endif
Note: See TracBrowser for help on using the repository browser.