All Projects → abolz → CmdLine2

abolz / CmdLine2

Licence: Apache-2.0 license
Command line argument parser (C++14)

Programming Languages

C++
36643 projects - #6 most used programming language
lua
6591 projects

Projects that are alternatives of or similar to CmdLine2

option-parser
A Lightweight, header-only CLI option parser for C++
Stars: ✭ 16 (-11.11%)
Mutual labels:  argument-parser, option-parser, command-line-parser
dropt
dropt is yet another C library for parsing command-line options.
Stars: ✭ 39 (+116.67%)
Mutual labels:  argument-parser, option-parser, command-line-parser
argparser
Simple command-line parser for C/C++ programs
Stars: ✭ 50 (+177.78%)
Mutual labels:  argument-parser, option-parser, command-line-parser
Clikt
Multiplatform command line interface parsing for Kotlin
Stars: ✭ 1,658 (+9111.11%)
Mutual labels:  argument-parser, option-parser, command-line-parser
Programoptions.hxx
Single-header program options parsing library for C++11
Stars: ✭ 112 (+522.22%)
Mutual labels:  argument-parser, option-parser, command-line-parser
declarative-parser
Modern, declarative argument parser for Python 3.6+
Stars: ✭ 31 (+72.22%)
Mutual labels:  argument-parser, option-parser, command-line-parser
Kotlin Argparser
Easy to use and concise yet powerful and robust command line argument parsing for Kotlin
Stars: ✭ 431 (+2294.44%)
Mutual labels:  argument-parser, option-parser, command-line-parser
Argagg
A simple C++11 command line argument parser
Stars: ✭ 180 (+900%)
Mutual labels:  argument-parser, option-parser, command-line-parser
command-line-commands
Add a git-like command interface to your app.
Stars: ✭ 40 (+122.22%)
Mutual labels:  option-parser, command-line-parser
go-getoptions
Fully featured Go (golang) command line option parser with built-in auto-completion support.
Stars: ✭ 41 (+127.78%)
Mutual labels:  argument-parser, option-parser
Argparse
Argparse for golang. Just because `flag` sucks
Stars: ✭ 294 (+1533.33%)
Mutual labels:  argument-parser, command-line-parser
Console CommandLine
Full featured command line options and arguments parser.
Stars: ✭ 19 (+5.56%)
Mutual labels:  argument-parser, option-parser
Argumentparser
Faster, easier, more declarative parsing of command line arguments in Objective-C/Foundation.
Stars: ✭ 251 (+1294.44%)
Mutual labels:  argument-parser, command-line-parser
Caporal.js
A full-featured framework for building command line applications (cli) with node.js
Stars: ✭ 3,279 (+18116.67%)
Mutual labels:  argument-parser, command-line-parser
Clap
Create your command-line parser, with all of the bells and whistles, declaratively or procedurally.
Stars: ✭ 7,174 (+39755.56%)
Mutual labels:  argument-parser, command-line-parser
minimist2
TypeScript/JavaScript ES6 rewrite of popular Minimist argument parser
Stars: ✭ 20 (+11.11%)
Mutual labels:  argument-parser, command-line-parser
Argh
Argh! A minimalist argument handler.
Stars: ✭ 752 (+4077.78%)
Mutual labels:  argument-parser, command-line-parser
Command Line Args
A mature, feature-complete library to parse command-line options.
Stars: ✭ 525 (+2816.67%)
Mutual labels:  option-parser, command-line-parser
Clipp
easy to use, powerful & expressive command line argument parsing for modern C++ / single header / usage & doc generation
Stars: ✭ 687 (+3716.67%)
Mutual labels:  argument-parser, option-parser
Lyra
A simple to use, composable, command line parser for C++ 11 and beyond
Stars: ✭ 238 (+1222.22%)
Mutual labels:  argument-parser, option-parser

Cmdline

Build Status Build status codecov

Command line argument parser (C++14)

Quick start

The following example shows how to use the library to parse command line arguments from the argv array.

// Include the CmdLine library.
// It's header-only.
#include "Cmdline.h"

