- C++ 95.6%
- Makefile 2.5%
- Meson 1.9%
| include | ||
| LICENSES | ||
| misc | ||
| src | ||
| .editorconfig | ||
| .gitignore | ||
| .version | ||
| LICENSE.md | ||
| makefile | ||
| meson.build | ||
| meson.options | ||
| README.md | ||
| REUSE.toml | ||
Argue
A header-only, single include argument parsing library for C++ 23 (or later). Stop arguing with your argument parser.
Dont want to hear me talk? skip straight to the code.
Why
Argument parsing libraries are (of course) a dime a dozen; So why am I making one?
Why not? Got a problem with me making a library?
On a serious note, It always seems like the ones on offer are:
- Too opinionated, make themselves difficult to use if you're not making use of all of their features.
- Limiting, making it impossible or very difficult to do things like having multiple short flags attach to one option/flag.
- Support very old C++ standards at the cost of usability.
Or if you are CLI11, you write this in your README:
An acceptable CLI parser library should be all of the following:
... truncated ...
- Permissively licensed
Which, was never on my "ridiculous and indefensible things a dev might say" bingo card.
So since this project is licensed under the LGPL version 3, this is in fact NOT an
acceptable library ☝️🤓 ! But hey, if you believe in free software and can cope with my
library not being acceptable, I think you might find it useful.
Terminology
In argue, there are a few fundamental types of command line arguments, and
It's worth clarifying what they mean here, since these terms are not widely
agreed on.
argue::flag
These are boolean on/off switches, they are either present or they are not.
They may be specified multiple times, for example if you wish to have varing
levels of output verbosity:
./program -vvv --help --version
argue::opt
These need to be provided with a value, and can only be specified once:
./program --output=foo -f file -i=./include --prefix /usr
argue::arg
These are so called 'positional' arguments, they appear on their own, and are
not associated with any options or flags:
./program foo
A great example of this type of argument is a URL you may pass to curl or wget
curl https://example.com
Usage
#include <argue.hpp>
auto main(int argc, const char **argv) -> int {
std::string url_string, url_two_string;
argue::cli cli;
// multiple 'short' option/flag names, '-h' AND '-?'
auto help = argue::flag("help", {"h", "?"}, "display help info");
// The description is completely optional, in case you prefer to
// write your own help text
cli.add_option({"output", {"o"}})
// chaining method calls
.add_args({
// the index can be specified explicitly, otherwise
// the indexes will be assigned in the order the
// args were added in
{0, "URL", url_string, "a url to download"},
{"URL_TWO", url_two_string, "a second url to download"}
// the url_string and url_two_string variables will hold the
// associated value if found
})
// add pre-declared flags or declare them inline with the initializer list
.add_flags({
{"verbose", {"V"}, "increase verbosity"},
help
});
// adding a flag/opt/arg with the |= operator
cli |= argue::flag("version", {"V"}, "display version info");
// this parses the command line, I know, shocker
cli.parse(argc, argv);
// return the amount of times a flag occurrs in
// the command line, or 0 if it never occurrs.
int verbosity = cli.count("verbose");
// check for a flag given a reference to it
if (cli.got(help)) {
cli.help(); // generated help text
return 0;
}
std::string output_path;
// check for an option given its' long name
if (cli.got("output")) {
// cli.map contains the values of all found options and args
// they are all held as strings, conversion is done on your
// terms if needed.
output_path = cli.map.at("output");
/* do stuff with the output_path */
}
return 0;
}
Installation
Just a simple make-install.
make install
# or to remove
make uninstall
This will install the argue.hpp header and a pkg-config file for ease of use.
The makefile respects DESTDIR and PREFIX, with the default prefix being /usr/local.
Note: pkg-config file installed under /usr/local (sadly) may not be detected for use by default.
If you run into this issue, you may need to set PKG_CONFIG_PATH environment variable like so:
export PKG_CONFIG_PATH="/usr/local/share/pkgconfig:/usr/local/lib/pkgconfig:/usr/share/pkgconfig:/usr/lib/pkgconfig"
This should be how pkg-config and pkgconf work out of the box, but thats not always true in reality.
Related issue "Just configure them when building pkgconf"
If you wish to avoid this issue entirely, issue the install command with PREFIX=/usr.
License
This repository is licensed under the terms of the GNU Lesser General Public License, version 3.0 or later.
See the license file to view the license text.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.