@@ -24,17 +24,30 @@ struct patch_util {
24
24
struct object_id oid ;
25
25
};
26
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
+
27
38
/*
28
39
* Reads the patches into a string list, with the `util` field being populated
29
40
* as struct object_id (will need to be free()d).
30
41
*/
31
42
static int read_patches (const char * range , struct string_list * list )
32
43
{
33
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 ;
36
46
struct patch_util * util = NULL ;
37
47
int in_header = 1 ;
48
+ char * line ;
49
+ int offset , len ;
50
+ size_t size ;
38
51
39
52
argv_array_pushl (& cp .args , "log" , "--no-color" , "-p" , "--no-merges" ,
40
53
"--reverse" , "--date-order" , "--decorate=no" ,
@@ -54,17 +67,20 @@ static int read_patches(const char *range, struct string_list *list)
54
67
55
68
if (start_command (& cp ))
56
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 ) {
59
71
error_errno (_ ("could not read `log` output" ));
60
72
finish_command (& cp );
61
73
return -1 ;
62
74
}
63
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 ) {
65
79
const char * p ;
66
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 )) {
68
84
if (util ) {
69
85
string_list_append (list , buf .buf )-> util = util ;
70
86
strbuf_reset (& buf );
@@ -75,8 +91,7 @@ static int read_patches(const char *range, struct string_list *list)
75
91
free (util );
76
92
string_list_clear (list , 1 );
77
93
strbuf_release (& buf );
78
- strbuf_release (& line );
79
- fclose (in );
94
+ strbuf_release (& contents );
80
95
finish_command (& cp );
81
96
return -1 ;
82
97
}
@@ -85,26 +100,28 @@ static int read_patches(const char *range, struct string_list *list)
85
100
continue ;
86
101
}
87
102
88
- if (starts_with (line . buf , "diff --git" )) {
103
+ if (starts_with (line , "diff --git" )) {
89
104
in_header = 0 ;
90
105
strbuf_addch (& buf , '\n' );
91
106
if (!util -> diff_offset )
92
107
util -> diff_offset = buf .len ;
93
108
strbuf_addch (& buf , ' ' );
94
- strbuf_addbuf (& buf , & line );
109
+ strbuf_addstr (& buf , line );
95
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 );
98
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 );
102
119
strbuf_addch (& buf , '\n' );
103
120
}
104
121
continue ;
105
- } else if (starts_with (line . buf , "@@ " ))
122
+ } else if (starts_with (line , "@@ " ))
106
123
strbuf_addstr (& buf , "@@" );
107
- else if (!line . buf [0 ] || starts_with (line . buf , "index " ))
124
+ else if (!line [0 ] || starts_with (line , "index " ))
108
125
/*
109
126
* A completely blank (not ' \n', which is context)
110
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)
117
134
* we are not interested.
118
135
*/
119
136
continue ;
120
- else if (line . buf [0 ] == '>' ) {
137
+ else if (line [0 ] == '>' ) {
121
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 ] == '<' ) {
124
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 ] == '#' ) {
127
144
strbuf_addch (& buf , ' ' );
128
- strbuf_add (& buf , line . buf + 1 , line . len - 1 );
145
+ strbuf_addstr (& buf , line + 1 );
129
146
} else {
130
147
strbuf_addch (& buf , ' ' );
131
- strbuf_addbuf (& buf , & line );
148
+ strbuf_addstr (& buf , line );
132
149
}
133
150
134
151
strbuf_addch (& buf , '\n' );
135
152
util -> diffsize ++ ;
136
153
}
137
- fclose (in );
138
- strbuf_release (& line );
154
+ strbuf_release (& contents );
139
155
140
156
if (util )
141
157
string_list_append (list , buf .buf )-> util = util ;
0 commit comments