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;