281 lines
		
	
	
		
			9.5 KiB
		
	
	
	
		
			Plaintext
		
	
	
			
		
		
	
	
			281 lines
		
	
	
		
			9.5 KiB
		
	
	
	
		
			Plaintext
		
	
	
| 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.
 | |
| 	`int_var` is incremented on each use of `--option`, and
 | |
| 	reset to zero with `--no-option`.
 | |
| 
 | |
| `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_INTEGER(short, long, &int_var, description)`::
 | |
| 	Introduce an option with integer argument.
 | |
| 	The integer is put into `int_var`.
 | |
| 
 | |
| `OPT_DATE(short, long, &int_var, description)`::
 | |
| 	Introduce an option with date argument, see `approxidate()`.
 | |
| 	The timestamp is put into `int_var`.
 | |
| 
 | |
| `OPT_EXPIRY_DATE(short, long, &int_var, description)`::
 | |
| 	Introduce an option with expiry date argument, see `parse_expiry_date()`.
 | |
| 	The timestamp is put into `int_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.
 | |
| 
 | |
| 
 | |
| 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.
 |