LCOV - code coverage report
Current view: top level - advgetopt - advgetopt_data.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 209 209 100.0 %
Date: 2022-07-15 17:40:56 Functions: 12 12 100.0 %
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             : /** \file
      21             :  * \brief Advanced getopt data access implementation.
      22             :  *
      23             :  * The advgetopt class has many function used to access the data in the
      24             :  * class. These functions are gathered here.
      25             :  */
      26             : 
      27             : // self
      28             : //
      29             : #include    "advgetopt/advgetopt.h"
      30             : 
      31             : #include    "advgetopt/conf_file.h"
      32             : #include    "advgetopt/exception.h"
      33             : #include    "advgetopt/validator_double.h"
      34             : #include    "advgetopt/validator_integer.h"
      35             : #include    "advgetopt/version.h"
      36             : 
      37             : 
      38             : // cppthread
      39             : //
      40             : #include    <cppthread/log.h>
      41             : 
      42             : 
      43             : // C
      44             : //
      45             : #include    <string.h>
      46             : 
      47             : 
      48             : // last include
      49             : //
      50             : #include    <snapdev/poison.h>
      51             : 
      52             : 
      53             : 
      54             : 
      55             : namespace advgetopt
      56             : {
      57             : 
      58             : 
      59             : 
      60             : 
      61             : 
      62             : /** \brief Check whether a parameter is defined.
      63             :  *
      64             :  * This function returns true if the specified parameter is found as part of
      65             :  * the command line options.
      66             :  *
      67             :  * You must specify the long name of the option. So a `--verbose` option can
      68             :  * be checked with:
      69             :  *
      70             :  * \code
      71             :  *   if(is_defined("verbose")) ...
      72             :  * \endcode
      73             :  *
      74             :  * For options that come with a short name, you may also specify the short
      75             :  * name. This is done with a string in this case. It can be a UTF-8
      76             :  * character. The short name is used if the string represents exactly one
      77             :  * Unicode character. So the following is equivalent to the previous
      78             :  * example, assuming your verbose definition has `v` as the short name:
      79             :  *
      80             :  * \code
      81             :  *   if(is_defined("v")) ...
      82             :  * \endcode
      83             :  *
      84             :  * \note
      85             :  * This function returns true when the option was found on the command line,
      86             :  * the environment variable, or a configuration file. It returns false if
      87             :  * the option is defined, but was not specified anywhere by the client using
      88             :  * your program. Also, specifying the option in one of those three locations
      89             :  * when not allowed at that location will not result in this flag being raised.
      90             :  *
      91             :  * \param[in] name  The long name or short name of the option to check.
      92             :  *
      93             :  * \return true if the option was defined in a configuration file, the
      94             :  *         environment variable, or the command line.
      95             :  */
      96        1431 : bool getopt::is_defined(std::string const & name) const
      97             : {
      98        1431 :     is_parsed();
      99             : 
     100        2854 :     option_info::pointer_t opt(get_option(name));
     101        1427 :     if(opt != nullptr)
     102             :     {
     103        1086 :         return opt->is_defined();
     104             :     }
     105             : 
     106         341 :     return false;
     107             : }
     108             : 
     109             : 
     110             : /** \brief Retrieve the number of arguments.
     111             :  *
     112             :  * This function returns the number of arguments that were specified after
     113             :  * the named option.
     114             :  *
     115             :  * The function returns zero if the argument was never specified on the
     116             :  * command line. If the option accepts exactly one parameter (i.e. not
     117             :  * marked as a multiple arguments option: GETOPT_FLAG_MULTIPLE) then
     118             :  * the function returns either zero (not specified) or one (specified
     119             :  * at least once.)
     120             :  *
     121             :  * \param[in] name  The name of the option to check.
     122             :  *
     123             :  * \return The number of arguments specified on the command line or zero.
     124             :  */
     125         635 : size_t getopt::size(std::string const & name) const
     126             : {
     127         635 :     is_parsed();
     128             : 
     129        1264 :     option_info::pointer_t opt(get_option(name));
     130         632 :     if(opt != nullptr)
     131             :     {
     132         411 :         return opt->size();
     133             :     }
     134         221 :     return 0;
     135             : }
     136             : 
     137             : 
     138             : /** \brief Check whether an option has a default value.
     139             :  *
     140             :  * Some parameters may be given a default. This function is used to
     141             :  * detect whether such a default value is defined.
     142             :  *
     143             :  * \note
     144             :  * This function is particularly useful in the event the default value
     145             :  * may be an empty string.
     146             :  *
     147             :  * \exception getopt_exception_undefined
     148             :  * The getopt_exception_undefined exception is raised if this function is
     149             :  * called with an empty \p name.
     150             :  *
     151             :  * \param[in] name  The name of the parameter of which you want to know
     152             :  *                  whether it has a default value or not.
     153             :  *
     154             :  * \return true if the default value was defined (even if an empty string.)
     155             :  */
     156          86 : bool getopt::has_default(std::string const & name) const
     157             : {
     158         170 :     option_info::pointer_t opt(get_option(name));
     159          84 :     if(opt != nullptr)
     160             :     {
     161          79 :         return opt->has_default();
     162             :     }
     163             : 
     164           5 :     return false;
     165             : }
     166             : 
     167             : 
     168             : /** \brief Get the default value for this option.
     169             :  *
     170             :  * When an option is not defined, you may use this function to retrieve its
     171             :  * default instead. This is actually done automatically when you call the
     172             :  * get_string() or get_long() functions.
     173             :  *
     174             :  * An option without a default has this function returning nullptr.
     175             :  *
     176             :  * \note
     177             :  * Whether an option has a default value should be checked with the
     178             :  * has_default() function which returns true when the default value
     179             :  * was defined. An option with an empty string as the default is
     180             :  * a valid case which cannot be detected otherwise.
     181             :  *
     182             :  * \exception getopt_exception_undefined
     183             :  * The getopt_exception_undefined exception is raised if this function is
     184             :  * called with an empty \p name.
     185             :  *
     186             :  * \param[in] name  The name of the parameter of which you want to retrieve
     187             :  *                  the default value.
     188             :  *
     189             :  * \return The default value or an empty string if no value is defined.
     190             :  */
     191         569 : std::string getopt::get_default(std::string const & name) const
     192             : {
     193        1136 :     option_info::pointer_t opt(get_option(name));
     194         567 :     if(opt != nullptr)
     195             :     {
     196         325 :         return opt->get_default();
     197             :     }
     198             : 
     199         242 :     return std::string();
     200             : }
     201             : 
     202             : 
     203             : /** \brief This function retrieves an argument as a long value.
     204             :  *
     205             :  * This function reads the specified argument from the named option and
     206             :  * transforms it to a long value. It then checks the result against the
     207             :  * specified minimum and maximum range.
     208             :  *
     209             :  * The function name represents an argument that needs to be defined. You
     210             :  * can test whether it was defined on the command line with the is_defined()
     211             :  * function. The index must be between 0 and 'size() - 1' inclusive. If
     212             :  * the item was not defined, then size() returns zero and you cannot call
     213             :  * this function.
     214             :  *
     215             :  * The function does not check the validity of the minimum and maximum
     216             :  * parameters. If \p min \> \p max is true then the function will always
     217             :  * fail with a call to usage() as no value can be defined between \p min
     218             :  * and \p max in that case. The minimum and maximum values are inclusive,
     219             :  * so a range of 1 to 9 is defined with exactly 1 and 9 in min and max.
     220             :  * For example, the z library compression could be retrieved with:
     221             :  *
     222             :  * \code
     223             :  * int level(6); // default to 6
     224             :  * if(opt.is_defined("zlevel"))
     225             :  * {
     226             :  *   zlevel = opt.get_long("zlevel", 0, 1, 9);
     227             :  * }
     228             :  * \endcode
     229             :  *
     230             :  * Note that the function can be used to read unsigned numbers, however
     231             :  * at this point getopt does not really support negative numbers (i.e. because
     232             :  * -\<number> is viewed as an option.)
     233             :  *
     234             :  * \exception getopt_exception_undefined
     235             :  * The getopt_exception_undefined exception is raised if \p name was not
     236             :  * found on the command line and it has no default, or if \p idx is
     237             :  * out of bounds.
     238             :  *
     239             :  * \param[in] name  The name of the option to retrieve.
     240             :  * \param[in] idx  The index of the argument to retrieve.
     241             :  * \param[in] min  The minimum value that will be returned (inclusive).
     242             :  * \param[in] max  The maximum value that will be returned (inclusive).
     243             :  *
     244             :  * \return The argument as a long.
     245             :  */
     246         130 : long getopt::get_long(std::string const & name, int idx, long min, long max) const
     247             : {
     248         130 :     is_parsed();
     249             : 
     250         260 :     option_info::pointer_t opt(get_option(name));
     251         130 :     if(opt == nullptr)
     252             :     {
     253             :         throw getopt_logic_error(
     254             :                   "there is no --"
     255           6 :                 + name
     256           9 :                 + " option defined.");
     257             :     }
     258             : 
     259         127 :     long result(0.0);
     260         127 :     if(!opt->is_defined())
     261             :     {
     262          96 :         std::string const d(opt->get_default());
     263          48 :         if(d.empty())
     264             :         {
     265             :             throw getopt_logic_error(
     266             :                       "the --"
     267          12 :                     + name
     268          18 :                     + " option was not defined on the command line and it has no or an empty default.");
     269             :         }
     270          42 :         if(!validator_integer::convert_string(d, result))
     271             :         {
     272             :             // here we throw because this default value is defined in the
     273             :             // options of the tool and not by the user
     274             :             //
     275             :             throw getopt_logic_error(
     276             :                       "invalid default number \""
     277           6 :                     + d
     278           9 :                     + "\" for option --"
     279           9 :                     + name);
     280             :         }
     281             :     }
     282             :     else
     283             :     {
     284          79 :         result = opt->get_long(idx);
     285             :     }
     286             : 
     287             :     // TODO: replace with validators
     288             :     //
     289         118 :     if(result < min || result > max)
     290             :     {
     291           4 :         cppthread::log << cppthread::log_level_t::error
     292           2 :                        << result
     293           2 :                        << " is out of bounds ("
     294           2 :                        << min
     295           2 :                        << ".."
     296           2 :                        << max
     297           2 :                        << " inclusive) in parameter --"
     298           2 :                        << name
     299           2 :                        << "."
     300           4 :                        << cppthread::end;
     301           2 :         result = -1;
     302             :     }
     303             : 
     304         236 :     return result;
     305             : }
     306             : 
     307             : 
     308             : /** \brief This function retrieves an argument as a double value.
     309             :  *
     310             :  * This function reads the specified argument from the named option and
     311             :  * transforms it to a double value. It then checks the result against the
     312             :  * specified minimum and maximum range.
     313             :  *
     314             :  * The function name represents an argument that needs to be defined. You
     315             :  * can test whether it was defined on the command line with the is_defined()
     316             :  * function. The index must be between 0 and 'size() - 1' inclusive. If
     317             :  * the item was not defined, then size() returns zero and you cannot call
     318             :  * this function.
     319             :  *
     320             :  * The function does not check the validity of the minimum and maximum
     321             :  * parameters. If \p min \> \p max is true then the function will always
     322             :  * fail with a call to usage() as no value can be defined between \p min
     323             :  * and \p max in that case. The minimum and maximum values are inclusive,
     324             :  * so a range of 1 to 9 is defined with exactly 1 and 9 in min and max.
     325             :  * For example, the z library compression could be retrieved with:
     326             :  *
     327             :  * \code
     328             :  * int level(6); // default to 6
     329             :  * if(opt.is_defined("zlevel"))
     330             :  * {
     331             :  *   zlevel = opt.get_double("zlevel", 0, 1.0, 9.0);
     332             :  * }
     333             :  * \endcode
     334             :  *
     335             :  * Note that the function can be used to read unsigned numbers, however
     336             :  * at this point getopt does not really support negative numbers (i.e. because
     337             :  * -\<number> is viewed as an option.)
     338             :  *
     339             :  * \todo
     340             :  * Fix example with a parameter which makes sense (i.e. accepts doubles).
     341             :  *
     342             :  * \exception getopt_exception_undefined
     343             :  * The getopt_exception_undefined exception is raised if \p name was not
     344             :  * found on the command line and it has no default, or if \p idx is
     345             :  * out of bounds.
     346             :  *
     347             :  * \param[in] name  The name of the option to retrieve.
     348             :  * \param[in] idx  The index of the argument to retrieve.
     349             :  * \param[in] min  The minimum value that will be returned (inclusive).
     350             :  * \param[in] max  The maximum value that will be returned (inclusive).
     351             :  *
     352             :  * \return The argument as a long.
     353             :  */
     354          47 : double getopt::get_double(std::string const & name, int idx, double min, double max) const
     355             : {
     356          47 :     is_parsed();
     357             : 
     358          94 :     option_info::pointer_t opt(get_option(name));
     359          47 :     if(opt == nullptr)
     360             :     {
     361             :         throw getopt_logic_error(
     362             :                   "there is no --"
     363           2 :                 + name
     364           3 :                 + " option defined.");
     365             :     }
     366             : 
     367          46 :     double result(0);
     368          46 :     if(!opt->is_defined())
     369             :     {
     370          10 :         std::string const d(opt->get_default());
     371           5 :         if(d.empty())
     372             :         {
     373             :             throw getopt_logic_error(
     374             :                       "the --"
     375           2 :                     + name
     376           3 :                     + " option was not defined on the command line and it has no or an empty default.");
     377             :         }
     378           4 :         if(!validator_double::convert_string(d, result))
     379             :         {
     380             :             // here we throw because this default value is defined in the
     381             :             // options of the tool and not by the user
     382             :             //
     383             :             throw getopt_logic_error(
     384             :                       "invalid default number \""
     385           2 :                     + d
     386           3 :                     + "\" for option --"
     387           3 :                     + name
     388           3 :                     + ".");
     389             :         }
     390             :     }
     391             :     else
     392             :     {
     393          41 :         result = opt->get_double(idx);
     394             :     }
     395             : 
     396             :     // TODO: replace with validators
     397             :     //
     398          44 :     if(result < min || result > max)
     399             :     {
     400           2 :         cppthread::log << cppthread::log_level_t::error
     401           1 :                        << result
     402           1 :                        << " is out of bounds ("
     403           1 :                        << min
     404           1 :                        << ".."
     405           1 :                        << max
     406           1 :                        << " inclusive) in parameter --"
     407           1 :                        << name
     408           1 :                        << "."
     409           2 :                        << cppthread::end;
     410           1 :         result = -1.0;
     411             :     }
     412             : 
     413          88 :     return result;
     414             : }
     415             : 
     416             : 
     417             : /** \brief Get the content of an option as a string.
     418             :  *
     419             :  * Get the content of the named parameter as a string. Command line options
     420             :  * that accept multiple arguments accept the \p idx parameter to
     421             :  * specify which item you are interested in.
     422             :  *
     423             :  * Note that the option must have been specified on the command line or have
     424             :  * a default value. For options that do not have a default value, you want
     425             :  * to call the is_defined() function first.
     426             :  *
     427             :  * \note
     428             :  * If the function returns the default value, it gets returned as is. i.e.
     429             :  * it won't be passed through the variable processing function.
     430             :  *
     431             :  * \exception getopt_exception_undefined
     432             :  * The getopt_exception_undefined exception is raised if \p name was not
     433             :  * found on the command line and it has no default, or if \p idx is
     434             :  * out of bounds.
     435             :  *
     436             :  * \param[in] name  The name of the option to read.
     437             :  * \param[in] idx  The zero based index of a multi-argument command line option.
     438             :  * \param[in] raw  Whether to return the value without replacing the variables.
     439             :  *
     440             :  * \return The option argument as a string.
     441             :  */
     442         583 : std::string getopt::get_string(
     443             :       std::string const & name
     444             :     , int idx
     445             :     , bool raw) const
     446             : {
     447         583 :     is_parsed();
     448             : 
     449        1166 :     option_info::pointer_t opt(get_option(name));
     450         583 :     if(opt == nullptr)
     451             :     {
     452             :         throw getopt_logic_error(
     453             :                   "there is no --"
     454           6 :                 + name
     455           9 :                 + " option defined.");
     456             :     }
     457             : 
     458         580 :     if(!opt->is_defined())
     459             :     {
     460          49 :         if(opt->has_default())
     461             :         {
     462          44 :             return opt->get_default();
     463             :         }
     464             :         throw getopt_logic_error(
     465             :                   "the --"
     466          10 :                 + name
     467          15 :                 + " option was not defined on the command line and it has no default.");
     468             :     }
     469             : 
     470             :     // it was defined, but if REQUIRED is not set and the value is empty
     471             :     // then we want to return the default if it has such defined
     472             :     //
     473        1061 :     std::string const value(opt->get_value(idx, raw));
     474        1060 :     if(value.empty()
     475          68 :     && opt->has_default()
     476         538 :     && !opt->has_flag(GETOPT_FLAG_REQUIRED))
     477             :     {
     478           8 :         return opt->get_default();
     479             :     }
     480             : 
     481         522 :     return value;
     482             : }
     483             : 
     484             : 
     485             : /** \brief Retrieve the value of an argument.
     486             :  *
     487             :  * This operator returns the value of an argument just like the get_string()
     488             :  * does when the argument is defined. When the argument is not defined and it
     489             :  * has no default, it returns an empty string instead of throwing.
     490             :  *
     491             :  * The function is only capable of returning the very first value. If this
     492             :  * argument has the GETOPT_FLAG_MULTIPLE flag set, you probably want to use
     493             :  * the get_string() instead.
     494             :  *
     495             :  * \param[in] name  The name of the option to retrieve.
     496             :  *
     497             :  * \return The value of that option or an empty string if not defined.
     498             :  */
     499         207 : std::string getopt::operator [] (std::string const & name) const
     500             : {
     501         207 :     is_parsed();
     502             : 
     503         207 :     if(name.empty())
     504             :     {
     505           2 :         throw getopt_logic_error("argument name cannot be empty.");
     506             :     }
     507             : 
     508         410 :     option_info::pointer_t opt(get_option(name));
     509         205 :     if(opt == nullptr)
     510             :     {
     511           4 :         return std::string();
     512             :     }
     513             : 
     514         201 :     if(!opt->is_defined())
     515             :     {
     516          11 :         if(opt->has_default())
     517             :         {
     518          10 :             return opt->get_default();
     519             :         }
     520           1 :         return std::string();
     521             :     }
     522             : 
     523         190 :     return opt->get_value(0);
     524             : }
     525             : 
     526             : 
     527             : /** \brief Access a parameter in read and write mode.
     528             :  *
     529             :  * This function allows you to access an argument which may or may not
     530             :  * yet exist.
     531             :  *
     532             :  * The return value is a reference to that parameter. You can read
     533             :  * and write to the reference.
     534             :  *
     535             :  * A non-existant argument is created only if necessary. That is,
     536             :  * only if you actually use an assignment operator as follow:
     537             :  *
     538             :  * \code
     539             :  *      // straight assignment:
     540             :  *      opt["my-var"] = "123";
     541             :  *
     542             :  *      // or concatenation:
     543             :  *      opt["my-var"] += "append";
     544             :  * \endcode
     545             :  *
     546             :  * In read mode and unless you defined a default, a non-existant argument
     547             :  * is viewed as an empty string or 0 if retrieved as a long:
     548             :  *
     549             :  * \code
     550             :  *      // if non-existant you get an empty string:
     551             :  *      std::string value = opt["non-existant"];
     552             :  *
     553             :  *      // if non-existant you get zero:
     554             :  *      long value = opt["non-existant"].get_long();
     555             :  * \endcode
     556             :  *
     557             :  * The get_long() function may generate an error if the parameter is not
     558             :  * a valid integer. Also when a default is defined, it tries to convert
     559             :  * the default value to a number and if that fails an error is generated.
     560             :  *
     561             :  * \note
     562             :  * This operator only allows you to access the very first value of
     563             :  * this option. If the option is marked with GETOPT_FLAG_MULTIPLE,
     564             :  * you may want to use the get_option() function and then handle
     565             :  * the option multiple values manually with the option_info::get_value()
     566             :  * and option_info::set_value().
     567             :  *
     568             :  * \warning
     569             :  * If the option is an alias and the destination is not defined you
     570             :  * can still get an exception raised.
     571             :  *
     572             :  * \param[in] name  The name of the option to access.
     573             :  *
     574             :  * \return A reference to this option with support for many std::string like
     575             :  *         operators.
     576             :  */
     577         176 : option_info_ref getopt::operator [] (std::string const & name)
     578             : {
     579         176 :     is_parsed();
     580             : 
     581         176 :     if(name.empty())
     582             :     {
     583           2 :         throw getopt_logic_error("argument name cannot be empty.");
     584             :     }
     585             : 
     586         348 :     option_info::pointer_t opt(get_option(name));
     587         174 :     if(opt == nullptr)
     588             :     {
     589          55 :         if(name.length() == 1)
     590             :         {
     591           2 :             throw getopt_logic_error("argument name cannot be one letter if it does not exist in operator [].");
     592             :         }
     593             : 
     594             :         // The option doesn't exist yet, create it
     595             :         //
     596          53 :         opt = std::make_shared<option_info>(name);
     597          53 :         opt->set_variables(f_variables);
     598          53 :         opt->add_flag(GETOPT_FLAG_DYNAMIC_CONFIGURATION);
     599          53 :         f_options_by_name[name] = opt;
     600             :     }
     601             : 
     602         344 :     return option_info_ref(opt);
     603             : }
     604             : 
     605             : 
     606             : /** \brief Process the system options.
     607             :  *
     608             :  * If you have the GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS flag turned on,
     609             :  * then several options are automatically added to your list of supported
     610             :  * options, such as `--version`.
     611             :  *
     612             :  * This function processes these options if any were used by the client.
     613             :  *
     614             :  * If the function finds one or more system flags as being defined, it
     615             :  * returns a non-zero set of SYSTEM_OPTION_... flags. This can be useful
     616             :  * to decide whether to continue processing or not.
     617             :  *
     618             :  * We define a set of flags that can help you decide whether to continue
     619             :  * or exit. In most cases, we propose that you exit your program if any
     620             :  * one of the options was a command. This is done like so:
     621             :  *
     622             :  * \code
     623             :  * advgetopt::flag_t const r(process_system_options(stdout));
     624             :  * if((r & SYSTEM_OPTION_COMMANDS_MASK) != 0)
     625             :  * {
     626             :  *     exit(1);
     627             :  * }
     628             :  * \endcode
     629             :  *
     630             :  * You may still want to continue, though, if other flags where set,
     631             :  * even if some commands were used. For example, some tools will print
     632             :  * their version and move forward with there work (i.e. compilers often do
     633             :  * that to help with logging all the information about a build process,
     634             :  * including the version of the compiler.)
     635             :  *
     636             :  * \param[in] out  The stream where output is sent if required.
     637             :  *
     638             :  * \return non-zero set of flags if any of the system parameters were processed.
     639             :  */
     640          45 : flag_t getopt::process_system_options(std::basic_ostream<char> & out)
     641             : {
     642          45 :     flag_t result(SYSTEM_OPTION_NONE);
     643             : 
     644             :     // --version
     645          45 :     if(is_defined("version"))
     646             :     {
     647           4 :         if(f_options_environment.f_version == nullptr)
     648             :         {
     649           1 :             out << "warning: no version found." << std::endl;
     650             :         }
     651             :         else
     652             :         {
     653           3 :             out << f_options_environment.f_version << std::endl;
     654             :         }
     655           4 :         result |= SYSTEM_OPTION_VERSION;
     656             :     }
     657             : 
     658             :     // --has-sanitizer
     659          45 :     if(is_defined("has-sanitizer"))
     660             :     {
     661           1 :         out << sanitizer_details() << std::flush;
     662           1 :         result |= SYSTEM_OPTION_HELP;
     663             :     }
     664             : 
     665             :     // --compiler-version
     666          45 :     if(is_defined("compiler-version"))
     667             :     {
     668           1 :         out << LIBADVGETOPT_COMPILER_VERSION << std::endl;
     669           1 :         result |= SYSTEM_OPTION_HELP;
     670             :     }
     671             : 
     672             :     // --help
     673          45 :     if(is_defined("help"))
     674             :     {
     675           1 :         less(out, usage());
     676           1 :         result |= SYSTEM_OPTION_HELP;
     677             :     }
     678             : 
     679             :     // --long-help
     680          45 :     if(is_defined("long-help"))
     681             :     {
     682           1 :         less(out, usage(GETOPT_FLAG_SHOW_ALL));
     683           1 :         result |= SYSTEM_OPTION_HELP;
     684             :     }
     685             : 
     686             :     // --<group-name>-help
     687             :     //
     688          45 :     if(f_options_environment.f_groups != nullptr)
     689             :     {
     690           6 :         for(group_description const * grp = f_options_environment.f_groups
     691           6 :           ; grp->f_group != GETOPT_FLAG_GROUP_NONE
     692             :           ; ++grp)
     693             :         {
     694             :             // the name is not mandatory, without it you do not get the command
     695             :             // line option but still get the group description
     696             :             //
     697           4 :             if(grp->f_name != nullptr
     698           4 :             && *grp->f_name != '\0')
     699             :             {
     700           8 :                 std::string const name(grp->f_name);
     701           8 :                 std::string const option_name(name + "-help");
     702           4 :                 if(is_defined(option_name))
     703             :                 {
     704           2 :                     less(out, usage(grp->f_group));
     705           2 :                     result |= SYSTEM_OPTION_HELP;
     706             :                 }
     707             :             }
     708             :         }
     709             :     }
     710             : 
     711             :     // --copyright
     712          45 :     if(is_defined("copyright"))
     713             :     {
     714           3 :         if(f_options_environment.f_copyright == nullptr)
     715             :         {
     716           1 :             out << "warning: no copyright notice found." << std::endl;
     717             :         }
     718             :         else
     719             :         {
     720           2 :             less(out, f_options_environment.f_copyright);
     721             :         }
     722           3 :         result |= SYSTEM_OPTION_COPYRIGHT;
     723             :     }
     724             : 
     725             :     // --license
     726          45 :     if(is_defined("license"))
     727             :     {
     728           4 :         if(f_options_environment.f_license == nullptr)
     729             :         {
     730           1 :             out << "warning: no license found." << std::endl;
     731             :         }
     732             :         else
     733             :         {
     734           3 :             less(out, f_options_environment.f_license);
     735             :         }
     736           4 :         result |= SYSTEM_OPTION_LICENSE;
     737             :     }
     738             : 
     739             :     // --build-date
     740          45 :     if(is_defined("build-date"))
     741             :     {
     742             :         out << "Built on "
     743           2 :             << (f_options_environment.f_build_date == nullptr
     744             :                     ? "<no-build-date>"
     745             :                     : f_options_environment.f_build_date)
     746             :             << " at "
     747           2 :             << (f_options_environment.f_build_time == nullptr
     748             :                     ? "<no-build-time>"
     749           6 :                     : f_options_environment.f_build_time)
     750           2 :             << std::endl;
     751           2 :         result |= SYSTEM_OPTION_BUILD_DATE;
     752             :     }
     753             : 
     754             :     // --environment-variable-name
     755          45 :     if(is_defined("environment-variable-name"))
     756             :     {
     757           3 :         if(f_options_environment.f_environment_variable_name == nullptr
     758           2 :         || *f_options_environment.f_environment_variable_name == '\0')
     759             :         {
     760             :             out << f_options_environment.f_project_name
     761           2 :                 << " does not support an environment variable."
     762           2 :                 << std::endl;
     763             :         }
     764             :         else
     765             :         {
     766           1 :             out << f_options_environment.f_environment_variable_name << std::endl;
     767             :         }
     768           3 :         result |= SYSTEM_OPTION_ENVIRONMENT_VARIABLE_NAME;
     769             :     }
     770             : 
     771             :     // --configuration-filenames
     772          45 :     if(is_defined("configuration-filenames"))
     773             :     {
     774           6 :         string_list_t list(get_configuration_filenames(false, false));
     775           3 :         if(list.empty())
     776             :         {
     777             :             out << f_options_environment.f_project_name
     778           1 :                 << " does not support configuration files."
     779           1 :                 << std::endl;
     780             :         }
     781             :         else
     782             :         {
     783           2 :             out << "Configuration filenames:" << std::endl;
     784          26 :             for(auto n : list)
     785             :             {
     786          24 :                 out << " . " << n << std::endl;
     787             :             }
     788             :         }
     789           3 :         result |= SYSTEM_OPTION_CONFIGURATION_FILENAMES;
     790             :     }
     791             : 
     792             :     // --path-to-option-definitions
     793          45 :     if(is_defined("path-to-option-definitions"))
     794             :     {
     795           2 :         if(f_options_environment.f_options_files_directory == nullptr
     796           1 :         || *f_options_environment.f_options_files_directory == '\0')
     797             :         {
     798           1 :             out << "/usr/share/advgetopt/options/" << std::endl;
     799             :         }
     800             :         else
     801             :         {
     802           1 :             out << f_options_environment.f_options_files_directory;
     803           1 :             if(f_options_environment.f_options_files_directory[strlen(f_options_environment.f_options_files_directory) - 1] != '/')
     804             :             {
     805           1 :                 out << '/';
     806             :             }
     807           1 :             out << std::endl;
     808             :         }
     809           2 :         result |= SYSTEM_OPTION_PATH_TO_OPTION_DEFINITIONS;
     810             :     }
     811             : 
     812             :     // --config-dir
     813          45 :     if(is_defined("config-dir"))
     814             :     {
     815             :         // these are automatically used in the get_configuration_filenames()
     816             :         // function, there is nothing for us to do here
     817             :         //
     818           3 :         result |= SYSTEM_OPTION_CONFIG_DIR;
     819             :     }
     820             : 
     821             :     // --show-option-sources
     822          45 :     if(is_defined("show-option-sources"))
     823             :     {
     824           3 :         show_option_sources(out);
     825           3 :         result |= SYSTEM_OPTION_SHOW_OPTION_SOURCES;
     826             :     }
     827             : 
     828             :     // --print-option
     829          45 :     if(is_defined("print-option"))
     830             :     {
     831           6 :         std::string const name(get_string("print-option"));
     832           3 :         if(is_defined(name))
     833             :         {
     834           1 :             out << get_string(name) << std::endl;
     835             :         }
     836           2 :         else if(has_default(name))
     837             :         {
     838           1 :             out << get_default(name) << std::endl;
     839             :         }
     840           3 :         result |= SYSTEM_OPTION_SHOW_OPTION_VALUE;
     841             :     }
     842             : 
     843          45 :     return result;
     844             : }
     845             : 
     846             : 
     847             : 
     848             : 
     849             : 
     850           6 : } // namespace advgetopt
     851             : // vim: ts=4 sw=4 et

Generated by: LCOV version 1.13