-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* jk/argv-array: run_hook: use argv_array API checkout: use argv_array API bisect: use argv_array API quote: provide sq_dequote_to_argv_array refactor argv_array into generic code quote.h: fix bogus comment add sha1_array API docs
- Loading branch information
Showing
11 changed files
with
261 additions
and
107 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
argv-array API | ||
============== | ||
|
||
The argv-array API allows one to dynamically build and store | ||
NULL-terminated lists. An argv-array maintains the invariant that the | ||
`argv` member always points to a non-NULL array, and that the array is | ||
always NULL-terminated at the element pointed to by `argv[argc]`. This | ||
makes the result suitable for passing to functions expecting to receive | ||
argv from main(), or the link:api-run-command.html[run-command API]. | ||
|
||
The link:api-string-list.html[string-list API] is similar, but cannot be | ||
used for these purposes; instead of storing a straight string pointer, | ||
it contains an item structure with a `util` field that is not compatible | ||
with the traditional argv interface. | ||
|
||
Each `argv_array` manages its own memory. Any strings pushed into the | ||
array are duplicated, and all memory is freed by argv_array_clear(). | ||
|
||
Data Structures | ||
--------------- | ||
|
||
`struct argv_array`:: | ||
|
||
A single array. This should be initialized by assignment from | ||
`ARGV_ARRAY_INIT`, or by calling `argv_array_init`. The `argv` | ||
member contains the actual array; the `argc` member contains the | ||
number of elements in the array, not including the terminating | ||
NULL. | ||
|
||
Functions | ||
--------- | ||
|
||
`argv_array_init`:: | ||
Initialize an array. This is no different than assigning from | ||
`ARGV_ARRAY_INIT`. | ||
|
||
`argv_array_push`:: | ||
Push a copy of a string onto the end of the array. | ||
|
||
`argv_array_pushf`:: | ||
Format a string and push it onto the end of the array. This is a | ||
convenience wrapper combining `strbuf_addf` and `argv_array_push`. | ||
|
||
`argv_array_clear`:: | ||
Free all memory associated with the array and return it to the | ||
initial, empty state. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
sha1-array API | ||
============== | ||
|
||
The sha1-array API provides storage and manipulation of sets of SHA1 | ||
identifiers. The emphasis is on storage and processing efficiency, | ||
making them suitable for large lists. Note that the ordering of items is | ||
not preserved over some operations. | ||
|
||
Data Structures | ||
--------------- | ||
|
||
`struct sha1_array`:: | ||
|
||
A single array of SHA1 hashes. This should be initialized by | ||
assignment from `SHA1_ARRAY_INIT`. The `sha1` member contains | ||
the actual data. The `nr` member contains the number of items in | ||
the set. The `alloc` and `sorted` members are used internally, | ||
and should not be needed by API callers. | ||
|
||
Functions | ||
--------- | ||
|
||
`sha1_array_append`:: | ||
Add an item to the set. The sha1 will be placed at the end of | ||
the array (but note that some operations below may lose this | ||
ordering). | ||
|
||
`sha1_array_sort`:: | ||
Sort the elements in the array. | ||
|
||
`sha1_array_lookup`:: | ||
Perform a binary search of the array for a specific sha1. | ||
If found, returns the offset (in number of elements) of the | ||
sha1. If not found, returns a negative integer. If the array is | ||
not sorted, this function has the side effect of sorting it. | ||
|
||
`sha1_array_clear`:: | ||
Free all memory associated with the array and return it to the | ||
initial, empty state. | ||
|
||
`sha1_array_for_each_unique`:: | ||
Efficiently iterate over each unique element of the list, | ||
executing the callback function for each one. If the array is | ||
not sorted, this function has the side effect of sorting it. | ||
|
||
Examples | ||
-------- | ||
|
||
----------------------------------------- | ||
void print_callback(const unsigned char sha1[20], | ||
void *data) | ||
{ | ||
printf("%s\n", sha1_to_hex(sha1)); | ||
} | ||
|
||
void some_func(void) | ||
{ | ||
struct sha1_array hashes = SHA1_ARRAY_INIT; | ||
unsigned char sha1[20]; | ||
|
||
/* Read objects into our set */ | ||
while (read_object_from_stdin(sha1)) | ||
sha1_array_append(&hashes, sha1); | ||
|
||
/* Check if some objects are in our set */ | ||
while (read_object_from_stdin(sha1)) { | ||
if (sha1_array_lookup(&hashes, sha1) >= 0) | ||
printf("it's in there!\n"); | ||
|
||
/* | ||
* Print the unique set of objects. We could also have | ||
* avoided adding duplicate objects in the first place, | ||
* but we would end up re-sorting the array repeatedly. | ||
* Instead, this will sort once and then skip duplicates | ||
* in linear time. | ||
*/ | ||
sha1_array_for_each_unique(&hashes, print_callback, NULL); | ||
} | ||
----------------------------------------- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
#include "cache.h" | ||
#include "argv-array.h" | ||
#include "strbuf.h" | ||
|
||
static const char *empty_argv_storage = NULL; | ||
const char **empty_argv = &empty_argv_storage; | ||
|
||
void argv_array_init(struct argv_array *array) | ||
{ | ||
array->argv = empty_argv; | ||
array->argc = 0; | ||
array->alloc = 0; | ||
} | ||
|
||
static void argv_array_push_nodup(struct argv_array *array, const char *value) | ||
{ | ||
if (array->argv == empty_argv) | ||
array->argv = NULL; | ||
|
||
ALLOC_GROW(array->argv, array->argc + 2, array->alloc); | ||
array->argv[array->argc++] = value; | ||
array->argv[array->argc] = NULL; | ||
} | ||
|
||
void argv_array_push(struct argv_array *array, const char *value) | ||
{ | ||
argv_array_push_nodup(array, xstrdup(value)); | ||
} | ||
|
||
void argv_array_pushf(struct argv_array *array, const char *fmt, ...) | ||
{ | ||
va_list ap; | ||
struct strbuf v = STRBUF_INIT; | ||
|
||
va_start(ap, fmt); | ||
strbuf_vaddf(&v, fmt, ap); | ||
va_end(ap); | ||
|
||
argv_array_push_nodup(array, strbuf_detach(&v, NULL)); | ||
} | ||
|
||
void argv_array_clear(struct argv_array *array) | ||
{ | ||
if (array->argv != empty_argv) { | ||
int i; | ||
for (i = 0; i < array->argc; i++) | ||
free((char **)array->argv[i]); | ||
free(array->argv); | ||
} | ||
argv_array_init(array); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
#ifndef ARGV_ARRAY_H | ||
#define ARGV_ARRAY_H | ||
|
||
extern const char **empty_argv; | ||
|
||
struct argv_array { | ||
const char **argv; | ||
int argc; | ||
int alloc; | ||
}; | ||
|
||
#define ARGV_ARRAY_INIT { empty_argv, 0, 0 } | ||
|
||
void argv_array_init(struct argv_array *); | ||
void argv_array_push(struct argv_array *, const char *); | ||
__attribute__((format (printf,2,3))) | ||
void argv_array_pushf(struct argv_array *, const char *fmt, ...); | ||
void argv_array_clear(struct argv_array *); | ||
|
||
#endif /* ARGV_ARRAY_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.