diff options
Diffstat (limited to 'Documentation/technical')
| -rw-r--r-- | Documentation/technical/api-builtin.txt | 15 | ||||
| -rw-r--r-- | Documentation/technical/api-history-graph.txt | 179 | ||||
| -rw-r--r-- | Documentation/technical/api-parse-options.txt | 204 | ||||
| -rw-r--r-- | Documentation/technical/api-path-list.txt | 125 | ||||
| -rw-r--r-- | Documentation/technical/api-revision-walking.txt | 60 | ||||
| -rw-r--r-- | Documentation/technical/api-run-command.txt | 4 | ||||
| -rw-r--r-- | Documentation/technical/api-strbuf.txt | 239 | 
7 files changed, 810 insertions, 16 deletions
| diff --git a/Documentation/technical/api-builtin.txt b/Documentation/technical/api-builtin.txt index 52cdb4c520..7ede1e64e5 100644 --- a/Documentation/technical/api-builtin.txt +++ b/Documentation/technical/api-builtin.txt @@ -4,7 +4,7 @@ builtin API  Adding a new built-in  --------------------- -There are 4 things to do to add a bulit-in command implementation to +There are 4 things to do to add a built-in command implementation to  git:  . Define the implementation of the built-in command `foo` with @@ -18,8 +18,8 @@ git:    defined in `git.c`.  The entry should look like:  	{ "foo", cmd_foo, <options> }, - -  where options is the bitwise-or of: ++ +where options is the bitwise-or of:  `RUN_SETUP`:: @@ -33,6 +33,12 @@ git:  	If the standard output is connected to a tty, spawn a pager and  	feed our output to it. +`NEED_WORK_TREE`:: + +	Make sure there is a work tree, i.e. the command cannot act +	on bare repositories. +	This makes only sense when `RUN_SETUP` is also set. +  . Add `builtin-foo.o` to `BUILTIN_OBJS` in `Makefile`.  Additionally, if `foo` is a new command, there are 3 more things to do: @@ -41,8 +47,7 @@ Additionally, if `foo` is a new command, there are 3 more things to do:  . Write documentation in `Documentation/git-foo.txt`. -. Add an entry for `git-foo` to the list at the end of -  `Documentation/cmd-list.perl`. +. Add an entry for `git-foo` to `command-list.txt`.  How a built-in is called diff --git a/Documentation/technical/api-history-graph.txt b/Documentation/technical/api-history-graph.txt new file mode 100644 index 0000000000..e9559790a3 --- /dev/null +++ b/Documentation/technical/api-history-graph.txt @@ -0,0 +1,179 @@ +history graph API +================= + +The graph API is used to draw a text-based representation of the commit +history.  The API generates the graph in a line-by-line fashion. + +Functions +--------- + +Core functions: + +* `graph_init()` creates a new `struct git_graph` + +* `graph_release()` destroys a `struct git_graph`, and frees the memory +  associated with it. + +* `graph_update()` moves the graph to a new commit. + +* `graph_next_line()` outputs the next line of the graph into a strbuf.  It +  does not add a terminating newline. + +* `graph_padding_line()` outputs a line of vertical padding in the graph.  It +  is similar to `graph_next_line()`, but is guaranteed to never print the line +  containing the current commit.  Where `graph_next_line()` would print the +  commit line next, `graph_padding_line()` prints a line that simply extends +  all branch lines downwards one row, leaving their positions unchanged. + +* `graph_is_commit_finished()` determines if the graph has output all lines +  necessary for the current commit.  If `graph_update()` is called before all +  lines for the current commit have been printed, the next call to +  `graph_next_line()` will output an ellipsis, to indicate that a portion of +  the graph was omitted. + +The following utility functions are wrappers around `graph_next_line()` and +`graph_is_commit_finished()`.  They always print the output to stdout. +They can all be called with a NULL graph argument, in which case no graph +output will be printed. + +* `graph_show_commit()` calls `graph_next_line()` until it returns non-zero. +  This prints all graph lines up to, and including, the line containing this +  commit.  Output is printed to stdout.  The last line printed does not contain +  a terminating newline.  This should not be called if the commit line has +  already been printed, or it will loop forever. + +* `graph_show_oneline()` calls `graph_next_line()` and prints the result to +  stdout.  The line printed does not contain a terminating newline. + +* `graph_show_padding()` calls `graph_padding_line()` and prints the result to +  stdout.  The line printed does not contain a terminating newline. + +* `graph_show_remainder()` calls `graph_next_line()` until +  `graph_is_commit_finished()` returns non-zero.  Output is printed to stdout. +  The last line printed does not contain a terminating newline.  Returns 1 if +  output was printed, and 0 if no output was necessary. + +* `graph_show_strbuf()` prints the specified strbuf to stdout, prefixing all +  lines but the first with a graph line.  The caller is responsible for +  ensuring graph output for the first line has already been printed to stdout. +  (This can be done with `graph_show_commit()` or `graph_show_oneline()`.)  If +  a NULL graph is supplied, the strbuf is printed as-is. + +* `graph_show_commit_msg()` is similar to `graph_show_strbuf()`, but it also +  prints the remainder of the graph, if more lines are needed after the strbuf +  ends.  It is better than directly calling `graph_show_strbuf()` followed by +  `graph_show_remainder()` since it properly handles buffers that do not end in +  a terminating newline.  The output printed by `graph_show_commit_msg()` will +  end in a newline if and only if the strbuf ends in a newline. + +Data structure +-------------- +`struct git_graph` is an opaque data type used to store the current graph +state. + +Calling sequence +---------------- + +* Create a `struct git_graph` by calling `graph_init()`.  When using the +  revision walking API, this is done automatically by `setup_revisions()` if +  the '--graph' option is supplied. + +* Use the revision walking API to walk through a group of contiguous commits. +  The `get_revision()` function automatically calls `graph_update()` each time +  it is invoked. + +* For each commit, call `graph_next_line()` repeatedly, until +  `graph_is_commit_finished()` returns non-zero.  Each call go +  `graph_next_line()` will output a single line of the graph.  The resulting +  lines will not contain any newlines.  `graph_next_line()` returns 1 if the +  resulting line contains the current commit, or 0 if this is merely a line +  needed to adjust the graph before or after the current commit.  This return +  value can be used to determine where to print the commit summary information +  alongside the graph output. + +Limitations +----------- + +* `graph_update()` must be called with commits in topological order.  It should +  not be called on a commit if it has already been invoked with an ancestor of +  that commit, or the graph output will be incorrect. + +* `graph_update()` must be called on a contiguous group of commits.  If +  `graph_update()` is called on a particular commit, it should later be called +  on all parents of that commit.  Parents must not be skipped, or the graph +  output will appear incorrect. ++ +`graph_update()` may be used on a pruned set of commits only if the parent list +has been rewritten so as to include only ancestors from the pruned set. + +* The graph API does not currently support reverse commit ordering.  In +  order to implement reverse ordering, the graphing API needs an +  (efficient) mechanism to find the children of a commit. + +Sample usage +------------ + +------------ +struct commit *commit; +struct git_graph *graph = graph_init(opts); + +while ((commit = get_revision(opts)) != NULL) { +	graph_update(graph, commit); +	while (!graph_is_commit_finished(graph)) +	{ +		struct strbuf sb; +		int is_commit_line; + +		strbuf_init(&sb, 0); +		is_commit_line = graph_next_line(graph, &sb); +		fputs(sb.buf, stdout); + +		if (is_commit_line) +			log_tree_commit(opts, commit); +		else +			putchar(opts->diffopt.line_termination); +	} +} + +graph_release(graph); +------------ + +Sample output +------------- + +The following is an example of the output from the graph API.  This output does +not include any commit summary information--callers are responsible for +outputting that information, if desired. + +------------ +* +* +M +|\ +* | +| | * +| \ \ +|  \ \ +M-. \ \ +|\ \ \ \ +| | * | | +| | | | | * +| | | | | * +| | | | | M +| | | | | |\ +| | | | | | * +| * | | | | | +| | | | | M  \ +| | | | | |\  | +| | | | * | | | +| | | | * | | | +* | | | | | | | +| |/ / / / / / +|/| / / / / / +* | | | | | | +|/ / / / / / +* | | | | | +| | | | | * +| | | | |/ +| | | | * +------------ diff --git a/Documentation/technical/api-parse-options.txt b/Documentation/technical/api-parse-options.txt index b7cda94f54..539863b1f9 100644 --- a/Documentation/technical/api-parse-options.txt +++ b/Documentation/technical/api-parse-options.txt @@ -1,6 +1,206 @@  parse-options API  ================= -Talk about <parse-options.h> +The parse-options API is used to parse and massage options in git +and to provide a usage help with consistent look. -(Pierre) +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: + +* 'sticked' and 'separate form' of options with arguments. +  `-oArg` is sticked, `-o Arg` is separate form. +  `\--option=Arg` is sticked, `\--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`. + +* 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, 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. ++ +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. + +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__DRY_RUN(&int_var)`:: +	Add `-n, \--dry-run`. + +`OPT__QUIET(&int_var)`:: +	Add `-q, \--quiet`. + +`OPT__VERBOSE(&int_var)`:: +	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_BOOLEAN(short, long, &int_var, description)`:: +	Introduce a boolean option. +	`int_var` is incremented on each use. + +`OPT_BIT(short, long, &int_var, description, mask)`:: +	Introduce a boolean option. +	If used, `int_var` is bitwise-ored with `mask`. + +`OPT_SET_INT(short, long, &int_var, description, integer)`:: +	Introduce a boolean option. +	If used, set `int_var` to `integer`. + +`OPT_SET_PTR(short, long, &ptr_var, description, ptr)`:: +	Introduce a boolean option. +	If used, set `ptr_var` to `ptr`. + +`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_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_ARGUMENT(long, description)`:: +	Introduce a long-option argument that will be kept in `argv[]`. + + +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 `funct`, 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. diff --git a/Documentation/technical/api-path-list.txt b/Documentation/technical/api-path-list.txt index d077683171..9dbedd0a67 100644 --- a/Documentation/technical/api-path-list.txt +++ b/Documentation/technical/api-path-list.txt @@ -1,9 +1,126 @@  path-list API  ============= -Talk about <path-list.h>, things like +The path_list API offers a data structure and functions to handle sorted +and unsorted string lists. -* it is not just paths but strings in general; -* the calling sequence. +The name is a bit misleading, a path_list may store not only paths but +strings in general. -(Dscho) +The caller: + +. Allocates and clears a `struct path_list` variable. + +. Initializes the members. You might want to set the flag `strdup_paths` +  if the strings should be strdup()ed. For example, this is necessary +  when you add something like git_path("..."), since that function returns +  a static buffer that will change with the next call to git_path(). ++ +If you need something advanced, you can manually malloc() the `items` +member (you need this if you add things later) and you should set the +`nr` and `alloc` members in that case, too. + +. Adds new items to the list, using `path_list_append` or `path_list_insert`. + +. Can check if a string is in the list using `path_list_has_path` or +  `unsorted_path_list_has_path` and get it from the list using +  `path_list_lookup` for sorted lists. + +. Can sort an unsorted list using `sort_path_list`. + +. Finally it should free the list using `path_list_clear`. + +Example: + +---- +struct path_list list; +int i; + +memset(&list, 0, sizeof(struct path_list)); +path_list_append("foo", &list); +path_list_append("bar", &list); +for (i = 0; i < list.nr; i++) +	printf("%s\n", list.items[i].path) +---- + +NOTE: It is more efficient to build an unsorted list and sort it +afterwards, instead of building a sorted list (`O(n log n)` instead of +`O(n^2)`). ++ +However, if you use the list to check if a certain string was added +already, you should not do that (using unsorted_path_list_has_path()), +because the complexity would be quadratic again (but with a worse factor). + +Functions +--------- + +* General ones (works with sorted and unsorted lists as well) + +`print_path_list`:: + +	Dump a path_list to stdout, useful mainly for debugging purposes. It +	can take an optional header argument and it writes out the +	string-pointer pairs of the path_list, each one in its own line. + +`path_list_clear`:: + +	Free a path_list. The `path` pointer of the items will be freed in case +	the `strdup_paths` member of the path_list is set. The second parameter +	controls if the `util` pointer of the items should be freed or not. + +* Functions for sorted lists only + +`path_list_has_path`:: + +	Determine if the path_list has a given string or not. + +`path_list_insert`:: + +	Insert a new element to the path_list. The returned pointer can be handy +	if you want to write something to the `util` pointer of the +	path_list_item containing the just added string. ++ +Since this function uses xrealloc() (which die()s if it fails) if the +list needs to grow, it is safe not to check the pointer. I.e. you may +write `path_list_insert(...)->util = ...;`. + +`path_list_lookup`:: + +	Look up a given string in the path_list, returning the containing +	path_list_item. If the string is not found, NULL is returned. + +* Functions for unsorted lists only + +`path_list_append`:: + +	Append a new string to the end of the path_list. + +`sort_path_list`:: + +	Make an unsorted list sorted. + +`unsorted_path_list_has_path`:: + +	It's like `path_list_has_path()` but for unsorted lists. ++ +This function needs to look through all items, as opposed to its +counterpart for sorted lists, which performs a binary search. + +Data structures +--------------- + +* `struct path_list_item` + +Represents an item of the list. The `path` member is a pointer to the +string, and you may use the `util` member for any purpose, if you want. + +* `struct path_list` + +Represents the list itself. + +. The array of items are available via the `items` member. +. The `nr` member contains the number of items stored in the list. +. The `alloc` member is used to avoid reallocating at every insertion. +  You should not tamper with it. +. Setting the `strdup_paths` member to 1 will strdup() the strings +  before adding them, see above. diff --git a/Documentation/technical/api-revision-walking.txt b/Documentation/technical/api-revision-walking.txt index 01a24551af..996da0503a 100644 --- a/Documentation/technical/api-revision-walking.txt +++ b/Documentation/technical/api-revision-walking.txt @@ -1,9 +1,67 @@  revision walking API  ==================== +The revision walking API offers functions to build a list of revisions +and then iterate over that list. + +Calling sequence +---------------- + +The walking API has a given calling sequence: first you need to +initialize a rev_info structure, then add revisions to control what kind +of revision list do you want to get, finally you can iterate over the +revision list. + +Functions +--------- + +`init_revisions`:: + +	Initialize a rev_info structure with default values. The second +	parameter may be NULL or can be prefix path, and then the `.prefix` +	variable will be set to it. This is typically the first function you +	want to call when you want to deal with a revision list. After calling +	this function, you are free to customize options, like set +	`.ignore_merges` to 0 if you don't want to ignore merges, and so on. See +	`revision.h` for a complete list of available options. + +`add_pending_object`:: + +	This function can be used if you want to add commit objects as revision +	information. You can use the `UNINTERESTING` object flag to indicate if +	you want to include or exclude the given commit (and commits reachable +	from the given commit) from the revision list. ++ +NOTE: If you have the commits as a string list then you probably want to +use setup_revisions(), instead of parsing each string and using this +function. + +`setup_revisions`:: + +	Parse revision information, filling in the `rev_info` structure, and +	removing the used arguments from the argument list. Returns the number +	of arguments left that weren't recognized, which are also moved to the +	head of the argument list. The last parameter is used in case no +	parameter given by the first two arguments. + +`prepare_revision_walk`:: + +	Prepares the rev_info structure for a walk. You should check if it +	returns any error (non-zero return code) and if it does not, you can +	start using get_revision() to do the iteration. + +`get_revision`:: + +	Takes a pointer to a `rev_info` structure and iterates over it, +	returning a `struct commit *` each time you call it. The end of the +	revision list is indicated by returning a NULL pointer. + +Data structures +--------------- +  Talk about <revision.h>, things like:  * two diff_options, one for path limiting, another for output; -* calling sequence: init_revisions(), setup_revsions(), get_revision(); +* remaining functions;  (Linus, JC, Dscho) diff --git a/Documentation/technical/api-run-command.txt b/Documentation/technical/api-run-command.txt index c364a22c8f..3e1342acf4 100644 --- a/Documentation/technical/api-run-command.txt +++ b/Documentation/technical/api-run-command.txt @@ -63,7 +63,7 @@ command to run in a sub-process.  The caller: -1. allocates and clears (memset(&chld, '0', sizeof(chld));) a +1. allocates and clears (memset(&chld, 0, sizeof(chld));) a     struct child_process variable;  2. initializes the members;  3. calls start_command(); @@ -136,7 +136,7 @@ to produce output that the caller reads.  The caller: -1. allocates and clears (memset(&asy, '0', sizeof(asy));) a +1. allocates and clears (memset(&asy, 0, sizeof(asy));) a     struct async variable;  2. initializes .proc and .data;  3. calls start_async(); diff --git a/Documentation/technical/api-strbuf.txt b/Documentation/technical/api-strbuf.txt index a52e4f36d5..a9668e5f2d 100644 --- a/Documentation/technical/api-strbuf.txt +++ b/Documentation/technical/api-strbuf.txt @@ -1,6 +1,241 @@  strbuf API  ========== -Talk about <strbuf.h> +strbuf's are meant to be used with all the usual C string and memory +APIs. Given that the length of the buffer is known, it's often better to +use the mem* functions than a str* one (memchr vs. strchr e.g.). +Though, one has to be careful about the fact that str* functions often +stop on NULs and that strbufs may have embedded NULs. -(Pierre, JC) +An strbuf is NUL terminated for convenience, but no function in the +strbuf API actually relies on the string being free of NULs. + +strbufs has some invariants that are very important to keep in mind: + +. The `buf` member is never NULL, so you it can be used in any usual C +string operations safely. strbuf's _have_ to be initialized either by +`strbuf_init()` or by `= STRBUF_INIT` before the invariants, though. ++ +Do *not* assume anything on what `buf` really is (e.g. if it is +allocated memory or not), use `strbuf_detach()` to unwrap a memory +buffer from its strbuf shell in a safe way. That is the sole supported +way. This will give you a malloced buffer that you can later `free()`. ++ +However, it it totally safe to modify anything in the string pointed by +the `buf` member, between the indices `0` and `len-1` (inclusive). + +. The `buf` member is a byte array that has at least `len + 1` bytes +  allocated. The extra byte is used to store a `'\0'`, allowing the +  `buf` member to be a valid C-string. Every strbuf function ensure this +  invariant is preserved. ++ +NOTE: It is OK to "play" with the buffer directly if you work it this +      way: ++ +---- +strbuf_grow(sb, SOME_SIZE); <1> +strbuf_setlen(sb, sb->len + SOME_OTHER_SIZE); +---- +<1> Here, the memory array starting at `sb->buf`, and of length +`strbuf_avail(sb)` is all yours, and you can be sure that +`strbuf_avail(sb)` is at least `SOME_SIZE`. ++ +NOTE: `SOME_OTHER_SIZE` must be smaller or equal to `strbuf_avail(sb)`. ++ +Doing so is safe, though if it has to be done in many places, adding the +missing API to the strbuf module is the way to go. ++ +WARNING: Do _not_ assume that the area that is yours is of size `alloc +- 1` even if it's true in the current implementation. Alloc is somehow a +"private" member that should not be messed with. Use `strbuf_avail()` +instead. + +Data structures +--------------- + +* `struct strbuf` + +This is string buffer structure. The `len` member can be used to +determine the current length of the string, and `buf` member provides access to +the string itself. + +Functions +--------- + +* Life cycle + +`strbuf_init`:: + +	Initialize the structure. The second parameter can be zero or a bigger +	number to allocate memory, in case you want to prevent further reallocs. + +`strbuf_release`:: + +	Release a string buffer and the memory it used. You should not use the +	string buffer after using this function, unless you initialize it again. + +`strbuf_detach`:: + +	Detach the string from the strbuf and returns it; you now own the +	storage the string occupies and it is your responsibility from then on +	to release it with `free(3)` when you are done with it. + +`strbuf_attach`:: + +	Attach a string to a buffer. You should specify the string to attach, +	the current length of the string and the amount of allocated memory. +	The amount must be larger than the string length, because the string you +	pass is supposed to be a NUL-terminated string.  This string _must_ be +	malloc()ed, and after attaching, the pointer cannot be relied upon +	anymore, and neither be free()d directly. + +`strbuf_swap`:: + +	Swap the contents of two string buffers. + +* Related to the size of the buffer + +`strbuf_avail`:: + +	Determine the amount of allocated but unused memory. + +`strbuf_grow`:: + +	Ensure that at least this amount of unused memory is available after +	`len`. This is used when you know a typical size for what you will add +	and want to avoid repetitive automatic resizing of the underlying buffer. +	This is never a needed operation, but can be critical for performance in +	some cases. + +`strbuf_setlen`:: + +	Set the length of the buffer to a given value. This function does *not* +	allocate new memory, so you should not perform a `strbuf_setlen()` to a +	length that is larger than `len + strbuf_avail()`. `strbuf_setlen()` is +	just meant as a 'please fix invariants from this strbuf I just messed +	with'. + +`strbuf_reset`:: + +	Empty the buffer by setting the size of it to zero. + +* Related to the contents of the buffer + +`strbuf_rtrim`:: + +	Strip whitespace from the end of a string. + +`strbuf_cmp`:: + +	Compare two buffers. Returns an integer less than, equal to, or greater +	than zero if the first buffer is found, respectively, to be less than, +	to match, or be greater than the second buffer. + +* Adding data to the buffer + +NOTE: All of these functions in this section will grow the buffer as +      necessary. + +`strbuf_addch`:: + +	Add a single character to the buffer. + +`strbuf_insert`:: + +	Insert data to the given position of the buffer. The remaining contents +	will be shifted, not overwritten. + +`strbuf_remove`:: + +	Remove given amount of data from a given position of the buffer. + +`strbuf_splice`:: + +	Remove the bytes between `pos..pos+len` and replace it with the given +	data. + +`strbuf_add`:: + +	Add data of given length to the buffer. + +`strbuf_addstr`:: + +Add a NUL-terminated string to the buffer. ++ +NOTE: This function will *always* be implemented as an inline or a macro +that expands to: ++ +---- +strbuf_add(..., s, strlen(s)); +---- ++ +Meaning that this is efficient to write things like: ++ +---- +strbuf_addstr(sb, "immediate string"); +---- + +`strbuf_addbuf`:: + +	Copy the contents of an other buffer at the end of the current one. + +`strbuf_adddup`:: + +	Copy part of the buffer from a given position till a given length to the +	end of the buffer. + +`strbuf_expand`:: + +	This function can be used to expand a format string containing +	placeholders. To that end, it parses the string and calls the specified +	function for every percent sign found. ++ +The callback function is given a pointer to the character after the `%` +and a pointer to the struct strbuf.  It is expected to add the expanded +version of the placeholder to the strbuf, e.g. to add a newline +character if the letter `n` appears after a `%`.  The function returns +the length of the placeholder recognized and `strbuf_expand()` skips +over it. ++ +All other characters (non-percent and not skipped ones) are copied +verbatim to the strbuf.  If the callback returned zero, meaning that the +placeholder is unknown, then the percent sign is copied, too. ++ +In order to facilitate caching and to make it possible to give +parameters to the callback, `strbuf_expand()` passes a context pointer, +which can be used by the programmer of the callback as she sees fit. + +`strbuf_addf`:: + +	Add a formatted string to the buffer. + +`strbuf_fread`:: + +	Read a given size of data from a FILE* pointer to the buffer. ++ +NOTE: The buffer is rewinded if the read fails. If -1 is returned, +`errno` must be consulted, like you would do for `read(3)`. +`strbuf_read()`, `strbuf_read_file()` and `strbuf_getline()` has the +same behaviour as well. + +`strbuf_read`:: + +	Read the contents of a given file descriptor. The third argument can be +	used to give a hint about the file size, to avoid reallocs. + +`strbuf_read_file`:: + +	Read the contents of a file, specified by its path. The third argument +	can be used to give a hint about the file size, to avoid reallocs. + +`strbuf_getline`:: + +	Read a line from a FILE* pointer. The second argument specifies the line +	terminator character, typically `'\n'`. + +`stripspace`:: + +	Strip whitespace from a buffer. The second parameter controls if +	comments are considered contents to be removed or not. + +`launch_editor`:: | 
