summaryrefslogtreecommitdiff
path: root/list-objects-filter.c
diff options
context:
space:
mode:
authorMatthew DeVore <matvore@google.com>2019-06-27 22:54:05 (GMT)
committerJunio C Hamano <gitster@pobox.com>2019-06-28 15:41:53 (GMT)
commit9430147ca0aab0189d7e52df97b95a0985fc0c8a (patch)
tree063bbf5b2d710466c1e34bdffcdc2b3a59f5fc71 /list-objects-filter.c
parent8dca754b1e874719a732bc9ab7b0e14b21b1bc10 (diff)
downloadgit-9430147ca0aab0189d7e52df97b95a0985fc0c8a.zip
git-9430147ca0aab0189d7e52df97b95a0985fc0c8a.tar.gz
git-9430147ca0aab0189d7e52df97b95a0985fc0c8a.tar.bz2
list-objects-filter: encapsulate filter components
Encapsulate filter_fn, filter_free_fn, and filter_data into their own opaque struct. Due to opaqueness, filter_fn and filter_free_fn can no longer be accessed directly by users. Currently, all usages of filter_fn are guarded by a necessary check: (obj->flags & NOT_USER_GIVEN) && filter_fn Take the opportunity to include this check into the new function list_objects_filter__filter_object(), so that we no longer need to write this check at every caller of the filter function. Also, the init functions in list-objects-filter.c no longer need to confusingly return the filter constituents in various places (filter_fn and filter_free_fn as out parameters, and filter_data as the function's return value); they can just initialize the "struct filter" passed in. Helped-by: Jeff Hostetler <git@jeffhostetler.com> Helped-by: Jonathan Tan <jonathantanmy@google.com> Helped-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Matthew DeVore <matvore@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'list-objects-filter.c')
-rw-r--r--list-objects-filter.c112
1 files changed, 75 insertions, 37 deletions
diff --git a/list-objects-filter.c b/list-objects-filter.c
index 36e1f77..e06b82d 100644
--- a/list-objects-filter.c
+++ b/list-objects-filter.c
@@ -26,6 +26,20 @@
*/
#define FILTER_SHOWN_BUT_REVISIT (1<<21)
+struct filter {
+ enum list_objects_filter_result (*filter_object_fn)(
+ struct repository *r,
+ enum list_objects_filter_situation filter_situation,
+ struct object *obj,
+ const char *pathname,
+ const char *filename,
+ void *filter_data);
+
+ void (*free_fn)(void *filter_data);
+
+ void *filter_data;
+};
+
/*
* A filter for list-objects to omit ALL blobs from the traversal.
* And to OPTIONALLY collect a list of the omitted OIDs.
@@ -67,18 +81,17 @@ static enum list_objects_filter_result filter_blobs_none(
}
}
-static void *filter_blobs_none__init(
+static void filter_blobs_none__init(
struct oidset *omitted,
struct list_objects_filter_options *filter_options,
- filter_object_fn *filter_fn,
- filter_free_fn *filter_free_fn)
+ struct filter *filter)
{
struct filter_blobs_none_data *d = xcalloc(1, sizeof(*d));
d->omits = omitted;
- *filter_fn = filter_blobs_none;
- *filter_free_fn = free;
- return d;
+ filter->filter_data = d;
+ filter->filter_object_fn = filter_blobs_none;
+ filter->free_fn = free;
}
/*
@@ -201,11 +214,10 @@ static void filter_trees_free(void *filter_data) {
free(d);
}
-static void *filter_trees_depth__init(
+static void filter_trees_depth__init(
struct oidset *omitted,
struct list_objects_filter_options *filter_options,
- filter_object_fn *filter_fn,
- filter_free_fn *filter_free_fn)
+ struct filter *filter)
{
struct filter_trees_depth_data *d = xcalloc(1, sizeof(*d));
d->omits = omitted;
@@ -213,9 +225,9 @@ static void *filter_trees_depth__init(
d->exclude_depth = filter_options->tree_exclude_depth;
d->current_depth = 0;
- *filter_fn = filter_trees_depth;
- *filter_free_fn = filter_trees_free;
- return d;
+ filter->filter_data = d;
+ filter->filter_object_fn = filter_trees_depth;
+ filter->free_fn = filter_trees_free;
}
/*
@@ -281,19 +293,18 @@ include_it:
return LOFR_MARK_SEEN | LOFR_DO_SHOW;
}
-static void *filter_blobs_limit__init(
+static void filter_blobs_limit__init(
struct oidset *omitted,
struct list_objects_filter_options *filter_options,
- filter_object_fn *filter_fn,
- filter_free_fn *filter_free_fn)
+ struct filter *filter)
{
struct filter_blobs_limit_data *d = xcalloc(1, sizeof(*d));
d->omits = omitted;
d->max_bytes = filter_options->blob_limit_value;
- *filter_fn = filter_blobs_limit;
- *filter_free_fn = free;
- return d;
+ filter->filter_data = d;
+ filter->filter_object_fn = filter_blobs_limit;
+ filter->free_fn = free;
}
/*
@@ -456,11 +467,10 @@ static void filter_sparse_free(void *filter_data)
free(d);
}
-static void *filter_sparse_oid__init(
+static void filter_sparse_oid__init(
struct oidset *omitted,
struct list_objects_filter_options *filter_options,
- filter_object_fn *filter_fn,
- filter_free_fn *filter_free_fn)
+ struct filter *filter)
{
struct filter_sparse_data *d = xcalloc(1, sizeof(*d));
d->omits = omitted;
@@ -473,16 +483,15 @@ static void *filter_sparse_oid__init(
d->array_frame[d->nr].child_prov_omit = 0;
d->nr++;
- *filter_fn = filter_sparse;
- *filter_free_fn = filter_sparse_free;
- return d;
+ filter->filter_data = d;
+ filter->filter_object_fn = filter_sparse;
+ filter->free_fn = filter_sparse_free;
}
-typedef void *(*filter_init_fn)(
+typedef void (*filter_init_fn)(
struct oidset *omitted,
struct list_objects_filter_options *filter_options,
- filter_object_fn *filter_fn,
- filter_free_fn *filter_free_fn);
+ struct filter *filter);
/*
* Must match "enum list_objects_filter_choice".
@@ -495,12 +504,11 @@ static filter_init_fn s_filters[] = {
filter_sparse_oid__init,
};
-void *list_objects_filter__init(
+struct filter *list_objects_filter__init(
struct oidset *omitted,
- struct list_objects_filter_options *filter_options,
- filter_object_fn *filter_fn,
- filter_free_fn *filter_free_fn)
+ struct list_objects_filter_options *filter_options)
{
+ struct filter *filter;
filter_init_fn init_fn;
assert((sizeof(s_filters) / sizeof(s_filters[0])) == LOFC__COUNT);
@@ -510,10 +518,40 @@ void *list_objects_filter__init(
filter_options->choice);
init_fn = s_filters[filter_options->choice];
- if (init_fn)
- return init_fn(omitted, filter_options,
- filter_fn, filter_free_fn);
- *filter_fn = NULL;
- *filter_free_fn = NULL;
- return NULL;
+ if (!init_fn)
+ return NULL;
+
+ filter = xcalloc(1, sizeof(*filter));
+ init_fn(omitted, filter_options, filter);
+ return filter;
+}
+
+enum list_objects_filter_result list_objects_filter__filter_object(
+ struct repository *r,
+ enum list_objects_filter_situation filter_situation,
+ struct object *obj,
+ const char *pathname,
+ const char *filename,
+ struct filter *filter)
+{
+ if (filter && (obj->flags & NOT_USER_GIVEN))
+ return filter->filter_object_fn(r, filter_situation, obj,
+ pathname, filename,
+ filter->filter_data);
+ /*
+ * No filter is active or user gave object explicitly. In this case,
+ * always show the object (except when LOFS_END_TREE, since this tree
+ * had already been shown when LOFS_BEGIN_TREE).
+ */
+ if (filter_situation == LOFS_END_TREE)
+ return 0;
+ return LOFR_MARK_SEEN | LOFR_DO_SHOW;
+}
+
+void list_objects_filter__free(struct filter *filter)
+{
+ if (!filter)
+ return;
+ filter->free_fn(filter->filter_data);
+ free(filter);
}