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>
Thomas Gummerer committed
Jul 11, 2019 at 17:08 UTC
44b67cb62b339fdc6239ef6b72b8c75b559a574a
1 file changed
+42
-26
range-diff.c
+42
-26
@@ -24,6 +24,17 @@ struct patch_util {
24
struct object_id oid;
25
};
26
27
+static size_t find_end_of_line(char *buffer, unsigned long size)
28
+{
29
+ char *eol = memchr(buffer, '\n', size);
30
+
31
+ if (!eol)
32
+ return size;
33
+
34
+ *eol = '\0';
35
+ return eol + 1 - buffer;
36
+}
37
+
38
/*
39
* Reads the patches into a string list, with the `util` field being populated
40
* as struct object_id (will need to be free()d).
@@ -31,10 +42,12 @@ struct patch_util {
42
static int read_patches(const char *range, struct string_list *list)
43
{
44
struct child_process cp = CHILD_PROCESS_INIT;
34
- FILE *in;
35
- struct strbuf buf = STRBUF_INIT, line = STRBUF_INIT;
45
+ struct strbuf buf = STRBUF_INIT, contents = STRBUF_INIT;
46
struct patch_util *util = NULL;
47
int in_header = 1;
48
+ char *line;
49
+ int offset, len;
50
+ size_t size;
51
52
argv_array_pushl(&cp.args, "log", "--no-color", "-p", "--no-merges",
53
"--reverse", "--date-order", "--decorate=no",
@@ -54,17 +67,20 @@ static int read_patches(const char *range, struct string_list *list)
67
68
if (start_command(&cp))
69
return error_errno(_("could not start `log`"));
57
- in = fdopen(cp.out, "r");
58
- if (!in) {
70
+ if (strbuf_read(&contents, cp.out, 0) < 0) {
71
error_errno(_("could not read `log` output"));
72
finish_command(&cp);
73
return -1;
74
}
75
64
- while (strbuf_getline(&line, in) != EOF) {
76
+ line = contents.buf;
77
+ size = contents.len;
78
+ for (offset = 0; size > 0; offset += len, size -= len, line += len) {
79
const char *p;
80
67
- if (skip_prefix(line.buf, "commit ", &p)) {
81
+ len = find_end_of_line(line, size);
82
+ line[len - 1] = '\0';
83
+ if (skip_prefix(line, "commit ", &p)) {
84
if (util) {
85
string_list_append(list, buf.buf)->util = util;
86
strbuf_reset(&buf);
@@ -75,8 +91,7 @@ static int read_patches(const char *range, struct string_list *list)
91
free(util);
92
string_list_clear(list, 1);
93
strbuf_release(&buf);
78
- strbuf_release(&line);
79
- fclose(in);
94
+ strbuf_release(&contents);
95
finish_command(&cp);
96
return -1;
97
}
@@ -85,26 +100,28 @@ static int read_patches(const char *range, struct string_list *list)
100
continue;
101
}
102
88
- if (starts_with(line.buf, "diff --git")) {
103
+ if (starts_with(line, "diff --git")) {
104
in_header = 0;
105
strbuf_addch(&buf, '\n');
106
if (!util->diff_offset)
107
util->diff_offset = buf.len;
108
strbuf_addch(&buf, ' ');
94
- strbuf_addbuf(&buf, &line);
109
+ strbuf_addstr(&buf, line);
110
} else if (in_header) {
96
- if (starts_with(line.buf, "Author: ")) {
97
- strbuf_addbuf(&buf, &line);
111
+ if (starts_with(line, "Author: ")) {
112
+ strbuf_addstr(&buf, line);
113
strbuf_addstr(&buf, "\n\n");
99
- } else if (starts_with(line.buf, " ")) {
100
- strbuf_rtrim(&line);
101
- strbuf_addbuf(&buf, &line);
114
+ } else if (starts_with(line, " ")) {
115
+ p = line + len - 2;
116
+ while (isspace(*p) && p >= line)
117
+ p--;
118
+ strbuf_add(&buf, line, p - line + 1);
119
strbuf_addch(&buf, '\n');
120
}
121
continue;
105
- } else if (starts_with(line.buf, "@@ "))
122
+ } else if (starts_with(line, "@@ "))
123
strbuf_addstr(&buf, "@@");
107
- else if (!line.buf[0] || starts_with(line.buf, "index "))
124
+ else if (!line[0] || starts_with(line, "index "))
125
/*
126
* A completely blank (not ' \n', which is context)
127
* 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)
134
* we are not interested.
135
*/
136
continue;
120
- else if (line.buf[0] == '>') {
137
+ else if (line[0] == '>') {
138
strbuf_addch(&buf, '+');
122
- strbuf_add(&buf, line.buf + 1, line.len - 1);
123
- } else if (line.buf[0] == '<') {
139
+ strbuf_addstr(&buf, line + 1);
140
+ } else if (line[0] == '<') {
141
strbuf_addch(&buf, '-');
125
- strbuf_add(&buf, line.buf + 1, line.len - 1);
126
- } else if (line.buf[0] == '#') {
142
+ strbuf_addstr(&buf, line + 1);
143
+ } else if (line[0] == '#') {
144
strbuf_addch(&buf, ' ');
128
- strbuf_add(&buf, line.buf + 1, line.len - 1);
145
+ strbuf_addstr(&buf, line + 1);
146
} else {
147
strbuf_addch(&buf, ' ');
131
- strbuf_addbuf(&buf, &line);
148
+ strbuf_addstr(&buf, line);
149
}
150
151
strbuf_addch(&buf, '\n');
152
util->diffsize++;
153
}
137
- fclose(in);
138
- strbuf_release(&line);
154
+ strbuf_release(&contents);
155
156
if (util)
157
string_list_append(list, buf.buf)->util = util;