static void test_filter_matches_differently_after_set(void) { filter_t filter; assert_int_equal(0, filter_init(&filter, 1)); assert_int_equal(0, filter_set(&filter, "abcd")); assert_true(filter_matches(&filter, "abcd")); assert_int_equal(0, filter_set(&filter, "a123")); assert_false(filter_matches(&filter, "abcd")); assert_true(filter_matches(&filter, "a123")); filter_dispose(&filter); }
static void test_regexp_is_changed(void) { filter_t filter; assert_int_equal(0, filter_init(&filter, 1)); assert_int_equal(0, filter_set(&filter, "abcd")); assert_true(filter_matches(&filter, "abcd")); assert_int_equal(0, filter_change(&filter, "a123", 0)); assert_false(filter_matches(&filter, "abcd")); assert_true(filter_matches(&filter, "a123")); filter_dispose(&filter); }
static void test_case_sensitivity_is_changed(void) { filter_t filter; assert_int_equal(0, filter_init(&filter, 1)); assert_int_equal(0, filter_set(&filter, "abcd")); assert_true(filter_matches(&filter, "abcd")); assert_false(filter_matches(&filter, "aBCd")); assert_int_equal(0, filter_change(&filter, "abcd", 0)); assert_true(filter_matches(&filter, "abcd")); assert_true(filter_matches(&filter, "aBCd")); filter_dispose(&filter); }
static void test_append_produces_desired_effect(void) { filter_t filter; assert_int_equal(0, filter_init(&filter, 1)); assert_int_equal(0, filter_set(&filter, "abcd")); assert_true(filter_matches(&filter, "abcd")); assert_false(filter_matches(&filter, "efgh")); assert_int_equal(0, filter_append(&filter, "efgh")); assert_true(filter_matches(&filter, "abcd")); assert_true(filter_matches(&filter, "efgh")); filter_dispose(&filter); }
int filters_file_is_visible(view_t *view, const char dir[], const char name[], int is_dir, int apply_local_filter) { /* FIXME: some very long file names won't be matched against some regexps. */ char name_with_slash[NAME_MAX + 1 + 1]; char path[PATH_MAX + sizeof(name_with_slash)]; if(is_dir) { append_slash(name, name_with_slash, sizeof(name_with_slash)); name = name_with_slash; } if(filter_matches(&view->auto_filter, name) > 0) { return 0; } if(apply_local_filter && filter_matches(&view->local_filter.filter, name) == 0) { return 0; } if(matcher_is_empty(view->manual_filter)) { return 1; } if(matcher_is_full_path(view->manual_filter)) { const size_t nchars = copy_str(path, sizeof(path) - 1, dir); path[nchars - 1U] = '/'; copy_str(path + nchars, sizeof(path) - nchars, name); name = path; } return matcher_matches(view->manual_filter, name) ? !view->invert : view->invert; }
static void test_append_escapes(void) { filter_t filter; assert_int_equal(0, filter_init(&filter, 1)); assert_int_equal(0, filter_append(&filter, "ef|gh")); assert_true(filter_matches(&filter, "ef|gh")); filter_dispose(&filter); }
int local_filter_matches(view_t *view, const dir_entry_t *entry) { /* FIXME: some very long file names won't be matched against some regexps. */ char name_with_slash[NAME_MAX + 1 + 1]; const char *filename = entry->name; if(fentry_is_dir(entry)) { append_slash(filename, name_with_slash, sizeof(name_with_slash)); filename = name_with_slash; } return filter_matches(&view->local_filter.filter, filename) != 0; }
/* zap_entries() filter to filter-out files that match filter passed in the * arg. */ static int is_newly_filtered(view_t *view, const dir_entry_t *entry, void *arg) { filter_t *const filter = arg; /* FIXME: some very long file names won't be matched against some regexps. */ char name_with_slash[NAME_MAX + 1 + 1]; const char *filename = entry->name; if(fentry_is_dir(entry)) { append_slash(filename, name_with_slash, sizeof(name_with_slash)); filename = name_with_slash; } return filter_matches(filter, filename) == 0; }
/* Copies/moves elements of the unfiltered list into dir_entry list. add * parameter controls whether entries matching filter are copied into dir_entry * list. clear parameter controls whether entries not matching filter are * cleared in unfiltered list. Returns zero unless addition is performed in * which case can return non-zero when all files got filtered out. */ static int update_filtering_lists(view_t *view, int add, int clear) { /* filters_drop_temporaries() is a similar function. */ size_t i; size_t list_size = 0U; dir_entry_t *parent_entry = NULL; int parent_added = 0; for(i = 0; i < view->local_filter.unfiltered_count; ++i) { /* FIXME: some very long file names won't be matched against some * regexps. */ char name_with_slash[NAME_MAX + 1 + 1]; dir_entry_t *const entry = &view->local_filter.unfiltered[i]; const char *name = entry->name; if(is_parent_dir(name)) { if(entry->child_pos == 0) { parent_entry = entry; if(add && cfg_parent_dir_is_visible(is_root_dir(view->curr_dir))) { (void)add_dir_entry(&view->dir_entry, &list_size, entry); parent_added = 1; } continue; } else if(!filter_is_empty(&view->local_filter.filter)) { if(clear) { fentry_free(view, entry); } continue; } } if(fentry_is_dir(entry)) { append_slash(name, name_with_slash, sizeof(name_with_slash)); name = name_with_slash; } /* tag links to position of nodes passed through filter in list of visible * files. Nodes that didn't pass have -1. */ entry->tag = -1; if(filter_matches(&view->local_filter.filter, name) != 0) { if(add) { dir_entry_t *e = add_dir_entry(&view->dir_entry, &list_size, entry); if(e != NULL) { entry->tag = list_size - 1U; /* We basically grow the tree node by node while performing * reparenting. */ reparent_tree_node(entry, e); } } } else { if(clear) { fentry_free(view, entry); } } } if(clear) { /* XXX: the check of name pointer is horrible, but is needed to prevent * freeing of entry in use. */ if(!parent_added && parent_entry != NULL && list_size != 0U && view->dir_entry[0].name != parent_entry->name) { fentry_free(view, parent_entry); } } if(add) { view->list_rows = list_size; view->filtered = view->local_filter.prefiltered_count + view->local_filter.unfiltered_count - list_size; ensure_filtered_list_not_empty(view, parent_entry); return list_size == 0U || (list_size == 1U && parent_added && (filter_matches(&view->local_filter.filter, "../") == 0)); } return 0; }