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