diff options
author | Alexandr Miloslavskiy <alexandr.miloslavskiy@syntevo.com> | 2019-11-19 19:48:51 +0300 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2019-11-20 07:01:53 +0300 |
commit | 24e4750c969b844536af1d286e7d977c74c078a2 (patch) | |
tree | 0b5be5c3f0873076b4035fb7d4ec67f37f53f160 | |
parent | add97702ed7cc3aa57b15c50b72606eb2f2f8cf5 (diff) |
pathspec: add new function to parse file
This will be used to support the new option '--pathspec-from-file' in
`git add`, `git-commit`, `git reset` etc.
Note also that we specifically handle CR/LF line endings to support
Windows better.
To simplify code, file is first parsed into `argv_array`. This allows
to avoid refactoring `parse_pathspec()`.
I considered adding `nul_term_line` to `flags` instead, but decided
that it doesn't fit there.
The new code is mostly taken from `cmd_update_index()` and
`split_mail_conv()`.
Co-authored-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Alexandr Miloslavskiy <alexandr.miloslavskiy@syntevo.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r-- | pathspec.c | 38 | ||||
-rw-r--r-- | pathspec.h | 10 |
2 files changed, 48 insertions, 0 deletions
diff --git a/pathspec.c b/pathspec.c index 12c2b322b3..128f27fcb7 100644 --- a/pathspec.c +++ b/pathspec.c @@ -3,6 +3,8 @@ #include "dir.h" #include "pathspec.h" #include "attr.h" +#include "argv-array.h" +#include "quote.h" /* * Finds which of the given pathspecs match items in the index. @@ -613,6 +615,42 @@ void parse_pathspec(struct pathspec *pathspec, } } +void parse_pathspec_file(struct pathspec *pathspec, unsigned magic_mask, + unsigned flags, const char *prefix, + const char *file, int nul_term_line) +{ + struct argv_array parsed_file = ARGV_ARRAY_INIT; + strbuf_getline_fn getline_fn = nul_term_line ? strbuf_getline_nul : + strbuf_getline; + struct strbuf buf = STRBUF_INIT; + struct strbuf unquoted = STRBUF_INIT; + FILE *in; + + if (!strcmp(file, "-")) + in = stdin; + else + in = xfopen(file, "r"); + + while (getline_fn(&buf, in) != EOF) { + if (!nul_term_line && buf.buf[0] == '"') { + strbuf_reset(&unquoted); + if (unquote_c_style(&unquoted, buf.buf, NULL)) + die(_("line is badly quoted: %s"), buf.buf); + strbuf_swap(&buf, &unquoted); + } + argv_array_push(&parsed_file, buf.buf); + strbuf_reset(&buf); + } + + strbuf_release(&unquoted); + strbuf_release(&buf); + if (in != stdin) + fclose(in); + + parse_pathspec(pathspec, magic_mask, flags, prefix, parsed_file.argv); + argv_array_clear(&parsed_file); +} + void copy_pathspec(struct pathspec *dst, const struct pathspec *src) { int i, j; diff --git a/pathspec.h b/pathspec.h index 1c18a2c90c..a27dc81ba2 100644 --- a/pathspec.h +++ b/pathspec.h @@ -85,6 +85,16 @@ void parse_pathspec(struct pathspec *pathspec, unsigned flags, const char *prefix, const char **args); +/* + * Same as parse_pathspec() but uses file as input. + * When 'file' is exactly "-" it uses 'stdin' instead. + */ +void parse_pathspec_file(struct pathspec *pathspec, + unsigned magic_mask, + unsigned flags, + const char *prefix, + const char *file, + int nul_term_line); void copy_pathspec(struct pathspec *dst, const struct pathspec *src); void clear_pathspec(struct pathspec *); |