LCOV - code coverage report
Current view: top level - advgetopt - option_info.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 247 247 100.0 %
Date: 2020-11-13 17:54:34 Functions: 47 47 100.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13