A simple to use, composable, command line parser for C++ 11 and beyond

Related tags

CLI Clara
Overview

Clara v1.1.5

Build Status Build status codecov

!! This repository is unmaintained. Go here for a fork that is somewhat maintained. !!


A simple to use, composable, command line parser for C++ 11 and beyond.

Clara is a single-header library.

To use, just #include "clara.hpp"

A parser for a single option can be created like this:

int width = 0;
// ...
using namespace clara;
auto cli
    = Opt( width, "width" )
        ["-w"]["--width"]
        ("How wide should it be?");

You can use this parser directly like this:

auto result = cli.parse( Args( argc, argv ) );
if( !result ) {
    std::cerr << "Error in command line: " << result.errorMessage() << std::endl;
    exit(1);
}

// Everything was ok, width will have a value if supplied on command line

Note that exceptions are not used for error handling.

You can combine parsers by composing with |, like this:

int width = 0;
std::string name;
bool doIt = false;
std::string command;
auto cli
    = Opt( width, "width" )
        ["-w"]["--width"]
        ("How wide should it be?")
    | Opt( name, "name" )
        ["-n"]["--name"]
        ("By what name should I be known")
    | Opt( doIt )
        ["-d"]["--doit"]
        ("Do the thing" )
    | Arg( command, "command" )
        ("which command to run");

Opts specify options that start with a short dash (-) or long dash (--). On Windows forward slashes are also accepted (and automatically interpretted as a short dash). Options can be argument taking (such as -w 42), in which case the Opt takes a second argument - a hint, or they are pure flags (such as -d), in which case the Opt has only one argument - which must be a boolean. The option names are provided in one or more sets of square brackets, and a description string can be provided in parentheses. The first argument to an Opt is any variable, local, global member, of any type that can be converted from a string using std::ostream.

Args specify arguments that are not tied to options, and so have no square bracket names. They otherwise work just like Opts.

A, console optimised, usage string can be obtained by inserting the parser into a stream. The usage string is built from the information supplied and is formatted for the console width.

As a convenience, the standard help options (-h, --help and -?) can be specified using the Help parser, which just takes a boolean to bind to.

For more usage please see the unit tests or look at how it is used in the Catch code-base (catch-lib.net). Fuller documentation will be coming soon.

