Argh! A minimalist argument handler.

logo

Frustration-free command line processing

Language Standard License Try it online Build Status

So many different command line processing libraries out there and none of them just work!
Some bring their whole extended family of related and unrelated external dependencies (yes, I'm looking at you Boost).
Some require quirky syntax and/or very verbose setups that sacrifice simplicity for the generation of a cute usage message and validation. Many come to dominate your main() file and yet others do not build on multiple plaforms - for some even their own tests and trivial usage cause crashes on some systems. Argh!

If you're writing a highly-sophisticated command line tool, then Boost.Program_options and its kind might give you many advanced options. However, if you need to get up and running quickly, effectively and with minimal fuss, give the single header-file argh a try.

TL;DR

It doesn't get much simpler than this:

#include <iostream>
#include "argh.h"

int main(int, char* argv[])
{
    argh::parser cmdl(argv);

    if (cmdl[{ "-v", "--verbose" }])
        std::cout << "Verbose, I am.\n";

    return EXIT_SUCCESS;
}

Philosophy

Contrary to many alternatives, argh takes a minimalist laissez-faire approach, very suitable for fuss-less prototyping with the following rules:

The API is:

  • Minimalistic but expressive:
    • No getters nor binders
    • Just the [] and () operators
    • Easy iteration (range-for too)
  • You don't pay for what you don't use
  • Conversion to typed variables happens (via std::istream >>) on the user side after the parsing phase
  • No exceptions thrown for failures
  • Liberal BSD license
  • Single header file
  • No non-std dependencies

argh does not care about:

  • How many '-' preceded your option
  • Which flags and options you support - that is your responsibility
  • Syntax validation: any command line is a valid (not necessarily unique) combination of positional parameters, flags and options
  • Automatically producing a usage message

Tutorial

Create parser:

auto cmdl = argh::parser(argc, argv);

In fact, you can even drop argc. This will also work:

argh::parser cmdl(argv);

Positional argument access by (integer) index with [<size_t>]:

cout << "Exe name is: " << cmdl[0] << '\n';
                               ^^^
assert(cmdl[10000].empty()); // out-of-bound index returns empty string
            ^^^^^

Boolean flag argument access by (string) name with [<std::string>]:

cout << "Verbose mode is " << ( cmdl["verbose"] ? "ON" : "OFF" ) << '\n';
                                    ^^^^^^^^^^^

Any dashes are trimmed so are not required.

Your flag can have several alternatives, just list them with [{ "<name-1>", "<name-2>", ... }]:

cout << "Verbose mode is " << ( cmdl[{ "-v", "--verbose" }] ? "ON" : "OFF" ) << '\n';
                                    ^^^^^^^^^^^^^^^^^^^^^^^

Beyond bool and std::string access with [], as shown above, we can also access the argument values as an std::istream. This is very useful for type conversions.

std::istream positional argument access by (integer) index with (<size_t>):

std::string my_app_name;
cmdl(0) >> my_app_name; // streaming into a string
    ^^^
cout << "Exe name is: " << my_app_name << '\n';

We can also check if a particular positional arg was given or not (this is like using [<std::string>] above):

if (!cmdl(10))
  cerr << "Must provide at least 10 arguments!" << '\n';
else if (cmdl(11))
  cout << "11th argument  is: " << cmdl[11] << '\n';

But we can also set default values for positional arguments. These are passed as the second argument:

float scale_factor;
cmdl(2, 1.0f) >> scale_factor;
     ^^^^^^^

If the position argument was not given or the streaming conversion failed, the default value will be used.

Similarly, parameters can be accessed by name(s) (i.e. by string or list of string literals) with:
(<std::string> [, <default value>]) or ({ "<name-1>", "<name-2>", ... } [, <default value>]):

float scale_factor;
cmdl("scale", 1.0f) >> scale_factor; // Use 1.0f as default value
     ^^^^^^^^^^^^^

float threshold;
if (!(cmdl({ "-t", "--threshold"}) >> threshold)) // Check for missing param and/or bad (inconvertible) param value
  cerr << "Must provide a valid threshold value! Got '" << cmdl("threshold").str() << "'" << endl;
else                                                                        ^^^^^^
  cout << "Threshold set to: " << threshold << '\n';

As shown above, use std::istream::str() to get the param value as a std:string or just stream the value into a variable of a suitable type. Standard stream state indicates failure, including when the argument was not given.
When using multiple names, the first value found will be returned.

Positional arguments can be iterated upon directly using range-for:

cout << "Positional args:\n";
for (auto& pos_arg : cmdl)
  cout << '\t' << pos_arg << '\n';

Similarly, cmdl.size() will return the count of positional arguments.

Positional arguments, flags and parameters are accessible as "ranges":

cout << "Positional args:\n";
for (auto& pos_arg : cmdl.pos_args())
  cout << '\t' << pos_arg << '\n';

cout << "\nFlags:\n";
for (auto& flag : cmdl.flags())
  cout << '\t' << flag << '\n';

cout << "\nParameters:\n";
for (auto& param : cmdl.params())
  cout << '\t' << param.first << " : " << param.second << '\n';

By default, options are assumed to be boolean flags. When this is not what you want, there are several ways to specify when an option is a parameter with an associated value.

Specify PREFER_PARAM_FOR_UNREG_OPTION mode to interpret any <option> <non-option> as <parameter-name> <parameter-value>:

using namespace argh;
auto cmdl = parser(argc, argv, parser::PREFER_PARAM_FOR_UNREG_OPTION);
                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
cout << cmdl("--threshold").str() << '\n';

Pre-register an expected parameter name with add_param() (before calling parse()):

argh::parser cmdl;
cmdl.add_param("threshold"); // pre-register "threshold" as a param: name + value
cmdl.parse(argc, argv);
cout << cmdl("threshold").str() << '\n';

You can also batch pre-register multiple options as parameters with add_params({ ... }):

argh::parser cmdl;
cmdl.add_params({ "-t", "--threshold", "-s", "--scale" }); // batch pre-register multiple params: name + value
cmdl.parse(argc, argv);
cout << cmdl("threshold").str() << '\n';

Since pre-registration has to be done before parsing, we might as well just use the ctor:

argh::parser cmdl({ "-t", "--threshold", "-s", "--scale" }); // batch pre-register multiple params: name + value
cmdl.parse(argc, argv);
cout << cmdl("threshold").str() << '\n';

Use a = (with no spaces around it) within the option when calling the app:

>> my_app --threshold=42
42

Tips

  • By default, arguments of the form --<name>=<value> (with no spaces, one or more dashes), e.g. --answer=42, will be parsed as <parameter-name> <parameter-value>. To disable this specify the NO_SPLIT_ON_EQUALSIGN mode.
  • Specifying the SINGLE_DASH_IS_MULTIFLAG mode, a.k.a Compound Arguments, will split a single-hyphen argument into multiple single-character flags (as is common in various POSIX tools).
  • When using SINGLE_DASH_IS_MULTIFLAG, you can still pre-register the last character as a param with the value, such that if we pre-register f as a param, >> myapp -xvf 42 will be parsed with two boolean flags x and v and a one param f=42.
  • When parsing parameter values as strings that may contain spaces (e.g. --config="C:\Folder\With Space\Config.ini"), prefer using .str() instead of >> to avoid the default automatic whitespace input stream tokenization:
    cout << cmdl({ "-c", "--config" }).str().

Terminology

Any command line is composed of 2 types of Args:

  1. Positional Args:
    Free standing, in-order, values
    e.g. config.json
  2. Options:
    Args beginning with - (and that are not negative numbers).
    We identify 2 kinds of Options:
    1. Flags:
      Boolean options => (appear ? true : false)
      e.g. -v, --verbose
    2. Parameters:
      A named value followed by a non-option value
      e.g. --gamma 2.2

Thus, any command line can always be broken into some combination of (1) positional args (2) flags and (3) parameters.

API Summary

Parsing

Parse the command line using either

  • The parse() method: parser::parse([argc,] argv [, mode]); or
  • The shorter form using the ctor directly: argh::parser([argc,] argv [, mode]);
  • The shortest form does not even require argc, so in default mode just use:
    parser(argv);

Special Parsing Modes

Extra flexibility can be added by specifying parsing modes:

  • NO_SPLIT_ON_EQUALSIGN: By default, an option of the form --pi=22/7 will be parsed as a parameter pi with an associated value "22/7". By setting this mode, it will be not be broken at the =.
  • PREFER_FLAG_FOR_UNREG_OPTION: Split <option> <non-option> into <flag> and <pos_arg>. e.g. myapp -v config.json will have v as a lit flag and config.json as a positional arg. This is the default mode.
  • PREFER_PARAM_FOR_UNREG_OPTION: Interpret <option> <non-option> as <parameter-name> <parameter-value>. e.g. myapp --gamma 2.2 will have gamma as a parameter with the value "2.2".
  • SINGLE_DASH_IS_MULTIFLAG: Splits an option with a single dash into separate boolean flags, one for each letter (a.k.a Compound Arguments). e.g. in this mode, -xvf will be parsed as 3 separate flags: x, v, f.

Argument Access

  • Use bracket operators to access flags and positional args:

    • Use operator[index] to access position arg strings by index:
      • e.g. assert(cmdl[0] == argv[0]), the app name.
    • Use operator[string] to access boolean flags by name:
      • e.g. if (cmdl["v"]) make_verbose();
    • Use operator[{...}] to access boolean flags by multiple names:
      • e.g. if (cmdl[{ "v", "verbose" }]) make_verbose();
  • Use the parenthesis operators to get an std::istream to stream values from parameters and positional args:

    • Use operator(index) to access position arg istream by index:
      • e.g. cmdl(0) >> my_app_name.
    • Use operator(string) to access parameter values by name:
      • e.g. cmdl("scale") >> scale_factor;
    • Use operator({...}) to access parameter values by multiple names:
      • e.g. cmdl({ "-s", "--scale" }) >> scale_factor;
    • Use operator(index, <default>) and operator(string/{list}, <default>) to stream a default value if the arg did not appear on the command line:
      • e.g. cmdl("scale", 1.0f) >> scale_factor;

The streaming happens at the user's side, so conversion failure can be checked there: e.g

if (!(cmdl("scale") >> scale_factor))
  cerr << "Must provide valid scale factor!" << '\n';

Use the .str() method to get the parameter value as a string: e.g. cmdl("name").str();

More Methods

  • Use parser::add_param(), parser::add_params() or the parser({...}) constructor to optionally pre-register a parameter name when in PREFER_FLAG_FOR_UNREG_OPTION mode.
  • Use parser, parser::pos_args(), parser::flags() and parser::params() to access and iterate over the Arg containers directly.

Finding Argh!

  • copy argh.h somewhere into your projects directories
  • or include the repository as a submodule
  • or use CMake!

Finding Argh! - CMake

The provided CMakeLists.txt generates targets for tests, a demo application and an install target to install argh system-wide and make it known to CMake. You can control generation of test and example targets using the options BUILD_TESTS and BUILD_EXAMPLES. Only argh alongside its license and readme will be installed - not tests and demo!

Add argh to your CMake-project by using

find_package(argh)

The package exports argh INTERFACE library target and argh_INCLUDE_DIR variable. Make argh.h known to your compiler by using one of the following methods; both will make the location of argh.h known to the compiler, not link in a precompiled library - even when using target_link_libraries().

target_include_directories(${MY_TARGET_NAME} PRIVATE "${argh_INCLUDE_DIR}")
#OR
target_link_libraries(${MY_TARGET_NAME} argh)

Buck

The Buck build system is also supported.

Run the example:

buck run :example

Run the tests:

buck run :tests
buck run test_package

If you take argh as a submodule, then the visible target is //:argh.

Colophon

I your feedback.
If you found Argh! useful - do Tweet about it to let me know.
If you found it lacking, please post an issue.

Comments
  • doctest.h:1398:92: error: use of deleted function

    doctest.h:1398:92: error: use of deleted function

    Hi, the Debian packaged version of argh received a bug report which says:

        In file included from /<<PKGBUILDDIR>>/argh_tests.cpp:4:
        /usr/include/doctest/doctest.h: In instantiation of ‘doctest::detail::Expression_lhs<const L> doctest::detail::ExpressionDecomposer::operator<<(const L&&) [with L = std::__cxx11::  basic_istringstream<char>]’:
        /<<PKGBUILDDIR>>/argh_tests.cpp:62:5:   required from here
        /usr/include/doctest/doctest.h:1398:92: error: use of deleted function ‘doctest::detail::Expression_lhs<const std::__cxx11::basic_istringstream<char> >::Expression_lhs(doctest::    detail::Expression_lhs<const std::__cxx11::basic_istringstream<char> >&&)’
         1398 |             return Expression_lhs<const L>(doctest::detail::forward<const L>(operand), m_at);
              |                                                                                            ^
        In file included from /<<PKGBUILDDIR>>/argh_tests.cpp:4:
        /usr/include/doctest/doctest.h:1317:12: note: ‘doctest::detail::Expression_lhs<const std::__cxx11::basic_istringstream<char> >::Expression_lhs(doctest::detail::Expression_lhs<const std::__cxx11::basic_istringstream<char> >&&)’ is implicitly deleted because the default definition would be ill-formed:
         1317 |     struct Expression_lhs
              |            ^~~~~~~~~~~~~~
        /usr/include/doctest/doctest.h:1317:12: error: use of deleted function ‘std::__cxx11::basic_istringstream<_CharT, _Traits, _Alloc>::basic_istringstream(const std::__cxx11::         basic_istringstream<_CharT, _Traits, _Alloc>&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’
        In file included from /<<PKGBUILDDIR>>/argh.h:4,
                         from /<<PKGBUILDDIR>>/argh_tests.cpp:1:
        /usr/include/c++/11/sstream:619:7: note: declared here
          619 |       basic_istringstream(const basic_istringstream&) = delete;
              |       ^~~~~~~~~~~~~~~~~~~
        [ 75%] Linking CXX executable argh_example
    

    Any idea how to fix this? Kind regards, Andreas.

  • Case insensitivity mode

    Case insensitivity mode

    Hi, thank you for your amazing work! I wonder if you could add a mode to enable cases insensitivity for option/flag name matching? Sure, i could manually preprocess arguments beforehand, but that would require to make my own flag parser and then apply case transformations, which is something i don't want to bother with. I just wonder if something like CASE_INSENSITIVE_FLAG_MATCH could be added, this would be really important feature for my project. This would just transform any flag name into lower cased one on parsing and store it, but the operators don't have to bother doing transformations, it would expect you to always enter lower cased names to decrease the complexity.

    The lower cased transformation could be something as simple as:

    std::transform(s.begin(), s.end(), s.begin(), [](unsigned char c) { return std::tolower(c) });
    

    which is completely in bounds of std libs and c++11 requirements.

  • Uncompileable with clang 14

    Uncompileable with clang 14

    In file included from ../argh_tests.cpp:4:
    ../doctest.h:4403:33: error: variable length array declaration not allowed at file scope
            static char             altStackMem[SIGSTKSZ];
                                    ^           ~~~~~~~~
    In file included from ../argh_tests.cpp:4:
    ../doctest.h:4453:36: error: variable length array declaration not allowed at file scope
        char    FatalConditionHandler::altStackMem[SIGSTKSZ] = {};
                                       ^           ~~~~~~~~
    
  • Multiple params with the same name?

    Multiple params with the same name?

    Is it possible to do something like this:

    myprogram -p foo -p bar -p baz

    and be able to get all three -p parameter values? When I try I can only get the first one.

  • Don't install 'LICENSE' or 'README.md' directly to the installation directory.

    Don't install 'LICENSE' or 'README.md' directly to the installation directory.

    This change unconditionally uses GNUInstallDirs which will correctly 'namespace' these files with the 'argh' project name.

    =========

    The names 'LICENSE' and 'README.md' are extremely common and likely to be taken by other ports. This happened in a recent full vcpkg catalog rebuild:

    Starting package 757/1254: qt-advanced-docking-system:x86-windows Building package qt-advanced-docking-system[core]:x86-windows... Could not locate cached archive: C:\agent_work\1\s\archives\a1\a1507296ead5788137561997571557204aaac78f.zip -- Downloading https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/archive/661d0c4356ab61d155b53718aa1bf6bab86dad13.tar.gz... -- Extracting source C:/agent/_work/1/s/downloads/githubuser0xFFFF-Qt-Advanced-Docking-System-661d0c4356ab61d155b53718aa1bf6bab86dad13.tar.gz -- Applying patch config_changes.patch -- Using source at C:/agent/_work/1/s/buildtrees/qt-advanced-docking-system/src/bab86dad13-3088149a9b -- Configuring x86-windows -- Building x86-windows-dbg -- Building x86-windows-rel -- Installing: C:/agent/_work/1/s/packages/qt-advanced-docking-system_x86-windows/share/qt-advanced-docking-system/copyright -- Performing post-build validation -- Performing post-build validation done Stored binary cache: C:\agent_work\1\s\archives\a1\a1507296ead5788137561997571557204aaac78f.zip Building package qt-advanced-docking-system[core]:x86-windows... done Installing package qt-advanced-docking-system[core]:x86-windows... The following files are already installed in C:/agent/_work/1/s/installed/x86-windows and are in conflict with qt-advanced-docking-system:x86-windows

    Installed by argh:x86-windows license/LICENSE

    Elapsed time for package qt-advanced-docking-system:x86-windows: 11.09 s

  • Passing the rest of arguments to the next stage parser

    Passing the rest of arguments to the next stage parser

    #include <string>
    #include <iostream>
    
    #include <argh.h>
    
    
    int main(){
    	argh::parser app;
    	app.add_param("odf");
    	app.add_param("ods");
    
    
    	const char *argv[]{"test", "--ods", "ods", "--odf", "1", "aaa", "10", "-b", "--bbb", nullptr};
    	//                 argv[0]           ods      odf   mpi  [       remaining          ]
    
    	int argc = sizeof(argv) / sizeof(argv[0]) - 1;
    
    	app.parse(argc, argv);
    
    	int i = 0;
    
    	// `test ods aaa 10`
    	// All the dashed arguments : `-b` `--bbb` - are missing
    	while(auto curArgObj = app(i++)){
    		std::string curArg;
    		curArgObj >> curArg;
    		std::cout << curArg << " ";
    	}
    	std::cout << std::endl;
    
    	return 0;
    }
    

    As one can see, argh eats even the args that have not been registered, but we wanna pass them to the next stage cli args parser.

  • Can't include in more than one T.U., due to only one method being declared inline

    Can't include in more than one T.U., due to only one method being declared inline

    Any reason why only void parser::parse(const char * const argv[], int mode) is defined inline? I know it might not be the common use case, but I'd need to include argh.h in multiple TUs, and this is causing multiple definitions error while linking.

    Am I missing something?

  • question: Several arguments for a param support

    question: Several arguments for a param support

    Is there an easy way to parse things like:

    --output outputdir --input file1 file2 file3

    I need several values for each parameter in some cases, and cannot know in advance the position of each argument.

  • Conan center mark argh! as deprecated

    Conan center mark argh! as deprecated

    Hi @adishavit,

    Wanted to give a try and saw that conan center is marking this as deprecated https://conan.io/center/argh?os=&tab=configuration. Not sure if is an issue in the conanfile.py configuration or something.

    Thanks!

  • How parse compound params

    How parse compound params

    Hi there,

    I would like to know how I can capture a complex parameter and parse it accordingly.

    For example, I have a complex type vec3f composed of 3 floats named x, y, z.

    I want to define a parameter to be parsed where on the command-line I can specify —position=1.00,-3.14,3 and the result is that these in turn are parsed to fill vec3f( 1.00, -3.14, 3) inside my code.

    Any comment would be welcome.

  • Multiple parameters with the same name

    Multiple parameters with the same name

    Hi. Thank you very much for working on this awesome library! I'm having pleasure using it. Please consider this fix which fixes #36 . With this patch you'll be able to pass multiple parameters with the same name and work with a subset of parameters like this:

    // app --foo=value1 --foo=value2 --foo=value3
    auto fooArgsCounr = args.params("foo").size();  // 3
    for (const auto& params : args.params("foo")) {
        // iterate over "foo" params and "value1", "value2" and "value3" values
    }
    

    Thanks in advance!

  • Support list of same parameters

    Support list of same parameters

    Hi,

    Can you add support list of same parameters?

    Example:

    nativium --build=debug  --build=release  --build=relwithdebinfo
    

    Get all --build parameters and a vector of it.

    Thanks.

  • accept vector<string> for argv

    accept vector for argv

    Because sometimes you don't have access to the command line arguments in their raw form...

    std::vector<std::string> args;
    int main(int argc, char** argv) {
       for (size_t i=0; i < argc; ++i)
          args.emplace_back(argv[0]);
       run_application();
    }
    
    void application() {
       auto cmdl = argh::parser(args);
       // ...
    }
    
  • Set Up CI

    Set Up CI

    We've had various reports of backward compatibility issues with certain platforms.
    It would be great if someone can help set up a CI service for multiple platforms to continuously check the project.

  • Added instructions on how to use argh with tipi.build

    Added instructions on how to use argh with tipi.build

    Hey! I just stumbled upon argh during a demo with a customer and used it to demo our tool (they are using it). As depending on it with tipi just worked out of the box I though you may be happy to add the instructions about how to use argh in tipi.build projects to the readme.

    I hope this is okay with you. If there's something broken we'd love to help and fix.

    P.S.: Full disclaimer: I'm one of the co-founders of tipi.build

Argument Parser for Modern C++
Argument Parser for Modern C++

Highlights Single header file Requires C++17 MIT License Quick Start Simply include argparse.hpp and you're good to go. #include <argparse/argparse.hp

Dec 1, 2022
A simple header-only C++ argument parser library. Supposed to be flexible and powerful, and attempts to be compatible with the functionality of the Python standard argparse library (though not necessarily the API).

args Note that this library is essentially in maintenance mode. I haven't had the time to work on it or give it the love that it deserves. I'm not add

Aug 31, 2021
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

Nov 29, 2022
⛳ Simple, extensible, header-only C++17 argument parser released into the public domain.

⛳ flags Simple, extensible, header-only C++17 argument parser released into the public domain. why requirements api get get (with default value) posit

Oct 25, 2022
SimPle SHell - minimalist Unix interactive shell written in a single C file

SimPle SHell - minimalist Unix interactive shell written in a single C file. The shell does not support scripting yet and is in an early stage of development. If you notice any bug, please open an issue on github.

Oct 24, 2021
Get the ability to use variable argument lists in C++ without requiring the first parameter! Meant to support a WG14 proposal to fix up not having empty argument lists.

Vargs Alright, it's time to commit code crimes for the greater good! What if you did not need to pass an initial parameter to your C++ ... functions?

Aug 9, 2022
Benchmarking algebraic effect handler implementations

Benchmarking Effect handlers. Currently supported libraries and languages are: kk (extension .kk), Koka. ml (extension .ml), multi-core OCaml.

Dec 18, 2021
A simple header-only C++ argument parser library. Supposed to be flexible and powerful, and attempts to be compatible with the functionality of the Python standard argparse library (though not necessarily the API).

args Note that this library is essentially in maintenance mode. I haven't had the time to work on it or give it the love that it deserves. I'm not add

Dec 2, 2022
A collection of single-file C libraries. (generic containers, random number generation, argument parsing and other functionalities)

cauldron A collection of single-file C libraries and tools with the goal to be portable and modifiable. Libraries library description arena-allocator.

Oct 26, 2022
Cobalt Strike Beacon Object File (BOF) that takes the name of of a PE file as an argument and spawns the process in a suspended state
Cobalt Strike Beacon Object File (BOF) that takes the name of of a PE file as an argument and spawns the process in a suspended state

Beacon Object File (BOF) that spawns an arbitrary process from beacons memory. Supports Parent Process ID (PPID) spoofing & blocking non-MS signed DLLs from loading into the processes memory (some EDR DLLs).

Dec 1, 2022
Argument Parser for Modern C++
Argument Parser for Modern C++

Highlights Single header file Requires C++17 MIT License Quick Start Simply include argparse.hpp and you're good to go. #include <argparse/argparse.hp

Dec 1, 2022
A simple header-only C++ argument parser library. Supposed to be flexible and powerful, and attempts to be compatible with the functionality of the Python standard argparse library (though not necessarily the API).

args Note that this library is essentially in maintenance mode. I haven't had the time to work on it or give it the love that it deserves. I'm not add

Aug 31, 2021
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

Nov 29, 2022
⛳ Simple, extensible, header-only C++17 argument parser released into the public domain.

⛳ flags Simple, extensible, header-only C++17 argument parser released into the public domain. why requirements api get get (with default value) posit

Oct 25, 2022
Fuzzing with the generated argument
Fuzzing with the generated argument

WuLearn-fuzz Fuzzing with the generated argument. It is almost based on Yuan-fuzz. You can see more detail in it. Just change it for fun. Usage Instal

Mar 14, 2022
communicate between usermode and kernelmode through a swapped qword ptr argument

communicate between usermode and kernelmode through a swapped qword ptr argument

Nov 29, 2022
minimalist reddit2nntp gateway
minimalist reddit2nntp gateway

nntpit This is a simple reddit2nntp gateway server that lets you use a newsreader to follow discussions on reddit. The intention is for you to run it

Nov 24, 2022
A minimalist andf platform-agnostic application layer for writing graphical applications, with a strong emphasis on simplicity and ease of use.
A minimalist andf platform-agnostic application layer for writing graphical applications, with a strong emphasis on simplicity and ease of use.

SlimApp A minimalist(*) and platform-agnostic application layer for writing graphical applications. Available as either a single header file or a dire

Oct 5, 2022
A minimalist library with basic facilities for developing interactive real-time 3D applications, with a strong emphasis on simplicity and ease of use.
A minimalist library with basic facilities for developing interactive real-time 3D applications, with a strong emphasis on simplicity and ease of use.

SlimEngine A minimalist and platform-agnostic base project for interactive graphical applications (2D/3D) with a strong emphasis on simplicity, ease o

Oct 29, 2022
Data compression utility for minimalist demoscene programs.

bzpack Bzpack is a data compression utility which targets retrocomputing and demoscene enthusiasts. Given the artificially imposed size limits on prog

Jul 27, 2022