E-MailRelay

goptionsusage.h
Go to the documentation of this file.
1//
2// Copyright (C) 2001-2024 Graeme Walker <graeme_walker@users.sourceforge.net>
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program. If not, see <http://www.gnu.org/licenses/>.
16// ===
17///
18/// \file goptionsusage.h
19///
20
21#ifndef G_OPTIONS_USAGE_H
22#define G_OPTIONS_USAGE_H
23
24#include "gdef.h"
25#include "goptions.h"
26#include <functional>
27#include <string>
28#include <vector>
29
30 namespace G
31{
32 class OptionsUsage ;
33}
34
35//| \class G::OptionsUsage
36/// Provides help text for a set of options.
37///
38/// If configured with a fixed separator the help() text is
39/// formatted as:
40/// \code
41/// <margin><syntax><separator><detail-to-width1>
42/// <margin><separator-spaces><more-detail-to-width2>
43/// \endcode
44///
45/// Or with a tab separator:
46/// \code
47/// <margin><syntax><TAB><detail-to-width1>
48/// <margin><TAB><more-detail-to-width2>
49/// \endcode
50///
51/// Or with a two-column layout:
52/// \code
53/// <margin><syntax><spaces-to-column><detail-to-width1>
54/// <margin><spaces-to-column><more-detail-to-width2>
55/// \endcode
56///
57/// Or two-column layout in 'overflow' mode:
58/// \code
59/// <margin><syntax>
60/// <margin><overflow-spaces><detail-to-width2>
61/// <margin><overflow-spaces><more-detail-to-width2>
62/// \endcode
63///
64 class G::OptionsUsage
65{
66 public:
67 struct Config /// A configuration structure for G::OptionsUsage.
68 {
69 static constexpr std::size_t default_ = static_cast<std::size_t>(-1) ;
70
71 std::string separator ; ///< separator between syntax and description
72 std::size_t separator_spaces {1U} ; ///< extra spaces on wrapped lines if using a separator
73 std::size_t column {30U} ; ///< left hand column width if no separator (includes margin)
74 std::size_t width {default_} ; ///< overall width for wrapping, or zero for none, defaults to $COLUMNS
75 std::size_t width2 {0U} ; ///< width after the first line, or zero for 'width'
76 std::size_t margin {2U} ; ///< spaces added to the left
77 std::size_t overflow {20U} ; ///< use 'overflow' format if rhs is squashed down to this
78 std::size_t overflow_spaces {1U} ; ///< 'overflow' format extra spaces on wrapped lines
79
80 bool extra {false} ; ///< include descriptions' extra text
81 bool alt_usage {false} ; ///< use alternate "usage:" string
82
83 unsigned int level_max {99U} ; ///< show options at-or-below this level
84 unsigned int level_min {1U} ; ///< .. and at-or-above this level
85 unsigned int main_tag {0U} ; ///< show options with this main tag, or zero for all
86 unsigned int tag_bits {0U} ; ///< show options with matching tag bits, or zero for all
87
88 Config & set_separator( const std::string & ) ;
89 Config & set_column( std::size_t ) noexcept ;
90 Config & set_width( std::size_t ) noexcept ;
91 Config & set_width2( std::size_t ) noexcept ;
92 Config & set_margin( std::size_t ) noexcept ;
93 Config & set_extra( bool = true ) noexcept ;
94 Config & set_alt_usage( bool = true ) noexcept ;
95
96 Config & set_level_max( unsigned int ) noexcept ;
97 Config & set_level_min( unsigned int ) noexcept ;
98 Config & set_main_tag( unsigned int ) noexcept ;
99 Config & set_tag_bits( unsigned int ) noexcept ;
100 Config & setDefaults() ;
101 Config & setWidthsWrtMargin() ;
102 Config & setOverflowFormat( char = ' ' ) ;
103 } ;
104
105 using SortFn = std::function<bool(const Option&,const Option&)> ;
106
107 explicit OptionsUsage( const std::vector<Option> & , SortFn = sort() ) ;
108 ///< Constructor.
109
110 std::string summary( const Config & , const std::string & exe ,
111 const std::string & args = {} ) const ;
112 ///< Returns a one-line (or line-wrapped) usage summary, as
113 ///< "usage: <exe> <options> <args>". The 'args' parameter
114 ///< should represent the non-option arguments (with a
115 ///< leading space), like " <foo> [<bar>]".
116 ///<
117 ///< Eg:
118 ///< \code
119 ///< std::cout << usage.summary(
120 ///< OptionsUsage::Config().set_level_max(verbose?1U:99U).set_extra(verbose) ,
121 ///< getopt.args().prefix() , " <arg> [<arg> ...]" ) << std::endl ;
122 ///< \endcode
123
124 std::string help( const Config & , bool * overflow_p = nullptr ) const ;
125 ///< Returns a multi-line string giving help on each option.
126 ///< Use the optional overflow flag if using help() for separate
127 ///< sections that should have the same layout: initialise to
128 ///< false, call help() for each section and discard the result,
129 ///< then call help() again for each section.
130
131 void output( const Config & , std::ostream & stream ,
132 const std::string & exe , const std::string & args = {} ) const ;
133 ///< Streams out multi-line usage text using summary() and
134 ///< help().
135
136 static SortFn sort() ;
137 ///< Returns the default sort function that sorts by level first
138 ///< and then by name.
139
140 private:
141 std::string summaryPartOne( const Config & ) const ;
142 std::string summaryPartTwo( const Config & ) const ;
143 std::string helpSyntax( const Option & , bool = false , char = '\0' ) const ;
144 std::string helpDescription( const Option & , bool ) const ;
145 std::string helpSeparator( const Config & , std::size_t syntax_length ) const ;
146 std::string helpPadding( const Config & ) const ;
147 std::string helpImp( const Config & , bool , bool & ) const ;
148 std::string optionHelp( const Config & , const Option & option , bool , bool & ) const ;
149 std::string helpWrap( const Config & , const std::string & syntax_simple ,
150 const std::string & syntax_aligned , const std::string & separator ,
151 const std::string & description , bool , bool & ) const ;
152 static Config setDefaults( const Config & ) ;
153 static Config setWidthsWrtMargin( const Config & ) ;
154
155 private:
156 std::vector<Option> m_options ;
157 char m_space_margin {' '} ;
158 char m_space_separator {' '} ;
159 char m_space_indent {' '} ;
160 char m_space_padding {' '} ;
161 char m_space_overflow {' '} ;
162 char m_space_syntax {' '} ;
163} ;
164
165 inline G::OptionsUsage::Config & G::OptionsUsage::Config::set_separator( const std::string & s ) { separator = s ; return *this ; }
166 inline G::OptionsUsage::Config & G::OptionsUsage::Config::set_column( std::size_t n ) noexcept { column = n ; return *this ; }
167 inline G::OptionsUsage::Config & G::OptionsUsage::Config::set_width( std::size_t n ) noexcept { width = n ; return *this ; }
168 inline G::OptionsUsage::Config & G::OptionsUsage::Config::set_width2( std::size_t n ) noexcept { width2 = n ; return *this ; }
169 inline G::OptionsUsage::Config & G::OptionsUsage::Config::set_margin( std::size_t n ) noexcept { margin = n ; return *this ; }
170 inline G::OptionsUsage::Config & G::OptionsUsage::Config::set_extra( bool b ) noexcept { extra = b ; return *this ; }
171 inline G::OptionsUsage::Config & G::OptionsUsage::Config::set_alt_usage( bool b ) noexcept { alt_usage = b ; return *this ; }
172 inline G::OptionsUsage::Config & G::OptionsUsage::Config::set_level_max( unsigned int n ) noexcept { level_max = n ; return *this ; }
173 inline G::OptionsUsage::Config & G::OptionsUsage::Config::set_level_min( unsigned int n ) noexcept { level_min = n ; return *this ; }
174 inline G::OptionsUsage::Config & G::OptionsUsage::Config::set_main_tag( unsigned int n ) noexcept { main_tag = n ; return *this ; }
175 inline G::OptionsUsage::Config & G::OptionsUsage::Config::set_tag_bits( unsigned int n ) noexcept { tag_bits = n ; return *this ; }
176
177#endif
G::OptionsUsage
Provides help text for a set of options.
Definition: goptionsusage.h:65
G::OptionsUsage::sort
static SortFn sort()
Returns the default sort function that sorts by level first and then by name.
Definition: goptionsusage.cpp:288
G::OptionsUsage::summary
std::string summary(const Config &, const std::string &exe, const std::string &args={}) const
Returns a one-line (or line-wrapped) usage summary, as "usage: <exe> <options> <args>".
Definition: goptionsusage.cpp:49
G::OptionsUsage::output
void output(const Config &, std::ostream &stream, const std::string &exe, const std::string &args={}) const
Streams out multi-line usage text using summary() and help().
Definition: goptionsusage.cpp:90
G::OptionsUsage::help
std::string help(const Config &, bool *overflow_p=nullptr) const
Returns a multi-line string giving help on each option.
Definition: goptionsusage.cpp:69
goptions.h
G
Low-level classes.
Definition: garg.h:36
std
STL namespace.
G::Option
A structure representing a G::Options command-line option.
Definition: goption.h:38
G::OptionsUsage::Config
A configuration structure for G::OptionsUsage.
Definition: goptionsusage.h:68
G::OptionsUsage::Config::alt_usage
bool alt_usage
use alternate "usage:" string
Definition: goptionsusage.h:81
G::OptionsUsage::Config::overflow_spaces
std::size_t overflow_spaces
'overflow' format extra spaces on wrapped lines
Definition: goptionsusage.h:78
G::OptionsUsage::Config::width
std::size_t width
overall width for wrapping, or zero for none, defaults to $COLUMNS
Definition: goptionsusage.h:74
G::OptionsUsage::Config::level_max
unsigned int level_max
show options at-or-below this level
Definition: goptionsusage.h:83
G::OptionsUsage::Config::level_min
unsigned int level_min
.. and at-or-above this level
Definition: goptionsusage.h:84
G::OptionsUsage::Config::separator_spaces
std::size_t separator_spaces
extra spaces on wrapped lines if using a separator
Definition: goptionsusage.h:72
G::OptionsUsage::Config::overflow
std::size_t overflow
use 'overflow' format if rhs is squashed down to this
Definition: goptionsusage.h:77
G::OptionsUsage::Config::separator
std::string separator
separator between syntax and description
Definition: goptionsusage.h:71
G::OptionsUsage::Config::tag_bits
unsigned int tag_bits
show options with matching tag bits, or zero for all
Definition: goptionsusage.h:86
G::OptionsUsage::Config::margin
std::size_t margin
spaces added to the left
Definition: goptionsusage.h:76
G::OptionsUsage::Config::main_tag
unsigned int main_tag
show options with this main tag, or zero for all
Definition: goptionsusage.h:85
G::OptionsUsage::Config::extra
bool extra
include descriptions' extra text
Definition: goptionsusage.h:80
G::OptionsUsage::Config::column
std::size_t column
left hand column width if no separator (includes margin)
Definition: goptionsusage.h:73
G::OptionsUsage::Config::width2
std::size_t width2
width after the first line, or zero for 'width'
Definition: goptionsusage.h:75