Commit 84cfcc185bafc66089214a140b5a8522a9d9e4e8

Authored by Henry Fredrick Schreiner
1 parent a8f5b328

Adding nicer docs

Showing 1 changed file with 141 additions and 118 deletions
include/CLI/Option.hpp
@@ -116,6 +116,18 @@ protected: @@ -116,6 +116,18 @@ protected:
116 116
117 public: 117 public:
118 118
  119 + /// @name Basic
  120 + ///@{
  121 +
  122 + /// Count the total number of times an option was passed
  123 + int count() const {
  124 + int out = 0;
  125 + for(const std::vector<std::string>& vec : results_)
  126 + out += vec.size();
  127 + return out;
  128 + }
  129 +
  130 +
119 /// This class is true if option is passed. 131 /// This class is true if option is passed.
120 operator bool() const { 132 operator bool() const {
121 return results_.size() > 0; 133 return results_.size() > 0;
@@ -126,6 +138,10 @@ public: @@ -126,6 +138,10 @@ public:
126 results_.clear(); 138 results_.clear();
127 } 139 }
128 140
  141 + ///@}
  142 + /// @name Configuration
  143 + ///@{
  144 +
129 /// Set the option as required 145 /// Set the option as required
130 Option* required(bool value = true) { 146 Option* required(bool value = true) {
131 required_ = value; 147 required_ = value;
@@ -137,11 +153,6 @@ public: @@ -137,11 +153,6 @@ public:
137 return required(value); 153 return required(value);
138 } 154 }
139 155
140 - /// True if this is a required option  
141 - bool get_required() const {  
142 - return required_;  
143 - }  
144 -  
145 /// Set the number of expected arguments (Flags bypass this) 156 /// Set the number of expected arguments (Flags bypass this)
146 Option* expected(int value) { 157 Option* expected(int value) {
147 if(value == 0) 158 if(value == 0)
@@ -152,31 +163,6 @@ public: @@ -152,31 +163,6 @@ public:
152 return this; 163 return this;
153 } 164 }
154 165
155 - /// The number of arguments the option expects  
156 - int get_expected() const {  
157 - return expected_;  
158 - }  
159 -  
160 - /// True if this has a default value  
161 - int get_default() const {  
162 - return default_;  
163 - }  
164 -  
165 - /// True if the argument can be given directly  
166 - bool get_positional() const {  
167 - return pname_.length() > 0;  
168 - }  
169 -  
170 - /// True if option has at least one non-positional name  
171 - bool nonpositional() const {  
172 - return (snames_.size() + lnames_.size()) > 0;  
173 - }  
174 -  
175 - /// True if option has description  
176 - bool has_description() const {  
177 - return description_.length() > 0;  
178 - }  
179 -  
180 /// Adds a validator 166 /// Adds a validator
181 Option* check(std::function<bool(std::string)> validator) { 167 Option* check(std::function<bool(std::string)> validator) {
182 168
@@ -190,15 +176,6 @@ public: @@ -190,15 +176,6 @@ public:
190 return this; 176 return this;
191 } 177 }
192 178
193 - /// Get the group of this option  
194 - const std::string& get_group() const {  
195 - return group_;  
196 - }  
197 -  
198 - /// Get the description  
199 - const std::string& get_description() const {  
200 - return description_;  
201 - }  
202 179
203 /// Sets required options 180 /// Sets required options
204 Option* requires(Option* opt) { 181 Option* requires(Option* opt) {
@@ -236,6 +213,84 @@ public: @@ -236,6 +213,84 @@ public:
236 return this; 213 return this;
237 } 214 }
238 215
  216 + /// Ignore case
  217 + ///
  218 + /// The template hides the fact that we don't have the definition of App yet.
  219 + /// You are never expected to add an argument to the template here.
  220 + template<typename T=App>
  221 + Option* ignore_case(bool value = true) {
  222 + ignore_case_ = value;
  223 + for(const Option_p& opt : dynamic_cast<T*>(parent_)->options_)
  224 + if(opt.get() != this && *opt == *this)
  225 + throw OptionAlreadyAdded(opt->get_name());
  226 + return this;
  227 + }
  228 +
  229 + ///@}
  230 + /// @name Accessors
  231 + ///@{
  232 +
  233 + /// True if this is a required option
  234 + bool get_required() const {
  235 + return required_;
  236 + }
  237 +
  238 + /// The number of arguments the option expects
  239 + int get_expected() const {
  240 + return expected_;
  241 + }
  242 +
  243 + /// True if this has a default value
  244 + int get_default() const {
  245 + return default_;
  246 + }
  247 +
  248 + /// True if the argument can be given directly
  249 + bool get_positional() const {
  250 + return pname_.length() > 0;
  251 + }
  252 +
  253 + /// True if option has at least one non-positional name
  254 + bool nonpositional() const {
  255 + return (snames_.size() + lnames_.size()) > 0;
  256 + }
  257 +
  258 + /// True if option has description
  259 + bool has_description() const {
  260 + return description_.length() > 0;
  261 + }
  262 +
  263 + /// Get the group of this option
  264 + const std::string& get_group() const {
  265 + return group_;
  266 + }
  267 +
  268 + /// Get the description
  269 + const std::string& get_description() const {
  270 + return description_;
  271 + }
  272 +
  273 + // Just the pname
  274 + std::string get_pname() const {
  275 + return pname_;
  276 + }
  277 +
  278 + ///@}
  279 + /// @name Help
  280 + ///@{
  281 +
  282 + /// Gets a , sep list of names. Does not include the positional name if opt_only=true.
  283 + std::string get_name(bool opt_only=false) const {
  284 + std::vector<std::string> name_list;
  285 + if(!opt_only && pname_.length() > 0)
  286 + name_list.push_back(pname_);
  287 + for(const std::string& sname : snames_)
  288 + name_list.push_back("-"+sname);
  289 + for(const std::string& lname : lnames_)
  290 + name_list.push_back("--"+lname);
  291 + return detail::join(name_list);
  292 + }
  293 +
