sjrdc / px

a command line argument parser written in modern C++

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Contributors Forks Stargazers Issues GPLv3 License

build and test

About The Project

px is a command line argument parser written in modern C++.

why?

Don't we have enough command line argument parsers already? Probably, yes... This is meant to be an excercise in the use of some C++17 and C++20 features, as well as a way to provide a parser that

  • adheres to the DRY principle; in many of these libraries, we need to first provide names to arguments, to later retrieve values with the same name, or assign some default, then validate the retrieved value. All of this could be a lot leaner.
  • facilitates the use of the filesystem library (to obtain path variable directly from an argument)
  • by no means aims to provide many different ways to specify arguments; one simple syntax is sufficient

px is built with

Getting Started

To get a local copy up and running follow these simple steps.

prerequisites

px is a header only library without any dependencies; as such there are no prerequisites, except a compiler that supports modern C++. Tests are written with google test and hence require the presence of this library to build and run.

example usage

#include "px.h"
#include <filesystem>

namespace fs = std::filesystem;

void show_kittens(int i)
{
}

void store_kittens(const fs::path& p)
{
}

int main(int argc, char** argv)
{
    int i = 1;
    fs::path pth;
    
    px::command_line cli("the program name");
    cli.add_value_argument<int>("integer", "-i")
        .set_description("the number of kittens to show; must be large than 0 and 5 at most")
        .set_validator([](auto i) { return i > 0 && i <= 5; })
        .bind(&i);
    cli.add_value_argument<fs::path>("path", "-p")
        .set_required(true)
        .set_description("the path to use for storage of the shown kittens (must be an existing file)")
        .bind(&pth)
        .set_validator([](auto p) { return fs::exists(p) && fs::is_regular_file(p); });
    auto& help_arg = cli.add_flag_argument("help", "-h")
        .set_alternate_tag("--help");
    
    try
    {
        cli.parse(argc, argv);
    }
    catch (std::runtime_error& e)
    {
        if (help_arg.get_value())
        {
            cli.print_help(std::cout);
            return 0;
        }
        else
        {
            std::cerr << e.what() << "\n\n";
            cli.print_help(std::cerr);
            return 1          ;        
        }
    }
    
    show_kittens(i);
    store_kittens(pth);
    
    return 0;
}

option syntax

While the aim is to provide just minimal support for option syntaxes, the following is assumed

  • an argument can be tag-based (i.e. there is a tag preceding the value) or position-based (i.e., the arguments are distinguished by their order)
  • an argument tag starts with a hyphen
  • a long argument tag starts with two hyphens
  • arguments of the two categories may both be specified when invoking a program from the command line
  • two hyphens are used to separate tag-based arguments from position-based arguments

Roadmap

See the open issues for a list of proposed features (and known issues).

Contributing

Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are greatly appreciated.

  1. Fork the Project
  2. Create your Feature Branch (git checkout -b feature/AmazingFeature)
  3. Commit your Changes (git commit -m 'Add some AmazingFeature')
  4. Push to the Branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

License

Distributed under the GPLv3 License. See LICENSE for more information.

Acknowledgements

About

a command line argument parser written in modern C++

License:GNU General Public License v3.0


Languages

Language:C++ 92.5%Language:CMake 6.0%Language:Starlark 1.5%