26
26
*/
27
27
#define FILTER_SHOWN_BUT_REVISIT (1<<21)
28
28
29
+ struct filter {
30
+ enum list_objects_filter_result (* filter_object_fn )(
31
+ struct repository * r ,
32
+ enum list_objects_filter_situation filter_situation ,
33
+ struct object * obj ,
34
+ const char * pathname ,
35
+ const char * filename ,
36
+ void * filter_data );
37
+
38
+ void (* free_fn )(void * filter_data );
39
+
40
+ void * filter_data ;
41
+ };
42
+
29
43
/*
30
44
* A filter for list-objects to omit ALL blobs from the traversal.
31
45
* And to OPTIONALLY collect a list of the omitted OIDs.
@@ -67,18 +81,17 @@ static enum list_objects_filter_result filter_blobs_none(
67
81
}
68
82
}
69
83
70
- static void * filter_blobs_none__init (
84
+ static void filter_blobs_none__init (
71
85
struct oidset * omitted ,
72
86
struct list_objects_filter_options * filter_options ,
73
- filter_object_fn * filter_fn ,
74
- filter_free_fn * filter_free_fn )
87
+ struct filter * filter )
75
88
{
76
89
struct filter_blobs_none_data * d = xcalloc (1 , sizeof (* d ));
77
90
d -> omits = omitted ;
78
91
79
- * filter_fn = filter_blobs_none ;
80
- * filter_free_fn = free ;
81
- return d ;
92
+ filter -> filter_data = d ;
93
+ filter -> filter_object_fn = filter_blobs_none ;
94
+ filter -> free_fn = free ;
82
95
}
83
96
84
97
/*
@@ -201,21 +214,20 @@ static void filter_trees_free(void *filter_data) {
201
214
free (d );
202
215
}
203
216
204
- static void * filter_trees_depth__init (
217
+ static void filter_trees_depth__init (
205
218
struct oidset * omitted ,
206
219
struct list_objects_filter_options * filter_options ,
207
- filter_object_fn * filter_fn ,
208
- filter_free_fn * filter_free_fn )
220
+ struct filter * filter )
209
221
{
210
222
struct filter_trees_depth_data * d = xcalloc (1 , sizeof (* d ));
211
223
d -> omits = omitted ;
212
224
oidmap_init (& d -> seen_at_depth , 0 );
213
225
d -> exclude_depth = filter_options -> tree_exclude_depth ;
214
226
d -> current_depth = 0 ;
215
227
216
- * filter_fn = filter_trees_depth ;
217
- * filter_free_fn = filter_trees_free ;
218
- return d ;
228
+ filter -> filter_data = d ;
229
+ filter -> filter_object_fn = filter_trees_depth ;
230
+ filter -> free_fn = filter_trees_free ;
219
231
}
220
232
221
233
/*
@@ -281,19 +293,18 @@ static enum list_objects_filter_result filter_blobs_limit(
281
293
return LOFR_MARK_SEEN | LOFR_DO_SHOW ;
282
294
}
283
295
284
- static void * filter_blobs_limit__init (
296
+ static void filter_blobs_limit__init (
285
297
struct oidset * omitted ,
286
298
struct list_objects_filter_options * filter_options ,
287
- filter_object_fn * filter_fn ,
288
- filter_free_fn * filter_free_fn )
299
+ struct filter * filter )
289
300
{
290
301
struct filter_blobs_limit_data * d = xcalloc (1 , sizeof (* d ));
291
302
d -> omits = omitted ;
292
303
d -> max_bytes = filter_options -> blob_limit_value ;
293
304
294
- * filter_fn = filter_blobs_limit ;
295
- * filter_free_fn = free ;
296
- return d ;
305
+ filter -> filter_data = d ;
306
+ filter -> filter_object_fn = filter_blobs_limit ;
307
+ filter -> free_fn = free ;
297
308
}
298
309
299
310
/*
@@ -456,11 +467,10 @@ static void filter_sparse_free(void *filter_data)
456
467
free (d );
457
468
}
458
469
459
- static void * filter_sparse_oid__init (
470
+ static void filter_sparse_oid__init (
460
471
struct oidset * omitted ,
461
472
struct list_objects_filter_options * filter_options ,
462
- filter_object_fn * filter_fn ,
463
- filter_free_fn * filter_free_fn )
473
+ struct filter * filter )
464
474
{
465
475
struct filter_sparse_data * d = xcalloc (1 , sizeof (* d ));
466
476
d -> omits = omitted ;
@@ -473,16 +483,15 @@ static void *filter_sparse_oid__init(
473
483
d -> array_frame [d -> nr ].child_prov_omit = 0 ;
474
484
d -> nr ++ ;
475
485
476
- * filter_fn = filter_sparse ;
477
- * filter_free_fn = filter_sparse_free ;
478
- return d ;
486
+ filter -> filter_data = d ;
487
+ filter -> filter_object_fn = filter_sparse ;
488
+ filter -> free_fn = filter_sparse_free ;
479
489
}
480
490
481
- typedef void * (* filter_init_fn )(
491
+ typedef void (* filter_init_fn )(
482
492
struct oidset * omitted ,
483
493
struct list_objects_filter_options * filter_options ,
484
- filter_object_fn * filter_fn ,
485
- filter_free_fn * filter_free_fn );
494
+ struct filter * filter );
486
495
487
496
/*
488
497
* Must match "enum list_objects_filter_choice".
@@ -495,12 +504,11 @@ static filter_init_fn s_filters[] = {
495
504
filter_sparse_oid__init ,
496
505
};
497
506
498
- void * list_objects_filter__init (
507
+ struct filter * list_objects_filter__init (
499
508
struct oidset * omitted ,
500
- struct list_objects_filter_options * filter_options ,
501
- filter_object_fn * filter_fn ,
502
- filter_free_fn * filter_free_fn )
509
+ struct list_objects_filter_options * filter_options )
503
510
{
511
+ struct filter * filter ;
504
512
filter_init_fn init_fn ;
505
513
506
514
assert ((sizeof (s_filters ) / sizeof (s_filters [0 ])) == LOFC__COUNT );
@@ -510,10 +518,40 @@ void *list_objects_filter__init(
510
518
filter_options -> choice );
511
519
512
520
init_fn = s_filters [filter_options -> choice ];
513
- if (init_fn )
514
- return init_fn (omitted , filter_options ,
515
- filter_fn , filter_free_fn );
516
- * filter_fn = NULL ;
517
- * filter_free_fn = NULL ;
518
- return NULL ;
521
+ if (!init_fn )
522
+ return NULL ;
523
+
524
+ filter = xcalloc (1 , sizeof (* filter ));
525
+ init_fn (omitted , filter_options , filter );
526
+ return filter ;
527
+ }
528
+
529
+ enum list_objects_filter_result list_objects_filter__filter_object (
530
+ struct repository * r ,
531
+ enum list_objects_filter_situation filter_situation ,
532
+ struct object * obj ,
533
+ const char * pathname ,
534
+ const char * filename ,
535
+ struct filter * filter )
536
+ {
537
+ if (filter && (obj -> flags & NOT_USER_GIVEN ))
538
+ return filter -> filter_object_fn (r , filter_situation , obj ,
539
+ pathname , filename ,
540
+ filter -> filter_data );
541
+ /*
542
+ * No filter is active or user gave object explicitly. In this case,
543
+ * always show the object (except when LOFS_END_TREE, since this tree
544
+ * had already been shown when LOFS_BEGIN_TREE).
545
+ */
546
+ if (filter_situation == LOFS_END_TREE )
547
+ return 0 ;
548
+ return LOFR_MARK_SEEN | LOFR_DO_SHOW ;
549
+ }
550
+
551
+ void list_objects_filter__free (struct filter * filter )
552
+ {
553
+ if (!filter )
554
+ return ;
555
+ filter -> free_fn (filter -> filter_data );
556
+ free (filter );
519
557
}
0 commit comments