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")); }
static int sort_dir_list(const void *one, const void *two) { int retval; char *pfirst, *psecond; dir_entry_t *const first = (dir_entry_t *)one; dir_entry_t *const second = (dir_entry_t *)two; int first_is_dir; int second_is_dir; int dirs; if(is_parent_dir(first->name)) { return -1; } else if(is_parent_dir(second->name)) { return 1; } first_is_dir = is_directory_entry(first); second_is_dir = is_directory_entry(second); dirs = first_is_dir || second_is_dir; retval = 0; switch(sort_type) { case SORT_BY_NAME: case SORT_BY_INAME: if(first->name[0] == '.' && second->name[0] != '.') retval = -1; else if(first->name[0] != '.' && second->name[0] == '.') retval = 1; else retval = compare_file_names(dirs, first->name, second->name, sort_type == SORT_BY_INAME); break; case SORT_BY_TYPE: if(first_is_dir != second_is_dir) { retval = first_is_dir ? -1 : 1; } break; case SORT_BY_EXTENSION: pfirst = strrchr(first->name, '.'); psecond = strrchr(second->name, '.'); if(pfirst && psecond) retval = compare_file_names(dirs, ++pfirst, ++psecond, 0); else if(pfirst || psecond) retval = pfirst ? -1 : 1; else retval = compare_file_names(dirs, first->name, second->name, 0); break; case SORT_BY_SIZE: { if(first_is_dir) tree_get_data(curr_stats.dirsize_cache, first->name, &first->size); if(second_is_dir) tree_get_data(curr_stats.dirsize_cache, second->name, &second->size); retval = (first->size < second->size) ? -1 : (first->size > second->size); } break; case SORT_BY_TIME_MODIFIED: retval = first->mtime - second->mtime; break; case SORT_BY_TIME_ACCESSED: retval = first->atime - second->atime; break; case SORT_BY_TIME_CHANGED: retval = first->ctime - second->ctime; break; #ifndef _WIN32 case SORT_BY_MODE: retval = first->mode - second->mode; break; case SORT_BY_OWNER_NAME: /* FIXME */ case SORT_BY_OWNER_ID: retval = first->uid - second->uid; break; case SORT_BY_GROUP_NAME: /* FIXME */ case SORT_BY_GROUP_ID: retval = first->gid - second->gid; break; case SORT_BY_PERMISSIONS: { char first_perm[11], second_perm[11]; get_perm_string(first_perm, sizeof(first_perm), first->mode); get_perm_string(second_perm, sizeof(second_perm), second->mode); retval = strcmp(first_perm, second_perm); } break; #endif default: assert(0 && "All possible sort options should be handled"); break; } if(retval == 0) { retval = first->list_num - second->list_num; } else if(sort_descending) { retval = -retval; } return retval; }
static int sort_dir_list(const void *one, const void *two) { int retval; char *pfirst, *psecond; dir_entry_t *const first = (dir_entry_t *)one; dir_entry_t *const second = (dir_entry_t *)two; int first_is_dir; int second_is_dir; if(is_parent_dir(first->name)) { return -1; } else if(is_parent_dir(second->name)) { return 1; } first_is_dir = is_directory_entry(first); second_is_dir = is_directory_entry(second); retval = 0; switch(sort_type) { case SK_BY_NAME: case SK_BY_INAME: if(custom_view) { retval = compare_entry_names(first, second, sort_type == SK_BY_INAME); } else { retval = compare_full_file_names(first->name, second->name, sort_type == SK_BY_INAME); } break; case SK_BY_DIR: if(first_is_dir != second_is_dir) { retval = first_is_dir ? -1 : 1; } break; case SK_BY_TYPE: retval = strcmp(get_type_str(first->type), get_type_str(second->type)); break; case SK_BY_FILEEXT: case SK_BY_EXTENSION: pfirst = strrchr(first->name, '.'); psecond = strrchr(second->name, '.'); if(first_is_dir && second_is_dir && sort_type == SK_BY_FILEEXT) { retval = compare_file_names(first->name, second->name, 0); } else if(first_is_dir != second_is_dir && sort_type == SK_BY_FILEEXT) { retval = first_is_dir ? -1 : 1; } else if(pfirst && psecond) { if(pfirst == first->name && psecond != second->name) { retval = -1; } else if(pfirst != first->name && psecond == second->name) { retval = 1; } else { retval = compare_file_names(++pfirst, ++psecond, 0); } } else if(pfirst || psecond) retval = pfirst ? -1 : 1; else retval = compare_file_names(first->name, second->name, 0); break; case SK_BY_SIZE: { if(first_is_dir) { char full_path[PATH_MAX]; get_full_path_of(first, sizeof(full_path), full_path); tree_get_data(curr_stats.dirsize_cache, full_path, &first->size); } if(second_is_dir) { char full_path[PATH_MAX]; get_full_path_of(second, sizeof(full_path), full_path); tree_get_data(curr_stats.dirsize_cache, full_path, &second->size); } retval = (first->size < second->size) ? -1 : (first->size > second->size); } break; case SK_BY_TIME_MODIFIED: retval = first->mtime - second->mtime; break; case SK_BY_TIME_ACCESSED: retval = first->atime - second->atime; break; case SK_BY_TIME_CHANGED: retval = first->ctime - second->ctime; break; #ifndef _WIN32 case SK_BY_MODE: retval = first->mode - second->mode; break; case SK_BY_OWNER_NAME: /* FIXME */ case SK_BY_OWNER_ID: retval = first->uid - second->uid; break; case SK_BY_GROUP_NAME: /* FIXME */ case SK_BY_GROUP_ID: retval = first->gid - second->gid; break; case SK_BY_PERMISSIONS: { char first_perm[11], second_perm[11]; get_perm_string(first_perm, sizeof(first_perm), first->mode); get_perm_string(second_perm, sizeof(second_perm), second->mode); retval = strcmp(first_perm, second_perm); } break; #endif } if(retval == 0) { retval = first->list_num - second->list_num; } else if(sort_descending) { retval = -retval; } return retval; }