comparison modules/options/options.hpp @ 618:1ae8106369e5

Options: initial reimport, closes #705
author David Demelier <markand@malikania.fr>
date Tue, 26 Sep 2017 09:50:02 +0200
parents
children
comparison
equal deleted inserted replaced
617:266f32919d0a 618:1ae8106369e5
1 /*
2 * options.hpp -- parse Unix command line options
3 *
4 * Copyright (c) 2015-2017 David Demelier <markand@malikania.fr>
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19 #ifndef OPTIONS_HPP
20 #define OPTIONS_HPP
21
22 /**
23 * \file options.hpp
24 * \brief Basic Unix options parser.
25 */
26
27 /**
28 * \page options Options parser.
29 *
30 * ## Export macros
31 *
32 * You must define `OPTIONS_DLL` globally and `OPTIONS_BUILDING_DLL` when
33 * compiling the library if you want a DLL, alternatively you can provide your
34 * own `OPTIONS_EXPORT` macro instead.
35 */
36
37 /**
38 * \cond OPTIONS_HIDDEN_SYMBOLS
39 */
40
41 #if !defined(OPTIONS_EXPORT)
42 # if defined(OPTIONS_DLL)
43 # if defined(_WIN32)
44 # if defined(OPTIONS_BUILDING_DLL)
45 # define OPTIONS_EXPORT __declspec(dllexport)
46 # else
47 # define OPTIONS_EXPORT __declspec(dllimport)
48 # endif
49 # else
50 # define OPTIONS_EXPORT
51 # endif
52 # else
53 # define OPTIONS_EXPORT
54 # endif
55 #endif
56
57 /**
58 * \endcond
59 */
60
61 #include <exception>
62 #include <map>
63 #include <string>
64 #include <utility>
65 #include <vector>
66
67 /**
68 * Namespace for options parsing.
69 */
70 namespace option {
71
72 /**
73 * \brief This exception is thrown when an invalid option has been found.
74 */
75 class invalid_option : public std::exception {
76 private:
77 std::string message_;
78 std::string name_;
79
80 public:
81 /**
82 * Construct the exception.
83 *
84 * \param arg the argument missing
85 */
86 inline invalid_option(std::string name)
87 : name_(std::move(name))
88 {
89 message_ = std::string("invalid option: ") + name_;
90 }
91
92 /**
93 * Get the option name.
94 *
95 * \return the name
96 */
97 inline const std::string& name() const noexcept
98 {
99 return name_;
100 }
101
102 /**
103 * Get the error message.
104 *
105 * \return the error message
106 */
107 const char* what() const noexcept override
108 {
109 return message_.c_str();
110 }
111 };
112
113 /**
114 * \brief This exception is thrown when an option requires a value and no value
115 * has been given.
116 */
117 class missing_value : public std::exception {
118 private:
119 std::string message_;
120 std::string name_;
121
122 public:
123 /**
124 * Construct the exception.
125 *
126 * \param name the option that requires a value
127 */
128 inline missing_value(std::string name)
129 : name_(std::move(name))
130 {
131 message_ = std::string("missing argument for: ") + name_;
132 }
133
134 /**
135 * Get the option name.
136 *
137 * \return the name
138 */
139 inline const std::string& name() const noexcept
140 {
141 return name_;
142 }
143
144 /**
145 * Get the error message.
146 *
147 * \return the error message
148 */
149 const char* what() const noexcept override
150 {
151 return message_.c_str();
152 }
153 };
154
155 /**
156 * Packed multimap of options.
157 */
158 using result = std::multimap<std::string, std::string>;
159
160 /**
161 * Define the allowed options.
162 */
163 using options = std::map<std::string, bool>;
164
165 /**
166 * Extract the command line options and return a result.
167 *
168 * \param args the arguments
169 * \param definition
170 * \warning the arguments vector is modified in place to remove parsed options
171 * \throw missing_value
172 * \throw invalid_option
173 */
174 OPTIONS_EXPORT result read(std::vector<std::string>& args, const options& definition);
175
176 /**
177 * Overloaded function for usage with main() arguments.
178 *
179 * \param argc the number of arguments
180 * \param argv the argument vector
181 * \param definition
182 * \note don't forget to remove the first argv[0] argument
183 * \warning the argc and argv are modified in place to remove parsed options
184 * \throw missing_value
185 * \throw invalid_option
186 */
187 OPTIONS_EXPORT result read(int& argc, char**& argv, const options& definition);
188
189 } // !option
190
191 #endif // !OPTIONS_HPP