opt
opt is a bare-bones command line argument parsing library for C++14 and later. It supports a non-standard key-value option style similar to the dd program from coreutils, or the well-known iproute2 command suite. Clever usage of positional and keyword arguments can result in extremely readable command lines.
The following example shows the command line of a hypothetical tool for running commands repeatedly at a specified time interval:
$ ./run "echo hello" every 500m sec times=10 stop_on_error
... if implemented would print 'hello' every 500ms for 10 times ...
The usage example below shows how to describe this kind of syntax. The library generates automatically a usage message:
$ ./run help
Usage: ./run [help] [cmd=]COMMAND [mode=](oneshot|after|repeat|every)
[timeout=]TIMEOUT [unit=](seconds|sec|s|minutes|m|hours|hr|h) [quiet]
[stop_on_error] [until=TIME] [times=INT]
opt is distributed under the open source MIT license.
Argument types
Positional arguments and boolean flags are supported. Numeric values can be
followed by SI unit prefixes (e.g. 2.4k
-> int: 2400, float: 2.4e+3). Supported
types for options are bool
, std::string
, std::string_view
, std::intmax_t
,
std::uintmax_t
, float
, double
. Enum types and composite types
std::complex<T>
, std::array<T, N>
, std::vector<T>
, std::set<T>
, are
also supported, where T
is one of the supported types. Additional types can
be supported by specializing a static method. For more information, read the
documentation.
Usage
Option syntax for the hypothetical run
command shown above can be defined
through the following C++ code:
#include "opt.hpp"
enum Mode {
OneShot,
Repeat,
};
template<>
const opt::Option<Mode>::value_map opt::Option<Mode>::values = {
{ "oneshot", OneShot },
{ "after", OneShot },
{ "repeat", Repeat },
{ "every", Repeat },
};
enum Unit {
Second,
Minute,
Hour,
};
template<>
const opt::Option<Unit>::value_map opt::Option<Unit>::values = {
{ "seconds", Second },
{ "sec", Second },
{ "s", Second },
{ "minutes", Minute },
{ "m", Minute },
{ "hours", Hour },
{ "hr", Hour },
{ "h", Hour },
};
int main(int argc, char* argv[]) {
using opt::Option;
using opt::Placeholder;
using opt::Required;
Option<opt::StringView> cmd("cmd", Placeholder("COMMAND"), Required);
Option<Mode> mode("mode", Required);
Option<float> timeout("timeout", Placeholder("TIMEOUT"), Required);
Option<Unit> unit("unit", Required);
Option<bool> quiet("quiet", false);
Option<bool> stop_on_error("stop_on_error", false);
Option<float> until("until", Placeholder("TIME"), 0.0f);
Option<std::uintmax_t> times("times", 0);
if (!opt::parse({ cmd, mode, timeout, unit },
{ quiet, stop_on_error, until, times },
argv, argv + argc))
return -1;
if (!cmd.is_set() || !mode.is_set() ||
!timeout.is_set() || !unit.is_set()) {
std::cerr << "error: required options are not set" << std::endl;
opt::usage(argv[0],
{ cmd, mode, timeout, unit },
{ quiet, stop_on_error, until, times });
return -1;
}
/* ... */
return 0;
}