summaryrefslogtreecommitdiff
path: root/range-diff.c
diff options
context:
space:
mode:
authorThomas Gummerer <t.gummerer@gmail.com>2019-07-11 16:08:46 (GMT)
committerJunio C Hamano <gitster@pobox.com>2019-07-11 21:29:27 (GMT)
commit44b67cb62b339fdc6239ef6b72b8c75b559a574a (patch)
treee0b945eeb5283761968d5a3e15efcd0c6a43ebe8 /range-diff.c
parent1ca69225981a915b0041f74047fe554b1580da5b (diff)
downloadgit-44b67cb62b339fdc6239ef6b72b8c75b559a574a.zip
git-44b67cb62b339fdc6239ef6b72b8c75b559a574a.tar.gz
git-44b67cb62b339fdc6239ef6b72b8c75b559a574a.tar.bz2
range-diff: split lines manually
Currently range-diff uses the 'strbuf_getline()' function for doing its line by line processing. In a future patch we want to do parts of that parsing using the 'parse_git_diff_header()' function. That function does its own line by line reading of the input, and doesn't use strbufs. This doesn't match with how we do the line-by-line processing in range-diff currently. Switch range-diff to do our own line by line parsing, so we can re-use the 'parse_git_diff_header()' function later. Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'range-diff.c')
-rw-r--r--range-diff.c68
1 files changed, 42 insertions, 26 deletions
diff --git a/range-diff.c b/range-diff.c
index 9242b89..784fac3 100644
--- a/range-diff.c
+++ b/range-diff.c
@@ -24,6 +24,17 @@ struct patch_util {
struct object_id oid;
};
+static size_t find_end_of_line(char *buffer, unsigned long size)
+{
+ char *eol = memchr(buffer, '\n', size);
+
+ if (!eol)
+ return size;
+
+ *eol = '\0';
+ return eol + 1 - buffer;
+}
+
/*
* Reads the patches into a string list, with the `util` field being populated
* as struct object_id (will need to be free()d).
@@ -31,10 +42,12 @@ struct patch_util {
static int read_patches(const char *range, struct string_list *list)
{
struct child_process cp = CHILD_PROCESS_INIT;
- FILE *in;
- struct strbuf buf = STRBUF_INIT, line = STRBUF_INIT;
+ struct strbuf buf = STRBUF_INIT, contents = STRBUF_INIT;
struct patch_util *util = NULL;
int in_header = 1;
+ char *line;
+ int offset, len;
+ size_t size;
argv_array_pushl(&cp.args, "log", "--no-color", "-p", "--no-merges",
"--reverse", "--date-order", "--decorate=no",
@@ -54,17 +67,20 @@ static int read_patches(const char *range, struct string_list *list)
if (start_command(&cp))
return error_errno(_("could not start `log`"));
- in = fdopen(cp.out, "r");
- if (!in) {
+ if (strbuf_read(&contents, cp.out, 0) < 0) {
error_errno(_("could not read `log` output"));
finish_command(&cp);
return -1;
}
- while (strbuf_getline(&line, in) != EOF) {
+ line = contents.buf;
+ size = contents.len;
+ for (offset = 0; size > 0; offset += len, size -= len, line += len) {
const char *p;
- if (skip_prefix(line.buf, "commit ", &p)) {
+ len = find_end_of_line(line, size);
+ line[len - 1] = '\0';
+ if (skip_prefix(line, "commit ", &p)) {
if (util) {
string_list_append(list, buf.buf)->util = util;
strbuf_reset(&buf);
@@ -75,8 +91,7 @@ static int read_patches(const char *range, struct string_list *list)
free(util);
string_list_clear(list, 1);
strbuf_release(&buf);
- strbuf_release(&line);
- fclose(in);
+ strbuf_release(&contents);
finish_command(&cp);
return -1;
}
@@ -85,26 +100,28 @@ static int read_patches(const char *range, struct string_list *list)
continue;
}
- if (starts_with(line.buf, "diff --git")) {
+ if (starts_with(line, "diff --git")) {
in_header = 0;
strbuf_addch(&buf, '\n');
if (!util->diff_offset)
util->diff_offset = buf.len;
strbuf_addch(&buf, ' ');
- strbuf_addbuf(&buf, &line);
+ strbuf_addstr(&buf, line);
} else if (in_header) {
- if (starts_with(line.buf, "Author: ")) {
- strbuf_addbuf(&buf, &line);
+ if (starts_with(line, "Author: ")) {
+ strbuf_addstr(&buf, line);
strbuf_addstr(&buf, "\n\n");
- } else if (starts_with(line.buf, " ")) {
- strbuf_rtrim(&line);
- strbuf_addbuf(&buf, &line);
+ } else if (starts_with(line, " ")) {
+ p = line + len - 2;
+ while (isspace(*p) && p >= line)
+ p--;
+ strbuf_add(&buf, line, p - line + 1);
strbuf_addch(&buf, '\n');
}
continue;
- } else if (starts_with(line.buf, "@@ "))
+ } else if (starts_with(line, "@@ "))
strbuf_addstr(&buf, "@@");
- else if (!line.buf[0] || starts_with(line.buf, "index "))
+ else if (!line[0] || starts_with(line, "index "))
/*
* A completely blank (not ' \n', which is context)
* line is not valid in a diff. We skip it
@@ -117,25 +134,24 @@ static int read_patches(const char *range, struct string_list *list)
* we are not interested.
*/
continue;
- else if (line.buf[0] == '>') {
+ else if (line[0] == '>') {
strbuf_addch(&buf, '+');
- strbuf_add(&buf, line.buf + 1, line.len - 1);
- } else if (line.buf[0] == '<') {
+ strbuf_addstr(&buf, line + 1);
+ } else if (line[0] == '<') {
strbuf_addch(&buf, '-');
- strbuf_add(&buf, line.buf + 1, line.len - 1);
- } else if (line.buf[0] == '#') {
+ strbuf_addstr(&buf, line + 1);
+ } else if (line[0] == '#') {
strbuf_addch(&buf, ' ');
- strbuf_add(&buf, line.buf + 1, line.len - 1);
+ strbuf_addstr(&buf, line + 1);
} else {
strbuf_addch(&buf, ' ');
- strbuf_addbuf(&buf, &line);
+ strbuf_addstr(&buf, line);
}
strbuf_addch(&buf, '\n');
util->diffsize++;
}
- fclose(in);
- strbuf_release(&line);
+ strbuf_release(&contents);
if (util)
string_list_append(list, buf.buf)->util = util;