int main(int argc, char* argv[])
// or:
// int wmain(int argc, wchar_t* argv[])
{
    // Create a command line parser.
    cl::Cmdline cli("Example", "A short description");

    // The parser needs to know about the valid options (and the syntax which
    // might be used to specifiy the options on the command line).
    // Options can be created and attached to the parser using the Cmdline::Add
    // method.

    // This adds an option to enable (or disable) debug output.
    // The value of the option will be assigned to the variable `debug`.

    bool debug = false;

    cli.Add(
        // 1)
        //
        // The 1st parameter is the name of the option. Multiple option names
        // may be separated by `|`. So the `debug` option might be specified as
        // `-d` or `--debug`.
        //
        "d|debug",

        // 2)
        //
        // The 2nd parameter provides a short description of the option which
        // will be displayed in the automatically generated help message.
        //
        "Enable debug output",

        // 3)
        //
        // The 3rd parameter is a combination of flags, which specify ow and how
        // often the option might be specified on the command line and whether
        // the option takes an argument or not.
        //
        // The `Multiple` flag can be used to tell the parser that an option
        // may appear multiple times on the command line.
        // The default value for `Multiple` is `no`, i.e. the option may
        // appear at most once on the command line.
        //
        cl::Multiple::yes
        //
        // The `Arg` flag can be used to tell the parser whether the option
        // accepts an argument. The `optional` value means that an argument is
        // optional, i.e. both `--debug` and `--debug=on` or `--debug=false` are
        // valid.
        // The default value is `Arg::no`, i.e. an argument is not allowed.
        //
        | cl::Arg::optional,
        //
        // There are more options which can be used to customize the syntax for
        // options. These are described later.
        //

        // 4)
        //
        // The 4th parameter is the actual option parser which effectively takes
        // the string representation of the command line argument and is used to
        // convert the option (or the options' argument - if present) into the
        // target object.
        //
        // For now it should be sufficient to note that Var(T& target) is a
        // convenience function which converts the string as given on the
        // command line into an object of type `T` and assigns the result to the
        // given target variable.
        // More advanced usages of the parser will be described later.
        //
        cl::Var(debug)
    );

    // The next command adds an option which may be specified multiple times and
    // the argument of each occurence will be added to the `include_directories`
    // array defined below.

    std::vector<std::string> include_directories;
    // or:
    // std::vector<std::wstring> include_directories;

    cli.Add("I", "Include directories",

        // The `Arg::required` flag tells the parser that an "-I" must have an
        // argument specified. Either using the "-I=dir" syntax or as an
        // additional argument like "-I dir".
        cl::Multiple::yes | cl::Arg::required,

        // `Var` works with STL containers, too.
        cl::Var(include_directories)
        );

    // The `cli` object now knows everything it needs to know to parse the
    // command line argument array.

    // The Cmdline::Parse method takes a pair of iterators, parses the command
    // line arguments and calls the options' parser to convert the strings into
    // some objects of another type. Note that the Parse method does not know
    // anything about the program name which is stored in argv[0], so we skip
    // that.
    auto const result = cli.Parse(argv + 1, argv + argc);

    // The parser may generate warning and/or error messages. These messages
    // may be obtained with `Cmdline::diag()`. For convenience the `PrintDiag()`
    // method prints the diagnostic messages to `stderr`.
    cli.PrintDiag();

    if (!result) {
        // The result of `Cmdline::Parse` can be explicitly converted to `bool`
        // to indicate success or failure. If the options were specified with
        // an invalid syntax or a conversion error has occurred, the result will
        // be `false`.
        //
        // To provide the user with some information how to avoid these mistakes
        // the Cmdling objects provides a `FormatHelp` methods which returns a
        // string containing a description of all the options which the program
        // accepts.
        // Again, for convenience, the `PrintHelp` method prints this help
        // message to `stderr`. Here we need to tell the CmdLine library the
        // program name in order to print some nicer help message...
        cli.PrintHelp();
        return -1;
    }

    // The command line has been successfully parsed.
    // Now do something useful...

    return 0;
}

Option flags

As noted above, the flags argument (3rd) controls how the options must/may be specified on the command line. Here is a list of the options flags the library supports.

In the examples below, the descr parameter is used to indicate the type of the variable.

There are (currently) no restrictions on the combinations of flags. You may combine any flag with any other, but the syntax may become odd or ambiguous. So be careful.

TODO

Implement Cmdline::SyntaxCheck() to check for odd or ambiguous option combinations. Or perform this check (in debug-mode only) in Cmdline::Add()?

enum class Required

Controls whether an option must appear on the command line.

  • no
    The option is not required to appear on the command line. This is the default.

    cli.Add("f", "bool", Required::no, Var(f));
    
    // ""       ==>  f = <initial value>
    // "-f"     ==>  f = true
    // "-f -f"  ==>  Error
  • yes
    The option is required to appear on the command line.

    cli.Add("f", "bool", Required::yes, Var(f));
    
    // ""       ==>  Error
    // "-f"     ==>  f = true
    // "-f -f"  ==>  Error

enum class Multiple

