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 :
21 : /** \file
22 : * \brief Implementation of the option_info class.
23 : *
24 : * This is the implementation of the class used to define one command
25 : * line option.
26 : */
27 :
28 : // self
29 : //
30 : #include "advgetopt/option_info.h"
31 :
32 : #include "advgetopt/validator_double.h"
33 : #include "advgetopt/validator_integer.h"
34 :
35 :
36 : // advgetopt lib
37 : //
38 : #include "advgetopt/exception.h"
39 :
40 :
41 : // cppthread lib
42 : //
43 : #include <cppthread/guard.h>
44 : #include <cppthread/log.h>
45 : #include <cppthread/mutex.h>
46 :
47 :
48 : // snapdev lib
49 : //
50 : #include <snapdev/not_used.h>
51 : #include <snapdev/tokenize_string.h>
52 :
53 :
54 : // libutf8 lib
55 : //
56 : #include <libutf8/libutf8.h>
57 : #include <libutf8/iterator.h>
58 :
59 :
60 : // boost lib
61 : //
62 : #include <boost/algorithm/string/replace.hpp>
63 :
64 :
65 : // last include
66 : //
67 : #include <snapdev/poison.h>
68 :
69 :
70 :
71 :
72 : namespace advgetopt
73 : {
74 :
75 :
76 : namespace
77 : {
78 :
79 :
80 : /** \brief The library trace mode.
81 : *
82 : * This flag is used to determine whether the source of each option should
83 : * be traced. Very often, I have a problem where I'm not so sure where a
84 : * certain option was defined and how to fix the value of that option.
85 : * This flag allows us to debug that information at run time.
86 : *
87 : * When the flag is set to true (automatically done by the getopt object
88 : * when argv includes the "--show-sources" command line option), the sources
89 : * start to be traced. Once all the parsing is done, getopt again will check
90 : * whether it has the "--show-sources" command line option specified and if
91 : * so, it prints out all the options current values and the various sources
92 : * that were involved.
93 : */
94 : bool g_trace_sources = false;
95 :
96 :
97 : /** \brief The filename of the configuration being processed.
98 : *
99 : * This variable holds the filename of the configuration currently
100 : * being processed. This information is used to generate the trace
101 : * of the sources. That way it is possible to see where the current
102 : * value of a given variable comes from.
103 : *
104 : * This parameter is currently set from the
105 : * getopt::process_configuration_file() function.
106 : */
107 2 : std::string g_configuration_filename = std::string();
108 :
109 :
110 :
111 : } // no name namespace
112 :
113 :
114 :
115 : // from utils.cpp
116 : //
117 : // (it's here because we do not want to make cppthread public in
118 : // out header files--we could have an advgetopt_private.h, though)
119 : //
120 : cppthread::mutex & get_global_mutex();
121 :
122 :
123 :
124 :
125 : /** \brief Transform a string to a short name.
126 : *
127 : * This function transforms a string to a short name. The input string
128 : * can represent a UTF-8 character that can be used as a short name.
129 : *
130 : * An empty string is not considered to represent any name and thus
131 : * this function returns NO_SHORT_NAME when the input is an empty
132 : * string.
133 : *
134 : * \param[in] name The name to be checked.
135 : *
136 : * \return The short name character or NO_SHORT_NAME if it's not a match.
137 : */
138 2231723 : short_name_t string_to_short_name(std::string const & name)
139 : {
140 2231723 : if(!name.empty())
141 : {
142 2231722 : libutf8::utf8_iterator u8(name);
143 2231722 : short_name_t const short_name(*u8++);
144 2231722 : if(u8 == name.end())
145 : {
146 1112070 : return short_name;
147 : }
148 : }
149 :
150 1119653 : return NO_SHORT_NAME;
151 : }
152 :
153 :
154 : /** \brief Convert a short name to a UTF-8 string.
155 : *
156 : * This function is the opposite of the to_short_name() except that the
157 : * input is expected to be a valid short name or NO_SHORT_NAME.
158 : *
159 : * When the input is NO_SHORT_NAME, the function outputs an empty string.
160 : *
161 : * \note
162 : * There are other short names that are not really considered valid such
163 : * as control characters, the dash (-), and probably most other
164 : * punctuation, character codes which are not currently assigned to
165 : * any character in Unicode, etc. This function ignores all of those
166 : * potential problems.
167 : *
168 : * \param[in] short_name The short name to convert to UTF-8.
169 : *
170 : * \return The short name as a UTF-8 string or an empty string.
171 : */
172 2224181 : std::string short_name_to_string(short_name_t short_name)
173 : {
174 2224181 : if(short_name == NO_SHORT_NAME)
175 : {
176 1 : return std::string();
177 : }
178 2224180 : return libutf8::to_u8string(short_name);
179 : }
180 :
181 :
182 : /** \brief Create a new option_info object.
183 : *
184 : * This function creates a new option_info object with the specified \p name
185 : * and \p short_name. The \p short_name is optional.
186 : *
187 : * When adding options to a map of options, all the long and short names
188 : * must be unique. See the add_child() function for details.
189 : *
190 : * The \p short_name parameter is a UTF-32 character. To not offer a short
191 : * name for an option, use NO_SHORT_NAME as the value (which is the default
192 : * if not specified to the constructor.)
193 : *
194 : * \li Special Option Name: "--"
195 : *
196 : * The "--" long name is viewed as the separator between options and
197 : * \em filenames. When "--" is found by itself on the command line, then
198 : * it is viewed as a switch to go from having options to only having
199 : * \em filenames. Of course, these options may be used as any type of
200 : * values, not just filenames (it could be URLs, email addresses, numbers,
201 : * etc.)
202 : *
203 : * The "--" separator cannot be assigned a short name.
204 : *
205 : * \li Special Option Name: "*"
206 : *
207 : * The "*" long name is viewed as the \em accept \em all option. This
208 : * means all the options may not be defined in the list of options but
209 : * we still want to accept them. This is to allow dynamically defined
210 : * (supported) command options and especially to not have to declare
211 : * all the valid options found in a configuration file.
212 : *
213 : * \li Underscore and Dashes
214 : *
215 : * It is customary to support dashes between words in options appearing
216 : * on the command line (`--help-me`), however, it is unusual in
217 : * configuration files where underscores are used instead (`under_score`.)
218 : * When we compare option names, `'-' == '_'` is always considered true
219 : * so either dashes or underscore can be used in both cases.
220 : *
221 : * For this reason, the long name is saved with only dashes. That
222 : * means all the maps are indexed using the long name with dashes.
223 : *
224 : * \exception getopt_exception_logic
225 : * The constructor raises the invalid exception if the long name is an
226 : * empty string since this is not allowed. It will also raise that
227 : * exception if the name is the default option ("--") and a short name
228 : * is also defined. (i.e. no short name is allowed along the default
229 : * option.)
230 : *
231 : * \param[in] name The (long) name of this option.
232 : * \param[in] short_name The short name of this option (one character.)
233 : */
234 1727 : option_info::option_info(std::string const & name, short_name_t short_name)
235 : : f_name(boost::replace_all_copy(name, "_", "-"))
236 1735 : , f_short_name(short_name)
237 : {
238 1727 : if(f_name.empty())
239 : {
240 4 : if(short_name != NO_SHORT_NAME)
241 : {
242 : throw getopt_logic_error(
243 : "option_info::option_info(): all options must at least have a long name (short name: '"
244 4 : + libutf8::to_u8string(short_name)
245 6 : + "'.)");
246 : }
247 : throw getopt_logic_error(
248 2 : "option_info::option_info(): all options must at least have a long name.");
249 : }
250 :
251 1723 : if(f_name == "--")
252 : {
253 22 : if(short_name != NO_SHORT_NAME)
254 : {
255 : throw getopt_logic_error(
256 : "option_info::option_info(): the default parameter \"--\" cannot include a short name ('"
257 4 : + libutf8::to_u8string(short_name)
258 6 : + "'.)");
259 : }
260 :
261 20 : add_flag(GETOPT_FLAG_DEFAULT_OPTION);
262 : }
263 : else
264 : {
265 1701 : if(f_name[0] == '-')
266 : {
267 : throw getopt_logic_error(
268 : "option_info::option_info(): an option cannot start with a dash (-), \""
269 2 : + f_name
270 3 : + "\" is not valid.");
271 : }
272 :
273 1700 : if(short_name == '-')
274 : {
275 : throw getopt_logic_error(
276 1 : "option_info::option_info(): the short name of an option cannot be the dash (-).");
277 : }
278 : }
279 1719 : }
280 :
281 :
282 : /** \brief Get the long name of the option.
283 : *
284 : * This option retrieves the long name of the option.
285 : *
286 : * \note
287 : * Remember that the underscores in long names are converted to dashes.
288 : * This is because it makes more sense to look for command line parameters
289 : * with dashes. This function will return the name with only dashes.
290 : *
291 : * \note
292 : * The name is always defined. The creation of an option_info object
293 : * fails if the name is empty.
294 : *
295 : * \return The long name with dashes instead of underscores.
296 : */
297 3462 : std::string const & option_info::get_name() const
298 : {
299 3462 : return f_name;
300 : }
301 :
302 :
303 : /** \brief Assign a short name to an option.
304 : *
305 : * This function is used to assign a short name to an option.
306 : *
307 : * It can be changed to anything, including the NO_SHORT_NAME special
308 : * value.
309 : *
310 : * \warning
311 : * If you want this function to work as expected (i.e. for the option
312 : * to later be found using its short name), make sure to call the
313 : * getopt::set_short_name() on your getopt object and not directly this
314 : * function. This is because the getopt object needs to add the newly
315 : * named option to its map of options sorted by short name.
316 : *
317 : * \param[in] short_name The short name to assign to this option.
318 : *
319 : * \sa get_short_name()
320 : * \sa getopt::set_short_name()
321 : */
322 15 : void option_info::set_short_name(short_name_t short_name)
323 : {
324 15 : f_short_name = short_name;
325 15 : }
326 :
327 :
328 : /** \brief Get the short name of the option.
329 : *
330 : * This function returns the \p short_name of this option.
331 : *
332 : * The short name is a Unicode character (UTF-32).
333 : *
334 : * \return The short name character.
335 : */
336 1844 : short_name_t option_info::get_short_name() const
337 : {
338 1844 : return f_short_name;
339 : }
340 :
341 :
342 : /** \brief Retrieve the name of the option without any section names.
343 : *
344 : * The name of an option can include section names. These
345 : * are rarely used on the command line, but they are useful for
346 : * configuration files if you want to create multiple layers of
347 : * options (a.k.a. sections.)
348 : *
349 : * This function removes all the section names from the option name
350 : * and returns what's left.
351 : *
352 : * \return The base name without any section names.
353 : */
354 4 : std::string option_info::get_basename() const
355 : {
356 4 : std::string::size_type const pos(f_name.rfind("::"));
357 4 : if(pos == std::string::npos)
358 : {
359 1 : return f_name;
360 : }
361 :
362 3 : return f_name.substr(pos + 2);
363 : }
364 :
365 :
366 : /** \brief Retrieve the name of the sections.
367 : *
368 : * The name of an option can include section names. These
369 : * are rarely used on the command line, but they are useful for
370 : * configuration files if you want to create multiple layers of
371 : * options (a.k.a. sections.)
372 : *
373 : * This function returns all the section names found in this option
374 : * name. The last scope operator gets removed too.
375 : *
376 : * If the name does not include any sections, then this function returns
377 : * an empty string.
378 : *
379 : * \return The section names without the basename.
380 : */
381 4 : std::string option_info::get_section_name() const
382 : {
383 4 : std::string::size_type const pos(f_name.rfind("::"));
384 4 : if(pos == std::string::npos)
385 : {
386 1 : return std::string();
387 : }
388 :
389 3 : return f_name.substr(0, pos);
390 : }
391 :
392 :
393 : /** \brief Retrieve a list of section names.
394 : *
395 : * The name of an option can include section names. These
396 : * are rarely used on the command line, but they are useful for
397 : * configuration files if you want to create multiple layers of
398 : * options (a.k.a. sections.)
399 : *
400 : * This function returns a string_list_t of the section names found in
401 : * this option name.
402 : *
403 : * If the name does not include any sections, then this function returns
404 : * an empty list.
405 : *
406 : * \return The list of section name.
407 : */
408 4 : string_list_t option_info::get_section_name_list() const
409 : {
410 4 : std::string::size_type const pos(f_name.rfind("::"));
411 4 : if(pos == std::string::npos)
412 : {
413 1 : return string_list_t();
414 : }
415 :
416 6 : string_list_t section_list;
417 12 : snapdev::tokenize_string(section_list
418 6 : , f_name.substr(0, pos)
419 : , "::"
420 : , true
421 6 : , std::string()
422 : , &snapdev::string_predicate<string_list_t>);
423 3 : return section_list;
424 : }
425 :
426 :
427 : /** \brief Check whether this is the default option.
428 : *
429 : * This function checks whether this option represents the default option.
430 : * The default option is where non-options, generally filenames, are added
431 : * when not following an argument.
432 : *
433 : * The name of the default option is always "--". However, it is not
434 : * required. When no default option is defined, filenames can't be
435 : * specified and when such are found on the command line, an error
436 : * ensues.
437 : *
438 : * \return true if the name of the option is "--".
439 : */
440 1976 : bool option_info::is_default_option() const
441 : {
442 1976 : return has_flag(GETOPT_FLAG_DEFAULT_OPTION)
443 1976 : || (f_name.size() == 2 && f_name[0] == '-' && f_name[1] == '-');
444 : }
445 :
446 :
447 : /** \brief Set the option specific environment variable name.
448 : *
449 : * Each option can be given a specific environment variable name. That
450 : * parameter is used to retrieve the option value if not defined on the
451 : * command line.
452 : *
453 : * By default this is an empty string.
454 : *
455 : * \param[in] name The name of the environment variable attached to this
456 : * option.
457 : *
458 : * \sa get_environment_variable_name()
459 : * \sa get_environment_variable_value()
460 : */
461 18 : void option_info::set_environment_variable_name(std::string const & name)
462 : {
463 18 : f_environment_variable_name = name;
464 18 : }
465 :
466 :
467 : /** \brief Set the default value of this option.
468 : *
469 : * This function is an overload which allows us to call set_default()
470 : * with a nullptr.
471 : *
472 : * \param[in] default_value The new default value for this option.
473 : *
474 : * \sa get_environment_variable_name()
475 : * \sa get_environment_variable_value()
476 : */
477 1595 : void option_info::set_environment_variable_name(char const * name)
478 : {
479 1595 : if(name != nullptr)
480 : {
481 18 : set_environment_variable_name(std::string(name));
482 : }
483 1595 : }
484 :
485 :
486 : /** \brief Retrieve the environment variable name of this option.
487 : *
488 : * Each command line option can be assigned an environment variable
489 : * name. When checking for the global environment variable name, the
490 : * advgetopt library also checks each option's environment variable
491 : * name which has priority over the global variable (i.e. it will
492 : * overwrite a value found in the global environment variable).
493 : *
494 : * The value returned is an empty string by default, which means the
495 : * option does not have a value defined in an environment variable.
496 : *
497 : * \return The environment variable name of this option.
498 : *
499 : * \sa set_environment_variable_name()
500 : * \sa get_environment_variable_value()
501 : */
502 1323 : std::string option_info::get_environment_variable_name() const
503 : {
504 1323 : return f_environment_variable_name;
505 : }
506 :
507 :
508 : /** \brief Retrieve the environment variable value of this option.
509 : *
510 : * Each command line option can be assigned an environment variable
511 : * name. Using this name, this function attempts to retrieve the
512 : * corresponding value defined in that variable.
513 : *
514 : * \param[out] value Save the resulting value in this variable.
515 : * \param[in] intro The introducer to prepend. May be nullptr.
516 : *
517 : * \return true if a value was defined.
518 : *
519 : * \sa set_environment_variable_name()
520 : * \sa get_environment_variable_name()
521 : */
522 18 : bool option_info::get_environment_variable_value(
523 : std::string & value
524 : , char const * intro) const
525 : {
526 : // make it empty by default
527 : //
528 18 : value.clear();
529 :
530 18 : if(f_environment_variable_name.empty())
531 : {
532 0 : return false;
533 : }
534 :
535 36 : std::string name(f_environment_variable_name);
536 18 : if(intro != nullptr)
537 : {
538 0 : name = intro + name;
539 : }
540 :
541 18 : char const * env(getenv(name.c_str()));
542 18 : if(env == nullptr)
543 : {
544 5 : return false;
545 : }
546 :
547 13 : value = env;
548 :
549 13 : return true;
550 : }
551 :
552 :
553 : /** \brief Get the flags.
554 : *
555 : * The options have flags determining various sub-options available
556 : * to them. Right now we have flags to tell how each option can be
557 : * used (on the command line, in an environment variable, or in
558 : * a configuration file.)
559 : *
560 : * \note
561 : * We have the GETOPT_FLAG_ALIAS flag which is used to define
562 : * an alias. That means values do not get set in an option which
563 : * is marked as an alias. Instead, they get set in the option
564 : * which is being aliased. This means your software does not have
565 : * to check both options. The setup function will actually call
566 : * the set_alias() function at some point to finalize aliases
567 : * so you do not really need the flag, except to know that no
568 : * value will be defined here because it will instead be saved
569 : * in the aliased option.
570 : *
571 : * \param[in] flags The new flags.
572 : */
573 67 : void option_info::set_flags(flag_t flags)
574 : {
575 67 : f_flags = flags;
576 67 : }
577 :
578 :
579 : /** \brief Make sure a given flag is set.
580 : *
581 : * This function adds the given flag from the set of flags being set.
582 : *
583 : * \param[in] flag The flag(s) to set.
584 : */
585 1889 : void option_info::add_flag(flag_t flag)
586 : {
587 1889 : f_flags |= flag;
588 1889 : }
589 :
590 :
591 : /** \brief Make sure a given flag is not set.
592 : *
593 : * This function removes the given flag from the set of flags being set.
594 : *
595 : * \param[in] flag The flag(s) to clear.
596 : */
597 46 : void option_info::remove_flag(flag_t flag)
598 : {
599 46 : f_flags &= ~flag;
600 46 : }
601 :
602 :
603 : /** \brief Retrieve the flags.
604 : *
605 : * This function retrieves all the flags defined in this option.
606 : *
607 : * To just check whether a flag is set or not, use the has_flag()
608 : * function instead.
609 : *
610 : * \return This option flags.
611 : */
612 1189 : flag_t option_info::get_flags() const
613 : {
614 1189 : return f_flags;
615 : }
616 :
617 :
618 : /** \brief Check whether a flag is set.
619 : *
620 : * This function is used to check whether a flag is set or not.
621 : *
622 : * \note
623 : * The \p flag parameter can be set to more than one flag in which case
624 : * the function returns true if any one of those flags is set.
625 : *
626 : * \return true if the flag is set, false otherwise.
627 : */
628 19257 : bool option_info::has_flag(flag_t flag) const
629 : {
630 19257 : return (f_flags & flag) != 0;
631 : }
632 :
633 :
634 : /** \brief Check whether this option has a default value.
635 : *
636 : * Whenever an option is given a default value, the GETOPT_FLAG_HAS_DEFAULT
637 : * flag gets set. This allows us to distinguish between an option with a
638 : * default which is the empty string and an option without a default.
639 : *
640 : * The set_default() forces the flag to be set.
641 : *
642 : * The remove_default() clears the flag.
643 : *
644 : * \return true if the flag is set, false otherwise.
645 : *
646 : * \sa set_default()
647 : * \sa remove_default()
648 : * \sa get_default()
649 : */
650 387 : bool option_info::has_default() const
651 : {
652 387 : return has_flag(GETOPT_FLAG_HAS_DEFAULT);
653 : }
654 :
655 :
656 : /** \brief Set the default value.
657 : *
658 : * This function sets the default value for this option.
659 : *
660 : * The default value is always defined as a string, but it can later be
661 : * converted to a different type using the option validator.
662 : *
663 : * Often, though, the default value is not compatible with the validator.
664 : * For example, you may have a parameter which is set to a percentage
665 : * from -100% to +100% and the default may be the string "off".
666 : *
667 : * \note
668 : * After calling this function, the option is viewed as having a default
669 : * even if that's the empty string.
670 : *
671 : * \param[in] default_value The new default value for this option.
672 : *
673 : * \sa remove_default()
674 : * \sa has_default()
675 : * \sa get_default()
676 : */
677 117 : void option_info::set_default(std::string const & default_value)
678 : {
679 117 : f_default_value = default_value;
680 117 : add_flag(GETOPT_FLAG_HAS_DEFAULT);
681 117 : }
682 :
683 :
684 : /** \brief Set the default value of this option.
685 : *
686 : * This function is an overload which allows us to call set_default()
687 : * with a nullptr.
688 : *
689 : * \param[in] default_value The new default value for this option.
690 : *
691 : * \sa remove_default()
692 : * \sa has_default()
693 : * \sa get_default()
694 : */
695 1598 : void option_info::set_default(char const * default_value)
696 : {
697 1598 : if(default_value != nullptr)
698 : {
699 103 : set_default(std::string(default_value));
700 : }
701 1598 : }
702 :
703 :
704 : /** \brief Remove the default value.
705 : *
706 : * Call this function remove the default value. The default string gets
707 : * cleared and the GETOPT_FLAG_NO_DEFAULT flag gets set.
708 : *
709 : * \sa set_default()
710 : * \sa has_default()
711 : * \sa get_default()
712 : */
713 4 : void option_info::remove_default()
714 : {
715 4 : f_default_value.clear();
716 4 : remove_flag(GETOPT_FLAG_HAS_DEFAULT);
717 4 : }
718 :
719 :
720 : /** \brief Retrieve the default value.
721 : *
722 : * This function returns the default value.
723 : *
724 : * \return The default string value.
725 : */
726 729 : std::string const & option_info::get_default() const
727 : {
728 729 : return f_default_value;
729 : }
730 :
731 :
732 : /** \brief Set the help string for this option.
733 : *
734 : * The usage() function prints this string whenever the command
735 : * line includes the help command line option (such as `-h` or
736 : * `--help`.)
737 : *
738 : * The string can include various flags such as `%p` to include
739 : * dynamically defined parameters. See the process_help_string()
740 : * function for additional details about these parameters.
741 : *
742 : * \note
743 : * When using a special flag (i.e. GETOPT_FLAG_HELP), the help value
744 : * string is used as the value used by that special feature:
745 : *
746 : * \li GETOPT_FLAG_HELP
747 : *
748 : * It represents a string to print out by the usage() function. The option
749 : * purpose is solaly for adding a string of help in the output.
750 : *
751 : * \li GETOPT_FLAG_EXTERNAL_OPTIONS
752 : *
753 : * It represents the filename to read additional advgetopt options. In
754 : * some cases, your static array of option structures is to define this
755 : * special flag.
756 : *
757 : * \li GETOPT_FLAG_LICENSE
758 : *
759 : * It represents the program license.
760 : *
761 : * \li GETOPT_FLAG_COPYRIGHT
762 : *
763 : * It represents the program copyright notice.
764 : *
765 : * \param[in] help The help string for this option.
766 : */
767 1616 : void option_info::set_help(std::string const & help)
768 : {
769 1616 : f_help = help;
770 1616 : }
771 :
772 :
773 : /** \brief Set the help string for this option.
774 : *
775 : * This function is an overload which allows us to call set_help() with
776 : * a nullptr and not crash. We just ignore the call when that happens.
777 : *
778 : * \param[in] help The help string for this option or nullptr.
779 : */
780 1606 : void option_info::set_help(char const * help)
781 : {
782 1606 : if(help != nullptr)
783 : {
784 1589 : set_help(std::string(help));
785 : }
786 1606 : }
787 :
788 :
789 : /** \brief Get the help string.
790 : *
791 : * This function returns the help string for this command line option.
792 : *
793 : * \warning
794 : * Note that when a special flag is set, this string may represent something
795 : * else that a help string.
796 : *
797 : * \return The help string of this argument.
798 : */
799 302 : std::string const & option_info::get_help() const
800 : {
801 302 : return f_help;
802 : }
803 :
804 :
805 : /** \brief Set the validator for this option.
806 : *
807 : * This function parses the specified name and optional parameters and
808 : * create a corresponding validator for this option.
809 : *
810 : * The \p name_and_params string can be defined as one of:
811 : *
812 : * \code
813 : * <validator-name>
814 : * <validator-name>()
815 : * <validator-name>(<param1>)
816 : * <validator-name>(<param1>, <param2>, ...)
817 : * \endcode
818 : *
819 : * The list of parameters is optional. There may be no, just one,
820 : * or any number of parameters. How the parameters are parsed is left
821 : * to the validator to decide.
822 : *
823 : * If the input string is empty, the current validator, if one is
824 : * installed, gets removed.
825 : *
826 : * \note
827 : * If the option_info already has a set of values, they get validated
828 : * against the new validator. Any value which does not validate gets
829 : * removed at once. The validation process also generates an error
830 : * when an invalid error is found. Note that it is expected that you
831 : * will setup a validator before you start parsing data so this feature
832 : * should seldom be used.
833 : *
834 : * \param[in] name_and_params The validator name and parameters.
835 : *
836 : * \return true if the validator was installed and all existing values were
837 : * considered valid.
838 : */
839 28 : bool option_info::set_validator(std::string const & name_and_params)
840 : {
841 28 : return set_validator(validator::create(name_and_params));
842 : }
843 :
844 :
845 : /** \brief Set the validator for this option.
846 : *
847 : * Options may be assigned a validator. Without a validator, any value
848 : * is considered valid.
849 : *
850 : * A value is checked when you call the validates() function. The function
851 : * returns true if the value is considered valid. False in all other cases.
852 : *
853 : * You can define your own validators and add them to the library list of
854 : * available validators before using the library in order to get your
855 : * options to use said validators.
856 : *
857 : * \note
858 : * If the option_info already has a set of values, they get validated
859 : * against the new validator. Any value which does not validate gets
860 : * removed at once. The validation process also generates an error
861 : * when an invalid error is found. Note that it is expected that you
862 : * will setup a validator before you start parsing data so this feature
863 : * should seldom be used.
864 : *
865 : * \param[in] validator A pointer to a validator.
866 : *
867 : * \return true if the validator was installed and all existing values were
868 : * considered valid.
869 : */
870 28 : bool option_info::set_validator(validator::pointer_t validator)
871 : {
872 28 : f_validator = validator;
873 :
874 : // make sure that all existing values validate against this
875 : // new validator
876 : //
877 28 : std::size_t const size(f_value.size());
878 28 : bool const r(validate_all_values());
879 28 : if(size != f_value.size())
880 : {
881 3 : value_changed(0);
882 : }
883 28 : return r;
884 : }
885 :
886 :
887 : /** \brief Clear the validator.
888 : *
889 : * This function removes the existing validator by resetting the pointer
890 : * back to nullptr.
891 : *
892 : * \param[in] null_ptr Ignored.
893 : *
894 : * \return Always true since no validator means any existing values would
895 : * be considered valid.
896 : */
897 5 : bool option_info::set_validator(std::nullptr_t null_ptr)
898 : {
899 5 : snapdev::NOT_USED(null_ptr);
900 :
901 5 : f_validator.reset();
902 :
903 5 : return true;
904 : }
905 :
906 :
907 : /** \brief Check a value validity.
908 : *
909 : * This function us used internally to verify values that get added at
910 : * the time they get added. It runs the validator::validate() function
911 : * and returns true if the value is considered valid. When the value
912 : * does not validate, it returns false and removes the value from the
913 : * f_value vector. This means no invalid values are ever kept in an
914 : * option_info object.
915 : *
916 : * An option without a validator has values that are always valid.
917 : * Also, an empty value is always considered valid.
918 : *
919 : * \note
920 : * This function is private since there is no need for the user of
921 : * the option_info to ever call it (i.e. it automatically gets called
922 : * any time a value gets added to the f_value vector.)
923 : *
924 : * \param[in] idx The value to check.
925 : *
926 : * \return true if the value is considered valid, false otherwise.
927 : */
928 671 : bool option_info::validates(int idx)
929 : {
930 671 : if(static_cast<size_t>(idx) >= f_value.size())
931 : {
932 : throw getopt_undefined( // LCOV_EXCL_LINE
933 : "option_info::get_value(): no value at index " // LCOV_EXCL_LINE
934 : + std::to_string(idx) // LCOV_EXCL_LINE
935 : + " (idx >= " // LCOV_EXCL_LINE
936 : + std::to_string(f_value.size()) // LCOV_EXCL_LINE
937 : + ") for --" // LCOV_EXCL_LINE
938 : + f_name // LCOV_EXCL_LINE
939 : + " so you can't get this value."); // LCOV_EXCL_LINE
940 : }
941 :
942 : // the value is considered valid when:
943 : // * there is no validator
944 : // * if the value is empty
945 : // * when the value validate against the specified validator
946 : //
947 1342 : if(f_validator == nullptr
948 67 : || f_value[idx].empty()
949 730 : || f_validator->validate(f_value[idx]))
950 : {
951 653 : return true;
952 : }
953 :
954 36 : cppthread::log << cppthread::log_level_t::error
955 18 : << "input \""
956 18 : << f_value[idx]
957 18 : << "\" given to parameter --"
958 18 : << f_name
959 18 : << " is not considered valid."
960 36 : << cppthread::end;
961 :
962 : // get rid of that value since it does not validate
963 : //
964 18 : f_value.erase(f_value.begin() + idx);
965 18 : if(f_value.empty())
966 : {
967 10 : f_source = option_source_t::SOURCE_UNDEFINED;
968 : }
969 :
970 18 : return false;
971 : }
972 :
973 :
974 : /** \brief Retrieve a pointer to the validator.
975 : *
976 : * The validator of an option may be used for additional tasks such as
977 : * converting the value to a specific type (i.e. a string to an
978 : * integer, for example.)
979 : *
980 : * This function allows you to retrieve the validator to be able to
981 : * make use of those functions. You will have to use
982 : * std::dynamic_cast_pointer<>() to change the type of validator to
983 : * the specialized validator of this option. If that returns a null
984 : * pointer, then the option is not using that type of validator.
985 : *
986 : * \todo
987 : * Add a template function that does the cast for the caller.
988 : *
989 : * \return A pointer to this option validator.
990 : */
991 19 : validator::pointer_t option_info::get_validator() const
992 : {
993 19 : return f_validator;
994 : }
995 :
996 :
997 : /** \brief Set the alias option.
998 : *
999 : * After loading all the options, we run the link_aliases() function which
1000 : * makes sure that all the options that are marked as an alias are
1001 : * properly linked.
1002 : *
1003 : * \param[in] alias The final destination of this option.
1004 : */
1005 20 : void option_info::set_alias_destination(option_info::pointer_t destination)
1006 : {
1007 20 : if(destination->has_flag(GETOPT_FLAG_ALIAS))
1008 : {
1009 : throw getopt_invalid(
1010 : "option_info::set_alias(): you can't set an alias as"
1011 1 : " an alias of another option.");
1012 : }
1013 :
1014 19 : f_alias_destination = destination;
1015 19 : }
1016 :
1017 :
1018 : /** \brief Get a link to the destination alias.
1019 : *
1020 : * This function returns a pointer to the aliased option.
1021 : *
1022 : * \return The alias or a nullptr.
1023 : */
1024 95 : option_info::pointer_t option_info::get_alias_destination() const
1025 : {
1026 95 : return f_alias_destination;
1027 : }
1028 :
1029 :
1030 : /** \brief Set the list of separators.
1031 : *
1032 : * Options marked with the GETOPT_FLAG_MULTIPLE flag
1033 : * get their value cut by separators when such is found in an
1034 : * environment variable or a configuration file.
1035 : *
1036 : * This function saves the list of separators in a vector.
1037 : *
1038 : * \todo
1039 : * At the moment, this is only applied when the parameter is specified with
1040 : * the long option and an equal sign, as in: `--tags=a,b,c,d`. I thinks that
1041 : * it should also work without the equal sign.
1042 : *
1043 : * \param[in] separators The list of separators to be used for this argument.
1044 : */
1045 1599 : void option_info::set_multiple_separators(char const * const * separators)
1046 : {
1047 1599 : f_multiple_separators.clear();
1048 1599 : if(separators == nullptr)
1049 : {
1050 1580 : return;
1051 : }
1052 :
1053 73 : for(; *separators != nullptr; ++separators)
1054 : {
1055 27 : f_multiple_separators.push_back(*separators);
1056 : }
1057 : }
1058 :
1059 :
1060 : /** \brief Set the list of separators.
1061 : *
1062 : * Options marked with the GETOPT_FLAG_MULTIPLE flag
1063 : * get their value cut by separators when such is found in an
1064 : * environment variable or a configuration file.
1065 : *
1066 : * This function saves the specified list of separators.
1067 : *
1068 : * \todo
1069 : * See the other set_multiple_separators() function about the issue of
1070 : * the separators not being used in all cases.
1071 : *
1072 : * \param[in] separators The list of separators to be used for this argument.
1073 : */
1074 7 : void option_info::set_multiple_separators(string_list_t const & separators)
1075 : {
1076 7 : f_multiple_separators = separators;
1077 7 : }
1078 :
1079 :
1080 : /** \brief Retrieve the list of separators for this argument.
1081 : *
1082 : * This function returns a reference to the list of separators of this
1083 : * option. It is expected to be used when a value is found in a
1084 : * configuration file or a command line in an environment variable.
1085 : * Parameters on the command line are already broken down by the
1086 : * shell and we do not do any further manipulation with those.
1087 : *
1088 : * \warning
1089 : * As mentioned in the set_multiple_separators() function, the separators
1090 : * are only used when parsing a long parameter using the equal sign notation
1091 : * (i.e. `--tags=a,b,c,d`). It also works in environment variables. I am
1092 : * thinking that the `--tags a,b,c,d` should probably work the same way
1093 : * though because otherwise many people will have a surprise.
1094 : *
1095 : * \return A reference to the list of separators used to cut multiple
1096 : * arguments found in a configuration file or an environment
1097 : * variable.
1098 : */
1099 9 : string_list_t const & option_info::get_multiple_separators() const
1100 : {
1101 9 : return f_multiple_separators;
1102 : }
1103 :
1104 :
1105 : /** \brief Assign variables to this option info.
1106 : *
1107 : * The getopt object holds a set of variables which is can pass down to
1108 : * the option info. If defined, then the get_value() function returns
1109 : * a processed value (a.k.a. the `${...}` references in that value are
1110 : * replaced by their corresponding value).
1111 : *
1112 : * \param[in] vars A pointer to a list of variables.
1113 : */
1114 1664 : void option_info::set_variables(variables::pointer_t vars)
1115 : {
1116 1664 : f_variables = vars;
1117 1664 : }
1118 :
1119 :
1120 : /** \brief Retrieve the list of variables held by this option info.
1121 : *
1122 : * This option info object may replace variables in values (see get_value()
1123 : * for details) using this list of variables. Option info objects created
1124 : * by the getopt class always have this pointer set, although the list of
1125 : * variables may be empty.
1126 : *
1127 : * \return A pointer to the list of variables found in the option info object.
1128 : */
1129 6 : variables::pointer_t option_info::get_variables() const
1130 : {
1131 6 : return f_variables;
1132 : }
1133 :
1134 :
1135 : /** \brief Check whether one of the values matches the input.
1136 : *
1137 : * This function searches the set of existing values in this option_info
1138 : * and if found returns true.
1139 : *
1140 : * \note
1141 : * It is possible to add the same value multiple times. However, there are
1142 : * cases where you may not want to have the same value more than once.
1143 : * This function can be used to try to not do that.
1144 : *
1145 : * \param[in] value The value to search in this option.
1146 : *
1147 : * \return true if the value is already defined in this option_info.
1148 : *
1149 : * \sa set_value()
1150 : */
1151 11 : bool option_info::has_value(std::string const & value) const
1152 : {
1153 11 : auto const it(std::find(f_value.begin(), f_value.end(), value));
1154 11 : return it != f_value.end();
1155 : }
1156 :
1157 :
1158 : /** \brief Add a value to this option.
1159 : *
1160 : * Whenever an option is found it may be followed by one or more values.
1161 : * This function is used to add these values to this option.
1162 : *
1163 : * Later you can use the size() function to know how many values were
1164 : * added and the get_value() to retrieve any one of these values.
1165 : *
1166 : * \warning
1167 : * This function sets the value at offset 0 if it is already defined and
1168 : * the GETOPT_FLAG_MULTIPLE flag is not set in this option. In other words,
1169 : * you can't use this function to add multiple values if this option does
1170 : * not support that feature.
1171 : *
1172 : * \param[in] value The value to add to this option.
1173 : * \param[in] source Where the value comes from.
1174 : *
1175 : * \return true when the value was accepted (no error occurred).
1176 : *
1177 : * \sa set_value()
1178 : */
1179 483 : bool option_info::add_value(std::string const & value, option_source_t source)
1180 : {
1181 622 : return set_value(
1182 483 : has_flag(GETOPT_FLAG_MULTIPLE)
1183 139 : ? f_value.size()
1184 : : 0
1185 : , value
1186 483 : , source);
1187 : }
1188 :
1189 :
1190 : /** \brief Replace a value.
1191 : *
1192 : * This function is generally used to replace an existing value. If the
1193 : * index is set to the size of the existing set of values, then a new
1194 : * value is saved in the vector.
1195 : *
1196 : * This is particularly useful if you want to edit a configuration file.
1197 : *
1198 : * If the option comes with a validator, then the value gets checked
1199 : * against that validator. If that results in an error, the value is
1200 : * not added to the vector so an invalid value will never be returned
1201 : * by the option_info class.
1202 : *
1203 : * The value does not get added when it currently is locked or when
1204 : * it does not validate as per the validator of this option_info.
1205 : *
1206 : * \exception getopt_exception_undefined
1207 : * If the index is out of range (too large or negative), then this
1208 : * exception is raised.
1209 : *
1210 : * \param[in] idx The position of the value to update.
1211 : * \param[in] value The new value.
1212 : * \param[in] source Where the value comes from.
1213 : *
1214 : * \return true if the set_value() added the value.
1215 : *
1216 : * \sa add_value()
1217 : * \sa validates()
1218 : * \sa lock()
1219 : * \sa unlock()
1220 : */
1221 688 : bool option_info::set_value(int idx, std::string const & value, option_source_t source)
1222 : {
1223 688 : if(source == option_source_t::SOURCE_UNDEFINED)
1224 : {
1225 : throw getopt_logic_error(
1226 : "option_info::set_value(): called with SOURCE_UNDEFINED ("
1227 2 : + std::to_string(static_cast<int>(source))
1228 3 : + ").");
1229 : }
1230 :
1231 687 : if(has_flag(GETOPT_FLAG_LOCK))
1232 : {
1233 8 : return false;
1234 : }
1235 :
1236 679 : if(source == option_source_t::SOURCE_DIRECT
1237 679 : && !has_flag(GETOPT_FLAG_DYNAMIC_CONFIGURATION))
1238 : {
1239 2 : cppthread::log << cppthread::log_level_t::error
1240 1 : << "option \"--"
1241 1 : << f_name
1242 1 : << "\" can't be directly updated."
1243 2 : << cppthread::end;
1244 1 : return false;
1245 : }
1246 :
1247 678 : if(has_flag(GETOPT_FLAG_MULTIPLE))
1248 : {
1249 155 : if(static_cast<size_t>(idx) > f_value.size())
1250 : {
1251 : throw getopt_logic_error(
1252 : "option_info::set_value(): no value at index "
1253 4 : + std::to_string(idx)
1254 6 : + " and it is not the last available index + 1 (idx > "
1255 8 : + std::to_string(f_value.size())
1256 6 : + ") so you can't set this value (try add_value() maybe?).");
1257 : }
1258 : }
1259 : else
1260 : {
1261 523 : if(idx != 0)
1262 : {
1263 : throw getopt_logic_error(
1264 : "option_info::set_value(): single value option \"--"
1265 4 : + f_name
1266 6 : + "\" does not accepts index "
1267 8 : + std::to_string(idx)
1268 6 : + " which is not 0.");
1269 : }
1270 : }
1271 :
1272 674 : f_source = source;
1273 674 : if(static_cast<size_t>(idx) == f_value.size())
1274 : {
1275 541 : f_value.push_back(value);
1276 : }
1277 : else
1278 : {
1279 133 : if(f_value[idx] == value)
1280 : {
1281 : // no change, we can return as is
1282 : //
1283 21 : return true;
1284 : }
1285 112 : f_value[idx] = value;
1286 : }
1287 653 : f_integer.clear();
1288 653 : f_double.clear();
1289 :
1290 653 : bool const r(validates(idx));
1291 :
1292 653 : value_changed(idx);
1293 :
1294 653 : return r;
1295 : }
1296 :
1297 :
1298 : /** \brief Set a multi-value at once.
1299 : *
1300 : * This function views the \p value parameter as a multi-value parameter
1301 : * which it breaks down in multiple parameters and add the results to this
1302 : * option_info object as the current value(s).
1303 : *
1304 : * To separate the values, the function makes use of the separators as
1305 : * set by one the set_multiple_separators() functions.
1306 : *
1307 : * The resulting values must not be the empty string. Empty strings are
1308 : * ignored. So if the separator is a comma and you write:
1309 : *
1310 : * \code
1311 : * foo,,,bar
1312 : * \endcode
1313 : *
1314 : * The result includes "foo" and "bar" and no empty strings.
1315 : *
1316 : * \note
1317 : * The function has the side effect of clearing any existing parameters
1318 : * first. So only the newly defined parameters in \p value will be set
1319 : * in the option once the function returns.
1320 : *
1321 : * \todo
1322 : * Add support for quoted values
1323 : *
1324 : * \param[in] value The multi-value to save in this option.
1325 : * \param[in] source Where the value comes from.
1326 : *
1327 : * \return true if all the values in \p value were considered valid.
1328 : *
1329 : * \sa add_value()
1330 : * \sa set_value()
1331 : */
1332 38 : bool option_info::set_multiple_values(std::string const & value, option_source_t source)
1333 : {
1334 38 : if(source == option_source_t::SOURCE_UNDEFINED)
1335 : {
1336 : throw getopt_logic_error(
1337 : "option_info::set_multiple_values(): called with SOURCE_UNDEFINED ("
1338 2 : + std::to_string(static_cast<int>(source))
1339 3 : + ").");
1340 : }
1341 :
1342 74 : string_list_t result;
1343 37 : split_string(unquote(value, "[]"), result, f_multiple_separators);
1344 :
1345 74 : if(!has_flag(GETOPT_FLAG_MULTIPLE)
1346 37 : && result.size() > 1)
1347 : {
1348 : throw getopt_logic_error(
1349 : "option_info::set_multiple_value(): parameter --"
1350 2 : + f_name
1351 3 : + " expects zero or one parameter. The set_multiple_value() function should not be called with parameters that only accept one value.");
1352 : }
1353 :
1354 36 : f_source = source;
1355 36 : f_value.swap(result);
1356 36 : f_integer.clear();
1357 36 : f_double.clear();
1358 :
1359 36 : bool const r(validate_all_values());
1360 :
1361 36 : if(f_value != result)
1362 : {
1363 : // TBD: should we not call this function with all instances?
1364 : // i.e. for(int idx(0); idx < f_value.size(); ++idx) ...
1365 : // and check each value in f_value with the old value in
1366 : // the result variable (knowing that result may be smaller)
1367 : //
1368 34 : value_changed(0);
1369 : }
1370 :
1371 72 : return r;
1372 : }
1373 :
1374 :
1375 : /** \brief Validate all the values of this option_info object.
1376 : *
1377 : * Whenever you change the validator of an option_info, or change
1378 : * all the values with set_multiple_value(), all the values get
1379 : * verified using this function. The function removes any value
1380 : * which does not validate according to the current validator.
1381 : *
1382 : * \note
1383 : * Keep in mind that an empty value is always considered valid,
1384 : * no matter what the validator is. This is because when you
1385 : * use an option without a value (i.e. `--order` instead of
1386 : * `--order asc`) the value is set to the empty string unless
1387 : * there is a default. This allows you to know that the
1388 : * option was used without a value, which is useful for some
1389 : * options.
1390 : *
1391 : * \return true if all the values were considered valid.
1392 : */
1393 64 : bool option_info::validate_all_values()
1394 : {
1395 64 : bool all_valid(true);
1396 64 : if(f_validator != nullptr)
1397 : {
1398 35 : for(size_t idx(0); idx < f_value.size(); )
1399 : {
1400 18 : if(!validates(idx))
1401 : {
1402 : // the value was removed, so do not increment `idx`
1403 : //
1404 9 : all_valid = false;
1405 : }
1406 : else
1407 : {
1408 9 : ++idx;
1409 : }
1410 : }
1411 : }
1412 :
1413 64 : return all_valid;
1414 : }
1415 :
1416 :
1417 : /** \brief Check whether a value is defined.
1418 : *
1419 : * When parsing the options on the command line or a configuration file,
1420 : * values get added to the various existing option_info. If a special
1421 : * "*" option is also defined, then any value found on the command line
1422 : * or the configuration file are returned.
1423 : *
1424 : * To know whether this or that option was defined with a value, use
1425 : * this function. Even an option which doesn't come with a parameter
1426 : * will get an is_defined() returning true once it was found on the
1427 : * command line. The value will be the empty string.
1428 : *
1429 : * \return true if that option was found on the command line, in the
1430 : * environment variable, or in the configuration file.
1431 : */
1432 2478 : bool option_info::is_defined() const
1433 : {
1434 2478 : return !f_value.empty();
1435 : }
1436 :
1437 :
1438 : /** \brief Return the source of this option info.
1439 : *
1440 : * This function returns the source of this option, i.e. whether it came
1441 : * from the command line, the environment variable, a configuration file,
1442 : * or some other source that you can define.
1443 : *
1444 : * The source is similar to a priority in the sense that a source with a
1445 : * higher number cannot overwrite the value of a smaller source. The source
1446 : * is set at the same time as you set the option. The mechanism may not be
1447 : * working exactly as expected when trying to add options from different
1448 : * sources.
1449 : *
1450 : * \note
1451 : * In the old version, the value would be the value set with the last
1452 : * set_value() command. That worked because we did not try to support
1453 : * fully dynamic options. Now we want to have the ability to set an
1454 : * option on the command line and that has to prevent the set from
1455 : * a dynamic source. Since the dynamic source would do the set_value()
1456 : * at a later time, just the order is not enough to know whether the
1457 : * dynamic source has permission to overwrite that value.
1458 : *
1459 : * \return The source of the option info.
1460 : */
1461 5 : option_source_t option_info::source() const
1462 : {
1463 5 : return f_source;
1464 : }
1465 :
1466 :
1467 : /** \brief Whether the sources should be traced.
1468 : *
1469 : * This is a global flag that you can set before calling any getopt functions
1470 : * so that way you can make sure that you get a full trace of all the
1471 : * sources for all your options. Then you can use the --show-sources
1472 : * command line options to see the resulting data.
1473 : *
1474 : * \note
1475 : * This option is costly since it saves a lot of data, which is why we have
1476 : * it as an option. If the getopt() function detects in the argv passed to
1477 : * it a "--show-sources" option, then it will automatically call this
1478 : * function with true, even before it starts parsing anything. The flag is
1479 : * false by default.
1480 : *
1481 : * \param[in] trace Whether the sources should be traced.
1482 : */
1483 1 : void option_info::set_trace_sources(bool trace)
1484 : {
1485 1 : g_trace_sources = trace;
1486 1 : }
1487 :
1488 :
1489 : /** \brief Get the trace of this option.
1490 : *
1491 : * An option can be marked for tracing. This allows you to see exactly
1492 : * which value came from which source. We currently support multiple
1493 : * sources such as the command line, environment variable, direct,
1494 : * dynamic, configuration files.
1495 : *
1496 : * \return An array of strings representing the source of each value
1497 : * in the order they were set in this option_info.
1498 : */
1499 92 : string_list_t const & option_info::trace_sources() const
1500 : {
1501 92 : return f_trace_sources;
1502 : }
1503 :
1504 :
1505 : /** \brief Save the filename of the current configuration file.
1506 : *
1507 : * While parsing a configuration file, this function gets called to
1508 : * set the name which is used to generate the trace of the source
1509 : * of all the configuration data.
1510 : */
1511 244 : void option_info::set_configuration_filename(std::string const & filename)
1512 : {
1513 244 : g_configuration_filename = filename;
1514 244 : }
1515 :
1516 :
1517 : /** \brief Retrieve the number of values defined for this option.
1518 : *
1519 : * This function returns the number of values that were found for this
1520 : * option.
1521 : *
1522 : * If the option is marked as GETOPT_FLAG_MULTIPLE, then this function
1523 : * may return 0 or more. Without that flag, this function only returns
1524 : * 0 or 1.
1525 : *
1526 : * You must use the size() parameter to know how many items are defined
1527 : * and call the get_value() with a correct `idx` parameter (i.e. a value
1528 : * between 0 and `size() - 1`.)
1529 : *
1530 : * \return The number of values defined in this option.
1531 : */
1532 492 : size_t option_info::size() const
1533 : {
1534 492 : return f_value.size();
1535 : }
1536 :
1537 :
1538 : /** \brief Retrieve the value.
1539 : *
1540 : * This function returns the value for this option. By default, set the
1541 : * \p idx parameter to zero.
1542 : *
1543 : * The number of values is defined by the size() function.
1544 : *
1545 : * The is_defined() function returns true if at least one value is defined.
1546 : * It is a good idea to check first otherwise you will get an exception.
1547 : *
1548 : * If the parameter is marked as one that can be processed through the
1549 : * variables::process_value() function and the variables were defined
1550 : * with set_variables(), then the value will be processed for variables
1551 : * unless you set the \p raw parameter to true.
1552 : *
1553 : * \exception getopt_exception_undefined
1554 : * If the \p idx parameter is too large or no value was found for this
1555 : * option, then this function raises an invalid error.
1556 : *
1557 : * \param[in] idx The index of the parameter to retrieve.
1558 : * \param[in] raw Whether to allow the variable processing or not.
1559 : *
1560 : * \return The value at \p idx.
1561 : */
1562 1266 : std::string option_info::get_value(int idx, bool raw) const
1563 : {
1564 1266 : if(static_cast<size_t>(idx) >= f_value.size())
1565 : {
1566 : throw getopt_undefined(
1567 : "option_info::get_value(): no value at index "
1568 4 : + std::to_string(idx)
1569 6 : + " (idx >= "
1570 8 : + std::to_string(f_value.size())
1571 6 : + ") for --"
1572 6 : + f_name
1573 6 : + " so you can't get this value.");
1574 : }
1575 :
1576 2528 : if(!raw
1577 1264 : && f_variables != nullptr
1578 2364 : && has_flag(GETOPT_FLAG_PROCESS_VARIABLES))
1579 : {
1580 6 : return f_variables->process_value(f_value[idx]);
1581 : }
1582 : else
1583 : {
1584 1258 : return f_value[idx];
1585 : }
1586 : }
1587 :
1588 :
1589 : /** \brief Get the value as a long.
1590 : *
1591 : * This function returns the value converted to a `long`.
1592 : *
1593 : * If the value does not represent a valid long value, an error is
1594 : * emitted through the logger.
1595 : *
1596 : * The value will be parsed through the variables if defined and this
1597 : * parameter allows it. This means the value may be a variable reference
1598 : * instead of an actually value (i.e. `${one}`)
1599 : *
1600 : * \note
1601 : * The function will transform all the values in case this is a
1602 : * GETOPT_FLAG_MULTIPLE option and cache the results.
1603 : * Calling the function many times with the same index is very fast
1604 : * after the first time.
1605 : *
1606 : * \exception getopt_exception_undefined
1607 : * If the value was not defined, the function raises this exception.
1608 : *
1609 : * \param[in] idx The index of the value to retrieve as a long.
1610 : *
1611 : * \return The value at \p idx converted to a long or -1 on error.
1612 : */
1613 157 : long option_info::get_long(int idx) const
1614 : {
1615 157 : if(static_cast<size_t>(idx) >= f_value.size())
1616 : {
1617 : throw getopt_undefined(
1618 : "option_info::get_long(): no value at index "
1619 2 : + std::to_string(idx)
1620 3 : + " (idx >= "
1621 4 : + std::to_string(f_value.size())
1622 3 : + ") for --"
1623 3 : + f_name
1624 3 : + " so you can't get this value.");
1625 : }
1626 :
1627 : // since we may change the f_integer vector between threads,
1628 : // add protection (i.e. most everything else is created at the
1629 : // beginning so in the main thread)
1630 : //
1631 312 : cppthread::guard lock(get_global_mutex());
1632 :
1633 156 : if(f_integer.size() != f_value.size())
1634 : {
1635 : // we did not yet convert to integers do that now
1636 : //
1637 88 : size_t const max(f_value.size());
1638 180 : for(size_t i(f_integer.size()); i < max; ++i)
1639 : {
1640 102 : std::int64_t v;
1641 102 : if(!validator_integer::convert_string(get_value(i), v))
1642 : {
1643 10 : f_integer.clear();
1644 :
1645 20 : cppthread::log << cppthread::log_level_t::error
1646 10 : << "invalid number ("
1647 10 : << f_value[i]
1648 10 : << ") in parameter --"
1649 10 : << f_name
1650 10 : << " at offset "
1651 10 : << i
1652 10 : << "."
1653 20 : << cppthread::end;
1654 10 : return -1;
1655 : }
1656 92 : f_integer.push_back(v);
1657 : }
1658 : }
1659 :
1660 146 : return f_integer[idx];
1661 : }
1662 :
1663 :
1664 : /** \brief Get the value as a double.
1665 : *
1666 : * This function returns the value converted to a `double`.
1667 : *
1668 : * If the value does not represent a valid double value, an error is
1669 : * emitted through the logger.
1670 : *
1671 : * The value will be parsed through the variables if defined and this
1672 : * parameter allows it. This means the value may be a variable reference
1673 : * instead of an actually value (i.e. `${pi}`)
1674 : *
1675 : * \note
1676 : * The function will transform all the values in case this is a
1677 : * GETOPT_FLAG_MULTIPLE option and cache the results.
1678 : * Calling the function many times with the same index is very fast
1679 : * after the first time.
1680 : *
1681 : * \exception getopt_exception_undefined
1682 : * If the value was not defined, the function raises this exception.
1683 : *
1684 : * \param[in] idx The index of the value to retrieve as a double.
1685 : *
1686 : * \return The value at \p idx converted to a double or -1.0 on error.
1687 : */
1688 0 : double option_info::get_double(int idx) const
1689 : {
1690 0 : if(static_cast<size_t>(idx) >= f_value.size())
1691 : {
1692 : throw getopt_undefined(
1693 : "option_info::get_double(): no value at index "
1694 0 : + std::to_string(idx)
1695 0 : + " (idx >= "
1696 0 : + std::to_string(f_value.size())
1697 0 : + ") for --"
1698 0 : + f_name
1699 0 : + " so you can't get this value.");
1700 : }
1701 :
1702 : // since we may change the f_integer vector between threads,
1703 : // add protection (i.e. most everything else is created at the
1704 : // beginning so in the main thread)
1705 : //
1706 0 : cppthread::guard lock(get_global_mutex());
1707 :
1708 0 : if(f_double.size() != f_value.size())
1709 : {
1710 : // we did not yet convert to doubles do that now
1711 : //
1712 0 : size_t const max(f_value.size());
1713 0 : for(size_t i(f_double.size()); i < max; ++i)
1714 : {
1715 0 : double v;
1716 0 : if(!validator_double::convert_string(get_value(i), v))
1717 : {
1718 0 : f_double.clear();
1719 :
1720 0 : cppthread::log << cppthread::log_level_t::error
1721 0 : << "invalid number ("
1722 0 : << f_value[i]
1723 0 : << ") in parameter --"
1724 0 : << f_name
1725 0 : << " at offset "
1726 0 : << i
1727 0 : << "."
1728 0 : << cppthread::end;
1729 0 : return -1;
1730 : }
1731 0 : f_double.push_back(v);
1732 : }
1733 : }
1734 :
1735 0 : return f_double[idx];
1736 : }
1737 :
1738 :
1739 : /** \brief Lock this value.
1740 : *
1741 : * This function allows for locking a value so further reading of data
1742 : * from different sources will not overwrite it.
1743 : *
1744 : * When parsing the data we have multiple levels. Here are these levels
1745 : * in priority order (first option found is the one we keep):
1746 : *
1747 : * \li Command line options
1748 : * \li Environment Variables
1749 : * \li Configuration File: Local (`./\<name>.conf`)
1750 : * \li Configuration File: User's (`~/.config/\<proc>/\<name>.conf`)
1751 : * \li Configuration File: Project sub-folder (`/etc/\<proc>/\<proc>.d/\<ohter-name>.conf`)
1752 : * \li Configuration File: Project folder (`/etc/\<proc>/\<other-name>.conf`)
1753 : * \li Configuration File: System sub-folder (`/etc/\<proc>/\<name>.conf`)
1754 : * \li Configuration File: System folder (`/etc/\<proc>/\<name>.conf`)
1755 : *
1756 : * \note
1757 : * Most of our packages do not have a Project and a System set of
1758 : * configuration files. Often they will have just the System files.
1759 : *
1760 : * We use this lock because we want to support multiple values so just
1761 : * detecting that a value is set to not add more options is not a good
1762 : * test. Instead we lock the values that are set before moving to the
1763 : * next level.
1764 : *
1765 : * \param[in] always Always lock that option, whether it is defined or not.
1766 : */
1767 6 : void option_info::lock(bool always)
1768 : {
1769 6 : if(!always)
1770 : {
1771 4 : if(!is_defined())
1772 : {
1773 2 : return;
1774 : }
1775 : }
1776 :
1777 4 : add_flag(GETOPT_FLAG_LOCK);
1778 : }
1779 :
1780 :
1781 : /** \brief Unlock this value.
1782 : *
1783 : * This function does the opposite of the lock() function. It allows for
1784 : * the value to be updated again.
1785 : *
1786 : * Once the getpot object is done parsing all the input, it unlocks all
1787 : * the values using this function. The unlock is always unconditional.
1788 : */
1789 4 : void option_info::unlock()
1790 : {
1791 4 : remove_flag(GETOPT_FLAG_LOCK);
1792 4 : }
1793 :
1794 :
1795 : /** \brief Reset this value.
1796 : *
1797 : * This function clears the value so it is marked as undefined again.
1798 : *
1799 : * To reuse the same getopt object multiple times, you can use the
1800 : * reset() function which clears the values. Then you can parse a
1801 : * new set of argc/argv parameters.
1802 : */
1803 27 : void option_info::reset()
1804 : {
1805 27 : if(is_defined())
1806 : {
1807 23 : f_source = option_source_t::SOURCE_UNDEFINED;
1808 23 : f_value.clear();
1809 23 : f_integer.clear();
1810 23 : f_double.clear();
1811 :
1812 23 : value_changed(0);
1813 : }
1814 27 : }
1815 :
1816 :
1817 : /** \brief Add a callback to call on a change to this value.
1818 : *
1819 : * Since we now officially support dynamically setting option values, we
1820 : * decided to add a callback mechanism that lets you know that an option
1821 : * changed. That way you can react to the change as soon as possible instead
1822 : * of having to poll for the value once in a while.
1823 : *
1824 : * \param[in] c The callback. Usually an std::bind() call.
1825 : *
1826 : * \return The new callback identifier.
1827 : */
1828 2 : option_info::callback_id_t option_info::add_callback(callback_t const & c)
1829 : {
1830 4 : cppthread::guard lock(get_global_mutex());
1831 :
1832 2 : ++f_next_callback_id;
1833 2 : f_callbacks.emplace_back(f_next_callback_id, c);
1834 4 : return f_next_callback_id;
1835 : }
1836 :
1837 :
1838 : /** \brief Remove a callback.
1839 : *
1840 : * This function is the opposite of the add_callback(). It removes a callback
1841 : * that you previously added. This is useful if you are interested in hearing
1842 : * about the value when set but are not interested at all about future
1843 : * changes.
1844 : *
1845 : * \param[in] id The id returned by the add_callback() function.
1846 : */
1847 3 : void option_info::remove_callback(callback_id_t id)
1848 : {
1849 6 : cppthread::guard lock(get_global_mutex());
1850 :
1851 3 : auto it(std::find_if(
1852 : f_callbacks.begin()
1853 : , f_callbacks.end()
1854 4 : , [id](auto e)
1855 4 : {
1856 4 : return e.f_id == id;
1857 7 : }));
1858 3 : if(it != f_callbacks.end())
1859 : {
1860 2 : f_callbacks.erase(it);
1861 : }
1862 3 : }
1863 :
1864 :
1865 : /** \brief Call whenever the value changed so we can handle callbacks.
1866 : *
1867 : * This function is called on a change of the internal values.
1868 : *
1869 : * The function is used to call the callbacks that were added to this
1870 : * option_info object. The function first copies the existing list of
1871 : * callbacks so you can safely update the list from within a callback.
1872 : *
1873 : * \warning
1874 : * Destroying your advgetopt::getopt option is not safe while a callback
1875 : * is running.
1876 : *
1877 : * \param[in] idx This represents the index of the value that last changed
1878 : * (currently poor attempt to fix this issue).
1879 : */
1880 713 : void option_info::value_changed(int idx)
1881 : {
1882 713 : trace_source(idx);
1883 :
1884 1426 : callback_vector_t callbacks;
1885 713 : callbacks.reserve(f_callbacks.size());
1886 :
1887 : {
1888 1426 : cppthread::guard lock(get_global_mutex());
1889 713 : callbacks = f_callbacks;
1890 : }
1891 :
1892 719 : for(auto e : callbacks)
1893 : {
1894 6 : e.f_callback(*this);
1895 : }
1896 713 : }
1897 :
1898 :
1899 :
1900 : /** \brief Remember the source information at of this last change.
1901 : *
1902 : * The getopt class supports a flag which turns on the trace mode. This
1903 : * allows it to memorize where the values came fram. This includes the
1904 : * source and if the source is a configuration file, the path to that
1905 : * configuration file.
1906 : */
1907 713 : void option_info::trace_source(int idx)
1908 : {
1909 713 : if(!g_trace_sources)
1910 : {
1911 555 : return;
1912 : }
1913 :
1914 315 : std::string s;
1915 158 : switch(f_source)
1916 : {
1917 87 : case option_source_t::SOURCE_COMMAND_LINE:
1918 87 : s = "command-line";
1919 87 : break;
1920 :
1921 50 : case option_source_t::SOURCE_CONFIGURATION:
1922 50 : s = "configuration=\"" + g_configuration_filename + "\"";
1923 50 : break;
1924 :
1925 1 : case option_source_t::SOURCE_DIRECT:
1926 1 : s = "direct";
1927 1 : break;
1928 :
1929 1 : case option_source_t::SOURCE_DYNAMIC:
1930 1 : s = "dynamic";
1931 1 : break;
1932 :
1933 18 : case option_source_t::SOURCE_ENVIRONMENT_VARIABLE:
1934 18 : s = "environment-variable";
1935 18 : break;
1936 :
1937 1 : case option_source_t::SOURCE_UNDEFINED:
1938 : // this happens on a reset or all the values were invalid
1939 : //
1940 1 : f_trace_sources.push_back(f_name + " [*undefined-source*]");
1941 1 : return;
1942 :
1943 : }
1944 :
1945 157 : if(f_value.empty())
1946 : {
1947 : // this should never ever happen
1948 : // (if f_value is empty then f_source == SOURCE_UNDEFINED)
1949 : //
1950 : f_trace_sources.push_back(f_name + " [*undefined-value*]"); // LCOV_EXCL_LINE
1951 : }
1952 : else
1953 : {
1954 : // TODO: change the algorithm, if the option supports
1955 : //
1956 314 : if(!has_flag(GETOPT_FLAG_MULTIPLE)
1957 157 : || static_cast<std::size_t>(idx) >= f_value.size())
1958 : {
1959 139 : f_trace_sources.push_back(f_name + "=" + f_value[0] + " [" + s + "]");
1960 : }
1961 : else
1962 : {
1963 18 : f_trace_sources.push_back(f_name + "[" + std::to_string(idx) + "]=" + f_value[idx] + " [" + s + "]");
1964 : }
1965 : }
1966 : }
1967 :
1968 :
1969 6 : } // namespace advgetopt
1970 : // vim: ts=4 sw=4 et
|