Protocol++® (Protocolpp®)  v5.6.2
optionparser.h File Reference

This is the only file required to use The Lean Mean C++ Option Parser. Just #include it and you're set. More...

Classes

struct  option::Descriptor
 Describes an option, its help text (usage) and how it should be parsed. More...
 
class  option::Option
 A parsed option from the command line together with its argument if it has one. More...
 
struct  option::Arg
 Functions for checking the validity of option arguments. More...
 
struct  option::Stats
 Determines the minimum lengths of the buffer and options arrays used for Parser. More...
 
class  option::Parser
 Checks argument vectors for validity and parses them into data structures that are easier to work with. More...
 
struct  option::Parser::Action
 
class  option::Stats::CountOptionsAction
 
class  option::Parser::StoreOptionAction
 
struct  option::PrintUsageImplementation
 
struct  option::PrintUsageImplementation::IStringWriter
 
struct  option::PrintUsageImplementation::FunctionWriter< Function >
 
struct  option::PrintUsageImplementation::OStreamWriter< OStream >
 
struct  option::PrintUsageImplementation::TemporaryWriter< Temporary >
 
struct  option::PrintUsageImplementation::SyscallWriter< Syscall >
 
struct  option::PrintUsageImplementation::StreamWriter< Function, Stream >
 
class  option::PrintUsageImplementation::LinePartIterator
 
class  option::PrintUsageImplementation::LineWrapper
 

Namespaces

 option
 The namespace of The Lean Mean C++ Option Parser.
 

Typedefs

typedef ArgStatus(* option::CheckArg) (const Option &option, bool msg)
 Signature of functions that check if an argument is valid for a certain type of option. More...
 

Enumerations

enum  option::ArgStatus { option::ARG_NONE , option::ARG_OK , option::ARG_IGNORE , option::ARG_ILLEGAL }
 Possible results when checking if an argument is valid for a certain option. More...
 

Functions

template<typename OStream >
void option::printUsage (OStream &prn, const Descriptor usage[], int width=80, int last_column_min_percent=50, int last_column_own_line_max_percent=75)
 Outputs a nicely formatted usage string with support for multi-column formatting and line-wrapping. More...
 
template<typename Function >
void option::printUsage (Function *prn, const Descriptor usage[], int width=80, int last_column_min_percent=50, int last_column_own_line_max_percent=75)
 
template<typename Temporary >
void option::printUsage (const Temporary &prn, const Descriptor usage[], int width=80, int last_column_min_percent=50, int last_column_own_line_max_percent=75)
 
template<typename Syscall >
void option::printUsage (Syscall *prn, int fd, const Descriptor usage[], int width=80, int last_column_min_percent=50, int last_column_own_line_max_percent=75)
 
template<typename Function , typename Stream >
void option::printUsage (Function *prn, Stream *stream, const Descriptor usage[], int width=80, int last_column_min_percent=50, int last_column_own_line_max_percent=75)
 

Detailed Description

This is the only file required to use The Lean Mean C++ Option Parser. Just #include it and you're set.

The Lean Mean C++ Option Parser handles the program's command line arguments (argc, argv). It supports the short and long option formats of getopt(), getopt_long() and getopt_long_only() but has a more convenient interface.

