{"id":19717815,"url":"https://github.com/pboettch/cxx_argp","last_synced_at":"2025-08-31T16:41:12.115Z","repository":{"id":45493847,"uuid":"156745526","full_name":"pboettch/cxx_argp","owner":"pboettch","description":"Modern C++, header-only command line argument parser interface based on argp","archived":false,"fork":false,"pushed_at":"2021-12-10T13:47:41.000Z","size":32,"stargazers_count":12,"open_issues_count":0,"forks_count":6,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-06-27T00:45:51.845Z","etag":null,"topics":["argument-parser","cpp-library","cpp11"],"latest_commit_sha":null,"homepage":null,"language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pboettch.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"COPYING","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-11-08T17:42:20.000Z","updated_at":"2025-06-20T15:26:13.000Z","dependencies_parsed_at":"2022-07-19T01:47:30.679Z","dependency_job_id":null,"html_url":"https://github.com/pboettch/cxx_argp","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/pboettch/cxx_argp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pboettch%2Fcxx_argp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pboettch%2Fcxx_argp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pboettch%2Fcxx_argp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pboettch%2Fcxx_argp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pboettch","download_url":"https://codeload.github.com/pboettch/cxx_argp/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pboettch%2Fcxx_argp/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273010885,"owners_count":25030367,"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","status":"online","status_checked_at":"2025-08-31T02:00:09.071Z","response_time":79,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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","cpp-library","cpp11"],"created_at":"2024-11-11T22:51:06.600Z","updated_at":"2025-08-31T16:41:12.079Z","avatar_url":"https://github.com/pboettch.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Modern C++ argument parser based on ARGP\n\n## Description\n\nThis project provides a header-only, C++ (C++11 and later)\nargument parser library manufactured around GLIBC's ARGP-library.\n\nIts goal is to stick to a maximum to the original concepts and features of ARGP\nin regards to argument-parsing. However, it adds some more advanced features,\nespecially the **association of variables, check-functions and their\noption-arguments** - represented by the argp-struct.\n\nIt's licensed under the term of the LGPL3 (as is argp inside the GLIBC).\nAs a header-only library is has the same license-requirements as stated by\n[the Eigen Project](http://eigen.tuxfamily.org/index.php?title=Licensing_FAQ\u0026oldid=1117#So_what_does_the_LGPL_require_me_to_do.3F).\n\n\n## How to use it\n\nHere's how this library can be used:\n\n```C++\n#include \u003ccxx_argp_parser.h\u003e\n#include \u003ciostream\u003e\n\nint main(int argc, char *argv[])\n{\n\t// initializers are default values for omitted options\n\tstd::string host = \"127.0.0.1\";\n\n\t// create parser object,\n\tcxx_argp::parser parser;\n\n\t// add option and associate to simple variables, the class creates a\n\t// conversion function (if the type is supported) which does a basic check\n\t// and fills the variable\n\t// Note: the first argument is the real 'struct argp_option'\n\tparser.add_option({nullptr, 'h', \"host-address\", 0, \"IP address of host\"},\n\t                  host);\n\n\tif (parser.parse(argc, argv)) {\n\t\tstd::cerr \u003c\u003c \"parsing OK\\n\";\n\t} else {\n\t\tstd::cerr \u003c\u003c \"there was an error - exiting\\n\";\n\t\treturn 1;\n\t}\n\n\tstd::cerr \u003c\u003c \"hostname \" \u003c\u003c host \u003c\u003c \"\\n\";\n\n\t// here, do more checks on the values passed to the program\n\n\treturn 0;\n}\n```\n\nRunning this program (called readme, see the test-folder) without arguments,\n`hostname` keeps it default value\n\n```bash\n$ ./readme\nparsing OK\nhostname 127.0.0.1\n```\n\nRunning it with `-h google.com`, `hostname` changes:\n\n```bash\n$ ./readme -h google.com\nparsing OK\nhostname google.com\n```\n\nOmitting the argument to the '-h' option, errors out:\n\n```bash\n$ ./readme -h\n./readme: option requires an argument -- 'h'\nTry `readme --help' or `readme --usage' for more information.\n```\n\nPrinting the help, generated by argp: (note that the program exists\nbefore returning to main())\n\n```bash\nUsage: readme [OPTION...]\n\n  -h host-address            IP address of host\n  -?, --help                 Give this help list\n      --usage                Give a short usage message\n```\n\n## Adding options\n\nThe method `add_option()` adds an option to the parser-object. The first argment is\na value of `struct argp_option`, the second argument is either a variable,\nwhich is used by reference, or a lamdba-function, `std::function` or `std::bind`\n(of prototype `bool(const char *)`.\n\nThis second argument is used during argument parsing, if it was variable the option's\nargument is tried to be converted to the variable (based on its type), if this is not\npossible, an error is produced and argp will bail out.\n\nIf the second argument is a function, this function is called with the argument value\n(a `const char *`) for further processing. This function returns `true` if the\nargument is accepted, otherwise `false`.\n\n## Argument conversion\n\n### Basic types\n\nThe parser-library internally provides some conversion-functions for some variable-type,\nwhich will make parsing fail if conversion has not worked, e.g. using a string\non a float-type variable.\n\nFloating point, std::strings and integer argument conversion functions are built in,\n\n```C++\nfloat single = 1.1f;\ndouble doublef = 2.2;\nuint16_t port = 502;\nint16_t sint = 0;\nstd::string host = \"127.0.0.1\";\n\ncxx_argp::parser parser;\n\nparser.add_option({\"float\", 's', \"single\", 0, \"floating-point test\"}, single);\nparser.add_option({\"double\", 'd', \"double\", 0, \"floating-point test\"}, doublef);\nparser.add_option({\"port\", 'p', \"port\", 0, \"TCP port the server will listen on\"}, port);\nparser.add_option({\"host\", 'h', \"host-address\", 0, \"IP address of host\"}, host);\n```\n\n### Boolean and switches\n\n`bool`-variable-based options are consider as 'switches', i.e. the option is expected\nto not have an argument and if the option is present, the associated bool-variable is\nset to true.\n\n```C++\nbool enable = false;\n\nparser.add_option({\"enable\", 'e', nullptr, 0, \"enable\"}, enable);\n```\n\n### File streams and file names\n\nThe built-in conversion functions for file-streams is taking the argument as\na filename and tries to open the file. If this does not work, the argument is considered\nas an error.\n\n```C++\nstd::ifstream file;\n\nparser.add_option({\"file\", 'f', \"filename\", 0, \"a file\"}, file);\n```\n\nSometimes the filename and a stream is required. A paired type can then be used:\n\n```C++\nstd::pair\u003cstd::ifstream, std::string\u003e file_and_name;\n\nparser.add_option({\"file\", 'f', \"filename\", 0, \"a file\"}, file_and_name);\n```\n\nThis works the same way as for simple streams, except that the open file is the `first`-part of the pair\nand the `second`-part contains the filename as a `std::string`.\n\nTo just get a filename without any file-opening, `std::string` can be used.\n\n### Comma-separated list of integer\n\nA more complex conversion function is built in, this converts are comma-separated list of integers\ninto a `std::vector\u003c\u003e`:\n\n```C++\nstd::vector\u003cint\u003e vec;\n\nparser_.add_option({\"vector\", 'V', \"list\", 0, \"list of ints\"}, vec);\n```\n\nAn argument for such a type can be given as `1,12,3`, resulting the version containing 1, 12 and 3.\n\n\n### Custom argument converter\n\nCustom argument converters can be implemented by passing a function as second argument to\n`add_option()`. The user has thus complete control of what to do with the raw argument `const char *`.\n\nThe prototype of the function to be given is `bool(const char *)`.\n\nThe user has to return `true` if the argument is acceptable for this option, or `false` if not.\n\nThere are no limit in regards what can be done using this feature:\n\n#### Lambdas\n\nToggle a boolean:\n\n```C++\nbool enable = false;\n\nparser.add_option({\"enable\", 'e', nullptr, 0, \"enable\"},\n                  [\u0026enable] (const char *) { enable = !enable; return true; } );\n```\n\nA verbosity-level indicator:\n\n```C++\nint verbose = 0;\n\nparser.add_option({nullptr, 'v', nullptr, 0, \"verbosity level increase\"},\n                  [\u0026verbose] (const char *) { verbose++; return true; } );\n```\n\n#### `std::bind`\n\nA useful feature for when using `std::bind` could be to fill in a map-like\nobject (think of JSON as a more complex example than a `std::map`).\n\n```C++\nstd::map\u003cstd::string, std::string\u003e cfg;\n\nauto to_map = [\u0026cfg] (const char *arg, const std::string \u0026key) {\n\tmap[key] = arg;\n\treturn true;\n};\n\nparser.add_option({nullptr, 'a', nullptr, 0, \"value A\"},\n                  std::bind(to_map, std::placeholders::_1, \"value1\"));\nparser.add_option({nullptr, 'b', nullptr, 0, \"value B\"},\n                  std::bind(to_map, std::placeholders::_1, \"value2\"));\nparser.add_option({nullptr, 'c', nullptr, 0, \"value C\"},\n                  std::bind(to_map, std::placeholders::_1, \"value3\"));\n```\n\n## Contributing\n\nDo not hesite to ask questions and issue pull-requests here on GitHub.\nEvery help is more than welcome.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpboettch%2Fcxx_argp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpboettch%2Fcxx_argp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpboettch%2Fcxx_argp/lists"}