1212#include "packfile.h"
1313#include "object-store.h"
1414
15- static void process_blob (struct rev_info * revs ,
15+ struct traversal_context {
16+ struct rev_info * revs ;
17+ show_object_fn show_object ;
18+ show_commit_fn show_commit ;
19+ void * show_data ;
20+ filter_object_fn filter_fn ;
21+ void * filter_data ;
22+ };
23+
24+ static void process_blob (struct traversal_context * ctx ,
1625 struct blob * blob ,
17- show_object_fn show ,
1826 struct strbuf * path ,
19- const char * name ,
20- void * cb_data ,
21- filter_object_fn filter_fn ,
22- void * filter_data )
27+ const char * name )
2328{
2429 struct object * obj = & blob -> object ;
2530 size_t pathlen ;
2631 enum list_objects_filter_result r = LOFR_MARK_SEEN | LOFR_DO_SHOW ;
2732
28- if (!revs -> blob_objects )
33+ if (!ctx -> revs -> blob_objects )
2934 return ;
3035 if (!obj )
3136 die ("bad blob object" );
@@ -41,21 +46,21 @@ static void process_blob(struct rev_info *revs,
4146 * may cause the actual filter to report an incomplete list
4247 * of missing objects.
4348 */
44- if (revs -> exclude_promisor_objects &&
49+ if (ctx -> revs -> exclude_promisor_objects &&
4550 !has_object_file (& obj -> oid ) &&
4651 is_promisor_object (& obj -> oid ))
4752 return ;
4853
4954 pathlen = path -> len ;
5055 strbuf_addstr (path , name );
51- if (!(obj -> flags & USER_GIVEN ) && filter_fn )
52- r = filter_fn (LOFS_BLOB , obj ,
53- path -> buf , & path -> buf [pathlen ],
54- filter_data );
56+ if (!(obj -> flags & USER_GIVEN ) && ctx -> filter_fn )
57+ r = ctx -> filter_fn (LOFS_BLOB , obj ,
58+ path -> buf , & path -> buf [pathlen ],
59+ ctx -> filter_data );
5560 if (r & LOFR_MARK_SEEN )
5661 obj -> flags |= SEEN ;
5762 if (r & LOFR_DO_SHOW )
58- show (obj , path -> buf , cb_data );
63+ ctx -> show_object (obj , path -> buf , ctx -> show_data );
5964 strbuf_setlen (path , pathlen );
6065}
6166
@@ -81,26 +86,21 @@ static void process_blob(struct rev_info *revs,
8186 * the link, and how to do it. Whether it necessarily makes
8287 * any sense what-so-ever to ever do that is another issue.
8388 */
84- static void process_gitlink (struct rev_info * revs ,
89+ static void process_gitlink (struct traversal_context * ctx ,
8590 const unsigned char * sha1 ,
86- show_object_fn show ,
8791 struct strbuf * path ,
88- const char * name ,
89- void * cb_data )
92+ const char * name )
9093{
9194 /* Nothing to do */
9295}
9396
94- static void process_tree (struct rev_info * revs ,
97+ static void process_tree (struct traversal_context * ctx ,
9598 struct tree * tree ,
96- show_object_fn show ,
9799 struct strbuf * base ,
98- const char * name ,
99- void * cb_data ,
100- filter_object_fn filter_fn ,
101- void * filter_data )
100+ const char * name )
102101{
103102 struct object * obj = & tree -> object ;
103+ struct rev_info * revs = ctx -> revs ;
104104 struct tree_desc desc ;
105105 struct name_entry entry ;
106106 enum interesting match = revs -> diffopt .pathspec .nr == 0 ?
@@ -133,14 +133,14 @@ static void process_tree(struct rev_info *revs,
133133 }
134134
135135 strbuf_addstr (base , name );
136- if (!(obj -> flags & USER_GIVEN ) && filter_fn )
137- r = filter_fn (LOFS_BEGIN_TREE , obj ,
138- base -> buf , & base -> buf [baselen ],
139- filter_data );
136+ if (!(obj -> flags & USER_GIVEN ) && ctx -> filter_fn )
137+ r = ctx -> filter_fn (LOFS_BEGIN_TREE , obj ,
138+ base -> buf , & base -> buf [baselen ],
139+ ctx -> filter_data );
140140 if (r & LOFR_MARK_SEEN )
141141 obj -> flags |= SEEN ;
142142 if (r & LOFR_DO_SHOW )
143- show (obj , base -> buf , cb_data );
143+ ctx -> show_object (obj , base -> buf , ctx -> show_data );
144144 if (base -> len )
145145 strbuf_addch (base , '/' );
146146
@@ -157,29 +157,25 @@ static void process_tree(struct rev_info *revs,
157157 }
158158
159159 if (S_ISDIR (entry .mode ))
160- process_tree (revs ,
160+ process_tree (ctx ,
161161 lookup_tree (the_repository , entry .oid ),
162- show , base , entry .path ,
163- cb_data , filter_fn , filter_data );
162+ base , entry .path );
164163 else if (S_ISGITLINK (entry .mode ))
165- process_gitlink (revs , entry .oid -> hash ,
166- show , base , entry .path ,
167- cb_data );
164+ process_gitlink (ctx , entry .oid -> hash , base , entry .path );
168165 else
169- process_blob (revs ,
166+ process_blob (ctx ,
170167 lookup_blob (the_repository , entry .oid ),
171- show , base , entry .path ,
172- cb_data , filter_fn , filter_data );
168+ base , entry .path );
173169 }
174170
175- if (!(obj -> flags & USER_GIVEN ) && filter_fn ) {
176- r = filter_fn (LOFS_END_TREE , obj ,
177- base -> buf , & base -> buf [baselen ],
178- filter_data );
171+ if (!(obj -> flags & USER_GIVEN ) && ctx -> filter_fn ) {
172+ r = ctx -> filter_fn (LOFS_END_TREE , obj ,
173+ base -> buf , & base -> buf [baselen ],
174+ ctx -> filter_data );
179175 if (r & LOFR_MARK_SEEN )
180176 obj -> flags |= SEEN ;
181177 if (r & LOFR_DO_SHOW )
182- show (obj , base -> buf , cb_data );
178+ ctx -> show_object (obj , base -> buf , ctx -> show_data );
183179 }
184180
185181 strbuf_setlen (base , baselen );
@@ -242,82 +238,65 @@ static void add_pending_tree(struct rev_info *revs, struct tree *tree)
242238 add_pending_object (revs , & tree -> object , "" );
243239}
244240
245- static void traverse_trees_and_blobs (struct rev_info * revs ,
246- struct strbuf * base ,
247- show_object_fn show_object ,
248- void * show_data ,
249- filter_object_fn filter_fn ,
250- void * filter_data )
241+ static void traverse_trees_and_blobs (struct traversal_context * ctx ,
242+ struct strbuf * base )
251243{
252244 int i ;
253245
254246 assert (base -> len == 0 );
255247
256- for (i = 0 ; i < revs -> pending .nr ; i ++ ) {
257- struct object_array_entry * pending = revs -> pending .objects + i ;
248+ for (i = 0 ; i < ctx -> revs -> pending .nr ; i ++ ) {
249+ struct object_array_entry * pending = ctx -> revs -> pending .objects + i ;
258250 struct object * obj = pending -> item ;
259251 const char * name = pending -> name ;
260252 const char * path = pending -> path ;
261253 if (obj -> flags & (UNINTERESTING | SEEN ))
262254 continue ;
263255 if (obj -> type == OBJ_TAG ) {
264256 obj -> flags |= SEEN ;
265- show_object (obj , name , show_data );
257+ ctx -> show_object (obj , name , ctx -> show_data );
266258 continue ;
267259 }
268260 if (!path )
269261 path = "" ;
270262 if (obj -> type == OBJ_TREE ) {
271- process_tree (revs , (struct tree * )obj , show_object ,
272- base , path , show_data ,
273- filter_fn , filter_data );
263+ process_tree (ctx , (struct tree * )obj , base , path );
274264 continue ;
275265 }
276266 if (obj -> type == OBJ_BLOB ) {
277- process_blob (revs , (struct blob * )obj , show_object ,
278- base , path , show_data ,
279- filter_fn , filter_data );
267+ process_blob (ctx , (struct blob * )obj , base , path );
280268 continue ;
281269 }
282270 die ("unknown pending object %s (%s)" ,
283271 oid_to_hex (& obj -> oid ), name );
284272 }
285- object_array_clear (& revs -> pending );
273+ object_array_clear (& ctx -> revs -> pending );
286274}
287275
288- static void do_traverse (struct rev_info * revs ,
289- show_commit_fn show_commit ,
290- show_object_fn show_object ,
291- void * show_data ,
292- filter_object_fn filter_fn ,
293- void * filter_data )
276+ static void do_traverse (struct traversal_context * ctx )
294277{
295278 struct commit * commit ;
296279 struct strbuf csp ; /* callee's scratch pad */
297280 strbuf_init (& csp , PATH_MAX );
298281
299- while ((commit = get_revision (revs )) != NULL ) {
282+ while ((commit = get_revision (ctx -> revs )) != NULL ) {
300283 /*
301284 * an uninteresting boundary commit may not have its tree
302285 * parsed yet, but we are not going to show them anyway
303286 */
304287 if (get_commit_tree (commit ))
305- add_pending_tree (revs , get_commit_tree (commit ));
306- show_commit (commit , show_data );
288+ add_pending_tree (ctx -> revs , get_commit_tree (commit ));
289+ ctx -> show_commit (commit , ctx -> show_data );
307290
308- if (revs -> tree_blobs_in_commit_order )
291+ if (ctx -> revs -> tree_blobs_in_commit_order )
309292 /*
310293 * NEEDSWORK: Adding the tree and then flushing it here
311294 * needs a reallocation for each commit. Can we pass the
312295 * tree directory without allocation churn?
313296 */
314- traverse_trees_and_blobs (revs , & csp ,
315- show_object , show_data ,
316- filter_fn , filter_data );
297+ traverse_trees_and_blobs (ctx , & csp );
317298 }
318- traverse_trees_and_blobs (revs , & csp ,
319- show_object , show_data ,
320- filter_fn , filter_data );
299+ traverse_trees_and_blobs (ctx , & csp );
321300 strbuf_release (& csp );
322301}
323302
@@ -326,7 +305,14 @@ void traverse_commit_list(struct rev_info *revs,
326305 show_object_fn show_object ,
327306 void * show_data )
328307{
329- do_traverse (revs , show_commit , show_object , show_data , NULL , NULL );
308+ struct traversal_context ctx ;
309+ ctx .revs = revs ;
310+ ctx .show_commit = show_commit ;
311+ ctx .show_object = show_object ;
312+ ctx .show_data = show_data ;
313+ ctx .filter_fn = NULL ;
314+ ctx .filter_data = NULL ;
315+ do_traverse (& ctx );
330316}
331317
332318void traverse_commit_list_filtered (
@@ -337,14 +323,18 @@ void traverse_commit_list_filtered(
337323 void * show_data ,
338324 struct oidset * omitted )
339325{
340- filter_object_fn filter_fn = NULL ;
326+ struct traversal_context ctx ;
341327 filter_free_fn filter_free_fn = NULL ;
342- void * filter_data = NULL ;
343-
344- filter_data = list_objects_filter__init (omitted , filter_options ,
345- & filter_fn , & filter_free_fn );
346- do_traverse (revs , show_commit , show_object , show_data ,
347- filter_fn , filter_data );
348- if (filter_data && filter_free_fn )
349- filter_free_fn (filter_data );
328+
329+ ctx .revs = revs ;
330+ ctx .show_object = show_object ;
331+ ctx .show_commit = show_commit ;
332+ ctx .show_data = show_data ;
333+ ctx .filter_fn = NULL ;
334+
335+ ctx .filter_data = list_objects_filter__init (omitted , filter_options ,
336+ & ctx .filter_fn , & filter_free_fn );
337+ do_traverse (& ctx );
338+ if (ctx .filter_data && filter_free_fn )
339+ filter_free_fn (ctx .filter_data );
350340}
0 commit comments