LCOV - code coverage report
Current view: top level - advgetopt - advgetopt_data.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 176 212 83.0 %
Date: 2022-05-26 21:41:34 Functions: 12 13 92.3 %
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 lib
      39             : //
      40             : #include    <cppthread/log.h>
      41             : 
      42             : 
      43             : // C lib
      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        1368 : bool getopt::is_defined(std::string const & name) const
      97             : {
      98        1368 :     is_parsed();
      99             : 
     100        2728 :     option_info::pointer_t opt(get_option(name));
     101        1364 :     if(opt != nullptr)
     102             :     {
     103        1038 :         return opt->is_defined();
     104             :     }
     105             : 
     106         326 :     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         615 : size_t getopt::size(std::string const & name) const
     126             : {
     127         615 :     is_parsed();
     128             : 
     129        1224 :     option_info::pointer_t opt(get_option(name));
     130         612 :     if(opt != nullptr)
     131             :     {
     132         400 :         return opt->size();
     133             :     }
     134         212 :     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          79 : bool getopt::has_default(std::string const & name) const
     157             : {
     158         156 :     option_info::pointer_t opt(get_option(name));
     159          77 :     if(opt != nullptr)
     160             :     {
     161          72 :         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         553 : std::string getopt::get_default(std::string const & name) const
     192             : {
     193        1104 :     option_info::pointer_t opt(get_option(name));
     194         551 :     if(opt != nullptr)
     195             :     {
     196         318 :         return opt->get_default();
     197             :     }
     198             : 
     199         233 :     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, 9);
     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           0 : double getopt::get_double(std::string const & name, int idx, double min, double max) const
     355             : {
     356           0 :     is_parsed();
     357             : 
     358           0 :     option_info::pointer_t opt(get_option(name));
     359           0 :     if(opt == nullptr)
     360             :     {
     361             :         throw getopt_logic_error(
     362             :                   "there is no --"
     363           0 :                 + name
     364           0 :                 + " option defined.");
     365             :     }
     366             : 
     367           0 :     double result(0);
     368           0 :     if(!opt->is_defined())
     369             :     {
     370           0 :         std::string const d(opt->get_default());
     371           0 :         if(d.empty())
     372             :         {
     373             :             throw getopt_logic_error(
     374             :                       "the --"
     375           0 :                     + name
     376           0 :                     + " option was not defined on the command line and it has no or an empty default.");
     377             :         }
     378           0 :         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           0 :                     + d
     386           0 :                     + "\" for option --"
     387           0 :                     + name);
     388             :         }
     389             :     }
     390             :     else
     391             :     {
     392           0 :         result = opt->get_double(idx);
     393             :     }
     394             : 
     395             :     // TODO: replace with validators
     396             :     //
     397           0 :     if(result < min || result > max)
     398             :     {
     399           0 :         cppthread::log << cppthread::log_level_t::error
     400           0 :                        << result
     401           0 :                        << " is out of bounds ("
     402           0 :                        << min
     403           0 :                        << ".."
     404           0 :                        << max
     405           0 :                        << " inclusive) in parameter --"
     406           0 :                        << name
     407           0 :                        << "."
     408           0 :                        << cppthread::end;
     409           0 :         result = -1.0;
     410             :     }
     411             : 
     412           0 :     return result;
     413             : }
     414             : 
     415             : 
     416             : /** \brief Get the content of an option as a string.
     417             :  *
     418             :  * Get the content of the named parameter as a string. Command line options
     419             :  * that accept multiple arguments accept the \p idx parameter to
     420             :  * specify which item you are interested in.
     421             :  *
     422             :  * Note that the option must have been specified on the command line or have
     423             :  * a default value. For options that do not have a default value, you want
     424             :  * to call the is_defined() function first.
     425             :  *
     426             :  * \note
     427             :  * If the function returns the default value, it gets returned as is. i.e.
     428             :  * it won't be passed through the variable processing function.
     429             :  *
     430             :  * \exception getopt_exception_undefined
     431             :  * The getopt_exception_undefined exception is raised if \p name was not
     432             :  * found on the command line and it has no default, or if \p idx is
     433             :  * out of bounds.
     434             :  *
     435             :  * \param[in] name  The name of the option to read.
     436             :  * \param[in] idx  The zero based index of a multi-argument command line option.
     437             :  * \param[in] raw  Whether to return the value without replacing the variables.
     438             :  *
     439             :  * \return The option argument as a string.
     440             :  */
     441         562 : std::string getopt::get_string(
     442             :       std::string const & name
     443             :     , int idx
     444             :     , bool raw) const
     445             : {
     446         562 :     is_parsed();
     447             : 
     448        1124 :     option_info::pointer_t opt(get_option(name));
     449         562 :     if(opt == nullptr)
     450             :     {
     451             :         throw getopt_logic_error(
     452             :                   "there is no --"
     453           6 :                 + name
     454           9 :                 + " option defined.");
     455             :     }
     456             : 
     457         559 :     if(!opt->is_defined())
     458             :     {
     459          45 :         if(opt->has_default())
     460             :         {
     461          40 :             return opt->get_default();
     462             :         }
     463             :         throw getopt_logic_error(
     464             :                   "the --"
     465          10 :                 + name
     466          15 :                 + " option was not defined on the command line and it has no default.");
     467             :     }
     468             : 
     469             :     // it was defined, but if REQUIRED is not set and the value is empty
     470             :     // then we want to return the default if it has such defined
     471             :     //
     472        1027 :     std::string const value(opt->get_value(idx, raw));
     473        1026 :     if(value.empty()
     474          67 :     && opt->has_default()
     475         521 :     && !opt->has_flag(GETOPT_FLAG_REQUIRED))
     476             :     {
     477           8 :         return opt->get_default();
     478             :     }
     479             : 
     480         505 :     return value;
     481             : }
     482             : 
     483             : 
     484             : /** \brief Retrieve the value of an argument.
     485             :  *
     486             :  * This operator returns the value of an argument just like the get_string()
     487             :  * does when the argument is defined. When the argument is not defined and it
     488             :  * has no default, it returns an empty string instead of throwing.
     489             :  *
     490             :  * The function is only capable of returning the very first value. If this
     491             :  * argument has the GETOPT_FLAG_MULTIPLE flag set, you probably want to use
     492             :  * the get_string() instead.
     493             :  *
     494             :  * \param[in] name  The name of the option to retrieve.
     495             :  *
     496             :  * \return The value of that option or an empty string if not defined.
     497             :  */
     498         193 : std::string getopt::operator [] (std::string const & name) const
     499             : {
     500         193 :     is_parsed();
     501             : 
     502         193 :     if(name.empty())
     503             :     {
     504           2 :         throw getopt_logic_error("argument name cannot be empty.");
     505             :     }
     506             : 
     507         382 :     option_info::pointer_t opt(get_option(name));
     508         191 :     if(opt == nullptr)
     509             :     {
     510           1 :         return std::string();
     511             :     }
     512             : 
     513         190 :     if(!opt->is_defined())
     514             :     {
     515           6 :         if(opt->has_default())
     516             :         {
     517           5 :             return opt->get_default();
     518             :         }
     519           1 :         return std::string();
     520             :     }
     521             : 
     522         184 :     return opt->get_value(0);
     523             : }
     524             : 
     525             : 
     526             : /** \brief Access a parameter in read and write mode.
     527             :  *
     528             :  * This function allows you to access an argument which may or may not
     529             :  * yet exist.
     530             :  *
     531             :  * The return value is a reference to that parameter. You can read
     532             :  * and write to the reference.
     533             :  *
     534             :  * A non-existant argument is created only if necessary. That is,
     535             :  * only if you actually use an assignment operator as follow:
     536             :  *
     537             :  * \code
     538             :  *      // straight assignment:
     539             :  *      opt["my-var"] = "123";
     540             :  *
     541             :  *      // or concatenation:
     542             :  *      opt["my-var"] += "append";
     543             :  * \endcode
     544             :  *
     545             :  * In read mode and unless you defined a default, a non-existant argument
     546             :  * is viewed as an empty string or 0 if retrieved as a long:
     547             :  *
     548             :  * \code
     549             :  *      // if non-existant you get an empty string:
     550             :  *      std::string value = opt["non-existant"];
     551             :  *
     552             :  *      // if non-existant you get zero:
     553             :  *      long value = opt["non-existant"].get_long();
     554             :  * \endcode
     555             :  *
     556             :  * The get_long() function may generate an error if the parameter is not
     557             :  * a valid integer. Also when a default is defined, it tries to convert
     558             :  * the default value to a number and if that fails an error is generated.
     559             :  *
     560             :  * \note
     561             :  * This operator only allows you to access the very first value of
     562             :  * this option. If the option is marked with GETOPT_FLAG_MULTIPLE,
     563             :  * you may want to use the get_option() function and then handle
     564             :  * the option multiple values manually with the option_info::get_value()
     565             :  * and option_info::set_value().
     566             :  *
     567             :  * \warning
     568             :  * If the option is an alias and the destination is not defined you
     569             :  * can still get an exception raised.
     570             :  *
     571             :  * \param[in] name  The name of the option to access.
     572             :  *
     573             :  * \return A reference to this option with support for many std::string like
     574             :  *         operators.
     575             :  */
     576         169 : option_info_ref getopt::operator [] (std::string const & name)
     577             : {
     578         169 :     is_parsed();
     579             : 
     580         169 :     if(name.empty())
     581             :     {
     582           2 :         throw getopt_logic_error("argument name cannot be empty.");
     583             :     }
     584             : 
     585         334 :     option_info::pointer_t opt(get_option(name));
     586         167 :     if(opt == nullptr)
     587             :     {
     588          54 :         if(name.length() == 1)
     589             :         {
     590           2 :             throw getopt_logic_error("argument name cannot be one letter if it does not exist in operator [].");
     591             :         }
     592             : 
     593             :         // The option doesn't exist yet, create it
     594             :         //
     595          52 :         opt = std::make_shared<option_info>(name);
     596          52 :         opt->set_variables(f_variables);
     597          52 :         opt->add_flag(GETOPT_FLAG_DYNAMIC_CONFIGURATION);
     598          52 :         f_options_by_name[name] = opt;
     599             :     }
     600             : 
     601         330 :     return option_info_ref(opt);
     602             : }
     603             : 
     604             : 
     605             : /** \brief Generate a string describing whether we're using the sanitizer.
     606             :  *
     607             :  * This function determines whether this library was compiled with the
     608             :  * sanitizer extension. If so, then it will return detail about which
     609             :  * feature was compiled in.
     610             :  *
     611             :  * If no sanitizer options were compiled in, then it returns a
     612             :  * message saying so.
     613             :  *
     614             :  * \return A string with details about the sanitizer.
     615             :  */
     616           2 : std::string getopt::sanitizer_details()
     617             : {
     618           2 :     std::string result;
     619             : #if defined(__SANITIZE_ADDRESS__) || defined(__SANITIZE_THREAD__)
     620             : #if defined(__SANITIZE_ADDRESS__)
     621           2 :     result += "The address sanitizer is compiled in.\n";
     622             : #endif
     623             : #if defined(__SANITIZE_THREAD__)
     624             :     result += "The thread sanitizer is compiled in.\n";
     625             : #endif
     626             : #else
     627             :     result += "The address and thread sanitizers are not compiled in.\n";
     628             : #endif
     629           2 :     return result;
     630             : }
     631             : 
     632             : 
     633             : /** \brief Process the system options.
     634             :  *
     635             :  * If you have the GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS flag turned on,
     636             :  * then several options are automatically added to your list of supported
     637             :  * options, such as `--version`.
     638             :  *
     639             :  * This function processes these options if any were used by the client.
     640             :  *
     641             :  * If the function finds one or more system flags as being defined, it
     642             :  * returns a non-zero set of SYSTEM_OPTION_... flags. This can be useful
     643             :  * to decide whether to continue processing or not.
     644             :  *
     645             :  * We define a set of flags that can help you decide whether to continue
     646             :  * or exit. In most cases, we propose that you exit your program if any
     647             :  * one of the options was a command. This is done like so:
     648             :  *
     649             :  * \code
     650             :  * advgetopt::flag_t const r(process_system_options(stdout));
     651             :  * if((r & SYSTEM_OPTION_COMMANDS_MASK) != 0)
     652             :  * {
     653             :  *     exit(1);
     654             :  * }
     655             :  * \endcode
     656             :  *
     657             :  * You may still want to continue, though, if other flags where set,
     658             :  * even if some commands were used. For example, some tools will print
     659             :  * their version and move forward with there work (i.e. compilers often do
     660             :  * that to help with logging all the information about a build process,
     661             :  * including the version of the compiler.)
     662             :  *
     663             :  * \param[in] out  The stream where output is sent if required.
     664             :  *
     665             :  * \return non-zero set of flags if any of the system parameters were processed.
     666             :  */
     667          42 : flag_t getopt::process_system_options(std::basic_ostream<char> & out)
     668             : {
     669          42 :     flag_t result(SYSTEM_OPTION_NONE);
     670             : 
     671             :     // --version
     672          42 :     if(is_defined("version"))
     673             :     {
     674           4 :         if(f_options_environment.f_version == nullptr)
     675             :         {
     676           1 :             out << "warning: no version found." << std::endl;
     677             :         }
     678             :         else
     679             :         {
     680           3 :             out << f_options_environment.f_version << std::endl;
     681             :         }
     682           4 :         result |= SYSTEM_OPTION_VERSION;
     683             :     }
     684             : 
     685             :     // --has-sanitizer
     686          42 :     if(is_defined("has-sanitizer"))
     687             :     {
     688           1 :         out << sanitizer_details() << std::flush;
     689           1 :         result |= SYSTEM_OPTION_HELP;
     690             :     }
     691             : 
     692             :     // --compiler-version
     693          42 :     if(is_defined("compiler-version"))
     694             :     {
     695           1 :         out << LIBADVGETOPT_COMPILER_VERSION << std::endl;
     696           1 :         result |= SYSTEM_OPTION_HELP;
     697             :     }
     698             : 
     699             :     // --help
     700          42 :     if(is_defined("help"))
     701             :     {
     702           1 :         out << usage() << std::endl;
     703           1 :         result |= SYSTEM_OPTION_HELP;
     704             :     }
     705             : 
     706             :     // --long-help
     707          42 :     if(is_defined("long-help"))
     708             :     {
     709           1 :         out << usage(GETOPT_FLAG_SHOW_ALL) << std::endl;
     710           1 :         result |= SYSTEM_OPTION_HELP;
     711             :     }
     712             : 
     713             :     // --<group-name>-help
     714             :     //
     715          42 :     if(f_options_environment.f_groups != nullptr)
     716             :     {
     717           6 :         for(group_description const * grp = f_options_environment.f_groups
     718           6 :           ; grp->f_group != GETOPT_FLAG_GROUP_NONE
     719             :           ; ++grp)
     720             :         {
     721             :             // the name is not mandatory, without it you do not get the command
     722             :             // line option but still get the group description
     723             :             //
     724           4 :             if(grp->f_name != nullptr
     725           4 :             && *grp->f_name != '\0')
     726             :             {
     727           8 :                 std::string const name(grp->f_name);
     728           8 :                 std::string const option_name(name + "-help");
     729           4 :                 if(is_defined(option_name))
     730             :                 {
     731           2 :                     out << usage(grp->f_group) << std::endl;
     732           2 :                     result |= SYSTEM_OPTION_HELP;
     733             :                 }
     734             :             }
     735             :         }
     736             :     }
     737             : 
     738             :     // --copyright
     739          42 :     if(is_defined("copyright"))
     740             :     {
     741           3 :         if(f_options_environment.f_copyright == nullptr)
     742             :         {
     743           1 :             out << "warning: no copyright notice found." << std::endl;
     744             :         }
     745             :         else
     746             :         {
     747           2 :             out << f_options_environment.f_copyright << std::endl;
     748             :         }
     749           3 :         result |= SYSTEM_OPTION_COPYRIGHT;
     750             :     }
     751             : 
     752             :     // --license
     753          42 :     if(is_defined("license"))
     754             :     {
     755           4 :         if(f_options_environment.f_license == nullptr)
     756             :         {
     757           1 :             out << "warning: no license found." << std::endl;
     758             :         }
     759             :         else
     760             :         {
     761           3 :             out << f_options_environment.f_license << std::endl;
     762             :         }
     763           4 :         result |= SYSTEM_OPTION_LICENSE;
     764             :     }
     765             : 
     766             :     // --build-date
     767          42 :     if(is_defined("build-date"))
     768             :     {
     769             :         out << "Built on "
     770           2 :             << (f_options_environment.f_build_date == nullptr
     771             :                     ? "<no-build-date>"
     772             :                     : f_options_environment.f_build_date)
     773             :             << " at "
     774           2 :             << (f_options_environment.f_build_time == nullptr
     775             :                     ? "<no-build-time>"
     776           6 :                     : f_options_environment.f_build_time)
     777           2 :             << std::endl;
     778           2 :         result |= SYSTEM_OPTION_BUILD_DATE;
     779             :     }
     780             : 
     781             :     // --environment-variable-name
     782          42 :     if(is_defined("environment-variable-name"))
     783             :     {
     784           3 :         if(f_options_environment.f_environment_variable_name == nullptr
     785           2 :         || *f_options_environment.f_environment_variable_name == '\0')
     786             :         {
     787             :             out << f_options_environment.f_project_name
     788           2 :                 << " does not support an environment variable."
     789           2 :                 << std::endl;
     790             :         }
     791             :         else
     792             :         {
     793           1 :             out << f_options_environment.f_environment_variable_name << std::endl;
     794             :         }
     795           3 :         result |= SYSTEM_OPTION_ENVIRONMENT_VARIABLE_NAME;
     796             :     }
     797             : 
     798             :     // --configuration-filenames
     799          42 :     if(is_defined("configuration-filenames"))
     800             :     {
     801           6 :         string_list_t list(get_configuration_filenames(false, false));
     802           3 :         if(list.empty())
     803             :         {
     804             :             out << f_options_environment.f_project_name
     805           1 :                 << " does not support configuration files."
     806           1 :                 << std::endl;
     807             :         }
     808             :         else
     809             :         {
     810           2 :             out << "Configuration filenames:" << std::endl;
     811          26 :             for(auto n : list)
     812             :             {
     813          24 :                 out << " . " << n << std::endl;
     814             :             }
     815             :         }
     816           3 :         result |= SYSTEM_OPTION_CONFIGURATION_FILENAMES;
     817             :     }
     818             : 
     819             :     // --path-to-option-definitions
     820          42 :     if(is_defined("path-to-option-definitions"))
     821             :     {
     822           2 :         if(f_options_environment.f_options_files_directory == nullptr
     823           1 :         || *f_options_environment.f_options_files_directory == '\0')
     824             :         {
     825           1 :             out << "/usr/share/advgetopt/options/" << std::endl;
     826             :         }
     827             :         else
     828             :         {
     829           1 :             out << f_options_environment.f_options_files_directory;
     830           1 :             if(f_options_environment.f_options_files_directory[strlen(f_options_environment.f_options_files_directory) - 1] != '/')
     831             :             {
     832           1 :                 out << '/';
     833             :             }
     834           1 :             out << std::endl;
     835             :         }
     836           2 :         result |= SYSTEM_OPTION_PATH_TO_OPTION_DEFINITIONS;
     837             :     }
     838             : 
     839             :     // --config-dir
     840          42 :     if(is_defined("config-dir"))
     841             :     {
     842             :         // these are automatically used in the get_configuration_filenames()
     843             :         // function, there is nothing for us to do here
     844             :         //
     845           3 :         result |= SYSTEM_OPTION_CONFIG_DIR;
     846             :     }
     847             : 
     848             :     // --show-option-sources
     849          42 :     if(is_defined("show-option-sources"))
     850             :     {
     851           3 :         show_option_sources(out);
     852           3 :         result |= SYSTEM_OPTION_SHOW_OPTION_SOURCES;
     853             :     }
     854             : 
     855             :     // --print-option
     856          42 :     if(is_defined("print-option"))
     857             :     {
     858           0 :         std::string const name(get_string("print-option"));
     859           0 :         if(is_defined(name))
     860             :         {
     861           0 :             out << get_string(name) << std::endl;
     862             :         }
     863           0 :         else if(has_default(name))
     864             :         {
     865           0 :             out << get_default(name) << std::endl;
     866             :         }
     867           0 :         result |= SYSTEM_OPTION_SHOW_OPTION_VALUE;
     868             :     }
     869             : 
     870          42 :     return result;
     871             : }
     872             : 
     873             : 
     874             : 
     875             : 
     876             : 
     877           6 : } // namespace advgetopt
     878             : // vim: ts=4 sw=4 et

Generated by: LCOV version 1.13