LCOV - code coverage report
Current view: top level - advgetopt - advgetopt_usage.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 303 303 100.0 %
Date: 2022-07-15 17:40:56 Functions: 6 6 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 usage() implementation.
      22             :  *
      23             :  * The advgetopt class usage() and helper functions are grouped in this
      24             :  * file.
      25             :  */
      26             : 
      27             : // self
      28             : //
      29             : #include    "advgetopt/advgetopt.h"
      30             : 
      31             : #include    "advgetopt/exception.h"
      32             : 
      33             : 
      34             : // C++
      35             : //
      36             : #include    <iomanip>
      37             : #include    <iostream>
      38             : 
      39             : 
      40             : // C
      41             : //
      42             : //#include    <unistd.h>
      43             : //#include    <sys/ioctl.h>
      44             : 
      45             : 
      46             : // last include
      47             : //
      48             : #include    <snapdev/poison.h>
      49             : 
      50             : 
      51             : 
      52             : 
      53             : namespace advgetopt
      54             : {
      55             : 
      56             : 
      57             : 
      58             : /** \brief Transform group names in --\<name>-help commands.
      59             :  *
      60             :  * This function allows for the group names to be transformed into help
      61             :  * command line options.
      62             :  */
      63         355 : void getopt::parse_options_from_group_names()
      64             : {
      65             :     // add the --long-help if at least one option uses the GROUP1 or GROUP2
      66             :     //
      67         785 :     for(auto it(f_options_by_name.begin())
      68         785 :       ; it != f_options_by_name.end()
      69             :       ; ++it)
      70             :     {
      71         438 :         if(it->second->has_flag(GETOPT_FLAG_SHOW_GROUP1 | GETOPT_FLAG_SHOW_GROUP2))
      72             :         {
      73          16 :             option_info::pointer_t opt(std::make_shared<option_info>("long-help"));
      74           8 :             opt->add_flag(GETOPT_FLAG_COMMAND_LINE
      75             :                         | GETOPT_FLAG_FLAG
      76             :                         | GETOPT_FLAG_GROUP_COMMANDS);
      77           8 :             opt->set_help("show all the help from all the available options.");
      78           8 :             f_options_by_name["long-help"] = opt;
      79           8 :             if(f_options_by_short_name.find(L'?') == f_options_by_short_name.end())
      80             :             {
      81           8 :                 opt->set_short_name(L'?');
      82           8 :                 f_options_by_short_name[L'?'] = opt;
      83             :             }
      84           8 :             break;
      85             :         }
      86             :     }
      87             : 
      88         355 :     if(f_options_environment.f_groups == nullptr)
      89             :     {
      90             :         // no groups, ignore following loop
      91             :         //
      92         321 :         return;
      93             :     }
      94             : 
      95         102 :     for(group_description const * grp = f_options_environment.f_groups
      96         102 :       ; grp->f_group != GETOPT_FLAG_GROUP_NONE
      97             :       ; ++grp)
      98             :     {
      99             :         // the name is not mandatory, without it you do not get the command
     100             :         // line option but still get the group description
     101             :         //
     102          68 :         if(grp->f_name != nullptr
     103           6 :         && *grp->f_name != '\0')
     104             :         {
     105          12 :             std::string const name(grp->f_name);
     106          12 :             std::string const option_name(name + "-help");
     107          12 :             option_info::pointer_t opt(std::make_shared<option_info>(option_name));
     108           6 :             opt->add_flag(GETOPT_FLAG_COMMAND_LINE
     109             :                         | GETOPT_FLAG_FLAG
     110             :                         | GETOPT_FLAG_GROUP_COMMANDS);
     111          12 :             opt->set_help("show help from the \""
     112          12 :                         + name
     113          18 :                         + "\" group of options.");
     114           6 :             f_options_by_name[option_name] = opt;
     115             :         }
     116             :     }
     117             : }
     118             : 
     119             : 
     120             : /** \brief Search for \p group in the list of group names.
     121             :  *
     122             :  * This function is used to search for the name of a group.
     123             :  *
     124             :  * Groups are used by the usage() function to list options by some user
     125             :  * selected group.
     126             :  *
     127             :  * For example, it is often that a tool has a set of commands such as
     128             :  * `--delete` and a set of options such as `--verbose`. These can represent
     129             :  * to clear groups of commands and options.
     130             :  *
     131             :  * \param[in] group  The group to look for (i.e. GETOPT_FLAG_GROUP_ONE).
     132             :  *
     133             :  * \return The group structure or nullptr when not found.
     134             :  */
     135          45 : group_description const * getopt::find_group(flag_t group) const
     136             : {
     137          45 :     if(f_options_environment.f_groups == nullptr)
     138             :     {
     139           2 :         return nullptr;
     140             :     }
     141             : 
     142          43 :     if((group & ~GETOPT_FLAG_GROUP_MASK) != 0)
     143             :     {
     144          29 :         throw getopt_logic_error("group parameter must represent a valid group.");
     145             :     }
     146          14 :     if(group == GETOPT_FLAG_GROUP_NONE)
     147             :     {
     148           1 :         throw getopt_logic_error("group NONE cannot be assigned a name so you cannot search for it.");
     149             :     }
     150             : 
     151          21 :     for(group_description const * grp(f_options_environment.f_groups)
     152          21 :       ; grp->f_group != GETOPT_FLAG_GROUP_NONE
     153             :       ; ++grp)
     154             :     {
     155          20 :         if(group == grp->f_group)
     156             :         {
     157          12 :             if((grp->f_name == nullptr || *grp->f_name == '\0')
     158           2 :             && (grp->f_description == nullptr || *grp->f_description == '\0'))
     159             :             {
     160           2 :                 throw getopt_logic_error("at least one of a group name or description must be defined (a non-empty string).");
     161             :             }
     162          10 :             return grp;
     163             :         }
     164             :     }
     165             : 
     166             :     // group not defined
     167             :     //
     168           1 :     return nullptr;
     169             : }
     170             : 
     171             : 
     172             : /** \brief Create a string of the command line arguments.
     173             :  *
     174             :  * This function assembles the command line arguments in a string and
     175             :  * returns that string.
     176             :  *
     177             :  * The function has the ability to wrap strings around for better formatting.
     178             :  *
     179             :  * The list of arguments to show is defined by the \p show parameter. When
     180             :  * \p show is 0, then only the regular and error arguments are shown.
     181             :  * Otherwise only the argumenst with the specified flags are show. Only
     182             :  * the `..._SHOW_...` flags are valid here.
     183             :  *
     184             :  * When an error occurs, it is customary to set \p show to
     185             :  * GETOPT_FLAG_SHOW_USAGE_ON_ERROR so only a limited set of arguments
     186             :  * are shown.
     187             :  *
     188             :  * The library offers two groups in case you have a command line tools
     189             :  * with a large number of options, those two can be used to only show
     190             :  * those specific set of options with using a specific `--help` argument.
     191             :  *
     192             :  * \note
     193             :  * This function does NOT print anything in the output. This is your
     194             :  * responsibility. We do it this way because you may be using a logger
     195             :  * and not want to print the usage in the \em wrong destination.
     196             :  *
     197             :  * \bug
     198             :  * The options are written from our map. This means the order will be
     199             :  * alphabetical and not the order in which you defined the options.
     200             :  * We are not looking into fixing this problem. That's just something
     201             :  * you want to keep in mind.
     202             :  *
     203             :  * \param[in] show  Selection of the options to show.
     204             :  *
     205             :  * \return The assembled command line arguments.
     206             :  */
     207          80 : std::string getopt::usage(flag_t show) const
     208             : {
     209         160 :     std::stringstream ss;
     210             : 
     211          80 :     flag_t specific_group(show & GETOPT_FLAG_GROUP_MASK);
     212             : 
     213             :     // ignore all the non-show flags
     214             :     //
     215          80 :     show &= GETOPT_FLAG_SHOW_USAGE_ON_ERROR
     216             :           | GETOPT_FLAG_SHOW_ALL
     217             :           | GETOPT_FLAG_SHOW_GROUP1
     218             :           | GETOPT_FLAG_SHOW_GROUP2;
     219             : 
     220          80 :     size_t const line_width(get_screen_width());
     221          80 :     ss << breakup_line(process_help_string(f_options_environment.f_help_header), 0, line_width);
     222             : 
     223         160 :     std::string save_default;
     224         160 :     std::string save_help;
     225             : 
     226          80 :     flag_t pos(GETOPT_FLAG_GROUP_MINIMUM);
     227          80 :     flag_t group_max(GETOPT_FLAG_GROUP_MAXIMUM);
     228          80 :     if(f_options_environment.f_groups == nullptr)
     229             :     {
     230          73 :         group_max = GETOPT_FLAG_GROUP_MINIMUM;
     231          73 :         specific_group = GETOPT_FLAG_GROUP_NONE;
     232             :     }
     233           7 :     else if(specific_group != GETOPT_FLAG_GROUP_NONE)
     234             :     {
     235             :         // only display that specific group if asked to do so
     236             :         //
     237           2 :         pos = specific_group >> GETOPT_FLAG_GROUP_SHIFT;
     238           2 :         group_max = pos;
     239             :     }
     240             : 
     241         310 :     for(; pos <= group_max; ++pos)
     242             :     {
     243         115 :         bool group_name_shown(false);
     244         115 :         flag_t const group(pos << GETOPT_FLAG_GROUP_SHIFT);
     245         891 :         for(auto const & opt : f_options_by_name)
     246             :         {
     247        1552 :             if((opt.second->get_flags() & GETOPT_FLAG_GROUP_MASK) != group
     248         776 :             && f_options_environment.f_groups != nullptr)
     249             :             {
     250             :                 // this could be optimized but we'd probably not see much
     251             :                 // difference overall and it's just for the usage() call
     252             :                 //
     253         507 :                 continue;
     254             :             }
     255             : 
     256         452 :             std::string const help(opt.second->get_help());
     257         269 :             if(help.empty())
     258             :             {
     259             :                 // ignore entries without help
     260             :                 //
     261          10 :                 continue;
     262             :             }
     263             : 
     264         259 :             if(opt.second->has_flag(GETOPT_FLAG_ALIAS))
     265             :             {
     266             :                 // ignore entries representing an alias
     267             :                 //
     268          12 :                 continue;
     269             :             }
     270             : 
     271         247 :             if((show & GETOPT_FLAG_SHOW_ALL) == 0)
     272             :             {
     273         186 :                 if(show != 0)
     274             :                 {
     275          66 :                     if(!opt.second->has_flag(show))
     276             :                     {
     277             :                         // usage selected group is not present in this option, ignore
     278             :                         //
     279          58 :                         continue;
     280             :                     }
     281             :                 }
     282         120 :                 else if(opt.second->has_flag(GETOPT_FLAG_SHOW_GROUP1 | GETOPT_FLAG_SHOW_GROUP2))
     283             :                 {
     284             :                     // do not show specialized groups
     285             :                     //
     286           6 :                     continue;
     287             :                 }
     288             :             }
     289             : 
     290         183 :             if(!group_name_shown)
     291             :             {
     292          85 :                 group_name_shown = true;
     293             : 
     294          85 :                 if(group != GETOPT_FLAG_GROUP_NONE)
     295             :                 {
     296           8 :                     group_description const * grp(find_group(group));
     297           8 :                     if(grp != nullptr)
     298             :                     {
     299           8 :                         ss << std::endl
     300           8 :                            << breakup_line(process_help_string(grp->f_description), 0, line_width);
     301             :                     }
     302             :                 }
     303             :             }
     304             : 
     305         366 :             std::stringstream argument;
     306             : 
     307         183 :             if(opt.second->is_default_option())
     308             :             {
     309           6 :                 switch(opt.second->get_flags() & (GETOPT_FLAG_REQUIRED | GETOPT_FLAG_MULTIPLE))
     310             :                 {
     311           1 :                 case 0:
     312           1 :                     argument << "[default argument]";
     313           1 :                     break;
     314             : 
     315           1 :                 case GETOPT_FLAG_REQUIRED:
     316           1 :                     argument << "<default argument>";
     317           1 :                     break;
     318             : 
     319           2 :                 case GETOPT_FLAG_MULTIPLE:
     320           2 :                     argument << "[default arguments]";
     321           2 :                     break;
     322             : 
     323           2 :                 case GETOPT_FLAG_REQUIRED | GETOPT_FLAG_MULTIPLE:
     324           2 :                     argument << "<default arguments>";
     325           2 :                     break;
     326             : 
     327             :                 }
     328             :             }
     329             :             else
     330             :             {
     331         177 :                 argument << "--" << opt.second->get_name();
     332         177 :                 if(opt.second->get_short_name() != NO_SHORT_NAME)
     333             :                 {
     334          49 :                     argument << " or -" << short_name_to_string(opt.second->get_short_name());
     335             :                 }
     336             : 
     337         177 :                 switch(opt.second->get_flags() & (GETOPT_FLAG_FLAG | GETOPT_FLAG_REQUIRED | GETOPT_FLAG_MULTIPLE))
     338             :                 {
     339           1 :                 case 0:
     340           1 :                     argument << " [<arg>]";
     341           1 :                     break;
     342             : 
     343          36 :                 case GETOPT_FLAG_REQUIRED:
     344          36 :                     argument << " <arg>";
     345          36 :                     break;
     346             : 
     347           8 :                 case GETOPT_FLAG_MULTIPLE:
     348           8 :                     argument << " {<arg>}";
     349           8 :                     break;
     350             : 
     351           6 :                 case GETOPT_FLAG_REQUIRED | GETOPT_FLAG_MULTIPLE:
     352           6 :                     argument << " <arg> {<arg>}";
     353           6 :                     break;
     354             : 
     355             :                 }
     356             :             }
     357             : 
     358         183 :             if(opt.second->has_default())
     359             :             {
     360             :                 argument << " (default is \""
     361           9 :                          << opt.second->get_default()
     362          18 :                          << "\")";
     363             :             }
     364             : 
     365             :             // Output argument string with help
     366             :             //
     367         183 :             if(opt.second->is_default_option())
     368             :             {
     369           6 :                 save_default = argument.str();
     370           6 :                 save_help = help;
     371             :             }
     372             :             else
     373             :             {
     374         354 :                 std::string variable_name;
     375         177 :                 if(!opt.second->get_environment_variable_name().empty())
     376             :                 {
     377           2 :                     variable_name += "\nEnvironment Variable Name: \"";
     378           2 :                     if(f_options_environment.f_environment_variable_intro != nullptr)
     379             :                     {
     380           2 :                         variable_name += f_options_environment.f_environment_variable_intro;
     381             :                     }
     382           2 :                     variable_name += opt.second->get_environment_variable_name();
     383           2 :                     variable_name += '"';
     384             :                 }
     385         354 :                 ss << format_usage_string(argument.str()
     386         354 :                                         , process_help_string((help + variable_name).c_str())
     387             :                                         , 30
     388             :                                         , line_width);
     389             :             }
     390             :         }
     391             :     }
     392             : 
     393          80 :     if(!save_default.empty())
     394             :     {
     395          12 :         ss << format_usage_string(save_default
     396          12 :                                 , process_help_string(save_help.c_str())
     397             :                                 , 30
     398             :                                 , line_width);
     399             :     }
     400             : 
     401          80 :     if(f_options_environment.f_help_footer != nullptr
     402          78 :     && f_options_environment.f_help_footer[0] != '\0')
     403             :     {
     404          78 :         ss << std::endl;
     405          78 :         ss << breakup_line(process_help_string(f_options_environment.f_help_footer), 0, line_width);
     406             :     }
     407             : 
     408         160 :     return ss.str();
     409             : }
     410             : 
     411             : 
     412             : /** \brief Change the % flags in help strings.
     413             :  *
     414             :  * This function goes through the help string and replaces the `%\<flag>`
     415             :  * with various content available in the getopt object.
     416             :  *
     417             :  * This is helpful for various reasons. For example, you may use the
     418             :  * same set of options in several different programs, in which case the
     419             :  * `%p` is likely useful to print out the name of the program currently
     420             :  * in use.
     421             :  *
     422             :  * Similarly we offer ways to print out lists of configuration files,
     423             :  * the environment variable name & value, etc. The following is the
     424             :  * list of supported flags:
     425             :  *
     426             :  * \li "%%" -- print out a percent
     427             :  * \li "%a" -- print out the project name (a.k.a. application name)
     428             :  * \li "%b" -- print out the build date
     429             :  * \li "%c" -- print out the copyright notice
     430             :  * \li "%d" -- print out the first directory with configuration files.
     431             :  * \li "%*d" -- print out the complete list of directories with configuration
     432             :  * files.
     433             :  * \li "%e" -- print out the name of the environment variable.
     434             :  * \li "%*e" -- print out the name and value of the environment variable.
     435             :  * \li "%f" -- print out the first configuration path and filename.
     436             :  * \li "%*f" -- print out all the configuration full paths.
     437             :  * \li "%g" -- print out the list of existing configuration files.
     438             :  * \li "%*g" -- print out the list of all possible configuration files.
     439             :  * \li "%i" -- print out the directory to option files.
     440             :  * \li "%l" -- print out the license.
     441             :  * \li "%o" -- show the configuration filename where changes get written.
     442             :  * \li "%p" -- print out the program basename.
     443             :  * \li "%*p" -- print out the full program name.
     444             :  * \li "%s" -- print out the group name.
     445             :  * \li "%t" -- print out the build time.
     446             :  * \li "%v" -- print out the version.
     447             :  * \li "%w" -- print out the list of all the writable configuration files.
     448             :  *
     449             :  * Here is an example where the `%p` can be used:
     450             :  *
     451             :  * \code
     452             :  *    "Usage: %p [-opt] filename ..."
     453             :  * \endcode
     454             :  *
     455             :  * The other flags are more often used in places like the copyright notice
     456             :  * the footer, the license notice, etc.
     457             :  *
     458             :  * \param[in] help  A string that may include `%` flags.
     459             :  *
     460             :  * \return The string with any '%\<flag>' replaced.
     461             :  *
     462             :  * \sa parse_program_name()
     463             :  */
     464         350 : std::string getopt::process_help_string(char const * help) const
     465             : {
     466         350 :     if(help == nullptr)
     467             :     {
     468           1 :         return std::string();
     469             :     }
     470             : 
     471         698 :     std::string result;
     472             : 
     473       41227 :     while(help[0] != '\0')
     474             :     {
     475       20439 :         if(help[0] == '%')
     476             :         {
     477         433 :             switch(help[1])
     478             :             {
     479          13 :             case '%':
     480          13 :                 result += '%';
     481          13 :                 help += 2;
     482          13 :                 break;
     483             : 
     484          98 :             case '*':
     485          98 :                 switch(help[2])
     486             :                 {
     487          19 :                 case 'd':
     488          19 :                     if(f_options_environment.f_configuration_directories != nullptr)
     489             :                     {
     490          16 :                         bool first(true);
     491          68 :                         for(char const * const * directories(f_options_environment.f_configuration_directories)
     492          68 :                           ; *directories != nullptr
     493             :                           ; ++directories)
     494             :                         {
     495          52 :                             if(first)
     496             :                             {
     497          13 :                                 first = false;
     498             :                             }
     499             :                             else
     500             :                             {
     501          39 :                                 result += ", ";
     502             :                             }
     503          52 :                             result += *directories;
     504             :                         }
     505             :                     }
     506          19 :                     help += 3;
     507          19 :                     break;
     508             : 
     509          28 :                 case 'e':
     510          28 :                     if(f_options_environment.f_environment_variable_name != nullptr
     511          22 :                     && *f_options_environment.f_environment_variable_name != '\0')
     512             :                     {
     513          16 :                         result += f_options_environment.f_environment_variable_name;
     514          16 :                         char const * env(getenv(f_options_environment.f_environment_variable_name));
     515          16 :                         if(env != nullptr)
     516             :                         {
     517           8 :                             result += '=';
     518           8 :                             result += env;
     519             :                         }
     520             :                         else
     521             :                         {
     522           8 :                             result += " (not set)";
     523             :                         }
     524             :                     }
     525          28 :                     help += 3;
     526          28 :                     break;
     527             : 
     528          19 :                 case 'f':
     529          19 :                     if(f_options_environment.f_configuration_files != nullptr)
     530             :                     {
     531          16 :                         bool first(true);
     532          68 :                         for(char const * const * filenames(f_options_environment.f_configuration_files)
     533          68 :                           ; *filenames != nullptr
     534             :                           ; ++filenames)
     535             :                         {
     536          52 :                             if(first)
     537             :                             {
     538          13 :                                 first = false;
     539             :                             }
     540             :                             else
     541             :                             {
     542          39 :                                 result += ", ";
     543             :                             }
     544          52 :                             result += *filenames;
     545             :                         }
     546             :                     }
     547          19 :                     help += 3;
     548          19 :                     break;
     549             : 
     550          19 :                 case 'g':
     551             :                     {
     552          38 :                         string_list_t list(get_configuration_filenames(false, false));
     553          19 :                         bool first(true);
     554         193 :                         for(auto n : list)
     555             :                         {
     556         174 :                             if(first)
     557             :                             {
     558          13 :                                 first = false;
     559             :                             }
     560             :                             else
     561             :                             {
     562         161 :                                 result += ", ";
     563             :                             }
     564         174 :                             result += n;
     565             :                         }
     566          38 :                         help += 3;
     567             :                     }
     568          19 :                     break;
     569             : 
     570          13 :                 case 'p':
     571          13 :                     result += f_program_fullname;
     572          13 :                     help += 3;
     573          13 :                     break;
     574             : 
     575             :                 }
     576          98 :                 break;
     577             : 
     578          19 :             case 'a':
     579          19 :                 if(f_options_environment.f_project_name != nullptr)
     580             :                 {
     581          16 :                     result += f_options_environment.f_project_name;
     582             :                 }
     583          19 :                 help += 2;
     584          19 :                 break;
     585             : 
     586          19 :             case 'b':
     587          19 :                 if(f_options_environment.f_build_date != nullptr)
     588             :                 {
     589          16 :                     result += f_options_environment.f_build_date;
     590             :                 }
     591          19 :                 help += 2;
     592          19 :                 break;
     593             : 
     594          19 :             case 'c':
     595          19 :                 if(f_options_environment.f_copyright != nullptr)
     596             :                 {
     597          16 :                     result += f_options_environment.f_copyright;
     598             :                 }
     599          19 :                 help += 2;
     600          19 :                 break;
     601             : 
     602          19 :             case 'd':
     603          19 :                 if(f_options_environment.f_configuration_directories != nullptr
     604          16 :                 && *f_options_environment.f_configuration_directories != nullptr)
     605             :                 {
     606          13 :                     result += *f_options_environment.f_configuration_directories;
     607             :                 }
     608          19 :                 help += 2;
     609          19 :                 break;
     610             : 
     611          28 :             case 'e':
     612          28 :                 if(f_options_environment.f_environment_variable_name != nullptr)
     613             :                 {
     614          22 :                     result += f_options_environment.f_environment_variable_name;
     615             :                 }
     616          28 :                 help += 2;
     617          28 :                 break;
     618             : 
     619          13 :             case 'E':
     620          13 :                 if(f_options_environment.f_environment_variable_intro != nullptr)
     621             :                 {
     622          10 :                     result += f_options_environment.f_environment_variable_intro;
     623             :                 }
     624          13 :                 help += 2;
     625          13 :                 break;
     626             : 
     627          19 :             case 'f':
     628          19 :                 if(f_options_environment.f_configuration_files != nullptr
     629          16 :                 && *f_options_environment.f_configuration_files != nullptr)
     630             :                 {
     631          13 :                     result += *f_options_environment.f_configuration_files;
     632             :                 }
     633          19 :                 help += 2;
     634          19 :                 break;
     635             : 
     636          22 :             case 'g':
     637             :                 {
     638          44 :                     string_list_t list(get_configuration_filenames(true, false));
     639          22 :                     bool first(true);
     640          34 :                     for(auto n : list)
     641             :                     {
     642          12 :                         if(first)
     643             :                         {
     644           6 :                             first = false;
     645             :                         }
     646             :                         else
     647             :                         {
     648           6 :                             result += ", ";
     649             :                         }
     650          12 :                         result += n;
     651             :                     }
     652          44 :                     help += 2;
     653             :                 }
     654          22 :                 break;
     655             : 
     656          19 :             case 'i':
     657             :                 // in the advgetopt_options.cpp, we clearly add a final "/"
     658             :                 // so we want to add it here too, to be consistent
     659             :                 {
     660          38 :                     std::string directory("/usr/share/advgetopt/options/");
     661          19 :                     if(f_options_environment.f_options_files_directory != nullptr
     662          16 :                     && *f_options_environment.f_options_files_directory != '\0')
     663             :                     {
     664          13 :                         directory = f_options_environment.f_options_files_directory;
     665          13 :                         if(directory.back() != '/')
     666             :                         {
     667          13 :                             directory += '/';
     668             :                         }
     669             :                     }
     670          38 :                     result += directory;
     671             :                 }
     672          19 :                 help += 2;
     673          19 :                 break;
     674             : 
     675          19 :             case 'l':
     676          19 :                 if(f_options_environment.f_license != nullptr)
     677             :                 {
     678          16 :                     result += f_options_environment.f_license;
     679             :                 }
     680          19 :                 help += 2;
     681          19 :                 break;
     682             : 
     683          10 :             case 'm':
     684          10 :                 if(f_options_environment.f_section_variables_name != nullptr)
     685             :                 {
     686           5 :                     result += f_options_environment.f_section_variables_name;
     687             :                 }
     688          10 :                 help += 2;
     689          10 :                 break;
     690             : 
     691          19 :             case 'o':
     692             :                 {
     693          38 :                     string_list_t const list(get_configuration_filenames(false, true));
     694          19 :                     if(!list.empty())
     695             :                     {
     696          13 :                         result += list.back();
     697             :                     }
     698          38 :                     help += 2;
     699             :                 }
     700          19 :                 break;
     701             : 
     702          32 :             case 'p':
     703          32 :                 result += f_program_name;
     704          32 :                 help += 2;
     705          32 :                 break;
     706             : 
     707           5 :             case 's':
     708           5 :                 if(f_options_environment.f_group_name != nullptr)
     709             :                 {
     710           5 :                     result += f_options_environment.f_group_name;
     711             :                 }
     712           5 :                 help += 2;
     713           5 :                 break;
     714             : 
     715          19 :             case 't':
     716          19 :                 if(f_options_environment.f_build_time != nullptr)
     717             :                 {
     718          16 :                     result += f_options_environment.f_build_time;
     719             :                 }
     720          19 :                 help += 2;
     721          19 :                 break;
     722             : 
     723          19 :             case 'v':
     724          19 :                 if(f_options_environment.f_version != nullptr)
     725             :                 {
     726          16 :                     result += f_options_environment.f_version;
     727             :                 }
     728          19 :                 help += 2;
     729          19 :                 break;
     730             : 
     731          22 :             case 'w':
     732             :                 {
     733          44 :                     string_list_t const list(get_configuration_filenames(true, true));
     734          22 :                     bool first(true);
     735          31 :                     for(auto n : list)
     736             :                     {
     737           9 :                         if(first)
     738             :                         {
     739           6 :                             first = false;
     740             :                         }
     741             :                         else
     742             :                         {
     743           3 :                             result += ", ";
     744             :                         }
     745           9 :                         result += n;
     746             :                     }
     747          44 :                     help += 2;
     748             :                 }
     749          22 :                 break;
     750             : 
     751             :             }
     752             :         }
     753             :         else
     754             :         {
     755       20006 :             result += help[0];
     756       20006 :             ++help;
     757             :         }
     758             :     }
     759             : 
     760         349 :     return result;
     761             : }
     762             : 
     763             : 
     764             : 
     765             : 
     766           6 : } // namespace advgetopt
     767             : // vim: ts=4 sw=4 et

Generated by: LCOV version 1.13