26
*/
27
#define FILTER_SHOWN_BUT_REVISIT (1<<21)
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
+
43
/*
44
* A filter for list-objects to omit ALL blobs from the traversal.
45
* And to OPTIONALLY collect a list of the omitted OIDs.
81
}
82
}
83
70
-static void *filter_blobs_none__init(
84
+static void filter_blobs_none__init(
85
struct oidset *omitted,
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)
88
{
89
struct filter_blobs_none_data *d = xcalloc(1, sizeof(*d));
90
d->omits = omitted;
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;
95
}
96
97
/*
214
free(d);
215
}
216
204
-static void *filter_trees_depth__init(
217
+static void filter_trees_depth__init(
218
struct oidset *omitted,
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)
221
{
222
struct filter_trees_depth_data *d = xcalloc(1, sizeof(*d));
223
d->omits = omitted;
225
d->exclude_depth = filter_options->tree_exclude_depth;
226
d->current_depth = 0;
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;
231
}
232
233
/*
293
return LOFR_MARK_SEEN | LOFR_DO_SHOW;
294
}
295
284
-static void *filter_blobs_limit__init(
296
+static void filter_blobs_limit__init(
297
struct oidset *omitted,
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)
300
{
301
struct filter_blobs_limit_data *d = xcalloc(1, sizeof(*d));
302
d->omits = omitted;
303
d->max_bytes = filter_options->blob_limit_value;
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;
308
}
309
310
/*
467
free(d);
468
}
469
459
-static void *filter_sparse_oid__init(
470
+static void filter_sparse_oid__init(
471
struct oidset *omitted,
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)
474
{
475
struct filter_sparse_data *d = xcalloc(1, sizeof(*d));
476
d->omits = omitted;
483
d->array_frame[d->nr].child_prov_omit = 0;
484
d->nr++;
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;
489
}
490
481
-typedef void *(*filter_init_fn)(
491
+typedef void (*filter_init_fn)(
492
struct oidset *omitted,
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);
495
496
/*
497
* Must match "enum list_objects_filter_choice".
504
filter_sparse_oid__init,
505
};
506
498
-void *list_objects_filter__init(
507
+struct filter *list_objects_filter__init(
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)
510
{
511
+ struct filter *filter;
512
filter_init_fn init_fn;
513
514
assert((sizeof(s_filters) / sizeof(s_filters[0])) == LOFC__COUNT);
518
filter_options->choice);
519
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);
557
}