1 /* Copyright (C) 2004 The glibmm Development Team
2 *
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public
5 * License as published by the Free Software Foundation; either
6 * version 2.1 of the License, or (at your option) any later version.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #include <glibmm.h>
18 #include <iomanip>
19 #include <iostream>
20
21 class ExampleOptionGroup : public Glib::OptionGroup
22 {
23 public:
24 ExampleOptionGroup();
25
26 private:
27 bool on_pre_parse(Glib::OptionContext& context, Glib::OptionGroup& group) override;
28 bool on_post_parse(Glib::OptionContext& context, Glib::OptionGroup& group) override;
29 void on_error(Glib::OptionContext& context, Glib::OptionGroup& group) override;
30
31 bool on_option_arg_string(
32 const Glib::ustring& option_name, const Glib::ustring& value, bool has_value);
33 bool on_option_arg_filename(
34 const Glib::ustring& option_name, const std::string& value, bool has_value);
35
36 public:
37 // These members should live as long as the OptionGroup to which they are added,
38 // and as long as the OptionContext to which that OptionGroup is added.
39 int m_arg_foo;
40 std::string m_arg_filename;
41 Glib::ustring m_arg_goo;
42 bool m_arg_boolean;
43 Glib::OptionGroup::vecustrings m_arg_list;
44 Glib::OptionGroup::vecustrings m_remaining_list;
45 Glib::ustring m_arg_x_string;
46 Glib::ustring m_arg_x_filename;
47 };
48
ExampleOptionGroup()49 ExampleOptionGroup::ExampleOptionGroup()
50 : Glib::OptionGroup(
51 "example_group", "description of example group", "help description of example group"),
52 m_arg_foo(0),
53 m_arg_boolean(false)
54 {
55 Glib::OptionEntry entry1;
56 entry1.set_long_name("foo");
57 entry1.set_short_name('f');
58 entry1.set_description("The Foo");
59 add_entry(entry1, m_arg_foo);
60
61 Glib::OptionEntry entry2;
62 entry2.set_long_name("file");
63 entry2.set_short_name('F');
64 entry2.set_description("The Filename");
65 add_entry_filename(entry2, m_arg_filename);
66
67 Glib::OptionEntry entry3;
68 entry3.set_long_name("goo");
69 entry3.set_short_name('g');
70 entry3.set_description("The Goo");
71 // We can choose a default to be used if the user doesn't specify
72 // this option.
73 m_arg_goo = "default-goo-value";
74 add_entry(entry3, m_arg_goo);
75
76 Glib::OptionEntry entry4;
77 entry4.set_long_name("activate_something");
78 entry4.set_description("Activate something");
79 add_entry(entry4, m_arg_boolean);
80
81 Glib::OptionEntry entry5;
82 entry5.set_long_name("list");
83 entry5.set_short_name('l');
84 entry5.set_description("A List");
85 add_entry(entry5, m_arg_list);
86
87 Glib::OptionEntry entry6;
88 entry6.set_long_name("x-string");
89 entry6.set_short_name('x');
90 entry6.set_description("A string with custom parsing");
91 entry6.set_flags(Glib::OptionEntry::FLAG_OPTIONAL_ARG);
92 m_arg_x_string = "not specified";
93 add_entry(entry6, sigc::mem_fun(*this, &ExampleOptionGroup::on_option_arg_string));
94
95 Glib::OptionEntry entry7;
96 entry7.set_long_name("x-filename");
97 entry7.set_short_name('X');
98 entry7.set_description("A filename with custom parsing");
99 entry7.set_flags(Glib::OptionEntry::FLAG_OPTIONAL_ARG);
100 m_arg_x_filename = "not specified";
101 add_entry_filename(entry7, sigc::mem_fun(*this, &ExampleOptionGroup::on_option_arg_filename));
102
103 Glib::OptionEntry entry_remaining;
104 entry_remaining.set_long_name(G_OPTION_REMAINING);
105
106 add_entry(entry_remaining, m_remaining_list);
107 }
108
109 bool
on_pre_parse(Glib::OptionContext &,Glib::OptionGroup &)110 ExampleOptionGroup::on_pre_parse(Glib::OptionContext& /* context */, Glib::OptionGroup& /* group */)
111 {
112 // This is called before the m_arg_* instances are given their values.
113 // You do not need to override this method. This is just here to show you how,
114 // in case you want to do any extra processing.
115 std::cout << "on_pre_parse called" << std::endl;
116 return true;
117 }
118
119 bool
on_post_parse(Glib::OptionContext &,Glib::OptionGroup &)120 ExampleOptionGroup::on_post_parse(
121 Glib::OptionContext& /* context */, Glib::OptionGroup& /* group */)
122 {
123 // This is called after the m_arg_* instances are given their values.
124 // You do not need to override this method. This is just here to show you how,
125 // in case you want to do any extra processing.
126 std::cout << "on_post_parse called" << std::endl;
127 return true;
128 }
129
130 void
on_error(Glib::OptionContext &,Glib::OptionGroup &)131 ExampleOptionGroup::on_error(Glib::OptionContext& /* context */, Glib::OptionGroup& /* group */)
132 {
133 std::cout << "on_error called" << std::endl;
134 }
135
136 bool
on_option_arg_string(const Glib::ustring & option_name,const Glib::ustring & value,bool has_value)137 ExampleOptionGroup::on_option_arg_string(
138 const Glib::ustring& option_name, const Glib::ustring& value, bool has_value)
139 {
140 if (option_name != "-x" && option_name != "--x-string")
141 {
142 m_arg_x_string = "on_option_arg_string called with unexpected option_name: " + option_name;
143 throw Glib::OptionError(Glib::OptionError::UNKNOWN_OPTION, m_arg_x_string);
144 }
145
146 if (!has_value)
147 {
148 m_arg_x_string = "no value";
149 return true;
150 }
151
152 if (value.empty())
153 {
154 m_arg_x_string = "empty string";
155 return true;
156 }
157
158 m_arg_x_string = value;
159 if (value == "error")
160 {
161 throw Glib::OptionError(
162 Glib::OptionError::BAD_VALUE, "on_option_arg_string called with value = " + m_arg_x_string);
163 }
164 return value != "false";
165 }
166
167 bool
on_option_arg_filename(const Glib::ustring & option_name,const std::string & value,bool has_value)168 ExampleOptionGroup::on_option_arg_filename(
169 const Glib::ustring& option_name, const std::string& value, bool has_value)
170 {
171 if (option_name != "-X" && option_name != "--x-filename")
172 {
173 m_arg_x_filename = "on_option_arg_filename called with unexpected option_name: " + option_name;
174 throw Glib::OptionError(Glib::OptionError::UNKNOWN_OPTION, m_arg_x_filename);
175 }
176
177 if (!has_value)
178 {
179 m_arg_x_filename = "no value";
180 return true;
181 }
182
183 if (value.empty())
184 {
185 m_arg_x_filename = "empty string";
186 return true;
187 }
188
189 m_arg_x_filename = value;
190 if (value == "error")
191 {
192 throw Glib::OptionError(Glib::OptionError::BAD_VALUE,
193 "on_option_arg_filename called with value = " + m_arg_x_filename);
194 }
195 return value != "false";
196 }
197
198 int
main(int argc,char ** argv)199 main(int argc, char** argv)
200 {
201 // This example should be executed like so:
202 //./example --foo=1 --bar=2 --goo=abc
203 //./example --help
204
205 Glib::init();
206
207 // Set up the current locale.
208 setlocale(LC_ALL, "");
209
210 Glib::OptionContext context;
211
212 ExampleOptionGroup group;
213 context.set_main_group(group);
214
215 try
216 {
217 context.parse(argc, argv);
218 }
219 catch (const Glib::Error& ex)
220 {
221 std::cout << "Exception: " << ex.what() << std::endl;
222 }
223
224 std::cout << "parsed values: " << std::endl
225 << " foo = " << group.m_arg_foo << std::endl
226 << " filename = " << group.m_arg_filename << std::endl
227 << " activate_something = " << (group.m_arg_boolean ? "enabled" : "disabled")
228 << std::endl
229 << " goo = " << group.m_arg_goo << std::endl
230 << " x-string = " << group.m_arg_x_string << std::endl
231 << " x-filename = " << group.m_arg_x_filename << std::endl;
232
233 // This one shows the results of multiple instance of the same option, such as --list=1 --list=a
234 // --list=b
235 std::cout << " list = ";
236 for (const auto& i : group.m_arg_list)
237
238 {
239 std::cout << i << ", ";
240 }
241 std::cout << std::endl;
242
243 // This one shows the remaining arguments on the command line, which had no name= form:
244 std::cout << " remaining = ";
245 for (const auto& i : group.m_remaining_list)
246 {
247 std::cout << i << ", ";
248 }
249 std::cout << std::endl;
250
251 return 0;
252 }
253