diff options
| author | Edward Thomson <ethomson@edwardthomson.com> | 2021-05-05 23:01:57 +0100 |
|---|---|---|
| committer | Edward Thomson <ethomson@edwardthomson.com> | 2021-05-05 23:11:52 +0100 |
| commit | 5368be3053d311cb7c65d44ce6643b5de32694ec (patch) | |
| tree | 801211f7d1a0a2a5de46a4ebb56ba04b5e53a823 | |
| parent | 525516b419eabcfafb80c3694fb5f82656a0bc97 (diff) | |
| download | libgit2-5368be3053d311cb7c65d44ce6643b5de32694ec.tar.gz | |
clar: support long paths on Windows
| -rw-r--r-- | tests/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | tests/clar/fs.h | 80 |
2 files changed, 61 insertions, 20 deletions
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 6f8a18ec0..4d8732d23 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -9,6 +9,7 @@ SET(CLAR_FIXTURES "${CMAKE_CURRENT_SOURCE_DIR}/resources/") SET(CLAR_PATH "${CMAKE_CURRENT_SOURCE_DIR}") ADD_DEFINITIONS(-DCLAR_FIXTURE_PATH=\"${CLAR_FIXTURES}\") ADD_DEFINITIONS(-DCLAR_TMPDIR=\"libgit2_tests\") +ADD_DEFINITIONS(-DCLAR_WIN32_LONGPATHS) ADD_DEFINITIONS(-D_FILE_OFFSET_BITS=64) # Ensure that we do not use deprecated functions internally diff --git a/tests/clar/fs.h b/tests/clar/fs.h index d88f249c7..44ede4572 100644 --- a/tests/clar/fs.h +++ b/tests/clar/fs.h @@ -8,6 +8,12 @@ #ifdef _WIN32 +#ifdef CLAR_WIN32_LONGPATHS +# define CLAR_MAX_PATH 4096 +#else +# define CLAR_MAX_PATH MAX_PATH +#endif + #define RM_RETRY_COUNT 5 #define RM_RETRY_DELAY 10 @@ -48,21 +54,48 @@ fs_rmdir_rmdir(WCHAR *_wpath) return 0; } +static void translate_path(WCHAR *path, size_t path_size) +{ + size_t path_len, i; + + if (wcsncmp(path, L"\\\\?\\", 4) == 0) + return; + + path_len = wcslen(path); + cl_assert(path_size > path_len + 4); + + for (i = path_len; i > 0; i--) { + WCHAR c = path[i - 1]; + + if (c == L'/') + path[i + 3] = L'\\'; + else + path[i + 3] = path[i - 1]; + } + + path[0] = L'\\'; + path[1] = L'\\'; + path[2] = L'?'; + path[3] = L'\\'; + path[path_len + 4] = L'\0'; +} + static void fs_rmdir_helper(WCHAR *_wsource) { - WCHAR buffer[MAX_PATH]; + WCHAR buffer[CLAR_MAX_PATH]; HANDLE find_handle; WIN32_FIND_DATAW find_data; size_t buffer_prefix_len; /* Set up the buffer and capture the length */ - wcscpy_s(buffer, MAX_PATH, _wsource); - wcscat_s(buffer, MAX_PATH, L"\\"); + wcscpy_s(buffer, CLAR_MAX_PATH, _wsource); + translate_path(buffer, CLAR_MAX_PATH); + wcscat_s(buffer, CLAR_MAX_PATH, L"\\"); buffer_prefix_len = wcslen(buffer); /* FindFirstFile needs a wildcard to match multiple items */ - wcscat_s(buffer, MAX_PATH, L"*"); + wcscat_s(buffer, CLAR_MAX_PATH, L"*"); find_handle = FindFirstFileW(buffer, &find_data); cl_assert(INVALID_HANDLE_VALUE != find_handle); @@ -72,7 +105,7 @@ fs_rmdir_helper(WCHAR *_wsource) if (fs__dotordotdot(find_data.cFileName)) continue; - wcscpy_s(buffer + buffer_prefix_len, MAX_PATH - buffer_prefix_len, find_data.cFileName); + wcscpy_s(buffer + buffer_prefix_len, CLAR_MAX_PATH - buffer_prefix_len, find_data.cFileName); if (FILE_ATTRIBUTE_DIRECTORY & find_data.dwFileAttributes) fs_rmdir_helper(buffer); @@ -123,7 +156,7 @@ fs_rm_wait(WCHAR *_wpath) static void fs_rm(const char *_source) { - WCHAR wsource[MAX_PATH]; + WCHAR wsource[CLAR_MAX_PATH]; DWORD attrs; /* The input path is UTF-8. Convert it to wide characters @@ -133,7 +166,9 @@ fs_rm(const char *_source) _source, -1, /* Indicates NULL termination */ wsource, - MAX_PATH)); + CLAR_MAX_PATH)); + + translate_path(wsource, CLAR_MAX_PATH); /* Does the item exist? If not, we have no work to do */ attrs = GetFileAttributesW(wsource); @@ -158,21 +193,23 @@ fs_rm(const char *_source) static void fs_copydir_helper(WCHAR *_wsource, WCHAR *_wdest) { - WCHAR buf_source[MAX_PATH], buf_dest[MAX_PATH]; + WCHAR buf_source[CLAR_MAX_PATH], buf_dest[CLAR_MAX_PATH]; HANDLE find_handle; WIN32_FIND_DATAW find_data; size_t buf_source_prefix_len, buf_dest_prefix_len; - wcscpy_s(buf_source, MAX_PATH, _wsource); - wcscat_s(buf_source, MAX_PATH, L"\\"); + wcscpy_s(buf_source, CLAR_MAX_PATH, _wsource); + wcscat_s(buf_source, CLAR_MAX_PATH, L"\\"); + translate_path(buf_source, CLAR_MAX_PATH); buf_source_prefix_len = wcslen(buf_source); - wcscpy_s(buf_dest, MAX_PATH, _wdest); - wcscat_s(buf_dest, MAX_PATH, L"\\"); + wcscpy_s(buf_dest, CLAR_MAX_PATH, _wdest); + wcscat_s(buf_dest, CLAR_MAX_PATH, L"\\"); + translate_path(buf_dest, CLAR_MAX_PATH); buf_dest_prefix_len = wcslen(buf_dest); /* Get an enumerator for the items in the source. */ - wcscat_s(buf_source, MAX_PATH, L"*"); + wcscat_s(buf_source, CLAR_MAX_PATH, L"*"); find_handle = FindFirstFileW(buf_source, &find_data); cl_assert(INVALID_HANDLE_VALUE != find_handle); @@ -185,8 +222,8 @@ fs_copydir_helper(WCHAR *_wsource, WCHAR *_wdest) if (fs__dotordotdot(find_data.cFileName)) continue; - wcscpy_s(buf_source + buf_source_prefix_len, MAX_PATH - buf_source_prefix_len, find_data.cFileName); - wcscpy_s(buf_dest + buf_dest_prefix_len, MAX_PATH - buf_dest_prefix_len, find_data.cFileName); + wcscpy_s(buf_source + buf_source_prefix_len, CLAR_MAX_PATH - buf_source_prefix_len, find_data.cFileName); + wcscpy_s(buf_dest + buf_dest_prefix_len, CLAR_MAX_PATH - buf_dest_prefix_len, find_data.cFileName); if (FILE_ATTRIBUTE_DIRECTORY & find_data.dwFileAttributes) fs_copydir_helper(buf_source, buf_dest); @@ -205,7 +242,7 @@ fs_copydir_helper(WCHAR *_wsource, WCHAR *_wdest) static void fs_copy(const char *_source, const char *_dest) { - WCHAR wsource[MAX_PATH], wdest[MAX_PATH]; + WCHAR wsource[CLAR_MAX_PATH], wdest[CLAR_MAX_PATH]; DWORD source_attrs, dest_attrs; HANDLE find_handle; WIN32_FIND_DATAW find_data; @@ -217,14 +254,17 @@ fs_copy(const char *_source, const char *_dest) _source, -1, wsource, - MAX_PATH)); + CLAR_MAX_PATH)); cl_assert(MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, _dest, -1, wdest, - MAX_PATH)); + CLAR_MAX_PATH)); + + translate_path(wsource, CLAR_MAX_PATH); + translate_path(wdest, CLAR_MAX_PATH); /* Check the source for existence */ source_attrs = GetFileAttributesW(wsource); @@ -238,8 +278,8 @@ fs_copy(const char *_source, const char *_dest) * Use FindFirstFile to parse the path */ find_handle = FindFirstFileW(wsource, &find_data); cl_assert(INVALID_HANDLE_VALUE != find_handle); - wcscat_s(wdest, MAX_PATH, L"\\"); - wcscat_s(wdest, MAX_PATH, find_data.cFileName); + wcscat_s(wdest, CLAR_MAX_PATH, L"\\"); + wcscat_s(wdest, CLAR_MAX_PATH, find_data.cFileName); FindClose(find_handle); /* Check the new target for existence */ |
