Repository :
https://github.com/FarGroup/FarManager
On branch : master
Link :
https://github.com/FarGroup/FarManager/commit/21d2232f54c5e0d1bcac0c6f457fa475384f03da
>---------------------------------------------------------------
commit 21d2232f54c5e0d1bcac0c6f457fa475384f03da
Author: Alex Alabuzhev <
alab...@gmail.com>
Date: Mon Jun 29 22:59:07 2026 +0100
Refactoring
>---------------------------------------------------------------
21d2232f54c5e0d1bcac0c6f457fa475384f03da
far/changelog | 5 +++
far/exception_handler.cpp | 10 +++---
far/platform.com.cpp | 88 ++++++++++++++++++++++++++++-------------------
far/platform.com.hpp | 18 +++++++---
far/vbuild.m4 | 2 +-
5 files changed, 77 insertions(+), 46 deletions(-)
diff --git a/far/changelog b/far/changelog
index e10b3407f..33b14f22e 100644
--- a/far/changelog
+++ b/far/changelog
@@ -1,3 +1,8 @@
+--------------------------------------------------------------------------------
+drkns 2026-06-29 22:51:32+01:00 - build 6707
+
+1. Refactoring.
+
--------------------------------------------------------------------------------
drkns 2026-06-29 01:43:41+01:00 - build 6706
diff --git a/far/exception_handler.cpp b/far/exception_handler.cpp
index 70c10cda4..af477a1e0 100644
--- a/far/exception_handler.cpp
+++ b/far/exception_handler.cpp
@@ -793,11 +793,11 @@ private:
if (!imports.DebugCreate)
return;
- COM_INVOKE(imports.DebugCreate, (IID_IDebugClient, IID_PPV_ARGS_Helper(&ptr_setter(m_DebugClient))));
+ COM_INVOKE(imports.DebugCreate)(IID_IDebugClient, IID_PPV_ARGS_Helper(&ptr_setter(m_DebugClient)));
- COM_INVOKE(m_DebugClient->AttachProcess, ({}, GetCurrentProcessId(), DEBUG_ATTACH_NONINVASIVE | DEBUG_ATTACH_NONINVASIVE_NO_SUSPEND));
+ COM_INVOKE(m_DebugClient->AttachProcess)({}, GetCurrentProcessId(), DEBUG_ATTACH_NONINVASIVE | DEBUG_ATTACH_NONINVASIVE_NO_SUSPEND);
- COM_INVOKE(m_DebugClient->QueryInterface, (IID_IDebugControl, IID_PPV_ARGS_Helper(&ptr_setter(m_DebugControl))));
+ COM_INVOKE(m_DebugClient->QueryInterface)(IID_IDebugControl, IID_PPV_ARGS_Helper(&ptr_setter(m_DebugControl)));
if (const auto Result = m_DebugControl->WaitForEvent(DEBUG_WAIT_DEFAULT, INFINITE); FAILED(Result))
LOGWARNING(L"WaitForEvent(): {}"sv, os::format_error(Result));
@@ -806,9 +806,9 @@ private:
LOGWARNING(L"SetOutputMask(): {}"sv, os::format_error(Result));
if (os::com::ptr<IDebugClient5> DebugClient5; SUCCEEDED(m_DebugClient->QueryInterface(IID_IDebugClient5, IID_PPV_ARGS_Helper(&ptr_setter(DebugClient5)))))
- COM_INVOKE(DebugClient5->SetOutputCallbacksWide, (&m_Callbacks));
+ COM_INVOKE(DebugClient5->SetOutputCallbacksWide)(&m_Callbacks);
else
- COM_INVOKE(m_DebugClient->SetOutputCallbacks, (&m_Callbacks));
+ COM_INVOKE(m_DebugClient->SetOutputCallbacks)(&m_Callbacks);
}
string* m_To;
diff --git a/far/platform.com.cpp b/far/platform.com.cpp
index 2aa49e77e..9f06ecf5c 100644
--- a/far/platform.com.cpp
+++ b/far/platform.com.cpp
@@ -79,12 +79,18 @@ namespace os::com
CoTaskMemFree(const_cast<void*>(Object));
}
- HRESULT invoke(function_ref<HRESULT()> const Callable, string_view CallableName, source_location const& Location)
+ detail::check_result::check_result(string_view CallableName, source_location const& Location):
+ m_CallableName(CallableName),
+ m_Location(Location)
{
- if (const auto Result = Callable(); FAILED(Result))
- throw exception(Result, CallableName, Location);
- else
- return Result;
+ }
+
+ HRESULT detail::check_result::operator%(HRESULT const Result) const
+ {
+ if (FAILED(Result))
+ throw exception(Result, m_CallableName, m_Location);
+
+ return Result;
}
string get_shell_name(string_view Path)
@@ -100,14 +106,14 @@ namespace os::com
SCOPED_ACTION(initialize)(mode::sta);
ptr<IShellFolder> ShellFolder;
- COM_INVOKE(SHGetDesktopFolder, (&ptr_setter(ShellFolder)));
+ COM_INVOKE(SHGetDesktopFolder)(&ptr_setter(ShellFolder));
memory<PIDLIST_RELATIVE> IdList;
null_terminated const C_Path(Path);
- COM_INVOKE(ShellFolder->ParseDisplayName, ({}, {}, UNSAFE_CSTR(C_Path), {}, &ptr_setter(IdList), {}));
+ COM_INVOKE(ShellFolder->ParseDisplayName)({}, {}, UNSAFE_CSTR(C_Path), {}, &ptr_setter(IdList), {});
STRRET StrRet;
- COM_INVOKE(ShellFolder->GetDisplayNameOf, (IdList.get(), SHGDN_FOREDITING, &StrRet));
+ COM_INVOKE(ShellFolder->GetDisplayNameOf)(IdList.get(), SHGDN_FOREDITING, &StrRet);
if (StrRet.uType != STRRET_WSTR)
{
@@ -141,10 +147,10 @@ namespace os::com
try
{
ptr<IApplicationAssociationRegistration> AAR;
- COM_INVOKE(imports.SHCreateAssociationRegistration, (IID_IApplicationAssociationRegistration, IID_PPV_ARGS_Helper(&ptr_setter(AAR))));
+ COM_INVOKE(imports.SHCreateAssociationRegistration)(IID_IApplicationAssociationRegistration, IID_PPV_ARGS_Helper(&ptr_setter(AAR)));
memory<wchar_t*> Association;
- COM_INVOKE(AAR->QueryCurrentDefault, (null_terminated(Ext).c_str(), AT_FILEEXTENSION, AL_EFFECTIVE, &ptr_setter(Association)));
+ COM_INVOKE(AAR->QueryCurrentDefault)(null_terminated(Ext).c_str(), AT_FILEEXTENSION, AL_EFFECTIVE, &ptr_setter(Association));
return Association.get();
}
@@ -199,24 +205,24 @@ namespace os::com
try
{
ptr<IRunningObjectTable> RunningObjectTable;
- COM_INVOKE(GetRunningObjectTable, (0, &ptr_setter(RunningObjectTable)));
+ COM_INVOKE(GetRunningObjectTable)(0, &ptr_setter(RunningObjectTable));
ptr<IMoniker> FileMoniker;
- COM_INVOKE(CreateFileMoniker, (File.c_str(), &ptr_setter(FileMoniker)));
+ COM_INVOKE(CreateFileMoniker)(File.c_str(), &ptr_setter(FileMoniker));
ptr<IEnumMoniker> EnumMoniker;
- COM_INVOKE(RunningObjectTable->EnumRunning, (&ptr_setter(EnumMoniker)));
+ COM_INVOKE(RunningObjectTable->EnumRunning)(&ptr_setter(EnumMoniker));
for (;;)
{
try
{
ptr<IMoniker> Moniker;
- if (COM_INVOKE(EnumMoniker->Next, (1, &ptr_setter(Moniker), {})) == S_FALSE)
+ if (COM_INVOKE(EnumMoniker->Next)(1, &ptr_setter(Moniker), {}) == S_FALSE)
return {};
DWORD Type;
- COM_INVOKE(Moniker->IsSystemMoniker, (&Type));
+ COM_INVOKE(Moniker->IsSystemMoniker)(&Type);
if (Type != MKSYS_FILEMONIKER)
continue;
@@ -233,15 +239,15 @@ namespace os::com
throw exception(Result, WIDE_SV_LITERAL(FileMoniker->CommonPrefixWith));
}
- if (COM_INVOKE(FileMoniker->IsEqual, (PrefixMoniker.get())) == S_FALSE)
+ if (COM_INVOKE(FileMoniker->IsEqual)(PrefixMoniker.get()) == S_FALSE)
continue;
ptr<IUnknown> Unknown;
- if (COM_INVOKE(RunningObjectTable->GetObject, (Moniker.get(), &ptr_setter(Unknown))) == S_FALSE)
+ if (COM_INVOKE(RunningObjectTable->GetObject)(Moniker.get(), &ptr_setter(Unknown)) == S_FALSE)
continue;
ptr<IFileIsInUse> FileIsInUse;
- COM_INVOKE(Unknown->QueryInterface, (IID_IFileIsInUse, IID_PPV_ARGS_Helper(&ptr_setter(FileIsInUse))));
+ COM_INVOKE(Unknown->QueryInterface)(IID_IFileIsInUse, IID_PPV_ARGS_Helper(&ptr_setter(FileIsInUse)));
return FileIsInUse;
}
@@ -259,14 +265,14 @@ namespace os::com
}
}
- std::optional<bool> can_recycle(string_view const Object)
+ static bool can_recycle_impl(string_view const Object)
{
WARNING_PUSH()
WARNING_DISABLE_GCC("-Wnon-virtual-dtor")
class FileOperationProgressSink final: public IFileOperationProgressSink
{
public:
- explicit FileOperationProgressSink(std::optional<bool>& CanRecycle):
+ explicit FileOperationProgressSink(bool& CanRecycle):
m_CanRecycle(&CanRecycle)
{
}
@@ -316,7 +322,7 @@ WARNING_DISABLE_GCC("-Wnon-virtual-dtor")
IFACEMETHODIMP ResumeTimer() override { return S_OK; }
private:
- std::optional<bool>* m_CanRecycle;
+ bool* m_CanRecycle;
};
WARNING_POP()
@@ -326,35 +332,45 @@ WARNING_POP()
// So we call delete on the item in question, check the flag in the callback and then immediately abort the operation.
// This is ludicrous, but hey, as long as it works.
- if (!imports.SHCreateItemFromParsingName)
- return {};
-
SCOPED_ACTION(initialize)(mode::sta);
ptr<IFileOperation> FileOperation;
- if (FAILED(CoCreateInstance(CLSID_FileOperation, nullptr, CLSCTX_INPROC_SERVER, IID_IFileOperation, IID_PPV_ARGS_Helper(&ptr_setter(FileOperation)))))
- return {};
+ COM_INVOKE(CoCreateInstance)(CLSID_FileOperation, nullptr, CLSCTX_INPROC_SERVER, IID_IFileOperation, IID_PPV_ARGS_Helper(&ptr_setter(FileOperation)));
- if (FAILED(FileOperation->SetOperationFlags(
+ COM_INVOKE(FileOperation->SetOperationFlags)(
FOF_ALLOWUNDO | // We want to know if the item can be recycled
FOF_NORECURSION | // Since we're not actually deleting anything, probing only the top level item is fine (and way faster)
FOF_NO_UI // Obviously, we don't want any UI
- )))
- return {};
+ );
ptr<IShellItem> Item;
- if (FAILED(imports.SHCreateItemFromParsingName(null_terminated(Object).c_str(), nullptr, IID_IShellItem, IID_PPV_ARGS_Helper(&ptr_setter(Item)))))
- return {};
+ COM_INVOKE(imports.SHCreateItemFromParsingName)(null_terminated(Object).c_str(), nullptr, IID_IShellItem, IID_PPV_ARGS_Helper(&ptr_setter(Item)));
- std::optional<bool> CanRecycle;
+ bool CanRecycle{};
FileOperationProgressSink Sink(CanRecycle);
- if (FAILED(FileOperation->DeleteItem(Item.get(), &Sink)))
- return {};
+ COM_INVOKE(FileOperation->DeleteItem)(Item.get(), &Sink);
- [[maybe_unused]] const auto Result = FileOperation->PerformOperations();
- assert(Result == E_ABORT); // We should have aborted the operation in the callback, so it must fail
+ if (const auto Result = FileOperation->PerformOperations(); Result != E_ABORT)
+ throw exception(Result, WIDE_SV_LITERAL(FileOperation->PerformOperations)); // We should have aborted the operation in the callback, so it must fail
return CanRecycle;
}
+
+ std::optional<bool> can_recycle(string_view const Object)
+ {
+ // Both SHCreateItemFromParsingName and IFileOperation are Vista+, no point in trying if it's not there.
+ if (!imports.SHCreateItemFromParsingName)
+ return {};
+
+ try
+ {
+ return can_recycle_impl(Object);
+ }
+ catch (exception const& e)
+ {
+ LOGWARNING(L"can_recycle: {}"sv, e);
+ return {};
+ }
+ }
}
diff --git a/far/platform.com.hpp b/far/platform.com.hpp
index 178c442ef..e0344ed05 100644
--- a/far/platform.com.hpp
+++ b/far/platform.com.hpp
@@ -81,6 +81,18 @@ namespace os::com
{
void operator()(const void* Object) const;
};
+
+ class check_result
+ {
+ public:
+ explicit check_result(string_view CallableName, source_location const& Location = source_location::current());
+
+ HRESULT operator%(HRESULT Result) const;
+
+ private:
+ string_view m_CallableName;
+ source_location m_Location;
+ };
}
template<typename T>
@@ -98,10 +110,8 @@ namespace os::com
}
};
- HRESULT invoke(function_ref<HRESULT()> Callable, string_view CallableName, source_location const& Location = source_location::current());
-
-#define COM_INVOKE(Function, Args) \
- os::com::invoke([&]{ return Function Args; }, WIDE_SV_LITERAL(Function))
+#define COM_INVOKE(Function) \
+ os::com::detail::check_result{WIDE_SV_LITERAL(Function)} % Function // (Args);
string get_shell_name(string_view Path);
diff --git a/far/vbuild.m4 b/far/vbuild.m4
index 686eb7d33..2f6aae031 100644
--- a/far/vbuild.m4
+++ b/far/vbuild.m4
@@ -1 +1 @@
-6706
+6707