Feedback:
Send questions, bug reports, feature requests etc. to: optionparser-feedback(a)lists.sourceforge.net
Highlights:
  • It is a header-only library. Just #include "optionparser.h" and you're set.
  • It is freestanding. There are no dependencies whatsoever, not even the C or C++ standard library.
  • It has a usage message formatter that supports column alignment and line wrapping. This aids localization because it adapts to translated strings that are shorter or longer (even if they contain Asian wide characters).
  • Unlike getopt() and derivatives it doesn't force you to loop through options sequentially. Instead you can access options directly like this:
    • Test for presence of a switch in the argument vector:
      if ( options[QUIET] ) ...
    • Evaluate –enable-foo/–disable-foo pair where the last one used wins:
      if ( options[FOO].last()->type() == DISABLE ) ...
    • Cumulative option (-v verbose, -vv more verbose, -vvv even more verbose):
      int verbosity = options[VERBOSE].count();
    • Iterate over all –file=<fname> arguments:
      for (Option* opt = options[FILE]; opt; opt = opt->next())
      fname = opt->arg; ...
    • If you really want to, you can still process all arguments in order:
      for (int i = 0; i < p.optionsCount(); ++i) {
      Option& opt = buffer[i];
      switch(opt.index()) {
      case HELP: ...
      case VERBOSE: ...
      case FILE: fname = opt.arg; ...
      case UNKNOWN: ...

Despite these features the code size remains tiny. It is smaller than uClibc's GNU getopt() and just a couple 100 bytes larger than uClibc's SUSv3 getopt().
(This does not include the usage formatter, of course. But you don't have to use that.)
Download:
Tarball with examples and test programs: optionparser-1.7.tar.gz
Just the header (this is all you really need): optionparser.h
Changelog:
Version 1.7: Work on const-correctness.
Version 1.6: Fix for MSC compiler.
Version 1.5: Fixed 2 warnings about potentially uninitialized variables.
Added const version of Option::next().
Version 1.4: Fixed 2 printUsage() bugs that messed up output with small COLUMNS values.
Version 1.3: Compatible with Microsoft Visual C++.
Version 1.2: Added Option::namelen and removed the extraction of short option characters into a special buffer.
Changed Arg::Optional to accept arguments if they are attached rather than separate. This is what GNU getopt() does and how POSIX recommends utilities should interpret their arguments.
Version 1.1: Optional mode with argument reordering as done by GNU getopt(), so that options and non-options can be mixed. See Parser::parse().
Example program:
(Note: option::* identifiers are links that take you to their documentation.)
#error EXAMPLE SHORTENED FOR READABILITY. BETTER EXAMPLES ARE IN THE .TAR.GZ!
#include <iostream>
#include "optionparser.h"
enum optionIndex { UNKNOWN, HELP, PLUS };
const option::Descriptor usage[] =
{
{UNKNOWN, 0,"" , "" ,option::Arg::None, "USAGE: example [options]\n\n"
"Options:" },
{HELP, 0,"" , "help",option::Arg::None, " --help \tPrint usage and exit." },
{PLUS, 0,"p", "plus",option::Arg::None, " --plus, -p \tIncrement count." },
{UNKNOWN, 0,"" , "" ,option::Arg::None, "\nExamples:\n"
" example --unknown -- --this_is_no_option\n"
" example -unk --plus -ppp file1 file2\n" },
{0,0,0,0,0,0}
};
int main(int argc, char* argv[])
{
argc-=(argc>0); argv+=(argc>0); // skip program name argv[0] if present
option::Stats stats(usage, argc, argv);
option::Option options[stats.options_max], buffer[stats.buffer_max];
option::Parser parse(usage, argc, argv, options, buffer);
if (parse.error())
return 1;
if (options[HELP] || argc == 0) {
option::printUsage(std::cout, usage);
return 0;
}
std::cout << "--plus count: " <<
options[PLUS].count() << "\n";
for (option::Option* opt = options[UNKNOWN]; opt; opt = opt->next())
std::cout << "Unknown option: " << opt->name << "\n";
for (int i = 0; i < parse.nonOptionsCount(); ++i)
std::cout << "Non-option #" << i << ": " << parse.nonOption(i) << "\n";
}
A parsed option from the command line together with its argument if it has one.
Definition: optionparser.h:443
Option * next()
Returns a pointer to the next element of the linked list or NULL if called on last().
Definition: optionparser.h:695
int count() const
Returns the number of times this Option (or others with the same Descriptor::index) occurs in the arg...
Definition: optionparser.h:559
Checks argument vectors for validity and parses them into data structures that are easier to work wit...
Definition: optionparser.h:1090
void printUsage(OStream &prn, const Descriptor usage[], int width=80, int last_column_min_percent=50, int last_column_own_line_max_percent=75)
Outputs a nicely formatted usage string with support for multi-column formatting and line-wrapping.
Definition: optionparser.h:2824
This is the only file required to use The Lean Mean C++ Option Parser. Just #include it and you're se...
static ArgStatus None(const Option &, bool)
For options that don't take an argument: Returns ARG_NONE.
Definition: optionparser.h:926
Describes an option, its help text (usage) and how it should be parsed.
Definition: optionparser.h:316
Determines the minimum lengths of the buffer and options arrays used for Parser.
Definition: optionparser.h:960
Option syntax:
  • The Lean Mean C++ Option Parser follows POSIX getopt() conventions and supports GNU-style getopt_long() long options as well as Perl-style single-minus long options (getopt_long_only()).
  • short options have the format -X where X is any character that fits in a char.
  • short options can be grouped, i.e. -X -Y is equivalent to -XY.
  • a short option may take an argument either separate (-X foo) or attached (-Xfoo). You can make the parser accept the additional format -X=foo by registering X as a long option (in addition to being a short option) and enabling single-minus long options.
  • an argument-taking short option may be grouped if it is the last in the group, e.g. -ABCXfoo or -ABCX foo (foo is the argument to the -X option).
  • a lone minus character '-' is not treated as an option. It is customarily used where a file name is expected to refer to stdin or stdout.
  • long options have the format –option-name.
  • the option-name of a long option can be anything and include any characters. Even = characters will work, but don't do that.
  • [optional] long options may be abbreviated as long as the abbreviation is unambiguous. You can set a minimum length for abbreviations.
  • [optional] long options may begin with a single minus. The double minus form is always accepted, too.
  • a long option may take an argument either separate ( –option arg ) or attached ( –option=arg ). In the attached form the equals sign is mandatory.
  • an empty string can be passed as an attached long option argument: –option-name= . Note the distinction between an empty string as argument and no argument at all.
  • an empty string is permitted as separate argument to both long and short options.
  • Arguments to both short and long options may start with a '-' character. E.g. -X-X , -X -X or –long-X=-X . If -X and –long-X take an argument, that argument will be "-X" in all 3 cases.
  • If using the built-in Arg::Optional, optional arguments must be attached.
  • the special option (i.e. without a name) terminates the list of options. Everything that follows is a non-option argument, even if it starts with a '-' character. The itself will not appear in the parse results.
  • the first argument that doesn't start with '-' or '–' and does not belong to a preceding argument-taking option, will terminate the option list and is the first non-option argument. All following command line arguments are treated as non-option arguments, even if they start with '-' .
    NOTE: This behaviour is mandated by POSIX, but GNU getopt() only honours this if it is explicitly requested (e.g. by setting POSIXLY_CORRECT).
    You can enable the GNU behaviour by passing true as first argument to e.g. Parser::parse().
  • Arguments that look like options (i.e. '-' followed by at least 1 character) but aren't, are NOT treated as non-option arguments. They are treated as unknown options and are collected into a list of unknown options for error reporting.
    This means that in order to pass a first non-option argument beginning with the minus character it is required to use the special option, e.g.
    program -x -- --strange-filename
    In this example, –strange-filename is a non-option argument. If the were omitted, it would be treated as an unknown option.
    See option::Descriptor::longopt for information on how to collect unknown options.