LCOV - code coverage report
Current view: top level - advgetopt - option_info.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 364 393 92.6 %
Date: 2022-05-26 21:41:34 Functions: 62 63 98.4 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13