239 /// The name and any extras needed for positionals 294 /// The name and any extras needed for positionals
240 std::string help_positional() const { 295 std::string help_positional() const {
241 std::string out = pname_; 296 std::string out = pname_;
@@ -247,12 +302,54 @@ public: @@ -247,12 +302,54 @@ public:
247 return out; 302 return out;
248 } 303 }
249 304
250 - // Just the pname  
251 - std::string get_pname() const {  
252 - return pname_; 305 + /// The first half of the help print, name plus default, etc
  306 + std::string help_name() const {
  307 + std::stringstream out;
  308 + out << get_name(true) << help_aftername();
  309 + return out.str();
  310 + }
  311 +
  312 + /// pname with type info
  313 + std::string help_pname() const {
  314 + std::stringstream out;
  315 + out << get_pname() << help_aftername();
  316 + return out.str();
253 } 317 }
254 318
  319 + /// This is the part after the name is printed but before the description
  320 + std::string help_aftername() const {
  321 + std::stringstream out;
255 322
  323 + if(get_expected() != 0) {
  324 + if(typeval_ != "")
  325 + out << " " << typeval_;
  326 + if(defaultval_ != "")
  327 + out << "=" << defaultval_;
  328 + if(get_expected() > 1)
  329 + out << " x " << get_expected();
  330 + if(get_expected() == -1)
  331 + out << " ...";
  332 + }
  333 + if(envname_ != "")
  334 + out << " (env:" << envname_ << ")";
  335 + if(requires_.size() > 0) {
  336 + out << " Requires:";
  337 + for(const Option* opt : requires_)
  338 + out << " " << opt->get_name();
  339 + }
  340 + if(excludes_.size() > 0) {
  341 + out << " Excludes:";
  342 + for(const Option* opt : excludes_)
  343 + out << " " << opt->get_name();
  344 + }
  345 + return out.str();
  346 +
  347 + }
  348 +
  349 + ///@}
  350 + /// @name Parser tools
  351 + ///@{
  352 +
