source: trunk/lib/yat/CommandLine.h @ 795

Last change on this file since 795 was 795, checked in by Peter Johansson, 12 years ago

refs #388

Create a sub-directory 'lib/yat' in which files from yat are
placed. The files may be updated via 'make fetch', see file README for
more details on how to change which files are updated/copied through
this mechanism.

The reason we do not use subversion's external mechanism is that we
don't want the files to be synchronised with yat automatically. We
want the update to be moderated by some developer.

I chose to fetch files using the svn client rather than wget because
the svn allows us to get an Id string with information from the yat
repository. 'wget' would just download the file as it appears on the
server that is the string is not expanded.

The file 'config_public.h' is created by configure just as in
yat. This implies that automake adds $(top_builddir)/lib/yat to the
include path so unless in a VPATH build $(top_srcdir)/lib/yat is in
the include path. As we have already added $(top_srcdir)/lib to the
include path, and there are both a lib/utility.h and a
lib/yat/utility.h it is not obvious which file is included when having
'include "utility.h"'. For this reason, when being in bin/ and test/
it is needed to include "../lib/utility.h" rather than "utility.h"
when we want to include 'lib/utility.h'.

  • Property svn:eol-style set to native
File size: 5.5 KB
Line 
1#ifndef _theplu_yat_utility_commandline_
2#define _theplu_yat_utility_commandline_
3
4//$Id: CommandLine.h 1954 2009-05-07 15:30:58Z jari $
5
6/*
7  Copyright (C) 2007, 2008 Jari Häkkinen, Peter Johansson
8  Copyright (C) 2009 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 <cctype>
27#include <map>
28#include <iostream>
29#include <sstream>
30#include <stdexcept>
31#include <string>
32#include <typeinfo>
33#include <utility>
34#include <vector>
35
36namespace theplu {
37namespace yat {
38namespace utility {
39
40  class Option;
41
42  /**
43     @brief Class for parsing the command line.
44     
45     Provides parsing and storage of command line arguments. The class
46     is typically used by hooking a number of Option objects to
47     CommandLine, and then call the parse() function. Here is a short
48     example how the class may be used:
49 
50     \code
51 
52     CommandLine cmd;
53     OptionHelp help(cmd);
54     OptionInFile in(cmd, "i,in",
55                     "Read input from file (rather than standard input)");
56     OptionOutFile out(cmd, "o,out", "Place the output to file");
57     OptionSwitch target(cmd, "T,target", "treat DEST as a normal file", true);
58     OptionSwitch verbose(cmd, "v,verbose", "explain what is being done");
59     OptionSwitch version(cmd, "version", "output version and exit");
60     std::stringstream copyright;
61     copyright << "example 1.0\n"
62               << "Copyright (C) 2007 Peter Johansson\n\n"
63               << "This is free software see the source for copying "
64               << "conditions. There is NO\nwarranty; not even for "
65               << "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n";
66     try {
67       cmd.parse(argc, argv);
68     }
69     catch (cmd_error& e){
70       if (version.present()){
71         std::cout << copyright.str();     
72         return EXIT_SUCCESS;
73       }
74       std::cerr << e.what() << std::endl;
75       return EXIT_FAILURE;
76     } 
77     if (version.present()){
78       std::cout << copyright.str();     
79       return EXIT_SUCCESS;
80     }
81     ...
82     \endcode
83
84     After creation a number of Option classes are hooked up to the
85     CommandLine object in their constructors.
86
87     Each parameter is associated to a one-character flag and/or a
88     longer string flag. The longer flag expects to be preceded by
89     '--' as e.g. '--help' for help. The shorter flag expects to be
90     preceded by '-' as e.g. '-h', and can also be concatenated like
91     "program -vf", which is equivalent to "program -v -f". or
92     its sibblings for different types.
93  */
94  class CommandLine
95  {
96  public:
97    /**
98       \brief default constructor
99
100       \param str text preceeding the list of option in output
101    */
102    CommandLine(std::string str="Available options are:");
103
104    /**
105       \brief Destructor
106    */
107    virtual ~CommandLine(void);
108
109    /**
110       \brief Function to add an option.
111    */
112    void add(Option&);
113
114    /**
115       \brief Allow at most \a n free arguments.
116
117       An free argument is an argument not associated with an Option,
118       allowing commandlines such as \code prog foo bar \endcode
119     */
120    void allow_free_args(size_t n);
121
122    /**
123       \brief Arguments not associated with an Option
124
125       \see allow_free_args(size_t n)
126    */
127    const std::vector<std::string>& free_args(void) const;
128
129    /**
130       \brief parse the commandline
131
132       throw cmd_error if an error is detected.
133    */
134    void parse(int argc, char* argv[]);
135
136    /**
137       \brief has the commandline been parsed already
138
139       \return true if parse function has already been called
140
141       \since New in yat 0.5
142    */
143    bool parsed(void) const;
144
145    /**
146       @return Name of more; more specifically argv[0] is
147       stripped so only string after the last '/' remains.
148     */
149    std::string program_name(void) const;
150
151    /**
152       \return something like "Try `<program_name()> --help` for
153       more information."
154     */
155    std::string try_help(void) const;
156
157  private:
158    friend std::ostream& operator<<(std::ostream& os, const CommandLine& cl);
159    void add_private(std::string, Option&);
160    bool is_long_option(std::string str) const;
161    bool is_short_option(std::string str) const;
162    std::vector<std::string> split(std::string str, char del) const;
163
164    std::string description_;
165    std::vector<std::string> free_arg_;
166    size_t free_arg_max_;
167    std::vector<Option*> options_;
168    std::map<char, Option*> short_options_;
169    std::map<std::string, Option*> long_options_;
170    bool parsed_;
171    std::string program_name_;
172  };
173
174  /**
175     \brief CommandLine output operator
176
177     A typical output may look like this
178     \verbatim
179     Available options are:
180     -h, --help      display this help and exit
181     -v, --verbose   explain what is being done
182     \endverbatim
183     The output starts with a descriptive line such as "Available
184     options are:" (default) that can be set in constructor. Then follows the
185     options described in the order they were added to
186     Commandline. Each Option is described according to
187     Option::print(void) function.
188     \see OptionHelp
189
190     \relates CommandLine
191  */
192  std::ostream& operator<<(std::ostream&, const CommandLine&);
193
194}}} // end of namespace utility, yat, and theplu
195
196#endif
Note: See TracBrowser for help on using the repository browser.