Mercurial > code
annotate C++/OptionParser.cpp @ 304:bae4af872cde
MFS
author | David Demelier <markand@malikania.fr> |
---|---|
date | Sat, 15 Nov 2014 13:19:30 +0100 |
parents | ff2db0ed78f1 |
children | 99e83685d4da |
rev | line source |
---|---|
229
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
1 /* |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
2 * OptionParser.cpp -- safe getopt(3) replacement |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
3 * |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
4 * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr> |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
5 * |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
6 * Permission to use, copy, modify, and/or distribute this software for any |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
7 * purpose with or without fee is hereby granted, provided that the above |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
8 * copyright notice and this permission notice appear in all copies. |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
9 * |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
17 */ |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
18 |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
19 #include <iostream> |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
20 #include <iomanip> |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
21 |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
22 #include "OptionParser.h" |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
23 |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
24 /* -------------------------------------------------------- |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
25 * Option class |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
26 * -------------------------------------------------------- */ |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
27 |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
28 Option::Option(const std::string &name, const std::string &help, Type type, int flags) |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
29 : m_name(name) |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
30 , m_help(help) |
236 | 31 , m_flags(flags) |
229
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
32 , m_type(type) |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
33 { |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
34 } |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
35 |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
36 const std::string &Option::name() const |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
37 { |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
38 return m_name; |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
39 } |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
40 |
236 | 41 const std::string &Option::token() const |
42 { | |
43 return m_token; | |
44 } | |
45 | |
229
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
46 const std::string &Option::help() const |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
47 { |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
48 return m_help; |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
49 } |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
50 |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
51 Option::Type Option::type() const |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
52 { |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
53 return m_type; |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
54 } |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
55 |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
56 int Option::flags() const |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
57 { |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
58 return m_flags; |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
59 } |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
60 |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
61 /* -------------------------------------------------------- |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
62 * OptionValue class |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
63 * -------------------------------------------------------- */ |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
64 |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
65 OptionValue::OptionValue(const std::string &name) |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
66 : m_name(name) |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
67 , m_enabled(true) |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
68 { |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
69 } |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
70 |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
71 OptionValue::OptionValue(const std::string &name, const std::string &value) |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
72 : m_name(name) |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
73 , m_value(value) |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
74 { |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
75 } |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
76 |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
77 const std::string &OptionValue::name() const |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
78 { |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
79 return m_name; |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
80 } |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
81 |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
82 const std::string &OptionValue::value() const |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
83 { |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
84 return m_value; |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
85 } |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
86 |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
87 OptionValue::operator bool() const |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
88 { |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
89 return m_enabled; |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
90 } |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
91 |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
92 OptionValue::operator std::string() const |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
93 { |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
94 return m_value; |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
95 } |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
96 |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
97 /* -------------------------------------------------------- |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
98 * OptionResult class |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
99 * -------------------------------------------------------- */ |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
100 |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
101 auto OptionResult::begin() -> decltype(m_values.begin()) |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
102 { |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
103 return m_values.begin(); |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
104 } |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
105 |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
106 auto OptionResult::begin() const -> decltype(m_values.begin()) |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
107 { |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
108 return m_values.begin(); |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
109 } |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
110 |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
111 auto OptionResult::cbegin() const -> decltype(m_values.cbegin()) |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
112 { |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
113 return m_values.begin(); |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
114 } |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
115 |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
116 auto OptionResult::end() -> decltype(m_values.end()) |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
117 { |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
118 return m_values.end(); |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
119 } |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
120 |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
121 auto OptionResult::end() const -> decltype(m_values.end()) |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
122 { |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
123 return m_values.end(); |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
124 } |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
125 |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
126 auto OptionResult::cend() const -> decltype(m_values.cend()) |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
127 { |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
128 return m_values.cend(); |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
129 } |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
130 |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
131 int OptionResult::count() const |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
132 { |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
133 return static_cast<int>(m_values.size()); |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
134 } |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
135 |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
136 int OptionResult::total() const |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
137 { |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
138 return m_total; |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
139 } |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
140 |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
141 /* -------------------------------------------------------- |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
142 * OptionParser class |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
143 * -------------------------------------------------------- */ |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
144 |
236 | 145 OptionParser::Args OptionParser::unpack(const Args &args) const |
146 { | |
147 if (m_style != Getopt) | |
148 return args; | |
149 | |
150 Args ret; | |
151 | |
152 for (const auto &s : args) { | |
153 auto length = s.length(); | |
154 | |
155 if (length < 2 || s[0] != '-' || s[1] == '-') { | |
156 ret.push_back(s); | |
157 continue; | |
158 } | |
159 | |
160 for (int i = 1; i < (int)length; ++i) { | |
161 ret.push_back(std::string("-") + std::string(&s[i], 1)); | |
162 } | |
163 } | |
164 | |
165 return ret; | |
166 } | |
167 | |
168 OptionParser::OptionParser(Style style) | |
169 : m_style(style) | |
170 { | |
171 } | |
172 | |
229
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
173 void OptionParser::add(Option &&option) |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
174 { |
236 | 175 const auto &length = option.m_name.size(); |
176 | |
177 if (length > m_maxlength) | |
178 m_maxlength = length; | |
229
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
179 |
236 | 180 /* |
181 * If style is Getopt, we should use a double dash as the long option | |
182 * like --color and a single for short options like -v | |
183 */ | |
184 if (m_style == Getopt) { | |
185 if (length > 1) | |
186 option.m_token = "--" + option.m_name; | |
187 else | |
188 option.m_token = "-" + option.m_name; | |
189 } else | |
190 option.m_token = "/" + option.m_name; | |
229
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
191 |
236 | 192 m_options.emplace(std::make_pair(option.m_token, std::move(option))); |
229
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
193 } |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
194 |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
195 void OptionParser::add(const Option &option) |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
196 { |
236 | 197 add(Option(option)); |
229
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
198 } |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
199 |
236 | 200 OptionResult OptionParser::parse(int argc, const char * const *argv, int flags) |
201 { | |
202 Args args; | |
203 | |
204 for (int i = 0; i < argc; ++i) | |
205 args.push_back(argv[i]); | |
206 | |
207 return parse(args, flags); | |
208 } | |
209 | |
210 OptionResult OptionParser::parse(const Args &argslist, int flags) | |
229
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
211 { |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
212 OptionResult result; |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
213 int i; |
236 | 214 auto args = unpack(argslist); |
215 auto length = args.size(); | |
229
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
216 |
236 | 217 for (i = 0; i < (int)length; ++i) { |
229
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
218 /* Not a valid option at all? */ |
236 | 219 if (m_options.count(args[i]) == 0) { |
220 /* When breaking is enabled we should not emit a warning */ | |
229
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
221 if (flags & Strict) { |
236 | 222 if (!(flags & Silent)) { |
223 log(args[i], args[i] + " is not a valid option"); | |
224 usage(); | |
225 } | |
226 | |
229
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
227 break; |
236 | 228 } else if (flags & BreakNonOption) |
229 break; | |
230 else | |
229
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
231 continue; |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
232 } |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
233 |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
234 /* |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
235 * At this step, we have an option name valid, check if it requires |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
236 * an argument or not. |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
237 */ |
236 | 238 const auto &option = m_options.at(args[i]); |
229
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
239 const auto &name = option.name(); |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
240 auto type = option.type(); |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
241 |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
242 /* |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
243 * Already present and must appears only once? |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
244 */ |
236 | 245 if ((option.flags() & Option::Single) && m_placed.count(name) > 0) { |
229
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
246 if (!(flags & Silent)) { |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
247 log(name, "option " + name + " must appear only once"); |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
248 |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
249 if (flags & Strict) { |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
250 usage(); |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
251 break; |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
252 } |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
253 } else if (flags & Strict) |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
254 break; |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
255 } |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
256 |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
257 /* |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
258 * Need an argument or it is a simple switch ? |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
259 */ |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
260 if (type == Option::Type::Switch) |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
261 result.m_values.push_back(OptionValue(name)); |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
262 else { |
236 | 263 if (i + 1 >= (int)length) |
229
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
264 result.m_values.push_back(OptionValue(name, "")); |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
265 else { |
236 | 266 result.m_values.push_back(OptionValue(name, args[i + 1])); |
229
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
267 ++ i; |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
268 } |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
269 } |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
270 |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
271 m_placed.insert(name); |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
272 } |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
273 |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
274 result.m_total = i; |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
275 |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
276 return result; |
236 | 277 |
229
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
278 } |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
279 |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
280 void OptionParser::usage() |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
281 { |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
282 std::cout << "options available: " << std::endl; |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
283 |
236 | 284 for (const auto &option : m_options) { |
285 std::cout << " " << std::setw(m_maxlength) << option.second.name(); | |
286 std::cout << "\t" << option.second.help() << std::endl; | |
287 } | |
229
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
288 } |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
289 |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
290 void OptionParser::log(const std::string &, const std::string &error) |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
291 { |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
292 std::cout << error << std::endl; |
96ff112d05cf
Add OptionParser, getopt(3) replacement
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
293 } |