@@ -83,8 +83,37 @@ static inline void ferr_puts(const char *s, FILE *fp, int *err)
83
83
ferr_write (s , strlen (s ), fp , err );
84
84
}
85
85
86
- static int handle_file (const char * path ,
87
- unsigned char * sha1 , const char * output )
86
+ struct rerere_io {
87
+ int (* getline )(struct strbuf * , struct rerere_io * );
88
+ FILE * output ;
89
+ int wrerror ;
90
+ /* some more stuff */
91
+ };
92
+
93
+ static void rerere_io_putstr (const char * str , struct rerere_io * io )
94
+ {
95
+ if (io -> output )
96
+ ferr_puts (str , io -> output , & io -> wrerror );
97
+ }
98
+
99
+ static void rerere_io_putmem (const char * mem , size_t sz , struct rerere_io * io )
100
+ {
101
+ if (io -> output )
102
+ ferr_write (mem , sz , io -> output , & io -> wrerror );
103
+ }
104
+
105
+ struct rerere_io_file {
106
+ struct rerere_io io ;
107
+ FILE * input ;
108
+ };
109
+
110
+ static int rerere_file_getline (struct strbuf * sb , struct rerere_io * io_ )
111
+ {
112
+ struct rerere_io_file * io = (struct rerere_io_file * )io_ ;
113
+ return strbuf_getwholeline (sb , io -> input , '\n' );
114
+ }
115
+
116
+ static int handle_path (unsigned char * sha1 , struct rerere_io * io )
88
117
{
89
118
git_SHA_CTX ctx ;
90
119
int hunk_no = 0 ;
@@ -93,25 +122,11 @@ static int handle_file(const char *path,
93
122
} hunk = RR_CONTEXT ;
94
123
struct strbuf one = STRBUF_INIT , two = STRBUF_INIT ;
95
124
struct strbuf buf = STRBUF_INIT ;
96
- FILE * f = fopen (path , "r" );
97
- FILE * out = NULL ;
98
- int wrerror = 0 ;
99
-
100
- if (!f )
101
- return error ("Could not open %s" , path );
102
-
103
- if (output ) {
104
- out = fopen (output , "w" );
105
- if (!out ) {
106
- fclose (f );
107
- return error ("Could not write %s" , output );
108
- }
109
- }
110
125
111
126
if (sha1 )
112
127
git_SHA1_Init (& ctx );
113
128
114
- while (!strbuf_getwholeline (& buf , f , '\n' )) {
129
+ while (!io -> getline (& buf , io )) {
115
130
if (!prefixcmp (buf .buf , "<<<<<<< " )) {
116
131
if (hunk != RR_CONTEXT )
117
132
goto bad ;
@@ -131,13 +146,11 @@ static int handle_file(const char *path,
131
146
strbuf_swap (& one , & two );
132
147
hunk_no ++ ;
133
148
hunk = RR_CONTEXT ;
134
- if (out ) {
135
- ferr_puts ("<<<<<<<\n" , out , & wrerror );
136
- ferr_write (one .buf , one .len , out , & wrerror );
137
- ferr_puts ("=======\n" , out , & wrerror );
138
- ferr_write (two .buf , two .len , out , & wrerror );
139
- ferr_puts (">>>>>>>\n" , out , & wrerror );
140
- }
149
+ rerere_io_putstr ("<<<<<<<\n" , io );
150
+ rerere_io_putmem (one .buf , one .len , io );
151
+ rerere_io_putstr ("=======\n" , io );
152
+ rerere_io_putmem (two .buf , two .len , io );
153
+ rerere_io_putstr (">>>>>>>\n" , io );
141
154
if (sha1 ) {
142
155
git_SHA1_Update (& ctx , one .buf ? one .buf : "" ,
143
156
one .len + 1 );
@@ -152,8 +165,8 @@ static int handle_file(const char *path,
152
165
; /* discard */
153
166
else if (hunk == RR_SIDE_2 )
154
167
strbuf_addstr (& two , buf .buf );
155
- else if ( out )
156
- ferr_puts (buf .buf , out , & wrerror );
168
+ else
169
+ rerere_io_putstr (buf .buf , io );
157
170
continue ;
158
171
bad :
159
172
hunk = 99 ; /* force error exit */
@@ -163,21 +176,49 @@ static int handle_file(const char *path,
163
176
strbuf_release (& two );
164
177
strbuf_release (& buf );
165
178
166
- fclose (f );
167
- if (wrerror )
168
- error ("There were errors while writing %s (%s)" ,
169
- path , strerror (wrerror ));
170
- if (out && fclose (out ))
171
- wrerror = error ("Failed to flush %s: %s" ,
172
- path , strerror (errno ));
173
179
if (sha1 )
174
180
git_SHA1_Final (sha1 , & ctx );
175
- if (hunk != RR_CONTEXT ) {
181
+ if (hunk != RR_CONTEXT )
182
+ return -1 ;
183
+ return hunk_no ;
184
+ }
185
+
186
+ static int handle_file (const char * path , unsigned char * sha1 , const char * output )
187
+ {
188
+ int hunk_no = 0 ;
189
+ struct rerere_io_file io ;
190
+
191
+ memset (& io , 0 , sizeof (io ));
192
+ io .io .getline = rerere_file_getline ;
193
+ io .input = fopen (path , "r" );
194
+ io .io .wrerror = 0 ;
195
+ if (!io .input )
196
+ return error ("Could not open %s" , path );
197
+
198
+ if (output ) {
199
+ io .io .output = fopen (output , "w" );
200
+ if (!io .io .output ) {
201
+ fclose (io .input );
202
+ return error ("Could not write %s" , output );
203
+ }
204
+ }
205
+
206
+ hunk_no = handle_path (sha1 , (struct rerere_io * )& io );
207
+
208
+ fclose (io .input );
209
+ if (io .io .wrerror )
210
+ error ("There were errors while writing %s (%s)" ,
211
+ path , strerror (io .io .wrerror ));
212
+ if (io .io .output && fclose (io .io .output ))
213
+ io .io .wrerror = error ("Failed to flush %s: %s" ,
214
+ path , strerror (errno ));
215
+
216
+ if (hunk_no < 0 ) {
176
217
if (output )
177
218
unlink_or_warn (output );
178
219
return error ("Could not parse conflict hunks in %s" , path );
179
220
}
180
- if (wrerror )
221
+ if (io . io . wrerror )
181
222
return -1 ;
182
223
return hunk_no ;
183
224
}
0 commit comments