2016-08-18 19:46:44 -07:00
|
|
|
# kyaa
|
|
|
|
|
|
|
|
super hacky macro hacks for parsing arguments in C.
|
|
|
|
|
|
|
|
## prerequisites
|
|
|
|
|
|
|
|
C99 or greater.
|
|
|
|
|
|
|
|
standard library headers:
|
2016-08-18 19:55:00 -07:00
|
|
|
* `stdbool.h`
|
|
|
|
* `stdio.h`
|
2016-08-18 20:04:48 -07:00
|
|
|
* `string.h`
|
2016-08-18 19:46:44 -07:00
|
|
|
|
2017-03-30 23:29:13 -07:00
|
|
|
## tutorial
|
2016-08-18 19:46:44 -07:00
|
|
|
|
2016-08-18 19:55:00 -07:00
|
|
|
ensure `argc` and `argv` are defined.
|
|
|
|
kyaa doesn't actually care if it's in `main` or not.
|
2016-08-18 19:46:44 -07:00
|
|
|
|
2016-08-18 19:50:10 -07:00
|
|
|
iterate over the arguments with `KYAA_LOOP`:
|
2016-08-18 19:46:44 -07:00
|
|
|
|
|
|
|
```c
|
|
|
|
int main(int argc, char *argv[]) {
|
|
|
|
KYAA_LOOP {
|
2017-03-30 23:29:13 -07:00
|
|
|
// KYAA_ITER, kyaa_name, kyaa_read_stdin, and kyaa_flag are exposed here.
|
2016-08-18 19:46:44 -07:00
|
|
|
// [other code goes here]
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
2016-08-18 19:50:10 -07:00
|
|
|
use `KYAA_BEGIN` and `KYAA_END` to begin parsing arguments.
|
|
|
|
put unrelated code above `KYAA_BEGIN` or below `KYAA_END`, but not within:
|
2016-08-18 19:46:44 -07:00
|
|
|
|
|
|
|
```c
|
|
|
|
KYAA_LOOP {
|
|
|
|
// [other code goes here]
|
|
|
|
KYAA_BEGIN
|
|
|
|
// kyaa_arg and kyaa_etc are exposed here.
|
|
|
|
// [kyaa code goes here]
|
|
|
|
KYAA_END
|
|
|
|
// [other code goes here]
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
2016-08-18 19:50:10 -07:00
|
|
|
use `KYAA_FLAG` for defining flags that don't take an argument,
|
|
|
|
and `KYAA_FLAG_ARG` or `KYAA_FLAG_LONG` for flags that do:
|
2016-08-18 19:46:44 -07:00
|
|
|
|
|
|
|
```c
|
|
|
|
bool use_feature = false;
|
|
|
|
char *log_fn = "logs.txt";
|
|
|
|
long my_var = 0;
|
|
|
|
KYAA_LOOP {
|
|
|
|
// [other code goes here]
|
|
|
|
KYAA_BEGIN
|
|
|
|
|
|
|
|
// arguments: short flag, long flag, help description
|
|
|
|
KYAA_FLAG("-x", "--enable-feature",
|
|
|
|
" enable some feature")
|
|
|
|
use_feature = true;
|
|
|
|
|
|
|
|
// same arguments, but kyaa_etc contains the relevant string.
|
|
|
|
KYAA_FLAG_ARG("-l", "--log-file",
|
|
|
|
" use a given filename for the log file")
|
|
|
|
log_fn = kyaa_etc;
|
|
|
|
|
|
|
|
// same arguments, kyaa_etc is set, but kyaa_flag_arg is also set.
|
|
|
|
KYAA_FLAG_LONG("-v", "--var",
|
|
|
|
" set an integer variable\n"
|
|
|
|
" default: 0")
|
|
|
|
my_var = kyaa_flag_arg;
|
|
|
|
|
|
|
|
KYAA_END
|
|
|
|
// [other code goes here]
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
kyaa secretly wraps flag handling in if/else statements with {} blocks.
|
|
|
|
do not confuse it for a switch/case method.
|
|
|
|
|
2016-08-18 19:50:10 -07:00
|
|
|
kyaa handles `-h` and `--help` for printing help text.
|
|
|
|
additional help text may be defined using `KYAA_HELP`:
|
2016-08-18 19:46:44 -07:00
|
|
|
|
|
|
|
```c
|
|
|
|
KYAA_LOOP {
|
|
|
|
KYAA_BEGIN
|
|
|
|
KYAA_HELP(
|
|
|
|
" {files...}\n"
|
|
|
|
" do things with files.")
|
|
|
|
KYAA_END
|
|
|
|
|
|
|
|
do_stuff(kyaa_arg);
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
2016-08-18 19:50:10 -07:00
|
|
|
kyaa interprets an argument of `-` as a request to enable reading from stdin:
|
|
|
|
`kyaa_read_stdin` is set to true.
|
2016-08-18 19:46:44 -07:00
|
|
|
|
|
|
|
arguments may be passed in three ways, consider:
|
|
|
|
* `-v42`
|
|
|
|
* `-v 42`
|
|
|
|
* `--var 42`
|
|
|
|
|
2016-08-18 19:50:10 -07:00
|
|
|
kyaa returns `KYAA_OKAY` when `-h` or `--help` is given,
|
|
|
|
and `KYAA_ERROR` in the event of invalid flags, missing arguments,
|
|
|
|
or invalid numbers (`KYAA_FLAG_LONG`).
|
2016-08-19 02:11:10 -07:00
|
|
|
kyaa uses `continue` for handling arguments.
|
2016-08-18 19:46:44 -07:00
|
|
|
|
2016-08-18 19:50:10 -07:00
|
|
|
kyaa prints error messages to `stderr`, and help text to `stdout`.
|
2016-08-18 19:46:44 -07:00
|
|
|
|
2016-08-18 19:50:10 -07:00
|
|
|
`KYAA_ITER` may be redefined to avoid name collisions.
|
2016-08-18 19:46:44 -07:00
|
|
|
|
|
|
|
## TODO
|
|
|
|
|
|
|
|
* support `--var=42` argument style
|
2016-08-19 02:11:10 -07:00
|
|
|
* fix overlapping names, e.g. `KYAA_FLAG` vs `kyaa_flag`, `KYAA_FLAG_ARG` vs `kyaa_flag_arg`, etc.
|
2017-03-30 23:29:13 -07:00
|
|
|
* maybe pass `argc`/`argv` manually?
|
|
|
|
|
|
|
|
## API
|
|
|
|
|
|
|
|
### kyaa.h
|
|
|
|
|
|
|
|
```
|
|
|
|
KYAA_OKAY DEFINE int
|
|
|
|
KYAA_ERROR DEFINE int
|
|
|
|
KYAA_ITER DEFINE int
|
|
|
|
KYAA_SETUP MACRO
|
|
|
|
KYAA_LOOP MACRO
|
|
|
|
KYAA_BEGIN MACRO
|
|
|
|
KYAA_END MACRO
|
|
|
|
KYAA_DESCRIBE MACRO
|
|
|
|
KYAA_FLAG MACRO
|
|
|
|
KYAA_FLAG_ARG MACRO
|
|
|
|
KYAA_HELP MACRO
|
|
|
|
|
|
|
|
kyaa_name char *
|
|
|
|
kyaa_read_stdin bool
|
|
|
|
kyaa_flag char
|
|
|
|
kyaa_keep_parsing bool
|
|
|
|
kyaa_parse_next bool
|
|
|
|
kyaa_arg char *
|
|
|
|
kyaa_no_more bool
|
|
|
|
kyaa_helping bool
|
|
|
|
kyaa_any bool
|
|
|
|
kyaa_flag_arg char *
|
|
|
|
```
|
|
|
|
|
|
|
|
### kyaa\_extra.h
|
|
|
|
|
|
|
|
```
|
|
|
|
KYAA_FLAG_LONG MACRO
|
|
|
|
|
|
|
|
char *kyaa_skip_spaces(char *str)
|
|
|
|
const char *kyaa_str_to_long(char *str, long *p_out)
|
|
|
|
```
|