Some of the key features:

  • A single header file with no external dependencies (except the std library).
  • Define your interface once to get parsing, type conversions and usage strings with no redundancy.
  • Composable. Each Opt or Arg is an independent parser. Combine these to produce a composite parser - this can be done in stages across multiple function calls - or even projects.
  • Bind parsers directly to variables that will receive the results of the parse - no intermediate dictionaries to worry about.
  • Or can also bind parsers to lambdas for more custom handling.
  • Deduces types from bound variables or lambdas and performs type conversions (via ostream <<), with error handling, behind the scenes.
  • Bind parsers to vectors for args that can have multiple values.
  • Uses Result types for error propagation, rather than exceptions (doesn't yet build with exceptions disabled, but that will be coming later)
  • Models POSIX standards for short and long opt behaviour.

Roadmap

To see which direction Clara is going in, please see the roadmap

Old version

If you used the earlier, v0.x, version of Clara please note that this is a complete rewrite which assumes C++11 and has a different interface (composability was a big step forward). Conversion between v0.x and v1.x is a fairly simple and mechanical task, but is a bit of manual work - so don't take this version until you're ready (and, of course, able to use C++11).

I hope you'll find the new interface an improvement - and this will be built on to offer new features moving forwards. I don't expect to maintain v0.x any further, but it remains on a branch.

Issues
  • Please provide LICENSE file

    Please provide LICENSE file

    I've been trying to work out what license Clara is under. The "single-include" contains license text from clara_textflow.hpp:

    // This work is licensed under the BSD 2-Clause license.
    // See the accompanying LICENSE file, or the one at https://opensource.org/licenses/BSD-2-Clause
    

    But I can't see a LICENSE file in the repository.

    The separate clara.hpp contains no license information at all.

    I suspect that Clara is also under the 2-clause BSD license, but I think this needs to be made completely clear.

    Thanks.

    Mike.

    opened by Mike-Crowe-BrightSign 11
  • [Discussion] Why another command line parser?

    [Discussion] Why another command line parser?

    Why would I use this as opposed to: http://www.boost.org/doc/libs/1_60_0/doc/html/program_options.html

    Note that windows syntax for command line options is kinda silly; anything that is platform-agnostic uses - and -- notations. I'm not sure if Boost Program Options lets you change this syntax, but I never use anything but it.

    Maybe your documentation can explain why we need another parser for this, kind of like you do for Catch.

    opened by rcdailey 10
  • Clara: TextFlow: fixed issue with word wrapping

    Clara: TextFlow: fixed issue with word wrapping

    The issue with word wrapping was that in case that m_pos + width was greater or equal to m_end it fallbacked to m_end-m_pos branch which caused that printed string was greater than configured width.

    Also caused duplication of words as in next iteration m_len was added to m_pos this was less then m_end.

    Originally reported in https://github.com/catchorg/Catch2/issues/1400

    opened by JoeyGrajciar 8
  • Accept const char*[] argv in Args constructor

    Accept const char*[] argv in Args constructor

    This makes it easier to run tests using string literals.

    Currently this fails:

    const char *v[] = { "arg0", "arg1" };
    Args(2, v);          #   error: invalid conversion from 'const char**' to 'char**' 
    

    and this warns (fails if you fail on warnings):

    char *v[] = { "arg0", "arg1" };  # warning: ISO C++ forbids converting a string constant to 'char*' 
    Args(2, v);         
    

    And so the only workable solution is to use const_cast

    opened by ronen 8
  • Fix VS2015 warning C4702: unreachable code.

    Fix VS2015 warning C4702: unreachable code.

    This clears warning C4702: unreachable code reported while building Clara-based project (e.g. Catch), in Release configuration, using VS2015 Update 1 with warning level /W4.

    Apparently, convertInto invocation resolves to call the always throwing variant:

            template<typename T>
            inline void convertInto( bool, T& ) {
                throw std::runtime_error( "Invalid conversion" );
            }
    

    The issue has been discovered while switching nanodbc project to Catch (lexicalunit/nanodbc#90).

    opened by mloskot 6
  • Parser::operator<< fails for long help strings

    Parser::operator<< fails for long help strings

    I get a std::bad_alloc for help strings that are too wide for my console when trying to do std::cerr << cli << std::endl;

    The problem comes from this line of code:

                    auto row =
                            TextFlow::Column( cols.left ).width( optWidth ).indent( 2 ) +
                            TextFlow::Spacer(4) +
                            TextFlow::Column( cols.right ).width( consoleWidth - 7 - optWidth );
    

    where optWidth is not bounded to be less than consoleWidth - 7

    revisit 
    opened by stefansullivan 5
  • use correct length in string constructors

    use correct length in string constructors

    The string literal was changed without changing the length of the string given to the constructor.

    This causes all my Catch tests to fail when built using AddressSanitizer.

    opened by rioderelfte 5
  • Missing include for std::optional

    Missing include for std::optional

    https://github.com/catchorg/Clara/blob/adb5ec3a5c20defc80286fd6e8c14aeef10fdcd7/include/clara.hpp#L21-L27

    <optional> should probably be included here.

    bug 
    opened by coffee-lord 4
  • The placeholder in a bound option is....odd

    The placeholder in a bound option is....odd

    I'm a bit confused by the placeholder...what I think I want is to be able to set a default value for that field; I know that I can set it in the options struct constructor but I was expecting to be able to use the placeholder. However, that didn't work if the option never got specified...

    So I left the placeholder empty (since it didn't get used) but then when I run it it throws an invalid conversion:

    c:\Projects\ClaraExample\Debug>ClaraExample.exe --host
    Exception: Invalid conversion
    - while parsing: (--host)
    
    c:\Projects\ClaraExample\Debug>ClaraExample.exe --host=fred
    Exception: Invalid conversion
    - while parsing: (--host)
    
    

    This is the code:

    #define CLARA_CONFIG_MAIN
    #include <clara.h>
    #include <iostream>
    
    struct Opt
    {
        Opt()
            : showHelp(false)
            , hostname("api.github.com")
        {}
        std::string processName;
        bool showHelp;
        std::string hostname;
    };
    
    int main(int argc, char* argv[])
    {
        using namespace Clara;
        try
        {
            CommandLine<Opt> cli;
    
            cli.bindProcessName(&Opt::processName);
            cli["-?"]["-h"]["--help"]
                .describe("describes how to use the program")
                .bind(&Opt::showHelp);
            cli["--host"]
                .describe("host to connect to")
                .bind(&Opt::hostname, "");
                //.bind(&Opt::hostname, "must not be empty...but never gets used");
    
            Opt opt;
            cli.parseInto(argc, const_cast<const char**>(argv), opt);
            if (opt.showHelp)
            {
                cli.usage(std::cout, opt.processName);
            }
            else
            {
                std::cout << "Host: " << opt.hostname << std::endl;
            }
        }
        catch (const std::exception& e)
        {
            std::cerr << "Exception: " << e.what() << std::endl;
        }
        catch (...)
        {
            std::cerr << "Unknown exception..." << std::endl;
        }
    
        return 0;
    }
    
    

    I know that I can make this work by specifiying the placeholder, but it never seems to get used (using the 'bind' that is commented out above):

    # This is fine...option specified on the command line...
    c:\Projects\ClaraExample\Debug>ClaraExample.exe --host=fred
    Host: fred
    
    # This fails (and doesn't seem to use the placeholder)...
    c:\Projects\ClaraExample\Debug>ClaraExample.exe --host
    Exception: Expected argument to option: host
    
    

    How do I make the placeholder useful? Can the value be 'optional'?

    Is it possible/desirable to set the bound member variable (perhaps to the value of the placeholder) even if I don't specify the option on the command line (I;m not sure what side effects this might have on existing code...)?

    opened by colonelsammy 4
  • Contribution for docs/examples

    Contribution for docs/examples

    Hi @philsquared
    There is some issues about documentation and it's also add in the roadmap. Did you need help on this point ? Did you already have a table of content or a structure that we can complete ? Did you prefer complete explanation of each functionnality or just a bunch of examples ?

    related : https://github.com/catchorg/Clara/issues/49

    opened by edmBernard 3
  • Add support for std::optional if macro '__cpp_if_constexpr' returns 1

    Add support for std::optional if macro '__cpp_if_constexpr' returns 1

    I really like the idea to put command line options into optional values. This way the parser is not responsible for setting default values. And if one compiles with C++17 this PR would make it possible to deal with std::optional variables

    resolved 
    opened by ferkulat 3
  • "enum" type values

    I'd love a way to constrain a positional argument to "one of" a range of values only. For example, one of a selection of strings like "slow", "medium" or "fast" (for a --speed slow type argument). I couldn't see how to do it without just checking the string value afterwards (which is fine, but this seems like a common enough use case!)

    opened by mattgodbolt 1
  • Issue #93: Fix required option

    Issue #93: Fix required option

    A quick fix for the ``required" option.

    When the option is not provided in the command line, it raises an error. The related unit tests are also added.

    opened by bigwater 1
  • The functionality of required() in Opt

    The functionality of required() in Opt

    I checked the ``required()" function of an Opt and try to use it to represent a mandatory option in my project, however, seems it only affects the printed information of --help.

    Is the "required()" or "isOptional()" function going to raise an exception when the option is not present when parsing the command line?

    Checked the code, seems it is not implemented. // !TBD Check missing required options

    Thank you.

    opened by bigwater 1
  • added cmake target

    added cmake target

    I made two simple changes to make including clara in some cmake projects easier:

    1. defined an interface library that other targets could reference. This doesn't go all out and export targets,etc. as I primarily develop on linux and am not sure how to do that in a windows friendly way. But at least it reduces basic cmake (version > 3.11) inclusion to something like:
    FetchContent_Declare(
      clara_fc
      GIT_REPOSITORY https://github.com/catchorg/Clara.git
      GIT_TAG v1.1.5
      GIT_SHALLOW TRUE
    )
    
    FetchContent_MakeAvailable(clara_fc )
    
    add_executable(main main.cpp)
    
    target_link_libraries(main clara)
    
    1. added an option to skip building the tests if clara is not the top level project.
    opened by jasonbeach 0
Releases(v1.1.5)
Owner
Catch Org
Organisation account for Catch repositories
Catch Org
CLI11 is a command line parser for C++11 and beyond that provides a rich feature set with a simple and intuitive interface.

CLI11: Command line parser for C++11 What's new • Documentation • API Reference CLI11 is a command line parser for C++11 and beyond that provides a ri

null 2.1k Jul 5, 2022
Lightweight C++ command line option parser

Release versions Note that master is generally a work in progress, and you probably want to use a tagged release version. Version 3 breaking changes I

null 3.1k Jul 6, 2022
Tiny command-line parser for C / C++

tinyargs Another commandline argument parser for C / C++. This one is tiny, source only, and builds cleanly with -Wall -pedantic under C99 and C++11 o

Erik Agsjö 5 Nov 11, 2021
led is a line-oriented text editor in command line

led is a line-oriented text editor in command line. This editor is similar to the standard program on unix systems - GNU ed. But i'm not going to make an exact clone of that program, it's just a pet project.

Artem Mironov 9 Jun 14, 2022
easy to use, powerful & expressive command line argument parsing for modern C++ / single header / usage & doc generation

clipp - command line interfaces for modern C++ Easy to use, powerful and expressive command line argument handling for C++11/14/17 contained in a sing

André Müller 888 Jun 30, 2022
Simple command line utilities for extracting data from Fallout 4 and 76 files

fo76utils Simple command line utilities for extracting data from Fallout 4 and 76 files. baunpack - list the contents of, or extract from .BA2 archive

null 9 Jun 13, 2022
Simple command line tool that processes image files using the FidelityFX Super Resolution (FSR) or Contrast Adaptive Sharpening (CAS) shader systems.

Simple command line tool that processes image files using the FidelityFX Super Resolution (FSR) or Contrast Adaptive Sharpening (CAS) shader systems.

GPUOpen Effects 174 Jun 26, 2022
Simple, command line based player toolkit for the Ironsworn tabletop RPG

isscrolls - Command line based player toolkit for the Ironsworn tabletop RPG isscrolls is a simple toolkit for players of the Ironsworn tabletop RPG.

null 5 Jun 1, 2022
A simple command line application in order to create new Code workspaces.

mkcws Summary A simple command line application in order to create new Code workspaces. License This project's license is GPL 2. The whole license tex

Kevin Matthes 0 Apr 1, 2022
Simple command line tools to create/extract X4 .cat+.dat files

x4cat Simple command line tools to to create/extract X4 .cat+.dat files x4encat Usage: x4encat <archive name> Looks for a directory named <archive nam

Alexander Sago 1 Oct 31, 2021
Simple Driver loading command-line utility.

lddrv Simple Driver loading command-line utility. Command Line Load a driver: "lddrv.exe -operation create -binpath C:\Dev\TestDriver.sys -svcname Tes

Josh S. 2 Dec 21, 2021
udmp-parser: A Windows user minidump C++ parser library.

udmp-parser: A Windows user minidump C++ parser library. This is a cross-platform (Windows / Linux / OSX / x86 / x64) C++ library that parses Windows

Axel Souchet 90 Jul 1, 2022
JSONes - c++ json parser & writer. Simple api. Easy to use.

JSONes Just another small json parser and writer. It has no reflection or fancy specs. It is tested with examples at json.org Only standart library. N

Enes Kaya ÖCAL 2 Dec 28, 2021
A single header C++ library for parsing command line arguments and options with minimal amount of code

Quick Arg Parser Tired of unwieldy tools like getopt or argp? Quick Arg Parser is a single header C++ library for parsing command line arguments

null 44 Feb 21, 2022
null 76 Apr 18, 2022
Rizin - UNIX-like reverse engineering framework and command-line toolset.

Rizin - UNIX-like reverse engineering framework and command-line toolset.

Rizin Organization 1.5k Jul 7, 2022
A command line tool for numerically computing Out-of-time-ordered correlations for N=4 supersymmetric Yang-Mills theory and Beta deformed N=4 SYM.

A command line tool to compute OTOC for N=4 supersymmetric Yang–Mills theory This is a command line tool to numerically compute Out-of-time-ordered co

Gaoli Chen 1 Oct 16, 2021
C++ Library for pulling system and hardware information, without hitting the command line.

infoware C++ Library for pulling system and hardware information, without hitting the command line. Requirements No non-built-in ones by default. Some

The Phantom Derpstorm 287 Jun 27, 2022
EAMain provides a multi-platform entry point used for platforms that don't support console output, return codes and command-line arguments.

EAMain provides a multi-platform entry point used for platforms that don't support console output, return codes and command-line arguments.

Electronic Arts 30 May 17, 2022