@@ -83,8 +83,37 @@ static inline void ferr_puts(const char *s, FILE *fp, int *err)
8383 ferr_write (s , strlen (s ), fp , err );
8484}
8585
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 )
88117{
89118 git_SHA_CTX ctx ;
90119 int hunk_no = 0 ;
@@ -93,25 +122,11 @@ static int handle_file(const char *path,
93122 } hunk = RR_CONTEXT ;
94123 struct strbuf one = STRBUF_INIT , two = STRBUF_INIT ;
95124 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- }
110125
111126 if (sha1 )
112127 git_SHA1_Init (& ctx );
113128
114- while (!strbuf_getwholeline (& buf , f , '\n' )) {
129+ while (!io -> getline (& buf , io )) {
115130 if (!prefixcmp (buf .buf , "<<<<<<< " )) {
116131 if (hunk != RR_CONTEXT )
117132 goto bad ;
@@ -131,13 +146,11 @@ static int handle_file(const char *path,
131146 strbuf_swap (& one , & two );
132147 hunk_no ++ ;
133148 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 );
141154 if (sha1 ) {
142155 git_SHA1_Update (& ctx , one .buf ? one .buf : "" ,
143156 one .len + 1 );
@@ -152,8 +165,8 @@ static int handle_file(const char *path,
152165 ; /* discard */
153166 else if (hunk == RR_SIDE_2 )
154167 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 );
157170 continue ;
158171 bad :
159172 hunk = 99 ; /* force error exit */
@@ -163,21 +176,49 @@ static int handle_file(const char *path,
163176 strbuf_release (& two );
164177 strbuf_release (& buf );
165178
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 ));
173179 if (sha1 )
174180 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 ) {
176217 if (output )
177218 unlink_or_warn (output );
178219 return error ("Could not parse conflict hunks in %s" , path );
179220 }
180- if (wrerror )
221+ if (io . io . wrerror )
181222 return -1 ;
182223 return hunk_no ;
183224}
0 commit comments