mirror of
https://github.com/transmission/transmission
synced 2024-12-21 15:22:37 +00:00
Add CI configuration for clang-tidy on Windows (#6997)
* Add CI configuration for clang-tidy on Windows * Fix issues reported by clang-tidy on Windows * Workaround clang-tidy defects on Windows * Fix C-style casts (which clang-tidy didn't report)
This commit is contained in:
parent
e334f3c37f
commit
c21ee87eea
19 changed files with 331 additions and 218 deletions
61
.github/actions/prepare-deps-win32/action.yml
vendored
Normal file
61
.github/actions/prepare-deps-win32/action.yml
vendored
Normal file
|
@ -0,0 +1,61 @@
|
|||
name: Prepare Win32 build dependencies
|
||||
inputs:
|
||||
arch:
|
||||
description: Architecture (x86, x64)
|
||||
required: true
|
||||
type:
|
||||
description: Type (CoreDeps, Deps)
|
||||
required: true
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Get Build Tools
|
||||
shell: pwsh
|
||||
run: |
|
||||
$DepsPrefix = (Join-Path (Get-Item .).Root.Name "${{ inputs.arch }}-prefix")
|
||||
"DEPS_PREFIX=${DepsPrefix}" | Out-File $Env:GITHUB_ENV -Append
|
||||
(Join-Path $DepsPrefix bin) | Out-File $Env:GITHUB_PATH -Append
|
||||
|
||||
choco install `
|
||||
jom `
|
||||
nasm `
|
||||
nodejs
|
||||
& "C:\Program Files\OpenSSL\unins000.exe" /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP- | Out-Host
|
||||
(Join-Path $Env:ProgramFiles NASM) | Out-File $Env:GITHUB_PATH -Append
|
||||
(Join-Path (Get-Item -Path "${Env:ProgramFiles(x86)}\WiX Toolset v3.*")[0].FullName bin) | Out-File $Env:GITHUB_PATH -Append
|
||||
|
||||
Install-Module -Name Pscx -RequiredVersion 4.0.0-beta4 -AllowPrerelease -Force
|
||||
- name: Get Cache Key
|
||||
id: cache-key
|
||||
shell: pwsh
|
||||
run: |
|
||||
try {
|
||||
$DepsHash = & (Join-Path . src release windows main.ps1) -Mode DepsHash -BuildArch ${{ inputs.arch }} -BuildPart ${{ inputs.type }}
|
||||
"hash=${DepsHash}" | Out-File $Env:GITHUB_OUTPUT -Append
|
||||
} catch {
|
||||
Write-Error ("{1}{0}{2}{0}{3}" -f [Environment]::NewLine, $_.ToString(), $_.InvocationInfo.PositionMessage, $_.ScriptStackTrace) -ErrorAction Continue
|
||||
exit 1
|
||||
}
|
||||
- name: Restore Cache
|
||||
uses: actions/cache/restore@v4
|
||||
id: restore-cache
|
||||
with:
|
||||
path: ${{ env.DEPS_PREFIX }}
|
||||
key: ${{ github.job }}-${{ inputs.arch }}-${{ steps.cache-key.outputs.hash }}
|
||||
- name: Build Dependencies
|
||||
if: steps.restore-cache.outputs.cache-hit != 'true'
|
||||
shell: pwsh
|
||||
run: |
|
||||
try {
|
||||
& (Join-Path . src release windows main.ps1) -Mode Build -BuildArch ${{ inputs.arch }} -BuildPart ${{ inputs.type }}
|
||||
} catch {
|
||||
Write-Error ("{1}{0}{2}{0}{3}" -f [Environment]::NewLine, $_.ToString(), $_.InvocationInfo.PositionMessage, $_.ScriptStackTrace) -ErrorAction Continue
|
||||
exit 1
|
||||
}
|
||||
- name: Save Cache
|
||||
if: steps.restore-cache.outputs.cache-hit != 'true'
|
||||
uses: actions/cache/save@v4
|
||||
id: cache
|
||||
with:
|
||||
path: ${{ env.DEPS_PREFIX }}
|
||||
key: ${{ github.job }}-${{ inputs.arch }}-${{ steps.cache-key.outputs.hash }}
|
80
.github/workflows/actions.yml
vendored
80
.github/workflows/actions.yml
vendored
|
@ -272,6 +272,43 @@ jobs:
|
|||
run: |
|
||||
if grep 'warning:' makelog; then exit 1; fi
|
||||
|
||||
clang-tidy-libtransmission-win32:
|
||||
runs-on: windows-2022
|
||||
needs: [ what-to-make ]
|
||||
if: ${{ needs.what-to-make.outputs.test-style == 'true' }}
|
||||
steps:
|
||||
- name: Show Configuration
|
||||
run: |
|
||||
echo '${{ toJSON(needs) }}'
|
||||
echo '${{ toJSON(runner) }}'
|
||||
- name: Get Source
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
path: src
|
||||
- name: Prepare Build Deps
|
||||
uses: ./src/.github/actions/prepare-deps-win32
|
||||
with:
|
||||
arch: x64
|
||||
type: CoreDeps
|
||||
- name: Configure
|
||||
run: |
|
||||
Import-VisualStudioVars -VisualStudioVersion 2022 -Architecture x64
|
||||
cmake `
|
||||
-S src `
|
||||
-B obj `
|
||||
-G Ninja `
|
||||
-DCMAKE_BUILD_TYPE=Debug `
|
||||
-DCMAKE_PREFIX_PATH="${Env:DEPS_PREFIX}" `
|
||||
-DRUN_CLANG_TIDY=ON
|
||||
- name: Make
|
||||
run: |
|
||||
Import-VisualStudioVars -VisualStudioVersion 2022 -Architecture x64
|
||||
cmake --build obj --config Debug --target transmission.lib 2>&1 | tee makelog
|
||||
- name: Test for warnings
|
||||
run: |
|
||||
if (Select-String -Path makelog -Pattern 'warning:') { exit 1 }
|
||||
|
||||
macos-14-arm64:
|
||||
runs-on: macos-14
|
||||
needs: [ what-to-make ]
|
||||
|
@ -458,51 +495,16 @@ jobs:
|
|||
run: |
|
||||
echo '${{ toJSON(needs) }}'
|
||||
echo '${{ toJSON(runner) }}'
|
||||
- name: Get Build Tools
|
||||
run: |
|
||||
$DepsPrefix = (Join-Path (Get-Item .).Root.Name "${{ matrix.arch }}-prefix")
|
||||
"DEPS_PREFIX=${DepsPrefix}" | Out-File $Env:GITHUB_ENV -Append
|
||||
(Join-Path $DepsPrefix bin) | Out-File $Env:GITHUB_PATH -Append
|
||||
|
||||
choco install `
|
||||
jom `
|
||||
nasm `
|
||||
nodejs
|
||||
& "C:\Program Files\OpenSSL\unins000.exe" /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP- | Out-Host
|
||||
(Join-Path $Env:ProgramFiles NASM) | Out-File $Env:GITHUB_PATH -Append
|
||||
(Join-Path (Get-Item -Path "${Env:ProgramFiles(x86)}\WiX Toolset v3.*")[0].FullName bin) | Out-File $Env:GITHUB_PATH -Append
|
||||
|
||||
Install-Module -Name Pscx -RequiredVersion 4.0.0-beta4 -AllowPrerelease -Force
|
||||
- name: Get Source
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
path: src
|
||||
submodules: recursive
|
||||
- name: Get Cache Key
|
||||
id: cache-key
|
||||
run: |
|
||||
try {
|
||||
$DepsHash = & (Join-Path . src release windows main.ps1) -Mode DepsHash -BuildArch ${{ matrix.arch }}
|
||||
"hash=${DepsHash}" | Out-File $Env:GITHUB_OUTPUT -Append
|
||||
} catch {
|
||||
Write-Error ("{1}{0}{2}{0}{3}" -f [Environment]::NewLine, $_.ToString(), $_.InvocationInfo.PositionMessage, $_.ScriptStackTrace) -ErrorAction Continue
|
||||
exit 1
|
||||
}
|
||||
- name: Get Cache
|
||||
uses: actions/cache@v4
|
||||
id: cache
|
||||
- name: Prepare Build Deps
|
||||
uses: ./src/.github/actions/prepare-deps-win32
|
||||
with:
|
||||
path: ${{ env.DEPS_PREFIX }}
|
||||
key: ${{ github.job }}-${{ matrix.arch }}-${{ steps.cache-key.outputs.hash }}
|
||||
- name: Build Dependencies
|
||||
if: steps.cache.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
try {
|
||||
& (Join-Path . src release windows main.ps1) -Mode Build -BuildArch ${{ matrix.arch }} -BuildPart Deps
|
||||
} catch {
|
||||
Write-Error ("{1}{0}{2}{0}{3}" -f [Environment]::NewLine, $_.ToString(), $_.InvocationInfo.PositionMessage, $_.ScriptStackTrace) -ErrorAction Continue
|
||||
exit 1
|
||||
}
|
||||
arch: ${{ matrix.arch }}
|
||||
type: Deps
|
||||
- name: Configure
|
||||
run: |
|
||||
Import-VisualStudioVars -VisualStudioVersion 2022 -Architecture ${{ matrix.arch }}
|
||||
|
|
|
@ -14,20 +14,32 @@
|
|||
#define ERROR_DIRECTORY_NOT_SUPPORTED 336
|
||||
#endif
|
||||
|
||||
#define TR_ERROR_IS_ENOENT(code) ((code) == ERROR_FILE_NOT_FOUND || (code) == ERROR_PATH_NOT_FOUND)
|
||||
#define TR_ERROR_IS_ENOSPC(code) ((code) == ERROR_DISK_FULL)
|
||||
|
||||
#define TR_ERROR_EINVAL ERROR_INVALID_PARAMETER
|
||||
#define TR_ERROR_EISDIR ERROR_DIRECTORY_NOT_SUPPORTED
|
||||
|
||||
#else /* _WIN32 */
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#define TR_ERROR_IS_ENOENT(code) ((code) == ENOENT)
|
||||
#define TR_ERROR_IS_ENOSPC(code) ((code) == ENOSPC)
|
||||
#include <cerrno>
|
||||
|
||||
#define TR_ERROR_EINVAL EINVAL
|
||||
#define TR_ERROR_EISDIR EISDIR
|
||||
|
||||
#endif /* _WIN32 */
|
||||
|
||||
constexpr inline bool tr_error_is_enoent(int code) noexcept
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return code == ERROR_FILE_NOT_FOUND || code == ERROR_PATH_NOT_FOUND;
|
||||
#else
|
||||
return code == ENOENT;
|
||||
#endif
|
||||
}
|
||||
|
||||
constexpr inline bool tr_error_is_enospc(int code) noexcept
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return code == ERROR_DISK_FULL;
|
||||
#else
|
||||
return code == ENOSPC;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -452,13 +452,13 @@ extern "C"
|
|||
|
||||
if (auto const wide_path = tr_win32_utf8_to_native(path); !std::empty(wide_path))
|
||||
{
|
||||
ULARGE_INTEGER freeBytesAvailable;
|
||||
ULARGE_INTEGER totalBytesAvailable;
|
||||
ULARGE_INTEGER free_bytes_available;
|
||||
ULARGE_INTEGER total_bytes_available;
|
||||
|
||||
if (GetDiskFreeSpaceExW(wide_path.c_str(), &freeBytesAvailable, &totalBytesAvailable, nullptr))
|
||||
if (GetDiskFreeSpaceExW(wide_path.c_str(), &free_bytes_available, &total_bytes_available, nullptr) != 0)
|
||||
{
|
||||
ret.free = freeBytesAvailable.QuadPart;
|
||||
ret.total = totalBytesAvailable.QuadPart;
|
||||
ret.free = free_bytes_available.QuadPart;
|
||||
ret.total = total_bytes_available.QuadPart;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -27,14 +27,6 @@
|
|||
|
||||
using namespace std::literals;
|
||||
|
||||
#ifndef MAXSIZE_T
|
||||
#define MAXSIZE_T ((SIZE_T) ~((SIZE_T)0))
|
||||
#endif
|
||||
|
||||
/* MSDN (http://msdn.microsoft.com/en-us/library/2k2xf226.aspx) only mentions
|
||||
"i64" suffix for C code, but no warning is issued */
|
||||
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL
|
||||
|
||||
struct tr_sys_dir_win32
|
||||
{
|
||||
std::wstring pattern;
|
||||
|
@ -45,6 +37,8 @@ struct tr_sys_dir_win32
|
|||
|
||||
namespace
|
||||
{
|
||||
auto constexpr DeltaEpochInMicrosecs = UINT64_C(11644473600000000);
|
||||
|
||||
auto constexpr NativeLocalPathPrefix = L"\\\\?\\"sv;
|
||||
auto constexpr NativeUncPathPrefix = L"\\\\?\\UNC\\"sv;
|
||||
|
||||
|
@ -72,11 +66,16 @@ constexpr time_t filetime_to_unix_time(FILETIME const& t)
|
|||
tmp <<= 32;
|
||||
tmp |= t.dwLowDateTime;
|
||||
tmp /= 10; /* to microseconds */
|
||||
tmp -= DELTA_EPOCH_IN_MICROSECS;
|
||||
tmp -= DeltaEpochInMicrosecs;
|
||||
|
||||
return tmp / 1000000UL;
|
||||
}
|
||||
|
||||
constexpr bool to_bool(BOOL value) noexcept
|
||||
{
|
||||
return value != FALSE;
|
||||
}
|
||||
|
||||
constexpr auto stat_to_sys_path_info(DWORD attributes, DWORD size_low, DWORD size_high, FILETIME const& mtime)
|
||||
{
|
||||
auto info = tr_sys_path_info{};
|
||||
|
@ -103,7 +102,7 @@ constexpr auto stat_to_sys_path_info(DWORD attributes, DWORD size_low, DWORD siz
|
|||
return info;
|
||||
}
|
||||
|
||||
auto constexpr Slashes = "\\/"sv;
|
||||
auto constexpr Slashes = R"(\/)"sv;
|
||||
|
||||
constexpr bool is_slash(char c)
|
||||
{
|
||||
|
@ -119,27 +118,22 @@ bool is_valid_path(std::string_view path)
|
|||
{
|
||||
if (is_unc_path(path))
|
||||
{
|
||||
if (path[2] != '\0' && !isalnum(path[2]))
|
||||
if (path[2] != '\0' && isalnum(path[2]) == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (auto const pos = path.find(':'); pos != std::string_view::npos)
|
||||
{
|
||||
auto pos = path.find(':');
|
||||
|
||||
if (pos != path.npos)
|
||||
if (pos != 1 || isalpha(path[0]) == 0)
|
||||
{
|
||||
if (pos != 1 || !isalpha(path[0]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
path.remove_prefix(2);
|
||||
return false;
|
||||
}
|
||||
|
||||
path.remove_prefix(2);
|
||||
}
|
||||
|
||||
return path.find_first_of("<>:\"|?*"sv) == path.npos;
|
||||
return path.find_first_of(R"(<>:"|?*)"sv) == std::string_view::npos;
|
||||
}
|
||||
|
||||
auto path_to_fixed_native_path(std::string_view path)
|
||||
|
@ -200,7 +194,7 @@ std::string native_path_to_path(std::wstring_view wide_path)
|
|||
{
|
||||
wide_path.remove_prefix(std::size(NativeUncPathPrefix));
|
||||
auto path = tr_win32_native_to_utf8(wide_path);
|
||||
path.insert(0, "\\\\"sv);
|
||||
path.insert(0, R"(\\)"sv);
|
||||
return path;
|
||||
}
|
||||
|
||||
|
@ -239,7 +233,7 @@ tr_sys_file_t open_file(std::string_view path, DWORD access, DWORD disposition,
|
|||
|
||||
bool create_dir(std::string_view path, int flags, int /*permissions*/, bool okay_if_exists, tr_error* error)
|
||||
{
|
||||
bool ret;
|
||||
bool ret = false;
|
||||
DWORD error_code = ERROR_SUCCESS;
|
||||
auto const wide_path = path_to_native_path(path);
|
||||
|
||||
|
@ -256,7 +250,7 @@ bool create_dir(std::string_view path, int flags, int /*permissions*/, bool okay
|
|||
}
|
||||
else
|
||||
{
|
||||
ret = CreateDirectoryW(wide_path.c_str(), nullptr);
|
||||
ret = to_bool(CreateDirectoryW(wide_path.c_str(), nullptr));
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
|
@ -282,14 +276,10 @@ bool create_dir(std::string_view path, int flags, int /*permissions*/, bool okay
|
|||
return ret;
|
||||
}
|
||||
|
||||
void create_temp_path(
|
||||
char* path_template,
|
||||
void (*callback)(char const* path, void* param, tr_error* error),
|
||||
void* callback_param,
|
||||
tr_error* error)
|
||||
template<typename CallbackT>
|
||||
void create_temp_path(char* path_template, CallbackT&& callback, tr_error* error)
|
||||
{
|
||||
TR_ASSERT(path_template != nullptr);
|
||||
TR_ASSERT(callback != nullptr);
|
||||
|
||||
auto path = std::string{ path_template };
|
||||
auto path_size = std::size(path);
|
||||
|
@ -313,7 +303,7 @@ void create_temp_path(
|
|||
|
||||
local_error = {};
|
||||
|
||||
(*callback)(path.c_str(), callback_param, &local_error);
|
||||
callback(path.c_str(), &local_error);
|
||||
|
||||
if (!local_error)
|
||||
{
|
||||
|
@ -336,7 +326,7 @@ std::optional<tr_sys_path_info> tr_sys_file_get_info_(tr_sys_file_t handle, tr_e
|
|||
TR_ASSERT(handle != TR_BAD_SYS_FILE);
|
||||
|
||||
auto attributes = BY_HANDLE_FILE_INFORMATION{};
|
||||
if (GetFileInformationByHandle(handle, &attributes))
|
||||
if (to_bool(GetFileInformationByHandle(handle, &attributes)))
|
||||
{
|
||||
return stat_to_sys_path_info(
|
||||
attributes.dwFileAttributes,
|
||||
|
@ -367,7 +357,7 @@ std::optional<BY_HANDLE_FILE_INFORMATION> get_file_info(char const* path, tr_err
|
|||
|
||||
// TODO: Use GetFileInformationByHandleEx on >= Server 2012
|
||||
auto info = BY_HANDLE_FILE_INFORMATION{};
|
||||
if (!GetFileInformationByHandle(handle, &info))
|
||||
if (!to_bool(GetFileInformationByHandle(handle, &info)))
|
||||
{
|
||||
set_system_error_if_file_found(error, GetLastError());
|
||||
CloseHandle(handle);
|
||||
|
@ -378,23 +368,6 @@ std::optional<BY_HANDLE_FILE_INFORMATION> get_file_info(char const* path, tr_err
|
|||
return info;
|
||||
}
|
||||
|
||||
void file_open_temp_callback(char const* path, void* param, tr_error* error)
|
||||
{
|
||||
auto* const result = static_cast<tr_sys_file_t*>(param);
|
||||
|
||||
TR_ASSERT(result != nullptr);
|
||||
|
||||
*result = open_file(path, GENERIC_READ | GENERIC_WRITE, CREATE_NEW, FILE_ATTRIBUTE_TEMPORARY, error);
|
||||
}
|
||||
|
||||
void dir_create_temp_callback(char const* path, void* param, tr_error* error)
|
||||
{
|
||||
auto* const result = static_cast<bool*>(param);
|
||||
|
||||
TR_ASSERT(result != nullptr);
|
||||
|
||||
*result = create_dir(path, 0, 0, false, error);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
bool tr_sys_path_exists(char const* path, tr_error* error)
|
||||
|
@ -406,7 +379,7 @@ bool tr_sys_path_exists(char const* path, tr_error* error)
|
|||
|
||||
if (auto const wide_path = path_to_native_path(path); !std::empty(wide_path))
|
||||
{
|
||||
DWORD attributes = GetFileAttributesW(wide_path.c_str());
|
||||
DWORD const attributes = GetFileAttributesW(wide_path.c_str());
|
||||
|
||||
if (attributes != INVALID_FILE_ATTRIBUTES)
|
||||
{
|
||||
|
@ -444,7 +417,7 @@ std::optional<tr_sys_path_info> tr_sys_path_get_info(std::string_view path, int
|
|||
else if ((flags & TR_SYS_PATH_NO_FOLLOW) != 0)
|
||||
{
|
||||
auto attributes = WIN32_FILE_ATTRIBUTE_DATA{};
|
||||
if (GetFileAttributesExW(wide_path.c_str(), GetFileExInfoStandard, &attributes))
|
||||
if (to_bool(GetFileAttributesExW(wide_path.c_str(), GetFileExInfoStandard, &attributes)))
|
||||
{
|
||||
return stat_to_sys_path_info(
|
||||
attributes.dwFileAttributes,
|
||||
|
@ -475,13 +448,13 @@ bool tr_sys_path_is_relative(std::string_view path)
|
|||
}
|
||||
|
||||
/* Local path: `X:` */
|
||||
if (std::size(path) == 2 && isalpha(path[0]) && path[1] == ':')
|
||||
if (std::size(path) == 2 && isalpha(path[0]) != 0 && path[1] == ':')
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Local path: `X:\...`. */
|
||||
if (std::size(path) > 2 && isalpha(path[0]) && path[1] == ':' && is_slash(path[2]))
|
||||
if (std::size(path) > 2 && isalpha(path[0]) != 0 && path[1] == ':' && is_slash(path[2]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -584,15 +557,18 @@ std::string_view tr_sys_path_basename(std::string_view path, tr_error* error)
|
|||
return !std::empty(path) ? path : "/"sv;
|
||||
}
|
||||
|
||||
[[nodiscard]] static bool isWindowsDeviceRoot(char ch) noexcept
|
||||
namespace
|
||||
{
|
||||
[[nodiscard]] bool isWindowsDeviceRoot(char ch) noexcept
|
||||
{
|
||||
return isalpha(static_cast<int>(ch)) != 0;
|
||||
}
|
||||
|
||||
[[nodiscard]] static constexpr bool isPathSeparator(char ch) noexcept
|
||||
[[nodiscard]] constexpr bool isPathSeparator(char ch) noexcept
|
||||
{
|
||||
return ch == '/' || ch == '\\';
|
||||
}
|
||||
} // namespace
|
||||
|
||||
// This function is adapted from Node.js's path.win32.dirname() function,
|
||||
// which is copyrighted by Joyent, Inc. and other Node contributors
|
||||
|
@ -674,7 +650,7 @@ std::string_view tr_sys_path_dirname(std::string_view path)
|
|||
}
|
||||
|
||||
auto end = std::string_view::npos;
|
||||
auto matched_slash = bool{ true };
|
||||
auto matched_slash = true;
|
||||
for (std::string_view::size_type i = len - 1; i >= offset; --i)
|
||||
{
|
||||
if (isPathSeparator(path[i]))
|
||||
|
@ -720,25 +696,19 @@ bool tr_sys_path_rename(char const* src_path, char const* dst_path, tr_error* er
|
|||
if (!std::empty(wide_src_path) && !std::empty(wide_dst_path))
|
||||
{
|
||||
DWORD flags = MOVEFILE_REPLACE_EXISTING;
|
||||
DWORD attributes;
|
||||
|
||||
attributes = GetFileAttributesW(wide_src_path.c_str());
|
||||
|
||||
if (attributes != INVALID_FILE_ATTRIBUTES && (attributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
|
||||
if (auto const src_attributes = GetFileAttributesW(wide_src_path.c_str());
|
||||
src_attributes != INVALID_FILE_ATTRIBUTES && (src_attributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
|
||||
{
|
||||
flags = 0;
|
||||
}
|
||||
else
|
||||
else if (auto const dst_attributes = GetFileAttributesW(wide_dst_path.c_str());
|
||||
dst_attributes != INVALID_FILE_ATTRIBUTES && (dst_attributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
|
||||
{
|
||||
attributes = GetFileAttributesW(wide_dst_path.c_str());
|
||||
|
||||
if (attributes != INVALID_FILE_ATTRIBUTES && (attributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
|
||||
{
|
||||
flags = 0;
|
||||
}
|
||||
flags = 0;
|
||||
}
|
||||
|
||||
ret = MoveFileExW(wide_src_path.c_str(), wide_dst_path.c_str(), flags);
|
||||
ret = to_bool(MoveFileExW(wide_src_path.c_str(), wide_dst_path.c_str(), flags));
|
||||
}
|
||||
|
||||
if (!ret)
|
||||
|
@ -764,7 +734,7 @@ bool tr_sys_path_copy(char const* src_path, char const* dst_path, tr_error* erro
|
|||
|
||||
auto cancel = BOOL{ FALSE };
|
||||
DWORD const flags = COPY_FILE_ALLOW_DECRYPTED_DESTINATION | COPY_FILE_FAIL_IF_EXISTS;
|
||||
if (CopyFileExW(wide_src_path.c_str(), wide_dst_path.c_str(), nullptr, nullptr, &cancel, flags) == 0)
|
||||
if (!to_bool(CopyFileExW(wide_src_path.c_str(), wide_dst_path.c_str(), nullptr, nullptr, &cancel, flags)))
|
||||
{
|
||||
set_system_error(error, GetLastError());
|
||||
return false;
|
||||
|
@ -787,11 +757,11 @@ bool tr_sys_path_remove(char const* path, tr_error* error)
|
|||
{
|
||||
if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
|
||||
{
|
||||
ret = RemoveDirectoryW(wide_path.c_str());
|
||||
ret = to_bool(RemoveDirectoryW(wide_path.c_str()));
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = DeleteFileW(wide_path.c_str());
|
||||
ret = to_bool(DeleteFileW(wide_path.c_str()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -824,11 +794,9 @@ tr_sys_file_t tr_sys_file_open(char const* path, int flags, int /*permissions*/,
|
|||
TR_ASSERT(path != nullptr);
|
||||
TR_ASSERT((flags & (TR_SYS_FILE_READ | TR_SYS_FILE_WRITE)) != 0);
|
||||
|
||||
tr_sys_file_t ret;
|
||||
DWORD native_access = 0;
|
||||
DWORD native_disposition = OPEN_EXISTING;
|
||||
DWORD native_flags = FILE_ATTRIBUTE_NORMAL;
|
||||
bool success;
|
||||
|
||||
if ((flags & TR_SYS_FILE_READ) != 0)
|
||||
{
|
||||
|
@ -854,9 +822,8 @@ tr_sys_file_t tr_sys_file_open(char const* path, int flags, int /*permissions*/,
|
|||
native_flags |= FILE_FLAG_SEQUENTIAL_SCAN;
|
||||
}
|
||||
|
||||
ret = open_file(path, native_access, native_disposition, native_flags, error);
|
||||
|
||||
success = ret != TR_BAD_SYS_FILE;
|
||||
auto ret = open_file(path, native_access, native_disposition, native_flags, error);
|
||||
auto success = ret != TR_BAD_SYS_FILE;
|
||||
|
||||
if (success && (flags & TR_SYS_FILE_APPEND) != 0)
|
||||
{
|
||||
|
@ -880,7 +847,11 @@ tr_sys_file_t tr_sys_file_open_temp(char* path_template, tr_error* error)
|
|||
|
||||
tr_sys_file_t ret = TR_BAD_SYS_FILE;
|
||||
|
||||
create_temp_path(path_template, file_open_temp_callback, &ret, error);
|
||||
create_temp_path(
|
||||
path_template,
|
||||
[&ret](char const* path, tr_error* error)
|
||||
{ ret = open_file(path, GENERIC_READ | GENERIC_WRITE, CREATE_NEW, FILE_ATTRIBUTE_TEMPORARY, error); },
|
||||
error);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -889,7 +860,7 @@ bool tr_sys_file_close(tr_sys_file_t handle, tr_error* error)
|
|||
{
|
||||
TR_ASSERT(handle != TR_BAD_SYS_FILE);
|
||||
|
||||
bool ret = CloseHandle(handle);
|
||||
bool const ret = to_bool(CloseHandle(handle));
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
|
@ -911,9 +882,9 @@ bool tr_sys_file_read(tr_sys_file_t handle, void* buffer, uint64_t size, uint64_
|
|||
}
|
||||
|
||||
bool ret = false;
|
||||
DWORD my_bytes_read;
|
||||
DWORD my_bytes_read = 0;
|
||||
|
||||
if (ReadFile(handle, buffer, (DWORD)size, &my_bytes_read, nullptr))
|
||||
if (to_bool(ReadFile(handle, buffer, static_cast<DWORD>(size), &my_bytes_read, nullptr)))
|
||||
{
|
||||
if (bytes_read != nullptr)
|
||||
{
|
||||
|
@ -948,15 +919,14 @@ bool tr_sys_file_read_at(
|
|||
}
|
||||
|
||||
bool ret = false;
|
||||
OVERLAPPED overlapped;
|
||||
DWORD my_bytes_read;
|
||||
auto overlapped = OVERLAPPED{};
|
||||
DWORD my_bytes_read = 0;
|
||||
|
||||
overlapped.Offset = (DWORD)offset;
|
||||
offset >>= 32;
|
||||
overlapped.OffsetHigh = (DWORD)offset;
|
||||
overlapped.Offset = static_cast<DWORD>(offset);
|
||||
overlapped.OffsetHigh = static_cast<DWORD>(offset >> 32);
|
||||
overlapped.hEvent = nullptr;
|
||||
|
||||
if (ReadFile(handle, buffer, (DWORD)size, &my_bytes_read, &overlapped))
|
||||
if (to_bool(ReadFile(handle, buffer, static_cast<DWORD>(size), &my_bytes_read, &overlapped)))
|
||||
{
|
||||
if (bytes_read != nullptr)
|
||||
{
|
||||
|
@ -985,9 +955,9 @@ bool tr_sys_file_write(tr_sys_file_t handle, void const* buffer, uint64_t size,
|
|||
}
|
||||
|
||||
bool ret = false;
|
||||
DWORD my_bytes_written;
|
||||
DWORD my_bytes_written = 0;
|
||||
|
||||
if (WriteFile(handle, buffer, (DWORD)size, &my_bytes_written, nullptr))
|
||||
if (to_bool(WriteFile(handle, buffer, static_cast<DWORD>(size), &my_bytes_written, nullptr)))
|
||||
{
|
||||
if (bytes_written != nullptr)
|
||||
{
|
||||
|
@ -1022,15 +992,14 @@ bool tr_sys_file_write_at(
|
|||
}
|
||||
|
||||
bool ret = false;
|
||||
OVERLAPPED overlapped;
|
||||
DWORD my_bytes_written;
|
||||
auto overlapped = OVERLAPPED{};
|
||||
DWORD my_bytes_written = 0;
|
||||
|
||||
overlapped.Offset = (DWORD)offset;
|
||||
offset >>= 32;
|
||||
overlapped.OffsetHigh = (DWORD)offset;
|
||||
overlapped.Offset = static_cast<DWORD>(offset);
|
||||
overlapped.OffsetHigh = static_cast<DWORD>(offset >> 32);
|
||||
overlapped.hEvent = nullptr;
|
||||
|
||||
if (WriteFile(handle, buffer, (DWORD)size, &my_bytes_written, &overlapped))
|
||||
if (to_bool(WriteFile(handle, buffer, static_cast<DWORD>(size), &my_bytes_written, &overlapped)))
|
||||
{
|
||||
if (bytes_written != nullptr)
|
||||
{
|
||||
|
@ -1054,7 +1023,7 @@ bool tr_sys_file_truncate(tr_sys_file_t handle, uint64_t size, tr_error* error)
|
|||
FILE_END_OF_FILE_INFO info;
|
||||
info.EndOfFile.QuadPart = size;
|
||||
|
||||
bool ret = SetFileInformationByHandle(handle, FileEndOfFileInfo, &info, sizeof(info));
|
||||
bool const ret = to_bool(SetFileInformationByHandle(handle, FileEndOfFileInfo, &info, sizeof(info)));
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
|
@ -1070,9 +1039,9 @@ bool tr_sys_file_preallocate(tr_sys_file_t handle, uint64_t size, int flags, tr_
|
|||
|
||||
if ((flags & TR_SYS_FILE_PREALLOC_SPARSE) != 0)
|
||||
{
|
||||
DWORD tmp;
|
||||
DWORD tmp = 0;
|
||||
|
||||
if (!DeviceIoControl(handle, FSCTL_SET_SPARSE, nullptr, 0, nullptr, 0, &tmp, nullptr))
|
||||
if (!to_bool(DeviceIoControl(handle, FSCTL_SET_SPARSE, nullptr, 0, nullptr, 0, &tmp, nullptr)))
|
||||
{
|
||||
set_system_error(error, GetLastError());
|
||||
return false;
|
||||
|
@ -1089,7 +1058,7 @@ bool tr_sys_file_lock(tr_sys_file_t handle, int operation, tr_error* error)
|
|||
TR_ASSERT(
|
||||
!!(operation & TR_SYS_FILE_LOCK_SH) + !!(operation & TR_SYS_FILE_LOCK_EX) + !!(operation & TR_SYS_FILE_LOCK_UN) == 1);
|
||||
|
||||
bool ret;
|
||||
bool ret = false;
|
||||
auto overlapped = OVERLAPPED{};
|
||||
|
||||
if ((operation & TR_SYS_FILE_LOCK_UN) == 0)
|
||||
|
@ -1150,7 +1119,10 @@ bool tr_sys_dir_create_temp(char* path_template, tr_error* error)
|
|||
|
||||
bool ret = false;
|
||||
|
||||
create_temp_path(path_template, dir_create_temp_callback, &ret, error);
|
||||
create_temp_path(
|
||||
path_template,
|
||||
[&ret](char const* path, tr_error* error) { ret = create_dir(path, 0, 0, false, error); },
|
||||
error);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -1195,7 +1167,7 @@ char const* tr_sys_dir_read_name(tr_sys_dir_t handle, tr_error* error)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (!FindNextFileW(handle->find_handle, &handle->find_data))
|
||||
if (!to_bool(FindNextFileW(handle->find_handle, &handle->find_data)))
|
||||
{
|
||||
error_code = GetLastError();
|
||||
}
|
||||
|
@ -1221,7 +1193,7 @@ bool tr_sys_dir_close(tr_sys_dir_t handle, tr_error* error)
|
|||
{
|
||||
TR_ASSERT(handle != TR_BAD_SYS_DIR);
|
||||
|
||||
bool ret = FindClose(handle->find_handle);
|
||||
bool const ret = to_bool(FindClose(handle->find_handle));
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
|
|
|
@ -46,7 +46,7 @@ bool preallocate_file_sparse(tr_sys_file_t fd, uint64_t length, tr_error* error)
|
|||
|
||||
tr_logAddDebug(fmt::format("Fast preallocation failed: {} ({})", local_error.message(), local_error.code()));
|
||||
|
||||
if (!TR_ERROR_IS_ENOSPC(local_error.code()))
|
||||
if (!tr_error_is_enospc(local_error.code()))
|
||||
{
|
||||
static char constexpr Zero = '\0';
|
||||
|
||||
|
@ -86,7 +86,7 @@ bool preallocate_file_full(tr_sys_file_t fd, uint64_t length, tr_error* error)
|
|||
|
||||
tr_logAddDebug(fmt::format("Full preallocation failed: {} ({})", local_error.message(), local_error.code()));
|
||||
|
||||
if (!TR_ERROR_IS_ENOSPC(local_error.code()))
|
||||
if (!tr_error_is_enospc(local_error.code()))
|
||||
{
|
||||
auto buf = std::array<uint8_t, 4096>{};
|
||||
bool success = true;
|
||||
|
|
|
@ -26,12 +26,12 @@ struct tr_peer;
|
|||
class ActiveRequests::Impl
|
||||
{
|
||||
public:
|
||||
size_t size() const
|
||||
[[nodiscard]] size_t size() const
|
||||
{
|
||||
return size_;
|
||||
}
|
||||
|
||||
size_t count(tr_peer const* peer) const
|
||||
[[nodiscard]] size_t count(tr_peer const* peer) const
|
||||
{
|
||||
auto const it = count_.find(peer);
|
||||
return it != std::end(count_) ? it->second : size_t{};
|
||||
|
|
|
@ -608,40 +608,40 @@ private:
|
|||
|
||||
// ---
|
||||
|
||||
size_t protocol_send_keepalive() const;
|
||||
size_t protocol_send_keepalive() const; // NOLINT(modernize-use-nodiscard)
|
||||
|
||||
template<typename... Args>
|
||||
size_t protocol_send_message(uint8_t type, Args const&... args) const;
|
||||
|
||||
size_t protocol_send_reject(peer_request const& req) const
|
||||
size_t protocol_send_reject(peer_request const& req) const // NOLINT(modernize-use-nodiscard)
|
||||
{
|
||||
TR_ASSERT(io_->supports_fext());
|
||||
return protocol_send_message(BtPeerMsgs::FextReject, req.index, req.offset, req.length);
|
||||
}
|
||||
|
||||
size_t protocol_send_cancel(peer_request const& req) const
|
||||
size_t protocol_send_cancel(peer_request const& req) const // NOLINT(modernize-use-nodiscard)
|
||||
{
|
||||
return protocol_send_message(BtPeerMsgs::Cancel, req.index, req.offset, req.length);
|
||||
}
|
||||
|
||||
size_t protocol_send_request(peer_request const& req) const
|
||||
size_t protocol_send_request(peer_request const& req) const // NOLINT(modernize-use-nodiscard)
|
||||
{
|
||||
TR_ASSERT(is_valid_request(req));
|
||||
return protocol_send_message(BtPeerMsgs::Request, req.index, req.offset, req.length);
|
||||
}
|
||||
|
||||
size_t protocol_send_dht_port(tr_port const port) const
|
||||
size_t protocol_send_dht_port(tr_port const port) const // NOLINT(modernize-use-nodiscard)
|
||||
{
|
||||
return protocol_send_message(BtPeerMsgs::DhtPort, port.host());
|
||||
}
|
||||
|
||||
size_t protocol_send_have(tr_piece_index_t const index) const
|
||||
size_t protocol_send_have(tr_piece_index_t const index) const // NOLINT(modernize-use-nodiscard)
|
||||
{
|
||||
static_assert(sizeof(tr_piece_index_t) == sizeof(uint32_t));
|
||||
return protocol_send_message(BtPeerMsgs::Have, index);
|
||||
}
|
||||
|
||||
size_t protocol_send_choke(bool const choke) const
|
||||
size_t protocol_send_choke(bool const choke) const // NOLINT(modernize-use-nodiscard)
|
||||
{
|
||||
return protocol_send_message(choke ? BtPeerMsgs::Choke : BtPeerMsgs::Unchoke);
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ namespace
|
|||
#ifdef _WIN32
|
||||
std::string win32_get_known_folder_ex(REFKNOWNFOLDERID folder_id, DWORD flags)
|
||||
{
|
||||
if (PWSTR path; SHGetKnownFolderPath(folder_id, flags | KF_FLAG_DONT_UNEXPAND, nullptr, &path) == S_OK)
|
||||
if (PWSTR path = nullptr; SHGetKnownFolderPath(folder_id, flags | KF_FLAG_DONT_UNEXPAND, nullptr, &path) == S_OK)
|
||||
{
|
||||
auto ret = tr_win32_native_to_utf8(path);
|
||||
CoTaskMemFree(path);
|
||||
|
|
|
@ -128,7 +128,7 @@ bool tr_session_id::is_local(std::string_view session_id) noexcept
|
|||
auto error = tr_error{};
|
||||
if (auto lockfile_fd = tr_sys_file_open(lockfile_path, TR_SYS_FILE_READ, 0, &error); lockfile_fd == TR_BAD_SYS_FILE)
|
||||
{
|
||||
if (TR_ERROR_IS_ENOENT(error.code()))
|
||||
if (tr_error_is_enoent(error.code()))
|
||||
{
|
||||
error = {};
|
||||
}
|
||||
|
|
|
@ -101,10 +101,19 @@ int cond_wait(void* vcond, void* vlock, struct timeval const* tv)
|
|||
return success == std::cv_status::timeout ? 1 : 0;
|
||||
}
|
||||
|
||||
#if defined(_WIN32) && defined(__clang_analyzer__)
|
||||
// See https://github.com/llvm/llvm-project/issues/98823
|
||||
#define WORKAROUND_CLANG_TIDY_GH98823
|
||||
#endif
|
||||
|
||||
unsigned long thread_current_id()
|
||||
{
|
||||
#ifndef WORKAROUND_CLANG_TIDY_GH98823
|
||||
thread_local auto const hashed = std::hash<std::thread::id>()(std::this_thread::get_id());
|
||||
return hashed;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void init_evthreads_once()
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
struct event_base;
|
||||
|
|
|
@ -29,7 +29,7 @@ using namespace std::literals;
|
|||
namespace
|
||||
{
|
||||
|
||||
enum class tr_app_type
|
||||
enum class tr_app_type : uint8_t
|
||||
{
|
||||
EXE,
|
||||
BATCH
|
||||
|
@ -52,17 +52,22 @@ void set_system_error(tr_error* error, DWORD code, std::string_view what)
|
|||
}
|
||||
}
|
||||
|
||||
constexpr bool to_bool(BOOL value) noexcept
|
||||
{
|
||||
return value != FALSE;
|
||||
}
|
||||
|
||||
// "The sort is case-insensitive, Unicode order, without regard to locale" © MSDN
|
||||
class WStrICompare
|
||||
{
|
||||
public:
|
||||
[[nodiscard]] auto compare(std::wstring_view a, std::wstring_view b) const noexcept // <=>
|
||||
[[nodiscard]] static auto compare(std::wstring_view a, std::wstring_view b) noexcept // <=>
|
||||
{
|
||||
int diff = wcsnicmp(std::data(a), std::data(b), std::min(std::size(a), std::size(b)));
|
||||
|
||||
if (diff == 0)
|
||||
{
|
||||
diff = std::size(a) < std::size(b) ? -1 : (std::size(a) > std::size(b) ? 1 : 0);
|
||||
diff = tr_compare_3way(std::size(a), std::size(b));
|
||||
}
|
||||
|
||||
return diff;
|
||||
|
@ -178,6 +183,9 @@ void append_argument(std::string& arguments, char const* argument)
|
|||
case '"':
|
||||
backslash_count = backslash_count * 2 + 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (backslash_count != 0)
|
||||
|
@ -298,7 +306,7 @@ bool tr_spawn_async(
|
|||
|
||||
PROCESS_INFORMATION pi;
|
||||
|
||||
bool const ret = CreateProcessW(
|
||||
bool const ret = to_bool(CreateProcessW(
|
||||
nullptr,
|
||||
std::data(cmd_line),
|
||||
nullptr,
|
||||
|
@ -308,7 +316,7 @@ bool tr_spawn_async(
|
|||
std::empty(full_env) ? nullptr : to_env_string(full_env).data(),
|
||||
std::empty(current_dir) ? nullptr : current_dir.c_str(),
|
||||
&si,
|
||||
&pi);
|
||||
&pi));
|
||||
|
||||
if (ret)
|
||||
{
|
||||
|
|
|
@ -90,6 +90,7 @@ extern "C"
|
|||
|
||||
int dht_sendto(int sockfd, void const* buf, int len, int flags, struct sockaddr const* to, int tolen)
|
||||
{
|
||||
// NOLINTNEXTLINE(readability-redundant-casting)
|
||||
return static_cast<int>(sendto(sockfd, static_cast<char const*>(buf), len, flags, to, tolen));
|
||||
}
|
||||
|
||||
|
|
|
@ -75,21 +75,32 @@ Config::Units<StorageUnits> Config::Storage{ Config::Base::Kilo, "B"sv, "kB"sv,
|
|||
|
||||
// ---
|
||||
|
||||
#if defined(_WIN32) && defined(__clang_analyzer__)
|
||||
// See https://github.com/llvm/llvm-project/issues/44701
|
||||
#define WORKAROUND_CLANG_TIDY_GH44701
|
||||
#endif
|
||||
|
||||
std::optional<std::locale> tr_locale_set_global(char const* locale_name) noexcept
|
||||
{
|
||||
#ifndef WORKAROUND_CLANG_TIDY_GH44701
|
||||
try
|
||||
#endif
|
||||
{
|
||||
return tr_locale_set_global(std::locale{ locale_name });
|
||||
}
|
||||
#ifndef WORKAROUND_CLANG_TIDY_GH44701
|
||||
catch (std::runtime_error const&)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
std::optional<std::locale> tr_locale_set_global(std::locale const& locale) noexcept
|
||||
{
|
||||
#ifndef WORKAROUND_CLANG_TIDY_GH44701
|
||||
try
|
||||
#endif
|
||||
{
|
||||
auto old_locale = std::locale::global(locale);
|
||||
|
||||
|
@ -98,10 +109,12 @@ std::optional<std::locale> tr_locale_set_global(std::locale const& locale) noexc
|
|||
|
||||
return old_locale;
|
||||
}
|
||||
#ifndef WORKAROUND_CLANG_TIDY_GH44701
|
||||
catch (std::exception const&)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// ---
|
||||
|
@ -336,7 +349,7 @@ std::string tr_win32_format_message(uint32_t code)
|
|||
nullptr,
|
||||
code,
|
||||
0,
|
||||
(LPWSTR)&wide_text,
|
||||
reinterpret_cast<LPWSTR>(&wide_text),
|
||||
0,
|
||||
nullptr);
|
||||
|
||||
|
@ -355,7 +368,7 @@ std::string tr_win32_format_message(uint32_t code)
|
|||
LocalFree(wide_text);
|
||||
|
||||
// Most (all?) messages contain "\r\n" in the end, chop it
|
||||
while (!std::empty(text) && isspace(text.back()))
|
||||
while (!std::empty(text) && isspace(text.back()) != 0)
|
||||
{
|
||||
text.resize(text.size() - 1);
|
||||
}
|
||||
|
@ -370,7 +383,7 @@ namespace tr_main_win32_impl
|
|||
|
||||
std::optional<std::vector<std::string>> win32MakeUtf8Argv()
|
||||
{
|
||||
int argc;
|
||||
int argc = 0;
|
||||
auto argv = std::vector<std::string>{};
|
||||
if (wchar_t** wargv = CommandLineToArgvW(GetCommandLineW(), &argc); wargv != nullptr)
|
||||
{
|
||||
|
@ -390,7 +403,7 @@ std::optional<std::vector<std::string>> win32MakeUtf8Argv()
|
|||
argv.emplace_back(std::move(str));
|
||||
}
|
||||
|
||||
LocalFree(wargv);
|
||||
LocalFree(reinterpret_cast<HLOCAL>(wargv));
|
||||
}
|
||||
|
||||
if (static_cast<int>(std::size(argv)) == argc)
|
||||
|
|
|
@ -34,6 +34,11 @@ namespace libtransmission
|
|||
namespace
|
||||
{
|
||||
|
||||
constexpr bool to_bool(BOOL value) noexcept
|
||||
{
|
||||
return value != FALSE;
|
||||
}
|
||||
|
||||
BOOL tr_get_overlapped_result_ex(
|
||||
HANDLE handle,
|
||||
LPOVERLAPPED overlapped,
|
||||
|
@ -48,7 +53,7 @@ BOOL tr_get_overlapped_result_ex(
|
|||
|
||||
if (!is_real_impl_valid)
|
||||
{
|
||||
real_impl = (impl_t)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "GetOverlappedResultEx");
|
||||
real_impl = reinterpret_cast<impl_t>(GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "GetOverlappedResultEx"));
|
||||
is_real_impl_valid = true;
|
||||
}
|
||||
|
||||
|
@ -142,14 +147,15 @@ private:
|
|||
return;
|
||||
}
|
||||
|
||||
if ((fd_ = CreateFileW(
|
||||
wide_path.c_str(),
|
||||
FILE_LIST_DIRECTORY,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||
nullptr,
|
||||
OPEN_EXISTING,
|
||||
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED,
|
||||
nullptr)) == INVALID_HANDLE_VALUE)
|
||||
fd_ = CreateFileW(
|
||||
wide_path.c_str(),
|
||||
FILE_LIST_DIRECTORY,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||
nullptr,
|
||||
OPEN_EXISTING,
|
||||
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED,
|
||||
nullptr);
|
||||
if (fd_ == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
tr_logAddError(fmt::format(_("Couldn't read '{path}'"), fmt::arg("path", path)));
|
||||
return;
|
||||
|
@ -157,7 +163,15 @@ private:
|
|||
|
||||
overlapped_.Pointer = this;
|
||||
|
||||
if (!ReadDirectoryChangesW(fd_, buffer_, sizeof(buffer_), false, Win32WatchMask, nullptr, &overlapped_, nullptr))
|
||||
if (!to_bool(ReadDirectoryChangesW(
|
||||
fd_,
|
||||
std::data(buffer_),
|
||||
std::size(buffer_),
|
||||
FALSE,
|
||||
Win32WatchMask,
|
||||
nullptr,
|
||||
&overlapped_,
|
||||
nullptr)))
|
||||
{
|
||||
tr_logAddError(fmt::format(_("Couldn't read '{path}'"), fmt::arg("path", path)));
|
||||
return;
|
||||
|
@ -188,7 +202,8 @@ private:
|
|||
bufferevent_setcb(event_, &Win32Watchdir::onBufferEvent, nullptr, nullptr, this);
|
||||
bufferevent_enable(event_, EV_READ);
|
||||
|
||||
thread_ = (HANDLE)_beginthreadex(nullptr, 0, Win32Watchdir::staticThreadFunc, this, 0, nullptr);
|
||||
// NOLINTNEXTLINE(performance-no-int-to-ptr)
|
||||
thread_ = reinterpret_cast<HANDLE>(_beginthreadex(nullptr, 0, Win32Watchdir::staticThreadFunc, this, 0, nullptr));
|
||||
if (thread_ == nullptr)
|
||||
{
|
||||
tr_logAddError(_("Couldn't create thread"));
|
||||
|
@ -203,22 +218,31 @@ private:
|
|||
|
||||
unsigned int threadFunc()
|
||||
{
|
||||
DWORD bytes_transferred;
|
||||
DWORD bytes_transferred = 0;
|
||||
|
||||
while (tr_get_overlapped_result_ex(fd_, &overlapped_, &bytes_transferred, INFINITE, FALSE))
|
||||
while (to_bool(tr_get_overlapped_result_ex(fd_, &overlapped_, &bytes_transferred, INFINITE, FALSE)))
|
||||
{
|
||||
PFILE_NOTIFY_INFORMATION info = (PFILE_NOTIFY_INFORMATION)buffer_;
|
||||
auto* info = reinterpret_cast<PFILE_NOTIFY_INFORMATION>(std::data(buffer_));
|
||||
|
||||
while (info->NextEntryOffset != 0)
|
||||
{
|
||||
*((BYTE**)&info) += info->NextEntryOffset;
|
||||
*reinterpret_cast<BYTE**>(&info) += info->NextEntryOffset;
|
||||
}
|
||||
|
||||
info->NextEntryOffset = bytes_transferred - ((BYTE*)info - (BYTE*)buffer_);
|
||||
info->NextEntryOffset = bytes_transferred -
|
||||
(reinterpret_cast<BYTE*>(info) - reinterpret_cast<BYTE*>(std::data(buffer_)));
|
||||
|
||||
send(notify_pipe_[1], (char const*)buffer_, bytes_transferred, 0);
|
||||
send(notify_pipe_[1], reinterpret_cast<char const*>(std::data(buffer_)), bytes_transferred, 0);
|
||||
|
||||
if (!ReadDirectoryChangesW(fd_, buffer_, sizeof(buffer_), FALSE, Win32WatchMask, nullptr, &overlapped_, nullptr))
|
||||
if (!to_bool(ReadDirectoryChangesW(
|
||||
fd_,
|
||||
std::data(buffer_),
|
||||
std::size(buffer_),
|
||||
FALSE,
|
||||
Win32WatchMask,
|
||||
nullptr,
|
||||
&overlapped_,
|
||||
nullptr)))
|
||||
{
|
||||
tr_logAddError(_("Couldn't read directory changes"));
|
||||
return 0;
|
||||
|
@ -249,7 +273,7 @@ private:
|
|||
|
||||
auto buffer = std::vector<char>{};
|
||||
buffer.resize(sizeof(FILE_NOTIFY_INFORMATION) + name_size);
|
||||
PFILE_NOTIFY_INFORMATION ev = (PFILE_NOTIFY_INFORMATION)std::data(buffer);
|
||||
auto* ev = reinterpret_cast<PFILE_NOTIFY_INFORMATION>(std::data(buffer));
|
||||
|
||||
size_t const header_size = offsetof(FILE_NOTIFY_INFORMATION, FileName);
|
||||
|
||||
|
@ -263,7 +287,7 @@ private:
|
|||
break;
|
||||
}
|
||||
|
||||
if (nread == (size_t)-1)
|
||||
if (nread == static_cast<size_t>(-1))
|
||||
{
|
||||
auto const error_code = errno;
|
||||
tr_logAddError(fmt::format(
|
||||
|
@ -292,12 +316,12 @@ private:
|
|||
{
|
||||
name_size = nleft;
|
||||
buffer.resize(sizeof(FILE_NOTIFY_INFORMATION) + name_size);
|
||||
ev = (PFILE_NOTIFY_INFORMATION)std::data(buffer);
|
||||
ev = reinterpret_cast<PFILE_NOTIFY_INFORMATION>(std::data(buffer));
|
||||
}
|
||||
|
||||
// consume entire name into buffer
|
||||
nread = bufferevent_read(event, &buffer[header_size], nleft);
|
||||
if (nread == (size_t)-1)
|
||||
if (nread == static_cast<size_t>(-1))
|
||||
{
|
||||
auto const error_code = errno;
|
||||
tr_logAddError(fmt::format(
|
||||
|
@ -330,7 +354,7 @@ private:
|
|||
|
||||
HANDLE fd_ = INVALID_HANDLE_VALUE;
|
||||
OVERLAPPED overlapped_ = {};
|
||||
DWORD buffer_[8 * 1024 / sizeof(DWORD)];
|
||||
std::array<DWORD, 8 * 1024 / sizeof(DWORD)> buffer_ = {};
|
||||
std::array<evutil_socket_t, 2> notify_pipe_{ static_cast<evutil_socket_t>(-1), static_cast<evutil_socket_t>(-1) };
|
||||
struct bufferevent* event_ = nullptr;
|
||||
HANDLE thread_ = {};
|
||||
|
@ -342,9 +366,9 @@ std::unique_ptr<Watchdir> Watchdir::create(
|
|||
std::string_view dirname,
|
||||
Callback callback,
|
||||
TimerMaker& timer_maker,
|
||||
struct event_base* event_base)
|
||||
struct event_base* evbase)
|
||||
{
|
||||
return std::make_unique<Win32Watchdir>(dirname, std::move(callback), timer_maker, event_base);
|
||||
return std::make_unique<Win32Watchdir>(dirname, std::move(callback), timer_maker, evbase);
|
||||
}
|
||||
|
||||
} // namespace libtransmission
|
||||
|
|
|
@ -46,7 +46,7 @@ namespace
|
|||
|
||||
auto error = tr_error{};
|
||||
auto const info = tr_sys_path_get_info(path, 0, &error);
|
||||
if (error && !TR_ERROR_IS_ENOENT(error.code()))
|
||||
if (error && !tr_error_is_enoent(error.code()))
|
||||
{
|
||||
tr_logAddWarn(fmt::format(
|
||||
_("Skipping '{path}': {error} ({error_code})"),
|
||||
|
|
|
@ -129,7 +129,7 @@ CURLcode ssl_context_func(CURL* /*curl*/, void* ssl_ctx, void* /*user_data*/)
|
|||
|
||||
for (auto& sys_store_name : SysStoreNames)
|
||||
{
|
||||
HCERTSTORE const sys_cert_store = CertOpenSystemStoreW(0, sys_store_name);
|
||||
auto* const sys_cert_store = CertOpenSystemStoreW(0, sys_store_name);
|
||||
if (sys_cert_store == nullptr)
|
||||
{
|
||||
continue;
|
||||
|
@ -145,7 +145,7 @@ CURLcode ssl_context_func(CURL* /*curl*/, void* ssl_ctx, void* /*user_data*/)
|
|||
break;
|
||||
}
|
||||
|
||||
tr_x509_cert_t const cert = tr_x509_cert_new(sys_cert->pbCertEncoded, sys_cert->cbCertEncoded);
|
||||
auto* const cert = tr_x509_cert_new(sys_cert->pbCertEncoded, sys_cert->cbCertEncoded);
|
||||
if (cert == nullptr)
|
||||
{
|
||||
continue;
|
||||
|
@ -406,7 +406,7 @@ public:
|
|||
// if unset: steady-state, all is good
|
||||
// if set: do not accept new tasks
|
||||
// if set and deadline reached: kill all remaining tasks
|
||||
std::atomic<time_t> deadline_ = {};
|
||||
std::atomic<time_t> deadline_ = {}; // NOLINT(readability-redundant-member-init)
|
||||
|
||||
[[nodiscard]] auto deadline() const
|
||||
{
|
||||
|
|
|
@ -10,7 +10,7 @@ Param(
|
|||
[string] $BuildArch,
|
||||
|
||||
[Parameter()]
|
||||
[ValidateSet('All', 'Deps', 'App')]
|
||||
[ValidateSet('All', 'CoreDeps', 'Deps', 'App')]
|
||||
[string] $BuildPart = 'All',
|
||||
|
||||
[Parameter()]
|
||||
|
@ -258,14 +258,23 @@ if (-not $SourceDir) {
|
|||
if ($Mode -eq 'DepsHash') {
|
||||
Import-Script Toolchain
|
||||
|
||||
$Names = @(
|
||||
Invoke-Build Expat -CacheArchiveNameOnly
|
||||
Invoke-Build DBus -CacheArchiveNameOnly
|
||||
Invoke-Build Zlib -CacheArchiveNameOnly
|
||||
Invoke-Build OpenSsl -CacheArchiveNameOnly
|
||||
Invoke-Build Curl -CacheArchiveNameOnly
|
||||
Invoke-Build Qt$UseQtVersion -CacheArchiveNameOnly
|
||||
)
|
||||
$Names = @()
|
||||
|
||||
if (@('All', 'CoreDeps', 'Deps') -contains $BuildPart) {
|
||||
$Names = $Names + @(
|
||||
Invoke-Build Zlib -CacheArchiveNameOnly
|
||||
Invoke-Build OpenSsl -CacheArchiveNameOnly
|
||||
Invoke-Build Curl -CacheArchiveNameOnly
|
||||
)
|
||||
}
|
||||
|
||||
if (@('All', 'Deps') -contains $BuildPart) {
|
||||
$Names = $Names + @(
|
||||
Invoke-Build Expat -CacheArchiveNameOnly
|
||||
Invoke-Build DBus -CacheArchiveNameOnly
|
||||
Invoke-Build Qt$UseQtVersion -CacheArchiveNameOnly
|
||||
)
|
||||
}
|
||||
|
||||
Write-Output (Get-StringHash ($Names -join ':'))
|
||||
}
|
||||
|
@ -285,12 +294,15 @@ if ($Mode -eq 'Build') {
|
|||
$Env:CMAKE_CXX_COMPILER_LAUNCHER = ''
|
||||
}
|
||||
|
||||
if (@('All', 'Deps') -contains $BuildPart) {
|
||||
Invoke-Build Expat
|
||||
Invoke-Build DBus
|
||||
if (@('All', 'CoreDeps', 'Deps') -contains $BuildPart) {
|
||||
Invoke-Build Zlib
|
||||
Invoke-Build OpenSsl
|
||||
Invoke-Build Curl
|
||||
}
|
||||
|
||||
if (@('All', 'Deps') -contains $BuildPart) {
|
||||
Invoke-Build Expat
|
||||
Invoke-Build DBus
|
||||
Invoke-Build Qt$UseQtVersion
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue