ArgueWithCpp (argwc) is a C++ library designed to make argument parsing for C++ programs easier and more convenient using config files ("Grammar files"). Those files describe the structure of the arguments and how they should be passed, and then they could be used in the code directly with no extra overhead.
Here's an example snippet of the ArgGrammar.awc file:
argfile {
buzzword "--dir" {
arg $path required;
};
flag $verbose "--verbose";
};
And to use in C++:
#include <argwc.h>
#include "argfile.h"
#include <iostream>
int main(int argc, char** argv) {
argwc mngr(argc, argv, argfile().text);
if (mngr.arg_exists("path"))
std::cout << mngr.get_arg("path") << std::endl;
else
std::cout << "no path provided" << std::endl;
if (mngr.flag_enabled("verbose")) {
std::cout << "Verbose mode enabled" << std::endl;
}
}Then the program can be ran via:
./myprogram --dir sometextgoeshere --verbose- Make it deserialize information from
argwc-compinstead of parsing at runtime - Add custom string formatting for
valandarg(perhaps via regex?) - Make
orderedactually work - Incorporate it with argwc-comp such that they don't have to be separate executables
- Custom error messages assigned by the user
- Syntax highlighter for VSCode
- Macros?
- Add an optional
xargsattribute toargfilesuch that text from stdin is accepted as argument
- Reimplement the parse args function (i can barely understand it)
- More consts where there should be consts
- Proper unit tests
In the C++ half, argwc is invoked like this:
#include <ArgueWithCpp/argwc.h>
#include "argfile.h"
int main(int argc, char** argv) {
argwc argmn(argc, argv, argfile::data);
// use argwc here
}argwc(int argc, char** argv, const std::span<uint8_t> data)The class constructor. Takes the argc and argv parameters passed to the main() function. Also takes code arguement which should be included from the argfile. See Argue With Cpp Compiler.
bool flag_enabled(const std::string& flagname)Returns true if the flag is present, false otherwise.
std::string get_arg(const std::string& varname)Returns the value of the argument varname.
void print_arguments()Prints the arguments passed to argwc, excluding the program path/name.
bool flag_exists(const std::string& flagname);
bool arg_exists(const std::string& argname);
bool obj_exists(const std::string& objname);Each return true if the corresponding object is present, while obj_exists returns true if an object from either type is present. All return false otherwise.
In the ArgueWithCpp half, you must create an ArgGrammar.awc file that describes the arguments grammar. Every Grammar file starts with a:
argfile {
// grammar goes here
};
Every statement ends with a semicolon. As of now, there are for statements, buzzword, flag, arg, and val statements. buzzword statements are arguments consumed solely for aesthetics or structure. flag are statements that return true if present and false otherwise. And arg may contain an arbitrary string. val statements are like args but are taken with the format "varname=value". Here's an example:
argfile {
buzzword "--greet" required {
arg $name required;
}
val $greetingType "--set-greeting-type"; // used like: --set-greeting-type=hello
flag $beFriendly "--be-friendly";
};
The brackets after a statement but before its semicolon represents a scope where the statements inside will only be invoked if the outer statement is also passed. Statements marked with required will make the program throw if not passed.
The ArgueWithCpp compiler is a arwc-to-C++ transpiler to allow packacing the Grammar file directly with the executable. Download it from here. Then put it in your ~/.bin, ~/.local/bin, or if you have root access, /usr/local/bin. Then write your ArgueWithCpp file and compile it with argwc-comp /path/to/your/grammarfile.awc /path/to/your/src/directory/argfile.h. Then include it from the C++ file and use it as above.