Line data Source code
1 : /*
2 : * License:
3 : * Copyright (c) 2006-2019 Made to Order Software Corp. All Rights Reserved
4 : *
5 : * https://snapwebsites.org/
6 : * contact@m2osw.com
7 : *
8 : * This program is free software; you can redistribute it and/or modify
9 : * it under the terms of the GNU General Public License as published by
10 : * the Free Software Foundation; either version 2 of the License, or
11 : * (at your option) any later version.
12 : *
13 : * This program is distributed in the hope that it will be useful,
14 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 : * GNU General Public License for more details.
17 : *
18 : * You should have received a copy of the GNU General Public License along
19 : * with this program; if not, write to the Free Software Foundation, Inc.,
20 : * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 : *
22 : * Authors:
23 : * Alexis Wilke alexis@m2osw.com
24 : * Doug Barbieri doug@m2osw.com
25 : */
26 :
27 :
28 : /** \file
29 : * \brief Implementation of the option_info class.
30 : *
31 : * This is the implementation of the class used to define one command
32 : * line option.
33 : */
34 :
35 : // self
36 : //
37 : #include "advgetopt/option_info.h"
38 :
39 :
40 : // advgetopt lib
41 : //
42 : #include "advgetopt/exception.h"
43 :
44 :
45 : // cppthread lib
46 : //
47 : #include <cppthread/guard.h>
48 : #include <cppthread/log.h>
49 : #include <cppthread/mutex.h>
50 :
51 :
52 : // snapdev lib
53 : //
54 : #include <snapdev/not_used.h>
55 : #include <snapdev/tokenize_string.h>
56 :
57 :
58 : // libutf8 lib
59 : //
60 : #include <libutf8/libutf8.h>
61 : #include <libutf8/iterator.h>
62 :
63 :
64 : // boost lib
65 : //
66 : #include <boost/algorithm/string/replace.hpp>
67 :
68 :
69 : // last include
70 : //
71 : #include <snapdev/poison.h>
72 :
73 :
74 :
75 :
76 : namespace advgetopt
77 : {
78 :
79 :
80 :
81 : // from utils.cpp
82 : //
83 : // (it's here because we do not want to make cppthread public in
84 : // out header files--we could have an advgetopt_private.h, though)
85 : //
86 : cppthread::mutex & get_global_mutex();
87 :
88 :
89 :
90 :
91 : /** \brief Transform a string to a short name.
92 : *
93 : * This function transforms a string to a short name. The input string
94 : * can represent a UTF-8 character that can be used as a short name.
95 : *
96 : * An empty string is not considered to represent any name and thus
97 : * this function returns NO_SHORT_NAME when the input is an empty
98 : * string.
99 : *
100 : * \param[in] name The name to be checked.
101 : *
102 : * \return The short name character or NO_SHORT_NAME if it's not a match.
103 : */
104 2230074 : short_name_t string_to_short_name(std::string const & name)
105 : {
106 2230074 : if(!name.empty())
107 : {
108 2230073 : libutf8::utf8_iterator u8(name);
109 2230073 : short_name_t const short_name(*u8++);
110 2230073 : if(u8 == name.end())
111 : {
112 1112070 : return short_name;
113 : }
114 : }
115 :
116 1118004 : return NO_SHORT_NAME;
117 : }
118 :
119 :
120 : /** \brief Convert a short name to a UTF-8 string.
121 : *
122 : * This function is the opposite of the to_short_name() except that the
123 : * input is expected to be a valid short name or NO_SHORT_NAME.
124 : *
125 : * When the input is NO_SHORT_NAME, the function outputs an empty string.
126 : *
127 : * \note
128 : * There are other short names that are not really considered valid such
129 : * as control characters, the dash (-), and probably most other
130 : * punctuation, character codes which are not currently assigned to
131 : * any character in Unicode, etc. This function ignores all of those
132 : * potential problems.
133 : *
134 : * \param[in] short_name The short name to convert to UTF-8.
135 : *
136 : * \return The short name as a UTF-8 string or an empty string.
137 : */
138 2224175 : std::string short_name_to_string(short_name_t short_name)
139 : {
140 2224175 : if(short_name == NO_SHORT_NAME)
141 : {
142 1 : return std::string();
143 : }
144 2224174 : return libutf8::to_u8string(short_name);
145 : }
146 :
147 :
148 : /** \brief Create a new option_info object.
149 : *
150 : * This function creates a new option_info object with the specified \p name
151 : * and \p short_name. The \p short_name is optional.
152 : *
153 : * When adding options to a map of options, all the long and short names
154 : * must be unique. See the add_child() function for details.
155 : *
156 : * The \p short_name parameter is a UTF-32 character. To not offer a short
157 : * name for an option, use NO_SHORT_NAME as the value (which is the default
158 : * if not specified to the constructor.)
159 : *
160 : * \li Special Option Name: "--"
161 : *
162 : * The "--" long name is viewed as the separator between options and
163 : * \em filenames. When "--" is found by itself on the command line, then
164 : * it is viewed as a switch to go from having options to only having
165 : * \em filenames. Of course, these options may be used as any type of
166 : * values, not just filenames (it could be URLs, email addresses, numbers,
167 : * etc.)
168 : *
169 : * The "--" separator cannot be assigned a short name.
170 : *
171 : * \li Special Option Name: "*"
172 : *
173 : * The "*" long name is viewed as the \em accept \em all option. This
174 : * means all the options may not be defined in the list of options but
175 : * we still want to accept them. This is to allow dynamically defined
176 : * (supported) command options and especially to not have to declare
177 : * all the valid options found in a configuration file.
178 : *
179 : * \li Underscore and Dashes
180 : *
181 : * It is customary to support dashes between words in options appearing
182 : * on the command line (`--help-me`), however, it is unusual in
183 : * configuration files where underscores are used instead (`under_score`.)
184 : * When we compare option names, `'-' == '_'` is always considered true
185 : * so either dashes or underscore can be used in both cases.
186 : *
187 : * For this reason, the long name is saved with only dashes. That
188 : * means all the maps are indexed using the long name with dashes.
189 : *
190 : * \exception getopt_exception_logic
191 : * The constructor raises the invalid exception if the long name is an
192 : * empty string since this is not allowed. It will also raise that
193 : * exception if the name is the default option ("--") and a short name
194 : * is also defined. (i.e. no short name is allowed along the default
195 : * option.)
196 : *
197 : * \param[in] name The (long) name of this option.
198 : * \param[in] short_name The short name of this option (one character.)
199 : */
200 1140 : option_info::option_info(std::string const & name, short_name_t short_name)
201 : : f_name(boost::replace_all_copy(name, "_", "-"))
202 1148 : , f_short_name(short_name)
203 : {
204 1140 : if(f_name.empty())
205 : {
206 4 : if(short_name != NO_SHORT_NAME)
207 : {
208 : throw getopt_logic_error(
209 : "option_info::option_info(): all options must at least have a long name (short name: '"
210 4 : + libutf8::to_u8string(short_name)
211 6 : + "'.)");
212 : }
213 : throw getopt_logic_error(
214 2 : "option_info::option_info(): all options must at least have a long name.");
215 : }
216 :
217 1136 : if(f_name == "--")
218 : {
219 16 : if(short_name != NO_SHORT_NAME)
220 : {
221 : throw getopt_logic_error(
222 : "option_info::option_info(): the default parameter \"--\" cannot include a short name ('"
223 4 : + libutf8::to_u8string(short_name)
224 6 : + "'.)");
225 : }
226 :
227 14 : add_flag(GETOPT_FLAG_DEFAULT_OPTION);
228 : }
229 : else
230 : {
231 1120 : if(f_name[0] == '-')
232 : {
233 : throw getopt_logic_error(
234 : "option_info::option_info(): an option cannot start with a dash (-), \""
235 2 : + f_name
236 3 : + "\" is not valid.");
237 : }
238 :
239 1119 : if(short_name == '-')
240 : {
241 : throw getopt_logic_error(
242 1 : "option_info::option_info(): the short name of an option cannot be the dash (-).");
243 : }
244 : }
245 1132 : }
246 :
247 :
248 : /** \brief Get the long name of the option.
249 : *
250 : * This option retrieves the long name of the option.
251 : *
252 : * \note
253 : * Remember that the underscores in long names are converted to dashes.
254 : * This is because it makes more sense to look for command line parameters
255 : * with dashes. This function will return the name with only dashes.
256 : *
257 : * \note
258 : * The name is always defined. The creation of an option_info object
259 : * fails if the name is empty.
260 : *
261 : * \return The long name with dashes instead of underscores.
262 : */
263 1187 : std::string const & option_info::get_name() const
264 : {
265 1187 : return f_name;
266 : }
267 :
268 :
269 : /** \brief Assign a short name to an option.
270 : *
271 : * This function is used to assign a short name to an option.
272 : *
273 : * \warning
274 : * If you want this function to function as expected (i.e. for the option
275 : * to later be found using its short name), make sure to call the
276 : * set_short_name() on your getopt object and not directly this function.
277 : * This is because the getopt object needs to add the newly named option
278 : * to its map of options sorted by short name.
279 : *
280 : * \exception getopt_exception_logic
281 : * Calling this function with an option which already has a short name
282 : * results in a logic exception. Also, \p short_name cannot be
283 : * NO_SHORT_NAME.
284 : *
285 : * \param[in] short_name The short name to assign to this option.
286 : */
287 5 : void option_info::set_short_name(short_name_t short_name)
288 : {
289 5 : if(short_name == NO_SHORT_NAME)
290 : {
291 : throw getopt_logic_error("The short name of option \""
292 2 : + f_name
293 3 : + "\" cannot be set to NO_SHORT_NAME.");
294 : }
295 :
296 4 : if(f_short_name != NO_SHORT_NAME)
297 : {
298 : throw getopt_logic_error("The short name of option \""
299 2 : + f_name
300 2 : + "\" cannot be changed from '"
301 4 : + short_name_to_string(f_short_name)
302 2 : + "' to '"
303 4 : + short_name_to_string(short_name)
304 3 : + "'.");
305 : }
306 :
307 3 : f_short_name = short_name;
308 3 : }
309 :
310 :
311 : /** \brief Get the short name of the option.
312 : *
313 : * This function returns the \p short_name of this option.
314 : *
315 : * The short name is a Unicode character (UTF-32).
316 : *
317 : * \return The short name character.
318 : */
319 206 : short_name_t option_info::get_short_name() const
320 : {
321 206 : return f_short_name;
322 : }
323 :
324 :
325 : /** \brief Retrieve the name of the option without any section names.
326 : *
327 : * The name of an option can include section names. These
328 : * are rarely used on the command line, but they are useful for
329 : * configuration files if you want to create multiple layers of
330 : * options (a.k.a. sections.)
331 : *
332 : * This function removes all the section names from the option name
333 : * and returns what's left.
334 : *
335 : * \return The base name without any section names.
336 : */
337 4 : std::string option_info::get_basename() const
338 : {
339 4 : std::string::size_type const pos(f_name.rfind("::"));
340 4 : if(pos == std::string::npos)
341 : {
342 1 : return f_name;
343 : }
344 :
345 3 : return f_name.substr(pos + 2);
346 : }
347 :
348 :
349 : /** \brief Retrieve the name of the sections.
350 : *
351 : * The name of an option can include section names. These
352 : * are rarely used on the command line, but they are useful for
353 : * configuration files if you want to create multiple layers of
354 : * options (a.k.a. sections.)
355 : *
356 : * This function returns all the section names found in this option
357 : * name. The last scope operator gets removed too.
358 : *
359 : * If the name does not include any sections, then this function returns
360 : * an empty string.
361 : *
362 : * \return The section names without the basename.
363 : */
364 4 : std::string option_info::get_section_name() const
365 : {
366 4 : std::string::size_type const pos(f_name.rfind("::"));
367 4 : if(pos == std::string::npos)
368 : {
369 1 : return std::string();
370 : }
371 :
372 3 : return f_name.substr(0, pos);
373 : }
374 :
375 :
376 : /** \brief Retrieve a list of section names.
377 : *
378 : * The name of an option can include section names. These
379 : * are rarely used on the command line, but they are useful for
380 : * configuration files if you want to create multiple layers of
381 : * options (a.k.a. sections.)
382 : *
383 : * This function returns a string_list_t of the section names found in
384 : * this option name.
385 : *
386 : * If the name does not include any sections, then this function returns
387 : * an empty list.
388 : *
389 : * \return The list of section name.
390 : */
391 4 : string_list_t option_info::get_section_name_list() const
392 : {
393 4 : std::string::size_type const pos(f_name.rfind("::"));
394 4 : if(pos == std::string::npos)
395 : {
396 1 : return string_list_t();
397 : }
398 :
399 6 : string_list_t section_list;
400 9 : snap::tokenize_string(section_list
401 6 : , f_name.substr(0, pos)
402 : , "::"
403 : , true
404 6 : , std::string()
405 : , &snap::string_predicate<string_list_t>);
406 3 : return section_list;
407 : }
408 :
409 :
410 : /** \brief Check whether this is the default option.
411 : *
412 : * This function checks whether this option represents the default option.
413 : * The default option is where non-options, generally filenames, are added
414 : * when not following an argument.
415 : *
416 : * The name of the default option is always "--". However, it is not
417 : * required. When no default option is defined, filenames can't be
418 : * specified and when such are found on the command line, an error
419 : * ensues.
420 : *
421 : * \return true if the name of the option is "--".
422 : */
423 1360 : bool option_info::is_default_option() const
424 : {
425 1360 : return has_flag(GETOPT_FLAG_DEFAULT_OPTION)
426 1360 : || (f_name.size() == 2 && f_name[0] == '-' && f_name[1] == '-');
427 : }
428 :
429 :
430 : /** \brief Get the flags.
431 : *
432 : * The options have flags determining various sub-options available
433 : * to them. Right now we have flags to tell how each option can be
434 : * used (on the command line, in an environment variable, or in
435 : * a configuration file.)
436 : *
437 : * \note
438 : * We have the GETOPT_FLAG_ALIAS flag which is used to define
439 : * an alias. That means values do not get set in an option which
440 : * is marked as an alias. Instead, they get set in the option
441 : * which is being aliased. This means your software does not have
442 : * to check both options. The setup function will actually call
443 : * the set_alias() function at some point to finalize aliases
444 : * so you do not really need the flag, except to know that no
445 : * value will be defined here because it will instead be saved
446 : * in the aliased option.
447 : *
448 : * \param[in] flags The new flags.
449 : */
450 66 : void option_info::set_flags(flag_t flags)
451 : {
452 66 : f_flags = flags;
453 66 : }
454 :
455 :
456 : /** \brief Make sure a given flag is set.
457 : *
458 : * This function adds the given flag from the set of flags being set.
459 : *
460 : * \param[in] flag The flag(s) to set.
461 : */
462 1234 : void option_info::add_flag(flag_t flag)
463 : {
464 1234 : f_flags |= flag;
465 1234 : }
466 :
467 :
468 : /** \brief Make sure a given flag is not set.
469 : *
470 : * This function removes the given flag from the set of flags being set.
471 : *
472 : * \param[in] flag The flag(s) to clear.
473 : */
474 46 : void option_info::remove_flag(flag_t flag)
475 : {
476 46 : f_flags &= ~flag;
477 46 : }
478 :
479 :
480 : /** \brief Retrieve the flags.
481 : *
482 : * This function retrieves all the flags defined in this option.
483 : *
484 : * To just check whether a flag is set or not, use the has_flag()
485 : * function instead.
486 : *
487 : * \return This option flags.
488 : */
489 1161 : flag_t option_info::get_flags() const
490 : {
491 1161 : return f_flags;
492 : }
493 :
494 :
495 : /** \brief Check whether a flag is set.
496 : *
497 : * This function is used to check whether a flag is set or not.
498 : *
499 : * \note
500 : * The \p flag parameter can be set to more than one flag in which case
501 : * the function returns true if any one of those flags is set.
502 : *
503 : * \return true if the flag is set, false otherwise.
504 : */
505 15809 : bool option_info::has_flag(flag_t flag) const
506 : {
507 15809 : return (f_flags & flag) != 0;
508 : }
509 :
510 :
511 : /** \brief Check whether this option has a default value.
512 : *
513 : * Whenever an option is given a default value, the GETOPT_FLAG_HAS_DEFAULT
514 : * flag gets set. This allows us to distinguish between an option with a
515 : * default which is the empty string and an option without a default.
516 : *
517 : * The set_default() forces the flag to be set.
518 : *
519 : * The remove_default() clears the flag.
520 : *
521 : * \return true if the flag is set, false otherwise.
522 : *
523 : * \sa set_default()
524 : * \sa remove_default()
525 : */
526 296 : bool option_info::has_default() const
527 : {
528 296 : return has_flag(GETOPT_FLAG_HAS_DEFAULT);
529 : }
530 :
531 :
532 : /** \brief Set the default value.
533 : *
534 : * This function sets the default value for this option.
535 : *
536 : * The default value is always defined as a string, but it can later be
537 : * converted to a different type using the option validator.
538 : *
539 : * Often, though, the default value is not compatible with the validator.
540 : * For example, you may have a parameter which is set to a percentage
541 : * from -100% to +100% and the default may be the string "off".
542 : *
543 : * \note
544 : * After calling this function, the option is viewed as having a default
545 : * even if that's the empty string.
546 : *
547 : * \param[in] default_value The new default value for this option.
548 : *
549 : * \sa remove_default()
550 : */
551 105 : void option_info::set_default(std::string const & default_value)
552 : {
553 105 : f_default_value = default_value;
554 105 : add_flag(GETOPT_FLAG_HAS_DEFAULT);
555 105 : }
556 :
557 :
558 : /** \brief Set the default value of this option.
559 : *
560 : * This function is an overload which allows us to call set_default()
561 : * with a nullptr.
562 : *
563 : * \param[in] default_value The new default value for this option.
564 : *
565 : * \sa remove_default()
566 : */
567 1016 : void option_info::set_default(char const * default_value)
568 : {
569 1016 : if(default_value != nullptr)
570 : {
571 91 : set_default(std::string(default_value));
572 : }
573 1016 : }
574 :
575 :
576 : /** \brief Remove the default value.
577 : *
578 : * Call this function remove the default value. The default string gets
579 : * cleared and the GETOPT_FLAG_NO_DEFAULT flag gets set.
580 : *
581 : * \sa set_default()
582 : */
583 4 : void option_info::remove_default()
584 : {
585 4 : f_default_value.clear();
586 4 : remove_flag(GETOPT_FLAG_HAS_DEFAULT);
587 4 : }
588 :
589 :
590 : /** \brief Retrieve the default value.
591 : *
592 : * This function returns the default value.
593 : *
594 : * \return The default string value.
595 : */
596 687 : std::string const & option_info::get_default() const
597 : {
598 687 : return f_default_value;
599 : }
600 :
601 :
602 : /** \brief Set the help string for this option.
603 : *
604 : * The usage() function prints this string whenever the command
605 : * line includes the help command line option (such as `-h` or
606 : * `--help`.)
607 : *
608 : * The string can include various flags such as `%p` to include
609 : * dynamically defined parameters. See the process_help_string()
610 : * function for additional details about these parameters.
611 : *
612 : * \note
613 : * When using a special flag (i.e. GETOPT_FLAG_HELP), the help value
614 : * string is used as the value used by that special feature:
615 : *
616 : * \li GETOPT_FLAG_HELP
617 : *
618 : * It represents a string to print out by the usage() function. The option
619 : * purpose is solaly for adding a string of help in the output.
620 : *
621 : * \li GETOPT_FLAG_EXTERNAL_OPTIONS
622 : *
623 : * It represents the filename to read additional advgetopt options. In
624 : * some cases, your static array of option structures is to define this
625 : * special flag.
626 : *
627 : * \li GETOPT_FLAG_LICENSE
628 : *
629 : * It represents the program license.
630 : *
631 : * \li GETOPT_FLAG_COPYRIGHT
632 : *
633 : * It represents the program copyright notice.
634 : *
635 : * \param[in] help The help string for this option.
636 : */
637 1041 : void option_info::set_help(std::string const & help)
638 : {
639 1041 : f_help = help;
640 1041 : }
641 :
642 :
643 : /** \brief Set the help string for this option.
644 : *
645 : * This function is an overload which allows us to call set_help() with
646 : * a nullptr and not crash. We just ignore the call when that happens.
647 : *
648 : * \param[in] help The help string for this option or nullptr.
649 : */
650 1022 : void option_info::set_help(char const * help)
651 : {
652 1022 : if(help != nullptr)
653 : {
654 1014 : set_help(std::string(help));
655 : }
656 1022 : }
657 :
658 :
659 : /** \brief Get the help string.
660 : *
661 : * This function returns the help string for this command line option.
662 : *
663 : * \warning
664 : * Note that when a special flag is set, this string may represent something
665 : * else that a help string.
666 : *
667 : * \return The help string of this argument.
668 : */
669 290 : std::string const & option_info::get_help() const
670 : {
671 290 : return f_help;
672 : }
673 :
674 :
675 : /** \brief Set the validator for this option.
676 : *
677 : * This function parses the specified name and optional parameters and
678 : * create a corresponding validator for this option.
679 : *
680 : * The \p name_and_params string can be defined as one of:
681 : *
682 : * \code
683 : * <validator-name>
684 : * <validator-name>()
685 : * <validator-name>(<param1>)
686 : * <validator-name>(<param1>, <param2>, ...)
687 : * \endcode
688 : *
689 : * The list of parameters is optional. There may be no, just one,
690 : * or any number of parameters. How the parameters are parsed is left
691 : * to the validator to decide.
692 : *
693 : * If the input string is empty, the current validator, if one is
694 : * installed, gets removed.
695 : *
696 : * \note
697 : * If the option_info already has a set of values, they get validated
698 : * against the new validator. Any value which does not validate gets
699 : * removed at once. The validation process also generates an error
700 : * when an invalid error is found. Note that it is expected that you
701 : * will setup a validator before you start parsing data so this feature
702 : * should seldom be used.
703 : *
704 : * \param[in] name_and_params The validator name and parameters.
705 : *
706 : * \return true if the validator was installed and all existing values were
707 : * considered valid.
708 : */
709 28 : bool option_info::set_validator(std::string const & name_and_params)
710 : {
711 28 : f_validator = validator::create(name_and_params);
712 :
713 : // make sure that all existing values validate against this
714 : // new validator
715 : //
716 26 : return validate_all_values();
717 : }
718 :
719 :
720 : /** \brief Set the validator for this option.
721 : *
722 : * Options may be assigned a validator. Without a validator, any value
723 : * is considered valid.
724 : *
725 : * A value is checked when you call the validates() function. The function
726 : * returns true if the value is considered valid. False in all other cases.
727 : *
728 : * You can define your own validators and add them to the library list of
729 : * available validators before using the library in order to get your
730 : * options to use said validators.
731 : *
732 : * \note
733 : * If the option_info already has a set of values, they get validated
734 : * against the new validator. Any value which does not validate gets
735 : * removed at once. The validation process also generates an error
736 : * when an invalid error is found. Note that it is expected that you
737 : * will setup a validator before you start parsing data so this feature
738 : * should seldom be used.
739 : *
740 : * \param[in] validator A pointer to a validator.
741 : *
742 : * \return true if the validator was installed and all existing values were
743 : * considered valid.
744 : */
745 2 : bool option_info::set_validator(validator::pointer_t validator)
746 : {
747 2 : f_validator = validator;
748 :
749 : // make sure that all existing values validate against this
750 : // new validator
751 : //
752 2 : return validate_all_values();
753 : }
754 :
755 :
756 : /** \brief Clear the validator.
757 : *
758 : * This function removes the existing validator by resetting the pointer
759 : * back to nullptr.
760 : *
761 : * \param[in] null_ptr Ignored.
762 : *
763 : * \return Always true since no validator means any existing values would
764 : * be considered valid.
765 : */
766 5 : bool option_info::set_validator(std::nullptr_t null_ptr)
767 : {
768 5 : snap::NOTUSED(null_ptr);
769 :
770 5 : f_validator.reset();
771 :
772 5 : return true;
773 : }
774 :
775 :
776 : /** \brief Check a value validity.
777 : *
778 : * This function us used internally to verify values that get added at
779 : * the time they get added. It runs the validator::validate() function
780 : * and returns true if the value is considered valid. When the value
781 : * does not validate, it returns false and removes the value from the
782 : * f_value vector. This means no invalid values are ever kept in an
783 : * option_info object.
784 : *
785 : * An option without a validator has values that are always valid.
786 : * Also, an empty value is always considered valid.
787 : *
788 : * \note
789 : * This function is private since there is no need for the user of
790 : * the option_info to ever call it (i.e. it automatically gets called
791 : * any time a value gets added to the f_value vector.)
792 : *
793 : * \param[in] idx The value to check.
794 : *
795 : * \return true if the value is considered valid, false otherwise.
796 : */
797 606 : bool option_info::validates(int idx)
798 : {
799 606 : if(static_cast<size_t>(idx) >= f_value.size())
800 : {
801 : throw getopt_undefined( // LCOV_EXCL_LINE
802 : "option_info::get_value(): no value at index " // LCOV_EXCL_LINE
803 : + std::to_string(idx) // LCOV_EXCL_LINE
804 : + " (idx >= " // LCOV_EXCL_LINE
805 : + std::to_string(f_value.size()) // LCOV_EXCL_LINE
806 : + ") for --" // LCOV_EXCL_LINE
807 : + f_name // LCOV_EXCL_LINE
808 : + " so you can't get this value."); // LCOV_EXCL_LINE
809 : }
810 :
811 : // the value is considered valid when:
812 : // * there is no validator
813 : // * if the value is empty
814 : // * when the value validate against the specified validator
815 : //
816 1212 : if(f_validator == nullptr
817 71 : || f_value[idx].empty()
818 669 : || f_validator->validate(f_value[idx]))
819 : {
820 588 : return true;
821 : }
822 :
823 36 : cppthread::log << cppthread::log_level_t::error
824 18 : << "input \""
825 18 : << f_value[idx]
826 18 : << "\" given to parameter --"
827 18 : << f_name
828 18 : << " is not considered valid."
829 18 : << cppthread::end;
830 :
831 : // get rid of that value since it does not validate
832 : //
833 18 : f_value.erase(f_value.begin() + idx);
834 :
835 18 : return false;
836 : }
837 :
838 :
839 : /** \brief Retrieve a pointer to the validator.
840 : *
841 : * The validator of an option may be used for additional tasks such as
842 : * converting the value to a specific type (i.e. a string to an
843 : * integer, for example.)
844 : *
845 : * This function allows you to retrieve the validator to be able to
846 : * make use of those functions. You will have to use
847 : * std::dynamic_cast_pointer<>() to change the type of validator to
848 : * the specialized validator of this option. If that returns a null
849 : * pointer, then the option is not using that type of validator.
850 : *
851 : * \todo
852 : * Add a template function that does the cast for the caller.
853 : *
854 : * \return A pointer to this option validator.
855 : */
856 19 : validator::pointer_t option_info::get_validator() const
857 : {
858 19 : return f_validator;
859 : }
860 :
861 :
862 : /** \brief Set the alias option.
863 : *
864 : * After loading all the options, we run the link_aliases() function which
865 : * makes sure that all the options that are marked as an alias are
866 : * properly linked.
867 : *
868 : * \param[in] alias The final destination of this option.
869 : */
870 20 : void option_info::set_alias_destination(option_info::pointer_t destination)
871 : {
872 20 : if(destination->has_flag(GETOPT_FLAG_ALIAS))
873 : {
874 : throw getopt_invalid(
875 : "option_info::set_alias(): you can't set an alias as"
876 1 : " an alias of another option.");
877 : }
878 :
879 19 : f_alias_destination = destination;
880 19 : }
881 :
882 :
883 : /** \brief Get a link to the destination alias.
884 : *
885 : * This function returns a pointer to the aliased option.
886 : *
887 : * \return The alias or a nullptr.
888 : */
889 95 : option_info::pointer_t option_info::get_alias_destination() const
890 : {
891 95 : return f_alias_destination;
892 : }
893 :
894 :
895 : /** \brief Set the list of separators.
896 : *
897 : * Options marked with the GETOPT_FLAG_CONFIGURATION_MULTIPLE flag
898 : * get their value cut by separators when such is found in an
899 : * environment variable or a configuration file.
900 : *
901 : * This function saves the list of separators in a vector.
902 : *
903 : * \param[in] separators The list of separators to be used for this argument.
904 : */
905 1017 : void option_info::set_multiple_separators(char const * const * separators)
906 : {
907 1017 : f_multiple_separators.clear();
908 1017 : if(separators == nullptr)
909 : {
910 998 : return;
911 : }
912 :
913 73 : for(; *separators != nullptr; ++separators)
914 : {
915 27 : f_multiple_separators.push_back(*separators);
916 : }
917 : }
918 :
919 :
920 : /** \brief Set the list of separators.
921 : *
922 : * Options marked with the GETOPT_FLAG_CONFIGURATION_MULTIPLE flag
923 : * get their value cut by separators when such is found in an
924 : * environment variable or a configuration file.
925 : *
926 : * This function saves the specified list of separators.
927 : *
928 : * \param[in] separators The list of separators to be used for this argument.
929 : */
930 7 : void option_info::set_multiple_separators(string_list_t const & separators)
931 : {
932 7 : f_multiple_separators = separators;
933 7 : }
934 :
935 :
936 : /** \brief Retrieve the list of separators for this argument.
937 : *
938 : * This function returns a reference to the list of separators of this
939 : * option. It is expected to be used when a value is found in a
940 : * configuration file or a command line in an environment variable.
941 : * Parameters on the command line are already broken down by the
942 : * shell and we do not do any further manipulation with those.
943 : *
944 : * \return A reference to the list of separators used to cut multiple
945 : * arguments found in a configuration file or an environment
946 : * variable.
947 : */
948 9 : string_list_t const & option_info::get_multiple_separators() const
949 : {
950 9 : return f_multiple_separators;
951 : }
952 :
953 :
954 : /** \brief Check whether one of the values matches the input.
955 : *
956 : * This function searches the set of existing values in this option_info
957 : * and if found returns true.
958 : *
959 : * \note
960 : * It is possible to add the same value multiple times. However, there are
961 : * cases where you may not want to have the same value more than once.
962 : * This function can be used to try to not do that.
963 : *
964 : * \param[in] value The value to search in this option.
965 : *
966 : * \return true if the value is already defined in this option_info.
967 : *
968 : * \sa set_value()
969 : */
970 9 : bool option_info::has_value(std::string const & value) const
971 : {
972 9 : auto const it(std::find(f_value.begin(), f_value.end(), value));
973 9 : return it != f_value.end();
974 : }
975 :
976 :
977 : /** \brief Add a value to this option.
978 : *
979 : * Whenever an option is found it may be followed by one or more values.
980 : * This function is used to add these values to this option.
981 : *
982 : * Later you can use the size() function to know how many values were
983 : * added and the get_value() to retrieve any one of these values.
984 : *
985 : * \warning
986 : * This function sets the value at offset 0 if it is already defined and
987 : * the GETOPT_FLAG_MULTIPLE flag is not set in this option. In other words,
988 : * you can't use this function to add multiple values if this option does
989 : * not support that feature.
990 : *
991 : * \param[in] value The value to add to this option.
992 : *
993 : * \return true when the value was accepted (no error occurred).
994 : *
995 : * \sa set_value()
996 : */
997 434 : bool option_info::add_value(std::string const & value)
998 : {
999 552 : return set_value(has_flag(GETOPT_FLAG_MULTIPLE)
1000 118 : ? f_value.size()
1001 : : 0
1002 434 : , value);
1003 : }
1004 :
1005 :
1006 : /** \brief Replace a value.
1007 : *
1008 : * This function is generally used to replace an existing value. If the
1009 : * index is set to the size of the existing set of values, then a new
1010 : * value is saved in the vector.
1011 : *
1012 : * This is particularly useful if you want to edit a configuration file.
1013 : *
1014 : * If the option comes with a validator, then the value gets checked
1015 : * against that validator. If that results in an error, the value is
1016 : * not added to the vector so an invalid value will never be returned
1017 : * by the option_info class.
1018 : *
1019 : * The value does not get added when it currently is locked or when
1020 : * it does not validate as per the validator of this option_info.
1021 : *
1022 : * \exception getopt_exception_undefined
1023 : * If the index is out of range (too large or negative), then this
1024 : * exception is raised.
1025 : *
1026 : * \param[in] idx The position of the value to update.
1027 : * \param[in] value The new value.
1028 : *
1029 : * \return true if the set_value() added the value.
1030 : *
1031 : * \sa add_value()
1032 : * \sa validates()
1033 : * \sa lock()
1034 : * \sa unlock()
1035 : */
1036 600 : bool option_info::set_value(int idx, std::string const & value)
1037 : {
1038 600 : if(has_flag(GETOPT_FLAG_LOCK))
1039 : {
1040 8 : return false;
1041 : }
1042 :
1043 592 : if(has_flag(GETOPT_FLAG_MULTIPLE))
1044 : {
1045 134 : if(static_cast<size_t>(idx) > f_value.size())
1046 : {
1047 : throw getopt_logic_error(
1048 : "option_info::set_value(): no value at index "
1049 4 : + std::to_string(idx)
1050 4 : + " and it is not the last available index + 1 (idx > "
1051 8 : + std::to_string(f_value.size())
1052 6 : + ") so you can't set this value (try add_value() maybe?).");
1053 : }
1054 : }
1055 : else
1056 : {
1057 458 : if(idx != 0)
1058 : {
1059 : throw getopt_logic_error(
1060 : "option_info::set_value(): single value option \"--"
1061 4 : + f_name
1062 4 : + "\" does not accepts index "
1063 8 : + std::to_string(idx)
1064 6 : + " which is not 0.");
1065 : }
1066 : }
1067 :
1068 588 : if(static_cast<size_t>(idx) == f_value.size())
1069 : {
1070 468 : f_value.push_back(value);
1071 : }
1072 : else
1073 : {
1074 120 : f_value[idx] = value;
1075 : }
1076 588 : f_integer.clear();
1077 :
1078 588 : return validates(idx);
1079 : }
1080 :
1081 :
1082 : /** \brief Set a multi-value at once.
1083 : *
1084 : * This function views the \p value parameter as a multi-value parameter
1085 : * which it breaks down in multiple parameters and add the results to this
1086 : * option_info object as the current value(s).
1087 : *
1088 : * To separate the values, the function makes use of the separators as
1089 : * set by one the set_multiple_separators() functions.
1090 : *
1091 : * The resulting values must not be the empty string. Empty strings are
1092 : * ignored. So if the separator is a comma and you write:
1093 : *
1094 : * \code
1095 : * foo,,,bar
1096 : * \endcode
1097 : *
1098 : * The result includes "foo" and "bar" and no empty strings.
1099 : *
1100 : * \note
1101 : * The function has the side effect of clearing any existing parameters
1102 : * first. So only the newly defined parameters in \p value will be set
1103 : * in the option once the function returns.
1104 : *
1105 : * \todo
1106 : * Add support for quoted values
1107 : *
1108 : * \param[in] value The multi-value to save in this option.
1109 : *
1110 : * \return true if all the values in \p value were considered valid.
1111 : *
1112 : * \sa add_value()
1113 : * \sa set_value()
1114 : */
1115 25 : bool option_info::set_multiple_value(std::string const & value)
1116 : {
1117 25 : f_value.clear();
1118 25 : f_integer.clear();
1119 :
1120 25 : split_string(unquote(value, "[]"), f_value, f_multiple_separators);
1121 :
1122 50 : if(!has_flag(GETOPT_FLAG_MULTIPLE)
1123 25 : && f_value.size() > 1)
1124 : {
1125 1 : f_value.clear();
1126 : throw getopt_logic_error(
1127 : "option_info::set_multiple_value(): parameter --"
1128 2 : + f_name
1129 3 : + " expects zero or one parameter. The set_multiple_value() function should not be called with parameters that only accept one value.");
1130 : }
1131 :
1132 24 : return validate_all_values();
1133 : }
1134 :
1135 :
1136 : /** \brief Validate all the values of this option_info object.
1137 : *
1138 : * Whenever you change the validator of an option_info, or change
1139 : * all the values with set_multiple_value(), all the values get
1140 : * verified using this function. The function removes any value
1141 : * which does not validate according to the current validator.
1142 : *
1143 : * \note
1144 : * Keep in mind that an empty value is always considered valid,
1145 : * no matter what the validator is. This is because when you
1146 : * use an option without a value (i.e. `--order` instead of
1147 : * `--order asc`) the value is set to the empty string unless
1148 : * there is a default. This allows you to know that the
1149 : * option was used without a value, which is useful for some
1150 : * options.
1151 : *
1152 : * \return true if all the values were considered valid.
1153 : */
1154 52 : bool option_info::validate_all_values()
1155 : {
1156 52 : bool all_valid(true);
1157 52 : if(f_validator != nullptr)
1158 : {
1159 35 : for(size_t idx(0); idx < f_value.size(); )
1160 : {
1161 18 : if(!validates(idx))
1162 : {
1163 : // the value was removed, so do not increment `idx`
1164 : //
1165 9 : all_valid = false;
1166 : }
1167 : else
1168 : {
1169 9 : ++idx;
1170 : }
1171 : }
1172 : }
1173 :
1174 52 : return all_valid;
1175 : }
1176 :
1177 :
1178 : /** \brief Check whether a value is defined.
1179 : *
1180 : * When parsing the options on the command line or a configuration file,
1181 : * values get added to the various existing option_info. If a special
1182 : * "*" option is also defined, then any value found on the command line
1183 : * or the configuration file are returned.
1184 : *
1185 : * To know whether this or that option was defined with a value, use
1186 : * this function. Even an option which doesn't come with a parameter
1187 : * will get an is_defined() returning true once it was found on the
1188 : * command line. The value will be the empty string.
1189 : *
1190 : * \return true if that option was found on the command line, in the
1191 : * environment variable, or in the configuration file.
1192 : */
1193 2085 : bool option_info::is_defined() const
1194 : {
1195 2085 : return !f_value.empty();
1196 : }
1197 :
1198 :
1199 : /** \brief Retrieve the number of values defined for this option.
1200 : *
1201 : * This function returns the number of values that were found for this
1202 : * option.
1203 : *
1204 : * If the option is marked as GETOPT_FLAG_MULTIPLE, then this function
1205 : * may return 0 or more. Without that flag, this function only returns
1206 : * 0 or 1.
1207 : *
1208 : * You must use the size() parameter to know how many items are defined
1209 : * and call the get_value() with a correct `idx` parameter (i.e. a value
1210 : * between 0 and `size() - 1`.)
1211 : *
1212 : * \return The number of values defined in this option.
1213 : */
1214 500 : size_t option_info::size() const
1215 : {
1216 500 : return f_value.size();
1217 : }
1218 :
1219 :
1220 : /** \brief Retrieve the value.
1221 : *
1222 : * This function returns the value for this option. By default, set the
1223 : * \p idx parameter to zero.
1224 : *
1225 : * The number of values is defined by the size() function.
1226 : *
1227 : * The is_defined() function returns true if at least one value is defined.
1228 : * It is a good idea to check first otherwise you will get an exception.
1229 : *
1230 : * \exception getopt_exception_undefined
1231 : * If the \p idx parameter is too large or no value was found for this
1232 : * option, then this function raises an invalid error.
1233 : *
1234 : * \return The value.
1235 : */
1236 1117 : std::string const & option_info::get_value(int idx) const
1237 : {
1238 1117 : if(static_cast<size_t>(idx) >= f_value.size())
1239 : {
1240 : throw getopt_undefined(
1241 : "option_info::get_value(): no value at index "
1242 4 : + std::to_string(idx)
1243 4 : + " (idx >= "
1244 8 : + std::to_string(f_value.size())
1245 4 : + ") for --"
1246 6 : + f_name
1247 6 : + " so you can't get this value.");
1248 : }
1249 :
1250 1115 : return f_value[idx];
1251 : }
1252 :
1253 :
1254 : /** \brief Get the value as a long.
1255 : *
1256 : * This function returns the value converted to a `long`.
1257 : *
1258 : * If the value does not represent a valid long value, an error is
1259 : * emitted through the logger.
1260 : *
1261 : * \note
1262 : * The function will transform all the values in case this is a
1263 : * GETOPT_FLAG_CONFIGURATION_MULTIPLE option and cache the results.
1264 : * Calling the function many times with the same index is very fast
1265 : * after the first time.
1266 : *
1267 : * \exception getopt_exception_undefined
1268 : * If the value was not defined, the function raises this exception.
1269 : *
1270 : * \param[in] idx The index of the value to retrieve as a long.
1271 : *
1272 : * \return The value at \p idx converted to a long or -1 on error.
1273 : */
1274 153 : long option_info::get_long(int idx) const
1275 : {
1276 153 : if(static_cast<size_t>(idx) >= f_value.size())
1277 : {
1278 : throw getopt_undefined(
1279 : "option_info::get_long(): no value at index "
1280 2 : + std::to_string(idx)
1281 2 : + " (idx >= "
1282 4 : + std::to_string(f_value.size())
1283 2 : + ") for --"
1284 3 : + f_name
1285 3 : + " so you can't get this value.");
1286 : }
1287 :
1288 : // since we may change the f_integer vector between threads,
1289 : // add protection (i.e. most everything else is created at the
1290 : // beginning so in the main thread)
1291 : //
1292 304 : cppthread::guard lock(get_global_mutex());
1293 :
1294 152 : if(f_integer.size() != f_value.size())
1295 : {
1296 : // we did not yet convert to integers do that now
1297 : //
1298 86 : size_t const max(f_value.size());
1299 176 : for(size_t i(f_integer.size()); i < max; ++i)
1300 : {
1301 : std::int64_t v;
1302 100 : if(!validator_integer::convert_string(f_value[i], v))
1303 : {
1304 10 : f_integer.clear();
1305 :
1306 20 : cppthread::log << cppthread::log_level_t::error
1307 10 : << "invalid number ("
1308 10 : << f_value[i]
1309 10 : << ") in parameter --"
1310 10 : << f_name
1311 10 : << " at offset "
1312 10 : << i
1313 10 : << "."
1314 10 : << cppthread::end;
1315 10 : return -1;
1316 : }
1317 90 : f_integer.push_back(v);
1318 : }
1319 : }
1320 :
1321 142 : return f_integer[idx];
1322 : }
1323 :
1324 :
1325 : /** \brief Lock this value.
1326 : *
1327 : * This function allows for locking a value so further reading of data
1328 : * will not overwrite it.
1329 : *
1330 : * When parsing the data we have multiple levels. Here are these levels
1331 : * in priority order (first option found is the one we keep):
1332 : *
1333 : * \li Command line options
1334 : * \li Environment Variables
1335 : * \li Configuration File: Local (`./\<name>.conf`)
1336 : * \li Configuration File: User's (`~/.config/\<proc>/\<name>.conf`)
1337 : * \li Configuration File: Project sub-folder (`/etc/\<proc>/\<proc>.d/\<ohter-name>.conf`)
1338 : * \li Configuration File: Project folder (`/etc/\<proc>/\<other-name>.conf`)
1339 : * \li Configuration File: System sub-folder (`/etc/\<proc>/\<name>.conf`)
1340 : * \li Configuration File: System folder (`/etc/\<proc>/\<name>.conf`)
1341 : *
1342 : * \note
1343 : * Most of our packages do not have a Project and a System set of
1344 : * configuration files. Often they will have just the System files.
1345 : *
1346 : * We use this lock because we want to support multiple values so just
1347 : * detecting that a value is set to not add more options is not a good
1348 : * test. Instead we lock the values that are set before moving to the
1349 : * next level.
1350 : *
1351 : * \param[in] always Always lock that option, whether it is defined or not.
1352 : */
1353 6 : void option_info::lock(bool always)
1354 : {
1355 6 : if(!always)
1356 : {
1357 4 : if(!is_defined())
1358 : {
1359 2 : return;
1360 : }
1361 : }
1362 :
1363 4 : add_flag(GETOPT_FLAG_LOCK);
1364 : }
1365 :
1366 :
1367 : /** \brief Unlock this value.
1368 : *
1369 : * This function does the opposite of the lock() function. It allows for
1370 : * the value to be updated again.
1371 : *
1372 : * Once the getpot object is done parsing all the input, it unlocks all
1373 : * the values using this function. The unlock is always unconditional.
1374 : */
1375 4 : void option_info::unlock()
1376 : {
1377 4 : remove_flag(GETOPT_FLAG_LOCK);
1378 4 : }
1379 :
1380 :
1381 : /** \brief Reset this value.
1382 : *
1383 : * This function clears the value so it is marked as undefined again.
1384 : *
1385 : * To reuse the same getopt object multiple times, you can use the
1386 : * reset() function which clears the values. Then you can parse a
1387 : * new set of argc/argv parameters.
1388 : */
1389 24 : void option_info::reset()
1390 : {
1391 24 : f_value.clear();
1392 24 : f_integer.clear();
1393 24 : }
1394 :
1395 :
1396 :
1397 6 : } // namespace advgetopt
1398 : // vim: ts=4 sw=4 et
|