Line data Source code
1 : // Copyright (c) 2006-2025 Made to Order Software Corp. All Rights Reserved
2 : //
3 : // https://snapwebsites.org/project/advgetopt
4 : // contact@m2osw.com
5 : //
6 : // This program is free software; you can redistribute it and/or modify
7 : // it under the terms of the GNU General Public License as published by
8 : // the Free Software Foundation; either version 2 of the License, or
9 : // (at your option) any later version.
10 : //
11 : // This program is distributed in the hope that it will be useful,
12 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : // GNU General Public License for more details.
15 : //
16 : // You should have received a copy of the GNU General Public License along
17 : // with this program; if not, write to the Free Software Foundation, Inc.,
18 : // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 :
20 : // advgetopt
21 : //
22 : #include <advgetopt/exception.h>
23 :
24 :
25 : // self
26 : //
27 : #include "catch_main.h"
28 :
29 :
30 : // snapdev
31 : //
32 : #include <snapdev/safe_setenv.h>
33 :
34 :
35 : // C++
36 : //
37 : #include <fstream>
38 :
39 :
40 : // C
41 : //
42 : #include <unistd.h>
43 :
44 :
45 : // last include
46 : //
47 : #include <snapdev/poison.h>
48 :
49 :
50 :
51 :
52 :
53 :
54 :
55 9 : CATCH_TEST_CASE("configuration_filenames", "[config][getopt][filenames]")
56 : {
57 9 : CATCH_START_SECTION("configuration_filenames: configuration Files")
58 : {
59 5 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("unittest-any", "any");
60 :
61 1 : advgetopt::options_environment environment_options;
62 :
63 1 : char const * confs[] =
64 : {
65 1 : SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
66 : ".config/file.mdi",
67 : "/etc/snapwebsites/server.conf",
68 : nullptr
69 1 : };
70 :
71 1 : environment_options.f_project_name = "unittest-any";
72 1 : environment_options.f_options = nullptr;
73 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
74 1 : environment_options.f_help_header = "Testing all possible filenames";
75 1 : environment_options.f_configuration_files = confs;
76 :
77 1 : advgetopt::getopt opt(environment_options);
78 :
79 1 : advgetopt::string_list_t const filenames(opt.get_configuration_filenames(false, false));
80 :
81 1 : CATCH_REQUIRE(filenames.size() == 6);
82 1 : CATCH_REQUIRE(filenames[0] == SNAP_CATCH2_NAMESPACE::g_config_filename);
83 1 : CATCH_REQUIRE(filenames[1] == SNAP_CATCH2_NAMESPACE::g_config_project_filename);
84 1 : CATCH_REQUIRE(filenames[2] == ".config/file.mdi");
85 1 : CATCH_REQUIRE(filenames[3] == ".config/unittest-any.d/50-file.mdi");
86 1 : CATCH_REQUIRE(filenames[4] == "/etc/snapwebsites/server.conf");
87 1 : CATCH_REQUIRE(filenames[5] == "/etc/snapwebsites/unittest-any.d/50-server.conf");
88 1 : }
89 9 : CATCH_END_SECTION()
90 :
91 9 : CATCH_START_SECTION("configuration_filenames: configuration Files (writable)")
92 : {
93 5 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("unittest-writable", "writable");
94 :
95 1 : advgetopt::options_environment environment_options;
96 :
97 1 : char const * confs[] =
98 : {
99 : ".config/file.mdi",
100 1 : SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
101 : "/etc/snapwebsites/server.conf",
102 : nullptr
103 1 : };
104 :
105 1 : environment_options.f_project_name = "unittest-writable";
106 1 : environment_options.f_options = nullptr;
107 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
108 1 : environment_options.f_help_header = "Testing all possible filenames";
109 1 : environment_options.f_configuration_files = confs;
110 :
111 1 : advgetopt::getopt opt(environment_options);
112 :
113 1 : advgetopt::string_list_t const filenames(opt.get_configuration_filenames(false, true));
114 :
115 1 : CATCH_REQUIRE(filenames.size() == 3);
116 1 : CATCH_REQUIRE(filenames[0] == ".config/unittest-writable.d/50-file.mdi");
117 1 : CATCH_REQUIRE(filenames[1] == SNAP_CATCH2_NAMESPACE::g_config_project_filename);
118 1 : CATCH_REQUIRE(filenames[2] == "/etc/snapwebsites/unittest-writable.d/50-server.conf");
119 1 : }
120 9 : CATCH_END_SECTION()
121 :
122 9 : CATCH_START_SECTION("configuration_filenames: configuration file + directories")
123 : {
124 5 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("unittest-with-directories", "with-dirs", true);
125 :
126 1 : advgetopt::options_environment environment_options;
127 :
128 1 : char const * dirs[] =
129 : {
130 1 : SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
131 : ".config",
132 : "/etc/snapwebsites",
133 : nullptr
134 1 : };
135 :
136 1 : environment_options.f_project_name = "unittest-with-directories";
137 1 : environment_options.f_options = nullptr;
138 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
139 1 : environment_options.f_help_header = "Testing all possible filenames";
140 1 : environment_options.f_configuration_filename = "snapfirewall.conf";
141 1 : environment_options.f_configuration_directories = dirs;
142 :
143 1 : advgetopt::getopt opt(environment_options);
144 :
145 1 : advgetopt::string_list_t const filenames(opt.get_configuration_filenames(false, false));
146 :
147 1 : CATCH_REQUIRE(filenames.size() == 6);
148 1 : CATCH_REQUIRE(filenames[0] == SNAP_CATCH2_NAMESPACE::g_config_filename + "/snapfirewall.conf");
149 1 : CATCH_REQUIRE(filenames[1] == SNAP_CATCH2_NAMESPACE::g_config_project_filename + "/50-snapfirewall.conf");
150 1 : CATCH_REQUIRE(filenames[2] == ".config/snapfirewall.conf");
151 1 : CATCH_REQUIRE(filenames[3] == ".config/unittest-with-directories.d/50-snapfirewall.conf");
152 1 : CATCH_REQUIRE(filenames[4] == "/etc/snapwebsites/snapfirewall.conf");
153 1 : CATCH_REQUIRE(filenames[5] == "/etc/snapwebsites/unittest-with-directories.d/50-snapfirewall.conf");
154 1 : }
155 9 : CATCH_END_SECTION()
156 :
157 9 : CATCH_START_SECTION("configuration_filenames: configuration file + directories + '--config-dir'")
158 : {
159 5 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("unittest-with-directories-and-config-dir", "with-many-dirs", true);
160 :
161 1 : advgetopt::options_environment environment_options;
162 :
163 1 : char const * dirs[] =
164 : {
165 1 : SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
166 : ".config",
167 : "/etc/advgetopt",
168 : nullptr
169 1 : };
170 :
171 1 : environment_options.f_project_name = "unittest-with-directories-and-config-dir";
172 1 : environment_options.f_options = nullptr;
173 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
174 1 : environment_options.f_help_header = "Testing all possible filenames";
175 1 : environment_options.f_configuration_filename = "snapmerger.conf";
176 1 : environment_options.f_configuration_directories = dirs;
177 :
178 1 : char const * cargv[] =
179 : {
180 : "/usr/bin/config",
181 : "--config-dir",
182 : "/var/lib/advgetopt",
183 : "--config-dir",
184 : "/opt/config",
185 : nullptr
186 : };
187 1 : int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
188 1 : char ** argv = const_cast<char **>(cargv);
189 :
190 1 : advgetopt::getopt opt(environment_options, argc, argv);
191 :
192 1 : advgetopt::string_list_t const filenames(opt.get_configuration_filenames(false, false));
193 :
194 1 : CATCH_REQUIRE(filenames.size() == 10);
195 1 : CATCH_REQUIRE(filenames[0] == "/var/lib/advgetopt/snapmerger.conf");
196 1 : CATCH_REQUIRE(filenames[1] == "/var/lib/advgetopt/unittest-with-directories-and-config-dir.d/50-snapmerger.conf");
197 1 : CATCH_REQUIRE(filenames[2] == "/opt/config/snapmerger.conf");
198 1 : CATCH_REQUIRE(filenames[3] == "/opt/config/unittest-with-directories-and-config-dir.d/50-snapmerger.conf");
199 1 : CATCH_REQUIRE(filenames[4] == SNAP_CATCH2_NAMESPACE::g_config_filename + "/snapmerger.conf");
200 1 : CATCH_REQUIRE(filenames[5] == SNAP_CATCH2_NAMESPACE::g_config_project_filename + "/50-snapmerger.conf");
201 1 : CATCH_REQUIRE(filenames[6] == ".config/snapmerger.conf");
202 1 : CATCH_REQUIRE(filenames[7] == ".config/unittest-with-directories-and-config-dir.d/50-snapmerger.conf");
203 1 : CATCH_REQUIRE(filenames[8] == "/etc/advgetopt/snapmerger.conf");
204 1 : CATCH_REQUIRE(filenames[9] == "/etc/advgetopt/unittest-with-directories-and-config-dir.d/50-snapmerger.conf");
205 1 : }
206 9 : CATCH_END_SECTION()
207 :
208 9 : CATCH_START_SECTION("configuration_filenames: existing configuration files")
209 : {
210 5 : CATCH_WHEN("R/W Config must exist--no user defined config")
211 : {
212 5 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("unittest-must-exist", "must-be-here");
213 :
214 : {
215 1 : std::ofstream config_file;
216 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
217 1 : CATCH_REQUIRE(config_file.good());
218 : config_file <<
219 : "# Auto-generated\n"
220 : "ip=192.168.0.1\n"
221 1 : "wall=iptables\n"
222 : ;
223 1 : }
224 :
225 1 : unlink(SNAP_CATCH2_NAMESPACE::g_config_project_filename.c_str());
226 :
227 1 : char const * confs[] =
228 : {
229 1 : SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
230 : ".config/file-which-was-never-created.mdi",
231 : "/etc/snapwebsites/not-an-existing-file.conf",
232 : nullptr
233 1 : };
234 :
235 1 : advgetopt::options_environment environment_options;
236 1 : environment_options.f_project_name = "unittest";
237 1 : environment_options.f_options = nullptr;
238 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
239 1 : environment_options.f_help_header = "Testing all possible filenames";
240 1 : environment_options.f_configuration_files = confs;
241 :
242 1 : advgetopt::getopt opt(environment_options);
243 :
244 1 : advgetopt::string_list_t const filenames(opt.get_configuration_filenames(true, false));
245 :
246 1 : CATCH_REQUIRE(filenames.size() == 1);
247 1 : CATCH_REQUIRE(filenames[0] == SNAP_CATCH2_NAMESPACE::g_config_filename);
248 6 : }
249 :
250 5 : CATCH_WHEN("R/W Config must exist--user defined config exists")
251 : {
252 5 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("unittest-user-exist", "existing");
253 :
254 : {
255 1 : std::ofstream config_file;
256 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
257 1 : CATCH_REQUIRE(config_file.good());
258 : config_file <<
259 : "# Auto-generated\n"
260 : "block-ip=192.168.6.11\n"
261 1 : "firewall=iptables\n"
262 : ;
263 1 : }
264 :
265 : {
266 1 : std::ofstream config_file;
267 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_project_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
268 1 : CATCH_REQUIRE(config_file.good());
269 : config_file <<
270 : "# Auto-generated\n"
271 : "ip=10.0.2.5\n"
272 1 : "duration=6h\n"
273 : ;
274 1 : }
275 :
276 1 : char const * confs[] =
277 : {
278 : ".config/file-which-was-never-created.mdi",
279 : "/etc/snapwebsites/not-an-existing-file.conf",
280 1 : SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
281 : nullptr
282 1 : };
283 :
284 1 : advgetopt::options_environment environment_options;
285 1 : environment_options.f_project_name = "unittest-user-exist";
286 1 : environment_options.f_options = nullptr;
287 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
288 1 : environment_options.f_help_header = "Testing all possible filenames";
289 1 : environment_options.f_configuration_files = confs;
290 :
291 1 : advgetopt::getopt opt(environment_options);
292 :
293 1 : advgetopt::string_list_t const filenames(opt.get_configuration_filenames(true, false));
294 :
295 1 : CATCH_REQUIRE(filenames.size() == 2);
296 1 : CATCH_REQUIRE(filenames[0] == SNAP_CATCH2_NAMESPACE::g_config_filename);
297 1 : CATCH_REQUIRE(filenames[1] == SNAP_CATCH2_NAMESPACE::g_config_project_filename);
298 6 : }
299 :
300 5 : CATCH_WHEN("Writable Config must exist--user defined config exists")
301 : {
302 5 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("unittest-writable-exist", "present");
303 :
304 : {
305 1 : std::ofstream config_file;
306 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
307 1 : CATCH_REQUIRE(config_file.good());
308 : config_file <<
309 : "# Auto-generated\n"
310 : "block-ip=192.168.6.11\n"
311 1 : "firewall=iptables\n"
312 : ;
313 1 : }
314 :
315 : {
316 1 : std::ofstream config_file;
317 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_project_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
318 1 : CATCH_REQUIRE(config_file.good());
319 : config_file <<
320 : "# Auto-generated\n"
321 : "ip=10.0.2.5\n"
322 1 : "duration=6h\n"
323 : ;
324 1 : }
325 :
326 1 : char const * confs[] =
327 : {
328 : ".config/file-which-was-never-created.mdi",
329 1 : SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
330 : "/etc/snapwebsites/not/an-existing-file.conf",
331 : nullptr
332 1 : };
333 :
334 1 : advgetopt::options_environment environment_options;
335 1 : environment_options.f_project_name = "unittest-writable-exist";
336 1 : environment_options.f_options = nullptr;
337 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
338 1 : environment_options.f_help_header = "Testing all possible filenames";
339 1 : environment_options.f_configuration_files = confs;
340 :
341 1 : advgetopt::getopt opt(environment_options);
342 :
343 1 : advgetopt::string_list_t const filenames(opt.get_configuration_filenames(true, true));
344 :
345 1 : CATCH_REQUIRE(filenames.size() == 1);
346 1 : CATCH_REQUIRE(filenames[0] == SNAP_CATCH2_NAMESPACE::g_config_project_filename);
347 6 : }
348 :
349 5 : CATCH_WHEN("Writable Config must exist--user defined config exists and we test with a user folder")
350 : {
351 5 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("unittest-writable-user", "user-write");
352 :
353 : {
354 1 : std::ofstream config_file;
355 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
356 1 : CATCH_REQUIRE(config_file.good());
357 : config_file <<
358 : "# Auto-generated\n"
359 : "block-ip=192.168.6.11\n"
360 1 : "firewall=iptables\n"
361 : ;
362 1 : }
363 :
364 : {
365 1 : std::ofstream config_file;
366 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_project_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
367 1 : CATCH_REQUIRE(config_file.good());
368 : config_file <<
369 : "# Auto-generated\n"
370 : "ip=10.0.2.5\n"
371 1 : "duration=6h\n"
372 : ;
373 1 : }
374 :
375 1 : char const * confs[] =
376 : {
377 : "~/.config/file-which-was-never-created.mdi",
378 1 : SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
379 : "/etc/snapwebsites/not/an-existing-file.conf",
380 : nullptr
381 1 : };
382 :
383 1 : advgetopt::options_environment environment_options;
384 1 : environment_options.f_project_name = "unittest-writable-user";
385 1 : environment_options.f_options = nullptr;
386 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
387 1 : environment_options.f_help_header = "Testing all possible filenames";
388 1 : environment_options.f_configuration_files = confs;
389 :
390 1 : advgetopt::getopt opt(environment_options);
391 :
392 1 : advgetopt::string_list_t const filenames(opt.get_configuration_filenames(true, true));
393 :
394 1 : CATCH_REQUIRE(filenames.size() == 1);
395 1 : CATCH_REQUIRE(filenames[0] == SNAP_CATCH2_NAMESPACE::g_config_project_filename);
396 6 : }
397 :
398 5 : CATCH_WHEN("R/W Config test must exist--user defined config exists and we test with a user folder")
399 : {
400 5 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("unittest-user-folder", "tilde");
401 :
402 1 : std::string tmpdir(SNAP_CATCH2_NAMESPACE::g_tmp_dir());
403 1 : tmpdir += "/.config/home-that-never-gets-created";
404 3 : snapdev::safe_setenv env("HOME", tmpdir);
405 :
406 : {
407 1 : std::ofstream config_file;
408 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_project_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
409 1 : CATCH_REQUIRE(config_file.good());
410 : config_file <<
411 : "# Auto-generated\n"
412 : "ip=10.0.2.5\n"
413 1 : "duration=6h\n"
414 : ;
415 1 : }
416 :
417 1 : char const * dirs[] =
418 : {
419 : "~/.config/folder-which-was-never-created",
420 : "/etc/snapwebsites/not-an-existing-folder",
421 1 : SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
422 : nullptr
423 1 : };
424 :
425 1 : advgetopt::options_environment environment_options;
426 1 : environment_options.f_project_name = "unittest-user-folder";
427 1 : environment_options.f_options = nullptr;
428 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
429 1 : environment_options.f_help_header = "Testing all possible filenames";
430 1 : environment_options.f_configuration_filename = "snapfirewall.conf";
431 1 : environment_options.f_configuration_directories = dirs;
432 :
433 1 : advgetopt::getopt opt(environment_options);
434 :
435 1 : advgetopt::string_list_t const filenames(opt.get_configuration_filenames(false, false));
436 :
437 1 : CATCH_REQUIRE(filenames.size() == 5);
438 1 : CATCH_REQUIRE(filenames[0] == tmpdir + "/.config/folder-which-was-never-created/snapfirewall.conf");
439 1 : CATCH_REQUIRE(filenames[1] == "/etc/snapwebsites/not-an-existing-folder/snapfirewall.conf");
440 1 : CATCH_REQUIRE(filenames[2] == "/etc/snapwebsites/not-an-existing-folder/unittest-user-folder.d/50-snapfirewall.conf");
441 1 : CATCH_REQUIRE(filenames[3] == SNAP_CATCH2_NAMESPACE::g_config_filename + "/snapfirewall.conf");
442 1 : CATCH_REQUIRE(filenames[4] == SNAP_CATCH2_NAMESPACE::g_config_filename + "/unittest-user-folder.d/50-snapfirewall.conf");
443 6 : }
444 : }
445 9 : CATCH_END_SECTION()
446 9 : }
447 :
448 :
449 :
450 3 : CATCH_TEST_CASE("load_configuration_file", "[config][getopt][filenames]")
451 : {
452 3 : CATCH_START_SECTION("load_configuration_file: load a configuration file")
453 : {
454 5 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("load", "tool");
455 :
456 : {
457 1 : std::ofstream config_file;
458 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
459 1 : CATCH_REQUIRE(config_file.good());
460 : config_file <<
461 : "# Auto-generated\n"
462 : "sizes=132\n"
463 1 : "filenames=green,orange,blue brown white\n"
464 : ;
465 1 : }
466 :
467 1 : char const * confs[] =
468 : {
469 : "~/.config/file-which-was-never-created.mdi",
470 1 : SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
471 : "/etc/snapwebsites/not/an-existing-file.conf",
472 : nullptr
473 1 : };
474 :
475 1 : char const * const separators[] {
476 : ",",
477 : " ",
478 : nullptr
479 : };
480 :
481 1 : advgetopt::option const options[] =
482 : {
483 : advgetopt::define_option(
484 : advgetopt::Name("sizes")
485 : , advgetopt::ShortName('s')
486 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
487 : , advgetopt::Help("sizes.")
488 : ),
489 5 : advgetopt::define_option(
490 : advgetopt::Name("filenames")
491 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED, advgetopt::GETOPT_FLAG_MULTIPLE>())
492 : , advgetopt::Help("enter a list of filenames.")
493 : , advgetopt::DefaultValue("a.out")
494 : , advgetopt::Separators(separators)
495 : ),
496 : advgetopt::end_options()
497 5 : };
498 :
499 1 : advgetopt::options_environment environment_options;
500 1 : environment_options.f_project_name = "load";
501 1 : environment_options.f_options = options;
502 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
503 1 : environment_options.f_help_header = "Testing loading a filenames";
504 1 : environment_options.f_configuration_files = confs;
505 :
506 1 : advgetopt::getopt opt(environment_options);
507 :
508 1 : opt.process_configuration_file(SNAP_CATCH2_NAMESPACE::g_config_filename);
509 :
510 3 : CATCH_REQUIRE(opt.size("sizes") == 1);
511 3 : CATCH_REQUIRE(opt.get_string("sizes") == "132");
512 :
513 3 : CATCH_REQUIRE(opt.size("filenames") == 5);
514 3 : CATCH_REQUIRE(opt.get_string("filenames") == "green");
515 3 : CATCH_REQUIRE(opt.get_string("filenames", 0) == "green");
516 3 : CATCH_REQUIRE(opt.get_string("filenames", 1) == "orange");
517 3 : CATCH_REQUIRE(opt.get_string("filenames", 2) == "blue");
518 3 : CATCH_REQUIRE(opt.get_string("filenames", 3) == "brown");
519 3 : CATCH_REQUIRE(opt.get_string("filenames", 4) == "white");
520 1 : }
521 3 : CATCH_END_SECTION()
522 :
523 3 : CATCH_START_SECTION("load_configuration_file: load an extended configuration file")
524 : {
525 5 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("load-extended", "extended");
526 :
527 : {
528 1 : std::ofstream config_file;
529 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
530 1 : CATCH_REQUIRE(config_file.good());
531 : config_file <<
532 : "# Auto-generated\n"
533 : "sizes=132\n"
534 : "object=property.obj\n"
535 : "filenames=green,orange,blue brown white\n"
536 1 : "visibility=hidden\n"
537 : ;
538 1 : }
539 :
540 1 : char const * confs[] =
541 : {
542 : "~/.config/file-which-was-never-created.mdi",
543 1 : SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
544 : "/etc/snapwebsites/not/an-existing-file.conf",
545 : nullptr
546 1 : };
547 :
548 1 : char const * const separators[] {
549 : ",",
550 : " ",
551 : nullptr
552 : };
553 :
554 1 : advgetopt::option const options[] =
555 : {
556 : advgetopt::define_option(
557 : advgetopt::Name("sizes")
558 : , advgetopt::ShortName('s')
559 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
560 : , advgetopt::Help("sizes.")
561 : ),
562 6 : advgetopt::define_option(
563 : advgetopt::Name("filenames")
564 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED, advgetopt::GETOPT_FLAG_MULTIPLE>())
565 : , advgetopt::Help("enter a list of filenames.")
566 : , advgetopt::DefaultValue("a.out")
567 : , advgetopt::Separators(separators)
568 : ),
569 : advgetopt::end_options()
570 6 : };
571 :
572 1 : advgetopt::options_environment environment_options;
573 1 : environment_options.f_project_name = "load-extended";
574 1 : environment_options.f_options = options;
575 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS | advgetopt::GETOPT_ENVIRONMENT_FLAG_DYNAMIC_PARAMETERS;
576 1 : environment_options.f_help_header = "Testing loading filenames";
577 1 : environment_options.f_configuration_files = confs;
578 :
579 1 : advgetopt::getopt opt(environment_options);
580 :
581 1 : opt.process_configuration_file(SNAP_CATCH2_NAMESPACE::g_config_filename);
582 :
583 3 : CATCH_REQUIRE(opt.size("sizes") == 1);
584 3 : CATCH_REQUIRE(opt.get_string("sizes") == "132");
585 :
586 3 : CATCH_REQUIRE(opt.size("filenames") == 5);
587 3 : CATCH_REQUIRE(opt.get_string("filenames") == "green");
588 3 : CATCH_REQUIRE(opt.get_string("filenames", 0) == "green");
589 3 : CATCH_REQUIRE(opt.get_string("filenames", 1) == "orange");
590 3 : CATCH_REQUIRE(opt.get_string("filenames", 2) == "blue");
591 3 : CATCH_REQUIRE(opt.get_string("filenames", 3) == "brown");
592 3 : CATCH_REQUIRE(opt.get_string("filenames", 4) == "white");
593 :
594 3 : CATCH_REQUIRE(opt.size("object") == 1);
595 3 : CATCH_REQUIRE(opt.get_string("object") == "property.obj");
596 :
597 3 : CATCH_REQUIRE(opt.size("visibility") == 1);
598 3 : CATCH_REQUIRE(opt.get_string("visibility") == "hidden");
599 1 : }
600 3 : CATCH_END_SECTION()
601 :
602 3 : CATCH_START_SECTION("load_configuration_file: load a configuration file with sections")
603 : {
604 5 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("load-with-sections", "sections");
605 :
606 : {
607 1 : std::ofstream config_file;
608 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
609 1 : CATCH_REQUIRE(config_file.good());
610 : config_file <<
611 : "# Auto-generated\n"
612 : "\n"
613 : "[integers]\n"
614 : "sizes=132\n"
615 : "\n"
616 : "[objects]\n"
617 : "object=property.obj\n"
618 : "filenames=green orange blue brown white\n"
619 : "\n"
620 : "[flags]\n"
621 : "visibility=hidden\n"
622 : "\n"
623 : "[integers]\n"
624 : "max=1111\n"
625 : "\n"
626 1 : "# vim: ts=4 sw=4 et\n"
627 : ;
628 1 : }
629 :
630 1 : char const * confs[] =
631 : {
632 : "~/.config/file-which-was-never-created.mdi",
633 1 : SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
634 : "/etc/snapwebsites/not/an-existing-file.conf",
635 : nullptr
636 1 : };
637 :
638 1 : char const * const separators[] {
639 : ",",
640 : " ",
641 : nullptr
642 : };
643 :
644 1 : advgetopt::option const options[] =
645 : {
646 : advgetopt::define_option(
647 : advgetopt::Name("objects::object")
648 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
649 : , advgetopt::Help("object.")
650 : ),
651 : advgetopt::define_option(
652 : advgetopt::Name("integers::sizes")
653 : , advgetopt::ShortName('s')
654 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
655 : , advgetopt::Help("sizes.")
656 : ),
657 6 : advgetopt::define_option(
658 : advgetopt::Name("objects::filenames")
659 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED, advgetopt::GETOPT_FLAG_MULTIPLE>())
660 : , advgetopt::Help("enter a list of filenames.")
661 : , advgetopt::DefaultValue("a.out")
662 : , advgetopt::Separators(separators)
663 : ),
664 : advgetopt::define_option(
665 : advgetopt::Name("integers::max")
666 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
667 : , advgetopt::Help("maximum value.")
668 : , advgetopt::DefaultValue("+oo")
669 : ),
670 : advgetopt::define_option(
671 : advgetopt::Name("flags::visibility")
672 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
673 : , advgetopt::Help("visibility.")
674 : , advgetopt::DefaultValue("flashy")
675 : ),
676 : advgetopt::end_options()
677 6 : };
678 :
679 1 : advgetopt::options_environment environment_options;
680 1 : environment_options.f_project_name = "load-sections";
681 1 : environment_options.f_options = options;
682 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
683 1 : environment_options.f_help_header = "Testing loading sections";
684 1 : environment_options.f_configuration_files = confs;
685 :
686 1 : advgetopt::getopt opt(environment_options);
687 :
688 1 : opt.process_configuration_file(SNAP_CATCH2_NAMESPACE::g_config_filename);
689 :
690 3 : CATCH_REQUIRE(opt.size("integers::sizes") == 1);
691 3 : CATCH_REQUIRE(opt.get_string("integers::sizes") == "132");
692 :
693 3 : CATCH_REQUIRE(opt.size("objects::filenames") == 5);
694 3 : CATCH_REQUIRE(opt.get_string("objects::filenames") == "green");
695 3 : CATCH_REQUIRE(opt.get_string("objects::filenames", 0) == "green");
696 3 : CATCH_REQUIRE(opt.get_string("objects::filenames", 1) == "orange");
697 3 : CATCH_REQUIRE(opt.get_string("objects::filenames", 2) == "blue");
698 3 : CATCH_REQUIRE(opt.get_string("objects::filenames", 3) == "brown");
699 3 : CATCH_REQUIRE(opt.get_string("objects::filenames", 4) == "white");
700 :
701 3 : CATCH_REQUIRE(opt.size("integers::max") == 1);
702 3 : CATCH_REQUIRE(opt.get_string("integers::max") == "1111");
703 :
704 3 : CATCH_REQUIRE(opt.size("objects::object") == 1);
705 3 : CATCH_REQUIRE(opt.get_string("objects::object") == "property.obj");
706 :
707 3 : CATCH_REQUIRE(opt.size("flags::visibility") == 1);
708 3 : CATCH_REQUIRE(opt.get_string("flags::visibility") == "hidden");
709 :
710 3 : std::string const name(advgetopt::CONFIGURATION_SECTIONS);
711 1 : CATCH_REQUIRE(opt.size(name) == 3);
712 1 : CATCH_REQUIRE(opt.get_string(name) == "flags");
713 1 : CATCH_REQUIRE(opt.get_string(name, 0) == "flags");
714 1 : CATCH_REQUIRE(opt.get_string(name, 1) == "integers");
715 1 : CATCH_REQUIRE(opt.get_string(name, 2) == "objects");
716 1 : }
717 3 : CATCH_END_SECTION()
718 3 : }
719 :
720 :
721 :
722 2 : CATCH_TEST_CASE("load_multiple_configurations", "[config][getopt][filenames]")
723 : {
724 2 : CATCH_START_SECTION("load_multiple_configurations: configuration files")
725 : {
726 5 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("multiple", "multiplicity");
727 :
728 1 : advgetopt::options_environment environment_options;
729 :
730 1 : std::string tmpdir(SNAP_CATCH2_NAMESPACE::g_tmp_dir());
731 1 : tmpdir += "/.config/home";
732 :
733 1 : std::stringstream ss;
734 1 : ss << "mkdir -p " << tmpdir;
735 1 : if(system(ss.str().c_str()) != 0)
736 : {
737 0 : std::cerr << "fatal error: creating sub-temporary directory \"" << tmpdir << "\" failed.\n";
738 0 : exit(1);
739 : }
740 :
741 3 : snapdev::safe_setenv env("HOME", tmpdir);
742 :
743 : {
744 1 : std::ofstream config_file;
745 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
746 1 : CATCH_REQUIRE(config_file.good());
747 : config_file <<
748 : "# Auto-generated\n"
749 : "ip=10.0.2.5\n"
750 : "duration=6h\n"
751 : "size=604\n"
752 : "gap=6\n"
753 1 : "filename=utf9.txt\n"
754 : ;
755 1 : }
756 :
757 : {
758 1 : std::ofstream config_file;
759 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_project_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
760 1 : CATCH_REQUIRE(config_file.good());
761 : config_file <<
762 : "# Auto-generated\n"
763 : "ip=10.1.7.205\n"
764 : "gap=9\n"
765 1 : "filename=utf7.txt\n"
766 : ;
767 1 : }
768 :
769 : {
770 1 : std::ofstream config_file;
771 1 : config_file.open(tmpdir + "/advgetopt.conf", std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
772 1 : CATCH_REQUIRE(config_file.good());
773 : config_file <<
774 : "# Auto-generated\n"
775 : "duration=105min\n"
776 1 : "filename=utf8.txt\n"
777 : ;
778 1 : }
779 :
780 1 : char const * confs[] =
781 : {
782 1 : SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
783 1 : SNAP_CATCH2_NAMESPACE::g_config_project_filename.c_str(),
784 : "~/advgetopt.conf",
785 : nullptr
786 1 : };
787 :
788 1 : advgetopt::option const options[] =
789 : {
790 : advgetopt::define_option(
791 : advgetopt::Name("size")
792 : , advgetopt::ShortName('s')
793 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
794 : , advgetopt::Help("size.")
795 : ),
796 : advgetopt::define_option(
797 : advgetopt::Name("filename")
798 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED, advgetopt::GETOPT_FLAG_MULTIPLE>())
799 : , advgetopt::Help("enter a filenames.")
800 : , advgetopt::DefaultValue("a.out")
801 : ),
802 : advgetopt::define_option(
803 : advgetopt::Name("duration")
804 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
805 : , advgetopt::Help("how long it lasts.")
806 : ),
807 : advgetopt::define_option(
808 : advgetopt::Name("gap")
809 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
810 : , advgetopt::Help("gap size.")
811 : ),
812 : advgetopt::define_option(
813 : advgetopt::Name("ip")
814 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
815 : , advgetopt::Help("enter the ip address.")
816 : ),
817 : advgetopt::end_options()
818 : };
819 :
820 1 : environment_options.f_project_name = "unittest";
821 1 : environment_options.f_options = options;
822 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
823 1 : environment_options.f_help_header = "Testing a load with multiple filenames and see that we get the latest";
824 1 : environment_options.f_configuration_files = confs;
825 :
826 1 : advgetopt::getopt opt(environment_options);
827 :
828 1 : opt.parse_configuration_files(0, nullptr);
829 :
830 3 : CATCH_REQUIRE(opt.size("size") == 1);
831 3 : CATCH_REQUIRE(opt.get_string("size") == "604");
832 :
833 : // although it is marked as multiple, the old entries are still
834 : // overwritten with newer versions; if the last entry had multiple
835 : // filenames, then we'd get get multiple names here
836 : //
837 3 : CATCH_REQUIRE(opt.size("filename") == 1);
838 3 : CATCH_REQUIRE(opt.get_string("filename", 0) == "utf8.txt");
839 :
840 3 : CATCH_REQUIRE(opt.size("duration") == 1);
841 3 : CATCH_REQUIRE(opt.get_string("duration") == "105min");
842 :
843 3 : CATCH_REQUIRE(opt.size("gap") == 1);
844 3 : CATCH_REQUIRE(opt.get_string("gap") == "9");
845 :
846 3 : CATCH_REQUIRE(opt.size("ip") == 1);
847 3 : CATCH_REQUIRE(opt.get_string("ip") == "10.1.7.205");
848 1 : }
849 2 : CATCH_END_SECTION()
850 :
851 2 : CATCH_START_SECTION("load_multiple_configurations: configuration files with sections")
852 : {
853 5 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("multiple-with-sections", "multiplicity-with-sections");
854 :
855 1 : advgetopt::options_environment environment_options;
856 :
857 1 : std::string tmpdir(SNAP_CATCH2_NAMESPACE::g_tmp_dir());
858 1 : tmpdir += "/.config/home2";
859 :
860 1 : std::stringstream ss;
861 1 : ss << "mkdir -p " << tmpdir;
862 1 : if(system(ss.str().c_str()) != 0)
863 : {
864 0 : std::cerr << "fatal error: creating sub-temporary directory \"" << tmpdir << "\" failed.\n";
865 0 : exit(1);
866 : }
867 :
868 3 : snapdev::safe_setenv env("HOME", tmpdir);
869 :
870 : {
871 1 : std::ofstream config_file;
872 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
873 1 : CATCH_REQUIRE(config_file.good());
874 : config_file <<
875 : "# Auto-generated\n"
876 : "\n"
877 : "[connection]\n"
878 : "ip=10.0.2.5\n"
879 : "duration=6h\n"
880 : "size=604\n"
881 : "\n"
882 : "[data-settings]\n"
883 : "gap=6\n"
884 1 : "filename=utf9.txt\n"
885 : ;
886 1 : }
887 :
888 : {
889 1 : std::ofstream config_file;
890 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_project_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
891 1 : CATCH_REQUIRE(config_file.good());
892 : config_file <<
893 : "# Auto-generated\n"
894 : "\n"
895 : "[connection]\n"
896 : "duration=3min\n"
897 : "\n"
898 : "[data-settings]\n"
899 : "gap=9\n"
900 1 : "filename=utf7.txt\n"
901 : ;
902 1 : }
903 :
904 : {
905 1 : std::ofstream config_file;
906 1 : config_file.open(tmpdir + "/advgetopt.conf", std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
907 1 : CATCH_REQUIRE(config_file.good());
908 : config_file <<
909 : "# Auto-generated\n"
910 : "\n"
911 : "[connection]\n"
912 : "ip=192.168.255.3\n"
913 : "\n"
914 : "[data-settings]\n"
915 1 : "filename=utf8.txt\n"
916 : ;
917 1 : }
918 :
919 1 : char const * confs[] =
920 : {
921 1 : SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
922 1 : SNAP_CATCH2_NAMESPACE::g_config_project_filename.c_str(),
923 : "~/advgetopt.conf",
924 : nullptr
925 1 : };
926 :
927 1 : advgetopt::option const options[] =
928 : {
929 : advgetopt::define_option(
930 : advgetopt::Name("connection::size")
931 : , advgetopt::ShortName('s')
932 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
933 : , advgetopt::Help("size.")
934 : ),
935 : advgetopt::define_option(
936 : advgetopt::Name("data-settings::filename")
937 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED, advgetopt::GETOPT_FLAG_MULTIPLE>())
938 : , advgetopt::Help("enter a filenames.")
939 : , advgetopt::DefaultValue("a.out")
940 : ),
941 : advgetopt::define_option(
942 : advgetopt::Name("connection::duration")
943 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
944 : , advgetopt::Help("how long it lasts.")
945 : ),
946 : advgetopt::define_option(
947 : advgetopt::Name("data-settings::gap")
948 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
949 : , advgetopt::Help("gap size.")
950 : ),
951 : advgetopt::define_option(
952 : advgetopt::Name("connection::ip")
953 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
954 : , advgetopt::Help("enter the ip address.")
955 : ),
956 : advgetopt::end_options()
957 : };
958 :
959 1 : environment_options.f_project_name = "unittest";
960 1 : environment_options.f_options = options;
961 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
962 1 : environment_options.f_help_header = "Testing a load with multiple filenames and see that we get the latest";
963 1 : environment_options.f_configuration_files = confs;
964 :
965 1 : advgetopt::getopt opt(environment_options);
966 :
967 1 : opt.parse_configuration_files(0, nullptr);
968 :
969 3 : CATCH_REQUIRE(opt.size("connection::size") == 1);
970 3 : CATCH_REQUIRE(opt.get_string("connection::size") == "604");
971 :
972 : // although it is marked as multiple, the old entries are still
973 : // overwritten with newer versions; if the last entry had multiple
974 : // filenames, then we'd get get multiple names here
975 : //
976 3 : CATCH_REQUIRE(opt.size("data-settings::filename") == 1);
977 3 : CATCH_REQUIRE(opt.get_string("data-settings::filename", 0) == "utf8.txt");
978 :
979 3 : CATCH_REQUIRE(opt.size("connection::duration") == 1);
980 3 : CATCH_REQUIRE(opt.get_string("connection::duration") == "3min");
981 :
982 3 : CATCH_REQUIRE(opt.size("data-settings::gap") == 1);
983 3 : CATCH_REQUIRE(opt.get_string("data-settings::gap") == "9");
984 :
985 3 : CATCH_REQUIRE(opt.size("connection::ip") == 1);
986 3 : CATCH_REQUIRE(opt.get_string("connection::ip") == "192.168.255.3");
987 :
988 3 : std::string const name(advgetopt::CONFIGURATION_SECTIONS);
989 1 : CATCH_REQUIRE(opt.size(name) == 2);
990 1 : CATCH_REQUIRE(opt.get_string(name) == "connection");
991 1 : CATCH_REQUIRE(opt.get_string(name, 1) == "data-settings");
992 1 : }
993 2 : CATCH_END_SECTION()
994 2 : }
995 :
996 :
997 :
998 8 : CATCH_TEST_CASE("load_invalid_configuration_file", "[config][getopt][filenames][invalid]")
999 : {
1000 8 : CATCH_START_SECTION("load_invalid_configuration_file: load with unexpected parameter name (one letter--dynamic allowed)")
1001 : {
1002 5 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("loading-invalid", "invalid-one-letter");
1003 :
1004 : {
1005 1 : std::ofstream config_file;
1006 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
1007 1 : CATCH_REQUIRE(config_file.good());
1008 : config_file <<
1009 : "# Auto-generated\n"
1010 : "sizes=-132\n"
1011 1 : "f=dynamic\n"
1012 : ;
1013 1 : }
1014 :
1015 1 : char const * confs[] =
1016 : {
1017 : "~/.config/file-which-was-never-created.mdi",
1018 1 : SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
1019 : "/etc/snapwebsites/not/an-existing-file.conf",
1020 : nullptr
1021 1 : };
1022 :
1023 1 : char const * const separators[] {
1024 : ",",
1025 : " ",
1026 : nullptr
1027 : };
1028 :
1029 1 : advgetopt::option const options[] =
1030 : {
1031 : advgetopt::define_option(
1032 : advgetopt::Name("sizes")
1033 : , advgetopt::ShortName('s')
1034 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
1035 : , advgetopt::Help("sizes.")
1036 : ),
1037 6 : advgetopt::define_option(
1038 : advgetopt::Name("filenames")
1039 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED, advgetopt::GETOPT_FLAG_MULTIPLE>())
1040 : , advgetopt::Help("enter a list of filenames.")
1041 : , advgetopt::DefaultValue("a.out")
1042 : , advgetopt::Separators(separators)
1043 : ),
1044 : advgetopt::end_options()
1045 6 : };
1046 :
1047 1 : advgetopt::options_environment environment_options;
1048 1 : environment_options.f_project_name = "loading-invalid";
1049 1 : environment_options.f_options = options;
1050 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS | advgetopt::GETOPT_ENVIRONMENT_FLAG_DYNAMIC_PARAMETERS;
1051 1 : environment_options.f_help_header = "Testing loading a one letter parameter";
1052 1 : environment_options.f_configuration_files = confs;
1053 :
1054 1 : advgetopt::getopt opt(environment_options);
1055 :
1056 2 : SNAP_CATCH2_NAMESPACE::push_expected_log(
1057 : "error: unknown option \"f\" found in configuration file \""
1058 2 : + SNAP_CATCH2_NAMESPACE::g_config_filename
1059 4 : + "\" on line 3.");
1060 1 : opt.process_configuration_file(SNAP_CATCH2_NAMESPACE::g_config_filename);
1061 1 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
1062 :
1063 3 : CATCH_REQUIRE(opt.size("sizes") == 1);
1064 3 : CATCH_REQUIRE(opt.get_string("sizes") == "-132");
1065 3 : CATCH_REQUIRE(opt.get_long("sizes") == -132);
1066 :
1067 3 : CATCH_REQUIRE(opt.size("filenames") == 0);
1068 1 : }
1069 8 : CATCH_END_SECTION()
1070 :
1071 8 : CATCH_START_SECTION("load_invalid_configuration_file: load with unexpected parameter name (one letter--no dynamic allowed)")
1072 : {
1073 5 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("loading-undefined", "undefined-one-letter");
1074 :
1075 : {
1076 1 : std::ofstream config_file;
1077 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
1078 1 : CATCH_REQUIRE(config_file.good());
1079 : config_file <<
1080 : "# Auto-generated\n"
1081 : "sizes=-132\n"
1082 1 : "f=dynamic\n"
1083 : ;
1084 1 : }
1085 :
1086 1 : char const * confs[] =
1087 : {
1088 : "~/.config/file-which-was-never-created.mdi",
1089 1 : SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
1090 : "/etc/snapwebsites/not/an-existing-file.conf",
1091 : nullptr
1092 1 : };
1093 :
1094 1 : char const * const separators[] {
1095 : ",",
1096 : " ",
1097 : nullptr
1098 : };
1099 :
1100 1 : advgetopt::option const options[] =
1101 : {
1102 : advgetopt::define_option(
1103 : advgetopt::Name("sizes")
1104 : , advgetopt::ShortName('s')
1105 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
1106 : , advgetopt::Help("sizes.")
1107 : ),
1108 6 : advgetopt::define_option(
1109 : advgetopt::Name("filenames")
1110 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED, advgetopt::GETOPT_FLAG_MULTIPLE>())
1111 : , advgetopt::Help("enter a list of filenames.")
1112 : , advgetopt::DefaultValue("a.out")
1113 : , advgetopt::Separators(separators)
1114 : ),
1115 : advgetopt::end_options()
1116 6 : };
1117 :
1118 1 : advgetopt::options_environment environment_options;
1119 1 : environment_options.f_project_name = "loading-invalid";
1120 1 : environment_options.f_options = options;
1121 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
1122 1 : environment_options.f_help_header = "Testing loading a one letter parameter";
1123 1 : environment_options.f_configuration_files = confs;
1124 :
1125 1 : advgetopt::getopt opt(environment_options);
1126 :
1127 2 : SNAP_CATCH2_NAMESPACE::push_expected_log(
1128 : "error: unknown option \"f\" found in configuration file \""
1129 2 : + SNAP_CATCH2_NAMESPACE::g_config_filename
1130 4 : + "\" on line 3.");
1131 1 : opt.process_configuration_file(SNAP_CATCH2_NAMESPACE::g_config_filename);
1132 1 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
1133 :
1134 3 : CATCH_REQUIRE(opt.size("sizes") == 1);
1135 3 : CATCH_REQUIRE(opt.get_string("sizes") == "-132");
1136 3 : CATCH_REQUIRE(opt.get_long("sizes") == -132);
1137 :
1138 3 : CATCH_REQUIRE(opt.size("filenames") == 0);
1139 1 : }
1140 8 : CATCH_END_SECTION()
1141 :
1142 8 : CATCH_START_SECTION("load_invalid_configuration_file: load with unexpected parameter name (undefined & no dynamic fields are allowed)")
1143 : {
1144 5 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("loading-invalid-dynamic", "invalid-dynamic");
1145 :
1146 : {
1147 1 : std::ofstream config_file;
1148 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
1149 1 : CATCH_REQUIRE(config_file.good());
1150 : config_file <<
1151 : "# Auto-generated\n"
1152 : "sizes=-1001\n"
1153 1 : "dynamic=\"undefined argument\"\n"
1154 : ;
1155 1 : }
1156 :
1157 1 : char const * confs[] =
1158 : {
1159 : "~/.config/file-which-was-never-created.mdi",
1160 1 : SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
1161 : "/etc/snapwebsites/not/an-existing-file.conf",
1162 : nullptr
1163 1 : };
1164 :
1165 1 : char const * const separators[] {
1166 : ",",
1167 : " ",
1168 : nullptr
1169 : };
1170 :
1171 1 : advgetopt::option const options[] =
1172 : {
1173 : advgetopt::define_option(
1174 : advgetopt::Name("sizes")
1175 : , advgetopt::ShortName('s')
1176 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
1177 : , advgetopt::Help("sizes.")
1178 : ),
1179 6 : advgetopt::define_option(
1180 : advgetopt::Name("filenames")
1181 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED, advgetopt::GETOPT_FLAG_MULTIPLE>())
1182 : , advgetopt::Help("enter a list of filenames.")
1183 : , advgetopt::DefaultValue("a.out")
1184 : , advgetopt::Separators(separators)
1185 : ),
1186 : advgetopt::end_options()
1187 6 : };
1188 :
1189 1 : advgetopt::options_environment environment_options;
1190 1 : environment_options.f_project_name = "loading-invalid";
1191 1 : environment_options.f_options = options;
1192 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
1193 1 : environment_options.f_help_header = "Testing loading an unknown parameter and no dynamic allowed";
1194 1 : environment_options.f_configuration_files = confs;
1195 :
1196 1 : advgetopt::getopt opt(environment_options);
1197 :
1198 2 : SNAP_CATCH2_NAMESPACE::push_expected_log(
1199 : "error: unknown option \"dynamic\" found in configuration file \""
1200 2 : + SNAP_CATCH2_NAMESPACE::g_config_filename
1201 4 : + "\" on line 3.");
1202 1 : opt.process_configuration_file(SNAP_CATCH2_NAMESPACE::g_config_filename);
1203 1 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
1204 :
1205 3 : CATCH_REQUIRE(opt.size("sizes") == 1);
1206 3 : CATCH_REQUIRE(opt.get_string("sizes") == "-1001");
1207 3 : CATCH_REQUIRE(opt.get_long("sizes") == -1001);
1208 :
1209 3 : CATCH_REQUIRE(opt.size("filenames") == 0);
1210 1 : }
1211 8 : CATCH_END_SECTION()
1212 :
1213 8 : CATCH_START_SECTION("load_invalid_configuration_file: load with parameter not supported in configuration files")
1214 : {
1215 5 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("loading-invalid-config", "invalid-param-in-config");
1216 :
1217 : {
1218 1 : std::ofstream config_file;
1219 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
1220 1 : CATCH_REQUIRE(config_file.good());
1221 : config_file <<
1222 : "# Auto-generated\n"
1223 : "sizes=-1001\n"
1224 1 : "filenames=unexpected, argument, in, configuration, file\n"
1225 : ;
1226 1 : }
1227 :
1228 1 : char const * confs[] =
1229 : {
1230 : "~/.config/file-which-was-never-created.mdi",
1231 1 : SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
1232 : "/etc/snapwebsites/not/an-existing-file.conf",
1233 : nullptr
1234 1 : };
1235 :
1236 1 : char const * const separators[] {
1237 : ",",
1238 : " ",
1239 : nullptr
1240 : };
1241 :
1242 1 : advgetopt::option const options[] =
1243 : {
1244 : advgetopt::define_option(
1245 : advgetopt::Name("sizes")
1246 : , advgetopt::ShortName('s')
1247 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
1248 : , advgetopt::Help("sizes.")
1249 : ),
1250 5 : advgetopt::define_option(
1251 : advgetopt::Name("filenames")
1252 : , advgetopt::Flags(advgetopt::command_flags<advgetopt::GETOPT_FLAG_REQUIRED, advgetopt::GETOPT_FLAG_MULTIPLE>())
1253 : , advgetopt::Help("enter a list of filenames.")
1254 : , advgetopt::DefaultValue("a.out")
1255 : , advgetopt::Separators(separators)
1256 : ),
1257 : advgetopt::end_options()
1258 5 : };
1259 :
1260 1 : advgetopt::options_environment environment_options;
1261 1 : environment_options.f_project_name = "loading-invalid";
1262 1 : environment_options.f_options = options;
1263 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
1264 1 : environment_options.f_help_header = "Testing loading an unknown parameter and no dynamic allowed";
1265 1 : environment_options.f_configuration_files = confs;
1266 :
1267 1 : advgetopt::getopt opt(environment_options);
1268 :
1269 2 : SNAP_CATCH2_NAMESPACE::push_expected_log(
1270 : "error: option \"filenames\" is not supported in configuration files (found in \""
1271 2 : + SNAP_CATCH2_NAMESPACE::g_config_filename
1272 4 : + "\").");
1273 1 : opt.process_configuration_file(SNAP_CATCH2_NAMESPACE::g_config_filename);
1274 1 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
1275 :
1276 3 : CATCH_REQUIRE(opt.size("sizes") == 1);
1277 3 : CATCH_REQUIRE(opt.get_string("sizes") == "-1001");
1278 3 : CATCH_REQUIRE(opt.get_long("sizes") == -1001);
1279 :
1280 3 : CATCH_REQUIRE(opt.size("filenames") == 0);
1281 1 : }
1282 8 : CATCH_END_SECTION()
1283 :
1284 8 : CATCH_START_SECTION("load_invalid_configuration_file: load a configuration file with a flag given a value other than true or false")
1285 : {
1286 5 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("load-flag-with-value", "unexpected-value-in-config");
1287 :
1288 : {
1289 1 : std::ofstream config_file;
1290 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
1291 1 : CATCH_REQUIRE(config_file.good());
1292 : config_file <<
1293 : "# Auto-generated\n"
1294 : "sizes=4153629\n"
1295 1 : "color-flag=turn it on\n" // not true or false
1296 : ;
1297 1 : }
1298 :
1299 1 : char const * confs[] =
1300 : {
1301 : "~/.config/file-which-was-never-created.mdi",
1302 1 : SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
1303 : "/etc/snapwebsites/not/an-existing-file.conf",
1304 : nullptr
1305 1 : };
1306 :
1307 1 : advgetopt::option const options[] =
1308 : {
1309 : advgetopt::define_option(
1310 : advgetopt::Name("sizes")
1311 : , advgetopt::ShortName('s')
1312 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
1313 : , advgetopt::Help("sizes.")
1314 : ),
1315 : advgetopt::define_option(
1316 : advgetopt::Name("color-flag")
1317 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_FLAG>())
1318 : , advgetopt::Help("flag that you want color.")
1319 : ),
1320 : advgetopt::end_options()
1321 : };
1322 :
1323 1 : advgetopt::options_environment environment_options;
1324 1 : environment_options.f_project_name = "load";
1325 1 : environment_options.f_options = options;
1326 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
1327 1 : environment_options.f_help_header = "Testing loading an invalid flag";
1328 1 : environment_options.f_configuration_files = confs;
1329 :
1330 1 : advgetopt::getopt opt(environment_options);
1331 :
1332 2 : SNAP_CATCH2_NAMESPACE::push_expected_log(
1333 : "error: option \"color_flag\" cannot be given value \"turn it on\" in configuration file \""
1334 2 : + SNAP_CATCH2_NAMESPACE::g_config_filename
1335 4 : + "\". It only accepts \"true\" or \"false\".");
1336 1 : opt.process_configuration_file(SNAP_CATCH2_NAMESPACE::g_config_filename);
1337 1 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
1338 :
1339 3 : CATCH_REQUIRE(opt.size("sizes") == 1);
1340 3 : CATCH_REQUIRE(opt.get_string("sizes") == "4153629");
1341 :
1342 3 : CATCH_REQUIRE(opt.size("color-flag") == 0);
1343 3 : CATCH_REQUIRE_FALSE(opt.is_defined("color-flag"));
1344 1 : }
1345 8 : CATCH_END_SECTION()
1346 :
1347 8 : CATCH_START_SECTION("load_invalid_configuration_file: load a configuration file with a flag given the value \"true\"")
1348 : {
1349 5 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("load-flag-with-true", "true-value-in-config");
1350 :
1351 : {
1352 1 : std::ofstream config_file;
1353 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
1354 1 : CATCH_REQUIRE(config_file.good());
1355 : config_file <<
1356 : "# Auto-generated\n"
1357 : "sizes=4153629\n"
1358 1 : "color-flag=true\n" // true is like specifying it on the command line
1359 : ;
1360 1 : }
1361 :
1362 1 : char const * confs[] =
1363 : {
1364 : "~/.config/file-which-was-never-created.mdi",
1365 1 : SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
1366 : "/etc/snapwebsites/not/an-existing-file.conf",
1367 : nullptr
1368 1 : };
1369 :
1370 1 : advgetopt::option const options[] =
1371 : {
1372 : advgetopt::define_option(
1373 : advgetopt::Name("sizes")
1374 : , advgetopt::ShortName('s')
1375 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
1376 : , advgetopt::Help("sizes.")
1377 : ),
1378 : advgetopt::define_option(
1379 : advgetopt::Name("color-flag")
1380 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_FLAG>())
1381 : , advgetopt::Help("flag that you want color.")
1382 : ),
1383 : advgetopt::end_options()
1384 : };
1385 :
1386 1 : advgetopt::options_environment environment_options;
1387 1 : environment_options.f_project_name = "load";
1388 1 : environment_options.f_options = options;
1389 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
1390 1 : environment_options.f_help_header = "Testing loading an invalid flag";
1391 1 : environment_options.f_configuration_files = confs;
1392 :
1393 1 : advgetopt::getopt opt(environment_options);
1394 :
1395 1 : opt.process_configuration_file(SNAP_CATCH2_NAMESPACE::g_config_filename);
1396 :
1397 3 : CATCH_REQUIRE(opt.size("sizes") == 1);
1398 3 : CATCH_REQUIRE(opt.get_string("sizes") == "4153629");
1399 :
1400 3 : CATCH_REQUIRE(opt.size("color-flag") == 1);
1401 3 : CATCH_REQUIRE(opt.is_defined("color-flag"));
1402 1 : }
1403 8 : CATCH_END_SECTION()
1404 :
1405 8 : CATCH_START_SECTION("load_invalid_configuration_file: load a configuration file with a flag given the value \"false\"")
1406 : {
1407 5 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("load-flag-with-false", "false-value-in-config");
1408 :
1409 : {
1410 1 : std::ofstream config_file;
1411 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
1412 1 : CATCH_REQUIRE(config_file.good());
1413 : config_file <<
1414 : "# Auto-generated\n"
1415 : "sizes=4153629\n"
1416 1 : "color-flag=false\n" // false is like "unspecifying" it on the command line
1417 : ;
1418 1 : }
1419 :
1420 1 : char const * confs[] =
1421 : {
1422 : "~/.config/file-which-was-never-created.mdi",
1423 1 : SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
1424 : "/etc/snapwebsites/not/an-existing-file.conf",
1425 : nullptr
1426 1 : };
1427 :
1428 1 : advgetopt::option const options[] =
1429 : {
1430 : advgetopt::define_option(
1431 : advgetopt::Name("sizes")
1432 : , advgetopt::ShortName('s')
1433 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
1434 : , advgetopt::Help("sizes.")
1435 : ),
1436 : advgetopt::define_option(
1437 : advgetopt::Name("color-flag")
1438 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_FLAG>())
1439 : , advgetopt::Help("flag that you want color.")
1440 : ),
1441 : advgetopt::end_options()
1442 : };
1443 :
1444 1 : advgetopt::options_environment environment_options;
1445 1 : environment_options.f_project_name = "load";
1446 1 : environment_options.f_options = options;
1447 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
1448 1 : environment_options.f_help_header = "Testing loading an invalid flag";
1449 1 : environment_options.f_configuration_files = confs;
1450 :
1451 1 : advgetopt::getopt opt(environment_options);
1452 :
1453 1 : opt.process_configuration_file(SNAP_CATCH2_NAMESPACE::g_config_filename);
1454 :
1455 3 : CATCH_REQUIRE(opt.size("sizes") == 1);
1456 3 : CATCH_REQUIRE(opt.get_string("sizes") == "4153629");
1457 :
1458 3 : CATCH_REQUIRE(opt.size("color-flag") == 0);
1459 3 : CATCH_REQUIRE_FALSE(opt.is_defined("color-flag"));
1460 1 : }
1461 8 : CATCH_END_SECTION()
1462 :
1463 8 : CATCH_START_SECTION("load_invalid_configuration_file: load a configuration file with an invalid sections definition")
1464 : {
1465 5 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("load-with-invalid-sections", "invalid-sections");
1466 :
1467 : {
1468 1 : std::ofstream config_file;
1469 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
1470 1 : CATCH_REQUIRE(config_file.good());
1471 : config_file <<
1472 : "# Auto-generated\n"
1473 : "[integers]\n"
1474 1 : "sizes=639\n"
1475 : ;
1476 1 : }
1477 :
1478 1 : char const * confs[] =
1479 : {
1480 : "~/.config/file-which-was-never-created.mdi",
1481 1 : SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
1482 : "/etc/snapwebsites/not/an-existing-file.conf",
1483 : nullptr
1484 1 : };
1485 :
1486 1 : advgetopt::option const options[] =
1487 : {
1488 : advgetopt::define_option(
1489 : advgetopt::Name("integers::sizes")
1490 : , advgetopt::ShortName('s')
1491 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
1492 : , advgetopt::Help("sizes.")
1493 : ),
1494 : advgetopt::define_option(
1495 : advgetopt::Name(advgetopt::CONFIGURATION_SECTIONS)
1496 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
1497 : , advgetopt::Help("MULTIPLE missing.")
1498 : ),
1499 : advgetopt::end_options()
1500 : };
1501 :
1502 1 : advgetopt::options_environment environment_options;
1503 1 : environment_options.f_project_name = "load-invalid-sections";
1504 1 : environment_options.f_options = options;
1505 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
1506 1 : environment_options.f_help_header = "Testing loading invalid sections declaration";
1507 1 : environment_options.f_configuration_files = confs;
1508 :
1509 1 : advgetopt::getopt opt(environment_options);
1510 :
1511 3 : SNAP_CATCH2_NAMESPACE::push_expected_log("error: option \"configuration_sections\" must have GETOPT_FLAG_MULTIPLE set.");
1512 1 : opt.process_configuration_file(SNAP_CATCH2_NAMESPACE::g_config_filename);
1513 1 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
1514 :
1515 : // it failed early so it's not considered to be 100% initialized
1516 : //
1517 7 : CATCH_REQUIRE_THROWS_MATCHES(
1518 : opt.size("integers::sizes-parameter")
1519 : , advgetopt::getopt_initialization
1520 : , Catch::Matchers::ExceptionMessage(
1521 : "getopt_exception: function called too soon, parser is not done yet (i.e. is_defined(), get_string(), get_long(), get_double() cannot be called until the parser is done)"));
1522 1 : }
1523 8 : CATCH_END_SECTION()
1524 8 : }
1525 :
1526 :
1527 :
1528 : // vim: ts=4 sw=4 et nowrap
|