Line data Source code
1 : /*
2 : * License:
3 : * Copyright (c) 2006-2019 Made to Order Software Corp. All Rights Reserved
4 : *
5 : * https://snapwebsites.org/
6 : * contact@m2osw.com
7 : *
8 : * This program is free software; you can redistribute it and/or modify
9 : * it under the terms of the GNU General Public License as published by
10 : * the Free Software Foundation; either version 2 of the License, or
11 : * (at your option) any later version.
12 : *
13 : * This program is distributed in the hope that it will be useful,
14 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 : * GNU General Public License for more details.
17 : *
18 : * You should have received a copy of the GNU General Public License along
19 : * with this program; if not, write to the Free Software Foundation, Inc.,
20 : * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 : *
22 : * Authors:
23 : * Alexis Wilke alexis@m2osw.com
24 : */
25 :
26 : // self
27 : //
28 : #include "main.h"
29 :
30 : // advgetopt lib
31 : //
32 : #include <advgetopt/conf_file.h>
33 : #include <advgetopt/exception.h>
34 :
35 : // snapdev lib
36 : //
37 : #include <snapdev/safe_setenv.h>
38 : #include <snapdev/tokenize_string.h>
39 :
40 : // C++ lib
41 : //
42 : #include <fstream>
43 :
44 : // C lib
45 : //
46 : #include <unistd.h>
47 :
48 :
49 :
50 :
51 :
52 :
53 :
54 3 : CATCH_TEST_CASE("configuration_spaces", "[config][getopt]")
55 : {
56 2 : CATCH_START_SECTION("Verify Configuration Spaces")
57 1114113 : for(int c(0); c < 0x110000; ++c)
58 : {
59 1114112 : if(c == '\r'
60 1114111 : || c == '\n')
61 : {
62 2 : CATCH_REQUIRE_FALSE(advgetopt::iswspace(c));
63 : }
64 1114110 : else if(std::iswspace(c))
65 : {
66 4 : CATCH_REQUIRE(advgetopt::iswspace(c));
67 : }
68 : else
69 : {
70 1114106 : CATCH_REQUIRE_FALSE(advgetopt::iswspace(c));
71 : }
72 : }
73 : CATCH_END_SECTION()
74 1 : }
75 :
76 :
77 4 : CATCH_TEST_CASE("configuration_setup", "[config][getopt]")
78 : {
79 4 : CATCH_START_SECTION("Check All Setups")
80 : // 5 * 6 * 8 * 8 * 16 = 30720
81 6 : for(int count(0); count < 5; ++count)
82 : {
83 5 : int const id(rand());
84 10 : std::string const name("setup-file-" + std::to_string(id));
85 :
86 5 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("setup", name);
87 :
88 : {
89 10 : std::ofstream config_file;
90 5 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
91 5 : CATCH_REQUIRE(config_file.good());
92 5 : config_file <<
93 : "# Auto-generated\n"
94 : "param=optional\n"
95 : ;
96 : }
97 :
98 35 : for(int lc(static_cast<int>(advgetopt::line_continuation_t::line_continuation_single_line));
99 35 : lc <= static_cast<int>(advgetopt::line_continuation_t::line_continuation_semicolon);
100 : ++lc)
101 : {
102 270 : for(advgetopt::assignment_operator_t ao(0);
103 270 : ao <= advgetopt::ASSIGNMENT_OPERATOR_MASK;
104 : ++ao)
105 : {
106 1920 : for(advgetopt::comment_t c(0);
107 1920 : c < advgetopt::COMMENT_MASK;
108 : ++c)
109 : {
110 26880 : for(advgetopt::section_operator_t so(0);
111 26880 : so < advgetopt::SECTION_OPERATOR_MASK;
112 : ++so)
113 : {
114 : advgetopt::conf_file_setup setup(SNAP_CATCH2_NAMESPACE::g_config_filename
115 : , static_cast<advgetopt::line_continuation_t>(lc)
116 : , ao
117 : , c
118 50400 : , so);
119 :
120 25200 : advgetopt::assignment_operator_t real_ao(ao == 0 ? advgetopt::ASSIGNMENT_OPERATOR_EQUAL : ao);
121 :
122 25200 : CATCH_REQUIRE(setup.get_original_filename() == SNAP_CATCH2_NAMESPACE::g_config_filename);
123 :
124 25200 : CATCH_REQUIRE(setup.is_valid());
125 25200 : CATCH_REQUIRE(setup.get_filename() == SNAP_CATCH2_NAMESPACE::g_config_filename);
126 25200 : CATCH_REQUIRE(setup.get_line_continuation() == static_cast<advgetopt::line_continuation_t>(lc));
127 25200 : CATCH_REQUIRE(setup.get_assignment_operator() == real_ao);
128 25200 : CATCH_REQUIRE(setup.get_comment() == c);
129 25200 : CATCH_REQUIRE(setup.get_section_operator() == so);
130 :
131 50400 : std::string const url(setup.get_config_url());
132 : //std::cerr << "+++ " << lc << " / " << ao << " / " << c << " / " << so << " URL [" << url << "]\n";
133 25200 : CATCH_REQUIRE(url.substr(0, 8) == "file:///");
134 :
135 25200 : CATCH_REQUIRE(url.substr(7, SNAP_CATCH2_NAMESPACE::g_config_filename.length()) == SNAP_CATCH2_NAMESPACE::g_config_filename);
136 :
137 25200 : std::string::size_type const qm_pos(url.find('?'));
138 25200 : if(qm_pos == std::string::npos)
139 : {
140 : // must have the defaults in this case
141 : //
142 0 : CATCH_REQUIRE(static_cast<advgetopt::line_continuation_t>(lc) == advgetopt::line_continuation_t::line_continuation_unix);
143 0 : CATCH_REQUIRE(real_ao == advgetopt::ASSIGNMENT_OPERATOR_EQUAL);
144 0 : CATCH_REQUIRE(c == (advgetopt::COMMENT_INI | advgetopt::COMMENT_SHELL));
145 0 : CATCH_REQUIRE(so == advgetopt::SECTION_OPERATOR_INI_FILE);
146 : }
147 : else
148 : {
149 50400 : std::string const qs(url.substr(qm_pos + 1));
150 :
151 50400 : std::vector<std::string> strings;
152 25200 : snap::tokenize_string(strings, qs, "&");
153 :
154 25200 : bool def_lc(true);
155 25200 : bool def_ao(true);
156 25200 : bool def_c(true);
157 25200 : bool def_so(true);
158 :
159 112140 : for(auto s : strings)
160 : {
161 86940 : std::string::size_type const eq_pos(s.find('='));
162 86940 : CATCH_REQUIRE(eq_pos != std::string::npos);
163 :
164 173880 : std::string const var_name(s.substr(0, eq_pos));
165 173880 : std::string const var_value(s.substr(eq_pos + 1));
166 :
167 86940 : if(var_name == "line-continuation")
168 : {
169 21000 : def_lc = false;
170 21000 : switch(static_cast<advgetopt::line_continuation_t>(lc))
171 : {
172 4200 : case advgetopt::line_continuation_t::line_continuation_single_line:
173 4200 : CATCH_REQUIRE(var_value == "single-line");
174 4200 : break;
175 :
176 4200 : case advgetopt::line_continuation_t::line_continuation_rfc_822:
177 4200 : CATCH_REQUIRE(var_value == "rfc-822");
178 4200 : break;
179 :
180 4200 : case advgetopt::line_continuation_t::line_continuation_msdos:
181 4200 : CATCH_REQUIRE(var_value == "msdos");
182 4200 : break;
183 :
184 0 : case advgetopt::line_continuation_t::line_continuation_unix:
185 0 : CATCH_REQUIRE(var_value == "unix");
186 0 : break;
187 :
188 4200 : case advgetopt::line_continuation_t::line_continuation_fortran:
189 4200 : CATCH_REQUIRE(var_value == "fortran");
190 4200 : break;
191 :
192 4200 : case advgetopt::line_continuation_t::line_continuation_semicolon:
193 4200 : CATCH_REQUIRE(var_value == "semi-colon");
194 4200 : break;
195 :
196 0 : default:
197 0 : CATCH_REQUIRE(("unknown_var_value for \"line-continuation\":" + var_value) == std::string());
198 0 : break;
199 :
200 : }
201 : }
202 65940 : else if(var_name == "assignment-operator")
203 : {
204 18900 : def_ao = false;
205 37800 : std::vector<std::string> operators;
206 18900 : snap::tokenize_string(operators, var_value, ",");
207 :
208 18900 : if((real_ao & advgetopt::ASSIGNMENT_OPERATOR_EQUAL) != 0)
209 : {
210 9450 : auto it(std::find(operators.begin(), operators.end(), "equal"));
211 9450 : CATCH_REQUIRE(it != operators.end());
212 9450 : operators.erase(it);
213 : }
214 18900 : if((real_ao & advgetopt::ASSIGNMENT_OPERATOR_COLON) != 0)
215 : {
216 12600 : auto it(std::find(operators.begin(), operators.end(), "colon"));
217 12600 : CATCH_REQUIRE(it != operators.end());
218 12600 : operators.erase(it);
219 : }
220 18900 : if((real_ao & advgetopt::ASSIGNMENT_OPERATOR_SPACE) != 0)
221 : {
222 12600 : auto it(std::find(operators.begin(), operators.end(), "space"));
223 12600 : CATCH_REQUIRE(it != operators.end());
224 12600 : operators.erase(it);
225 : }
226 :
227 18900 : CATCH_REQUIRE(operators.empty());
228 : }
229 47040 : else if(var_name == "comment")
230 : {
231 25200 : def_c = false;
232 50400 : std::vector<std::string> comments;
233 25200 : snap::tokenize_string(comments, var_value, ",");
234 :
235 25200 : if((c & advgetopt::COMMENT_INI) != 0)
236 : {
237 10800 : auto it(std::find(comments.begin(), comments.end(), "ini"));
238 10800 : CATCH_REQUIRE(it != comments.end());
239 10800 : comments.erase(it);
240 : }
241 25200 : if((c & advgetopt::COMMENT_SHELL) != 0)
242 : {
243 10800 : auto it(std::find(comments.begin(), comments.end(), "shell"));
244 10800 : CATCH_REQUIRE(it != comments.end());
245 10800 : comments.erase(it);
246 : }
247 25200 : if((c & advgetopt::COMMENT_CPP) != 0)
248 : {
249 10800 : auto it(std::find(comments.begin(), comments.end(), "cpp"));
250 10800 : CATCH_REQUIRE(it != comments.end());
251 10800 : comments.erase(it);
252 : }
253 25200 : if(c == advgetopt::COMMENT_NONE)
254 : {
255 3600 : auto it(std::find(comments.begin(), comments.end(), "none"));
256 3600 : CATCH_REQUIRE(it != comments.end());
257 3600 : comments.erase(it);
258 : }
259 :
260 25200 : CATCH_REQUIRE(comments.empty());
261 : }
262 21840 : else if(var_name == "section-operator")
263 : {
264 21840 : def_so = false;
265 43680 : std::vector<std::string> section_operators;
266 21840 : snap::tokenize_string(section_operators, var_value, ",");
267 :
268 21840 : if((so & advgetopt::SECTION_OPERATOR_C) != 0)
269 : {
270 11760 : auto it(std::find(section_operators.begin(), section_operators.end(), "c"));
271 11760 : CATCH_REQUIRE(it != section_operators.end());
272 11760 : section_operators.erase(it);
273 : }
274 21840 : if((so & advgetopt::SECTION_OPERATOR_CPP) != 0)
275 : {
276 11760 : auto it(std::find(section_operators.begin(), section_operators.end(), "cpp"));
277 11760 : CATCH_REQUIRE(it != section_operators.end());
278 11760 : section_operators.erase(it);
279 : }
280 21840 : if((so & advgetopt::SECTION_OPERATOR_BLOCK) != 0)
281 : {
282 11760 : auto it(std::find(section_operators.begin(), section_operators.end(), "block"));
283 11760 : CATCH_REQUIRE(it != section_operators.end());
284 11760 : section_operators.erase(it);
285 : }
286 21840 : if((so & advgetopt::SECTION_OPERATOR_INI_FILE) != 0)
287 : {
288 10080 : auto it(std::find(section_operators.begin(), section_operators.end(), "ini-file"));
289 10080 : CATCH_REQUIRE(it != section_operators.end());
290 10080 : section_operators.erase(it);
291 : }
292 :
293 21840 : CATCH_REQUIRE(section_operators.empty());
294 : }
295 : else
296 : {
297 0 : CATCH_REQUIRE(("unknown var_name = " + var_name) == std::string());
298 : }
299 : }
300 :
301 25200 : if(def_lc)
302 : {
303 4200 : CATCH_REQUIRE(static_cast<advgetopt::line_continuation_t>(lc) == advgetopt::line_continuation_t::line_continuation_unix);
304 : }
305 25200 : if(def_ao)
306 : {
307 6300 : CATCH_REQUIRE(real_ao == advgetopt::ASSIGNMENT_OPERATOR_EQUAL);
308 : }
309 25200 : if(def_c)
310 : {
311 0 : CATCH_REQUIRE(c == (advgetopt::COMMENT_INI | advgetopt::COMMENT_SHELL));
312 : }
313 : }
314 : }
315 : }
316 : }
317 : }
318 : }
319 : CATCH_END_SECTION()
320 :
321 4 : CATCH_START_SECTION("Check non-existant filename")
322 : advgetopt::conf_file_setup setup(
323 : "/etc/advgetopt/unknown-file.conf"
324 : , advgetopt::line_continuation_t::line_continuation_fortran
325 : , advgetopt::ASSIGNMENT_OPERATOR_COLON
326 : , advgetopt::COMMENT_INI
327 2 : , advgetopt::SECTION_OPERATOR_CPP);
328 :
329 1 : CATCH_REQUIRE(setup.get_original_filename() == "/etc/advgetopt/unknown-file.conf");
330 :
331 1 : CATCH_REQUIRE(setup.is_valid());
332 1 : CATCH_REQUIRE(setup.get_filename() == "/etc/advgetopt/unknown-file.conf");
333 1 : CATCH_REQUIRE(setup.get_line_continuation() == advgetopt::line_continuation_t::line_continuation_fortran);
334 1 : CATCH_REQUIRE(setup.get_assignment_operator() == advgetopt::ASSIGNMENT_OPERATOR_COLON);
335 1 : CATCH_REQUIRE(setup.get_comment() == advgetopt::COMMENT_INI);
336 1 : CATCH_REQUIRE(setup.get_section_operator() == advgetopt::SECTION_OPERATOR_CPP);
337 :
338 1 : CATCH_REQUIRE(setup.get_config_url() == "file:///etc/advgetopt/unknown-file.conf?line-continuation=fortran&assignment-operator=colon&comment=ini§ion-operator=cpp");
339 : CATCH_END_SECTION()
340 2 : }
341 :
342 :
343 :
344 3 : CATCH_TEST_CASE("config_reload_tests")
345 : {
346 2 : CATCH_START_SECTION("Load a file, update it, verify it does not get reloaded")
347 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("reload", "load-twice");
348 :
349 : {
350 2 : std::ofstream config_file;
351 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
352 1 : CATCH_REQUIRE(config_file.good());
353 1 : config_file <<
354 : "# Auto-generated\n"
355 : "param=value\n"
356 : "changing=without reloading is useless\n"
357 : "test=1009\n"
358 : ;
359 : }
360 :
361 2 : advgetopt::conf_file::pointer_t file1;
362 : {
363 : advgetopt::conf_file_setup setup(SNAP_CATCH2_NAMESPACE::g_config_filename
364 : , advgetopt::line_continuation_t::line_continuation_single_line
365 : , advgetopt::ASSIGNMENT_OPERATOR_EQUAL
366 : , advgetopt::COMMENT_SHELL
367 2 : , advgetopt::SECTION_OPERATOR_NONE);
368 :
369 1 : CATCH_REQUIRE(setup.get_original_filename() == SNAP_CATCH2_NAMESPACE::g_config_filename);
370 :
371 1 : CATCH_REQUIRE(setup.is_valid());
372 1 : CATCH_REQUIRE(setup.get_line_continuation() == advgetopt::line_continuation_t::line_continuation_single_line);
373 1 : CATCH_REQUIRE(setup.get_assignment_operator() == advgetopt::ASSIGNMENT_OPERATOR_EQUAL);
374 1 : CATCH_REQUIRE(setup.get_comment() == advgetopt::COMMENT_SHELL);
375 1 : CATCH_REQUIRE(setup.get_section_operator() == advgetopt::SECTION_OPERATOR_NONE);
376 :
377 1 : file1 = advgetopt::conf_file::get_conf_file(setup);
378 :
379 1 : CATCH_REQUIRE(file1->get_setup().get_config_url() == setup.get_config_url());
380 1 : CATCH_REQUIRE(file1->get_errno() == 0);
381 1 : CATCH_REQUIRE(file1->get_sections().empty());
382 1 : CATCH_REQUIRE(file1->get_parameters().size() == 3);
383 :
384 1 : CATCH_REQUIRE(file1->has_parameter("param"));
385 1 : CATCH_REQUIRE(file1->has_parameter("changing"));
386 1 : CATCH_REQUIRE(file1->has_parameter("test"));
387 :
388 1 : CATCH_REQUIRE(file1->get_parameter("param") == "value");
389 1 : CATCH_REQUIRE(file1->get_parameter("changing") == "without reloading is useless");
390 1 : CATCH_REQUIRE(file1->get_parameter("test") == "1009");
391 : }
392 :
393 : // change all the values now
394 : {
395 2 : std::ofstream config_file;
396 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
397 1 : CATCH_REQUIRE(config_file.good());
398 1 : config_file <<
399 : "# Auto-generated\n"
400 : "param=new data\n"
401 : "new=this is not even acknowledge\n"
402 : "changing=special value\n"
403 : "test=9010\n"
404 : "level=three\n"
405 : ;
406 : }
407 :
408 : // "reloading" that very same file has the old data
409 : {
410 : advgetopt::conf_file_setup setup(SNAP_CATCH2_NAMESPACE::g_config_filename
411 : , advgetopt::line_continuation_t::line_continuation_single_line
412 : , advgetopt::ASSIGNMENT_OPERATOR_EQUAL
413 : , advgetopt::COMMENT_SHELL
414 2 : , advgetopt::SECTION_OPERATOR_NONE);
415 :
416 1 : CATCH_REQUIRE(setup.get_original_filename() == SNAP_CATCH2_NAMESPACE::g_config_filename);
417 :
418 1 : CATCH_REQUIRE(setup.is_valid());
419 1 : CATCH_REQUIRE(setup.get_line_continuation() == advgetopt::line_continuation_t::line_continuation_single_line);
420 1 : CATCH_REQUIRE(setup.get_assignment_operator() == advgetopt::ASSIGNMENT_OPERATOR_EQUAL);
421 1 : CATCH_REQUIRE(setup.get_comment() == advgetopt::COMMENT_SHELL);
422 1 : CATCH_REQUIRE(setup.get_section_operator() == advgetopt::SECTION_OPERATOR_NONE);
423 :
424 2 : advgetopt::conf_file::pointer_t file(advgetopt::conf_file::get_conf_file(setup));
425 :
426 : // exact same pointer
427 : //
428 1 : CATCH_REQUIRE(file == file1);
429 :
430 1 : CATCH_REQUIRE(file->get_setup().get_config_url() == setup.get_config_url());
431 1 : CATCH_REQUIRE(file->get_errno() == 0);
432 1 : CATCH_REQUIRE(file->get_sections().empty());
433 1 : CATCH_REQUIRE(file->get_parameters().size() == 3);
434 :
435 1 : CATCH_REQUIRE(file->has_parameter("param"));
436 1 : CATCH_REQUIRE(file->has_parameter("changing"));
437 1 : CATCH_REQUIRE(file->has_parameter("test"));
438 :
439 1 : CATCH_REQUIRE(file->get_parameter("param") == "value");
440 1 : CATCH_REQUIRE(file->get_parameter("changing") == "without reloading is useless");
441 1 : CATCH_REQUIRE(file->get_parameter("test") == "1009");
442 : }
443 : CATCH_END_SECTION()
444 1 : }
445 :
446 :
447 :
448 3 : CATCH_TEST_CASE("config_duplicated_variables")
449 : {
450 2 : CATCH_START_SECTION("file with the same variable defined multiple times")
451 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("duplicated-variable", "multiple");
452 :
453 : {
454 2 : std::ofstream config_file;
455 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
456 1 : CATCH_REQUIRE(config_file.good());
457 1 : config_file <<
458 : "# Auto-generated\n"
459 : "unique = perfect \n"
460 : "multiple = defintions\n"
461 : "another = just fine \t\n"
462 : "multiple = value\r\n"
463 : "good = variable \n"
464 : "multiple = set\n"
465 : "more = data\t \n"
466 : ;
467 : }
468 :
469 : advgetopt::conf_file_setup setup(SNAP_CATCH2_NAMESPACE::g_config_filename
470 : , advgetopt::line_continuation_t::line_continuation_single_line
471 : , advgetopt::ASSIGNMENT_OPERATOR_EQUAL
472 : , advgetopt::COMMENT_SHELL
473 2 : , advgetopt::SECTION_OPERATOR_NONE);
474 :
475 1 : CATCH_REQUIRE(setup.get_original_filename() == SNAP_CATCH2_NAMESPACE::g_config_filename);
476 :
477 1 : CATCH_REQUIRE(setup.is_valid());
478 1 : CATCH_REQUIRE(setup.get_line_continuation() == advgetopt::line_continuation_t::line_continuation_single_line);
479 1 : CATCH_REQUIRE(setup.get_assignment_operator() == advgetopt::ASSIGNMENT_OPERATOR_EQUAL);
480 1 : CATCH_REQUIRE(setup.get_comment() == advgetopt::COMMENT_SHELL);
481 1 : CATCH_REQUIRE(setup.get_section_operator() == advgetopt::SECTION_OPERATOR_NONE);
482 :
483 1 : SNAP_CATCH2_NAMESPACE::push_expected_log(
484 : "warning: parameter \"multiple\" on line 5 in"
485 : " configuration file \""
486 2 : + SNAP_CATCH2_NAMESPACE::g_config_filename
487 2 : + "\" was found twice in the same configuration file.");
488 1 : SNAP_CATCH2_NAMESPACE::push_expected_log(
489 : "warning: parameter \"multiple\" on line 7 in"
490 : " configuration file \""
491 2 : + SNAP_CATCH2_NAMESPACE::g_config_filename
492 2 : + "\" was found twice in the same configuration file.");
493 2 : advgetopt::conf_file::pointer_t file(advgetopt::conf_file::get_conf_file(setup));
494 1 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
495 :
496 1 : CATCH_REQUIRE(file->get_setup().get_config_url() == setup.get_config_url());
497 1 : CATCH_REQUIRE(file->get_errno() == 0);
498 1 : CATCH_REQUIRE(file->get_sections().empty());
499 1 : CATCH_REQUIRE(file->get_parameters().size() == 5);
500 :
501 1 : CATCH_REQUIRE(file->has_parameter("unique"));
502 1 : CATCH_REQUIRE(file->has_parameter("another"));
503 1 : CATCH_REQUIRE(file->has_parameter("good"));
504 1 : CATCH_REQUIRE(file->has_parameter("more"));
505 1 : CATCH_REQUIRE(file->has_parameter("multiple"));
506 :
507 1 : CATCH_REQUIRE(file->get_parameter("unique") == "perfect");
508 1 : CATCH_REQUIRE(file->get_parameter("another") == "just fine");
509 1 : CATCH_REQUIRE(file->get_parameter("good") == "variable");
510 1 : CATCH_REQUIRE(file->get_parameter("more") == "data");
511 1 : CATCH_REQUIRE(file->get_parameter("multiple") == "set");
512 :
513 : // we get a warning while reading; but not when directly
514 : // accessing the file object
515 : //
516 1 : CATCH_REQUIRE(file->set_parameter(std::string(), "multiple", "new value"));
517 1 : CATCH_REQUIRE(file->get_parameter("multiple") == "new value");
518 : CATCH_END_SECTION()
519 1 : }
520 :
521 :
522 :
523 3 : CATCH_TEST_CASE("config_callback_calls")
524 : {
525 2 : CATCH_START_SECTION("setup a callback and test the set_parameter()/erase() functions")
526 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("callback-variable", "callback");
527 :
528 : {
529 2 : std::ofstream config_file;
530 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
531 1 : CATCH_REQUIRE(config_file.good());
532 1 : config_file <<
533 : "# Auto-generated\n"
534 : "unique = perfect \n"
535 : "definition = long value here\n"
536 : "another = just fine \t\n"
537 : "multiple = value\r\n"
538 : "good = variable \n"
539 : "organized = set\n"
540 : "more = data\t \n"
541 : ;
542 : }
543 :
544 : advgetopt::conf_file_setup setup(SNAP_CATCH2_NAMESPACE::g_config_filename
545 : , advgetopt::line_continuation_t::line_continuation_single_line
546 : , advgetopt::ASSIGNMENT_OPERATOR_EQUAL
547 : , advgetopt::COMMENT_SHELL
548 2 : , advgetopt::SECTION_OPERATOR_NONE);
549 :
550 1 : CATCH_REQUIRE(setup.get_original_filename() == SNAP_CATCH2_NAMESPACE::g_config_filename);
551 :
552 1 : CATCH_REQUIRE(setup.is_valid());
553 1 : CATCH_REQUIRE(setup.get_line_continuation() == advgetopt::line_continuation_t::line_continuation_single_line);
554 1 : CATCH_REQUIRE(setup.get_assignment_operator() == advgetopt::ASSIGNMENT_OPERATOR_EQUAL);
555 1 : CATCH_REQUIRE(setup.get_comment() == advgetopt::COMMENT_SHELL);
556 1 : CATCH_REQUIRE(setup.get_section_operator() == advgetopt::SECTION_OPERATOR_NONE);
557 :
558 2 : advgetopt::conf_file::pointer_t file(advgetopt::conf_file::get_conf_file(setup));
559 :
560 2 : struct conf_data
561 : {
562 : advgetopt::conf_file::pointer_t f_conf_file = advgetopt::conf_file::pointer_t();
563 : advgetopt::callback_action_t f_expected_action = advgetopt::callback_action_t::created;
564 : std::string f_expected_variable = std::string();
565 : std::string f_expected_value = std::string();
566 : };
567 2 : conf_data cf_data;
568 1 : cf_data.f_conf_file = file;
569 :
570 : struct conf_callback
571 : {
572 5 : void operator () (advgetopt::conf_file::pointer_t conf_file
573 : , advgetopt::callback_action_t action
574 : , std::string const & variable_name
575 : , std::string const & value)
576 : {
577 5 : CATCH_REQUIRE(conf_file == f_data->f_conf_file);
578 5 : CATCH_REQUIRE(action == f_data->f_expected_action);
579 5 : CATCH_REQUIRE(variable_name == f_data->f_expected_variable);
580 5 : CATCH_REQUIRE(value == f_data->f_expected_value);
581 5 : CATCH_REQUIRE(conf_file->get_parameter(variable_name) == f_data->f_expected_value);
582 5 : }
583 :
584 : conf_data * f_data = nullptr;
585 : };
586 1 : conf_callback cf;
587 1 : cf.f_data = &cf_data;
588 :
589 1 : file->set_callback(cf);
590 :
591 1 : CATCH_REQUIRE(file->get_setup().get_config_url() == setup.get_config_url());
592 1 : CATCH_REQUIRE(file->get_errno() == 0);
593 1 : CATCH_REQUIRE_FALSE(file->was_modified());
594 1 : CATCH_REQUIRE(file->get_sections().empty());
595 1 : CATCH_REQUIRE(file->get_parameters().size() == 7);
596 :
597 1 : CATCH_REQUIRE(file->has_parameter("unique"));
598 1 : CATCH_REQUIRE(file->has_parameter("definition"));
599 1 : CATCH_REQUIRE(file->has_parameter("another"));
600 1 : CATCH_REQUIRE(file->has_parameter("multiple"));
601 1 : CATCH_REQUIRE(file->has_parameter("good"));
602 1 : CATCH_REQUIRE(file->has_parameter("organized"));
603 1 : CATCH_REQUIRE(file->has_parameter("more"));
604 :
605 1 : CATCH_REQUIRE(file->get_parameter("unique") == "perfect");
606 1 : CATCH_REQUIRE(file->get_parameter("definition") == "long value here");
607 1 : CATCH_REQUIRE(file->get_parameter("another") == "just fine");
608 1 : CATCH_REQUIRE(file->get_parameter("multiple") == "value");
609 1 : CATCH_REQUIRE(file->get_parameter("good") == "variable");
610 1 : CATCH_REQUIRE(file->get_parameter("organized") == "set");
611 1 : CATCH_REQUIRE(file->get_parameter("more") == "data");
612 :
613 : // updated action
614 : //
615 1 : cf_data.f_expected_action = advgetopt::callback_action_t::updated;
616 1 : cf_data.f_expected_variable = "multiple";
617 1 : cf_data.f_expected_value = "new value";
618 1 : CATCH_REQUIRE(file->set_parameter(std::string(), "multiple", "new value"));
619 1 : CATCH_REQUIRE(file->was_modified());
620 1 : CATCH_REQUIRE(file->get_parameters().size() == 7);
621 1 : CATCH_REQUIRE(file->get_parameter("multiple") == "new value");
622 :
623 : // created action
624 : //
625 1 : cf_data.f_expected_action = advgetopt::callback_action_t::created;
626 1 : cf_data.f_expected_variable = "new-param";
627 1 : cf_data.f_expected_value = "with this value";
628 1 : CATCH_REQUIRE(file->set_parameter(std::string(), "new_param", "with this value"));
629 1 : CATCH_REQUIRE(file->was_modified());
630 1 : CATCH_REQUIRE(file->get_parameters().size() == 8);
631 1 : CATCH_REQUIRE(file->has_parameter("new-param"));
632 1 : CATCH_REQUIRE(file->get_parameter("new-param") == "with this value");
633 1 : CATCH_REQUIRE(file->has_parameter("new_param"));
634 1 : CATCH_REQUIRE(file->get_parameter("new_param") == "with this value");
635 :
636 : // updated action when modifying
637 : //
638 1 : cf_data.f_expected_action = advgetopt::callback_action_t::updated;
639 1 : cf_data.f_expected_variable = "new-param";
640 1 : cf_data.f_expected_value = "change completely";
641 1 : CATCH_REQUIRE(file->set_parameter(std::string(), "new_param", "change completely"));
642 1 : CATCH_REQUIRE(file->was_modified());
643 1 : CATCH_REQUIRE(file->get_parameters().size() == 8);
644 1 : CATCH_REQUIRE(file->has_parameter("new-param"));
645 1 : CATCH_REQUIRE(file->get_parameter("new-param") == "change completely");
646 1 : CATCH_REQUIRE(file->has_parameter("new_param"));
647 1 : CATCH_REQUIRE(file->get_parameter("new_param") == "change completely");
648 :
649 : // erased action
650 : //
651 1 : cf_data.f_expected_action = advgetopt::callback_action_t::erased;
652 1 : cf_data.f_expected_variable = "new-param";
653 1 : cf_data.f_expected_value = std::string();
654 1 : CATCH_REQUIRE(file->erase_parameter("new_param"));
655 1 : CATCH_REQUIRE(file->was_modified());
656 1 : CATCH_REQUIRE(file->get_parameters().size() == 7);
657 1 : CATCH_REQUIRE_FALSE(file->has_parameter("new-param"));
658 1 : CATCH_REQUIRE(file->get_parameter("new-param") == std::string());
659 1 : CATCH_REQUIRE_FALSE(file->has_parameter("new_param"));
660 1 : CATCH_REQUIRE(file->get_parameter("new_param") == std::string());
661 1 : CATCH_REQUIRE_FALSE(file->erase_parameter("new_param"));
662 :
663 : // created action again (because it was erased)
664 : //
665 1 : cf_data.f_expected_action = advgetopt::callback_action_t::created;
666 1 : cf_data.f_expected_variable = "new-param";
667 1 : cf_data.f_expected_value = "with this value";
668 1 : CATCH_REQUIRE(file->set_parameter(std::string(), "new_param", "with this value"));
669 1 : CATCH_REQUIRE(file->was_modified());
670 1 : CATCH_REQUIRE(file->get_parameters().size() == 8);
671 1 : CATCH_REQUIRE(file->has_parameter("new-param"));
672 1 : CATCH_REQUIRE(file->get_parameter("new-param") == "with this value");
673 1 : CATCH_REQUIRE(file->has_parameter("new_param"));
674 1 : CATCH_REQUIRE(file->get_parameter("new_param") == "with this value");
675 :
676 : // until you save it remains true even if you were to restore the
677 : // state to "normal" (we do not keep a copy of the original value
678 : // as found in the file.)
679 : //
680 1 : CATCH_REQUIRE(file->was_modified());
681 : CATCH_END_SECTION()
682 1 : }
683 :
684 :
685 :
686 8 : CATCH_TEST_CASE("config_line_continuation_tests")
687 : {
688 12 : CATCH_START_SECTION("single_line")
689 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("line-continuation", "single-line");
690 :
691 : {
692 2 : std::ofstream config_file;
693 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
694 1 : CATCH_REQUIRE(config_file.good());
695 1 : config_file <<
696 : "# Auto-generated\n"
697 : "normal=param\n"
698 : "\n"
699 : "rfc-822=start here\n"
700 : " continue=there\n"
701 : "\n"
702 : "msdos=end with &\n"
703 : " and-continue=on next line\n"
704 : "\n"
705 : "unix=end with \\\n"
706 : "to-continue=like this\n"
707 : "\n"
708 : "fortran=fortran is funny\n"
709 : "&since=it starts with an & on the following line\n"
710 : "\n"
711 : "semicolon=this ends with\n"
712 : "a=semi-colon only;\n"
713 : ;
714 : }
715 :
716 : advgetopt::conf_file_setup setup(SNAP_CATCH2_NAMESPACE::g_config_filename
717 : , advgetopt::line_continuation_t::line_continuation_single_line
718 : , advgetopt::ASSIGNMENT_OPERATOR_EQUAL
719 : , advgetopt::COMMENT_SHELL
720 2 : , advgetopt::SECTION_OPERATOR_NONE);
721 :
722 1 : CATCH_REQUIRE(setup.get_original_filename() == SNAP_CATCH2_NAMESPACE::g_config_filename);
723 :
724 1 : CATCH_REQUIRE(setup.is_valid());
725 1 : CATCH_REQUIRE(setup.get_line_continuation() == advgetopt::line_continuation_t::line_continuation_single_line);
726 1 : CATCH_REQUIRE(setup.get_assignment_operator() == advgetopt::ASSIGNMENT_OPERATOR_EQUAL);
727 1 : CATCH_REQUIRE(setup.get_comment() == advgetopt::COMMENT_SHELL);
728 1 : CATCH_REQUIRE(setup.get_section_operator() == advgetopt::SECTION_OPERATOR_NONE);
729 :
730 2 : advgetopt::conf_file::pointer_t file(advgetopt::conf_file::get_conf_file(setup));
731 :
732 1 : CATCH_REQUIRE(file->get_setup().get_config_url() == setup.get_config_url());
733 1 : CATCH_REQUIRE(file->get_errno() == 0);
734 1 : CATCH_REQUIRE(file->get_sections().empty());
735 1 : CATCH_REQUIRE(file->get_parameters().size() == 11);
736 :
737 1 : CATCH_REQUIRE(file->has_parameter("normal"));
738 1 : CATCH_REQUIRE(file->has_parameter("rfc-822"));
739 1 : CATCH_REQUIRE(file->has_parameter("continue"));
740 1 : CATCH_REQUIRE(file->has_parameter("msdos"));
741 1 : CATCH_REQUIRE(file->has_parameter("and-continue"));
742 1 : CATCH_REQUIRE(file->has_parameter("unix"));
743 1 : CATCH_REQUIRE(file->has_parameter("to-continue"));
744 1 : CATCH_REQUIRE(file->has_parameter("fortran"));
745 1 : CATCH_REQUIRE(file->has_parameter("&since"));
746 1 : CATCH_REQUIRE(file->has_parameter("semicolon"));
747 1 : CATCH_REQUIRE(file->has_parameter("a"));
748 :
749 1 : CATCH_REQUIRE(file->get_parameter("normal") == "param");
750 1 : CATCH_REQUIRE(file->get_parameter("rfc-822") == "start here");
751 1 : CATCH_REQUIRE(file->get_parameter("continue") == "there");
752 1 : CATCH_REQUIRE(file->get_parameter("msdos") == "end with &");
753 1 : CATCH_REQUIRE(file->get_parameter("and-continue") == "on next line");
754 1 : CATCH_REQUIRE(file->get_parameter("unix") == "end with \\");
755 1 : CATCH_REQUIRE(file->get_parameter("to-continue") == "like this");
756 1 : CATCH_REQUIRE(file->get_parameter("fortran") == "fortran is funny");
757 1 : CATCH_REQUIRE(file->get_parameter("&since") == "it starts with an & on the following line");
758 1 : CATCH_REQUIRE(file->get_parameter("semicolon") == "this ends with");
759 1 : CATCH_REQUIRE(file->get_parameter("a") == "semi-colon only;");
760 :
761 1114113 : for(int c(0); c < 0x110000; ++c)
762 : {
763 1114112 : if(c == '=')
764 : {
765 1 : CATCH_REQUIRE(file->is_assignment_operator(c));
766 : }
767 : else
768 : {
769 1114111 : CATCH_REQUIRE_FALSE(file->is_assignment_operator(c));
770 : }
771 : }
772 : CATCH_END_SECTION()
773 :
774 12 : CATCH_START_SECTION("rfc822")
775 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("line-continuation", "rfc822");
776 :
777 : {
778 2 : std::ofstream config_file;
779 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
780 1 : CATCH_REQUIRE(config_file.good());
781 1 : config_file <<
782 : "# Auto-generated\n"
783 : "normal=param\n"
784 : "\n"
785 : "rfc-822=start here\n"
786 : " continue=there\n"
787 : "\n"
788 : "msdos=end with &\n"
789 : " and-continue=on next line\n"
790 : "\n"
791 : "unix=end with \\\n"
792 : "to-continue=like this\n"
793 : "\n"
794 : "fortran=fortran is funny\n"
795 : "&since=it starts with an & on the following line\n"
796 : "\n"
797 : "semicolon=this ends with\n"
798 : "a=semi-colon only;\n"
799 : ;
800 : }
801 :
802 : advgetopt::conf_file_setup setup(SNAP_CATCH2_NAMESPACE::g_config_filename
803 : , advgetopt::line_continuation_t::line_continuation_rfc_822
804 : , advgetopt::ASSIGNMENT_OPERATOR_EQUAL
805 : , advgetopt::COMMENT_SHELL
806 2 : , advgetopt::SECTION_OPERATOR_NONE);
807 :
808 1 : CATCH_REQUIRE(setup.get_original_filename() == SNAP_CATCH2_NAMESPACE::g_config_filename);
809 :
810 1 : CATCH_REQUIRE(setup.is_valid());
811 1 : CATCH_REQUIRE(setup.get_line_continuation() == advgetopt::line_continuation_t::line_continuation_rfc_822);
812 1 : CATCH_REQUIRE(setup.get_assignment_operator() == advgetopt::ASSIGNMENT_OPERATOR_EQUAL);
813 1 : CATCH_REQUIRE(setup.get_comment() == advgetopt::COMMENT_SHELL);
814 1 : CATCH_REQUIRE(setup.get_section_operator() == advgetopt::SECTION_OPERATOR_NONE);
815 :
816 2 : advgetopt::conf_file::pointer_t file(advgetopt::conf_file::get_conf_file(setup));
817 :
818 1 : CATCH_REQUIRE(file->get_setup().get_config_url() == setup.get_config_url());
819 1 : CATCH_REQUIRE(file->get_errno() == 0);
820 1 : CATCH_REQUIRE(file->get_sections().empty());
821 1 : CATCH_REQUIRE(file->get_parameters().size() == 9);
822 :
823 1 : CATCH_REQUIRE(file->has_parameter("normal"));
824 1 : CATCH_REQUIRE(file->has_parameter("rfc-822"));
825 1 : CATCH_REQUIRE(file->has_parameter("msdos"));
826 1 : CATCH_REQUIRE_FALSE(file->has_parameter("and-continue"));
827 1 : CATCH_REQUIRE(file->has_parameter("unix"));
828 1 : CATCH_REQUIRE(file->has_parameter("to-continue"));
829 1 : CATCH_REQUIRE(file->has_parameter("fortran"));
830 1 : CATCH_REQUIRE(file->has_parameter("&since"));
831 1 : CATCH_REQUIRE(file->has_parameter("semicolon"));
832 1 : CATCH_REQUIRE(file->has_parameter("a"));
833 :
834 1 : CATCH_REQUIRE(file->get_parameter("normal") == "param");
835 1 : CATCH_REQUIRE(file->get_parameter("rfc-822") == "start herecontinue=there");
836 1 : CATCH_REQUIRE(file->get_parameter("msdos") == "end with &and-continue=on next line");
837 1 : CATCH_REQUIRE(file->get_parameter("and-continue") == std::string());
838 1 : CATCH_REQUIRE(file->get_parameter("unix") == "end with \\");
839 1 : CATCH_REQUIRE(file->get_parameter("to-continue") == "like this");
840 1 : CATCH_REQUIRE(file->get_parameter("fortran") == "fortran is funny");
841 1 : CATCH_REQUIRE(file->get_parameter("&since") == "it starts with an & on the following line");
842 1 : CATCH_REQUIRE(file->get_parameter("semicolon") == "this ends with");
843 1 : CATCH_REQUIRE(file->get_parameter("a") == "semi-colon only;");
844 : CATCH_END_SECTION()
845 :
846 12 : CATCH_START_SECTION("msdos")
847 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("line-continuation", "msdos");
848 :
849 : {
850 2 : std::ofstream config_file;
851 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
852 1 : CATCH_REQUIRE(config_file.good());
853 1 : config_file <<
854 : "# Auto-generated\n"
855 : "normal=param\n"
856 : "\n"
857 : "rfc-822=start here\n"
858 : " continue=there\n"
859 : "\n"
860 : "msdos=end with &\n"
861 : " and-continue=on next line\n"
862 : "\n"
863 : "unix=end with \\\n"
864 : "to-continue=like this\n"
865 : "\n"
866 : "fortran=fortran is funny\n"
867 : "&since=it starts with an & on the following line\n"
868 : "\n"
869 : "semicolon=this ends with\n"
870 : "a=semi-colon only;\n"
871 : ;
872 : }
873 :
874 : advgetopt::conf_file_setup setup(SNAP_CATCH2_NAMESPACE::g_config_filename
875 : , advgetopt::line_continuation_t::line_continuation_msdos
876 : , advgetopt::ASSIGNMENT_OPERATOR_EQUAL
877 : , advgetopt::COMMENT_SHELL
878 2 : , advgetopt::SECTION_OPERATOR_NONE);
879 :
880 1 : CATCH_REQUIRE(setup.get_original_filename() == SNAP_CATCH2_NAMESPACE::g_config_filename);
881 :
882 1 : CATCH_REQUIRE(setup.is_valid());
883 1 : CATCH_REQUIRE(setup.get_line_continuation() == advgetopt::line_continuation_t::line_continuation_msdos);
884 1 : CATCH_REQUIRE(setup.get_assignment_operator() == advgetopt::ASSIGNMENT_OPERATOR_EQUAL);
885 1 : CATCH_REQUIRE(setup.get_comment() == advgetopt::COMMENT_SHELL);
886 1 : CATCH_REQUIRE(setup.get_section_operator() == advgetopt::SECTION_OPERATOR_NONE);
887 :
888 2 : advgetopt::conf_file::pointer_t file(advgetopt::conf_file::get_conf_file(setup));
889 :
890 1 : CATCH_REQUIRE(file->get_setup().get_config_url() == setup.get_config_url());
891 1 : CATCH_REQUIRE(file->get_errno() == 0);
892 1 : CATCH_REQUIRE(file->get_sections().empty());
893 1 : CATCH_REQUIRE(file->get_parameters().size() == 10);
894 :
895 1 : CATCH_REQUIRE(file->has_parameter("normal"));
896 1 : CATCH_REQUIRE(file->has_parameter("rfc-822"));
897 1 : CATCH_REQUIRE(file->has_parameter("continue"));
898 1 : CATCH_REQUIRE(file->has_parameter("msdos"));
899 1 : CATCH_REQUIRE_FALSE(file->has_parameter("and-continue"));
900 1 : CATCH_REQUIRE(file->has_parameter("unix"));
901 1 : CATCH_REQUIRE(file->has_parameter("to-continue"));
902 1 : CATCH_REQUIRE(file->has_parameter("fortran"));
903 1 : CATCH_REQUIRE(file->has_parameter("&since"));
904 1 : CATCH_REQUIRE(file->has_parameter("semicolon"));
905 1 : CATCH_REQUIRE(file->has_parameter("a"));
906 :
907 1 : CATCH_REQUIRE(file->get_parameter("normal") == "param");
908 1 : CATCH_REQUIRE(file->get_parameter("rfc-822") == "start here");
909 1 : CATCH_REQUIRE(file->get_parameter("continue") == "there");
910 1 : CATCH_REQUIRE(file->get_parameter("msdos") == "end with and-continue=on next line");
911 1 : CATCH_REQUIRE(file->get_parameter("and-continue") == std::string());
912 1 : CATCH_REQUIRE(file->get_parameter("unix") == "end with \\");
913 1 : CATCH_REQUIRE(file->get_parameter("to-continue") == "like this");
914 1 : CATCH_REQUIRE(file->get_parameter("fortran") == "fortran is funny");
915 1 : CATCH_REQUIRE(file->get_parameter("&since") == "it starts with an & on the following line");
916 1 : CATCH_REQUIRE(file->get_parameter("semicolon") == "this ends with");
917 1 : CATCH_REQUIRE(file->get_parameter("a") == "semi-colon only;");
918 : CATCH_END_SECTION()
919 :
920 12 : CATCH_START_SECTION("unix")
921 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("line-continuation", "unix");
922 :
923 : {
924 2 : std::ofstream config_file;
925 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
926 1 : CATCH_REQUIRE(config_file.good());
927 1 : config_file <<
928 : "# Auto-generated\n"
929 : "normal=param\n"
930 : "\n"
931 : "rfc-822=start here\n"
932 : " continue=there\n"
933 : "\n"
934 : "msdos=end with &\n"
935 : " and-continue=on next line\n"
936 : "\n"
937 : "unix=end with \\\n"
938 : "to-continue=like this\n"
939 : "\n"
940 : "fortran=fortran is funny\n"
941 : "&since=it starts with an & on the following line\n"
942 : "\n"
943 : "semicolon=this ends with\n"
944 : "a=semi-colon only;\n"
945 : ;
946 : }
947 :
948 : advgetopt::conf_file_setup setup(SNAP_CATCH2_NAMESPACE::g_config_filename
949 : , advgetopt::line_continuation_t::line_continuation_unix
950 : , advgetopt::ASSIGNMENT_OPERATOR_EQUAL
951 : , advgetopt::COMMENT_SHELL
952 2 : , advgetopt::SECTION_OPERATOR_NONE);
953 :
954 1 : CATCH_REQUIRE(setup.get_original_filename() == SNAP_CATCH2_NAMESPACE::g_config_filename);
955 :
956 1 : CATCH_REQUIRE(setup.is_valid());
957 1 : CATCH_REQUIRE(setup.get_line_continuation() == advgetopt::line_continuation_t::line_continuation_unix);
958 1 : CATCH_REQUIRE(setup.get_assignment_operator() == advgetopt::ASSIGNMENT_OPERATOR_EQUAL);
959 1 : CATCH_REQUIRE(setup.get_comment() == advgetopt::COMMENT_SHELL);
960 1 : CATCH_REQUIRE(setup.get_section_operator() == advgetopt::SECTION_OPERATOR_NONE);
961 :
962 2 : advgetopt::conf_file::pointer_t file(advgetopt::conf_file::get_conf_file(setup));
963 :
964 1 : CATCH_REQUIRE(file->get_setup().get_config_url() == setup.get_config_url());
965 1 : CATCH_REQUIRE(file->get_errno() == 0);
966 1 : CATCH_REQUIRE(file->get_sections().empty());
967 1 : CATCH_REQUIRE(file->get_parameters().size() == 10);
968 :
969 1 : CATCH_REQUIRE(file->has_parameter("normal"));
970 1 : CATCH_REQUIRE(file->has_parameter("rfc-822"));
971 1 : CATCH_REQUIRE(file->has_parameter("continue"));
972 1 : CATCH_REQUIRE(file->has_parameter("msdos"));
973 1 : CATCH_REQUIRE(file->has_parameter("and-continue"));
974 1 : CATCH_REQUIRE(file->has_parameter("unix"));
975 1 : CATCH_REQUIRE_FALSE(file->has_parameter("to-continue"));
976 1 : CATCH_REQUIRE(file->has_parameter("fortran"));
977 1 : CATCH_REQUIRE(file->has_parameter("&since"));
978 1 : CATCH_REQUIRE(file->has_parameter("semicolon"));
979 1 : CATCH_REQUIRE(file->has_parameter("a"));
980 :
981 1 : CATCH_REQUIRE(file->get_parameter("normal") == "param");
982 1 : CATCH_REQUIRE(file->get_parameter("rfc-822") == "start here");
983 1 : CATCH_REQUIRE(file->get_parameter("continue") == "there");
984 1 : CATCH_REQUIRE(file->get_parameter("msdos") == "end with &");
985 1 : CATCH_REQUIRE(file->get_parameter("and-continue") == "on next line");
986 1 : CATCH_REQUIRE(file->get_parameter("unix") == "end with to-continue=like this");
987 1 : CATCH_REQUIRE(file->get_parameter("to-continue") == std::string());
988 1 : CATCH_REQUIRE(file->get_parameter("fortran") == "fortran is funny");
989 1 : CATCH_REQUIRE(file->get_parameter("&since") == "it starts with an & on the following line");
990 1 : CATCH_REQUIRE(file->get_parameter("semicolon") == "this ends with");
991 1 : CATCH_REQUIRE(file->get_parameter("a") == "semi-colon only;");
992 : CATCH_END_SECTION()
993 :
994 12 : CATCH_START_SECTION("fortran")
995 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("line-continuation", "fortran");
996 :
997 : {
998 2 : std::ofstream config_file;
999 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
1000 1 : CATCH_REQUIRE(config_file.good());
1001 1 : config_file <<
1002 : "# Auto-generated\n"
1003 : "normal=param\n"
1004 : "\n"
1005 : "rfc-822=start here\n"
1006 : " continue=there\n"
1007 : "\n"
1008 : "msdos=end with &\n"
1009 : " and-continue=on next line\n"
1010 : "\n"
1011 : "unix=end with \\\n"
1012 : "to-continue=like this\n"
1013 : "\n"
1014 : "fortran=fortran is funny\n"
1015 : "&since=it starts with an & on the following line\n"
1016 : "\n"
1017 : "semicolon=this ends with\n"
1018 : "a=semi-colon only;\n"
1019 : ;
1020 : }
1021 :
1022 : advgetopt::conf_file_setup setup(SNAP_CATCH2_NAMESPACE::g_config_filename
1023 : , advgetopt::line_continuation_t::line_continuation_fortran
1024 : , advgetopt::ASSIGNMENT_OPERATOR_EQUAL
1025 : , advgetopt::COMMENT_SHELL
1026 2 : , advgetopt::SECTION_OPERATOR_NONE);
1027 :
1028 1 : CATCH_REQUIRE(setup.get_original_filename() == SNAP_CATCH2_NAMESPACE::g_config_filename);
1029 :
1030 1 : CATCH_REQUIRE(setup.is_valid());
1031 1 : CATCH_REQUIRE(setup.get_line_continuation() == advgetopt::line_continuation_t::line_continuation_fortran);
1032 1 : CATCH_REQUIRE(setup.get_assignment_operator() == advgetopt::ASSIGNMENT_OPERATOR_EQUAL);
1033 1 : CATCH_REQUIRE(setup.get_comment() == advgetopt::COMMENT_SHELL);
1034 1 : CATCH_REQUIRE(setup.get_section_operator() == advgetopt::SECTION_OPERATOR_NONE);
1035 :
1036 2 : advgetopt::conf_file::pointer_t file(advgetopt::conf_file::get_conf_file(setup));
1037 :
1038 2 : std::cerr << "------------------ " << file->get_setup().get_config_url()
1039 2 : << "\n------------------ " << setup.get_config_url()
1040 3 : << "\n";
1041 :
1042 1 : CATCH_REQUIRE(file->get_setup().get_config_url() == setup.get_config_url());
1043 1 : CATCH_REQUIRE(file->get_errno() == 0);
1044 1 : CATCH_REQUIRE(file->get_sections().empty());
1045 1 : CATCH_REQUIRE(file->get_parameters().size() == 10);
1046 :
1047 1 : CATCH_REQUIRE(file->has_parameter("normal"));
1048 1 : CATCH_REQUIRE(file->has_parameter("rfc-822"));
1049 1 : CATCH_REQUIRE(file->has_parameter("continue"));
1050 1 : CATCH_REQUIRE(file->has_parameter("msdos"));
1051 1 : CATCH_REQUIRE(file->has_parameter("and-continue"));
1052 1 : CATCH_REQUIRE(file->has_parameter("unix"));
1053 1 : CATCH_REQUIRE(file->has_parameter("to-continue"));
1054 1 : CATCH_REQUIRE(file->has_parameter("fortran"));
1055 1 : CATCH_REQUIRE_FALSE(file->has_parameter("&since"));
1056 1 : CATCH_REQUIRE(file->has_parameter("semicolon"));
1057 1 : CATCH_REQUIRE(file->has_parameter("a"));
1058 :
1059 1 : CATCH_REQUIRE(file->get_parameter("normal") == "param");
1060 1 : CATCH_REQUIRE(file->get_parameter("rfc-822") == "start here");
1061 1 : CATCH_REQUIRE(file->get_parameter("continue") == "there");
1062 1 : CATCH_REQUIRE(file->get_parameter("msdos") == "end with &");
1063 1 : CATCH_REQUIRE(file->get_parameter("and-continue") == "on next line");
1064 1 : CATCH_REQUIRE(file->get_parameter("unix") == "end with \\");
1065 1 : CATCH_REQUIRE(file->get_parameter("to-continue") == "like this");
1066 1 : CATCH_REQUIRE(file->get_parameter("fortran") == "fortran is funnysince=it starts with an & on the following line");
1067 1 : CATCH_REQUIRE(file->get_parameter("&since") == std::string());
1068 1 : CATCH_REQUIRE(file->get_parameter("semicolon") == "this ends with");
1069 1 : CATCH_REQUIRE(file->get_parameter("a") == "semi-colon only;");
1070 : CATCH_END_SECTION()
1071 :
1072 12 : CATCH_START_SECTION("semicolon")
1073 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("line-continuation", "semicolon");
1074 :
1075 : {
1076 2 : 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 1 : config_file <<
1080 : "# Auto-generated\r\n"
1081 : "normal=param\r\n"
1082 : "\r\n"
1083 : "rfc-822=start here\r\n"
1084 : " continue=there\r\n"
1085 : "\r\n"
1086 : "msdos=end with &\r"
1087 : " and-continue=on next line\r\n"
1088 : "\r\n"
1089 : "unix=end with \\\r\n"
1090 : "to-continue=like this\r"
1091 : "\r\n"
1092 : "fortran=fortran is funny\r\n"
1093 : "&since=it starts with an & on the following line\r\n"
1094 : "\r"
1095 : "semicolon=this ends with\r\n"
1096 : "a=semi-colon only;\r\n"
1097 : ;
1098 : }
1099 :
1100 : advgetopt::conf_file_setup setup(SNAP_CATCH2_NAMESPACE::g_config_filename
1101 : , advgetopt::line_continuation_t::line_continuation_semicolon
1102 : , advgetopt::ASSIGNMENT_OPERATOR_EQUAL
1103 : , advgetopt::COMMENT_SHELL
1104 2 : , advgetopt::SECTION_OPERATOR_NONE);
1105 :
1106 1 : CATCH_REQUIRE(setup.get_original_filename() == SNAP_CATCH2_NAMESPACE::g_config_filename);
1107 :
1108 1 : CATCH_REQUIRE(setup.is_valid());
1109 1 : CATCH_REQUIRE(setup.get_line_continuation() == advgetopt::line_continuation_t::line_continuation_semicolon);
1110 1 : CATCH_REQUIRE(setup.get_assignment_operator() == advgetopt::ASSIGNMENT_OPERATOR_EQUAL);
1111 1 : CATCH_REQUIRE(setup.get_comment() == advgetopt::COMMENT_SHELL);
1112 1 : CATCH_REQUIRE(setup.get_section_operator() == advgetopt::SECTION_OPERATOR_NONE);
1113 :
1114 2 : advgetopt::conf_file::pointer_t file(advgetopt::conf_file::get_conf_file(setup));
1115 :
1116 1 : CATCH_REQUIRE(file->get_setup().get_config_url() == setup.get_config_url());
1117 1 : CATCH_REQUIRE(file->get_errno() == 0);
1118 1 : CATCH_REQUIRE(file->get_sections().empty());
1119 1 : CATCH_REQUIRE(file->get_parameters().size() == 1);
1120 :
1121 1 : CATCH_REQUIRE(file->has_parameter("normal"));
1122 1 : CATCH_REQUIRE_FALSE(file->has_parameter("rfc-822"));
1123 1 : CATCH_REQUIRE_FALSE(file->has_parameter("continue"));
1124 1 : CATCH_REQUIRE_FALSE(file->has_parameter("msdos"));
1125 1 : CATCH_REQUIRE_FALSE(file->has_parameter("and-continue"));
1126 1 : CATCH_REQUIRE_FALSE(file->has_parameter("unix"));
1127 1 : CATCH_REQUIRE_FALSE(file->has_parameter("to-continue"));
1128 1 : CATCH_REQUIRE_FALSE(file->has_parameter("fortran"));
1129 1 : CATCH_REQUIRE_FALSE(file->has_parameter("&since"));
1130 1 : CATCH_REQUIRE_FALSE(file->has_parameter("semicolon"));
1131 1 : CATCH_REQUIRE_FALSE(file->has_parameter("a"));
1132 :
1133 1 : CATCH_REQUIRE(file->get_parameter("normal") == std::string("param\n"
1134 : "\n"
1135 : "rfc-822=start here\n"
1136 : " continue=there\n"
1137 : "\n"
1138 : "msdos=end with &\n"
1139 : " and-continue=on next line\n"
1140 : "\n"
1141 : "unix=end with \\\n"
1142 : "to-continue=like this\n"
1143 : "\n"
1144 : "fortran=fortran is funny\n"
1145 : "&since=it starts with an & on the following line\n"
1146 : "\n"
1147 : "semicolon=this ends with\n"
1148 : "a=semi-colon only"));
1149 1 : CATCH_REQUIRE(file->get_parameter("rfc-822") == std::string());
1150 1 : CATCH_REQUIRE(file->get_parameter("continue") == std::string());
1151 1 : CATCH_REQUIRE(file->get_parameter("msdos") == std::string());
1152 1 : CATCH_REQUIRE(file->get_parameter("and-continue") == std::string());
1153 1 : CATCH_REQUIRE(file->get_parameter("unix") == std::string());
1154 1 : CATCH_REQUIRE(file->get_parameter("to-continue") == std::string());
1155 1 : CATCH_REQUIRE(file->get_parameter("fortran") == std::string());
1156 1 : CATCH_REQUIRE(file->get_parameter("&since") == std::string());
1157 1 : CATCH_REQUIRE(file->get_parameter("semicolon") == std::string());
1158 1 : CATCH_REQUIRE(file->get_parameter("a") == std::string());
1159 : CATCH_END_SECTION()
1160 6 : }
1161 :
1162 :
1163 :
1164 6 : CATCH_TEST_CASE("config_assignment_operator_tests")
1165 : {
1166 8 : CATCH_START_SECTION("equal")
1167 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("assignment-operator", "equal");
1168 :
1169 : {
1170 2 : std::ofstream config_file;
1171 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
1172 1 : CATCH_REQUIRE(config_file.good());
1173 1 : config_file <<
1174 : "# Auto-generated\n"
1175 : "equal=value\n"
1176 : "\n"
1177 : "name_value=127\n"
1178 : "\n"
1179 : "and=no operator\n"
1180 : ;
1181 : }
1182 :
1183 : advgetopt::conf_file_setup setup(SNAP_CATCH2_NAMESPACE::g_config_filename
1184 : , advgetopt::line_continuation_t::line_continuation_single_line
1185 : , advgetopt::ASSIGNMENT_OPERATOR_EQUAL
1186 : , advgetopt::COMMENT_SHELL
1187 2 : , advgetopt::SECTION_OPERATOR_NONE);
1188 :
1189 1 : CATCH_REQUIRE(setup.get_original_filename() == SNAP_CATCH2_NAMESPACE::g_config_filename);
1190 :
1191 1 : CATCH_REQUIRE(setup.is_valid());
1192 1 : CATCH_REQUIRE(setup.get_line_continuation() == advgetopt::line_continuation_t::line_continuation_single_line);
1193 1 : CATCH_REQUIRE(setup.get_assignment_operator() == advgetopt::ASSIGNMENT_OPERATOR_EQUAL);
1194 1 : CATCH_REQUIRE(setup.get_comment() == advgetopt::COMMENT_SHELL);
1195 1 : CATCH_REQUIRE(setup.get_section_operator() == advgetopt::SECTION_OPERATOR_NONE);
1196 :
1197 2 : advgetopt::conf_file::pointer_t file(advgetopt::conf_file::get_conf_file(setup));
1198 :
1199 1 : CATCH_REQUIRE(file->get_setup().get_config_url() == setup.get_config_url());
1200 1 : CATCH_REQUIRE(file->get_errno() == 0);
1201 1 : CATCH_REQUIRE(file->get_sections().empty());
1202 1 : CATCH_REQUIRE(file->get_parameters().size() == 3);
1203 :
1204 1 : CATCH_REQUIRE(file->has_parameter("equal"));
1205 1 : CATCH_REQUIRE(file->has_parameter("name-value"));
1206 1 : CATCH_REQUIRE(file->has_parameter("and"));
1207 :
1208 1 : CATCH_REQUIRE(file->get_parameter("equal") == "value");
1209 1 : CATCH_REQUIRE(file->get_parameter("name-value") == "127");
1210 1 : CATCH_REQUIRE(file->get_parameter("and") == "no operator");
1211 : CATCH_END_SECTION()
1212 :
1213 8 : CATCH_START_SECTION("colon")
1214 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("assignment-operator", "colon");
1215 :
1216 : {
1217 2 : std::ofstream config_file;
1218 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
1219 1 : CATCH_REQUIRE(config_file.good());
1220 1 : config_file <<
1221 : "# Auto-generated\n"
1222 : "equal_value\n"
1223 : "\n"
1224 : "name:value=127\n"
1225 : "\n"
1226 : "and_no-operator\n"
1227 : ;
1228 : }
1229 :
1230 : advgetopt::conf_file_setup setup(SNAP_CATCH2_NAMESPACE::g_config_filename
1231 : , advgetopt::line_continuation_t::line_continuation_single_line
1232 : , advgetopt::ASSIGNMENT_OPERATOR_COLON
1233 : , advgetopt::COMMENT_SHELL
1234 2 : , advgetopt::SECTION_OPERATOR_NONE);
1235 :
1236 1 : CATCH_REQUIRE(setup.get_original_filename() == SNAP_CATCH2_NAMESPACE::g_config_filename);
1237 :
1238 1 : CATCH_REQUIRE(setup.is_valid());
1239 1 : CATCH_REQUIRE(setup.get_line_continuation() == advgetopt::line_continuation_t::line_continuation_single_line);
1240 1 : CATCH_REQUIRE(setup.get_assignment_operator() == advgetopt::ASSIGNMENT_OPERATOR_COLON);
1241 1 : CATCH_REQUIRE(setup.get_comment() == advgetopt::COMMENT_SHELL);
1242 1 : CATCH_REQUIRE(setup.get_section_operator() == advgetopt::SECTION_OPERATOR_NONE);
1243 :
1244 2 : advgetopt::conf_file::pointer_t file(advgetopt::conf_file::get_conf_file(setup));
1245 :
1246 1 : CATCH_REQUIRE(file->get_setup().get_config_url() == setup.get_config_url());
1247 1 : CATCH_REQUIRE(file->get_errno() == 0);
1248 1 : CATCH_REQUIRE(file->get_sections().empty());
1249 1 : CATCH_REQUIRE(file->get_parameters().size() == 3);
1250 :
1251 1 : CATCH_REQUIRE(file->has_parameter("equal-value"));
1252 1 : CATCH_REQUIRE(file->has_parameter("name"));
1253 1 : CATCH_REQUIRE(file->has_parameter("and-no-operator"));
1254 :
1255 1 : CATCH_REQUIRE(file->get_parameter("equal-value") == std::string());
1256 1 : CATCH_REQUIRE(file->get_parameter("name") == "value=127");
1257 1 : CATCH_REQUIRE(file->get_parameter("and-no-operator") == std::string());
1258 : CATCH_END_SECTION()
1259 :
1260 8 : CATCH_START_SECTION("space")
1261 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("assignment-operator", "space");
1262 :
1263 : {
1264 2 : std::ofstream config_file;
1265 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
1266 1 : CATCH_REQUIRE(config_file.good());
1267 1 : config_file <<
1268 : "# Auto-generated\n"
1269 : "equal-value\n"
1270 : "\n"
1271 : "name 127\n"
1272 : "\n"
1273 : "and-no operator\n"
1274 : ;
1275 : }
1276 :
1277 : advgetopt::conf_file_setup setup(SNAP_CATCH2_NAMESPACE::g_config_filename
1278 : , advgetopt::line_continuation_t::line_continuation_single_line
1279 : , advgetopt::ASSIGNMENT_OPERATOR_SPACE
1280 : , advgetopt::COMMENT_SHELL
1281 2 : , advgetopt::SECTION_OPERATOR_NONE);
1282 :
1283 1 : CATCH_REQUIRE(setup.get_original_filename() == SNAP_CATCH2_NAMESPACE::g_config_filename);
1284 :
1285 1 : CATCH_REQUIRE(setup.is_valid());
1286 1 : CATCH_REQUIRE(setup.get_line_continuation() == advgetopt::line_continuation_t::line_continuation_single_line);
1287 1 : CATCH_REQUIRE(setup.get_assignment_operator() == advgetopt::ASSIGNMENT_OPERATOR_SPACE);
1288 1 : CATCH_REQUIRE(setup.get_comment() == advgetopt::COMMENT_SHELL);
1289 1 : CATCH_REQUIRE(setup.get_section_operator() == advgetopt::SECTION_OPERATOR_NONE);
1290 :
1291 2 : advgetopt::conf_file::pointer_t file(advgetopt::conf_file::get_conf_file(setup));
1292 :
1293 1 : CATCH_REQUIRE(file->get_setup().get_config_url() == setup.get_config_url());
1294 1 : CATCH_REQUIRE(file->get_errno() == 0);
1295 1 : CATCH_REQUIRE(file->get_sections().empty());
1296 1 : CATCH_REQUIRE(file->get_parameters().size() == 3);
1297 :
1298 1 : CATCH_REQUIRE(file->has_parameter("equal-value"));
1299 1 : CATCH_REQUIRE(file->has_parameter("name"));
1300 1 : CATCH_REQUIRE(file->has_parameter("and-no"));
1301 :
1302 1 : CATCH_REQUIRE(file->get_parameter("equal-value") == std::string());
1303 1 : CATCH_REQUIRE(file->get_parameter("name") == "127");
1304 1 : CATCH_REQUIRE(file->get_parameter("and-no") == "operator");
1305 : CATCH_END_SECTION()
1306 :
1307 8 : CATCH_START_SECTION("equal_colon_and_space")
1308 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("assignment-operator", "all");
1309 :
1310 : {
1311 2 : std::ofstream config_file;
1312 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
1313 1 : CATCH_REQUIRE(config_file.good());
1314 1 : config_file <<
1315 : "# Auto-generated\n"
1316 : "equal=value\n"
1317 : "\n"
1318 : "name: 127\n"
1319 : "\n"
1320 : "and no operator\n"
1321 : ;
1322 : }
1323 :
1324 : advgetopt::conf_file_setup setup(SNAP_CATCH2_NAMESPACE::g_config_filename
1325 : , advgetopt::line_continuation_t::line_continuation_single_line
1326 : , advgetopt::ASSIGNMENT_OPERATOR_EQUAL
1327 : | advgetopt::ASSIGNMENT_OPERATOR_COLON
1328 : | advgetopt::ASSIGNMENT_OPERATOR_SPACE
1329 : , advgetopt::COMMENT_SHELL
1330 2 : , advgetopt::SECTION_OPERATOR_NONE);
1331 :
1332 1 : CATCH_REQUIRE(setup.get_original_filename() == SNAP_CATCH2_NAMESPACE::g_config_filename);
1333 :
1334 1 : CATCH_REQUIRE(setup.is_valid());
1335 1 : CATCH_REQUIRE(setup.get_line_continuation() == advgetopt::line_continuation_t::line_continuation_single_line);
1336 1 : CATCH_REQUIRE(setup.get_assignment_operator() == (advgetopt::ASSIGNMENT_OPERATOR_EQUAL
1337 : | advgetopt::ASSIGNMENT_OPERATOR_COLON
1338 : | advgetopt::ASSIGNMENT_OPERATOR_SPACE));
1339 1 : CATCH_REQUIRE(setup.get_comment() == advgetopt::COMMENT_SHELL);
1340 1 : CATCH_REQUIRE(setup.get_section_operator() == advgetopt::SECTION_OPERATOR_NONE);
1341 :
1342 2 : advgetopt::conf_file::pointer_t file(advgetopt::conf_file::get_conf_file(setup));
1343 :
1344 1 : CATCH_REQUIRE(file->get_setup().get_config_url() == setup.get_config_url());
1345 1 : CATCH_REQUIRE(file->get_errno() == 0);
1346 1 : CATCH_REQUIRE(file->get_sections().empty());
1347 1 : CATCH_REQUIRE(file->get_parameters().size() == 3);
1348 :
1349 1 : CATCH_REQUIRE(file->has_parameter("equal"));
1350 1 : CATCH_REQUIRE(file->has_parameter("name"));
1351 1 : CATCH_REQUIRE(file->has_parameter("and"));
1352 :
1353 1 : CATCH_REQUIRE(file->get_parameter("equal") == "value");
1354 1 : CATCH_REQUIRE(file->get_parameter("name") == "127");
1355 1 : CATCH_REQUIRE(file->get_parameter("and") == "no operator");
1356 : CATCH_END_SECTION()
1357 4 : }
1358 :
1359 :
1360 :
1361 :
1362 :
1363 6 : CATCH_TEST_CASE("config_comment_tests")
1364 : {
1365 8 : CATCH_START_SECTION("ini comment")
1366 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("comment", "ini");
1367 :
1368 : {
1369 2 : std::ofstream config_file;
1370 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
1371 1 : CATCH_REQUIRE(config_file.good());
1372 1 : config_file <<
1373 : "; Auto-generated\n"
1374 : "ini=comment\n"
1375 : ";ignore=this one\n"
1376 : "is=the semi-colon\n"
1377 : ";continuation=with Unix\\\n"
1378 : "also=works for\\\n"
1379 : "comments\n"
1380 : ;
1381 : }
1382 :
1383 : advgetopt::conf_file_setup setup(SNAP_CATCH2_NAMESPACE::g_config_filename
1384 : , advgetopt::line_continuation_t::line_continuation_unix
1385 : , advgetopt::ASSIGNMENT_OPERATOR_EQUAL
1386 : , advgetopt::COMMENT_INI
1387 2 : , advgetopt::SECTION_OPERATOR_NONE);
1388 :
1389 1 : CATCH_REQUIRE(setup.get_original_filename() == SNAP_CATCH2_NAMESPACE::g_config_filename);
1390 :
1391 1 : CATCH_REQUIRE(setup.is_valid());
1392 1 : CATCH_REQUIRE(setup.get_line_continuation() == advgetopt::line_continuation_t::line_continuation_unix);
1393 1 : CATCH_REQUIRE(setup.get_assignment_operator() == advgetopt::ASSIGNMENT_OPERATOR_EQUAL);
1394 1 : CATCH_REQUIRE(setup.get_comment() == advgetopt::COMMENT_INI);
1395 1 : CATCH_REQUIRE(setup.get_section_operator() == advgetopt::SECTION_OPERATOR_NONE);
1396 :
1397 2 : advgetopt::conf_file::pointer_t file(advgetopt::conf_file::get_conf_file(setup));
1398 :
1399 1 : CATCH_REQUIRE(file->get_setup().get_config_url() == setup.get_config_url());
1400 1 : CATCH_REQUIRE(file->get_errno() == 0);
1401 1 : CATCH_REQUIRE(file->get_sections().empty());
1402 1 : CATCH_REQUIRE(file->get_parameters().size() == 2);
1403 :
1404 1 : CATCH_REQUIRE(file->has_parameter("ini"));
1405 1 : CATCH_REQUIRE(file->has_parameter("is"));
1406 :
1407 1 : CATCH_REQUIRE(file->get_parameter("ini") == "comment");
1408 1 : CATCH_REQUIRE(file->get_parameter("is") == "the semi-colon");
1409 : CATCH_END_SECTION()
1410 :
1411 8 : CATCH_START_SECTION("shell comment")
1412 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("comment", "shell");
1413 :
1414 : {
1415 2 : std::ofstream config_file;
1416 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
1417 1 : CATCH_REQUIRE(config_file.good());
1418 1 : config_file <<
1419 : "# Auto-generated\n"
1420 : "shell=comment\n"
1421 : "#ignore=this one\n"
1422 : "is=the hash (`#`) character\n"
1423 : "#continuation=with Unix\\\n"
1424 : "also=works for\\\n"
1425 : "comments\n"
1426 : ;
1427 : }
1428 :
1429 : advgetopt::conf_file_setup setup(SNAP_CATCH2_NAMESPACE::g_config_filename
1430 : , advgetopt::line_continuation_t::line_continuation_unix
1431 : , advgetopt::ASSIGNMENT_OPERATOR_EQUAL
1432 : , advgetopt::COMMENT_SHELL
1433 2 : , advgetopt::SECTION_OPERATOR_NONE);
1434 :
1435 1 : CATCH_REQUIRE(setup.get_original_filename() == SNAP_CATCH2_NAMESPACE::g_config_filename);
1436 :
1437 1 : CATCH_REQUIRE(setup.is_valid());
1438 1 : CATCH_REQUIRE(setup.get_line_continuation() == advgetopt::line_continuation_t::line_continuation_unix);
1439 1 : CATCH_REQUIRE(setup.get_assignment_operator() == advgetopt::ASSIGNMENT_OPERATOR_EQUAL);
1440 1 : CATCH_REQUIRE(setup.get_comment() == advgetopt::COMMENT_SHELL);
1441 1 : CATCH_REQUIRE(setup.get_section_operator() == advgetopt::SECTION_OPERATOR_NONE);
1442 :
1443 2 : advgetopt::conf_file::pointer_t file(advgetopt::conf_file::get_conf_file(setup));
1444 :
1445 1 : CATCH_REQUIRE(file->get_setup().get_config_url() == setup.get_config_url());
1446 1 : CATCH_REQUIRE(file->get_errno() == 0);
1447 1 : CATCH_REQUIRE(file->get_sections().empty());
1448 1 : CATCH_REQUIRE(file->get_parameters().size() == 2);
1449 :
1450 1 : CATCH_REQUIRE(file->has_parameter("shell"));
1451 1 : CATCH_REQUIRE(file->has_parameter("is"));
1452 :
1453 1 : CATCH_REQUIRE(file->get_parameter("shell") == "comment");
1454 1 : CATCH_REQUIRE(file->get_parameter("is") == "the hash (`#`) character");
1455 : CATCH_END_SECTION()
1456 :
1457 8 : CATCH_START_SECTION("C++ comment")
1458 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("comment", "cpp");
1459 :
1460 : {
1461 2 : std::ofstream config_file;
1462 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
1463 1 : CATCH_REQUIRE(config_file.good());
1464 1 : config_file <<
1465 : "// Auto-generated\n"
1466 : "cpp=comment\n"
1467 : "//ignore=this one\n"
1468 : "is=the double slash (`//`)\n"
1469 : "//continuation=with Unix\\\n"
1470 : "also=works for\\\n"
1471 : "comments\n"
1472 : ;
1473 : }
1474 :
1475 : advgetopt::conf_file_setup setup(SNAP_CATCH2_NAMESPACE::g_config_filename
1476 : , advgetopt::line_continuation_t::line_continuation_unix
1477 : , advgetopt::ASSIGNMENT_OPERATOR_EQUAL
1478 : , advgetopt::COMMENT_CPP
1479 2 : , advgetopt::SECTION_OPERATOR_NONE);
1480 :
1481 1 : CATCH_REQUIRE(setup.get_original_filename() == SNAP_CATCH2_NAMESPACE::g_config_filename);
1482 :
1483 1 : CATCH_REQUIRE(setup.is_valid());
1484 1 : CATCH_REQUIRE(setup.get_line_continuation() == advgetopt::line_continuation_t::line_continuation_unix);
1485 1 : CATCH_REQUIRE(setup.get_assignment_operator() == advgetopt::ASSIGNMENT_OPERATOR_EQUAL);
1486 1 : CATCH_REQUIRE(setup.get_comment() == advgetopt::COMMENT_CPP);
1487 1 : CATCH_REQUIRE(setup.get_section_operator() == advgetopt::SECTION_OPERATOR_NONE);
1488 :
1489 2 : advgetopt::conf_file::pointer_t file(advgetopt::conf_file::get_conf_file(setup));
1490 :
1491 1 : CATCH_REQUIRE(file->get_setup().get_config_url() == setup.get_config_url());
1492 1 : CATCH_REQUIRE(file->get_errno() == 0);
1493 1 : CATCH_REQUIRE(file->get_sections().empty());
1494 1 : CATCH_REQUIRE(file->get_parameters().size() == 2);
1495 :
1496 1 : CATCH_REQUIRE(file->has_parameter("cpp"));
1497 1 : CATCH_REQUIRE(file->has_parameter("is"));
1498 :
1499 1 : CATCH_REQUIRE(file->get_parameter("cpp") == "comment");
1500 1 : CATCH_REQUIRE(file->get_parameter("is") == "the double slash (`//`)");
1501 : CATCH_END_SECTION()
1502 :
1503 8 : CATCH_START_SECTION("All three comments")
1504 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("comment", "all-comments");
1505 :
1506 : {
1507 2 : std::ofstream config_file;
1508 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
1509 1 : CATCH_REQUIRE(config_file.good());
1510 1 : config_file <<
1511 : "// Auto-generated\n"
1512 : "all=comments\n"
1513 : ";ignore=this one\n"
1514 : "together=for powerful config support\n"
1515 : "#continuation=with Unix\\\n"
1516 : "also=works for\\\n"
1517 : "comments\n"
1518 : "but=maybe\n"
1519 : ";we=should\\\n"
1520 : "test=continuation\n"
1521 : "//with=each\\\n"
1522 : "each=type of comment\n"
1523 : ;
1524 : }
1525 :
1526 : advgetopt::conf_file_setup setup(SNAP_CATCH2_NAMESPACE::g_config_filename
1527 : , advgetopt::line_continuation_t::line_continuation_unix
1528 : , advgetopt::ASSIGNMENT_OPERATOR_EQUAL
1529 : , advgetopt::COMMENT_INI | advgetopt::COMMENT_SHELL | advgetopt::COMMENT_CPP
1530 2 : , advgetopt::SECTION_OPERATOR_NONE);
1531 :
1532 1 : CATCH_REQUIRE(setup.get_original_filename() == SNAP_CATCH2_NAMESPACE::g_config_filename);
1533 :
1534 1 : CATCH_REQUIRE(setup.is_valid());
1535 1 : CATCH_REQUIRE(setup.get_line_continuation() == advgetopt::line_continuation_t::line_continuation_unix);
1536 1 : CATCH_REQUIRE(setup.get_assignment_operator() == advgetopt::ASSIGNMENT_OPERATOR_EQUAL);
1537 1 : CATCH_REQUIRE(setup.get_comment() == (advgetopt::COMMENT_INI | advgetopt::COMMENT_SHELL | advgetopt::COMMENT_CPP));
1538 1 : CATCH_REQUIRE(setup.get_section_operator() == advgetopt::SECTION_OPERATOR_NONE);
1539 :
1540 2 : advgetopt::conf_file::pointer_t file(advgetopt::conf_file::get_conf_file(setup));
1541 :
1542 1 : CATCH_REQUIRE(file->get_setup().get_config_url() == setup.get_config_url());
1543 1 : CATCH_REQUIRE(file->get_errno() == 0);
1544 1 : CATCH_REQUIRE(file->get_sections().empty());
1545 1 : CATCH_REQUIRE(file->get_parameters().size() == 3);
1546 :
1547 1 : CATCH_REQUIRE(file->has_parameter("all"));
1548 1 : CATCH_REQUIRE(file->has_parameter("together"));
1549 1 : CATCH_REQUIRE(file->has_parameter("but"));
1550 :
1551 1 : CATCH_REQUIRE(file->get_parameter("all") == "comments");
1552 1 : CATCH_REQUIRE(file->get_parameter("together") == "for powerful config support");
1553 1 : CATCH_REQUIRE(file->get_parameter("but") == "maybe");
1554 : CATCH_END_SECTION()
1555 4 : }
1556 :
1557 :
1558 :
1559 :
1560 :
1561 7 : CATCH_TEST_CASE("config_section_tests")
1562 : {
1563 10 : CATCH_START_SECTION("section operator c (.)")
1564 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("section-operator", "section-c");
1565 :
1566 : {
1567 2 : std::ofstream config_file;
1568 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
1569 1 : CATCH_REQUIRE(config_file.good());
1570 1 : config_file <<
1571 : "# Auto-generated\n"
1572 : "a=color\n"
1573 : "a.b=red\n"
1574 : "a.b.c=122\n"
1575 : "m=size\n"
1576 : "z=edge\n"
1577 : "z.b=line\n"
1578 : "z.b.c=12.72\n"
1579 : ;
1580 : }
1581 :
1582 : advgetopt::conf_file_setup setup(SNAP_CATCH2_NAMESPACE::g_config_filename
1583 : , advgetopt::line_continuation_t::line_continuation_unix
1584 : , advgetopt::ASSIGNMENT_OPERATOR_EQUAL
1585 : , advgetopt::COMMENT_SHELL
1586 2 : , advgetopt::SECTION_OPERATOR_C);
1587 :
1588 1 : CATCH_REQUIRE(setup.get_original_filename() == SNAP_CATCH2_NAMESPACE::g_config_filename);
1589 :
1590 1 : CATCH_REQUIRE(setup.is_valid());
1591 1 : CATCH_REQUIRE(setup.get_line_continuation() == advgetopt::line_continuation_t::line_continuation_unix);
1592 1 : CATCH_REQUIRE(setup.get_assignment_operator() == advgetopt::ASSIGNMENT_OPERATOR_EQUAL);
1593 1 : CATCH_REQUIRE(setup.get_comment() == advgetopt::COMMENT_SHELL);
1594 1 : CATCH_REQUIRE(setup.get_section_operator() == advgetopt::SECTION_OPERATOR_C);
1595 :
1596 2 : advgetopt::conf_file::pointer_t file(advgetopt::conf_file::get_conf_file(setup));
1597 :
1598 1 : CATCH_REQUIRE(file->get_setup().get_config_url() == setup.get_config_url());
1599 1 : CATCH_REQUIRE(file->get_errno() == 0);
1600 :
1601 2 : advgetopt::conf_file::sections_t sections(file->get_sections());
1602 1 : CATCH_REQUIRE(sections.size() == 4);
1603 1 : CATCH_REQUIRE(sections.find("a") != sections.end());
1604 1 : CATCH_REQUIRE(sections.find("a::b") != sections.end());
1605 1 : CATCH_REQUIRE(sections.find("z") != sections.end());
1606 1 : CATCH_REQUIRE(sections.find("z::b") != sections.end());
1607 :
1608 1 : CATCH_REQUIRE(file->get_parameters().size() == 7);
1609 :
1610 1 : CATCH_REQUIRE(file->has_parameter("a"));
1611 1 : CATCH_REQUIRE(file->has_parameter("a::b"));
1612 1 : CATCH_REQUIRE(file->has_parameter("a::b::c"));
1613 1 : CATCH_REQUIRE(file->has_parameter("m"));
1614 1 : CATCH_REQUIRE(file->has_parameter("z"));
1615 1 : CATCH_REQUIRE(file->has_parameter("z::b"));
1616 1 : CATCH_REQUIRE(file->has_parameter("z::b::c"));
1617 :
1618 1 : CATCH_REQUIRE(file->get_parameter("a") == "color");
1619 1 : CATCH_REQUIRE(file->get_parameter("a::b") == "red");
1620 1 : CATCH_REQUIRE(file->get_parameter("a::b::c") == "122");
1621 1 : CATCH_REQUIRE(file->get_parameter("m") == "size");
1622 1 : CATCH_REQUIRE(file->get_parameter("z") == "edge");
1623 1 : CATCH_REQUIRE(file->get_parameter("z::b") == "line");
1624 1 : CATCH_REQUIRE(file->get_parameter("z::b::c") == "12.72");
1625 : CATCH_END_SECTION()
1626 :
1627 10 : CATCH_START_SECTION("section operator c++ (::)")
1628 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("section-operator", "section-cpp");
1629 :
1630 : {
1631 2 : std::ofstream config_file;
1632 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
1633 1 : CATCH_REQUIRE(config_file.good());
1634 1 : config_file <<
1635 : "# Auto-generated\n"
1636 : "a=color\n"
1637 : "a::b=red\n"
1638 : "a::b::c=122\n"
1639 : "m=size\n"
1640 : "z=edge\n"
1641 : "z::b=line\n"
1642 : "z::b::c=12.72\n"
1643 : ;
1644 : }
1645 :
1646 : advgetopt::conf_file_setup setup(SNAP_CATCH2_NAMESPACE::g_config_filename
1647 : , advgetopt::line_continuation_t::line_continuation_unix
1648 : , advgetopt::ASSIGNMENT_OPERATOR_EQUAL
1649 : , advgetopt::COMMENT_SHELL
1650 2 : , advgetopt::SECTION_OPERATOR_CPP);
1651 :
1652 1 : CATCH_REQUIRE(setup.get_original_filename() == SNAP_CATCH2_NAMESPACE::g_config_filename);
1653 :
1654 1 : CATCH_REQUIRE(setup.is_valid());
1655 1 : CATCH_REQUIRE(setup.get_line_continuation() == advgetopt::line_continuation_t::line_continuation_unix);
1656 1 : CATCH_REQUIRE(setup.get_assignment_operator() == advgetopt::ASSIGNMENT_OPERATOR_EQUAL);
1657 1 : CATCH_REQUIRE(setup.get_comment() == advgetopt::COMMENT_SHELL);
1658 1 : CATCH_REQUIRE(setup.get_section_operator() == advgetopt::SECTION_OPERATOR_CPP);
1659 :
1660 2 : advgetopt::conf_file::pointer_t file(advgetopt::conf_file::get_conf_file(setup));
1661 :
1662 1 : CATCH_REQUIRE(file->get_setup().get_config_url() == setup.get_config_url());
1663 1 : CATCH_REQUIRE(file->get_errno() == 0);
1664 :
1665 2 : advgetopt::conf_file::sections_t sections(file->get_sections());
1666 1 : CATCH_REQUIRE(sections.size() == 4);
1667 1 : CATCH_REQUIRE(sections.find("a") != sections.end());
1668 1 : CATCH_REQUIRE(sections.find("a::b") != sections.end());
1669 1 : CATCH_REQUIRE(sections.find("z") != sections.end());
1670 1 : CATCH_REQUIRE(sections.find("z::b") != sections.end());
1671 :
1672 1 : CATCH_REQUIRE(file->get_parameters().size() == 7);
1673 :
1674 1 : CATCH_REQUIRE(file->has_parameter("a"));
1675 1 : CATCH_REQUIRE(file->has_parameter("a::b"));
1676 1 : CATCH_REQUIRE(file->has_parameter("a::b::c"));
1677 1 : CATCH_REQUIRE(file->has_parameter("m"));
1678 1 : CATCH_REQUIRE(file->has_parameter("z"));
1679 1 : CATCH_REQUIRE(file->has_parameter("z::b"));
1680 1 : CATCH_REQUIRE(file->has_parameter("z::b::c"));
1681 :
1682 1 : CATCH_REQUIRE(file->get_parameter("a") == "color");
1683 1 : CATCH_REQUIRE(file->get_parameter("a::b") == "red");
1684 1 : CATCH_REQUIRE(file->get_parameter("a::b::c") == "122");
1685 1 : CATCH_REQUIRE(file->get_parameter("m") == "size");
1686 1 : CATCH_REQUIRE(file->get_parameter("z") == "edge");
1687 1 : CATCH_REQUIRE(file->get_parameter("z::b") == "line");
1688 1 : CATCH_REQUIRE(file->get_parameter("z::b::c") == "12.72");
1689 : CATCH_END_SECTION()
1690 :
1691 10 : CATCH_START_SECTION("section operator block ({ ... })")
1692 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("section-operator", "section-block");
1693 :
1694 : {
1695 2 : std::ofstream config_file;
1696 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
1697 1 : CATCH_REQUIRE(config_file.good());
1698 1 : config_file <<
1699 : "# Auto-generated\n"
1700 : "a=color\n"
1701 : "a {\n"
1702 : " b=red\n"
1703 : " b {\n"
1704 : " c=122\n"
1705 : " }\n"
1706 : "}\n"
1707 : "m=size\n"
1708 : "z=edge\n"
1709 : "z {\n"
1710 : " b {\n"
1711 : " c=12.72\n"
1712 : " }\n"
1713 : " b=line\n"
1714 : "}\n"
1715 : ;
1716 : }
1717 :
1718 : advgetopt::conf_file_setup setup(SNAP_CATCH2_NAMESPACE::g_config_filename
1719 : , advgetopt::line_continuation_t::line_continuation_unix
1720 : , advgetopt::ASSIGNMENT_OPERATOR_EQUAL
1721 : , advgetopt::COMMENT_SHELL
1722 2 : , advgetopt::SECTION_OPERATOR_BLOCK);
1723 :
1724 1 : CATCH_REQUIRE(setup.get_original_filename() == SNAP_CATCH2_NAMESPACE::g_config_filename);
1725 :
1726 1 : CATCH_REQUIRE(setup.is_valid());
1727 1 : CATCH_REQUIRE(setup.get_line_continuation() == advgetopt::line_continuation_t::line_continuation_unix);
1728 1 : CATCH_REQUIRE(setup.get_assignment_operator() == advgetopt::ASSIGNMENT_OPERATOR_EQUAL);
1729 1 : CATCH_REQUIRE(setup.get_comment() == advgetopt::COMMENT_SHELL);
1730 1 : CATCH_REQUIRE(setup.get_section_operator() == advgetopt::SECTION_OPERATOR_BLOCK);
1731 :
1732 2 : advgetopt::conf_file::pointer_t file(advgetopt::conf_file::get_conf_file(setup));
1733 :
1734 1 : CATCH_REQUIRE(file->get_setup().get_config_url() == setup.get_config_url());
1735 1 : CATCH_REQUIRE(file->get_errno() == 0);
1736 :
1737 2 : advgetopt::conf_file::sections_t sections(file->get_sections());
1738 1 : CATCH_REQUIRE(sections.size() == 4);
1739 1 : CATCH_REQUIRE(sections.find("a") != sections.end());
1740 1 : CATCH_REQUIRE(sections.find("a::b") != sections.end());
1741 1 : CATCH_REQUIRE(sections.find("z") != sections.end());
1742 1 : CATCH_REQUIRE(sections.find("z::b") != sections.end());
1743 :
1744 1 : CATCH_REQUIRE(file->get_parameters().size() == 7);
1745 :
1746 1 : CATCH_REQUIRE(file->has_parameter("a"));
1747 1 : CATCH_REQUIRE(file->has_parameter("a::b"));
1748 1 : CATCH_REQUIRE(file->has_parameter("a::b::c"));
1749 1 : CATCH_REQUIRE(file->has_parameter("m"));
1750 1 : CATCH_REQUIRE(file->has_parameter("z"));
1751 1 : CATCH_REQUIRE(file->has_parameter("z::b"));
1752 1 : CATCH_REQUIRE(file->has_parameter("z::b::c"));
1753 :
1754 1 : CATCH_REQUIRE(file->get_parameter("a") == "color");
1755 1 : CATCH_REQUIRE(file->get_parameter("a::b") == "red");
1756 1 : CATCH_REQUIRE(file->get_parameter("a::b::c") == "122");
1757 1 : CATCH_REQUIRE(file->get_parameter("m") == "size");
1758 1 : CATCH_REQUIRE(file->get_parameter("z") == "edge");
1759 1 : CATCH_REQUIRE(file->get_parameter("z::b") == "line");
1760 1 : CATCH_REQUIRE(file->get_parameter("z::b::c") == "12.72");
1761 : CATCH_END_SECTION()
1762 :
1763 10 : CATCH_START_SECTION("section operator ini file ([...])")
1764 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("section-operator", "section-ini-file");
1765 :
1766 : {
1767 2 : std::ofstream config_file;
1768 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
1769 1 : CATCH_REQUIRE(config_file.good());
1770 1 : config_file <<
1771 : "# Auto-generated\n"
1772 : "a=color\n"
1773 : "[a]\n"
1774 : "b=red\n"
1775 : "b-c=122\n"
1776 : "[]\n"
1777 : "m=size\n"
1778 : "z=edge\n"
1779 : "[z] # we allow comments here\n"
1780 : "b=line\n"
1781 : "b-c=12.72\n"
1782 : "[p]#nospacenecessary\n"
1783 : "b=comment\n"
1784 : "b-c=allowed\n"
1785 : ;
1786 : }
1787 :
1788 : advgetopt::conf_file_setup setup(SNAP_CATCH2_NAMESPACE::g_config_filename
1789 : , advgetopt::line_continuation_t::line_continuation_unix
1790 : , advgetopt::ASSIGNMENT_OPERATOR_EQUAL
1791 : , advgetopt::COMMENT_SHELL
1792 2 : , advgetopt::SECTION_OPERATOR_INI_FILE);
1793 :
1794 1 : CATCH_REQUIRE(setup.get_original_filename() == SNAP_CATCH2_NAMESPACE::g_config_filename);
1795 :
1796 1 : CATCH_REQUIRE(setup.is_valid());
1797 1 : CATCH_REQUIRE(setup.get_line_continuation() == advgetopt::line_continuation_t::line_continuation_unix);
1798 1 : CATCH_REQUIRE(setup.get_assignment_operator() == advgetopt::ASSIGNMENT_OPERATOR_EQUAL);
1799 1 : CATCH_REQUIRE(setup.get_comment() == advgetopt::COMMENT_SHELL);
1800 1 : CATCH_REQUIRE(setup.get_section_operator() == advgetopt::SECTION_OPERATOR_INI_FILE);
1801 :
1802 2 : advgetopt::conf_file::pointer_t file(advgetopt::conf_file::get_conf_file(setup));
1803 :
1804 1 : CATCH_REQUIRE(file->get_setup().get_config_url() == setup.get_config_url());
1805 1 : CATCH_REQUIRE(file->get_errno() == 0);
1806 :
1807 2 : advgetopt::conf_file::sections_t sections(file->get_sections());
1808 1 : CATCH_REQUIRE(sections.size() == 3);
1809 1 : CATCH_REQUIRE(sections.find("a") != sections.end());
1810 1 : CATCH_REQUIRE(sections.find("z") != sections.end());
1811 1 : CATCH_REQUIRE(sections.find("p") != sections.end());
1812 :
1813 1 : CATCH_REQUIRE(file->get_parameters().size() == 9);
1814 :
1815 1 : CATCH_REQUIRE(file->has_parameter("a"));
1816 1 : CATCH_REQUIRE(file->has_parameter("a::b"));
1817 1 : CATCH_REQUIRE(file->has_parameter("a::b-c"));
1818 1 : CATCH_REQUIRE(file->has_parameter("m"));
1819 1 : CATCH_REQUIRE(file->has_parameter("z"));
1820 1 : CATCH_REQUIRE(file->has_parameter("z::b"));
1821 1 : CATCH_REQUIRE(file->has_parameter("z::b-c"));
1822 1 : CATCH_REQUIRE(file->has_parameter("p::b"));
1823 1 : CATCH_REQUIRE(file->has_parameter("p::b-c"));
1824 :
1825 1 : CATCH_REQUIRE(file->get_parameter("a") == "color");
1826 1 : CATCH_REQUIRE(file->get_parameter("a::b") == "red");
1827 1 : CATCH_REQUIRE(file->get_parameter("a::b-c") == "122");
1828 1 : CATCH_REQUIRE(file->get_parameter("m") == "size");
1829 1 : CATCH_REQUIRE(file->get_parameter("z") == "edge");
1830 1 : CATCH_REQUIRE(file->get_parameter("z::b") == "line");
1831 1 : CATCH_REQUIRE(file->get_parameter("z::b-c") == "12.72");
1832 1 : CATCH_REQUIRE(file->get_parameter("p::b") == "comment");
1833 1 : CATCH_REQUIRE(file->get_parameter("p::b-c") == "allowed");
1834 : CATCH_END_SECTION()
1835 :
1836 10 : CATCH_START_SECTION("section operator ini-file & c++")
1837 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("section-operator", "section-double");
1838 :
1839 : {
1840 2 : std::ofstream config_file;
1841 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
1842 1 : CATCH_REQUIRE(config_file.good());
1843 1 : config_file <<
1844 : "# Auto-generated\n"
1845 : "[a]\n"
1846 : "b=red\n"
1847 : "b::c=209\n"
1848 : "::h=high\n"
1849 : "m=size\n"
1850 : "[z]\n"
1851 : "z=edge\n"
1852 : "::b=line\n"
1853 : "z::b::c=17.92\n"
1854 : ;
1855 : }
1856 :
1857 : advgetopt::conf_file_setup setup(SNAP_CATCH2_NAMESPACE::g_config_filename
1858 : , advgetopt::line_continuation_t::line_continuation_unix
1859 : , advgetopt::ASSIGNMENT_OPERATOR_EQUAL
1860 : , advgetopt::COMMENT_SHELL
1861 2 : , advgetopt::SECTION_OPERATOR_INI_FILE | advgetopt::SECTION_OPERATOR_CPP);
1862 :
1863 1 : CATCH_REQUIRE(setup.get_original_filename() == SNAP_CATCH2_NAMESPACE::g_config_filename);
1864 :
1865 1 : CATCH_REQUIRE(setup.is_valid());
1866 1 : CATCH_REQUIRE(setup.get_line_continuation() == advgetopt::line_continuation_t::line_continuation_unix);
1867 1 : CATCH_REQUIRE(setup.get_assignment_operator() == advgetopt::ASSIGNMENT_OPERATOR_EQUAL);
1868 1 : CATCH_REQUIRE(setup.get_comment() == advgetopt::COMMENT_SHELL);
1869 1 : CATCH_REQUIRE(setup.get_section_operator() == (advgetopt::SECTION_OPERATOR_INI_FILE | advgetopt::SECTION_OPERATOR_CPP));
1870 :
1871 2 : advgetopt::conf_file::pointer_t file(advgetopt::conf_file::get_conf_file(setup));
1872 :
1873 1 : CATCH_REQUIRE(file->get_setup().get_config_url() == setup.get_config_url());
1874 1 : CATCH_REQUIRE(file->get_errno() == 0);
1875 :
1876 2 : advgetopt::conf_file::sections_t sections(file->get_sections());
1877 1 : CATCH_REQUIRE(sections.size() == 4);
1878 1 : CATCH_REQUIRE(sections.find("a") != sections.end());
1879 1 : CATCH_REQUIRE(sections.find("a::b") != sections.end());
1880 1 : CATCH_REQUIRE(sections.find("z") != sections.end());
1881 1 : CATCH_REQUIRE(sections.find("z::z::b") != sections.end());
1882 :
1883 1 : CATCH_REQUIRE(file->get_parameters().size() == 7);
1884 :
1885 1 : CATCH_REQUIRE(file->has_parameter("a::b"));
1886 1 : CATCH_REQUIRE(file->has_parameter("a::b::c"));
1887 1 : CATCH_REQUIRE(file->has_parameter("h"));
1888 1 : CATCH_REQUIRE(file->has_parameter("a::m"));
1889 1 : CATCH_REQUIRE(file->has_parameter("z::z"));
1890 1 : CATCH_REQUIRE(file->has_parameter("b"));
1891 1 : CATCH_REQUIRE(file->has_parameter("z::z::b::c"));
1892 :
1893 1 : CATCH_REQUIRE(file->get_parameter("a::b") == "red");
1894 1 : CATCH_REQUIRE(file->get_parameter("a::b::c") == "209");
1895 1 : CATCH_REQUIRE(file->get_parameter("h") == "high");
1896 1 : CATCH_REQUIRE(file->get_parameter("a::m") == "size");
1897 1 : CATCH_REQUIRE(file->get_parameter("z::z") == "edge");
1898 1 : CATCH_REQUIRE(file->get_parameter("b") == "line");
1899 1 : CATCH_REQUIRE(file->get_parameter("z::z::b::c") == "17.92");
1900 : CATCH_END_SECTION()
1901 5 : }
1902 :
1903 :
1904 :
1905 :
1906 3 : CATCH_TEST_CASE("save_config_file")
1907 : {
1908 2 : CATCH_START_SECTION("load update save")
1909 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("save-operation", "configuration");
1910 :
1911 : {
1912 2 : std::ofstream config_file;
1913 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
1914 1 : CATCH_REQUIRE(config_file.good());
1915 1 : config_file <<
1916 : "# Auto-generated\n"
1917 : "a=color\n"
1918 : "b=red\n"
1919 : "c=122\n"
1920 : ;
1921 : }
1922 :
1923 : advgetopt::conf_file_setup setup(SNAP_CATCH2_NAMESPACE::g_config_filename
1924 : , advgetopt::line_continuation_t::line_continuation_single_line
1925 : , advgetopt::ASSIGNMENT_OPERATOR_EQUAL
1926 : , advgetopt::COMMENT_SHELL
1927 2 : , advgetopt::SECTION_OPERATOR_NONE);
1928 :
1929 1 : CATCH_REQUIRE(setup.get_original_filename() == SNAP_CATCH2_NAMESPACE::g_config_filename);
1930 :
1931 1 : CATCH_REQUIRE(setup.is_valid());
1932 1 : CATCH_REQUIRE(setup.get_line_continuation() == advgetopt::line_continuation_t::line_continuation_single_line);
1933 1 : CATCH_REQUIRE(setup.get_assignment_operator() == advgetopt::ASSIGNMENT_OPERATOR_EQUAL);
1934 1 : CATCH_REQUIRE(setup.get_comment() == advgetopt::COMMENT_SHELL);
1935 1 : CATCH_REQUIRE(setup.get_section_operator() == advgetopt::SECTION_OPERATOR_NONE);
1936 :
1937 2 : advgetopt::conf_file::pointer_t file(advgetopt::conf_file::get_conf_file(setup));
1938 :
1939 1 : CATCH_REQUIRE(file->get_setup().get_config_url() == setup.get_config_url());
1940 1 : CATCH_REQUIRE(file->get_errno() == 0);
1941 :
1942 2 : advgetopt::conf_file::sections_t sections(file->get_sections());
1943 1 : CATCH_REQUIRE(sections.empty());
1944 :
1945 1 : CATCH_REQUIRE(file->get_parameters().size() == 3);
1946 :
1947 1 : CATCH_REQUIRE(file->has_parameter("a"));
1948 1 : CATCH_REQUIRE(file->has_parameter("b"));
1949 1 : CATCH_REQUIRE(file->has_parameter("c"));
1950 :
1951 1 : CATCH_REQUIRE(file->get_parameter("a") == "color");
1952 1 : CATCH_REQUIRE(file->get_parameter("b") == "red");
1953 1 : CATCH_REQUIRE(file->get_parameter("c") == "122");
1954 :
1955 1 : CATCH_REQUIRE(file->save_configuration());
1956 :
1957 : // no backup since there was no modification so the save did nothing
1958 : //
1959 1 : CATCH_REQUIRE(access((SNAP_CATCH2_NAMESPACE::g_config_filename + ".bak").c_str(), F_OK) != 0);
1960 :
1961 1 : file->set_parameter(std::string(), "a", "size");
1962 1 : file->set_parameter(std::string(), "b", "tall");
1963 1 : file->set_parameter(std::string(), "c", "1920");
1964 :
1965 1 : CATCH_REQUIRE(file->save_configuration());
1966 :
1967 1 : CATCH_REQUIRE(access((SNAP_CATCH2_NAMESPACE::g_config_filename + ".bak").c_str(), F_OK) == 0);
1968 :
1969 2 : std::string const new_name(SNAP_CATCH2_NAMESPACE::g_config_filename + ".conf2");
1970 1 : rename(SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(), new_name.c_str());
1971 :
1972 : advgetopt::conf_file_setup setup2(new_name
1973 : , advgetopt::line_continuation_t::line_continuation_single_line
1974 : , advgetopt::ASSIGNMENT_OPERATOR_EQUAL
1975 : , advgetopt::COMMENT_SHELL
1976 2 : , advgetopt::SECTION_OPERATOR_NONE);
1977 :
1978 1 : CATCH_REQUIRE(setup.get_original_filename() == SNAP_CATCH2_NAMESPACE::g_config_filename);
1979 :
1980 1 : CATCH_REQUIRE(setup2.is_valid());
1981 1 : CATCH_REQUIRE(setup2.get_line_continuation() == advgetopt::line_continuation_t::line_continuation_single_line);
1982 1 : CATCH_REQUIRE(setup2.get_assignment_operator() == advgetopt::ASSIGNMENT_OPERATOR_EQUAL);
1983 1 : CATCH_REQUIRE(setup2.get_comment() == advgetopt::COMMENT_SHELL);
1984 1 : CATCH_REQUIRE(setup2.get_section_operator() == advgetopt::SECTION_OPERATOR_NONE);
1985 :
1986 2 : advgetopt::conf_file::pointer_t file2(advgetopt::conf_file::get_conf_file(setup2));
1987 :
1988 1 : CATCH_REQUIRE(file2->get_setup().get_config_url() == setup2.get_config_url());
1989 1 : CATCH_REQUIRE(file2->get_errno() == 0);
1990 :
1991 1 : CATCH_REQUIRE(file->get_sections().empty());
1992 :
1993 1 : CATCH_REQUIRE(file2->get_parameters().size() == 3);
1994 :
1995 1 : CATCH_REQUIRE(file2->has_parameter("a"));
1996 1 : CATCH_REQUIRE(file2->has_parameter("b"));
1997 1 : CATCH_REQUIRE(file2->has_parameter("c"));
1998 :
1999 1 : CATCH_REQUIRE(file2->get_parameter("a") == "size");
2000 1 : CATCH_REQUIRE(file2->get_parameter("b") == "tall");
2001 1 : CATCH_REQUIRE(file2->get_parameter("c") == "1920");
2002 : CATCH_END_SECTION()
2003 1 : }
2004 :
2005 :
2006 :
2007 :
2008 :
2009 :
2010 :
2011 4 : CATCH_TEST_CASE("invalid_configuration_setup", "[config][getopt][invalid]")
2012 : {
2013 4 : CATCH_START_SECTION("Empty Filename")
2014 1 : CATCH_REQUIRE_THROWS_MATCHES(
2015 : advgetopt::conf_file_setup(
2016 : std::string()
2017 : , static_cast<advgetopt::line_continuation_t>(rand())
2018 : , rand()
2019 : , rand()
2020 : , rand())
2021 : , advgetopt::getopt_invalid
2022 : , Catch::Matchers::ExceptionMessage(
2023 : "getopt_exception: trying to load a configuration file using an empty filename."));
2024 : CATCH_END_SECTION()
2025 :
2026 4 : CATCH_START_SECTION("Invalid Line Continuation")
2027 6 : for(int count(0); count < 5; ++count)
2028 : {
2029 5 : advgetopt::line_continuation_t lc(advgetopt::line_continuation_t::line_continuation_unix);
2030 0 : do
2031 : {
2032 5 : lc = static_cast<advgetopt::line_continuation_t>(rand());
2033 : }
2034 : while(lc >= advgetopt::line_continuation_t::line_continuation_single_line
2035 5 : && lc <= advgetopt::line_continuation_t::line_continuation_semicolon);
2036 :
2037 : advgetopt::conf_file_setup setup(
2038 : "/etc/advgetopt/system.conf"
2039 : , lc // <- this is invalid
2040 5 : , rand() & advgetopt::ASSIGNMENT_OPERATOR_MASK
2041 5 : , rand() & advgetopt::COMMENT_MASK
2042 20 : , rand() & advgetopt::SECTION_OPERATOR_MASK);
2043 :
2044 5 : CATCH_REQUIRE(setup.is_valid());
2045 :
2046 5 : CATCH_REQUIRE_THROWS_MATCHES(
2047 : setup.get_config_url()
2048 : , advgetopt::getopt_logic_error
2049 : , Catch::Matchers::ExceptionMessage(
2050 : "getopt_logic_error: unexpected line continuation."));
2051 : }
2052 : CATCH_END_SECTION()
2053 2 : }
2054 :
2055 :
2056 :
2057 :
2058 :
2059 :
2060 :
2061 3 : CATCH_TEST_CASE("config_reload_invalid_setup")
2062 : {
2063 2 : CATCH_START_SECTION("Load a file, update it, verify it does not get reloaded")
2064 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("invalid-reload", "load-twice-wrong-parameters");
2065 :
2066 : {
2067 2 : std::ofstream config_file;
2068 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
2069 1 : CATCH_REQUIRE(config_file.good());
2070 1 : config_file <<
2071 : "# Auto-generated\n"
2072 : "duplicates=work\n"
2073 : "varying=parameters\n"
2074 : "however=is\n"
2075 : "not=valid\n"
2076 : ;
2077 : }
2078 :
2079 : advgetopt::conf_file_setup setup(SNAP_CATCH2_NAMESPACE::g_config_filename
2080 : , advgetopt::line_continuation_t::line_continuation_single_line
2081 : , advgetopt::ASSIGNMENT_OPERATOR_EQUAL
2082 : , advgetopt::COMMENT_SHELL
2083 2 : , advgetopt::SECTION_OPERATOR_NONE);
2084 :
2085 1 : CATCH_REQUIRE(setup.is_valid());
2086 1 : CATCH_REQUIRE(setup.get_line_continuation() == advgetopt::line_continuation_t::line_continuation_single_line);
2087 1 : CATCH_REQUIRE(setup.get_assignment_operator() == advgetopt::ASSIGNMENT_OPERATOR_EQUAL);
2088 1 : CATCH_REQUIRE(setup.get_comment() == advgetopt::COMMENT_SHELL);
2089 1 : CATCH_REQUIRE(setup.get_section_operator() == advgetopt::SECTION_OPERATOR_NONE);
2090 :
2091 2 : advgetopt::conf_file::pointer_t file(advgetopt::conf_file::get_conf_file(setup));
2092 :
2093 1 : CATCH_REQUIRE(file->get_setup().get_config_url() == setup.get_config_url());
2094 1 : CATCH_REQUIRE(file->get_errno() == 0);
2095 1 : CATCH_REQUIRE(file->get_sections().empty());
2096 1 : CATCH_REQUIRE(file->get_parameters().size() == 4);
2097 :
2098 1 : CATCH_REQUIRE(file->has_parameter("duplicates"));
2099 1 : CATCH_REQUIRE(file->has_parameter("varying"));
2100 1 : CATCH_REQUIRE(file->has_parameter("however"));
2101 1 : CATCH_REQUIRE(file->has_parameter("not"));
2102 :
2103 1 : CATCH_REQUIRE(file->get_parameter("duplicates") == "work");
2104 1 : CATCH_REQUIRE(file->get_parameter("varying") == "parameters");
2105 1 : CATCH_REQUIRE(file->get_parameter("however") == "is");
2106 1 : CATCH_REQUIRE(file->get_parameter("not") == "valid");
2107 :
2108 : // "reloading" that very same file but with the "wrong" parameters
2109 : // fails
2110 : //
2111 7 : for(int lc(static_cast<int>(advgetopt::line_continuation_t::line_continuation_single_line));
2112 7 : lc <= static_cast<int>(advgetopt::line_continuation_t::line_continuation_semicolon);
2113 : ++lc)
2114 : {
2115 6 : if(static_cast<advgetopt::line_continuation_t>(lc) == advgetopt::line_continuation_t::line_continuation_single_line)
2116 : {
2117 1 : continue;
2118 : }
2119 :
2120 45 : for(advgetopt::assignment_operator_t ao(0);
2121 45 : ao <= advgetopt::ASSIGNMENT_OPERATOR_MASK;
2122 : ++ao)
2123 : {
2124 40 : if(ao == advgetopt::ASSIGNMENT_OPERATOR_EQUAL)
2125 : {
2126 5 : continue;
2127 : }
2128 :
2129 280 : for(advgetopt::comment_t c(0);
2130 280 : c < advgetopt::COMMENT_MASK;
2131 : ++c)
2132 : {
2133 245 : if(c == advgetopt::COMMENT_SHELL)
2134 : {
2135 35 : continue;
2136 : }
2137 :
2138 3360 : for(advgetopt::section_operator_t so(0);
2139 3360 : so < advgetopt::SECTION_OPERATOR_MASK;
2140 : ++so)
2141 : {
2142 3150 : if(c == advgetopt::SECTION_OPERATOR_NONE)
2143 : {
2144 525 : continue;
2145 : }
2146 :
2147 : advgetopt::conf_file_setup different_setup(SNAP_CATCH2_NAMESPACE::g_config_filename
2148 : , static_cast<advgetopt::line_continuation_t>(lc)
2149 : , ao
2150 : , c
2151 5250 : , so);
2152 :
2153 2625 : CATCH_REQUIRE_THROWS_MATCHES(
2154 : advgetopt::conf_file::get_conf_file(different_setup)
2155 : , advgetopt::getopt_logic_error
2156 : , Catch::Matchers::ExceptionMessage(
2157 : "getopt_logic_error: trying to load configuration file \""
2158 : + different_setup.get_config_url()
2159 : + "\" but an existing configuration file with the same name was loaded with URL: \""
2160 : + setup.get_config_url()
2161 : + "\"."));
2162 : }
2163 : }
2164 : }
2165 : }
2166 : CATCH_END_SECTION()
2167 1 : }
2168 :
2169 :
2170 3 : CATCH_TEST_CASE("missing_configuration_file", "[config][getopt][invalid]")
2171 : {
2172 2 : CATCH_START_SECTION("Create a conf_file without the file")
2173 6 : for(int count(0); count < 5; ++count)
2174 : {
2175 5 : int const id(rand());
2176 10 : std::string const name("delete-file-" + std::to_string(id));
2177 :
2178 5 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("delete", name);
2179 :
2180 : {
2181 10 : std::ofstream config_file;
2182 5 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
2183 5 : CATCH_REQUIRE(config_file.good());
2184 5 : config_file <<
2185 : "# Auto-generated\n"
2186 : "param=optional\n"
2187 : ;
2188 : }
2189 :
2190 : // create the setup while the file still exists
2191 : //
2192 : advgetopt::conf_file_setup setup(
2193 : SNAP_CATCH2_NAMESPACE::g_config_filename
2194 : , advgetopt::line_continuation_t::line_continuation_unix
2195 : , advgetopt::ASSIGNMENT_OPERATOR_EQUAL
2196 : , advgetopt::COMMENT_SHELL
2197 10 : , advgetopt::SECTION_OPERATOR_NONE);
2198 :
2199 : // now unlink() that file
2200 : //
2201 5 : unlink(SNAP_CATCH2_NAMESPACE::g_config_filename.c_str());
2202 :
2203 : // still valid since we do not check again after the
2204 : // constructor ran
2205 : //
2206 5 : CATCH_REQUIRE(setup.is_valid());
2207 5 : CATCH_REQUIRE(setup.get_filename() == SNAP_CATCH2_NAMESPACE::g_config_filename);
2208 5 : CATCH_REQUIRE(setup.get_line_continuation() == advgetopt::line_continuation_t::line_continuation_unix);
2209 5 : CATCH_REQUIRE(setup.get_assignment_operator() == advgetopt::ASSIGNMENT_OPERATOR_EQUAL);
2210 5 : CATCH_REQUIRE(setup.get_comment() == advgetopt::COMMENT_SHELL);
2211 5 : CATCH_REQUIRE(setup.get_section_operator() == advgetopt::SECTION_OPERATOR_NONE);
2212 :
2213 : // so when trying to create the conf_file object it fails
2214 : // opening the file
2215 : //
2216 10 : advgetopt::conf_file::pointer_t file(advgetopt::conf_file::get_conf_file(setup));
2217 5 : CATCH_REQUIRE(file->get_errno() == ENOENT);
2218 : }
2219 : CATCH_END_SECTION()
2220 1 : }
2221 :
2222 :
2223 11 : CATCH_TEST_CASE("invalid_sections")
2224 : {
2225 18 : CATCH_START_SECTION("variable name cannot start with a period when C operator is active")
2226 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("invalid-section-operator", "period-name");
2227 :
2228 : {
2229 2 : std::ofstream config_file;
2230 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
2231 1 : CATCH_REQUIRE(config_file.good());
2232 1 : config_file <<
2233 : "# Auto-generated\n"
2234 : "a=color\n"
2235 : "a..b=red\n"
2236 : ".a.b.c=122\n"
2237 : "m=size\n"
2238 : "z=edge\n"
2239 : "z.b=line\n"
2240 : "z..b.c=12.72\n"
2241 : ;
2242 : }
2243 :
2244 : advgetopt::conf_file_setup setup(SNAP_CATCH2_NAMESPACE::g_config_filename
2245 : , advgetopt::line_continuation_t::line_continuation_unix
2246 : , advgetopt::ASSIGNMENT_OPERATOR_EQUAL
2247 : , advgetopt::COMMENT_SHELL
2248 2 : , advgetopt::SECTION_OPERATOR_C);
2249 :
2250 1 : CATCH_REQUIRE(setup.is_valid());
2251 1 : CATCH_REQUIRE(setup.get_line_continuation() == advgetopt::line_continuation_t::line_continuation_unix);
2252 1 : CATCH_REQUIRE(setup.get_assignment_operator() == advgetopt::ASSIGNMENT_OPERATOR_EQUAL);
2253 1 : CATCH_REQUIRE(setup.get_comment() == advgetopt::COMMENT_SHELL);
2254 1 : CATCH_REQUIRE(setup.get_section_operator() == advgetopt::SECTION_OPERATOR_C);
2255 :
2256 1 : SNAP_CATCH2_NAMESPACE::push_expected_log(
2257 : "error: option name \".a.b.c\" cannot start with"
2258 : " a period (.).");
2259 2 : advgetopt::conf_file::pointer_t file(advgetopt::conf_file::get_conf_file(setup));
2260 1 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
2261 :
2262 1 : CATCH_REQUIRE(file->get_setup().get_config_url() == setup.get_config_url());
2263 1 : CATCH_REQUIRE(file->get_errno() == 0);
2264 :
2265 2 : advgetopt::conf_file::sections_t sections(file->get_sections());
2266 1 : CATCH_REQUIRE(sections.size() == 3);
2267 1 : CATCH_REQUIRE(sections.find("a") != sections.end());
2268 1 : CATCH_REQUIRE(sections.find("z") != sections.end());
2269 1 : CATCH_REQUIRE(sections.find("z::b") != sections.end());
2270 :
2271 1 : CATCH_REQUIRE(file->get_parameters().size() == 6);
2272 :
2273 1 : CATCH_REQUIRE(file->has_parameter("a"));
2274 1 : CATCH_REQUIRE(file->has_parameter("a::b"));
2275 1 : CATCH_REQUIRE(file->has_parameter("m"));
2276 1 : CATCH_REQUIRE(file->has_parameter("z"));
2277 1 : CATCH_REQUIRE(file->has_parameter("z::b"));
2278 1 : CATCH_REQUIRE(file->has_parameter("z::b::c"));
2279 :
2280 1 : CATCH_REQUIRE(file->get_parameter("a") == "color");
2281 1 : CATCH_REQUIRE(file->get_parameter("a::b") == "red");
2282 1 : CATCH_REQUIRE(file->get_parameter("m") == "size");
2283 1 : CATCH_REQUIRE(file->get_parameter("z") == "edge");
2284 1 : CATCH_REQUIRE(file->get_parameter("z::b") == "line");
2285 1 : CATCH_REQUIRE(file->get_parameter("z::b::c") == "12.72");
2286 : CATCH_END_SECTION()
2287 :
2288 18 : CATCH_START_SECTION("two section operators one after another can cause trouble")
2289 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("invalid-section-operator", "name-period-cpp-name");
2290 :
2291 : {
2292 2 : std::ofstream config_file;
2293 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
2294 1 : CATCH_REQUIRE(config_file.good());
2295 1 : config_file <<
2296 : "# Auto-generated\n"
2297 : "a=color\n"
2298 : "a..b=red\n"
2299 : "a.::b.c=122\n"
2300 : "m=size\n"
2301 : "z=edge\n"
2302 : "z.b=line\n"
2303 : "z..b.c=12.72\n"
2304 : ;
2305 : }
2306 :
2307 : advgetopt::conf_file_setup setup(SNAP_CATCH2_NAMESPACE::g_config_filename
2308 : , advgetopt::line_continuation_t::line_continuation_unix
2309 : , advgetopt::ASSIGNMENT_OPERATOR_EQUAL
2310 : , advgetopt::COMMENT_SHELL
2311 2 : , advgetopt::SECTION_OPERATOR_C | advgetopt::SECTION_OPERATOR_CPP);
2312 :
2313 1 : CATCH_REQUIRE(setup.is_valid());
2314 1 : CATCH_REQUIRE(setup.get_line_continuation() == advgetopt::line_continuation_t::line_continuation_unix);
2315 1 : CATCH_REQUIRE(setup.get_assignment_operator() == advgetopt::ASSIGNMENT_OPERATOR_EQUAL);
2316 1 : CATCH_REQUIRE(setup.get_comment() == advgetopt::COMMENT_SHELL);
2317 1 : CATCH_REQUIRE(setup.get_section_operator() == (advgetopt::SECTION_OPERATOR_C | advgetopt::SECTION_OPERATOR_CPP));
2318 :
2319 1 : SNAP_CATCH2_NAMESPACE::push_expected_log(
2320 : "error: option name \"a.::b.c\" cannot start with"
2321 : " a scope operator (::).");
2322 2 : advgetopt::conf_file::pointer_t file(advgetopt::conf_file::get_conf_file(setup));
2323 1 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
2324 :
2325 1 : CATCH_REQUIRE(file->get_setup().get_config_url() == setup.get_config_url());
2326 1 : CATCH_REQUIRE(file->get_errno() == 0);
2327 :
2328 2 : advgetopt::conf_file::sections_t sections(file->get_sections());
2329 1 : CATCH_REQUIRE(sections.size() == 3);
2330 1 : CATCH_REQUIRE(sections.find("a") != sections.end());
2331 1 : CATCH_REQUIRE(sections.find("z") != sections.end());
2332 1 : CATCH_REQUIRE(sections.find("z::b") != sections.end());
2333 :
2334 1 : CATCH_REQUIRE(file->get_parameters().size() == 6);
2335 :
2336 1 : CATCH_REQUIRE(file->has_parameter("a"));
2337 1 : CATCH_REQUIRE(file->has_parameter("a::b"));
2338 1 : CATCH_REQUIRE(file->has_parameter("m"));
2339 1 : CATCH_REQUIRE(file->has_parameter("z"));
2340 1 : CATCH_REQUIRE(file->has_parameter("z::b"));
2341 1 : CATCH_REQUIRE(file->has_parameter("z::b::c"));
2342 :
2343 1 : CATCH_REQUIRE(file->get_parameter("a") == "color");
2344 1 : CATCH_REQUIRE(file->get_parameter("a::b") == "red");
2345 1 : CATCH_REQUIRE(file->get_parameter("m") == "size");
2346 1 : CATCH_REQUIRE(file->get_parameter("z") == "edge");
2347 1 : CATCH_REQUIRE(file->get_parameter("z::b") == "line");
2348 1 : CATCH_REQUIRE(file->get_parameter("z::b::c") == "12.72");
2349 : CATCH_END_SECTION()
2350 :
2351 18 : CATCH_START_SECTION("section operator cannot appear at the end")
2352 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("invalid-section-operator", "name-period-name-cpp");
2353 :
2354 : {
2355 2 : std::ofstream config_file;
2356 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
2357 1 : CATCH_REQUIRE(config_file.good());
2358 1 : config_file <<
2359 : "# Auto-generated\n"
2360 : "a=color\n"
2361 : "a..b=red\n"
2362 : "a.b.c::=122\n"
2363 : "m=size\n"
2364 : "z=edge\n"
2365 : "z.b=line\n"
2366 : "z..b.c=12.72\n"
2367 : ;
2368 : }
2369 :
2370 : advgetopt::conf_file_setup setup(SNAP_CATCH2_NAMESPACE::g_config_filename
2371 : , advgetopt::line_continuation_t::line_continuation_unix
2372 : , advgetopt::ASSIGNMENT_OPERATOR_EQUAL
2373 : , advgetopt::COMMENT_SHELL
2374 2 : , advgetopt::SECTION_OPERATOR_C | advgetopt::SECTION_OPERATOR_CPP);
2375 :
2376 1 : CATCH_REQUIRE(setup.is_valid());
2377 1 : CATCH_REQUIRE(setup.get_line_continuation() == advgetopt::line_continuation_t::line_continuation_unix);
2378 1 : CATCH_REQUIRE(setup.get_assignment_operator() == advgetopt::ASSIGNMENT_OPERATOR_EQUAL);
2379 1 : CATCH_REQUIRE(setup.get_comment() == advgetopt::COMMENT_SHELL);
2380 1 : CATCH_REQUIRE(setup.get_section_operator() == (advgetopt::SECTION_OPERATOR_C | advgetopt::SECTION_OPERATOR_CPP));
2381 :
2382 1 : SNAP_CATCH2_NAMESPACE::push_expected_log(
2383 : "error: option name \"a.b.c::\" cannot end with a"
2384 : " section operator or be empty.");
2385 2 : advgetopt::conf_file::pointer_t file(advgetopt::conf_file::get_conf_file(setup));
2386 1 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
2387 :
2388 1 : CATCH_REQUIRE(file->get_setup().get_config_url() == setup.get_config_url());
2389 1 : CATCH_REQUIRE(file->get_errno() == 0);
2390 :
2391 2 : advgetopt::conf_file::sections_t sections(file->get_sections());
2392 1 : CATCH_REQUIRE(sections.size() == 3);
2393 1 : CATCH_REQUIRE(sections.find("a") != sections.end());
2394 1 : CATCH_REQUIRE(sections.find("z") != sections.end());
2395 1 : CATCH_REQUIRE(sections.find("z::b") != sections.end());
2396 :
2397 1 : CATCH_REQUIRE(file->get_parameters().size() == 6);
2398 :
2399 1 : CATCH_REQUIRE(file->has_parameter("a"));
2400 1 : CATCH_REQUIRE(file->has_parameter("a::b"));
2401 1 : CATCH_REQUIRE(file->has_parameter("m"));
2402 1 : CATCH_REQUIRE(file->has_parameter("z"));
2403 1 : CATCH_REQUIRE(file->has_parameter("z::b"));
2404 1 : CATCH_REQUIRE(file->has_parameter("z::b::c"));
2405 :
2406 1 : CATCH_REQUIRE(file->get_parameter("a") == "color");
2407 1 : CATCH_REQUIRE(file->get_parameter("a::b") == "red");
2408 1 : CATCH_REQUIRE(file->get_parameter("m") == "size");
2409 1 : CATCH_REQUIRE(file->get_parameter("z") == "edge");
2410 1 : CATCH_REQUIRE(file->get_parameter("z::b") == "line");
2411 1 : CATCH_REQUIRE(file->get_parameter("z::b::c") == "12.72");
2412 : CATCH_END_SECTION()
2413 :
2414 18 : CATCH_START_SECTION("sections not allowed")
2415 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("invalid-section-operator", "section-not-allowed");
2416 :
2417 : {
2418 2 : std::ofstream config_file;
2419 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
2420 1 : CATCH_REQUIRE(config_file.good());
2421 1 : config_file <<
2422 : "# Auto-generated\n"
2423 : "a=color\n"
2424 : "a::b=red\n"
2425 : "m.n=size\n"
2426 : "z=edge\n"
2427 : ;
2428 : }
2429 :
2430 : // no errors here since we do not detect the sections in this case
2431 : //
2432 : advgetopt::conf_file_setup setup(SNAP_CATCH2_NAMESPACE::g_config_filename
2433 : , advgetopt::line_continuation_t::line_continuation_unix
2434 : , advgetopt::ASSIGNMENT_OPERATOR_EQUAL
2435 : , advgetopt::COMMENT_SHELL
2436 2 : , advgetopt::SECTION_OPERATOR_NONE);
2437 :
2438 1 : CATCH_REQUIRE(setup.is_valid());
2439 1 : CATCH_REQUIRE(setup.get_line_continuation() == advgetopt::line_continuation_t::line_continuation_unix);
2440 1 : CATCH_REQUIRE(setup.get_assignment_operator() == advgetopt::ASSIGNMENT_OPERATOR_EQUAL);
2441 1 : CATCH_REQUIRE(setup.get_comment() == advgetopt::COMMENT_SHELL);
2442 1 : CATCH_REQUIRE(setup.get_section_operator() == (advgetopt::SECTION_OPERATOR_NONE));
2443 :
2444 1 : SNAP_CATCH2_NAMESPACE::push_expected_log(
2445 : "error: parameter \"a::b\" on line 3 in configuration file \""
2446 2 : + SNAP_CATCH2_NAMESPACE::g_config_filename
2447 2 : + "\" includes a character not acceptable for a section or"
2448 : " parameter name (controls, space, quotes, and \";#/=:?+\\\").");
2449 2 : advgetopt::conf_file::pointer_t file(advgetopt::conf_file::get_conf_file(setup));
2450 1 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
2451 :
2452 1 : CATCH_REQUIRE(file->get_setup().get_config_url() == setup.get_config_url());
2453 1 : CATCH_REQUIRE(file->get_errno() == 0);
2454 :
2455 2 : advgetopt::conf_file::sections_t sections(file->get_sections());
2456 1 : CATCH_REQUIRE(sections.empty());
2457 :
2458 1 : CATCH_REQUIRE(file->get_parameters().size() == 3);
2459 :
2460 1 : CATCH_REQUIRE(file->has_parameter("a"));
2461 1 : CATCH_REQUIRE_FALSE(file->has_parameter("a::b"));
2462 1 : CATCH_REQUIRE(file->has_parameter("m.n"));
2463 1 : CATCH_REQUIRE(file->has_parameter("z"));
2464 :
2465 1 : CATCH_REQUIRE(file->get_parameter("a") == "color");
2466 1 : CATCH_REQUIRE(file->get_parameter("a::b") == std::string());
2467 1 : CATCH_REQUIRE(file->get_parameter("m.n") == "size");
2468 1 : CATCH_REQUIRE(file->get_parameter("z") == "edge");
2469 :
2470 1 : SNAP_CATCH2_NAMESPACE::push_expected_log(
2471 : "error: option name \"blue::shepard\" cannot be added to"
2472 : " section \"j::k\" because there is no section support"
2473 : " for this configuration file.");
2474 1 : file->set_parameter("j::k", "blue::shepard", "2001");
2475 1 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
2476 : CATCH_END_SECTION()
2477 :
2478 18 : CATCH_START_SECTION("invalid characters in names")
2479 : std::string const bad_chars(
2480 : "\x01\x02\x03\x04\x05\x06\x07"
2481 : "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
2482 : "\x10\x11\x12\x13\x14\x15\x16\x17"
2483 : "\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F"
2484 : "\x20"
2485 : "'\";#/=:?+\\"
2486 2 : );
2487 43 : for(auto c : bad_chars)
2488 : {
2489 : // white spaces get removed from the line so we cannot test
2490 : // them in this way
2491 : //
2492 42 : if(std::iswspace(c))
2493 : {
2494 6 : continue;
2495 : }
2496 72 : std::string bc;
2497 36 : bc += c;
2498 :
2499 144 : for(int pos(0); pos < 3; ++pos)
2500 : {
2501 216 : std::string spos("undefined");
2502 216 : std::string bad_char("undefined");
2503 108 : switch(pos)
2504 : {
2505 36 : case 0:
2506 36 : spos = "start";
2507 36 : bad_char = bc + "bad-char";
2508 36 : break;
2509 :
2510 36 : case 1:
2511 36 : spos = "middle";
2512 36 : bad_char = "bad" + bc + "char";
2513 36 : break;
2514 :
2515 36 : case 2:
2516 36 : spos = "end";
2517 36 : bad_char = "bad-char" + bc;
2518 36 : break;
2519 :
2520 : }
2521 108 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("invalid-characters", "bad-character-" + std::to_string(static_cast<int>(c)) + "-" + spos);
2522 :
2523 : {
2524 216 : std::ofstream config_file;
2525 108 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
2526 108 : CATCH_REQUIRE(config_file.good());
2527 108 : char op(c == '=' ? ':' : '=');
2528 : config_file <<
2529 : "good" << op << "red\n"
2530 : << bad_char << op << "color\n" // <-- bad char
2531 108 : "fine" << op << "param\n";
2532 : ;
2533 : }
2534 :
2535 : // no errors here since we do not detect the sections in this case
2536 : //
2537 108 : advgetopt::assignment_operator_t as(c == '='
2538 108 : ? advgetopt::ASSIGNMENT_OPERATOR_COLON
2539 : : advgetopt::ASSIGNMENT_OPERATOR_EQUAL);
2540 : advgetopt::conf_file_setup setup(SNAP_CATCH2_NAMESPACE::g_config_filename
2541 : , advgetopt::line_continuation_t::line_continuation_unix
2542 : , as
2543 : , advgetopt::COMMENT_NONE
2544 216 : , advgetopt::SECTION_OPERATOR_NONE);
2545 :
2546 108 : CATCH_REQUIRE(setup.is_valid());
2547 108 : CATCH_REQUIRE(setup.get_line_continuation() == advgetopt::line_continuation_t::line_continuation_unix);
2548 108 : CATCH_REQUIRE(setup.get_assignment_operator() == as);
2549 108 : CATCH_REQUIRE(setup.get_comment() == advgetopt::COMMENT_NONE);
2550 108 : CATCH_REQUIRE(setup.get_section_operator() == (advgetopt::SECTION_OPERATOR_NONE));
2551 :
2552 108 : SNAP_CATCH2_NAMESPACE::push_expected_log(
2553 : "error: parameter \""
2554 216 : + bad_char
2555 216 : + "\" on line 2 in configuration file \""
2556 216 : + SNAP_CATCH2_NAMESPACE::g_config_filename
2557 216 : + "\" includes a character not acceptable for a section or"
2558 : " parameter name (controls, space, quotes, and \";#/=:?+\\\").");
2559 216 : advgetopt::conf_file::pointer_t file(advgetopt::conf_file::get_conf_file(setup));
2560 :
2561 108 : CATCH_REQUIRE(file->get_setup().get_config_url() == setup.get_config_url());
2562 108 : CATCH_REQUIRE(file->get_errno() == 0);
2563 :
2564 216 : advgetopt::conf_file::sections_t sections(file->get_sections());
2565 108 : CATCH_REQUIRE(sections.empty());
2566 :
2567 108 : CATCH_REQUIRE(file->get_parameters().size() == 2);
2568 :
2569 108 : CATCH_REQUIRE(file->has_parameter("good"));
2570 108 : CATCH_REQUIRE_FALSE(file->has_parameter(bad_char));
2571 108 : CATCH_REQUIRE(file->has_parameter("fine"));
2572 :
2573 108 : CATCH_REQUIRE(file->get_parameter("good") == "red");
2574 108 : CATCH_REQUIRE(file->get_parameter(bad_char) == std::string());
2575 108 : CATCH_REQUIRE(file->get_parameter("fine") == "param");
2576 : }
2577 : }
2578 1 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
2579 : CATCH_END_SECTION()
2580 :
2581 18 : CATCH_START_SECTION("too many sections")
2582 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("invalid-section-operator", "too-many-sections");
2583 :
2584 : {
2585 2 : std::ofstream config_file;
2586 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
2587 1 : CATCH_REQUIRE(config_file.good());
2588 1 : config_file <<
2589 : "# Auto-generated\n"
2590 : "a=color\n"
2591 : "a::b=red\n"
2592 : "m.n.o=size\n"
2593 : "z=edge\n"
2594 : ;
2595 : }
2596 :
2597 : advgetopt::conf_file_setup setup(SNAP_CATCH2_NAMESPACE::g_config_filename
2598 : , advgetopt::line_continuation_t::line_continuation_unix
2599 : , advgetopt::ASSIGNMENT_OPERATOR_EQUAL
2600 : , advgetopt::COMMENT_SHELL
2601 2 : , advgetopt::SECTION_OPERATOR_CPP | advgetopt::SECTION_OPERATOR_C | advgetopt::SECTION_OPERATOR_ONE_SECTION);
2602 :
2603 1 : CATCH_REQUIRE(setup.is_valid());
2604 1 : CATCH_REQUIRE(setup.get_line_continuation() == advgetopt::line_continuation_t::line_continuation_unix);
2605 1 : CATCH_REQUIRE(setup.get_assignment_operator() == advgetopt::ASSIGNMENT_OPERATOR_EQUAL);
2606 1 : CATCH_REQUIRE(setup.get_comment() == advgetopt::COMMENT_SHELL);
2607 1 : CATCH_REQUIRE(setup.get_section_operator() == (advgetopt::SECTION_OPERATOR_CPP | advgetopt::SECTION_OPERATOR_C | advgetopt::SECTION_OPERATOR_ONE_SECTION));
2608 :
2609 1 : SNAP_CATCH2_NAMESPACE::push_expected_log(
2610 : "error: option name \"m.n.o\" cannot be added to section"
2611 : " \"m::n\" because this configuration only accepts one"
2612 : " section level.");
2613 2 : advgetopt::conf_file::pointer_t file(advgetopt::conf_file::get_conf_file(setup));
2614 1 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
2615 :
2616 1 : CATCH_REQUIRE(file->get_setup().get_config_url() == setup.get_config_url());
2617 1 : CATCH_REQUIRE(file->get_errno() == 0);
2618 :
2619 2 : advgetopt::conf_file::sections_t sections(file->get_sections());
2620 1 : CATCH_REQUIRE(sections.size() == 1);
2621 1 : CATCH_REQUIRE(sections.find("a") != sections.end());
2622 :
2623 1 : CATCH_REQUIRE(file->get_parameters().size() == 3);
2624 :
2625 1 : CATCH_REQUIRE(file->has_parameter("a"));
2626 1 : CATCH_REQUIRE(file->has_parameter("a::b"));
2627 1 : CATCH_REQUIRE(file->has_parameter("z"));
2628 :
2629 1 : CATCH_REQUIRE(file->get_parameter("a") == "color");
2630 1 : CATCH_REQUIRE(file->get_parameter("a::b") == "red");
2631 1 : CATCH_REQUIRE(file->get_parameter("z") == "edge");
2632 : CATCH_END_SECTION()
2633 :
2634 18 : CATCH_START_SECTION("all '{' were not closed")
2635 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("invalid-section-operator", "unclosed-brackets");
2636 :
2637 : {
2638 2 : std::ofstream config_file;
2639 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
2640 1 : CATCH_REQUIRE(config_file.good());
2641 1 : config_file <<
2642 : "# Auto-generated\n"
2643 : "colors {\n"
2644 : " b=red\n"
2645 : " c=blue\n"
2646 : ;
2647 : }
2648 :
2649 : advgetopt::conf_file_setup setup(SNAP_CATCH2_NAMESPACE::g_config_filename
2650 : , advgetopt::line_continuation_t::line_continuation_unix
2651 : , advgetopt::ASSIGNMENT_OPERATOR_EQUAL
2652 : , advgetopt::COMMENT_SHELL
2653 2 : , advgetopt::SECTION_OPERATOR_BLOCK);
2654 :
2655 1 : CATCH_REQUIRE(setup.is_valid());
2656 1 : CATCH_REQUIRE(setup.get_line_continuation() == advgetopt::line_continuation_t::line_continuation_unix);
2657 1 : CATCH_REQUIRE(setup.get_assignment_operator() == advgetopt::ASSIGNMENT_OPERATOR_EQUAL);
2658 1 : CATCH_REQUIRE(setup.get_comment() == advgetopt::COMMENT_SHELL);
2659 1 : CATCH_REQUIRE(setup.get_section_operator() == advgetopt::SECTION_OPERATOR_BLOCK);
2660 :
2661 1 : SNAP_CATCH2_NAMESPACE::push_expected_log(
2662 : "error: unterminated `section { ... }`, the `}` is missing"
2663 : " in configuration file "
2664 2 : "\"" + SNAP_CATCH2_NAMESPACE::g_config_filename + "\".");
2665 2 : advgetopt::conf_file::pointer_t file(advgetopt::conf_file::get_conf_file(setup));
2666 1 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
2667 :
2668 1 : CATCH_REQUIRE(file->get_setup().get_config_url() == setup.get_config_url());
2669 1 : CATCH_REQUIRE(file->get_errno() == 0);
2670 :
2671 2 : advgetopt::conf_file::sections_t sections(file->get_sections());
2672 1 : CATCH_REQUIRE(sections.size() == 1);
2673 1 : CATCH_REQUIRE(sections.find("colors") != sections.end());
2674 :
2675 1 : CATCH_REQUIRE(file->get_parameters().size() == 2);
2676 :
2677 1 : CATCH_REQUIRE(file->has_parameter("colors::b"));
2678 1 : CATCH_REQUIRE(file->has_parameter("colors::c"));
2679 :
2680 1 : CATCH_REQUIRE(file->get_parameter("colors::b") == "red");
2681 1 : CATCH_REQUIRE(file->get_parameter("colors::c") == "blue");
2682 : CATCH_END_SECTION()
2683 :
2684 18 : CATCH_START_SECTION("data after ']' in INI file")
2685 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("invalid-section-operator", "additional-data");
2686 :
2687 : {
2688 2 : std::ofstream config_file;
2689 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
2690 1 : CATCH_REQUIRE(config_file.good());
2691 1 : config_file <<
2692 : "# Auto-generated\n"
2693 : "[colors]\n"
2694 : "b=red\n"
2695 : "c=blue\n"
2696 : "\n"
2697 : "[sizes] comment\n" // <- missing the comment introducer
2698 : "q=1000\n"
2699 : "r=9999\n"
2700 : ;
2701 : }
2702 :
2703 : advgetopt::conf_file_setup setup(SNAP_CATCH2_NAMESPACE::g_config_filename
2704 : , advgetopt::line_continuation_t::line_continuation_unix
2705 : , advgetopt::ASSIGNMENT_OPERATOR_EQUAL
2706 : , advgetopt::COMMENT_SHELL
2707 2 : , advgetopt::SECTION_OPERATOR_INI_FILE);
2708 :
2709 1 : CATCH_REQUIRE(setup.is_valid());
2710 1 : CATCH_REQUIRE(setup.get_line_continuation() == advgetopt::line_continuation_t::line_continuation_unix);
2711 1 : CATCH_REQUIRE(setup.get_assignment_operator() == advgetopt::ASSIGNMENT_OPERATOR_EQUAL);
2712 1 : CATCH_REQUIRE(setup.get_comment() == advgetopt::COMMENT_SHELL);
2713 1 : CATCH_REQUIRE(setup.get_section_operator() == advgetopt::SECTION_OPERATOR_INI_FILE);
2714 :
2715 1 : SNAP_CATCH2_NAMESPACE::push_expected_log(
2716 : "error: section names in configuration files cannot be followed by anything other than spaces in"
2717 : " \"[sizes] comment\" on line 6 from configuration file \""
2718 2 : + SNAP_CATCH2_NAMESPACE::g_config_filename
2719 2 : + "\".");
2720 2 : advgetopt::conf_file::pointer_t file(advgetopt::conf_file::get_conf_file(setup));
2721 1 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
2722 :
2723 1 : CATCH_REQUIRE(file->get_setup().get_config_url() == setup.get_config_url());
2724 1 : CATCH_REQUIRE(file->get_errno() == 0);
2725 :
2726 2 : advgetopt::conf_file::sections_t sections(file->get_sections());
2727 1 : CATCH_REQUIRE(sections.size() == 1);
2728 1 : CATCH_REQUIRE(sections.find("colors") != sections.end());
2729 :
2730 1 : CATCH_REQUIRE(file->get_parameters().size() == 4);
2731 :
2732 1 : CATCH_REQUIRE(file->has_parameter("colors::b"));
2733 1 : CATCH_REQUIRE(file->has_parameter("colors::c"));
2734 1 : CATCH_REQUIRE(file->has_parameter("colors::q"));
2735 1 : CATCH_REQUIRE(file->has_parameter("colors::r"));
2736 :
2737 1 : CATCH_REQUIRE(file->get_parameter("colors::b") == "red");
2738 1 : CATCH_REQUIRE(file->get_parameter("colors::c") == "blue");
2739 1 : CATCH_REQUIRE(file->get_parameter("colors::q") == "1000");
2740 1 : CATCH_REQUIRE(file->get_parameter("colors::r") == "9999");
2741 : CATCH_END_SECTION()
2742 :
2743 18 : CATCH_START_SECTION("INI file section inside a block is not allowed")
2744 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("invalid-section-operator", "ini-inside-block");
2745 :
2746 : {
2747 2 : std::ofstream config_file;
2748 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
2749 1 : CATCH_REQUIRE(config_file.good());
2750 1 : config_file <<
2751 : "# Auto-generated\n"
2752 : "[colors]\n"
2753 : "b=red\n"
2754 : "c=blue\n"
2755 : "\n"
2756 : "block {\n"
2757 : " b = block data\n"
2758 : " f = filename\n"
2759 : " [sizes]\n" // <-- INI section inside a block not allowed
2760 : " q=1000\n"
2761 : " r=9999\n"
2762 : "}\n"
2763 : ;
2764 : }
2765 :
2766 : advgetopt::conf_file_setup setup(SNAP_CATCH2_NAMESPACE::g_config_filename
2767 : , advgetopt::line_continuation_t::line_continuation_unix
2768 : , advgetopt::ASSIGNMENT_OPERATOR_EQUAL
2769 : , advgetopt::COMMENT_SHELL
2770 2 : , advgetopt::SECTION_OPERATOR_BLOCK | advgetopt::SECTION_OPERATOR_INI_FILE);
2771 :
2772 1 : CATCH_REQUIRE(setup.is_valid());
2773 1 : CATCH_REQUIRE(setup.get_line_continuation() == advgetopt::line_continuation_t::line_continuation_unix);
2774 1 : CATCH_REQUIRE(setup.get_assignment_operator() == advgetopt::ASSIGNMENT_OPERATOR_EQUAL);
2775 1 : CATCH_REQUIRE(setup.get_comment() == advgetopt::COMMENT_SHELL);
2776 1 : CATCH_REQUIRE(setup.get_section_operator() == (advgetopt::SECTION_OPERATOR_BLOCK | advgetopt::SECTION_OPERATOR_INI_FILE));
2777 :
2778 1 : SNAP_CATCH2_NAMESPACE::push_expected_log(
2779 : "error: `[...]` sections can't be used within a `section"
2780 : " { ... }` on line 9 from configuration file \""
2781 2 : + SNAP_CATCH2_NAMESPACE::g_config_filename
2782 2 : + "\".");
2783 2 : advgetopt::conf_file::pointer_t file(advgetopt::conf_file::get_conf_file(setup));
2784 1 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
2785 :
2786 1 : CATCH_REQUIRE(file->get_setup().get_config_url() == setup.get_config_url());
2787 1 : CATCH_REQUIRE(file->get_errno() == 0);
2788 :
2789 2 : advgetopt::conf_file::sections_t sections(file->get_sections());
2790 1 : CATCH_REQUIRE(sections.size() == 2);
2791 1 : CATCH_REQUIRE(sections.find("colors") != sections.end());
2792 1 : CATCH_REQUIRE(sections.find("colors::block") != sections.end());
2793 :
2794 1 : CATCH_REQUIRE(file->get_parameters().size() == 6);
2795 :
2796 1 : CATCH_REQUIRE(file->has_parameter("colors::b"));
2797 1 : CATCH_REQUIRE(file->has_parameter("colors::c"));
2798 1 : CATCH_REQUIRE(file->has_parameter("colors::block::b"));
2799 1 : CATCH_REQUIRE(file->has_parameter("colors::block::f"));
2800 1 : CATCH_REQUIRE(file->has_parameter("colors::block::q"));
2801 1 : CATCH_REQUIRE(file->has_parameter("colors::block::r"));
2802 :
2803 1 : CATCH_REQUIRE(file->get_parameter("colors::b") == "red");
2804 1 : CATCH_REQUIRE(file->get_parameter("colors::c") == "blue");
2805 1 : CATCH_REQUIRE(file->get_parameter("colors::block::b") == "block data");
2806 1 : CATCH_REQUIRE(file->get_parameter("colors::block::f") == "filename");
2807 1 : CATCH_REQUIRE(file->get_parameter("colors::block::q") == "1000");
2808 1 : CATCH_REQUIRE(file->get_parameter("colors::block::r") == "9999");
2809 : CATCH_END_SECTION()
2810 9 : }
2811 :
2812 :
2813 :
2814 7 : CATCH_TEST_CASE("invalid_variable_name")
2815 : {
2816 10 : CATCH_START_SECTION("empty variable name")
2817 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("invalid-variable-name", "name-missing");
2818 :
2819 : {
2820 2 : std::ofstream config_file;
2821 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
2822 1 : CATCH_REQUIRE(config_file.good());
2823 1 : config_file <<
2824 : "# Auto-generated\n"
2825 : "=color\n" // <-- name missing
2826 : "a..b=red\n"
2827 : "a.b.c=142\n"
2828 : ;
2829 : }
2830 :
2831 : advgetopt::conf_file_setup setup(SNAP_CATCH2_NAMESPACE::g_config_filename
2832 : , advgetopt::line_continuation_t::line_continuation_unix
2833 : , advgetopt::ASSIGNMENT_OPERATOR_EQUAL
2834 : , advgetopt::COMMENT_SHELL
2835 2 : , advgetopt::SECTION_OPERATOR_C);
2836 :
2837 1 : CATCH_REQUIRE(setup.is_valid());
2838 1 : CATCH_REQUIRE(setup.get_line_continuation() == advgetopt::line_continuation_t::line_continuation_unix);
2839 1 : CATCH_REQUIRE(setup.get_assignment_operator() == advgetopt::ASSIGNMENT_OPERATOR_EQUAL);
2840 1 : CATCH_REQUIRE(setup.get_comment() == advgetopt::COMMENT_SHELL);
2841 1 : CATCH_REQUIRE(setup.get_section_operator() == advgetopt::SECTION_OPERATOR_C);
2842 :
2843 1 : SNAP_CATCH2_NAMESPACE::push_expected_log(
2844 : "error: no option name in \"=color\""
2845 : " on line 2 from configuration file \""
2846 2 : + SNAP_CATCH2_NAMESPACE::g_config_filename
2847 2 : + "\", missing name before the assignment operator?");
2848 2 : advgetopt::conf_file::pointer_t file(advgetopt::conf_file::get_conf_file(setup));
2849 1 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
2850 :
2851 1 : CATCH_REQUIRE(file->get_setup().get_config_url() == setup.get_config_url());
2852 1 : CATCH_REQUIRE(file->get_errno() == 0);
2853 :
2854 2 : advgetopt::conf_file::sections_t sections(file->get_sections());
2855 1 : CATCH_REQUIRE(sections.size() == 2);
2856 1 : CATCH_REQUIRE(sections.find("a") != sections.end());
2857 1 : CATCH_REQUIRE(sections.find("a::b") != sections.end());
2858 :
2859 1 : CATCH_REQUIRE(file->get_parameters().size() == 2);
2860 :
2861 1 : CATCH_REQUIRE(file->has_parameter("a::b"));
2862 1 : CATCH_REQUIRE(file->has_parameter("a::b::c"));
2863 :
2864 1 : CATCH_REQUIRE(file->get_parameter("a::b") == "red");
2865 1 : CATCH_REQUIRE(file->get_parameter("a::b::c") == "142");
2866 : CATCH_END_SECTION()
2867 :
2868 10 : CATCH_START_SECTION("empty variable name after section name")
2869 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("invalid-variable-name", "section-and-name-missing");
2870 :
2871 : {
2872 2 : std::ofstream config_file;
2873 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
2874 1 : CATCH_REQUIRE(config_file.good());
2875 1 : config_file <<
2876 : "# Auto-generated\n"
2877 : "a..b=red\n"
2878 : "a.b.=color\n" // <-- name missing after section name
2879 : "a.b.c=142\n"
2880 : ;
2881 : }
2882 :
2883 : advgetopt::conf_file_setup setup(SNAP_CATCH2_NAMESPACE::g_config_filename
2884 : , advgetopt::line_continuation_t::line_continuation_unix
2885 : , advgetopt::ASSIGNMENT_OPERATOR_EQUAL
2886 : , advgetopt::COMMENT_SHELL
2887 2 : , advgetopt::SECTION_OPERATOR_C);
2888 :
2889 1 : CATCH_REQUIRE(setup.is_valid());
2890 1 : CATCH_REQUIRE(setup.get_line_continuation() == advgetopt::line_continuation_t::line_continuation_unix);
2891 1 : CATCH_REQUIRE(setup.get_assignment_operator() == advgetopt::ASSIGNMENT_OPERATOR_EQUAL);
2892 1 : CATCH_REQUIRE(setup.get_comment() == advgetopt::COMMENT_SHELL);
2893 1 : CATCH_REQUIRE(setup.get_section_operator() == advgetopt::SECTION_OPERATOR_C);
2894 :
2895 1 : SNAP_CATCH2_NAMESPACE::push_expected_log(
2896 : "error: option name \"a.b.\" cannot end with a section operator or be empty.");
2897 2 : advgetopt::conf_file::pointer_t file(advgetopt::conf_file::get_conf_file(setup));
2898 1 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
2899 :
2900 1 : CATCH_REQUIRE(file->get_setup().get_config_url() == setup.get_config_url());
2901 1 : CATCH_REQUIRE(file->get_errno() == 0);
2902 :
2903 2 : advgetopt::conf_file::sections_t sections(file->get_sections());
2904 1 : CATCH_REQUIRE(sections.size() == 2);
2905 1 : CATCH_REQUIRE(sections.find("a") != sections.end());
2906 1 : CATCH_REQUIRE(sections.find("a::b") != sections.end());
2907 :
2908 1 : CATCH_REQUIRE(file->get_parameters().size() == 2);
2909 :
2910 1 : CATCH_REQUIRE(file->has_parameter("a::b"));
2911 1 : CATCH_REQUIRE(file->has_parameter("a::b::c"));
2912 :
2913 1 : CATCH_REQUIRE(file->get_parameter("a::b") == "red");
2914 1 : CATCH_REQUIRE(file->get_parameter("a::b::c") == "142");
2915 : CATCH_END_SECTION()
2916 :
2917 10 : CATCH_START_SECTION("variable name starts with a dash")
2918 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("invalid-variable-name", "dash-name");
2919 :
2920 : {
2921 2 : std::ofstream config_file;
2922 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
2923 1 : CATCH_REQUIRE(config_file.good());
2924 1 : config_file <<
2925 : "# Auto-generated\n"
2926 : "a=color\n"
2927 : "-bad-dash=reddish\n" // <-- name starts with '-'
2928 : "size=412\n"
2929 : ;
2930 : }
2931 :
2932 : advgetopt::conf_file_setup setup(SNAP_CATCH2_NAMESPACE::g_config_filename
2933 : , advgetopt::line_continuation_t::line_continuation_unix
2934 : , advgetopt::ASSIGNMENT_OPERATOR_EQUAL
2935 : , advgetopt::COMMENT_SHELL
2936 2 : , advgetopt::SECTION_OPERATOR_C);
2937 :
2938 1 : CATCH_REQUIRE(setup.is_valid());
2939 1 : CATCH_REQUIRE(setup.get_line_continuation() == advgetopt::line_continuation_t::line_continuation_unix);
2940 1 : CATCH_REQUIRE(setup.get_assignment_operator() == advgetopt::ASSIGNMENT_OPERATOR_EQUAL);
2941 1 : CATCH_REQUIRE(setup.get_comment() == advgetopt::COMMENT_SHELL);
2942 1 : CATCH_REQUIRE(setup.get_section_operator() == advgetopt::SECTION_OPERATOR_C);
2943 :
2944 1 : SNAP_CATCH2_NAMESPACE::push_expected_log(
2945 : "error: option names in configuration files cannot"
2946 : " start with a dash or an underscore in"
2947 : " \"-bad-dash=reddish\" on line 3 from configuration file \""
2948 2 : + SNAP_CATCH2_NAMESPACE::g_config_filename
2949 2 : + "\".");
2950 2 : advgetopt::conf_file::pointer_t file(advgetopt::conf_file::get_conf_file(setup));
2951 1 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
2952 :
2953 1 : CATCH_REQUIRE(file->get_setup().get_config_url() == setup.get_config_url());
2954 1 : CATCH_REQUIRE(file->get_errno() == 0);
2955 :
2956 1 : CATCH_REQUIRE(file->get_sections().empty());
2957 :
2958 1 : CATCH_REQUIRE(file->get_parameters().size() == 2);
2959 :
2960 1 : CATCH_REQUIRE(file->has_parameter("a"));
2961 1 : CATCH_REQUIRE(file->has_parameter("size"));
2962 :
2963 1 : CATCH_REQUIRE(file->get_parameter("a") == "color");
2964 1 : CATCH_REQUIRE(file->get_parameter("size") == "412");
2965 : CATCH_END_SECTION()
2966 :
2967 10 : CATCH_START_SECTION("variable name starts with an underscore")
2968 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("invalid-variable-name", "underscore-name");
2969 :
2970 : {
2971 2 : std::ofstream config_file;
2972 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
2973 1 : CATCH_REQUIRE(config_file.good());
2974 1 : config_file <<
2975 : "# Auto-generated\n"
2976 : "a_variable=color\n"
2977 : "_bad_underscore=reddish\n" // <-- name starts with '_'
2978 : "pos_and_size=412x33+32-18\n"
2979 : ;
2980 : }
2981 :
2982 : advgetopt::conf_file_setup setup(SNAP_CATCH2_NAMESPACE::g_config_filename
2983 : , advgetopt::line_continuation_t::line_continuation_unix
2984 : , advgetopt::ASSIGNMENT_OPERATOR_EQUAL
2985 : , advgetopt::COMMENT_SHELL
2986 2 : , advgetopt::SECTION_OPERATOR_C);
2987 :
2988 1 : CATCH_REQUIRE(setup.is_valid());
2989 1 : CATCH_REQUIRE(setup.get_line_continuation() == advgetopt::line_continuation_t::line_continuation_unix);
2990 1 : CATCH_REQUIRE(setup.get_assignment_operator() == advgetopt::ASSIGNMENT_OPERATOR_EQUAL);
2991 1 : CATCH_REQUIRE(setup.get_comment() == advgetopt::COMMENT_SHELL);
2992 1 : CATCH_REQUIRE(setup.get_section_operator() == advgetopt::SECTION_OPERATOR_C);
2993 :
2994 1 : SNAP_CATCH2_NAMESPACE::push_expected_log(
2995 : "error: option names in configuration files cannot"
2996 : " start with a dash or an underscore in"
2997 : " \"_bad_underscore=reddish\" on line 3 from configuration file \""
2998 2 : + SNAP_CATCH2_NAMESPACE::g_config_filename
2999 2 : + "\".");
3000 2 : advgetopt::conf_file::pointer_t file(advgetopt::conf_file::get_conf_file(setup));
3001 1 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
3002 :
3003 1 : CATCH_REQUIRE(file->get_setup().get_config_url() == setup.get_config_url());
3004 1 : CATCH_REQUIRE(file->get_errno() == 0);
3005 :
3006 1 : CATCH_REQUIRE(file->get_sections().empty());
3007 :
3008 1 : CATCH_REQUIRE(file->get_parameters().size() == 2);
3009 :
3010 1 : CATCH_REQUIRE(file->has_parameter("a-variable"));
3011 1 : CATCH_REQUIRE(file->has_parameter("pos-and-size"));
3012 :
3013 1 : CATCH_REQUIRE(file->get_parameter("a-variable") == "color");
3014 1 : CATCH_REQUIRE(file->get_parameter("pos-and-size") == "412x33+32-18");
3015 : CATCH_END_SECTION()
3016 :
3017 10 : CATCH_START_SECTION("variable name with spaces")
3018 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("invalid-variable-name", "name-space-more-name");
3019 :
3020 : {
3021 2 : std::ofstream config_file;
3022 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
3023 1 : CATCH_REQUIRE(config_file.good());
3024 1 : config_file <<
3025 : "# Auto-generated\n"
3026 : "a variable=color\n"
3027 : "bad space=reddish\n"
3028 : "pos and size=412x33+32-18\n"
3029 : ;
3030 : }
3031 :
3032 : advgetopt::conf_file_setup setup(SNAP_CATCH2_NAMESPACE::g_config_filename
3033 : , advgetopt::line_continuation_t::line_continuation_unix
3034 : , advgetopt::ASSIGNMENT_OPERATOR_EQUAL
3035 : , advgetopt::COMMENT_SHELL
3036 2 : , advgetopt::SECTION_OPERATOR_C);
3037 :
3038 1 : CATCH_REQUIRE(setup.is_valid());
3039 1 : CATCH_REQUIRE(setup.get_line_continuation() == advgetopt::line_continuation_t::line_continuation_unix);
3040 1 : CATCH_REQUIRE(setup.get_assignment_operator() == advgetopt::ASSIGNMENT_OPERATOR_EQUAL);
3041 1 : CATCH_REQUIRE(setup.get_comment() == advgetopt::COMMENT_SHELL);
3042 1 : CATCH_REQUIRE(setup.get_section_operator() == advgetopt::SECTION_OPERATOR_C);
3043 :
3044 1 : SNAP_CATCH2_NAMESPACE::push_expected_log(
3045 : "error: option name from \"a variable=color\" on line"
3046 : " 2 in configuration file \""
3047 2 : + SNAP_CATCH2_NAMESPACE::g_config_filename
3048 2 : + "\" cannot include a space, missing assignment operator?");
3049 1 : SNAP_CATCH2_NAMESPACE::push_expected_log(
3050 : "error: option name from \"bad space=reddish\" on line"
3051 : " 3 in configuration file \""
3052 2 : + SNAP_CATCH2_NAMESPACE::g_config_filename
3053 2 : + "\" cannot include a space, missing assignment operator?");
3054 1 : SNAP_CATCH2_NAMESPACE::push_expected_log(
3055 : "error: option name from \"pos and size=412x33+32-18\" on line"
3056 : " 4 in configuration file \""
3057 2 : + SNAP_CATCH2_NAMESPACE::g_config_filename
3058 2 : + "\" cannot include a space, missing assignment operator?");
3059 2 : advgetopt::conf_file::pointer_t file(advgetopt::conf_file::get_conf_file(setup));
3060 1 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
3061 :
3062 1 : CATCH_REQUIRE(file->get_setup().get_config_url() == setup.get_config_url());
3063 1 : CATCH_REQUIRE(file->get_errno() == 0);
3064 :
3065 1 : CATCH_REQUIRE(file->get_sections().empty());
3066 :
3067 1 : CATCH_REQUIRE(file->get_parameters().empty());
3068 : CATCH_END_SECTION()
3069 11 : }
3070 :
3071 :
3072 :
3073 :
3074 :
3075 : // vim: ts=4 sw=4 et
|