super hacky macro hacks for parsing arguments in C
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Connor Olding d7c5652c1f move tests 4 months ago
tests move tests 4 months ago
.gitignore rewrite portions and add tests 4 months ago
LICENSE add unlicense 4 months ago
README.md note memory usage 4 months ago
kyaa.h add unlicense 4 months ago
kyaa_extra.h add unlicense 4 months ago

README.md

kyaa

super hacky macro hacks for parsing arguments in C.

FAQ

Fairly Arbitrary Questions

Why?

kyaa exists for when the “quick ‘n’ dirty” isn’t dirty enough. also, it keeps argument parsing in main, instead of delegating with callbacks and whatnot.

How?

kyaa secretly wraps flag-handling in if-else statements with curly braces. it’s not a switch-case method! kyaa instead uses continue to handle certain arguments.

Should I use this?

honestly, no.

What’s in a name?

i have no idea why i called it “kyaa,” other than it being the first thing that came to mind that wasn’t already in use by some other software.

What do I need?

the prerequisites are:

  • C99 (or greater)

  • stdbool.h

  • stdio.h (can be avoided by overriding KYAA_OUT and KYAA_ERR)

  • string.h

  • limits.h (just for kyaa_extra.h, can be avoided by defining LONG_MIN)

kyaa does not allocate any memory on heap.

tutorial

ensure argc and argv are defined in a function that returns an int. kyaa doesn’t actually care if it’s in main or not.

iterate over the arguments with KYAA_LOOP:

int main(int argc, char **argv) {
    KYAA_LOOP {
        // kyaa_iter, kyaa_name, and kyaa_read_stdin are exposed here.
        // [other code goes here]
    }
    return 0;
}

use KYAA_BEGIN and KYAA_END to begin parsing arguments. put unrelated code above KYAA_BEGIN or below KYAA_END, but not within:

    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]
    }

use KYAA_FLAG for defining flags that don’t take an argument, and KYAA_FLAG_ARG or KYAA_FLAG_LONG for flags that do:

    bool use_feature = false;
    const char *log_fn = "log.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_long_value is also set.
        KYAA_FLAG_LONG('v', "var",
"        set an integer variable\n"
"        default: 0")
            my_var = kyaa_long_value;

        KYAA_END
        // [other code goes here]
    }
    return 0;

kyaa handles -h and --help for printing help text. additional help text may be defined using KYAA_HELP:

    KYAA_LOOP {
        KYAA_BEGIN
        KYAA_HELP(
"  {files...}\n"
"        do things with files.")
        KYAA_END

        do_stuff(kyaa_arg);
    }

kyaa interprets an argument of - as a request to enable reading from stdin: kyaa_read_stdin is set to true. this may be reset by the user if desired.

flag values may be specified in four ways; the following are equivalent:

  • -v42
  • -v 42
  • --var 42
  • --var=42

kyaa returns KYAA_OKAY when -h or --help is given, or KYAA_FAIL in the event of invalid flags, missing arguments, or invalid numbers (KYAA_FLAG_LONG).

kyaa prints help text to stdout and error messages to stderr. this can be overridden by specifying KYAA_OUT and KYAA_ERR respectively.

API

kyaa.h

signature name arguments or default value description
define KYAA_OKAY 0 value to return upon a successful early exit
define KYAA_FAIL 1 value to return upon encountering an error
define KYAA_OUT printf(__VA_ARGS__) printf-like function for help text
define KYAA_ERR fprintf(stderr, __VA_ARGS__) printf-like function for error text
macro KYAA_SETUP none performs a sanity check and initializes variables
macro KYAA_LOOP none begins iterating over arguments
macro KYAA_BEGIN none begins parsing arguments
macro KYAA_END none finishes parsing arguments
macro KYAA_DESCRIBE c, name, description describes a flag for help text
macro KYAA_FLAG c, name, description handles a flag that takes no arguments
macro KYAA_FLAG_ARG c, name, description handles a flag that takes a string argument
macro KYAA_HELP description prints additional text for help text
const char * kyaa_name n/a the name of the program (usually argv[0])
int kyaa_iter n/a the index of the argument being parsed
const char * kyaa_arg n/a the whole argument being parsed
const char * kyaa_etc n/a an argument to a flag, or NULL
bool kyaa_read_stdin n/a set when an argument is - (remains set unless reset by user)

internal use

signature name arguments or default value description
macro KYAA_IS_LONG arg, name tests whether arg describes a long flag called name
char kyaa_char n/a the character assigned to the current flag being parsed
bool kyaa_parsing n/a whether parsing occurs (-- cancels parsing)
bool kyaa_skip n/a set when a flag needs another argument
bool kyaa_helping n/a set when -h or --help is encountered
bool kyaa_any n/a set when any flag has been matched
const char * kyaa_equals n/a a pointer to the first = character in a long flag, or NULL

kyaa_extra.h

signature name arguments or default value
macro KYAA_FLAG_LONG c, name, description
char * kyaa_flag_arg n/a
char * kyaa_skip_spaces char * str
const char * kyaa_str_to_long char * str, long * p_out