Determines whether an option may appear multiple times on the command line.

  • no
    The option may appear (at most) once on the command line. This is the default.

  • yes
    The option may appear multiple times on the command line.

    cli.Add("f", "bool", Multiple::yes, Var(f));
    
    // ""       ==>  f = <initial value>
    // "-f"     ==>  f = true
    // "-f -f"  ==>  f = true
    
    cli.Add("f", "bool", Multiple::yes | Required::yes, Var(f));
    
    // ""       ==>  Error
    // "-f"     ==>  f = true
    // "-f -f"  ==>  f = true

enum class Arg

Controls the number of arguments the option accepts.

  • no
    An argument is not allowed. This is the default.

    cli.Add("f", "bool", Arg::no, Var(f));
    
    // "-f"     ==>  f = true
    // "-f=on"  ==>  Error
  • optional
    An argument is optional.

    cli.Add("f", "bool", Arg::optional, Var(f));
    
    // "-f"        ==>  f = true
    // "-f=false"  ==>  f = false
  • yes
    An argument is required. If this flag is set, the parser may steal arguments from the command line if none is provided using the = syntax.

    cli.Add("f", "bool", Arg::required, Var(f));
    
    // "-f"      ==>  Error
    // "-f=1"    ==>  f = true
    // "-f yes"  ==>  f = true

enum class MayJoin

Controls whether the option may/must join its argument.

  • no
    The option must not join its argument: "-I dir" and "-I=dir" possible. If the option is specified with an equals sign ("-I=dir") the '=' will not be part of the option argument. This is the default.

    cli.Add("I", "Include directory", Arg::yes | MayJoin::no, Var(I));
    
    // "-I"      ==>  Error
    // "-Idir"   ==>  Error
    // "-I dir"  ==>  I = "dir"
    // "-I=dir"  ==>  I = "dir"
  • yes
    The option may join its argument: "-I dir" and "-Idir" are possible. If the option is specified with an equals sign ("-I=dir") the '=' will be part of the option argument.

    cli.Add("I", "Include directory", Arg::yes | MayJoin::yes, Var(I));
    
    // "-I"      ==>  Error
    // "-Idir"   ==>  I = "dir"
    // "-I dir"  ==>  I = "dir"
    // "-I=dir"  ==>  I = "=dir"

enum class MayGroup

May this option group with other options?

  • no
    The option may not be grouped with other options (even if the option name consists only of a single letter). This is the default.

    cli.Add("x", "bool", Arg::no | MayGroup::no, Var(x));
    cli.Add("v", "bool", Arg::no | MayGroup::no, Var(v));
    
    // "-x -v"  ==>  x = true, v = true
    // "-xv"    ==>  Error
  • yes
    The option may be grouped with other options. This flag is ignored if the name of the option is not a single letter and option groups must be prefixed with a single '-', e.g. "-xvf=file".

    cli.Add("x", "bool", Arg::no | MayGroup::yes, Var(x));
    cli.Add("v", "bool", Arg::no | MayGroup::yes, Var(v));
    
    // "-x -v"  ==>  x = true, v = true
    // "-xv"    ==>  x = true, v = true
    // "--xv"   ==>  Error (not an option group)

    Options which require an argument may be grouped, too. But the first option in a group, which requires an argument, terminates the option group, e.g.,

    cli.Add("x", "bool", MayGroup::yes | Arg::no, Var(x));
    cli.Add("v", "bool", MayGroup::yes | Arg::no, Var(v));
    cli.Add("f", "str", MayGroup::yes | Arg::yes, Var(v));
    
    // "-x -v -f file"  ==>  x = true, v = true, f = "file"
    // "-xvf file"      ==>  x = true, v = true, f = "file"
    // "-xvf=file"      ==>  x = true, v = true, f = "file"
    // "-xf"            ==>  Error (option 'f' requires an argument)
    // "-xfv=file"      ==>  Error (option 'f' must not join its argument)
    // "-xfv"           ==>  Error (option 'f' must not join its argument)
    // "--xfv"          ==>  Error (unknown option '--xvf')

    If option f may join its argument, the syntax would become

    cli.Add("x", "bool", MayGroup::yes | Arg::no, Var(x));
    cli.Add("v", "bool", MayGroup::yes | Arg::no, Var(v));
    cli.Add("f", "str", MayJoin::yes | MayGroup::yes | Arg::yes, Var(v));
    
    // "-x -v -f file"  ==>  as before
    // "-xvf file"      ==>  as before
    // "-xvf=file"      ==>  x = true, v = true, f = "=file"
    // "-xf"            ==>  Error (option 'f' requires an argument)
    // "-xfv=file"      ==>  x = true, v = false, f = "v=file"
    // "-xfv"           ==>  x = true, v = false, f = "v"
    // "--xfv"          ==>  Error (unknown option '--xvf')

    As noted above, there are no restrictions on the combinations of the flags, so be careful.

