Ejemplo n.º 1
0
/* Composes two views containing only files that are unique to each of them.
 * Assumes that both lists are sorted by id. */
static void
make_unique_lists(entries_t curr, entries_t other)
{
	int i, j = 0;

	flist_custom_start(curr_view, "unique");
	flist_custom_start(other_view, "unique");

	for(i = 0; i < other.nentries; ++i)
	{
		const int id = other.entries[i].id;

		while(j < curr.nentries && curr.entries[j].id < id)
		{
			flist_custom_put(curr_view, &curr.entries[j]);
			++j;
		}

		if(j >= curr.nentries || curr.entries[j].id != id)
		{
			flist_custom_put(other_view, &other.entries[i]);
			continue;
		}

		while(j < curr.nentries && curr.entries[j].id == id)
		{
			free_dir_entry(curr_view, &curr.entries[j++]);
		}
		while(i < other.nentries && other.entries[i].id == id)
		{
			free_dir_entry(other_view, &other.entries[i++]);
		}
		--i;
	}

	/* Entries' data has been moved out of them or freed, so need to free only the
	 * lists. */
	dynarray_free(curr.entries);
	dynarray_free(other.entries);

	(void)flist_custom_finish(curr_view, CV_REGULAR, 1);
	(void)flist_custom_finish(other_view, CV_REGULAR, 1);

	curr_view->list_pos = 0;
	other_view->list_pos = 0;

	ui_view_schedule_redraw(curr_view);
	ui_view_schedule_redraw(other_view);
}
Ejemplo n.º 2
0
TEST(symlinks_to_dirs_are_recognized_as_dirs, IF(not_windows))
{
	char test_dir[PATH_MAX];

	assert_non_null(os_realpath(TEST_DATA_PATH "/existing-files", test_dir));

	assert_success(chdir(SANDBOX_PATH));

	/* symlink() is not available on Windows, but other code is fine. */
#ifndef _WIN32
	assert_success(symlink(test_dir, "dir-link"));
#endif
	(void)test_dir;

	assert_false(flist_custom_active(&lwin));

	flist_custom_start(&lwin, "test");
	flist_custom_add(&lwin, "./dir-link");
	assert_true(flist_custom_finish(&lwin, 0) == 0);

	assert_int_equal(1, lwin.list_rows);
	assert_true(is_directory_entry(&lwin.dir_entry[0]));

	assert_success(remove("dir-link"));
}
Ejemplo n.º 3
0
TEST(reload_does_not_remove_broken_symlinks, IF(not_windows))
{
	char test_file[PATH_MAX];

	assert_non_null(os_realpath(TEST_DATA_PATH "/existing-files/a", test_file));

	assert_success(chdir(SANDBOX_PATH));

	/* symlink() is not available on Windows, but other code is fine. */
#ifndef _WIN32
	assert_success(symlink("/wrong/path", "broken-link"));
#endif

	assert_false(flist_custom_active(&lwin));

	flist_custom_start(&lwin, "test");
	flist_custom_add(&lwin, test_file);
	flist_custom_add(&lwin, "./broken-link");
	assert_true(flist_custom_finish(&lwin, 0) == 0);

	assert_int_equal(2, lwin.list_rows);
	load_dir_list(&lwin, 1);
	assert_int_equal(2, lwin.list_rows);

	assert_success(remove("broken-link"));
}
Ejemplo n.º 4
0
static void
setup_custom_view(FileView *view)
{
	assert_false(flist_custom_active(view));
	snprintf(view->curr_dir, sizeof(view->curr_dir), "%s/existing-files",
			test_data);
	flist_custom_start(view, "test");
	flist_custom_add(view, TEST_DATA_PATH "/existing-files/a");
	assert_true(flist_custom_finish(view, 0) == 0);
}
Ejemplo n.º 5
0
int
compare_two_panes(CompareType ct, ListType lt, int group_paths, int skip_empty)
{
	int next_id = 1;
	entries_t curr, other;

	trie_t *const trie = trie_create();
	ui_cancellation_reset();
	ui_cancellation_enable();

	curr = make_diff_list(trie, curr_view, &next_id, ct, skip_empty, 0);
	other = make_diff_list(trie, other_view, &next_id, ct, skip_empty,
			lt == LT_DUPS);

	ui_cancellation_disable();
	trie_free_with_data(trie, &free_compare_records);

	/* Clear progress message displayed by make_diff_list(). */
	ui_sb_quick_msg_clear();

	if(ui_cancellation_requested())
	{
		free_dir_entries(curr_view, &curr.entries, &curr.nentries);
		free_dir_entries(other_view, &other.entries, &other.nentries);
		status_bar_message("Comparison has been cancelled");
		return 1;
	}

	if(!group_paths || lt != LT_ALL)
	{
		/* Sort both lists according to unique file numbers to group identical files
		 * (sorting is stable, tags are set in make_diff_list()). */
		qsort(curr.entries, curr.nentries, sizeof(*curr.entries), &id_sorter);
		qsort(other.entries, other.nentries, sizeof(*other.entries), &id_sorter);
	}

	if(lt == LT_UNIQUE)
	{
		make_unique_lists(curr, other);
		return 0;
	}

	if(lt == LT_DUPS)
	{
		leave_only_dups(&curr, &other);
	}

	flist_custom_start(curr_view, lt == LT_ALL ? "diff" : "dups diff");
	flist_custom_start(other_view, lt == LT_ALL ? "diff" : "dups diff");

	fill_side_by_side(curr, other, group_paths);

	if(flist_custom_finish(curr_view, CV_DIFF, 0) != 0)
	{
		show_error_msg("Comparison", "No results to display");
		return 0;
	}
	if(flist_custom_finish(other_view, CV_DIFF, 0) != 0)
	{
		assert(0 && "The error shouldn't be happening here.");
	}

	curr_view->list_pos = 0;
	other_view->list_pos = 0;
	curr_view->custom.diff_cmp_type = ct;
	other_view->custom.diff_cmp_type = ct;
	curr_view->custom.diff_path_group = group_paths;
	other_view->custom.diff_path_group = group_paths;

	assert(curr_view->list_rows == other_view->list_rows &&
			"Diff views must be in sync!");

	ui_view_schedule_redraw(curr_view);
	ui_view_schedule_redraw(other_view);
	return 0;
}
Ejemplo n.º 6
0
int
compare_one_pane(FileView *view, CompareType ct, ListType lt, int skip_empty)
{
	int i, dup_id;
	FileView *other = (view == curr_view) ? other_view : curr_view;
	const char *const title = (lt == LT_ALL)  ? "compare"
	                        : (lt == LT_DUPS) ? "dups" : "nondups";

	int next_id = 1;
	entries_t curr;

	trie_t *trie = trie_create();
	ui_cancellation_reset();
	ui_cancellation_enable();

	curr = make_diff_list(trie, view, &next_id, ct, skip_empty, 0);

	ui_cancellation_disable();
	trie_free_with_data(trie, &free_compare_records);

	/* Clear progress message displayed by make_diff_list(). */
	ui_sb_quick_msg_clear();

	if(ui_cancellation_requested())
	{
		free_dir_entries(view, &curr.entries, &curr.nentries);
		status_bar_message("Comparison has been cancelled");
		return 1;
	}

	qsort(curr.entries, curr.nentries, sizeof(*curr.entries), &id_sorter);

	flist_custom_start(view, title);

	dup_id = -1;
	next_id = 0;
	for(i = 0; i < curr.nentries; ++i)
	{
		dir_entry_t *entry = &curr.entries[i];

		if(lt == LT_ALL)
		{
			flist_custom_put(view, entry);
			continue;
		}

		if(entry->id == dup_id)
		{
			put_or_free(view, entry, next_id, lt == LT_DUPS);
			continue;
		}

		dup_id = (i < curr.nentries - 1 && entry[0].id == entry[1].id)
		       ? entry->id
		       : -1;

		if(entry->id == dup_id)
		{
			put_or_free(view, entry, ++next_id, lt == LT_DUPS);
			continue;
		}

		put_or_free(view, entry, next_id, lt == LT_UNIQUE);
	}

	/* Entries' data has been moved out of them or freed, so need to free only the
	 * list. */
	dynarray_free(curr.entries);

	if(flist_custom_finish(view, lt == LT_UNIQUE ? CV_REGULAR : CV_COMPARE,
				0) != 0)
	{
		show_error_msg("Comparison", "No results to display");
		return 0;
	}

	/* Leave the other pane, if it's in the CV_DIFF mode, two panes are needed for
	 * this. */
	if(other->custom.type == CV_DIFF)
	{
		cd_updir(other, 1);
	}

	view->list_pos = 0;
	ui_view_schedule_redraw(view);
	return 0;
}
Ejemplo n.º 7
0
int
menu_to_custom_view(menu_state_t *m, FileView *view, int very)
{
	int i;
	char *current = NULL;
	const char *const rel_base = get_relative_path_base(m->d, view);

	flist_custom_start(view, m->d->title);

	for(i = 0; i < m->d->len; ++i)
	{
		char *path;
		int line_num;

		/* Skip empty lines. */
		if(skip_whitespace(m->d->items[i])[0] == '\0')
		{
			continue;
		}

		path = parse_file_spec(m->d->items[i], &line_num, rel_base);
		if(path == NULL)
		{
			continue;
		}

		flist_custom_add(view, path);

		/* Use either exact position or the next path. */
		if(i == m->d->pos || (current == NULL && i > m->d->pos))
		{
			current = path;
			continue;
		}

		free(path);
	}

	/* If current line and none of the lines below didn't contain valid path, try
	 * to use file above cursor position. */
	if(current == NULL && view->custom.entry_count != 0)
	{
		char full_path[PATH_MAX];
		get_full_path_of(&view->custom.entries[view->custom.entry_count - 1],
				sizeof(full_path), full_path);

		current = strdup(full_path);
	}

	if(flist_custom_finish(view, very ? CV_VERY : CV_REGULAR, 0) != 0)
	{
		free(current);
		return 1;
	}

	if(current != NULL)
	{
		flist_goto_by_path(view, current);
		free(current);
	}

	return 0;
}