powerd++  0.4.4
Classes | Namespaces | Functions
Options.hpp File Reference

Provides the nih::Options functor template, a substitute for getopt(3). More...

#include "utility.hpp"
#include <cstddef>
#include <type_traits>
#include <cassert>
Include dependency graph for Options.hpp:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  nih::enum_has_members< OptionT, class >
 Tests whether the given enum provides all the required definitions. More...
 
struct  nih::Parameter< OptionT >
 Container for an option definition. More...
 
class  nih::Options< OptionT, DefCount >
 An instance of this class offers operators to retrieve command line options and arguments. More...
 

Namespaces

 nih
 Not invented here namespace, for code that substitutes already commonly available functionality.
 

Functions

template<class OptionT >
size_t nih::argCount (Parameter< OptionT > const &def)
 Retrieves the count of arguments in an option definition. More...
 

Detailed Description

Provides the nih::Options functor template, a substitute for getopt(3).

The getopt(3) interface takes the command line arguments as char * const instead of char const *. I.e. it reserves the right to mutate the provided arguments, which it actually does.

The nih::Options functor is not a drop in substitute, but tries to be easily adoptable and does not change the data entrusted to it.

To use the options an enum or enum class is required, e.g.:

The options prefixed with OPT_ are obligatory. Their meaning is documented in nih::enum_has_members<>. Their presence is validated at compile time.

The enum values are returned when matching the next argument to a parameter. In order to do that a usage string and a list of parameter definitions are required:

static char const * const USAGE = "[-hv] [-i file] [-o file] [command ...]";
{MyOptions::USAGE, 'h', "help", "", "Show this help"},
{MyOptions::USAGE, 0, "usage", "", ""},
{MyOptions::FILE_IN, 'i', "in", "file", "Input file"},
{MyOptions::FILE_OUT, 'o', "out", "file", "Output file"},
{MyOptions::FLAG_VERBOSE, 'v', "verbose", "", "Verbose output"}
};

Each entry in the array defines a parameter consisting of the following:

Field Meaning
option The option symbol (enum value)
sparam An optional parameter character (short parameter)
lparam An optional long parameter string
args A comma separated list of parameter arguments
usage A descriptive string

Multiple parameters may be mapped to a single option (e.g. --help and --usage). Parameters without arguments are called flags. It is possible to map parameters with different numbers of arguments to a single option, but this is arguably semantically confusing and should not be done.

Multiple flags' parameter characters can be concatenated in an argument. A parameter with arguments' character can appear at the end of a character chain. The first argument to the parameter may be concatenated as well. E.g. -v -i file, -vi file and -vifile are all equivalent. Parameters' string representations always stand alone, they can neither be combined with each other nor with parameter characters. E.g. --verbose --in file is the equivalent parameter string representation.

The usage string and the parameter usage strings are used to assemble the string provided by the nih::Options<>::usage() method.

The parameter definitions must be passed to nih::Options constructor to create the functor:

#include <iostream>
...
int main(int argc, char * argv[]) {
char const * infile = "-";
char const * outfile = "-";
bool verbose = false;
auto getopt = nih::Options{argc, argv, USAGE, PARAMETERS};
while (true) switch (getopt()) { // get new option/argument
std::cerr << getopt.usage(); // show usage
return 0;
case MyOptions::FILE_IN:
infile = getopt[1]; // get first argument
break;
case MyOptions::FILE_OUT:
outfile = getopt[1]; // get first argument
break;
case MyOptions::FLAG_VERBOSE:
verbose = true;
break;
case MyOptions::OPT_UNKNOWN:
case MyOptions::OPT_NOOPT:
case MyOptions::OPT_DASH:
case MyOptions::OPT_LDASH:
std::cerr << "Unexpected command line argument: "
<< getopt[0] << '\n'; // output option/argument
return 1;
case MyOptions::OPT_DONE:
return do_something(infile, outfile, verbose);
}
return 0;
}

Every call of the functor moves on to the next parameter or argument. For non-option arguments it returns OPT_NOOPT.

The getopt[1] calls return the first argument following the option. It is possible to retrieve more arguments than were defined in the options definition. The [] opterator always returns a valid, terminated string (provided the command line arguments are valid, terminated strings). So it is always safe to dereference the pointer, even when reading beyond the end of command line arguments.

The getopt[0] calls return the command line argument that contains the selected option. So in the FILE_IN case it could be any of -i, --in, -vi, -ifile or -vifile. This is useful for the OPT_UNKNOWN and OPT_NOOPT cases. The getopt[1] call on the other hand would return file regardless of argument chaining.


Class Documentation

◆ nih::Parameter

struct nih::Parameter

template<class OptionT>
struct nih::Parameter< OptionT >

Container for an option definition.

Aliases can be defined by creating definitions with the same option member.

The lparam, args and usage members have to be 0 terminated, using string literals is safe.

Template Parameters
OptionTAn enum or enum class representing the available options
Class Members
const char * args A comma separated list of arguments.

Set to nullptr or "" if no argument is available.

const char * lparam The long version of this parameter.

Set to nullptr or "" if no long parameter is available.

OptionT option The enum value to return for this option.
char sparam The short version of this parameter.

Set to 0 if no short parameter is available.

const char * usage A usage string.
anonymous_namespace{loadplay.cpp}::USAGE
const char *const USAGE
The short usage string.
Definition: loadplay.cpp:54
anonymous_namespace{loadplay.cpp}::OE::OPT_DASH
@ OPT_DASH
Obligatory.
anonymous_namespace{loadplay.cpp}::OE::OPT_UNKNOWN
@ OPT_UNKNOWN
Obligatory.
anonymous_namespace{loadplay.cpp}::OE::FILE_OUT
@ FILE_OUT
Set output file instead of stdout.
anonymous_namespace{libloadplay.cpp}::main
class anonymous_namespace{libloadplay.cpp}::Main main
Sole instance of Main.
anonymous_namespace{loadrec.cpp}::verbose
void verbose(MsgTs &&... msg)
Outputs the given printf style message on stderr if g.verbose is set.
Definition: loadrec.cpp:151
nih::Parameter
Container for an option definition.
Definition: Options.hpp:183
anonymous_namespace{loadplay.cpp}::PARAMETERS
const Parameter< OE > PARAMETERS[]
Definitions of command line parameters.
Definition: loadplay.cpp:59
anonymous_namespace{loadplay.cpp}::OE::OPT_DONE
@ OPT_DONE
Obligatory.
nih::Options
An instance of this class offers operators to retrieve command line options and arguments.
Definition: Options.hpp:249
anonymous_namespace{loadplay.cpp}::OE::FILE_IN
@ FILE_IN
Set input file instead of stdin.
anonymous_namespace{loadrec.cpp}::OE::FLAG_VERBOSE
@ FLAG_VERBOSE
Verbose output on stderr.
anonymous_namespace{loadplay.cpp}::OE::OPT_NOOPT
@ OPT_NOOPT
Obligatory.
anonymous_namespace{loadplay.cpp}::OE::OPT_LDASH
@ OPT_LDASH
Obligatory.