Line data Source code
1 : // Copyright (c) 2006-2022 Made to Order Software Corp. All Rights Reserved
2 : //
3 : // https://snapwebsites.org/project/advgetopt
4 : // contact@m2osw.com
5 : //
6 : // This program is free software; you can redistribute it and/or modify
7 : // it under the terms of the GNU General Public License as published by
8 : // the Free Software Foundation; either version 2 of the License, or
9 : // (at your option) any later version.
10 : //
11 : // This program is distributed in the hope that it will be useful,
12 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : // GNU General Public License for more details.
15 : //
16 : // You should have received a copy of the GNU General Public License along
17 : // with this program; if not, write to the Free Software Foundation, Inc.,
18 : // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 :
20 : /** \file
21 : * \brief Advanced getopt data access implementation.
22 : *
23 : * The advgetopt class has many function used to access the data in the
24 : * class. These functions are gathered here.
25 : */
26 :
27 : // self
28 : //
29 : #include "advgetopt/advgetopt.h"
30 :
31 : #include "advgetopt/conf_file.h"
32 : #include "advgetopt/exception.h"
33 : #include "advgetopt/validator_double.h"
34 : #include "advgetopt/validator_integer.h"
35 : #include "advgetopt/version.h"
36 :
37 :
38 : // cppthread
39 : //
40 : #include <cppthread/log.h>
41 :
42 :
43 : // C
44 : //
45 : #include <string.h>
46 :
47 :
48 : // last include
49 : //
50 : #include <snapdev/poison.h>
51 :
52 :
53 :
54 :
55 : namespace advgetopt
56 : {
57 :
58 :
59 :
60 :
61 :
62 : /** \brief Check whether a parameter is defined.
63 : *
64 : * This function returns true if the specified parameter is found as part of
65 : * the command line options.
66 : *
67 : * You must specify the long name of the option. So a `--verbose` option can
68 : * be checked with:
69 : *
70 : * \code
71 : * if(is_defined("verbose")) ...
72 : * \endcode
73 : *
74 : * For options that come with a short name, you may also specify the short
75 : * name. This is done with a string in this case. It can be a UTF-8
76 : * character. The short name is used if the string represents exactly one
77 : * Unicode character. So the following is equivalent to the previous
78 : * example, assuming your verbose definition has `v` as the short name:
79 : *
80 : * \code
81 : * if(is_defined("v")) ...
82 : * \endcode
83 : *
84 : * \note
85 : * This function returns true when the option was found on the command line,
86 : * the environment variable, or a configuration file. It returns false if
87 : * the option is defined, but was not specified anywhere by the client using
88 : * your program. Also, specifying the option in one of those three locations
89 : * when not allowed at that location will not result in this flag being raised.
90 : *
91 : * \param[in] name The long name or short name of the option to check.
92 : *
93 : * \return true if the option was defined in a configuration file, the
94 : * environment variable, or the command line.
95 : */
96 1431 : bool getopt::is_defined(std::string const & name) const
97 : {
98 1431 : is_parsed();
99 :
100 2854 : option_info::pointer_t opt(get_option(name));
101 1427 : if(opt != nullptr)
102 : {
103 1086 : return opt->is_defined();
104 : }
105 :
106 341 : return false;
107 : }
108 :
109 :
110 : /** \brief Retrieve the number of arguments.
111 : *
112 : * This function returns the number of arguments that were specified after
113 : * the named option.
114 : *
115 : * The function returns zero if the argument was never specified on the
116 : * command line. If the option accepts exactly one parameter (i.e. not
117 : * marked as a multiple arguments option: GETOPT_FLAG_MULTIPLE) then
118 : * the function returns either zero (not specified) or one (specified
119 : * at least once.)
120 : *
121 : * \param[in] name The name of the option to check.
122 : *
123 : * \return The number of arguments specified on the command line or zero.
124 : */
125 635 : size_t getopt::size(std::string const & name) const
126 : {
127 635 : is_parsed();
128 :
129 1264 : option_info::pointer_t opt(get_option(name));
130 632 : if(opt != nullptr)
131 : {
132 411 : return opt->size();
133 : }
134 221 : return 0;
135 : }
136 :
137 :
138 : /** \brief Check whether an option has a default value.
139 : *
140 : * Some parameters may be given a default. This function is used to
141 : * detect whether such a default value is defined.
142 : *
143 : * \note
144 : * This function is particularly useful in the event the default value
145 : * may be an empty string.
146 : *
147 : * \exception getopt_exception_undefined
148 : * The getopt_exception_undefined exception is raised if this function is
149 : * called with an empty \p name.
150 : *
151 : * \param[in] name The name of the parameter of which you want to know
152 : * whether it has a default value or not.
153 : *
154 : * \return true if the default value was defined (even if an empty string.)
155 : */
156 86 : bool getopt::has_default(std::string const & name) const
157 : {
158 170 : option_info::pointer_t opt(get_option(name));
159 84 : if(opt != nullptr)
160 : {
161 79 : return opt->has_default();
162 : }
163 :
164 5 : return false;
165 : }
166 :
167 :
168 : /** \brief Get the default value for this option.
169 : *
170 : * When an option is not defined, you may use this function to retrieve its
171 : * default instead. This is actually done automatically when you call the
172 : * get_string() or get_long() functions.
173 : *
174 : * An option without a default has this function returning nullptr.
175 : *
176 : * \note
177 : * Whether an option has a default value should be checked with the
178 : * has_default() function which returns true when the default value
179 : * was defined. An option with an empty string as the default is
180 : * a valid case which cannot be detected otherwise.
181 : *
182 : * \exception getopt_exception_undefined
183 : * The getopt_exception_undefined exception is raised if this function is
184 : * called with an empty \p name.
185 : *
186 : * \param[in] name The name of the parameter of which you want to retrieve
187 : * the default value.
188 : *
189 : * \return The default value or an empty string if no value is defined.
190 : */
191 569 : std::string getopt::get_default(std::string const & name) const
192 : {
193 1136 : option_info::pointer_t opt(get_option(name));
194 567 : if(opt != nullptr)
195 : {
196 325 : return opt->get_default();
197 : }
198 :
199 242 : return std::string();
200 : }
201 :
202 :
203 : /** \brief This function retrieves an argument as a long value.
204 : *
205 : * This function reads the specified argument from the named option and
206 : * transforms it to a long value. It then checks the result against the
207 : * specified minimum and maximum range.
208 : *
209 : * The function name represents an argument that needs to be defined. You
210 : * can test whether it was defined on the command line with the is_defined()
211 : * function. The index must be between 0 and 'size() - 1' inclusive. If
212 : * the item was not defined, then size() returns zero and you cannot call
213 : * this function.
214 : *
215 : * The function does not check the validity of the minimum and maximum
216 : * parameters. If \p min \> \p max is true then the function will always
217 : * fail with a call to usage() as no value can be defined between \p min
218 : * and \p max in that case. The minimum and maximum values are inclusive,
219 : * so a range of 1 to 9 is defined with exactly 1 and 9 in min and max.
220 : * For example, the z library compression could be retrieved with:
221 : *
222 : * \code
223 : * int level(6); // default to 6
224 : * if(opt.is_defined("zlevel"))
225 : * {
226 : * zlevel = opt.get_long("zlevel", 0, 1, 9);
227 : * }
228 : * \endcode
229 : *
230 : * Note that the function can be used to read unsigned numbers, however
231 : * at this point getopt does not really support negative numbers (i.e. because
232 : * -\<number> is viewed as an option.)
233 : *
234 : * \exception getopt_exception_undefined
235 : * The getopt_exception_undefined exception is raised if \p name was not
236 : * found on the command line and it has no default, or if \p idx is
237 : * out of bounds.
238 : *
239 : * \param[in] name The name of the option to retrieve.
240 : * \param[in] idx The index of the argument to retrieve.
241 : * \param[in] min The minimum value that will be returned (inclusive).
242 : * \param[in] max The maximum value that will be returned (inclusive).
243 : *
244 : * \return The argument as a long.
245 : */
246 130 : long getopt::get_long(std::string const & name, int idx, long min, long max) const
247 : {
248 130 : is_parsed();
249 :
250 260 : option_info::pointer_t opt(get_option(name));
251 130 : if(opt == nullptr)
252 : {
253 : throw getopt_logic_error(
254 : "there is no --"
255 6 : + name
256 9 : + " option defined.");
257 : }
258 :
259 127 : long result(0.0);
260 127 : if(!opt->is_defined())
261 : {
262 96 : std::string const d(opt->get_default());
263 48 : if(d.empty())
264 : {
265 : throw getopt_logic_error(
266 : "the --"
267 12 : + name
268 18 : + " option was not defined on the command line and it has no or an empty default.");
269 : }
270 42 : if(!validator_integer::convert_string(d, result))
271 : {
272 : // here we throw because this default value is defined in the
273 : // options of the tool and not by the user
274 : //
275 : throw getopt_logic_error(
276 : "invalid default number \""
277 6 : + d
278 9 : + "\" for option --"
279 9 : + name);
280 : }
281 : }
282 : else
283 : {
284 79 : result = opt->get_long(idx);
285 : }
286 :
287 : // TODO: replace with validators
288 : //
289 118 : if(result < min || result > max)
290 : {
291 4 : cppthread::log << cppthread::log_level_t::error
292 2 : << result
293 2 : << " is out of bounds ("
294 2 : << min
295 2 : << ".."
296 2 : << max
297 2 : << " inclusive) in parameter --"
298 2 : << name
299 2 : << "."
300 4 : << cppthread::end;
301 2 : result = -1;
302 : }
303 :
304 236 : return result;
305 : }
306 :
307 :
308 : /** \brief This function retrieves an argument as a double value.
309 : *
310 : * This function reads the specified argument from the named option and
311 : * transforms it to a double value. It then checks the result against the
312 : * specified minimum and maximum range.
313 : *
314 : * The function name represents an argument that needs to be defined. You
315 : * can test whether it was defined on the command line with the is_defined()
316 : * function. The index must be between 0 and 'size() - 1' inclusive. If
317 : * the item was not defined, then size() returns zero and you cannot call
318 : * this function.
319 : *
320 : * The function does not check the validity of the minimum and maximum
321 : * parameters. If \p min \> \p max is true then the function will always
322 : * fail with a call to usage() as no value can be defined between \p min
323 : * and \p max in that case. The minimum and maximum values are inclusive,
324 : * so a range of 1 to 9 is defined with exactly 1 and 9 in min and max.
325 : * For example, the z library compression could be retrieved with:
326 : *
327 : * \code
328 : * int level(6); // default to 6
329 : * if(opt.is_defined("zlevel"))
330 : * {
331 : * zlevel = opt.get_double("zlevel", 0, 1.0, 9.0);
332 : * }
333 : * \endcode
334 : *
335 : * Note that the function can be used to read unsigned numbers, however
336 : * at this point getopt does not really support negative numbers (i.e. because
337 : * -\<number> is viewed as an option.)
338 : *
339 : * \todo
340 : * Fix example with a parameter which makes sense (i.e. accepts doubles).
341 : *
342 : * \exception getopt_exception_undefined
343 : * The getopt_exception_undefined exception is raised if \p name was not
344 : * found on the command line and it has no default, or if \p idx is
345 : * out of bounds.
346 : *
347 : * \param[in] name The name of the option to retrieve.
348 : * \param[in] idx The index of the argument to retrieve.
349 : * \param[in] min The minimum value that will be returned (inclusive).
350 : * \param[in] max The maximum value that will be returned (inclusive).
351 : *
352 : * \return The argument as a long.
353 : */
354 47 : double getopt::get_double(std::string const & name, int idx, double min, double max) const
355 : {
356 47 : is_parsed();
357 :
358 94 : option_info::pointer_t opt(get_option(name));
359 47 : if(opt == nullptr)
360 : {
361 : throw getopt_logic_error(
362 : "there is no --"
363 2 : + name
364 3 : + " option defined.");
365 : }
366 :
367 46 : double result(0);
368 46 : if(!opt->is_defined())
369 : {
370 10 : std::string const d(opt->get_default());
371 5 : if(d.empty())
372 : {
373 : throw getopt_logic_error(
374 : "the --"
375 2 : + name
376 3 : + " option was not defined on the command line and it has no or an empty default.");
377 : }
378 4 : if(!validator_double::convert_string(d, result))
379 : {
380 : // here we throw because this default value is defined in the
381 : // options of the tool and not by the user
382 : //
383 : throw getopt_logic_error(
384 : "invalid default number \""
385 2 : + d
386 3 : + "\" for option --"
387 3 : + name
388 3 : + ".");
389 : }
390 : }
391 : else
392 : {
393 41 : result = opt->get_double(idx);
394 : }
395 :
396 : // TODO: replace with validators
397 : //
398 44 : if(result < min || result > max)
399 : {
400 2 : cppthread::log << cppthread::log_level_t::error
401 1 : << result
402 1 : << " is out of bounds ("
403 1 : << min
404 1 : << ".."
405 1 : << max
406 1 : << " inclusive) in parameter --"
407 1 : << name
408 1 : << "."
409 2 : << cppthread::end;
410 1 : result = -1.0;
411 : }
412 :
413 88 : return result;
414 : }
415 :
416 :
417 : /** \brief Get the content of an option as a string.
418 : *
419 : * Get the content of the named parameter as a string. Command line options
420 : * that accept multiple arguments accept the \p idx parameter to
421 : * specify which item you are interested in.
422 : *
423 : * Note that the option must have been specified on the command line or have
424 : * a default value. For options that do not have a default value, you want
425 : * to call the is_defined() function first.
426 : *
427 : * \note
428 : * If the function returns the default value, it gets returned as is. i.e.
429 : * it won't be passed through the variable processing function.
430 : *
431 : * \exception getopt_exception_undefined
432 : * The getopt_exception_undefined exception is raised if \p name was not
433 : * found on the command line and it has no default, or if \p idx is
434 : * out of bounds.
435 : *
436 : * \param[in] name The name of the option to read.
437 : * \param[in] idx The zero based index of a multi-argument command line option.
438 : * \param[in] raw Whether to return the value without replacing the variables.
439 : *
440 : * \return The option argument as a string.
441 : */
442 583 : std::string getopt::get_string(
443 : std::string const & name
444 : , int idx
445 : , bool raw) const
446 : {
447 583 : is_parsed();
448 :
449 1166 : option_info::pointer_t opt(get_option(name));
450 583 : if(opt == nullptr)
451 : {
452 : throw getopt_logic_error(
453 : "there is no --"
454 6 : + name
455 9 : + " option defined.");
456 : }
457 :
458 580 : if(!opt->is_defined())
459 : {
460 49 : if(opt->has_default())
461 : {
462 44 : return opt->get_default();
463 : }
464 : throw getopt_logic_error(
465 : "the --"
466 10 : + name
467 15 : + " option was not defined on the command line and it has no default.");
468 : }
469 :
470 : // it was defined, but if REQUIRED is not set and the value is empty
471 : // then we want to return the default if it has such defined
472 : //
473 1061 : std::string const value(opt->get_value(idx, raw));
474 1060 : if(value.empty()
475 68 : && opt->has_default()
476 538 : && !opt->has_flag(GETOPT_FLAG_REQUIRED))
477 : {
478 8 : return opt->get_default();
479 : }
480 :
481 522 : return value;
482 : }
483 :
484 :
485 : /** \brief Retrieve the value of an argument.
486 : *
487 : * This operator returns the value of an argument just like the get_string()
488 : * does when the argument is defined. When the argument is not defined and it
489 : * has no default, it returns an empty string instead of throwing.
490 : *
491 : * The function is only capable of returning the very first value. If this
492 : * argument has the GETOPT_FLAG_MULTIPLE flag set, you probably want to use
493 : * the get_string() instead.
494 : *
495 : * \param[in] name The name of the option to retrieve.
496 : *
497 : * \return The value of that option or an empty string if not defined.
498 : */
499 207 : std::string getopt::operator [] (std::string const & name) const
500 : {
501 207 : is_parsed();
502 :
503 207 : if(name.empty())
504 : {
505 2 : throw getopt_logic_error("argument name cannot be empty.");
506 : }
507 :
508 410 : option_info::pointer_t opt(get_option(name));
509 205 : if(opt == nullptr)
510 : {
511 4 : return std::string();
512 : }
513 :
514 201 : if(!opt->is_defined())
515 : {
516 11 : if(opt->has_default())
517 : {
518 10 : return opt->get_default();
519 : }
520 1 : return std::string();
521 : }
522 :
523 190 : return opt->get_value(0);
524 : }
525 :
526 :
527 : /** \brief Access a parameter in read and write mode.
528 : *
529 : * This function allows you to access an argument which may or may not
530 : * yet exist.
531 : *
532 : * The return value is a reference to that parameter. You can read
533 : * and write to the reference.
534 : *
535 : * A non-existant argument is created only if necessary. That is,
536 : * only if you actually use an assignment operator as follow:
537 : *
538 : * \code
539 : * // straight assignment:
540 : * opt["my-var"] = "123";
541 : *
542 : * // or concatenation:
543 : * opt["my-var"] += "append";
544 : * \endcode
545 : *
546 : * In read mode and unless you defined a default, a non-existant argument
547 : * is viewed as an empty string or 0 if retrieved as a long:
548 : *
549 : * \code
550 : * // if non-existant you get an empty string:
551 : * std::string value = opt["non-existant"];
552 : *
553 : * // if non-existant you get zero:
554 : * long value = opt["non-existant"].get_long();
555 : * \endcode
556 : *
557 : * The get_long() function may generate an error if the parameter is not
558 : * a valid integer. Also when a default is defined, it tries to convert
559 : * the default value to a number and if that fails an error is generated.
560 : *
561 : * \note
562 : * This operator only allows you to access the very first value of
563 : * this option. If the option is marked with GETOPT_FLAG_MULTIPLE,
564 : * you may want to use the get_option() function and then handle
565 : * the option multiple values manually with the option_info::get_value()
566 : * and option_info::set_value().
567 : *
568 : * \warning
569 : * If the option is an alias and the destination is not defined you
570 : * can still get an exception raised.
571 : *
572 : * \param[in] name The name of the option to access.
573 : *
574 : * \return A reference to this option with support for many std::string like
575 : * operators.
576 : */
577 176 : option_info_ref getopt::operator [] (std::string const & name)
578 : {
579 176 : is_parsed();
580 :
581 176 : if(name.empty())
582 : {
583 2 : throw getopt_logic_error("argument name cannot be empty.");
584 : }
585 :
586 348 : option_info::pointer_t opt(get_option(name));
587 174 : if(opt == nullptr)
588 : {
589 55 : if(name.length() == 1)
590 : {
591 2 : throw getopt_logic_error("argument name cannot be one letter if it does not exist in operator [].");
592 : }
593 :
594 : // The option doesn't exist yet, create it
595 : //
596 53 : opt = std::make_shared<option_info>(name);
597 53 : opt->set_variables(f_variables);
598 53 : opt->add_flag(GETOPT_FLAG_DYNAMIC_CONFIGURATION);
599 53 : f_options_by_name[name] = opt;
600 : }
601 :
602 344 : return option_info_ref(opt);
603 : }
604 :
605 :
606 : /** \brief Process the system options.
607 : *
608 : * If you have the GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS flag turned on,
609 : * then several options are automatically added to your list of supported
610 : * options, such as `--version`.
611 : *
612 : * This function processes these options if any were used by the client.
613 : *
614 : * If the function finds one or more system flags as being defined, it
615 : * returns a non-zero set of SYSTEM_OPTION_... flags. This can be useful
616 : * to decide whether to continue processing or not.
617 : *
618 : * We define a set of flags that can help you decide whether to continue
619 : * or exit. In most cases, we propose that you exit your program if any
620 : * one of the options was a command. This is done like so:
621 : *
622 : * \code
623 : * advgetopt::flag_t const r(process_system_options(stdout));
624 : * if((r & SYSTEM_OPTION_COMMANDS_MASK) != 0)
625 : * {
626 : * exit(1);
627 : * }
628 : * \endcode
629 : *
630 : * You may still want to continue, though, if other flags where set,
631 : * even if some commands were used. For example, some tools will print
632 : * their version and move forward with there work (i.e. compilers often do
633 : * that to help with logging all the information about a build process,
634 : * including the version of the compiler.)
635 : *
636 : * \param[in] out The stream where output is sent if required.
637 : *
638 : * \return non-zero set of flags if any of the system parameters were processed.
639 : */
640 45 : flag_t getopt::process_system_options(std::basic_ostream<char> & out)
641 : {
642 45 : flag_t result(SYSTEM_OPTION_NONE);
643 :
644 : // --version
645 45 : if(is_defined("version"))
646 : {
647 4 : if(f_options_environment.f_version == nullptr)
648 : {
649 1 : out << "warning: no version found." << std::endl;
650 : }
651 : else
652 : {
653 3 : out << f_options_environment.f_version << std::endl;
654 : }
655 4 : result |= SYSTEM_OPTION_VERSION;
656 : }
657 :
658 : // --has-sanitizer
659 45 : if(is_defined("has-sanitizer"))
660 : {
661 1 : out << sanitizer_details() << std::flush;
662 1 : result |= SYSTEM_OPTION_HELP;
663 : }
664 :
665 : // --compiler-version
666 45 : if(is_defined("compiler-version"))
667 : {
668 1 : out << LIBADVGETOPT_COMPILER_VERSION << std::endl;
669 1 : result |= SYSTEM_OPTION_HELP;
670 : }
671 :
672 : // --help
673 45 : if(is_defined("help"))
674 : {
675 1 : less(out, usage());
676 1 : result |= SYSTEM_OPTION_HELP;
677 : }
678 :
679 : // --long-help
680 45 : if(is_defined("long-help"))
681 : {
682 1 : less(out, usage(GETOPT_FLAG_SHOW_ALL));
683 1 : result |= SYSTEM_OPTION_HELP;
684 : }
685 :
686 : // --<group-name>-help
687 : //
688 45 : if(f_options_environment.f_groups != nullptr)
689 : {
690 6 : for(group_description const * grp = f_options_environment.f_groups
691 6 : ; grp->f_group != GETOPT_FLAG_GROUP_NONE
692 : ; ++grp)
693 : {
694 : // the name is not mandatory, without it you do not get the command
695 : // line option but still get the group description
696 : //
697 4 : if(grp->f_name != nullptr
698 4 : && *grp->f_name != '\0')
699 : {
700 8 : std::string const name(grp->f_name);
701 8 : std::string const option_name(name + "-help");
702 4 : if(is_defined(option_name))
703 : {
704 2 : less(out, usage(grp->f_group));
705 2 : result |= SYSTEM_OPTION_HELP;
706 : }
707 : }
708 : }
709 : }
710 :
711 : // --copyright
712 45 : if(is_defined("copyright"))
713 : {
714 3 : if(f_options_environment.f_copyright == nullptr)
715 : {
716 1 : out << "warning: no copyright notice found." << std::endl;
717 : }
718 : else
719 : {
720 2 : less(out, f_options_environment.f_copyright);
721 : }
722 3 : result |= SYSTEM_OPTION_COPYRIGHT;
723 : }
724 :
725 : // --license
726 45 : if(is_defined("license"))
727 : {
728 4 : if(f_options_environment.f_license == nullptr)
729 : {
730 1 : out << "warning: no license found." << std::endl;
731 : }
732 : else
733 : {
734 3 : less(out, f_options_environment.f_license);
735 : }
736 4 : result |= SYSTEM_OPTION_LICENSE;
737 : }
738 :
739 : // --build-date
740 45 : if(is_defined("build-date"))
741 : {
742 : out << "Built on "
743 2 : << (f_options_environment.f_build_date == nullptr
744 : ? "<no-build-date>"
745 : : f_options_environment.f_build_date)
746 : << " at "
747 2 : << (f_options_environment.f_build_time == nullptr
748 : ? "<no-build-time>"
749 6 : : f_options_environment.f_build_time)
750 2 : << std::endl;
751 2 : result |= SYSTEM_OPTION_BUILD_DATE;
752 : }
753 :
754 : // --environment-variable-name
755 45 : if(is_defined("environment-variable-name"))
756 : {
757 3 : if(f_options_environment.f_environment_variable_name == nullptr
758 2 : || *f_options_environment.f_environment_variable_name == '\0')
759 : {
760 : out << f_options_environment.f_project_name
761 2 : << " does not support an environment variable."
762 2 : << std::endl;
763 : }
764 : else
765 : {
766 1 : out << f_options_environment.f_environment_variable_name << std::endl;
767 : }
768 3 : result |= SYSTEM_OPTION_ENVIRONMENT_VARIABLE_NAME;
769 : }
770 :
771 : // --configuration-filenames
772 45 : if(is_defined("configuration-filenames"))
773 : {
774 6 : string_list_t list(get_configuration_filenames(false, false));
775 3 : if(list.empty())
776 : {
777 : out << f_options_environment.f_project_name
778 1 : << " does not support configuration files."
779 1 : << std::endl;
780 : }
781 : else
782 : {
783 2 : out << "Configuration filenames:" << std::endl;
784 26 : for(auto n : list)
785 : {
786 24 : out << " . " << n << std::endl;
787 : }
788 : }
789 3 : result |= SYSTEM_OPTION_CONFIGURATION_FILENAMES;
790 : }
791 :
792 : // --path-to-option-definitions
793 45 : if(is_defined("path-to-option-definitions"))
794 : {
795 2 : if(f_options_environment.f_options_files_directory == nullptr
796 1 : || *f_options_environment.f_options_files_directory == '\0')
797 : {
798 1 : out << "/usr/share/advgetopt/options/" << std::endl;
799 : }
800 : else
801 : {
802 1 : out << f_options_environment.f_options_files_directory;
803 1 : if(f_options_environment.f_options_files_directory[strlen(f_options_environment.f_options_files_directory) - 1] != '/')
804 : {
805 1 : out << '/';
806 : }
807 1 : out << std::endl;
808 : }
809 2 : result |= SYSTEM_OPTION_PATH_TO_OPTION_DEFINITIONS;
810 : }
811 :
812 : // --config-dir
813 45 : if(is_defined("config-dir"))
814 : {
815 : // these are automatically used in the get_configuration_filenames()
816 : // function, there is nothing for us to do here
817 : //
818 3 : result |= SYSTEM_OPTION_CONFIG_DIR;
819 : }
820 :
821 : // --show-option-sources
822 45 : if(is_defined("show-option-sources"))
823 : {
824 3 : show_option_sources(out);
825 3 : result |= SYSTEM_OPTION_SHOW_OPTION_SOURCES;
826 : }
827 :
828 : // --print-option
829 45 : if(is_defined("print-option"))
830 : {
831 6 : std::string const name(get_string("print-option"));
832 3 : if(is_defined(name))
833 : {
834 1 : out << get_string(name) << std::endl;
835 : }
836 2 : else if(has_default(name))
837 : {
838 1 : out << get_default(name) << std::endl;
839 : }
840 3 : result |= SYSTEM_OPTION_SHOW_OPTION_VALUE;
841 : }
842 :
843 45 : return result;
844 : }
845 :
846 :
847 :
848 :
849 :
850 6 : } // namespace advgetopt
851 : // vim: ts=4 sw=4 et
|