--- title: flag.h related: - "[conf.h](conf.h.md)" - "[cum.h](cum.h.md)" - "[yaci](yaci.md)" categories: - C libraries --- **flag.h** is a single-header command line flag parser for C99, inspired by Python's argparse. Copy `flag.h` into your project and include it; there is nothing to build or link. It needs a POSIX system. Parsing arguments by hand is the kind of mistake you only make once. ## Example ``` #include "flag.h" int main(int argc, char **argv) { const char *output; // flag with a value: -o file const char *verbose; // boolean flag: -v flag_program(.help = "Copy INPUT to OUTPUT", .positionals = flag_list("INPUT")); flag_add(&output, "--output", "-o", .nargs = 1, .defaults = "out.txt", .help = "where to write"); flag_add(&verbose, "--verbose", "-v", .help = "print what is going on"); if (flag_parse(&argc, &argv)) { flag_show_help(STDERR_FILENO); return 1; } // Flags are removed from argv: argv[1] is now INPUT if (verbose) printf("copying %s to %s\n", argv[1], output); flag_free(); return 0; } ``` ``` $ ./prog -h usage: ./prog [-h] [-o O] [-v] INPUT Copy INPUT to OUTPUT options: --help, -h Show this help --output, -o O where to write (default: out.txt) --verbose, -v print what is going on $ ./prog -v in.txt -o x.txt copying in.txt to x.txt ``` ## API Optional arguments are passed by name, using designated initializers: `flag_add(&v, "--foo", .nargs = 1)`. ### flag_program Optional. Describes the program. | Field | Description | |---|---| | `.help` | Text shown under the usage line | | `.positionals` | Required positional arguments, `flag_list("A", "B")` | | `.name` | Name in the usage line (default `argv[0]`) | ### flag_add `flag_add(&var, "--long", "-s", ...)` registers a flag. `var` is a `const char *`. | Field | Description | |---|---| | `.nargs = 0` | Default. Boolean: `var` is non-NULL if given, else NULL | | `.nargs = 1` | Takes a value (`-s val`, `-s=val`); `var` points to it | | `.defaults` | Value of `var` when the flag is not given | | `.required = 1` | Error if the flag is not given | | `.help` | Text shown in the help | ### flag_parse, flag_show_help, flag_free - `flag_parse(&argc, &argv)` parses the command line. It returns 0 on success, or non-zero after printing errors to stderr. Flags and their values are removed from `argv`, so `argv[1..argc-1]` are the positionals. `-h`, `-help` and `--help` print the help and exit. - `flag_show_help(fd)` prints usage and options to `fd`. - `flag_free()` frees the parsed values. Don't use the flag variables after calling it. ## Notes - Flags can go anywhere, before or after positionals. - A flag takes at most one value. - Positionals are a minimum: extra arguments are left in `argv`. - If a flag is repeated, only the first is used; the rest stay in `argv`. - Short flags can't be combined: use `-a -b`, not `-ab`. ## Used by - [pm](pm.md), [vicel](vicel.md), [yaci](yaci.md) and [tffpr](tffpr.md). ## See also - [Source code](https://github.com/hugoocoto/flag.h) (CC-BY-4.0)