VideoTools
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
goptions.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2017 Graeme Walker
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 goptions.h
19 ///
20 
21 #ifndef G_OPTIONS_H
22 #define G_OPTIONS_H
23 
24 #include "gdef.h"
25 #include "gstrings.h"
26 #include "gexception.h"
27 #include <string>
28 #include <map>
29 
30 namespace G
31 {
32  class Options ;
33  class OptionsLevel ;
34  class OptionsLayout ;
35 }
36 
37 /// \class G::OptionsLevel
38 /// Used by G::Options for extra type safety.
39 ///
41 {
42 public:
43  unsigned int level ;
44  explicit OptionsLevel( unsigned int ) ;
45 } ;
46 
47 /// \class G::OptionsLayout
48 /// Describes the layout for G::Options output.
49 ///
51 {
52 public:
53  std::string separator ; ///< separator between columns for two-column output
54  std::string indent ; ///< indent for wrapped lines in two-column output
55  size_t column ; ///< left hand column width if no separator defined
56  size_t width ; ///< overall width for wrapping, or zero for no newlines
57  explicit OptionsLayout( size_t column ) ;
58  OptionsLayout( size_t column , size_t width ) ;
59 } ;
60 
61 /// \class G::Options
62 /// A class to represent allowed command-line options and to provide command-line
63 /// usage text.
64 ///
66 {
67 public:
68  typedef OptionsLevel Level ;
69  typedef OptionsLayout Layout ;
70  G_EXCEPTION( InvalidSpecification , "invalid options specification string" ) ;
71 
72  explicit Options( const std::string & spec , char sep_major = '|' , char sep_minor = '!' , char escape = '^' ) ;
73  ///< Constructor taking a specification string.
74  ///<
75  ///< Uses specifications like "p!port!defines the port number!!1!port!1|v!verbose!shows more logging!!0!!1"
76  ///< made up of (1) an optional single-character-option-letter, (2) a multi-character-option-name
77  ///< (3) an option-description, (4) optional option-description-extra text, (5) a value-type
78  ///< (with 0 for unvalued, 1 for a string value, and 2 for a comma-separated list (possibly
79  ///< multiple times)) or (6) a value-description (unless unvalued), and (7) a level enumeration.
80  ///<
81  ///< By convention mainstream options should have a level of 1, and obscure ones level 2 and above.
82  ///< If the option-description field is empty or if the level is zero then the option is hidden.
83 
84  Options() ;
85  ///< Default constructor for no options.
86 
87  const StringArray & names() const ;
88  ///< Returns the sorted list of long-form option names.
89 
90  std::string lookup( char c ) const ;
91  ///< Converts from short-form option character to the corresponding
92  ///< long-form name. Returns the empty string if none.
93 
94  bool valid( const std::string & ) const ;
95  ///< Returns true if the long-form option name is valid.
96 
97  bool visible( const std::string & name , Level , bool exact ) const ;
98  ///< Returns true if the option is visible at the given level.
99  ///< Returns false if not valid().
100 
101  bool valued( char ) const ;
102  ///< Returns true if the short-form option character is valid.
103  ///< Returns false if not valid().
104 
105  bool valued( const std::string & ) const ;
106  ///< Returns true if the long-form option name is valid.
107  ///< Returns false if not valid().
108 
109  bool multivalued( char ) const ;
110  ///< Returns true if the short-form option can have multiple values.
111  ///< Returns false if not valid().
112 
113  bool multivalued( const std::string & ) const ;
114  ///< Returns true if the long-form option can have multiple values.
115  ///< Returns false if not valid().
116 
117  bool unvalued( const std::string & option_name ) const ;
118  ///< Returns true if the given option name is valid and
119  ///< takes no value. Returns false if not valid().
120 
121  static size_t widthDefault() ;
122  ///< Returns a default, non-zero word-wrapping width, reflecting
123  ///< the size of the standard output where possible.
124 
125  static Layout layoutDefault() ;
126  ///< Returns a default column layout.
127 
128  static Level levelDefault() ;
129  ///< Returns the default level.
130 
131  static std::string introducerDefault() ;
132  ///< Returns the string "usage: ".
133 
134  std::string usageSummary( const std::string & exe , const std::string & args ,
135  const std::string & introducer = introducerDefault() ,
136  Level level = levelDefault() , size_t wrap_width = widthDefault() ) const ;
137  ///< Returns a one-line (or line-wrapped) usage summary, as
138  ///< "usage: <exe> <options> <args>"
139 
140  std::string usageHelp( Level level = levelDefault() ,
141  Layout layout = layoutDefault() , bool level_exact = false , bool extra = true ) const ;
142  ///< Returns a multi-line string giving help on each option.
143 
144  void showUsage( std::ostream & stream , const std::string & exe ,
145  const std::string & args = std::string() , const std::string & introducer = introducerDefault() ,
146  Level level = levelDefault() , Layout layout = layoutDefault() ,
147  bool extra = true ) const ;
148  ///< Streams out multi-line usage text using usageSummary() and
149  ///< usageHelp(). The 'args' parameter should represent the non-option
150  ///< arguments (with a leading space), like " <foo> [<bar>]".
151 
152 private:
153  struct Option
154  {
155  char c ;
156  std::string name ;
157  std::string description ;
158  std::string description_extra ;
159  unsigned int value_multiplicity ; // 0,1,2 (unvalued, single-valued, multi-valued)
160  bool hidden ;
161  std::string value_description ;
162  unsigned int level ;
163 
164  Option( char c_ , const std::string & name_ , const std::string & description_ ,
165  const std::string & description_extra_ , unsigned int value_multiplicity_ ,
166  const std::string & vd_ , unsigned int level_ ) ;
167  } ;
168 
169 private:
170  void parseSpec( const std::string & spec , char , char , char ) ;
171  void addSpec( const std::string & , char c , const std::string & , const std::string & ,
172  unsigned int , const std::string & , unsigned int ) ;
173  static size_t widthFloor( size_t w ) ;
174  std::string usageSummaryPartOne( Level ) const ;
175  std::string usageSummaryPartTwo( Level ) const ;
176  std::string usageHelpCore( const std::string & , Level , Layout , bool , bool ) const ;
177 
178 private:
179  typedef std::map<std::string,Option> Map ;
180  StringArray m_names ;
181  Map m_map ;
182 } ;
183 
184 inline
185 G::OptionsLevel::OptionsLevel( unsigned int l ) :
186  level(l)
187 {
188 }
189 
190 inline
191 G::OptionsLayout::OptionsLayout( size_t column_ ) :
192  column(column_) ,
193  width(G::Options::widthDefault())
194 {
195 }
196 
197 inline
198 G::OptionsLayout::OptionsLayout( size_t column_ , size_t width_ ) :
199  column(column_) ,
200  width(width_)
201 {
202 }
203 
204 #endif
bool valid(const std::string &) const
Returns true if the long-form option name is valid.
Definition: goptions.cpp:121
bool unvalued(const std::string &option_name) const
Returns true if the given option name is valid and takes no value.
Definition: goptions.cpp:95
static Level levelDefault()
Returns the default level.
Definition: goptions.cpp:169
Describes the layout for G::Options output.
Definition: goptions.h:50
bool multivalued(char) const
Returns true if the short-form option can have multiple values.
Definition: goptions.cpp:100
std::vector< std::string > StringArray
A std::vector of std::strings.
Definition: gstrings.h:33
static size_t widthDefault()
Returns a default, non-zero word-wrapping width, reflecting the size of the standard output where pos...
Definition: goptions.cpp:143
Used by G::Options for extra type safety.
Definition: goptions.h:40
std::string usageHelp(Level level=levelDefault(), Layout layout=layoutDefault(), bool level_exact=false, bool extra=true) const
Returns a multi-line string giving help on each option.
Definition: goptions.cpp:228
std::string lookup(char c) const
Converts from short-form option character to the corresponding long-form name.
Definition: goptions.cpp:126
static std::string introducerDefault()
Returns the string "usage: ".
Definition: goptions.cpp:164
std::string usageSummary(const std::string &exe, const std::string &args, const std::string &introducer=introducerDefault(), Level level=levelDefault(), size_t wrap_width=widthDefault()) const
Returns a one-line (or line-wrapped) usage summary, as "usage: <exe> <options> <args>".
Definition: goptions.cpp:300
static Layout layoutDefault()
Returns a default column layout.
Definition: goptions.cpp:159
std::string separator
separator between columns for two-column output
Definition: goptions.h:53
size_t width
overall width for wrapping, or zero for no newlines
Definition: goptions.h:56
bool valued(char) const
Returns true if the short-form option character is valid.
Definition: goptions.cpp:84
size_t column
left hand column width if no separator defined
Definition: goptions.h:55
bool visible(const std::string &name, Level, bool exact) const
Returns true if the option is visible at the given level.
Definition: goptions.cpp:111
const StringArray & names() const
Returns the sorted list of long-form option names.
Definition: goptions.cpp:136
std::string indent
indent for wrapped lines in two-column output
Definition: goptions.h:54
Options()
Default constructor for no options.
Definition: goptions.cpp:29
A class to represent allowed command-line options and to provide command-line usage text...
Definition: goptions.h:65
void showUsage(std::ostream &stream, const std::string &exe, const std::string &args=std::string(), const std::string &introducer=introducerDefault(), Level level=levelDefault(), Layout layout=layoutDefault(), bool extra=true) const
Streams out multi-line usage text using usageSummary() and usageHelp().
Definition: goptions.cpp:292