/* Synchronizes two lists of entries so that they contain only items that * present in both of the lists. Assumes that both lists are sorted by id. */ static void leave_only_dups(entries_t *curr, entries_t *other) { int new_id = 0; int i = 0, j = 0; /* Skip leading unmatched files. */ while(i < other->nentries && other->entries[i].id == -1) { ++i; } /* Process sequences of files in two lists. */ while(i < other->nentries) { const int id = other->entries[i].id; /* Skip sequence of unmatched files. */ while(j < curr->nentries && curr->entries[j].id < id) { curr->entries[j++].id = -1; } if(j < curr->nentries && curr->entries[j].id == id) { /* Allocate next id when we find a matching pair of files in both * lists. */ ++new_id; /* Update sequence of identical ids for other list. */ do { other->entries[i++].id = new_id; } while(i < other->nentries && other->entries[i].id == id); /* Update sequence of identical ids for current list. */ do { curr->entries[j++].id = new_id; } while(j < curr->nentries && curr->entries[j].id == id); } } /* Exclude unprocessed files in the tail. */ while(j < curr->nentries) { curr->entries[j++].id = -1; } (void)zap_entries(other_view, other->entries, &other->nentries, &is_not_duplicate, NULL, 1, 0); (void)zap_entries(curr_view, curr->entries, &curr->nentries, &is_not_duplicate, NULL, 1, 0); }
void name_filters_add_selection(view_t *view) { dir_entry_t *entry; filter_t filter; int filtered; (void)filter_init(&filter, FILTER_DEF_CASE_SENSITIVITY); /* Traverse items and update/create filter values. */ entry = NULL; while(iter_selection_or_current(view, &entry)) { const char *name = entry->name; char name_with_slash[NAME_MAX + 1 + 1]; if(fentry_is_dir(entry)) { append_slash(entry->name, name_with_slash, sizeof(name_with_slash)); name = name_with_slash; } (void)filter_append(&view->auto_filter, name); (void)filter_append(&filter, name); } /* Even current file might be unavailable for filtering. In this case, just * do nothing. */ if(filter_is_empty(&filter)) { filter_dispose(&filter); return; } if(view->custom.type == CV_DIFF) { (void)filter_in_compare(view, &filter, &is_newly_filtered); ui_view_schedule_redraw(view); filter_dispose(&filter); return; } /* Update entry lists to remove entries that must be filtered out now. No * view reload is needed. */ filtered = zap_entries(view, view->dir_entry, &view->list_rows, &is_newly_filtered, &filter, 0, 1); if(flist_custom_active(view)) { (void)zap_entries(view, view->local_filter.entries, &view->local_filter.entry_count, &is_newly_filtered, &filter, 1, 1); } else { view->filtered += filtered; } filter_dispose(&filter); fpos_ensure_valid_pos(view); ui_view_schedule_redraw(view); }