Skip to content

Commit 44b67cb

Browse files
tgummerergitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 1ca6922 commit 44b67cb

File tree

1 file changed

+42
-26
lines changed

1 file changed

+42
-26
lines changed

range-diff.c

Lines changed: 42 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,30 @@ struct patch_util {
2424
struct object_id oid;
2525
};
2626

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+
2738
/*
2839
* Reads the patches into a string list, with the `util` field being populated
2940
* as struct object_id (will need to be free()d).
3041
*/
3142
static int read_patches(const char *range, struct string_list *list)
3243
{
3344
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;
3646
struct patch_util *util = NULL;
3747
int in_header = 1;
48+
char *line;
49+
int offset, len;
50+
size_t size;
3851

3952
argv_array_pushl(&cp.args, "log", "--no-color", "-p", "--no-merges",
4053
"--reverse", "--date-order", "--decorate=no",
@@ -54,17 +67,20 @@ static int read_patches(const char *range, struct string_list *list)
5467

5568
if (start_command(&cp))
5669
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) {
5971
error_errno(_("could not read `log` output"));
6072
finish_command(&cp);
6173
return -1;
6274
}
6375

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) {
6579
const char *p;
6680

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)) {
6884
if (util) {
6985
string_list_append(list, buf.buf)->util = util;
7086
strbuf_reset(&buf);
@@ -75,8 +91,7 @@ static int read_patches(const char *range, struct string_list *list)
7591
free(util);
7692
string_list_clear(list, 1);
7793
strbuf_release(&buf);
78-
strbuf_release(&line);
79-
fclose(in);
94+
strbuf_release(&contents);
8095
finish_command(&cp);
8196
return -1;
8297
}
@@ -85,26 +100,28 @@ static int read_patches(const char *range, struct string_list *list)
85100
continue;
86101
}
87102

88-
if (starts_with(line.buf, "diff --git")) {
103+
if (starts_with(line, "diff --git")) {
89104
in_header = 0;
90105
strbuf_addch(&buf, '\n');
91106
if (!util->diff_offset)
92107
util->diff_offset = buf.len;
93108
strbuf_addch(&buf, ' ');
94-
strbuf_addbuf(&buf, &line);
109+
strbuf_addstr(&buf, line);
95110
} 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);
98113
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);
102119
strbuf_addch(&buf, '\n');
103120
}
104121
continue;
105-
} else if (starts_with(line.buf, "@@ "))
122+
} else if (starts_with(line, "@@ "))
106123
strbuf_addstr(&buf, "@@");
107-
else if (!line.buf[0] || starts_with(line.buf, "index "))
124+
else if (!line[0] || starts_with(line, "index "))
108125
/*
109126
* A completely blank (not ' \n', which is context)
110127
* 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)
117134
* we are not interested.
118135
*/
119136
continue;
120-
else if (line.buf[0] == '>') {
137+
else if (line[0] == '>') {
121138
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] == '<') {
124141
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] == '#') {
127144
strbuf_addch(&buf, ' ');
128-
strbuf_add(&buf, line.buf + 1, line.len - 1);
145+
strbuf_addstr(&buf, line + 1);
129146
} else {
130147
strbuf_addch(&buf, ' ');
131-
strbuf_addbuf(&buf, &line);
148+
strbuf_addstr(&buf, line);
132149
}
133150

134151
strbuf_addch(&buf, '\n');
135152
util->diffsize++;
136153
}
137-
fclose(in);
138-
strbuf_release(&line);
154+
strbuf_release(&contents);
139155

140156
if (util)
141157
string_list_append(list, buf.buf)->util = util;

0 commit comments

Comments
 (0)