| parse-options API |
| ================= |
| |
| The parse-options API is used to parse and massage options in Git |
| and to provide a usage help with consistent look. |
| |
| Basics |
| ------ |
| |
| The argument vector `argv[]` may usually contain mandatory or optional |
| 'non-option arguments', e.g. a filename or a branch, and 'options'. |
| Options are optional arguments that start with a dash and |
| that allow to change the behavior of a command. |
| |
| * There are basically three types of options: |
| 'boolean' options, |
| options with (mandatory) 'arguments' and |
| options with 'optional arguments' |
| (i.e. a boolean option that can be adjusted). |
| |
| * There are basically two forms of options: |
| 'Short options' consist of one dash (`-`) and one alphanumeric |
| character. |
| 'Long options' begin with two dashes (`--`) and some |
| alphanumeric characters. |
| |
| * Options are case-sensitive. |
| Please define 'lower-case long options' only. |
| |
| The parse-options API allows: |
| |
| * 'stuck' and 'separate form' of options with arguments. |
| `-oArg` is stuck, `-o Arg` is separate form. |
| `--option=Arg` is stuck, `--option Arg` is separate form. |
| |
| * Long options may be 'abbreviated', as long as the abbreviation |
| is unambiguous. |
| |
| * Short options may be bundled, e.g. `-a -b` can be specified as `-ab`. |
| |
| * Boolean long options can be 'negated' (or 'unset') by prepending |
| `no-`, e.g. `--no-abbrev` instead of `--abbrev`. Conversely, |
| options that begin with `no-` can be 'negated' by removing it. |
| Other long options can be unset (e.g., set string to NULL, set |
| integer to 0) by prepending `no-`. |
| |
| * Options and non-option arguments can clearly be separated using the `--` |
| option, e.g. `-a -b --option -- --this-is-a-file` indicates that |
| `--this-is-a-file` must not be processed as an option. |
| |
| Steps to parse options |
| ---------------------- |
| |
| . `#include "parse-options.h"` |
| |
| . define a NULL-terminated |
| `static const char * const builtin_foo_usage[]` array |
| containing alternative usage strings |
| |
| . define `builtin_foo_options` array as described below |
| in section 'Data Structure'. |
| |
| . in `cmd_foo(int argc, const char **argv, const char *prefix)` |
| call |
| |
| argc = parse_options(argc, argv, prefix, builtin_foo_options, builtin_foo_usage, flags); |
| + |
| `parse_options()` will filter out the processed options of `argv[]` and leave the |
| non-option arguments in `argv[]`. |
| `argc` is updated appropriately because of the assignment. |
| + |
| You can also pass NULL instead of a usage array as the fifth parameter of |
| parse_options(), to avoid displaying a help screen with usage info and |
| option list. This should only be done if necessary, e.g. to implement |
| a limited parser for only a subset of the options that needs to be run |
| before the full parser, which in turn shows the full help message. |
| + |
| Flags are the bitwise-or of: |
| |
| `PARSE_OPT_KEEP_DASHDASH`:: |
| Keep the `--` that usually separates options from |
| non-option arguments. |
| |
| `PARSE_OPT_STOP_AT_NON_OPTION`:: |
| Usually the whole argument vector is massaged and reordered. |
| Using this flag, processing is stopped at the first non-option |
| argument. |
| |
| `PARSE_OPT_KEEP_ARGV0`:: |
| Keep the first argument, which contains the program name. It's |
| removed from argv[] by default. |
| |
| `PARSE_OPT_KEEP_UNKNOWN`:: |
| Keep unknown arguments instead of erroring out. This doesn't |
| work for all combinations of arguments as users might expect |
| it to do. E.g. if the first argument in `--unknown --known` |
| takes a value (which we can't know), the second one is |
| mistakenly interpreted as a known option. Similarly, if |
| `PARSE_OPT_STOP_AT_NON_OPTION` is set, the second argument in |
| `--unknown value` will be mistakenly interpreted as a |
| non-option, not as a value belonging to the unknown option, |
| the parser early. That's why parse_options() errors out if |
| both options are set. |
| |
| `PARSE_OPT_NO_INTERNAL_HELP`:: |
| By default, parse_options() handles `-h`, `--help` and |
| `--help-all` internally, by showing a help screen. This option |
| turns it off and allows one to add custom handlers for these |
| options, or to just leave them unknown. |
| |
| Data Structure |
| -------------- |
| |
| The main data structure is an array of the `option` struct, |
| say `static struct option builtin_add_options[]`. |
| There are some macros to easily define options: |
| |
| `OPT__ABBREV(&int_var)`:: |
| Add `--abbrev[=<n>]`. |
| |
| `OPT__COLOR(&int_var, description)`:: |
| Add `--color[=<when>]` and `--no-color`. |
| |
| `OPT__DRY_RUN(&int_var, description)`:: |
| Add `-n, --dry-run`. |
| |
| `OPT__FORCE(&int_var, description)`:: |
| Add `-f, --force`. |
| |
| `OPT__QUIET(&int_var, description)`:: |
| Add `-q, --quiet`. |
| |
| `OPT__VERBOSE(&int_var, description)`:: |
| Add `-v, --verbose`. |
| |
| `OPT_GROUP(description)`:: |
| Start an option group. `description` is a short string that |
| describes the group or an empty string. |
| Start the description with an upper-case letter. |
| |
| `OPT_BOOL(short, long, &int_var, description)`:: |
| Introduce a boolean option. `int_var` is set to one with |
| `--option` and set to zero with `--no-option`. |
| |
| `OPT_COUNTUP(short, long, &int_var, description)`:: |
| Introduce a count-up option. |
| Each use of `--option` increments `int_var`, starting from zero |
| (even if initially negative), and `--no-option` resets it to |
| zero. To determine if `--option` or `--no-option` was encountered at |
| all, initialize `int_var` to a negative value, and if it is still |
| negative after parse_options(), then neither `--option` nor |
| `--no-option` was seen. |
| |
| `OPT_BIT(short, long, &int_var, description, mask)`:: |
| Introduce a boolean option. |
| If used, `int_var` is bitwise-ored with `mask`. |
| |
| `OPT_NEGBIT(short, long, &int_var, description, mask)`:: |
| Introduce a boolean option. |
| If used, `int_var` is bitwise-anded with the inverted `mask`. |
| |
| `OPT_SET_INT(short, long, &int_var, description, integer)`:: |
| Introduce an integer option. |
| `int_var` is set to `integer` with `--option`, and |
| reset to zero with `--no-option`. |
| |
| `OPT_STRING(short, long, &str_var, arg_str, description)`:: |
| Introduce an option with string argument. |
| The string argument is put into `str_var`. |
| |
| `OPT_STRING_LIST(short, long, &struct string_list, arg_str, description)`:: |
| Introduce an option with string argument. |
| The string argument is stored as an element in `string_list`. |
| Use of `--no-option` will clear the list of preceding values. |
| |
| `OPT_INTEGER(short, long, &int_var, description)`:: |
| Introduce an option with integer argument. |
| The integer is put into `int_var`. |
| |
| `OPT_MAGNITUDE(short, long, &unsigned_long_var, description)`:: |
| Introduce an option with a size argument. The argument must be a |
| non-negative integer and may include a suffix of 'k', 'm' or 'g' to |
| scale the provided value by 1024, 1024^2 or 1024^3 respectively. |
| The scaled value is put into `unsigned_long_var`. |
| |
| `OPT_EXPIRY_DATE(short, long, ×tamp_t_var, description)`:: |
| Introduce an option with expiry date argument, see `parse_expiry_date()`. |
| The timestamp is put into `timestamp_t_var`. |
| |
| `OPT_CALLBACK(short, long, &var, arg_str, description, func_ptr)`:: |
| Introduce an option with argument. |
| The argument will be fed into the function given by `func_ptr` |
| and the result will be put into `var`. |
| See 'Option Callbacks' below for a more elaborate description. |
| |
| `OPT_FILENAME(short, long, &var, description)`:: |
| Introduce an option with a filename argument. |
| The filename will be prefixed by passing the filename along with |
| the prefix argument of `parse_options()` to `prefix_filename()`. |
| |
| `OPT_ARGUMENT(long, description)`:: |
| Introduce a long-option argument that will be kept in `argv[]`. |
| |
| `OPT_NUMBER_CALLBACK(&var, description, func_ptr)`:: |
| Recognize numerical options like -123 and feed the integer as |
| if it was an argument to the function given by `func_ptr`. |
| The result will be put into `var`. There can be only one such |
| option definition. It cannot be negated and it takes no |
| arguments. Short options that happen to be digits take |
| precedence over it. |
| |
| `OPT_COLOR_FLAG(short, long, &int_var, description)`:: |
| Introduce an option that takes an optional argument that can |
| have one of three values: "always", "never", or "auto". If the |
| argument is not given, it defaults to "always". The `--no-` form |
| works like `--long=never`; it cannot take an argument. If |
| "always", set `int_var` to 1; if "never", set `int_var` to 0; if |
| "auto", set `int_var` to 1 if stdout is a tty or a pager, |
| 0 otherwise. |
| |
| `OPT_NOOP_NOARG(short, long)`:: |
| Introduce an option that has no effect and takes no arguments. |
| Use it to hide deprecated options that are still to be recognized |
| and ignored silently. |
| |
| `OPT_PASSTHRU(short, long, &char_var, arg_str, description, flags)`:: |
| Introduce an option that will be reconstructed into a char* string, |
| which must be initialized to NULL. This is useful when you need to |
| pass the command-line option to another command. Any previous value |
| will be overwritten, so this should only be used for options where |
| the last one specified on the command line wins. |
| |
| `OPT_PASSTHRU_ARGV(short, long, &argv_array_var, arg_str, description, flags)`:: |
| Introduce an option where all instances of it on the command-line will |
| be reconstructed into an argv_array. This is useful when you need to |
| pass the command-line option, which can be specified multiple times, |
| to another command. |
| |
| `OPT_CMDMODE(short, long, &int_var, description, enum_val)`:: |
| Define an "operation mode" option, only one of which in the same |
| group of "operating mode" options that share the same `int_var` |
| can be given by the user. `enum_val` is set to `int_var` when the |
| option is used, but an error is reported if other "operating mode" |
| option has already set its value to the same `int_var`. |
| |
| |
| The last element of the array must be `OPT_END()`. |
| |
| If not stated otherwise, interpret the arguments as follows: |
| |
| * `short` is a character for the short option |
| (e.g. `'e'` for `-e`, use `0` to omit), |
| |
| * `long` is a string for the long option |
| (e.g. `"example"` for `--example`, use `NULL` to omit), |
| |
| * `int_var` is an integer variable, |
| |
| * `str_var` is a string variable (`char *`), |
| |
| * `arg_str` is the string that is shown as argument |
| (e.g. `"branch"` will result in `<branch>`). |
| If set to `NULL`, three dots (`...`) will be displayed. |
| |
| * `description` is a short string to describe the effect of the option. |
| It shall begin with a lower-case letter and a full stop (`.`) shall be |
| omitted at the end. |
| |
| Option Callbacks |
| ---------------- |
| |
| The function must be defined in this form: |
| |
| int func(const struct option *opt, const char *arg, int unset) |
| |
| The callback mechanism is as follows: |
| |
| * Inside `func`, the only interesting member of the structure |
| given by `opt` is the void pointer `opt->value`. |
| `*opt->value` will be the value that is saved into `var`, if you |
| use `OPT_CALLBACK()`. |
| For example, do `*(unsigned long *)opt->value = 42;` to get 42 |
| into an `unsigned long` variable. |
| |
| * Return value `0` indicates success and non-zero return |
| value will invoke `usage_with_options()` and, thus, die. |
| |
| * If the user negates the option, `arg` is `NULL` and `unset` is 1. |
| |
| Sophisticated option parsing |
| ---------------------------- |
| |
| If you need, for example, option callbacks with optional arguments |
| or without arguments at all, or if you need other special cases, |
| that are not handled by the macros above, you need to specify the |
| members of the `option` structure manually. |
| |
| This is not covered in this document, but well documented |
| in `parse-options.h` itself. |
| |
| Examples |
| -------- |
| |
| See `test-parse-options.c` and |
| `builtin/add.c`, |
| `builtin/clone.c`, |
| `builtin/commit.c`, |
| `builtin/fetch.c`, |
| `builtin/fsck.c`, |
| `builtin/rm.c` |
| for real-world examples. |