enum class Positional

Positional option?

  • no
    The option is not a positional option, i.e. it requires '-' or '--' as a prefix when specified. This is the default.

    cli.Add("f", "str", Arg::yes | Positional::no, Var(f));
    
    // "--f file"  ==>  f = "file"
    // "file"      ==>  Error
  • yes
    Positional option, no '-' required.

    cli.Add("f", "str", Arg::yes | Positional::yes, Var(f));
    
    // "--f=file"  ==>  f = "file"
    // "file"      ==>  f = "file"

    Multiple positional options are allowed. They are processed in the order as they are attached to the parser until they no longer accept any further occurrence. E.g.

    cli.Add("f1", "str", Positional::yes, Var(f1));
    cli.Add("f2", "vec<str>", Multiple::yes | Positional::yes, Var(f2));
    
    // "eins"            ==>  f1 = "eins", f2 = {}
    // "eins zwei drei"  ==>  f1 = "eins", f2 = {"zwei", "drei"}

    As can be seen above, positional options still can be specified using the -f1=eins syntax. In particular, if the Arg::yes has been set, the syntax may even be -f1 eins.

    Again this may lead to ambiguities:

    cli.Add("f1", "str", Positional::yes, Var(f1));
    cli.Add("f2", "str", Positional::yes | Arg::yes, Var(f2));
    
    // "eins zwei"     ==>  f1 = "eins", f2 = "zwei"
    // "-f1 eins"      ==>  f1 = "", f2 = "zwei"
    // "-f1 -f2 zwei"  ==>  f1 = "", f2 = "zwei"

    compared to:

    cli.Add("f1", "str", Positional::yes | Arg::yes, Var(f1));
    cli.Add("f2", "str", Positional::yes, Var(f2));
    
    // "eins zwei"          ==>  f1 = "eins", f2 = "zwei"
    // "-f1 eins"           ==>  f1 = "eins", f2 = ""
    // "-f1 -f2=zwei"       ==>  f1 = "-f2=zwei", f2 = ""
    // "-f1 -f2=zwei zwei"  ==>  f1 = "-f2=zwei", f2 = "zwei"

    Note that the last two examples emit a warning:

    warning: option 'f2' is used as an argument for option 'f1'
    note: use '--f1=-f2=zwei' to suppress this warning

    which indicates a possible missing argument for f1. As noted,

    // "-f1=-f2=zwei zwei"  ==>  f1 = "-f2=zwei", f2 = "zwei"

    does not emit a warning.

enum class CommaSeparated

TODO

enum class StopParsing

TODO

Option parser

TODO

General

bool parse(ParseContext const& ctx); // 'const' is required here
ctx.name     // option name
ctx.arg      // option argument
ctx.index    // index in argv[]
ctx.cmdline  // for warning and/or error messages
auto parse = [](ParseContext const& ctx) {
    std::cout << "Index " << ctx.index << ":"
        << " --" << ctx.name << " " << ctx.arg << "\n";
    if (ctx.name == "b") {
        ctx.cmdline->EmitDiag(
            Diagnostic::warning, ctx.index, "option 'b' is deprecated");
    }
    return true;
};

cli.Add("a|b", "custom", Arg::optional | Multiple::yes, parse);

// "-a -b=eins -a=zwei" ==>
//      Index 0: --a
//      Index 1: --b eins
//      Index 2: --a zwei

and emits a warning:

warning: option 'b' is deprecated

Predefined

Assign

  • bool
  • integers
  • floating-point
  • strings
  • stream extraction operator operator<<(ostream, T)

Append

Var

Map

Predicates / Filters / Transforms

bool predicate(ParseContext const&, auto /*[const]*/& value);

Command-line parser

TODO

Unicode support

TODO

Yes. UTF conversions built-in.

Tokenize

TODO

const auto vec = TokenizeWindows("-a -b -c")
// vec = {"-a", "-b", "-c"}
const auto vec = TokenizeUnix("-a -b -c");
// vec = {"-a", "-b", "-c"}

Subcommands

TODO

No, not really. Example.

Console colors

TODO

#define CL_ANSI_CONSOLE_COLORS 1 // Windows/Unix (if supported)
#define CL_WINDOWS_CONSOLE_COLORS 1 // Windows only
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].