mirror of
https://git.proxmox.com/git/libgit2
synced 2025-08-11 16:16:43 +00:00
git_win32_path_dirload_with_stat: removed
This commit is contained in:
parent
07bbc045c7
commit
35c1d20750
@ -984,21 +984,6 @@ static void fs_iterator__seek_frame_start(
|
|||||||
ff->index = 0;
|
ff->index = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
GIT_INLINE(int) path_dirload_with_stat(
|
|
||||||
const char *path,
|
|
||||||
size_t prefix_len,
|
|
||||||
unsigned int flags,
|
|
||||||
const char *start_stat,
|
|
||||||
const char *end_stat,
|
|
||||||
git_vector *contents)
|
|
||||||
{
|
|
||||||
#if defined(GIT_WIN32) && !defined(__MINGW32__)
|
|
||||||
return git_win32_path_dirload_with_stat(path, prefix_len, flags, start_stat, end_stat, contents);
|
|
||||||
#else
|
|
||||||
return git_path_dirload_with_stat(path, prefix_len, flags, start_stat, end_stat, contents);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static int fs_iterator__expand_dir(fs_iterator *fi)
|
static int fs_iterator__expand_dir(fs_iterator *fi)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
@ -1013,7 +998,7 @@ static int fs_iterator__expand_dir(fs_iterator *fi)
|
|||||||
ff = fs_iterator__alloc_frame(fi);
|
ff = fs_iterator__alloc_frame(fi);
|
||||||
GITERR_CHECK_ALLOC(ff);
|
GITERR_CHECK_ALLOC(ff);
|
||||||
|
|
||||||
error = path_dirload_with_stat(
|
error = git_path_dirload_with_stat(
|
||||||
fi->path.ptr, fi->root_len, fi->dirload_flags,
|
fi->path.ptr, fi->root_len, fi->dirload_flags,
|
||||||
fi->base.start, fi->base.end, &ff->entries);
|
fi->base.start, fi->base.end, &ff->entries);
|
||||||
|
|
||||||
|
@ -312,175 +312,6 @@ char *git_win32_path_8dot3_name(const char *path)
|
|||||||
return shortname;
|
return shortname;
|
||||||
}
|
}
|
||||||
|
|
||||||
GIT_INLINE(int) path_with_stat_alloc(
|
|
||||||
git_path_with_stat **out,
|
|
||||||
const char *parent_path,
|
|
||||||
size_t parent_path_len,
|
|
||||||
const wchar_t *child_path_utf16,
|
|
||||||
bool trailing_slash)
|
|
||||||
{
|
|
||||||
git_path_with_stat *ps;
|
|
||||||
int inner_slash =
|
|
||||||
(parent_path_len > 0 && parent_path[parent_path_len-1] != '/');
|
|
||||||
size_t path_len, child_path_len, ps_size;
|
|
||||||
|
|
||||||
if ((child_path_len = git__utf16_to_8(NULL, 0, child_path_utf16)) < 0) {
|
|
||||||
giterr_set(GITERR_OS, "Could not convert path to UTF-8 (path too long?)");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
GITERR_CHECK_ALLOC_ADD(&path_len, parent_path_len, inner_slash);
|
|
||||||
GITERR_CHECK_ALLOC_ADD(&path_len, path_len, child_path_len);
|
|
||||||
GITERR_CHECK_ALLOC_ADD(&path_len, path_len, trailing_slash ? 1 : 0);
|
|
||||||
|
|
||||||
GITERR_CHECK_ALLOC_ADD(&ps_size, sizeof(git_path_with_stat), path_len);
|
|
||||||
GITERR_CHECK_ALLOC_ADD(&ps_size, ps_size, 1);
|
|
||||||
|
|
||||||
ps = git__calloc(1, ps_size);
|
|
||||||
GITERR_CHECK_ALLOC(ps);
|
|
||||||
|
|
||||||
if (parent_path_len)
|
|
||||||
memcpy(ps->path, parent_path, parent_path_len);
|
|
||||||
|
|
||||||
if (inner_slash)
|
|
||||||
ps->path[parent_path_len] = '/';
|
|
||||||
|
|
||||||
if (git__utf16_to_8(
|
|
||||||
&ps->path[parent_path_len + inner_slash],
|
|
||||||
child_path_len + 1, child_path_utf16) != child_path_len) {
|
|
||||||
git__free(ps);
|
|
||||||
giterr_set(GITERR_OS, "Could not convert path to UTF-8 (size changed)");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (trailing_slash)
|
|
||||||
ps->path[path_len-1] = '/';
|
|
||||||
|
|
||||||
ps->path_len = path_len;
|
|
||||||
|
|
||||||
*out = ps;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
GIT_INLINE(int) path_add_base(
|
|
||||||
git_win32_path out,
|
|
||||||
size_t dir_len,
|
|
||||||
wchar_t *base,
|
|
||||||
size_t base_len)
|
|
||||||
{
|
|
||||||
size_t out_len;
|
|
||||||
|
|
||||||
if (GIT_ADD_SIZET_OVERFLOW(&out_len, dir_len, base_len) < 0 ||
|
|
||||||
GIT_ADD_SIZET_OVERFLOW(&out_len, out_len, 2) < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (out_len > GIT_WIN_PATH_UTF16) {
|
|
||||||
giterr_set(GITERR_FILESYSTEM, "invalid path '%.*ls\\%.*ls' (path too long)", dir_len, out, base_len, base);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
out[dir_len] = '\\';
|
|
||||||
memcpy(&out[dir_len+1], base, base_len * sizeof(wchar_t));
|
|
||||||
out[out_len-1] = '\0';
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !defined(__MINGW32__)
|
|
||||||
int git_win32_path_dirload_with_stat(
|
|
||||||
const char *path,
|
|
||||||
size_t prefix_len,
|
|
||||||
unsigned int flags,
|
|
||||||
const char *start_stat,
|
|
||||||
const char *end_stat,
|
|
||||||
git_vector *contents)
|
|
||||||
{
|
|
||||||
int error = 0;
|
|
||||||
git_path_with_stat *ps;
|
|
||||||
git_win32_path path_filter, file_path;
|
|
||||||
DIR dir = {0};
|
|
||||||
int(*strncomp)(const char *a, const char *b, size_t sz);
|
|
||||||
size_t start_len = start_stat ? strlen(start_stat) : 0;
|
|
||||||
size_t end_len = end_stat ? strlen(end_stat) : 0;
|
|
||||||
size_t path_len, suffix_len, cmp_len;
|
|
||||||
const char *suffix;
|
|
||||||
int root_len;
|
|
||||||
|
|
||||||
if ((root_len = git_win32_path_from_utf8(file_path, path)) < 0 ||
|
|
||||||
!git_win32__findfirstfile_filter(path_filter, path)) {
|
|
||||||
giterr_set(GITERR_OS, "Could not parse the path '%s'", path);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
strncomp = (flags & GIT_PATH_DIR_IGNORE_CASE) != 0 ?
|
|
||||||
git__strncasecmp : git__strncmp;
|
|
||||||
|
|
||||||
path_len = strlen(path);
|
|
||||||
|
|
||||||
suffix = path + prefix_len;
|
|
||||||
suffix_len = path_len - prefix_len;
|
|
||||||
|
|
||||||
/* We use FIND_FIRST_EX_LARGE_FETCH here for a minor perf bump; this
|
|
||||||
* flag should be ignored on previous version of Windows.
|
|
||||||
*/
|
|
||||||
dir.h = FindFirstFileExW(
|
|
||||||
path_filter,
|
|
||||||
FindExInfoBasic,
|
|
||||||
&dir.f,
|
|
||||||
FindExSearchNameMatch,
|
|
||||||
NULL,
|
|
||||||
_FIND_FIRST_EX_LARGE_FETCH);
|
|
||||||
|
|
||||||
if (dir.h == INVALID_HANDLE_VALUE) {
|
|
||||||
error = -1;
|
|
||||||
giterr_set(GITERR_OS, "Could not open directory '%s'", path);
|
|
||||||
goto clean_up_and_exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
|
||||||
if (git_path_is_dot_or_dotdotW(dir.f.cFileName))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if ((error = path_add_base(file_path, root_len, dir.f.cFileName, wcslen(dir.f.cFileName))) < 0 ||
|
|
||||||
(error = path_with_stat_alloc(&ps,
|
|
||||||
suffix, suffix_len, dir.f.cFileName,
|
|
||||||
(dir.f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)) < 0)
|
|
||||||
goto clean_up_and_exit;
|
|
||||||
|
|
||||||
git_vector_insert(contents, ps);
|
|
||||||
|
|
||||||
/* skip stat if before start_stat or after end_stat */
|
|
||||||
cmp_len = min(start_len, ps->path_len);
|
|
||||||
if (cmp_len && strncomp(ps->path, start_stat, cmp_len) < 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
cmp_len = min(end_len, ps->path_len);
|
|
||||||
if (cmp_len && strncomp(ps->path, end_stat, cmp_len) > 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if ((error = git_win32__file_attribute_to_stat(&ps->st,
|
|
||||||
(WIN32_FILE_ATTRIBUTE_DATA *)&dir.f, file_path)) < 0) {
|
|
||||||
goto clean_up_and_exit;
|
|
||||||
}
|
|
||||||
} while (FindNextFileW(dir.h, &dir.f));
|
|
||||||
|
|
||||||
if (GetLastError() != ERROR_NO_MORE_FILES) {
|
|
||||||
error = -1;
|
|
||||||
giterr_set(GITERR_OS, "Could not get attributes for file in '%s'", path);
|
|
||||||
goto clean_up_and_exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* sort now that directory suffix is added */
|
|
||||||
git_vector_sort(contents);
|
|
||||||
|
|
||||||
clean_up_and_exit:
|
|
||||||
if (dir.h != INVALID_HANDLE_VALUE)
|
|
||||||
FindClose(dir.h);
|
|
||||||
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static bool path_is_volume(wchar_t *target, size_t target_len)
|
static bool path_is_volume(wchar_t *target, size_t target_len)
|
||||||
{
|
{
|
||||||
return (target_len && wcsncmp(target, L"\\??\\Volume{", 11) == 0);
|
return (target_len && wcsncmp(target, L"\\??\\Volume{", 11) == 0);
|
||||||
|
@ -80,30 +80,6 @@ extern int git_win32_path_to_utf8(git_win32_utf8_path dest, const wchar_t *src);
|
|||||||
*/
|
*/
|
||||||
extern char *git_win32_path_8dot3_name(const char *path);
|
extern char *git_win32_path_8dot3_name(const char *path);
|
||||||
|
|
||||||
#if !defined(__MINGW32__)
|
|
||||||
/**
|
|
||||||
* Load all directory entries along with stat info into a vector.
|
|
||||||
* Performed in a single pass per directory for optimized performance on Windows.
|
|
||||||
*
|
|
||||||
* This adds four things on top of plain `git_path_dirload`:
|
|
||||||
*
|
|
||||||
* 1. Each entry in the vector is a `git_path_with_stat` struct that
|
|
||||||
* contains both the path and the stat info
|
|
||||||
* 2. The entries will be sorted alphabetically
|
|
||||||
* 3. Entries that are directories will be suffixed with a '/'
|
|
||||||
* 4. Optionally, you can be a start and end prefix and only elements
|
|
||||||
* after the start and before the end (inclusively) will be stat'ed.
|
|
||||||
*
|
|
||||||
* @param path The directory to read from
|
|
||||||
* @param prefix_len The trailing part of path to prefix to entry paths
|
|
||||||
* @param flags GIT_PATH_DIR flags from above
|
|
||||||
* @param start_stat As optimization, only stat values after this prefix
|
|
||||||
* @param end_stat As optimization, only stat values before this prefix
|
|
||||||
* @param contents Vector to fill with git_path_with_stat structures
|
|
||||||
*/
|
|
||||||
extern int git_win32_path_dirload_with_stat(const char *path, size_t prefix_len, unsigned int flags, const char *start_stat, const char *end_stat, git_vector *contents);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern int git_win32_path_readlink_w(git_win32_path dest, const git_win32_path path);
|
extern int git_win32_path_readlink_w(git_win32_path dest, const git_win32_path path);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user