{"id":15047950,"url":"https://github.com/juzzlin/argengine","last_synced_at":"2026-02-25T07:38:34.810Z","repository":{"id":94664751,"uuid":"242378397","full_name":"juzzlin/Argengine","owner":"juzzlin","description":"A simple CLI argument (option) parser library for modern C++ based on lambda callbacks","archived":false,"fork":false,"pushed_at":"2025-02-08T12:22:45.000Z","size":129,"stargazers_count":11,"open_issues_count":2,"forks_count":5,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-10T01:10:34.633Z","etag":null,"topics":["argument-parser","argument-parsing","command-line-parser","cplusplus","cplusplus-11","cplusplus-17","lambda-functions","library","linux","modern-cpp","option-parser","windows"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/juzzlin.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-02-22T17:01:13.000Z","updated_at":"2025-02-08T12:22:49.000Z","dependencies_parsed_at":"2023-10-16T10:54:16.075Z","dependency_job_id":"d2fc3da0-2e86-43b5-9f37-14a7c4f2831a","html_url":"https://github.com/juzzlin/Argengine","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/juzzlin%2FArgengine","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/juzzlin%2FArgengine/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/juzzlin%2FArgengine/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/juzzlin%2FArgengine/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/juzzlin","download_url":"https://codeload.github.com/juzzlin/Argengine/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248137886,"owners_count":21053775,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["argument-parser","argument-parsing","command-line-parser","cplusplus","cplusplus-11","cplusplus-17","lambda-functions","library","linux","modern-cpp","option-parser","windows"],"created_at":"2024-09-24T21:06:12.496Z","updated_at":"2026-02-25T07:38:34.758Z","avatar_url":"https://github.com/juzzlin.png","language":"C++","readme":"Argengine\n=========\n\nLooking for a simple CLI argument parser for your C++ project? `Argengine` might be for you.\n\n# Features\n\n* Automatic help generation\n* Based on simple lambda callbacks\n* Builds with CMake\n* Designed for modern C++\n* Extensive unit tests\n* Single .hpp/.cpp\n* Very easy to use\n\n# Design Choices\n\n* Argument values are passed as strings. The client is responsible for possible data conversions.\n* Most of the data is passed by value for a cleaner API. It is assumed that argument parsing is not the performance bottleneck of your application\n* The PIMPL idiom is used to maintain API/ABI compatibility\n\n# Installation\n\n## Use from sources\n\nJust add `src/argengine.hpp` and `src/argengine.cpp` to your project and start using it!\n\n## Use as a CMake subproject\n\nCopy contents of `Argengine` under your main project (or clone as a Git submodule).\n\nIn your `CMakeLists.txt`:\n\n```\nadd_subdirectory(Argengine EXCLUDE_FROM_ALL)\ninclude_directories(Argengine/src)\n```\n\nLink to the library:\n\n```\ntarget_link_libraries(${YOUR_TARGET_NAME} Argengine_static)\n```\n\nIn your code:\n\n```\n#include \"argengine.hpp\"\n```\n\n## Use as a library\n\nBuild and install:\n\n`$ mkdir build \u0026\u0026 cd build`\n\n`$ cmake ..`\n\n`$ make`\n\n`$ sudo make install`\n\nLink to `libArgengine_static.a` or `libArgengine.so`.\n\n# Usage In A Nutshell\n\nThe basic principle is that for each option a lambda callback is added.\n\nA valueless callback:\n\n```\n    ...\n\n    juzzlin::Argengine ae(argc, argv);\n    ae.addOption({\"-f\", \"--foo\"}, [] {\n        // Do something\n    });\n    ae.parse();\n\n    ...\n```\n\nA single-value callback:\n\n```\n    ...\n\n    juzzlin::Argengine ae(argc, argv);\n    ae.addOption({\"-f\", \"--foo\"}, [] (std::string value) {\n        // Do something with value\n    });\n    ae.parse();\n\n    ...\n```\n\nThere can be as many option variants as liked, usually the short and long versions, e.g `-f` and `--foo`.\n\n`Argengine` doesn't care about the naming of the options and they can be anything: `-f`, `a`, `/c`, `foo`, `--foo` ...\n\nPositional arguments (for example a file name for a text editor after other options) can be received with a single callback:\n\n```\n    ...\n\n    juzzlin::Argengine ae(argc, argv);\n    ae.setPositionalArgumentCallback([] (std::vector\u003cstd::string\u003e args) {\n        // Do something with arguments\n    });\n    ae.parse();\n\n    ...\n```\n\nIf the callback for positional arguments is set, then no errors about `unknown options` will occur as all additional options will be taken as positional arguments.\n\n# Help\n\nBy default, `Argengine` will create a simple help that is shown with `-h` or `--help`.\n\nWithout any additional options a possible output will look like this:\n\n```\nUsage: ./ex1 [OPTIONS]\n\nOptions:\n\n-h, --help  Show this help.\n```\n\nThe help can be manually printed with `Argengine::printHelp()`.\n\nThe default help can be disabled by constructing `Argengine` with `Argengine::Argengine(argc, argv, false)`.\n\n## Custom help\n\nA custom help can be added with:\n\n`void Argengine::addHelp(OptionVariants optionVariants, ValuelessCallback callback)`\n\nYou'd still very likely want to call `Argengine::printHelp()` in the callback and just add some stuff around it.\n\n## Sorting order of options\n\nThe sorting order of options can be selected with:\n\n`void Argengine::setHelpSorting(HelpSorting helpSorting)`\n\n## Custom help text\n\nThe text printed before options can be set with:\n\n`void Argengine::setHelpText(std::string helpText)`\n\n# Examples\n\n## Valueless options: The simplest possible example\n\nValueless options are options without any value, so they are just flags. The lambda callback is of the form `[] {}`.\n\n```\n#include \"argengine.hpp\"\n#include \u003ciostream\u003e\n\nint main(int argc, char ** argv)\n{\n    juzzlin::Argengine ae(argc, argv);\n    ae.addOption({\"-f\", \"--foo\"}, [] {\n        std::cout \u003c\u003c \"'-f' or '--foo' given!\"  \u003c\u003c std::endl;\n    });\n    ae.parse();\n\n    return 0;\n}\n```\n\n## Single-value options: The simplest possible example\n\nSingle-value options are options that can have only one value.\n\nAs an example, for option `-f` The following formats are allowed: `-f 42`, `-f42`, `-f=42`.\n\nPreferably there should be either space or '`=`'. The spaceless format is accepted if not ambiguous.\n\nThe lambda callback is of the form `[] (std::string value) {}`.\n\n```\n#include \"argengine.hpp\"\n#include \u003ciostream\u003e\n\nint main(int argc, char ** argv)\n{\n    juzzlin::Argengine ae(argc, argv);\n    ae.addOption({\"-f\", \"--foo\"}, [] (std::string value) {\n        std::cout \u003c\u003c \"Value for '-f' or '--foo': \" \u003c\u003c value \u003c\u003c std::endl;\n    });\n    ae.parse();\n\n    return 0;\n}\n```\n\n## General: Marking an option **required**\n\nIn order to mark an option mandatory, there's an overload that accepts `bool required` right after the callback:\n\n```\n    ...\n\n    juzzlin::Argengine ae(argc, argv);\n    ae.addOption({\"-f\", \"--foo\"}, [] {\n        // Do something\n    },\n    true); // Required\n\n    ...\n```\n\n## General: Adding option documentation for the auto-generated help\n\nOne can add option documentation for the auto-generated help.\n\nConsider this example code:\n\n```\n    ...\n\n    juzzlin::Argengine ae(argc, argv);\n    ae.addOption(\n      { \"-p\" }, [](std::string value) {\n          std::cout \u003c\u003c value.size() \u003c\u003c std::endl;\n      },\n      true, \"Print length of given text. This option is required.\", \"TEXT\");\n\n    ...\n```\n\nHere we have added a documentation string `Print length of given text. This option is required.` and also a variable name `TEXT` for option `-p`.\n\nThus, this will generate a help content like this:\n\n```\nOptions:\n\n-h, --help       Show this help.\n-p [TEXT]        Print length of given text. This option is required.\n\n```\n\n## General: Setting two or more options as conflicting\n\nSometimes we want to prevent the user from giving a certain set of arguments.\n\nConsider this example code:\n\n```\n    ...\n\n    juzzlin::Argengine ae(argc, argv);\n    ae.addOption(\n      { \"foo\" }, [] {\n          std::cout \u003c\u003c \"Foo enabled!\" \u003c\u003c std::endl;\n      });\n\n    ae.addOption(\n      { \"bar\" }, [] {\n          std::cout \u003c\u003c \"Bar enabled!\" \u003c\u003c std::endl;\n      });\n\n    // Set \"foo\" and \"bar\" as conflicting options.\n    ae.addConflictingOptions({ \"foo\", \"bar\" });\n    ...\n```\n\nNow, if we give both `foo` and `bar` to the application, we'll get an error like this:\n\n\n```\nArgengine: Conflicting options: 'bar', 'foo'. These options cannot coexist.\n```\n\n## General: Adding option groups\n\nOption groups will make the given options depend on each other.\n\nConsider this example code:\n\n```\n    ...\n\n    juzzlin::Argengine ae(argc, argv);\n    ae.addOption(\n      { \"foo\" }, [] {\n          std::cout \u003c\u003c \"Foo enabled!\" \u003c\u003c std::endl;\n      });\n\n    ae.addOption(\n      { \"bar\" }, [] {\n          std::cout \u003c\u003c \"Bar enabled!\" \u003c\u003c std::endl;\n      });\n\n    // Add \"foo\" and \"bar\" as an option group.\n    ae.addOptionGroup({ \"foo\", \"bar\" });\n    ...\n```\n\nNow, if we give only `foo` to the application, we'll get an error like this:\n\n\n```\nArgengine: These options must coexist: 'bar', 'foo'. Missing options: 'bar'.\n```\n\n## General: Error handling\n\nFor error handling there are two options: exceptions or error value.\n\n`Argengine::parse()` will throw on error, `Argengine::parse(Error \u0026 error)` will set and error.\n\nExample of handling exceptions:\n\n```\n    ...\n\n    try {\n        ae.parse();\n    } catch(std::runtime_error \u0026 e) {\n        std::cerr \u003c\u003c e.what() \u003c\u003c std::endl;\n        ae.printHelp();\n        return EXIT_FAILURE;\n    }\n\n    ...\n```\n\nExample of handling error values:\n\n```\n    ...\n    Argengine::Error error;\n    ae.parse(error);\n\n    if (error.code != Argengine::Error::Code::Ok) {\n        std::cerr \u003c\u003c error.message \u003c\u003c std::endl\n                  \u003c\u003c std::endl;\n        ae.printHelp();\n        return EXIT_FAILURE;\n    }\n\n    ...\n```\n\n# Requirements\n\nC++17\n\n# Licence\n\nMIT\n\n# Projects currently using Argengine\n\n* https://github.com/juzzlin/DustRacing2D\n\n* https://github.com/juzzlin/Heimer\n\n* https://github.com/juzzlin/Noteahead\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjuzzlin%2Fargengine","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjuzzlin%2Fargengine","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjuzzlin%2Fargengine/lists"}