256 /// Process the callback 353 /// Process the callback
257 void run_callback() const { 354 void run_callback() const {
258 if(!callback_(results_)) 355 if(!callback_(results_))
@@ -283,31 +380,6 @@ public: @@ -283,31 +380,6 @@ public:
283 return false; 380 return false;
284 } 381 }
285 382
286 - /// Gets a , sep list of names. Does not include the positional name if opt_only=true.  
287 - std::string get_name(bool opt_only=false) const {  
288 - std::vector<std::string> name_list;  
289 - if(!opt_only && pname_.length() > 0)  
290 - name_list.push_back(pname_);  
291 - for(const std::string& sname : snames_)  
292 - name_list.push_back("-"+sname);  
293 - for(const std::string& lname : lnames_)  
294 - name_list.push_back("--"+lname);  
295 - return detail::join(name_list);  
296 - }  
297 -  
298 - /// Ignore case  
299 - ///  
300 - /// The template hides the fact that we don't have the definition of App yet.  
301 - /// You are never expected to add an argument to the template here.  
302 - template<typename T=App>  
303 - Option* ignore_case(bool value = true) {  
304 - ignore_case_ = value;  
305 - for(const Option_p& opt : dynamic_cast<T*>(parent_)->options_)  
306 - if(opt.get() != this && *opt == *this)  
307 - throw OptionAlreadyAdded(opt->get_name());  
308 - return this;  
309 - }  
310 -  
311 /// Check a name. Requires "-" or "--" for short / long, supports positional name 383 /// Check a name. Requires "-" or "--" for short / long, supports positional name
312 bool check_name(std::string name) const { 384 bool check_name(std::string name) const {
313 385
@@ -359,57 +431,6 @@ public: @@ -359,57 +431,6 @@ public:
359 return results_.size() - 1; 431 return results_.size() - 1;
360 } 432 }
361 433
362 - /// Count the total number of times an option was passed  
363 - int count() const {  
364 - int out = 0;  
365 - for(const std::vector<std::string>& vec : results_)  
366 - out += vec.size();  
367 - return out;  
368 - }  
369 -  
370 - /// The first half of the help print, name plus default, etc  
371 - std::string help_name() const {  
372 - std::stringstream out;  
373 - out << get_name(true) << _help_aftername();  
374 - return out.str();  
375 - }  
376 -  
377 - /// pname with type info  
378 - std::string help_pname() const {  
379 - std::stringstream out;  
380 - out << get_pname() << _help_aftername();  
381 - return out.str();  
382 - }  
383 -  
384 - /// This is the part after the name is printed but before the description  
385 - std::string _help_aftername() const {  
386 - std::stringstream out;  
387 -  
388 - if(get_expected() != 0) {  
389 - if(typeval_ != "")  
390 - out << " " << typeval_;  
391 - if(defaultval_ != "")  
392 - out << "=" << defaultval_;  
393 - if(get_expected() > 1)  
394 - out << " x " << get_expected();  
395 - if(get_expected() == -1)  
396 - out << " ...";  
397 - }  
398 - if(envname_ != "")  
399 - out << " (env:" << envname_ << ")";  
400 - if(requires_.size() > 0) {  
401 - out << " Requires:";  
402 - for(const Option* opt : requires_)  
403 - out << " " << opt->get_name();  
404 - }  
405 - if(excludes_.size() > 0) {  
406 - out << " Excludes:";  
407 - for(const Option* opt : excludes_)  
408 - out << " " << opt->get_name();  
409 - }  
410 - return out.str();  
411 -  
412 - }  
413 434
414 /// Produce a flattened vector of results, vs. a vector of vectors. 435 /// Produce a flattened vector of results, vs. a vector of vectors.
415 std::vector<std::string> flatten_results() const { 436 std::vector<std::string> flatten_results() const {
@@ -419,6 +440,8 @@ public: @@ -419,6 +440,8 @@ public:
419 return output; 440 return output;
420 } 441 }
421 442
  443 + ///@}
  444 +
422 }; 445 };
423 446
424 447