A header-only collection of useful and useless things to support C++ CLI design
*outdated gif, but it gives an idea!
I don't really like getopt
, I wanted the cleanest argument parser possible, so I wrote a first version of ProcessOptions
and then a few other things. I gathered these together here, and then CliKit was born!
This is not "low-level zero overhead black-magic" code. The mindset here is to promote readability and flexibility. So far, the elements contained in the kit are :
- Option processor, to crunch your
argc
andargv
buddies and give the help messages - Command shell, to input runtime commands
- A spinner, with customizable sprites
- A loading bar, in which you can put a spinner!
A tool to launch your project quickly and make your life simpler.
int main(int argc, char** argv)
{
clikit::usage.setIntro("myprogram [args...] [-a [args...]] [-b|--bye [args...]]");
clikit::ProcessOptions(argc, argv)
({
BADOPTIONS ( { clikit::usage(); }),
FIRSTARGS ( { crunch_pre_option(args); }),
OPTION ("-a", "a great option!" { flag_a = true; }),
OPTION ("-b,--bye", "farewell friend!" { prepare(args); })
});
...
- Any argument of your program starting with a
-
will be detected as an option and the following words as option arguments. - Anything before that will land in
args
in the function body provided toFIRSTARGS
. - Options are defined with the
OPTION
macros, which should be provided a comma-separated string of options, a help/usage message and a function body. - Within that function body,
args
contains a string vector of option arguments. BADOPTIONS
is optional and is called if non-defined options are detected. Their names are provided inargs
.
The CommandShell
uses a similar pattern :
CommandShell("> ", "exit") ({
COMMAND ("commandWord", { commandAction(args); }),
DEFAULT ({ processLine(args); }),
EXIT ({ exit(0); })
});
- The (optional) constructor parameters define the shell symbol and the exit command word
- Single-word commands can be provided in the COMMAND macro with a function body
- Any non-defined command will be processed by the function body provided in the (optional) DEFAULT macro
- In every function body,
args
contains a string vector of the rest of the line's words - The exit command has it's own macro for a different processing
Arrow-key detection (to bring up previous commands) is not currently supported to avoid external dependencies.
The following elements can be found in cliAnimations.h
A Spinner
object to load with the sprite sequence of your choice. Sprites can be strings of different length.
Spinner spin({ "-", "\\", "|", "/" });
while(1)
{
cout << '\r' << spin() << flush;
sleep_for(100ms);
}
The LoadingBar
object has a few options :
- Adjustable length
- Togglable percentage display
- Customizable loaded/not-loaded symbols
- Can have a
Spinner
Sample loader :
Spinner spinner({ "|X |","| X |","| X|","| X |" });
LoadingBar loader('X', '-', 60, true, spinner);
while (progress < 1)
{
cout << '\r' << loader(progress) << flush;
progress += 0.03;
sleep_for(100ms);
}
cout << '\r' << loader(1) << flush;