From dbbcd44fb47347a3fdbee88ea21805b7f4ac0b98 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Tue, 28 Jul 2020 16:23:39 -0400 Subject: strvec: rename files from argv-array to strvec This requires updating #include lines across the code-base, but that's all fairly mechanical, and was done with: git ls-files '*.c' '*.h' | xargs perl -i -pe 's/argv-array.h/strvec.h/' Signed-off-by: Jeff King Signed-off-by: Junio C Hamano diff --git a/Makefile b/Makefile index 372139f..65f8cfb 100644 --- a/Makefile +++ b/Makefile @@ -828,7 +828,6 @@ LIB_OBJS += apply.o LIB_OBJS += archive-tar.o LIB_OBJS += archive-zip.o LIB_OBJS += archive.o -LIB_OBJS += argv-array.o LIB_OBJS += attr.o LIB_OBJS += base85.o LIB_OBJS += bisect.o @@ -986,6 +985,7 @@ LIB_OBJS += sigchain.o LIB_OBJS += split-index.o LIB_OBJS += stable-qsort.o LIB_OBJS += strbuf.o +LIB_OBJS += strvec.o LIB_OBJS += streaming.o LIB_OBJS += string-list.o LIB_OBJS += sub-process.o diff --git a/add-patch.c b/add-patch.c index f899389..09d00c5 100644 --- a/add-patch.c +++ b/add-patch.c @@ -2,7 +2,7 @@ #include "add-interactive.h" #include "strbuf.h" #include "run-command.h" -#include "argv-array.h" +#include "strvec.h" #include "pathspec.h" #include "color.h" #include "diff.h" diff --git a/argv-array.c b/argv-array.c deleted file mode 100644 index b7461c4..0000000 --- a/argv-array.c +++ /dev/null @@ -1,109 +0,0 @@ -#include "cache.h" -#include "argv-array.h" -#include "strbuf.h" - -const char *empty_strvec[] = { NULL }; - -void strvec_init(struct strvec *array) -{ - array->argv = empty_strvec; - array->argc = 0; - array->alloc = 0; -} - -static void strvec_push_nodup(struct strvec *array, const char *value) -{ - if (array->argv == empty_strvec) - array->argv = NULL; - - ALLOC_GROW(array->argv, array->argc + 2, array->alloc); - array->argv[array->argc++] = value; - array->argv[array->argc] = NULL; -} - -const char *strvec_push(struct strvec *array, const char *value) -{ - strvec_push_nodup(array, xstrdup(value)); - return array->argv[array->argc - 1]; -} - -const char *strvec_pushf(struct strvec *array, const char *fmt, ...) -{ - va_list ap; - struct strbuf v = STRBUF_INIT; - - va_start(ap, fmt); - strbuf_vaddf(&v, fmt, ap); - va_end(ap); - - strvec_push_nodup(array, strbuf_detach(&v, NULL)); - return array->argv[array->argc - 1]; -} - -void strvec_pushl(struct strvec *array, ...) -{ - va_list ap; - const char *arg; - - va_start(ap, array); - while ((arg = va_arg(ap, const char *))) - strvec_push(array, arg); - va_end(ap); -} - -void strvec_pushv(struct strvec *array, const char **argv) -{ - for (; *argv; argv++) - strvec_push(array, *argv); -} - -void strvec_pop(struct strvec *array) -{ - if (!array->argc) - return; - free((char *)array->argv[array->argc - 1]); - array->argv[array->argc - 1] = NULL; - array->argc--; -} - -void strvec_split(struct strvec *array, const char *to_split) -{ - while (isspace(*to_split)) - to_split++; - for (;;) { - const char *p = to_split; - - if (!*p) - break; - - while (*p && !isspace(*p)) - p++; - strvec_push_nodup(array, xstrndup(to_split, p - to_split)); - - while (isspace(*p)) - p++; - to_split = p; - } -} - -void strvec_clear(struct strvec *array) -{ - if (array->argv != empty_strvec) { - int i; - for (i = 0; i < array->argc; i++) - free((char *)array->argv[i]); - free(array->argv); - } - strvec_init(array); -} - -const char **strvec_detach(struct strvec *array) -{ - if (array->argv == empty_strvec) - return xcalloc(1, sizeof(const char *)); - else { - const char **ret = array->argv; - strvec_init(array); - return ret; - } -} diff --git a/argv-array.h b/argv-array.h deleted file mode 100644 index ca66a33..0000000 --- a/argv-array.h +++ /dev/null @@ -1,102 +0,0 @@ -#ifndef ARGV_ARRAY_H -#define ARGV_ARRAY_H - -/** - * 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(). - * - * The string-list API (documented in string-list.h) 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 `strvec` manages its own memory. Any strings pushed into the - * array are duplicated, and all memory is freed by strvec_clear(). - */ - -extern const char *empty_strvec[]; - -/** - * A single array. This should be initialized by assignment from - * `STRVEC_INIT`, or by calling `strvec_init`. The `argv` - * member contains the actual array; the `argc` member contains the - * number of elements in the array, not including the terminating - * NULL. - */ -struct strvec { - const char **argv; - size_t argc; - size_t alloc; -}; - -#define STRVEC_INIT { empty_strvec, 0, 0 } - -/** - * Initialize an array. This is no different than assigning from - * `STRVEC_INIT`. - */ -void strvec_init(struct strvec *); - -/* Push a copy of a string onto the end of the array. */ -const char *strvec_push(struct strvec *, const char *); - -/** - * Format a string and push it onto the end of the array. This is a - * convenience wrapper combining `strbuf_addf` and `strvec_push`. - */ -__attribute__((format (printf,2,3))) -const char *strvec_pushf(struct strvec *, const char *fmt, ...); - -/** - * Push a list of strings onto the end of the array. The arguments - * should be a list of `const char *` strings, terminated by a NULL - * argument. - */ -LAST_ARG_MUST_BE_NULL -void strvec_pushl(struct strvec *, ...); - -/* Push a null-terminated array of strings onto the end of the array. */ -void strvec_pushv(struct strvec *, const char **); - -/** - * Remove the final element from the array. If there are no - * elements in the array, do nothing. - */ -void strvec_pop(struct strvec *); - -/* Splits by whitespace; does not handle quoted arguments! */ -void strvec_split(struct strvec *, const char *); - -/** - * Free all memory associated with the array and return it to the - * initial, empty state. - */ -void strvec_clear(struct strvec *); - -/** - * Disconnect the `argv` member from the `strvec` struct and - * return it. The caller is responsible for freeing the memory used - * by the array, and by the strings it references. After detaching, - * the `strvec` is in a reinitialized state and can be pushed - * into again. - */ -const char **strvec_detach(struct strvec *); - -/* compatibility for historic argv_array interface */ -#define argv_array strvec -#define ARGV_ARRAY_INIT STRVEC_INIT -#define argv_array_init strvec_init -#define argv_array_push strvec_push -#define argv_array_pushf strvec_pushf -#define argv_array_pushl strvec_pushl -#define argv_array_pushv strvec_pushv -#define argv_array_pop strvec_pop -#define argv_array_split strvec_split -#define argv_array_clear strvec_clear -#define argv_array_detach strvec_detach - -#endif /* ARGV_ARRAY_H */ diff --git a/bisect.c b/bisect.c index d5e8304..3160e82 100644 --- a/bisect.c +++ b/bisect.c @@ -11,7 +11,7 @@ #include "log-tree.h" #include "bisect.h" #include "oid-array.h" -#include "argv-array.h" +#include "strvec.h" #include "commit-slab.h" #include "commit-reach.h" #include "object-store.h" diff --git a/builtin/add.c b/builtin/add.c index 298e011..6cd9a4c 100644 --- a/builtin/add.c +++ b/builtin/add.c @@ -18,7 +18,7 @@ #include "diffcore.h" #include "revision.h" #include "bulk-checkin.h" -#include "argv-array.h" +#include "strvec.h" #include "submodule.h" #include "add-interactive.h" diff --git a/builtin/annotate.c b/builtin/annotate.c index da413ae..4353448 100644 --- a/builtin/annotate.c +++ b/builtin/annotate.c @@ -5,7 +5,7 @@ */ #include "git-compat-util.h" #include "builtin.h" -#include "argv-array.h" +#include "strvec.h" int cmd_annotate(int argc, const char **argv, const char *prefix) { diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c index ec49962..e929315 100644 --- a/builtin/bisect--helper.c +++ b/builtin/bisect--helper.c @@ -4,7 +4,7 @@ #include "bisect.h" #include "refs.h" #include "dir.h" -#include "argv-array.h" +#include "strvec.h" #include "run-command.h" #include "prompt.h" #include "quote.h" diff --git a/builtin/bundle.c b/builtin/bundle.c index f049d27..51fc6d9 100644 --- a/builtin/bundle.c +++ b/builtin/bundle.c @@ -1,5 +1,5 @@ #include "builtin.h" -#include "argv-array.h" +#include "strvec.h" #include "parse-options.h" #include "cache.h" #include "bundle.h" diff --git a/builtin/describe.c b/builtin/describe.c index 21d2cb9..32ad682 100644 --- a/builtin/describe.c +++ b/builtin/describe.c @@ -12,7 +12,7 @@ #include "revision.h" #include "diff.h" #include "hashmap.h" -#include "argv-array.h" +#include "strvec.h" #include "run-command.h" #include "object-store.h" #include "list-objects.h" diff --git a/builtin/difftool.c b/builtin/difftool.c index c280e68..c0608a7 100644 --- a/builtin/difftool.c +++ b/builtin/difftool.c @@ -18,7 +18,7 @@ #include "run-command.h" #include "exec-cmd.h" #include "parse-options.h" -#include "argv-array.h" +#include "strvec.h" #include "strbuf.h" #include "lockfile.h" #include "object-store.h" diff --git a/builtin/fetch.c b/builtin/fetch.c index 82ac4be..b183b55 100644 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@ -19,7 +19,7 @@ #include "submodule-config.h" #include "submodule.h" #include "connected.h" -#include "argv-array.h" +#include "strvec.h" #include "utf8.h" #include "packfile.h" #include "list-objects-filter-options.h" diff --git a/builtin/gc.c b/builtin/gc.c index 8e0b9cf..27951ee 100644 --- a/builtin/gc.c +++ b/builtin/gc.c @@ -18,7 +18,7 @@ #include "parse-options.h" #include "run-command.h" #include "sigchain.h" -#include "argv-array.h" +#include "strvec.h" #include "commit.h" #include "commit-graph.h" #include "packfile.h" diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index 7016b28..5f18f0e 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -27,7 +27,7 @@ #include "delta-islands.h" #include "reachable.h" #include "oid-array.h" -#include "argv-array.h" +#include "strvec.h" #include "list.h" #include "packfile.h" #include "object-store.h" diff --git a/builtin/rebase.c b/builtin/rebase.c index 37ba76a..38145a6 100644 --- a/builtin/rebase.c +++ b/builtin/rebase.c @@ -8,7 +8,7 @@ #include "builtin.h" #include "run-command.h" #include "exec-cmd.h" -#include "argv-array.h" +#include "strvec.h" #include "dir.h" #include "packfile.h" #include "refs.h" diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c index d43663b..1285631 100644 --- a/builtin/receive-pack.c +++ b/builtin/receive-pack.c @@ -15,7 +15,7 @@ #include "string-list.h" #include "oid-array.h" #include "connected.h" -#include "argv-array.h" +#include "strvec.h" #include "version.h" #include "tag.h" #include "gpg-interface.h" diff --git a/builtin/remote.c b/builtin/remote.c index e837799..a9f35ba 100644 --- a/builtin/remote.c +++ b/builtin/remote.c @@ -10,7 +10,7 @@ #include "refs.h" #include "refspec.h" #include "object-store.h" -#include "argv-array.h" +#include "strvec.h" #include "commit-reach.h" static const char * const builtin_remote_usage[] = { diff --git a/builtin/repack.c b/builtin/repack.c index df28773..8bccb38 100644 --- a/builtin/repack.c +++ b/builtin/repack.c @@ -7,7 +7,7 @@ #include "sigchain.h" #include "strbuf.h" #include "string-list.h" -#include "argv-array.h" +#include "strvec.h" #include "midx.h" #include "packfile.h" #include "prune-packed.h" diff --git a/builtin/show-branch.c b/builtin/show-branch.c index 7e52ee9..f0a7053 100644 --- a/builtin/show-branch.c +++ b/builtin/show-branch.c @@ -4,7 +4,7 @@ #include "refs.h" #include "builtin.h" #include "color.h" -#include "argv-array.h" +#include "strvec.h" #include "parse-options.h" #include "dir.h" #include "commit-slab.h" diff --git a/builtin/stash.c b/builtin/stash.c index 0c52a3b..1acf216 100644 --- a/builtin/stash.c +++ b/builtin/stash.c @@ -7,7 +7,7 @@ #include "cache-tree.h" #include "unpack-trees.h" #include "merge-recursive.h" -#include "argv-array.h" +#include "strvec.h" #include "run-command.h" #include "dir.h" #include "rerere.h" diff --git a/builtin/update-ref.c b/builtin/update-ref.c index b74dd9a6..8a2df44 100644 --- a/builtin/update-ref.c +++ b/builtin/update-ref.c @@ -4,7 +4,7 @@ #include "builtin.h" #include "parse-options.h" #include "quote.h" -#include "argv-array.h" +#include "strvec.h" static const char * const git_update_ref_usage[] = { N_("git update-ref [] -d []"), diff --git a/builtin/upload-archive.c b/builtin/upload-archive.c index 0188797..7fc8e0e 100644 --- a/builtin/upload-archive.c +++ b/builtin/upload-archive.c @@ -7,7 +7,7 @@ #include "pkt-line.h" #include "sideband.h" #include "run-command.h" -#include "argv-array.h" +#include "strvec.h" static const char upload_archive_usage[] = "git upload-archive "; diff --git a/builtin/worktree.c b/builtin/worktree.c index f0cbdef..3594509 100644 --- a/builtin/worktree.c +++ b/builtin/worktree.c @@ -4,7 +4,7 @@ #include "builtin.h" #include "dir.h" #include "parse-options.h" -#include "argv-array.h" +#include "strvec.h" #include "branch.h" #include "refs.h" #include "run-command.h" diff --git a/bundle.c b/bundle.c index 2a0d744..d46a387 100644 --- a/bundle.c +++ b/bundle.c @@ -10,7 +10,7 @@ #include "list-objects.h" #include "run-command.h" #include "refs.h" -#include "argv-array.h" +#include "strvec.h" static const char bundle_signature[] = "# v2 git bundle\n"; diff --git a/bundle.h b/bundle.h index 2dc9442..2cf1270 100644 --- a/bundle.h +++ b/bundle.h @@ -1,7 +1,7 @@ #ifndef BUNDLE_H #define BUNDLE_H -#include "argv-array.h" +#include "strvec.h" #include "cache.h" struct ref_list { diff --git a/diff.c b/diff.c index d24aaa3..ee00815 100644 --- a/diff.c +++ b/diff.c @@ -20,7 +20,7 @@ #include "hashmap.h" #include "ll-merge.h" #include "string-list.h" -#include "argv-array.h" +#include "strvec.h" #include "graph.h" #include "packfile.h" #include "parse-options.h" diff --git a/environment.c b/environment.c index aaca0e9..75fe5f4 100644 --- a/environment.c +++ b/environment.c @@ -14,7 +14,7 @@ #include "refs.h" #include "fmt-merge-msg.h" #include "commit.h" -#include "argv-array.h" +#include "strvec.h" #include "object-store.h" #include "chdir-notify.h" #include "shallow.h" diff --git a/exec-cmd.c b/exec-cmd.c index 7deeab3..bb24c2f 100644 --- a/exec-cmd.c +++ b/exec-cmd.c @@ -1,7 +1,7 @@ #include "cache.h" #include "exec-cmd.h" #include "quote.h" -#include "argv-array.h" +#include "strvec.h" #if defined(RUNTIME_PREFIX) diff --git a/graph.c b/graph.c index 4cd9915..96af8f6 100644 --- a/graph.c +++ b/graph.c @@ -4,7 +4,7 @@ #include "color.h" #include "graph.h" #include "revision.h" -#include "argv-array.h" +#include "strvec.h" /* Internal API */ diff --git a/http-backend.c b/http-backend.c index ec3144b..6a42bad 100644 --- a/http-backend.c +++ b/http-backend.c @@ -9,7 +9,7 @@ #include "run-command.h" #include "string-list.h" #include "url.h" -#include "argv-array.h" +#include "strvec.h" #include "packfile.h" #include "object-store.h" #include "protocol.h" diff --git a/http-push.c b/http-push.c index 1ff1883..3a47921 100644 --- a/http-push.c +++ b/http-push.c @@ -11,7 +11,7 @@ #include "remote.h" #include "list-objects.h" #include "sigchain.h" -#include "argv-array.h" +#include "strvec.h" #include "packfile.h" #include "object-store.h" #include "commit-reach.h" diff --git a/line-log.c b/line-log.c index c536928..05d077b 100644 --- a/line-log.c +++ b/line-log.c @@ -14,7 +14,7 @@ #include "graph.h" #include "userdiff.h" #include "line-log.h" -#include "argv-array.h" +#include "strvec.h" #include "bloom.h" static void range_set_grow(struct range_set *rs, size_t extra) diff --git a/list-objects-filter-options.c b/list-objects-filter-options.c index 3553ad7..3667766 100644 --- a/list-objects-filter-options.c +++ b/list-objects-filter-options.c @@ -2,7 +2,7 @@ #include "commit.h" #include "config.h" #include "revision.h" -#include "argv-array.h" +#include "strvec.h" #include "list-objects.h" #include "list-objects-filter.h" #include "list-objects-filter-options.h" diff --git a/ls-refs.c b/ls-refs.c index 50d8686..98fb190 100644 --- a/ls-refs.c +++ b/ls-refs.c @@ -2,7 +2,7 @@ #include "repository.h" #include "refs.h" #include "remote.h" -#include "argv-array.h" +#include "strvec.h" #include "ls-refs.h" #include "pkt-line.h" #include "config.h" diff --git a/parse-options-cb.c b/parse-options-cb.c index 86cd393..7cba964 100644 --- a/parse-options-cb.c +++ b/parse-options-cb.c @@ -4,7 +4,7 @@ #include "commit.h" #include "color.h" #include "string-list.h" -#include "argv-array.h" +#include "strvec.h" #include "oid-array.h" /*----- some often used options -----*/ diff --git a/pathspec.c b/pathspec.c index 8243e06..57c9b58 100644 --- a/pathspec.c +++ b/pathspec.c @@ -3,7 +3,7 @@ #include "dir.h" #include "pathspec.h" #include "attr.h" -#include "argv-array.h" +#include "strvec.h" #include "quote.h" /* diff --git a/quote.c b/quote.c index bcc0dbc..dac8b4e 100644 --- a/quote.c +++ b/quote.c @@ -1,6 +1,6 @@ #include "cache.h" #include "quote.h" -#include "argv-array.h" +#include "strvec.h" int quote_path_fully = 1; diff --git a/range-diff.c b/range-diff.c index 40af086..b4d1d56 100644 --- a/range-diff.c +++ b/range-diff.c @@ -2,7 +2,7 @@ #include "range-diff.h" #include "string-list.h" #include "run-command.h" -#include "argv-array.h" +#include "strvec.h" #include "hashmap.h" #include "xdiff-interface.h" #include "linear-assignment.h" diff --git a/range-diff.h b/range-diff.h index e11976d..916f18b 100644 --- a/range-diff.h +++ b/range-diff.h @@ -2,7 +2,7 @@ #define RANGE_DIFF_H #include "diff.h" -#include "argv-array.h" +#include "strvec.h" #define RANGE_DIFF_CREATION_FACTOR_DEFAULT 60 diff --git a/ref-filter.c b/ref-filter.c index 8447cb0..81c4399 100644 --- a/ref-filter.c +++ b/ref-filter.c @@ -22,7 +22,7 @@ #include "commit-reach.h" #include "worktree.h" #include "hashmap.h" -#include "argv-array.h" +#include "strvec.h" static struct ref_msg { const char *gone; diff --git a/refs.c b/refs.c index 639cba9..0067926 100644 --- a/refs.c +++ b/refs.c @@ -15,7 +15,7 @@ #include "tag.h" #include "submodule.h" #include "worktree.h" -#include "argv-array.h" +#include "strvec.h" #include "repository.h" #include "sigchain.h" diff --git a/refspec.c b/refspec.c index 9a9bf21..f9fb67d 100644 --- a/refspec.c +++ b/refspec.c @@ -1,5 +1,5 @@ #include "cache.h" -#include "argv-array.h" +#include "strvec.h" #include "refs.h" #include "refspec.h" diff --git a/remote-curl.c b/remote-curl.c index 5cbc6e5..05fb794 100644 --- a/remote-curl.c +++ b/remote-curl.c @@ -10,7 +10,7 @@ #include "pkt-line.h" #include "string-list.h" #include "sideband.h" -#include "argv-array.h" +#include "strvec.h" #include "credential.h" #include "oid-array.h" #include "send-pack.h" diff --git a/remote-testsvn.c b/remote-testsvn.c index cde39b9..809b290 100644 --- a/remote-testsvn.c +++ b/remote-testsvn.c @@ -8,7 +8,7 @@ #include "run-command.h" #include "vcs-svn/svndump.h" #include "notes.h" -#include "argv-array.h" +#include "strvec.h" static const char *url; static int dump_from_file; diff --git a/remote.c b/remote.c index bc46413..ba1a386 100644 --- a/remote.c +++ b/remote.c @@ -11,7 +11,7 @@ #include "tag.h" #include "string-list.h" #include "mergesort.h" -#include "argv-array.h" +#include "strvec.h" #include "commit-reach.h" #include "advice.h" diff --git a/revision.c b/revision.c index 6aa7f4f..07e16ed 100644 --- a/revision.c +++ b/revision.c @@ -23,7 +23,7 @@ #include "bisect.h" #include "packfile.h" #include "worktree.h" -#include "argv-array.h" +#include "strvec.h" #include "commit-reach.h" #include "commit-graph.h" #include "prio-queue.h" diff --git a/run-command.c b/run-command.c index a735e38..8f57661 100644 --- a/run-command.c +++ b/run-command.c @@ -2,7 +2,7 @@ #include "run-command.h" #include "exec-cmd.h" #include "sigchain.h" -#include "argv-array.h" +#include "strvec.h" #include "thread-utils.h" #include "strbuf.h" #include "string-list.h" diff --git a/run-command.h b/run-command.h index ef3071a..f5e05d3 100644 --- a/run-command.h +++ b/run-command.h @@ -3,7 +3,7 @@ #include "thread-utils.h" -#include "argv-array.h" +#include "strvec.h" /** * The run-command API offers a versatile tool to run sub-processes with diff --git a/sequencer.c b/sequencer.c index fd7701c..9e7f868 100644 --- a/sequencer.c +++ b/sequencer.c @@ -16,7 +16,7 @@ #include "rerere.h" #include "merge-recursive.h" #include "refs.h" -#include "argv-array.h" +#include "strvec.h" #include "quote.h" #include "trailer.h" #include "log-tree.h" diff --git a/serve.c b/serve.c index fbd2fcd..8d9a345 100644 --- a/serve.c +++ b/serve.c @@ -3,7 +3,7 @@ #include "config.h" #include "pkt-line.h" #include "version.h" -#include "argv-array.h" +#include "strvec.h" #include "ls-refs.h" #include "serve.h" #include "upload-pack.h" diff --git a/strvec.c b/strvec.c new file mode 100644 index 0000000..9e76ab9 --- /dev/null +++ b/strvec.c @@ -0,0 +1,109 @@ +#include "cache.h" +#include "strvec.h" +#include "strbuf.h" + +const char *empty_strvec[] = { NULL }; + +void strvec_init(struct strvec *array) +{ + array->argv = empty_strvec; + array->argc = 0; + array->alloc = 0; +} + +static void strvec_push_nodup(struct strvec *array, const char *value) +{ + if (array->argv == empty_strvec) + array->argv = NULL; + + ALLOC_GROW(array->argv, array->argc + 2, array->alloc); + array->argv[array->argc++] = value; + array->argv[array->argc] = NULL; +} + +const char *strvec_push(struct strvec *array, const char *value) +{ + strvec_push_nodup(array, xstrdup(value)); + return array->argv[array->argc - 1]; +} + +const char *strvec_pushf(struct strvec *array, const char *fmt, ...) +{ + va_list ap; + struct strbuf v = STRBUF_INIT; + + va_start(ap, fmt); + strbuf_vaddf(&v, fmt, ap); + va_end(ap); + + strvec_push_nodup(array, strbuf_detach(&v, NULL)); + return array->argv[array->argc - 1]; +} + +void strvec_pushl(struct strvec *array, ...) +{ + va_list ap; + const char *arg; + + va_start(ap, array); + while ((arg = va_arg(ap, const char *))) + strvec_push(array, arg); + va_end(ap); +} + +void strvec_pushv(struct strvec *array, const char **argv) +{ + for (; *argv; argv++) + strvec_push(array, *argv); +} + +void strvec_pop(struct strvec *array) +{ + if (!array->argc) + return; + free((char *)array->argv[array->argc - 1]); + array->argv[array->argc - 1] = NULL; + array->argc--; +} + +void strvec_split(struct strvec *array, const char *to_split) +{ + while (isspace(*to_split)) + to_split++; + for (;;) { + const char *p = to_split; + + if (!*p) + break; + + while (*p && !isspace(*p)) + p++; + strvec_push_nodup(array, xstrndup(to_split, p - to_split)); + + while (isspace(*p)) + p++; + to_split = p; + } +} + +void strvec_clear(struct strvec *array) +{ + if (array->argv != empty_strvec) { + int i; + for (i = 0; i < array->argc; i++) + free((char *)array->argv[i]); + free(array->argv); + } + strvec_init(array); +} + +const char **strvec_detach(struct strvec *array) +{ + if (array->argv == empty_strvec) + return xcalloc(1, sizeof(const char *)); + else { + const char **ret = array->argv; + strvec_init(array); + return ret; + } +} diff --git a/strvec.h b/strvec.h new file mode 100644 index 0000000..4be39c8 --- /dev/null +++ b/strvec.h @@ -0,0 +1,102 @@ +#ifndef STRVEC_H +#define STRVEC_H + +/** + * 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(). + * + * The string-list API (documented in string-list.h) 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 `strvec` manages its own memory. Any strings pushed into the + * array are duplicated, and all memory is freed by strvec_clear(). + */ + +extern const char *empty_strvec[]; + +/** + * A single array. This should be initialized by assignment from + * `STRVEC_INIT`, or by calling `strvec_init`. The `argv` + * member contains the actual array; the `argc` member contains the + * number of elements in the array, not including the terminating + * NULL. + */ +struct strvec { + const char **argv; + size_t argc; + size_t alloc; +}; + +#define STRVEC_INIT { empty_strvec, 0, 0 } + +/** + * Initialize an array. This is no different than assigning from + * `STRVEC_INIT`. + */ +void strvec_init(struct strvec *); + +/* Push a copy of a string onto the end of the array. */ +const char *strvec_push(struct strvec *, const char *); + +/** + * Format a string and push it onto the end of the array. This is a + * convenience wrapper combining `strbuf_addf` and `strvec_push`. + */ +__attribute__((format (printf,2,3))) +const char *strvec_pushf(struct strvec *, const char *fmt, ...); + +/** + * Push a list of strings onto the end of the array. The arguments + * should be a list of `const char *` strings, terminated by a NULL + * argument. + */ +LAST_ARG_MUST_BE_NULL +void strvec_pushl(struct strvec *, ...); + +/* Push a null-terminated array of strings onto the end of the array. */ +void strvec_pushv(struct strvec *, const char **); + +/** + * Remove the final element from the array. If there are no + * elements in the array, do nothing. + */ +void strvec_pop(struct strvec *); + +/* Splits by whitespace; does not handle quoted arguments! */ +void strvec_split(struct strvec *, const char *); + +/** + * Free all memory associated with the array and return it to the + * initial, empty state. + */ +void strvec_clear(struct strvec *); + +/** + * Disconnect the `argv` member from the `strvec` struct and + * return it. The caller is responsible for freeing the memory used + * by the array, and by the strings it references. After detaching, + * the `strvec` is in a reinitialized state and can be pushed + * into again. + */ +const char **strvec_detach(struct strvec *); + +/* compatibility for historic argv_array interface */ +#define argv_array strvec +#define ARGV_ARRAY_INIT STRVEC_INIT +#define argv_array_init strvec_init +#define argv_array_push strvec_push +#define argv_array_pushf strvec_pushf +#define argv_array_pushl strvec_pushl +#define argv_array_pushv strvec_pushv +#define argv_array_pop strvec_pop +#define argv_array_split strvec_split +#define argv_array_clear strvec_clear +#define argv_array_detach strvec_detach + +#endif /* STRVEC_H */ diff --git a/submodule.c b/submodule.c index e2ef569..874db5c 100644 --- a/submodule.c +++ b/submodule.c @@ -13,7 +13,7 @@ #include "refs.h" #include "string-list.h" #include "oid-array.h" -#include "argv-array.h" +#include "strvec.h" #include "blob.h" #include "thread-utils.h" #include "quote.h" diff --git a/t/helper/test-run-command.c b/t/helper/test-run-command.c index 1646aa2..8d3f6d5 100644 --- a/t/helper/test-run-command.c +++ b/t/helper/test-run-command.c @@ -12,7 +12,7 @@ #include "git-compat-util.h" #include "cache.h" #include "run-command.h" -#include "argv-array.h" +#include "strvec.h" #include "strbuf.h" #include "parse-options.h" #include "string-list.h" diff --git a/t/helper/test-trace2.c b/t/helper/test-trace2.c index 197819c..823f33c 100644 --- a/t/helper/test-trace2.c +++ b/t/helper/test-trace2.c @@ -1,6 +1,6 @@ #include "test-tool.h" #include "cache.h" -#include "argv-array.h" +#include "strvec.h" #include "run-command.h" #include "exec-cmd.h" #include "config.h" diff --git a/tmp-objdir.c b/tmp-objdir.c index 91c0056..06924a7 100644 --- a/tmp-objdir.c +++ b/tmp-objdir.c @@ -4,7 +4,7 @@ #include "sigchain.h" #include "string-list.h" #include "strbuf.h" -#include "argv-array.h" +#include "strvec.h" #include "quote.h" #include "object-store.h" diff --git a/transport-helper.c b/transport-helper.c index c6b753b..441763f 100644 --- a/transport-helper.c +++ b/transport-helper.c @@ -9,7 +9,7 @@ #include "string-list.h" #include "thread-utils.h" #include "sigchain.h" -#include "argv-array.h" +#include "strvec.h" #include "refs.h" #include "refspec.h" #include "transport-internal.h" diff --git a/unpack-trees.c b/unpack-trees.c index 4be5fc3..65c3395 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -1,5 +1,5 @@ #include "cache.h" -#include "argv-array.h" +#include "strvec.h" #include "repository.h" #include "config.h" #include "dir.h" diff --git a/unpack-trees.h b/unpack-trees.h index 9c2f082..f8a904a 100644 --- a/unpack-trees.h +++ b/unpack-trees.h @@ -2,7 +2,7 @@ #define UNPACK_TREES_H #include "cache.h" -#include "argv-array.h" +#include "strvec.h" #include "string-list.h" #include "tree-walk.h" diff --git a/upload-pack.c b/upload-pack.c index 951a2b2..b435dae 100644 --- a/upload-pack.c +++ b/upload-pack.c @@ -18,7 +18,7 @@ #include "sigchain.h" #include "version.h" #include "string-list.h" -#include "argv-array.h" +#include "strvec.h" #include "prio-queue.h" #include "protocol.h" #include "quote.h" diff --git a/wt-status.c b/wt-status.c index c560cbe..9817161 100644 --- a/wt-status.c +++ b/wt-status.c @@ -8,7 +8,7 @@ #include "diffcore.h" #include "quote.h" #include "run-command.h" -#include "argv-array.h" +#include "strvec.h" #include "remote.h" #include "refs.h" #include "submodule.h" -- cgit v0.10.2-6-g49f6