diff --git a/far/changelog b/far/changelog index 67dae456c5..4bbfca17aa 100644 --- a/far/changelog +++ b/far/changelog @@ -1,3 +1,9 @@ +drkns 02.09.2017 15:38:54 +0100 - build 5020 + +1. Рефакторинг. Убран дублирующийся код и кое-что вынесено из common.hpp. + +2. Используем IsProcessorFeaturePresent для определения отсутствия SSE2. + drkns 30.08.2017 20:44:52 +0100 - build 5019 1. Новые версии tinyxml2 и fmt. diff --git a/far/clipboard.cpp b/far/clipboard.cpp index c59b0b7fd8..7a6557c37a 100644 --- a/far/clipboard.cpp +++ b/far/clipboard.cpp @@ -51,7 +51,7 @@ clipboard_mode default_clipboard_mode::get() } //----------------------------------------------------------------------------- -enum class Clipboard::clipboard_format +enum class clipboard::clipboard_format { vertical_block_oem, vertical_block_unicode, @@ -64,15 +64,11 @@ enum class Clipboard::clipboard_format }; //----------------------------------------------------------------------------- -class system_clipboard: noncopyable, public Clipboard +class system_clipboard: public clipboard, public singleton, noncopyable { -public: - static Clipboard& GetInstance() - { - static system_clipboard s_Clipboard; - return s_Clipboard; - } + IMPLEMENTS_SINGLETON(system_clipboard); +public: virtual ~system_clipboard() override { system_clipboard::Close(); @@ -171,18 +167,14 @@ class system_clipboard: noncopyable, public Clipboard }; //----------------------------------------------------------------------------- -class internal_clipboard: noncopyable, public Clipboard +class internal_clipboard: public clipboard, public singleton, noncopyable { -public: - static Clipboard& GetInstance() - { - static internal_clipboard s_Clipboard; - return s_Clipboard; - } + IMPLEMENTS_SINGLETON(internal_clipboard); +public: static auto CreateInstance() { - return std::unique_ptr(new internal_clipboard); + return std::unique_ptr(new internal_clipboard); } virtual ~internal_clipboard() override @@ -259,36 +251,41 @@ class internal_clipboard: noncopyable, public Clipboard }; //----------------------------------------------------------------------------- -static thread_local Clipboard* OverridenInternalClipboard; +static thread_local clipboard* OverridenInternalClipboard; -void clipboard_restorer::operator()(Clipboard* Clip) const +void clipboard_restorer::operator()(clipboard* Clip) const { OverridenInternalClipboard = nullptr; delete Clip; } -std::unique_ptr OverrideClipboard() +std::unique_ptr OverrideClipboard() { auto ClipPtr = internal_clipboard::CreateInstance(); OverridenInternalClipboard = ClipPtr.get(); - return std::unique_ptr(ClipPtr.release()); + return std::unique_ptr(ClipPtr.release()); } -Clipboard& Clipboard::GetInstance(clipboard_mode Mode) +clipboard& clipboard::GetInstance(clipboard_mode Mode) { - return OverridenInternalClipboard? *OverridenInternalClipboard : - Mode == clipboard_mode::system? system_clipboard::GetInstance() : internal_clipboard::GetInstance(); + if (OverridenInternalClipboard) + return *OverridenInternalClipboard; + + if (Mode == clipboard_mode::system) + return system_clipboard::instance(); + + return internal_clipboard::instance(); } -bool Clipboard::SetText(const wchar_t *Data, size_t Size) +bool clipboard::SetText(const string_view& Str) { if (!Clear()) return false; - if (!Data) + if (Str.empty()) return true; - auto hData = os::memory::global::copy(Data, Size); + auto hData = os::memory::global::copy(Str.data(), Str.size()); if (!hData) return false; @@ -297,17 +294,17 @@ bool Clipboard::SetText(const wchar_t *Data, size_t Size) // 'Notepad++ binary text length' // return value is ignored - non-critical feature - SetData(RegisterFormat(clipboard_format::notepad_plusplus_binary_text_length), os::memory::global::copy(static_cast(Size))); + SetData(RegisterFormat(clipboard_format::notepad_plusplus_binary_text_length), os::memory::global::copy(static_cast(Str.size()))); return true; } -bool Clipboard::SetVText(const wchar_t *Data, size_t Size) +bool clipboard::SetVText(const string_view& Str) { - if (!SetText(Data, Size)) + if (!SetText(Str)) return false; - if (!Data) + if (Str.empty()) return true; const auto FarVerticalBlock = RegisterFormat(clipboard_format::vertical_block_unicode); @@ -329,7 +326,7 @@ bool Clipboard::SetVText(const wchar_t *Data, size_t Size) return true; } -bool Clipboard::SetHDROP(const string& NamesData, bool bMoved) +bool clipboard::SetHDROP(const string_view& NamesData, bool bMoved) { if (NamesData.empty()) return false; @@ -362,7 +359,7 @@ bool Clipboard::SetHDROP(const string& NamesData, bool bMoved) return SetData(RegisterFormat(clipboard_format::preferred_drop_effect), std::move(hMemoryMove)); } -bool Clipboard::GetText(string& Data) const +bool clipboard::GetText(string& Data) const { auto hClipData = GetData(CF_UNICODETEXT); if (!hClipData) @@ -387,7 +384,7 @@ bool Clipboard::GetText(string& Data) const return true; } -bool Clipboard::GetHDROPAsText(string& data) const +bool clipboard::GetHDROPAsText(string& data) const { const auto hClipData = GetData(CF_HDROP); if (!hClipData) @@ -418,7 +415,7 @@ bool Clipboard::GetHDROPAsText(string& data) const return true; } -bool Clipboard::GetVText(string& data) const +bool clipboard::GetVText(string& data) const { const auto& IsBorlandVerticalBlock = [this] { @@ -450,16 +447,16 @@ bool Clipboard::GetVText(string& data) const } //----------------------------------------------------------------------------- -bool SetClipboardText(const wchar_t* Data, size_t Size) +bool SetClipboardText(const string_view& Str) { clipboard_accessor Clip; - return Clip->Open() && Clip->SetText(Data, Size); + return Clip->Open() && Clip->SetText(Str); } -bool SetClipboardVText(const wchar_t *Data, size_t Size) +bool SetClipboardVText(const string_view& Str) { clipboard_accessor Clip; - return Clip->Open() && Clip->SetVText(Data, Size); + return Clip->Open() && Clip->SetVText(Str); } bool GetClipboardText(string& data) diff --git a/far/clipboard.hpp b/far/clipboard.hpp index 72f09a246e..04afc2f0b1 100644 --- a/far/clipboard.hpp +++ b/far/clipboard.hpp @@ -51,25 +51,19 @@ class default_clipboard_mode static clipboard_mode m_Mode; }; -class Clipboard +class clipboard { public: - static Clipboard& GetInstance(clipboard_mode Mode); - virtual ~Clipboard() = default; + static clipboard& GetInstance(clipboard_mode Mode); + virtual ~clipboard() = default; virtual bool Open() = 0; virtual bool Close() = 0; virtual bool Clear() = 0; - bool SetText(const wchar_t *Data, size_t Size); - bool SetText(const wchar_t *Data) { return SetText(Data, wcslen(Data)); } - bool SetText(const string& Data) { return SetText(Data.data(), Data.size()); } - - bool SetVText(const wchar_t *Data, size_t Size); - bool SetVText(const wchar_t *Data) { return SetVText(Data, wcslen(Data)); } - bool SetVText(const string& Data) { return SetVText(Data.data(), Data.size()); } - - bool SetHDROP(const string& NamesData, bool bMoved); + bool SetText(const string_view& Str); + bool SetVText(const string_view& Str); + bool SetHDROP(const string_view& NamesData, bool bMoved); bool GetText(string& data) const; bool GetVText(string& data) const; @@ -91,22 +85,17 @@ class Clipboard class clipboard_accessor:noncopyable { public: - explicit clipboard_accessor(clipboard_mode Mode = default_clipboard_mode::get()): m_Clipboard(Clipboard::GetInstance(Mode)) {} + explicit clipboard_accessor(clipboard_mode Mode = default_clipboard_mode::get()): m_Clipboard(clipboard::GetInstance(Mode)) {} ~clipboard_accessor() { m_Clipboard.Close(); } auto operator->() const { return &m_Clipboard; } private: - Clipboard& m_Clipboard; + clipboard& m_Clipboard; }; -bool SetClipboardText(const wchar_t* Data, size_t Size); -inline bool SetClipboardText(const wchar_t* Data) { return SetClipboardText(Data, wcslen(Data)); } -inline bool SetClipboardText(const string& Data) { return SetClipboardText(Data.data(), Data.size()); } - -bool SetClipboardVText(const wchar_t *Data, size_t Size); -inline bool SetClipboardVText(const wchar_t* Data) { return SetClipboardVText(Data, wcslen(Data)); } -inline bool SetClipboardVText(const string& Data) { return SetClipboardVText(Data.data(), Data.size()); } +bool SetClipboardText(const string_view& Str); +bool SetClipboardVText(const string_view& Str); bool GetClipboardText(string& data); bool GetClipboardVText(string& data); @@ -117,9 +106,9 @@ bool CopyData(const clipboard_accessor& From, const clipboard_accessor& To); struct clipboard_restorer { - void operator()(Clipboard* Clip) const; + void operator()(clipboard* Clip) const; }; -std::unique_ptr OverrideClipboard(); +std::unique_ptr OverrideClipboard(); #endif // CLIPBOARD_HPP_989E040C_4D10_4D7C_88C0_5EF499171878 diff --git a/far/common.hpp b/far/common.hpp index 8d9e8f1ad2..b18fae1a31 100644 --- a/far/common.hpp +++ b/far/common.hpp @@ -39,9 +39,9 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "common/compiler.hpp" #include "common/preprocessor.hpp" +#include "common/utility.hpp" #include "common/movable.hpp" #include "common/noncopyable.hpp" -#include "common/swapable.hpp" #include "common/rel_ops.hpp" #include "common/conditional.hpp" #include "common/scope_exit.hpp" @@ -59,33 +59,10 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "common/string_utils.hpp" #include "common/zip_view.hpp" #include "common/blob_view.hpp" +#include "common/singleton.hpp" // TODO: clean up & split -template -void resize_nomove(T& container, size_t size) -{ - T Tmp(size); - using std::swap; - swap(container, Tmp); -} - -template -void clear_and_shrink(T& container) -{ - T Tmp; - using std::swap; - swap(container, Tmp); -} - -template -void node_swap(T& Container, const typename T::const_iterator& a, const typename T::const_iterator& b) -{ - const auto NextA = std::next(a), NextB = std::next(b); - Container.splice(NextA, Container, b); - Container.splice(NextB, Container, a); -} - template bool CheckStructSize(const T* s) { @@ -98,12 +75,6 @@ bool CheckNullOrStructSize(const T* s) return !s || CheckStructSize(s); } -template -void ClearArray(T(&a)[N]) noexcept -{ - std::fill_n(a, N, T{}); -} - template auto NullToEmpty(const T* Str) { @@ -117,12 +88,6 @@ auto EmptyToNull(const T* Str) return (Str && !*Str)? nullptr : Str; } -template -auto make_hash(const T& value) -{ - return std::hash{}(value); -} - template T Round(const T &a, const T &b) { @@ -140,35 +105,6 @@ bool InRange(const T& from, const Y& what, const T& to) return from <= what && what <= to; } -template -auto make_raii_wrapper(owner* Owner, const acquire& Acquire, const release& Release) -{ - std::invoke(Acquire, Owner); - auto&& Releaser = [Release](owner* Owner){ std::invoke(Release, Owner); }; - return std::unique_ptr>(Owner, std::move(Releaser)); -} - -template -constexpr auto as_unsigned(T Value) -{ - return static_cast>(Value); -} - -template -constexpr auto as_underlying_type(T Value) -{ - return static_cast>(Value); -} - -namespace enum_helpers -{ - template - constexpr auto operation(T a, T b) - { - return static_cast::value, T, R>>(O()(as_underlying_type(a), as_underlying_type(b))); - } -} - #ifdef _DEBUG #define SELF_TEST(code) \ namespace \ @@ -185,39 +121,11 @@ namespace \ #define SELF_TEST(code) #endif -constexpr auto bit(size_t Number) -{ - return 1 << Number; -} - #define SIGN_UNICODE 0xFEFF #define SIGN_REVERSEBOM 0xFFFE #define SIGN_UTF8 0xBFBBEF #define EOL_STR L"\r\n" -constexpr size_t aligned_size(size_t Size, size_t Alignment = MEMORY_ALLOCATION_ALIGNMENT) -{ - return (Size + (Alignment - 1)) & ~(Alignment - 1); -} - -namespace detail -{ - template - struct aligned_sizeof_t - { - enum - { - value = aligned_size(sizeof(T), Alignment) - }; - }; -} - -template -constexpr auto aligned_sizeof() -{ - return detail::aligned_sizeof_t::value; -} - template class base: public T { @@ -226,17 +134,4 @@ class base: public T using base_type = base; }; -template -class singleton -{ -public: - static type& instance() - { - static type sInstance; - return sInstance; - } -}; - -#define IMPLEMENTS_SINGLETON(...) friend class singleton<__VA_ARGS__> - #endif // COMMON_HPP_1BD5AB87_3379_4AFE_9F63_DB850DCF72B4 diff --git a/far/common/swapable.hpp b/far/common/placement.hpp similarity index 71% rename from far/common/swapable.hpp rename to far/common/placement.hpp index 53a7dcbbbe..174aa5efbb 100644 --- a/far/common/swapable.hpp +++ b/far/common/placement.hpp @@ -1,12 +1,12 @@ -#ifndef SWAPABLE_HPP_681890D0_0B8D_4C94_BB0A_2C6D3281332A -#define SWAPABLE_HPP_681890D0_0B8D_4C94_BB0A_2C6D3281332A +#ifndef PLACEMENT_HPP_846A43B8_5BFF_4131_87E6_CFC3E6C44956 +#define PLACEMENT_HPP_846A43B8_5BFF_4131_87E6_CFC3E6C44956 #pragma once /* -swapable.hpp +placement.hpp */ /* -Copyright © 2015 Far Group +Copyright © 2017 Far Group All rights reserved. Redistribution and use in source and binary forms, with or without @@ -32,13 +32,26 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -template -struct swapable +namespace placement { - friend void swap(T& a, T& b) noexcept + template + auto& construct(T& Object, args&&... Args) { - a.swap(b); +#ifdef MEMCHECK +#pragma push_macro("new") +#undef new +#endif + return *new(std::addressof(Object)) T(FWD(Args)...); +#ifdef MEMCHECK +#pragma pop_macro("new") +#endif } -}; -#endif // SWAPABLE_HPP_681890D0_0B8D_4C94_BB0A_2C6D3281332A + template + void destruct(T& Object) + { + Object.~T(); + } +} + +#endif // PLACEMENT_HPP_846A43B8_5BFF_4131_87E6_CFC3E6C44956 diff --git a/far/legacy_cpu_check.hpp b/far/common/singleton.hpp similarity index 76% rename from far/legacy_cpu_check.hpp rename to far/common/singleton.hpp index 31a8d4d602..2886cdcb38 100644 --- a/far/legacy_cpu_check.hpp +++ b/far/common/singleton.hpp @@ -1,11 +1,9 @@ -#ifndef LEGACY_CPU_CHECK_HPP_38B388C1_AF11_4F09_9643_074418E35699 -#define LEGACY_CPU_CHECK_HPP_38B388C1_AF11_4F09_9643_074418E35699 +#ifndef SINGLETON_HPP_689EF327_41C5_4AB7_B9A6_CB5361D7B040 +#define SINGLETON_HPP_689EF327_41C5_4AB7_B9A6_CB5361D7B040 #pragma once /* -legacy_cpu_check.hpp - -Проверка поддержки SSE2 для x86 +singleton.hpp */ /* Copyright © 2017 Far Group @@ -34,6 +32,20 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -bool IsLegacyCPU(); +template +class singleton +{ +public: + static type& instance() + { + static type Instance; + return Instance; + } + +protected: + using singleton_type = singleton; +}; + +#define IMPLEMENTS_SINGLETON(...) friend class singleton<__VA_ARGS__> -#endif // LEGACY_CPU_CHECK_HPP_38B388C1_AF11_4F09_9643_074418E35699 +#endif // SINGLETON_HPP_689EF327_41C5_4AB7_B9A6_CB5361D7B040 diff --git a/far/common/smart_ptr.hpp b/far/common/smart_ptr.hpp index 2eaef61a65..e322cb2e11 100644 --- a/far/common/smart_ptr.hpp +++ b/far/common/smart_ptr.hpp @@ -179,4 +179,15 @@ class ptr_setter_t template auto ptr_setter(T& Ptr) { return ptr_setter_t(Ptr); } +template +auto make_raii_wrapper(owner* Owner, const acquire& Acquire, const release& Release) +{ + std::invoke(Acquire, Owner); + auto&& Releaser = [Release](owner* Owner) + { + std::invoke(Release, Owner); + }; + return std::unique_ptr>(Owner, std::move(Releaser)); +} + #endif // SMART_PTR_HPP_DE65D1E8_C925_40F7_905A_B7E3FF40B486 diff --git a/far/common/string_utils.hpp b/far/common/string_utils.hpp index d472d95a4a..7ec0f4056e 100644 --- a/far/common/string_utils.hpp +++ b/far/common/string_utils.hpp @@ -34,6 +34,62 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "preprocessor.hpp" +/* +Helper class to safely pass string_view to low level C or platform API. +Builds a compatible null-terminated std::basic_string if the given view is not null-terminated, +otherwise uses the same data. +*/ + +#include "placement.hpp" + +WARNING_PUSH() +WARNING_DISABLE_MSC(4582) // no page '%$S': constructor is not implicitly called +WARNING_DISABLE_MSC(4583) // no page '%$S': destructor is not implicitly called + +template +class null_terminated_t +{ +public: + explicit null_terminated_t(const basic_string_view& Str): + m_Terminated(Str.data()[Str.size()] == 0) + { + if (m_Terminated) + placement::construct(m_View, Str); + else + placement::construct(m_Str, ALL_CONST_RANGE(Str)); + } + + ~null_terminated_t() + { + if (m_Terminated) + placement::destruct(m_View); + else + placement::destruct(m_Str); + } + + auto data() const + { + return m_Terminated? m_View.data() : m_Str.data(); + } + + auto size() const + { + return m_Terminated? m_View.size() : m_Str.size(); + } + +private: + union + { + std::basic_string m_Str; + basic_string_view m_View; + }; + bool m_Terminated; +}; + +WARNING_POP() + +using null_terminated = null_terminated_t; + namespace detail { inline void append_one(string& Str, wchar_t Arg, size_t) { Str += Arg; } @@ -241,5 +297,4 @@ inline bool contains(const string_view& Str, const string_view& Token) return std::search(ALL_CONST_RANGE(Str), ALL_CONST_RANGE(Token)) != Str.cend(); } - #endif // STRING_UTILS_HPP_DE39ECEB_2377_44CB_AF4B_FA5BEA09C8C8 diff --git a/far/common/utility.hpp b/far/common/utility.hpp new file mode 100644 index 0000000000..26d4b21af7 --- /dev/null +++ b/far/common/utility.hpp @@ -0,0 +1,120 @@ +#ifndef UTILITY_HPP_D8E934C7_BF30_4CEB_B80C_6E508DF7A1BC +#define UTILITY_HPP_D8E934C7_BF30_4CEB_B80C_6E508DF7A1BC +#pragma once + +/* +utility.hpp +*/ +/* +Copyright © 2017 Far Group +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +template +void resize_nomove(T& container, size_t size) +{ + T Tmp(size); + using std::swap; + swap(container, Tmp); +} + + +template +void clear_and_shrink(T& container) +{ + T Tmp; + using std::swap; + swap(container, Tmp); +} + + +template +void node_swap(T& Container, const typename T::const_iterator& a, const typename T::const_iterator& b) +{ + const auto NextA = std::next(a), NextB = std::next(b); + Container.splice(NextA, Container, b); + Container.splice(NextB, Container, a); +} + + +template +auto make_hash(const T& value) +{ + return std::hash{}(value); +} + + +template +constexpr auto as_unsigned(T Value) +{ + return static_cast>(Value); +} + +template +constexpr auto as_underlying_type(T Value) +{ + return static_cast>(Value); +} + + +constexpr auto bit(size_t Number) +{ + return 1 << Number; +} + + +constexpr size_t aligned_size(size_t Size, size_t Alignment = MEMORY_ALLOCATION_ALIGNMENT) +{ + return (Size + (Alignment - 1)) & ~(Alignment - 1); +} + +namespace detail +{ + template + struct aligned_sizeof_t + { + enum + { + value = aligned_size(sizeof(T), Alignment) + }; + }; +} + +template +constexpr auto aligned_sizeof() +{ + return detail::aligned_sizeof_t::value; +} + +namespace enum_helpers +{ + template + constexpr auto operation(T a, T b) + { + return static_cast::value, T, R>>(O()(as_underlying_type(a), as_underlying_type(b))); + } +} + +#endif // UTILITY_HPP_D8E934C7_BF30_4CEB_B80C_6E508DF7A1BC diff --git a/far/config.hpp b/far/config.hpp index ffedfbdcd7..34417693e1 100644 --- a/far/config.hpp +++ b/far/config.hpp @@ -263,6 +263,7 @@ class StringOption: public detail::OptionImpl size_t size() const { return Get().size(); } operator const string&() const { return Get(); } + operator string_view() const { return Get(); } }; class Options: noncopyable diff --git a/far/console.cpp b/far/console.cpp index 4304facdc1..4ca89c6000 100644 --- a/far/console.cpp +++ b/far/console.cpp @@ -391,25 +391,15 @@ virtual bool WriteOutput(const matrix& Buffer, COORD BufferCoord, return true; } -virtual bool Write(LPCWSTR Buffer) const override -{ - return Write(Buffer, wcslen(Buffer)); -} - -virtual bool Write(const string& Buffer) const override -{ - return Write(Buffer.data(), Buffer.size()); -} - -virtual bool Write(LPCWSTR Buffer, size_t NumberOfCharsToWrite) const override +virtual bool Write(const string_view& Str) const override { DWORD NumberOfCharsWritten; const auto OutputHandle = GetOutputHandle(); DWORD Mode; return GetMode(OutputHandle, Mode)? - WriteConsole(OutputHandle, Buffer, static_cast(NumberOfCharsToWrite), &NumberOfCharsWritten, nullptr) != FALSE : - WriteFile(OutputHandle, Buffer, static_cast(NumberOfCharsToWrite*sizeof(wchar_t)), &NumberOfCharsWritten, nullptr) != FALSE; + WriteConsole(OutputHandle, Str.data(), static_cast(Str.size()), &NumberOfCharsWritten, nullptr) != FALSE : + WriteFile(OutputHandle, Str.data(), static_cast(Str.size() * sizeof(wchar_t)), &NumberOfCharsWritten, nullptr) != FALSE; } virtual bool Commit() const override diff --git a/far/console.hpp b/far/console.hpp index a303be3608..9a57728b96 100644 --- a/far/console.hpp +++ b/far/console.hpp @@ -91,9 +91,7 @@ class console: noncopyable bool ReadOutput(matrix& Buffer, SMALL_RECT& ReadRegion) const { COORD BufferCoord = {}; return ReadOutput(Buffer, BufferCoord, ReadRegion); } virtual bool WriteOutput(const matrix& Buffer, COORD BufferCoord, SMALL_RECT& WriteRegion) const = 0; bool WriteOutput(const matrix& Buffer, SMALL_RECT& WriteRegion) const { COORD BufferCoord = {}; return WriteOutput(Buffer, BufferCoord, WriteRegion); } - virtual bool Write(LPCWSTR Buffer) const = 0; - virtual bool Write(const string& Buffer) const = 0; - virtual bool Write(LPCWSTR Buffer, size_t NumberOfCharsToWrite) const = 0; + virtual bool Write(const string_view& Str) const = 0; virtual bool Commit() const = 0; virtual bool GetTextAttributes(FarColor& Attributes) const = 0; diff --git a/far/cpp.hpp b/far/cpp.hpp index 126fd9dc71..c21041916a 100644 --- a/far/cpp.hpp +++ b/far/cpp.hpp @@ -205,10 +205,10 @@ namespace std #endif #if (!defined _MSC_VER && __cpp_static_assert < 201411) || (defined _MSC_VER && _MSC_VER < 1910) -#define DETAIL_GET_MACRO(_1, _2, NAME, ...) NAME #define DETAIL_STATIC_ASSERT_2(expression, message) static_assert(expression, message) #define DETAIL_STATIC_ASSERT_1(expression) DETAIL_STATIC_ASSERT_2(expression, #expression) -#define static_assert(...) EXPAND(DETAIL_GET_MACRO(__VA_ARGS__, DETAIL_STATIC_ASSERT_2, DETAIL_STATIC_ASSERT_1)(__VA_ARGS__)) +#define DETAIL_STATIC_ASSERT_GET_MACRO(_1, _2, NAME, ...) NAME +#define static_assert(...) EXPAND(DETAIL_STATIC_ASSERT_GET_MACRO(__VA_ARGS__, DETAIL_STATIC_ASSERT_2, DETAIL_STATIC_ASSERT_1)(__VA_ARGS__)) #endif #endif // CPP_HPP_95E41B70_5DB2_4E5B_A468_95343C6438AD diff --git a/far/edit.cpp b/far/edit.cpp index 3d9fc6ef6d..42ed60b267 100644 --- a/far/edit.cpp +++ b/far/edit.cpp @@ -53,7 +53,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. void ColorItem::SetOwner(const GUID& Value) { - static std::unordered_set GuidSet; + static std::unordered_set GuidSet; Owner = &*GuidSet.emplace(Value).first; } @@ -1222,7 +1222,7 @@ bool Edit::ProcessKey(const Manager::Key& Key) } else if (m_SelEnd <= m_Str.size()) // TODO: если в начало условия добавить "StrSize &&", то пропадет баг "Ctrl-Ins в пустой строке очищает клипборд" { - SetClipboardText(m_Str.data() + m_SelStart, m_SelEnd - m_SelStart); + SetClipboardText(make_string_view(m_Str, m_SelStart, m_SelEnd - m_SelStart)); } } diff --git a/far/editor.hpp b/far/editor.hpp index 87b17fce49..8e5fb2137e 100644 --- a/far/editor.hpp +++ b/far/editor.hpp @@ -330,7 +330,7 @@ class Editor: public SimpleScreenObject numbered_iterator m_it_CurLine{ EndIterator() }; numbered_iterator m_it_LastGetLine{ EndIterator() }; - std::unordered_set ChangeEventSubscribers; + std::unordered_set ChangeEventSubscribers; std::list UndoData; std::list::iterator UndoPos{ UndoData.end() }; std::list::iterator UndoSavePos{ UndoData.end() }; diff --git a/far/elevation.cpp b/far/elevation.cpp index a6616623f2..adc8949f4f 100644 --- a/far/elevation.cpp +++ b/far/elevation.cpp @@ -113,12 +113,6 @@ elevation::~elevation() DisconnectNamedPipe(m_Pipe.native_handle()); } -elevation& elevation::instance() -{ - static elevation s_Elevation; - return s_Elevation; -} - void elevation::ResetApprove() { if (m_DontAskAgain) diff --git a/far/elevation.hpp b/far/elevation.hpp index 4d074c0efe..61e0bb9b91 100644 --- a/far/elevation.hpp +++ b/far/elevation.hpp @@ -52,7 +52,6 @@ class elevation: noncopyable, public singleton IMPLEMENTS_SINGLETON(elevation); public: - static elevation& instance(); ~elevation(); void ResetApprove(); bool Elevated() const {return m_Elevation;} diff --git a/far/far.vcxproj b/far/far.vcxproj index a6ff474120..63da7bbaba 100644 --- a/far/far.vcxproj +++ b/far/far.vcxproj @@ -256,7 +256,6 @@ cl /nologo /c /Fo"$(IntDir)%(Filename)_c++.testobj" /TP api_test.c - @@ -335,19 +334,21 @@ cl /nologo /c /Fo"$(IntDir)%(Filename)_c++.testobj" /TP api_test.c + + - + @@ -399,6 +400,7 @@ cl /nologo /c /Fo"$(IntDir)%(Filename)_c++.testobj" /TP api_test.c + @@ -437,7 +439,6 @@ cl /nologo /c /Fo"$(IntDir)%(Filename)_c++.testobj" /TP api_test.c - diff --git a/far/far.vcxproj.filters b/far/far.vcxproj.filters index 43be0cd0b0..722cb81c40 100644 --- a/far/far.vcxproj.filters +++ b/far/far.vcxproj.filters @@ -221,9 +221,6 @@ Source Files - - Source Files - Source Files @@ -658,9 +655,6 @@ Header Files - - Header Files - Header Files @@ -934,9 +928,6 @@ Header Files\common - - Header Files\common - Header Files\common @@ -1000,6 +991,15 @@ Header Files + + Header Files\common + + + Header Files\common + + + Header Files\common + diff --git a/far/farwinapi.cpp b/far/farwinapi.cpp index 51bccbca31..5139a19371 100644 --- a/far/farwinapi.cpp +++ b/far/farwinapi.cpp @@ -2138,16 +2138,17 @@ handle OpenConsoleActiveScreenBuffer() } } - bool get(const wchar_t* Name, string& strBuffer) + bool get(const string_view& Name, string& strBuffer) { GuardLastError ErrorGuard; + null_terminated C_Name(Name); // GetEnvironmentVariable might return 0 not only in case of failure, but also when variable is empty. // To recognise this, we set LastError to ERROR_SUCCESS manually and check it after the call, // which doesn't change it upon success. SetLastError(ERROR_SUCCESS); if (ApiDynamicStringReceiver(strBuffer, [&](wchar_t* Buffer, size_t Size) { - return ::GetEnvironmentVariable(Name, Buffer, static_cast(Size)); + return ::GetEnvironmentVariable(C_Name.data(), Buffer, static_cast(Size)); })) { return true; @@ -2163,39 +2164,37 @@ handle OpenConsoleActiveScreenBuffer() return false; } - bool set(const wchar_t* Name, const wchar_t* Value) + bool set(const string_view& Name, const string_view& Value) { - return ::SetEnvironmentVariable(Name, Value) != FALSE; + return ::SetEnvironmentVariable(null_terminated(Name).data(), null_terminated(Value).data()) != FALSE; } - bool del(const wchar_t* Name) + bool del(const string_view& Name) { - return ::SetEnvironmentVariable(Name, nullptr) != FALSE; + return ::SetEnvironmentVariable(null_terminated(Name).data(), nullptr) != FALSE; } - string expand(const wchar_t* Str) + string expand(const string_view& Str) { + null_terminated C_Str(Str); + string Result; if (!ApiDynamicStringReceiver(Result, [&](wchar_t* Buffer, size_t Size) { - auto ReturnedSize = ::ExpandEnvironmentStrings(Str, Buffer, static_cast(Size)); + const auto ReturnedSize = ::ExpandEnvironmentStrings(C_Str.data(), Buffer, static_cast(Size)); // This pesky function includes the terminating null character even upon success, breaking the usual pattern - if (ReturnedSize <= Size) - --ReturnedSize; - return ReturnedSize; + return ReturnedSize <= Size? ReturnedSize - 1 : ReturnedSize; })) { - Result = Str; + Result = make_string(Str); } return Result; } string get_pathext() { - auto PathExt(os::env::get(L"PATHEXT")); - if (PathExt.empty()) - PathExt = L".COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC"; - return PathExt; + const auto PathExt = get(L"PATHEXT"); + return !PathExt.empty()? PathExt : L".COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC"s; } } diff --git a/far/farwinapi.hpp b/far/farwinapi.hpp index 208bdb3e3d..6422121983 100644 --- a/far/farwinapi.hpp +++ b/far/farwinapi.hpp @@ -539,22 +539,11 @@ namespace os }; } - bool get(const wchar_t* Name, string& strBuffer); - inline bool get(const string& Name, string& strBuffer) { return get(Name.data(), strBuffer); } - template - string get(const T& Name) { string Result; get(Name, Result); return Result; } - - bool set(const wchar_t* Name, const wchar_t* Value); - inline bool set(const wchar_t* Name, const string& Value) { return set(Name, Value.data()); } - inline bool set(const string& Name, const wchar_t* Value) { return set(Name.data(), Value); } - inline bool set(const string& Name, const string& Value) { return set(Name.data(), Value.data()); } - - bool del(const wchar_t* Name); - inline bool del(const string& Name) { return del(Name.data()); } - - string expand(const wchar_t* str); - inline string expand(const string& str) { return expand(str.data()); } - + bool get(const string_view& Name, string& strBuffer); + inline string get(const string_view& Name) { string Result; get(Name, Result); return Result; } + bool set(const string_view& Name, const string_view& Value); + bool del(const string_view& Name); + string expand(const string_view& str); string get_pathext(); } diff --git a/far/legacy_cpu_check.cpp b/far/legacy_cpu_check.cpp deleted file mode 100644 index 63b33bc094..0000000000 --- a/far/legacy_cpu_check.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/* -legacy_cpu_check.cpp - -Проверка поддержки SSE2 для x86 -*/ -/* -Copyright © 2017 Far Group -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. -3. The name of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "headers.hpp" -#pragma hdrstop - -#include "legacy_cpu_check.hpp" - -#if defined(_WIN32) && !defined(_WIN64) -# if defined(_MSC_VER) -# include -# define cpuid(inf, n) __cpuidex(inf, n, 0) -# elif defined(__GNUC__) -# include -# define cpuid(inf, n) __cpuid_count(n, 0, inf[0], inf[1], inf[2], inf[3]) -# endif -#endif - -bool IsLegacyCPU() -{ -#if defined(_WIN32) && !defined(_WIN64) && (defined(_MSC_VER) || defined(__GNUC__)) - bool have_sse2 = false; - int info[4] = { 0, 0, 0, 0 }; - cpuid(info, 0); - if (info[0] >= 1) - { - cpuid(info, 1); - have_sse2 = (info[3] & ((int)1 << 26)) != 0; - } - return !have_sse2; -#else - return false; -#endif -} diff --git a/far/main.cpp b/far/main.cpp index 3376ce3eb3..25cfe6dff4 100644 --- a/far/main.cpp +++ b/far/main.cpp @@ -53,7 +53,6 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "keyboard.hpp" #include "clipboard.hpp" #include "pathmix.hpp" -#include "strmix.hpp" #include "dirmix.hpp" #include "elevation.hpp" #include "cmdline.hpp" @@ -75,7 +74,7 @@ global *Global = nullptr; static void show_help() { - WCHAR HelpMsg[]= + static const auto HelpMsg = L"Usage: far [switches] [apath [ppath]]" EOL_STR EOL_STR L"where" EOL_STR L" apath - path to a folder (or a file or an archive or command with prefix)" EOL_STR @@ -120,8 +119,9 @@ static void show_help() L" -v " EOL_STR L" View the specified file. If is -, data is read from the stdin." EOL_STR L" -w[-] Stretch to console window instead of console buffer or vise versa." EOL_STR - ; - Console().Write(HelpMsg, std::size(HelpMsg)-1); + ""_sv; + + Console().Write(HelpMsg); Console().Commit(); } diff --git a/far/makefile_gcc b/far/makefile_gcc index 8ab3d55458..92732c7a9e 100644 --- a/far/makefile_gcc +++ b/far/makefile_gcc @@ -91,7 +91,6 @@ SRCS = \ keyboard.cpp \ language.cpp \ lasterror.cpp \ - legacy_cpu_check.cpp \ locale.cpp \ lockscrn.cpp \ macro.cpp \ diff --git a/far/makefile_vc b/far/makefile_vc index 667edc56b8..6119d74e79 100644 --- a/far/makefile_vc +++ b/far/makefile_vc @@ -175,7 +175,6 @@ LINK_OBJS = \ "$(INTDIR)\keyboard.obj" \ "$(INTDIR)\language.obj" \ "$(INTDIR)\lasterror.obj" \ - "$(INTDIR)\legacy_cpu_check.obj" \ "$(INTDIR)\locale.obj" \ "$(INTDIR)\lockscrn.obj" \ "$(INTDIR)\macro.obj" \ diff --git a/far/memcheck.cpp b/far/memcheck.cpp index 3020c34ef6..5be0218aad 100644 --- a/far/memcheck.cpp +++ b/far/memcheck.cpp @@ -234,16 +234,16 @@ static string FindStr(const void* Data, size_t Size) { const auto ABegin = reinterpret_cast(Data), AEnd = ABegin + Size - 1; - if (std::all_of(ABegin, AEnd, [](char c){ return c >= ' ' || IsEol(c); })) + if (std::all_of(ABegin, AEnd, [](char c){ return c >= ' ' || IsEol(c) || c == '\t'; })) { - return string(encoding::ansi::get_chars(ABegin, AEnd - ABegin)); + return encoding::ansi::get_chars(ABegin, AEnd - ABegin); } const auto WBegin = reinterpret_cast(Data), WEnd = WBegin + (Size - 1) / sizeof(wchar_t); - if (std::all_of(WBegin, WEnd, [](wchar_t c){ return c >= L' ' || IsEol(c); })) + if (std::all_of(WBegin, WEnd, [](wchar_t c){ return c >= L' ' || IsEol(c) || c == L'\t'; })) { - return string(WBegin, WEnd); + return { WBegin, WEnd }; } return {}; @@ -277,9 +277,10 @@ void PrintMemory() { const auto BlockSize = i->Size - sizeof(MEMINFO) - sizeof(EndMarker); const auto UserAddress = ToUser(i); + const size_t Width = 16; Message = concat(str(UserAddress), L", "_sv, encoding::ansi::get_chars(FormatLine(i->File, i->Line, i->Function, i->AllocationType, BlockSize)), - L"\nData: "_sv, BlobToHexWString(UserAddress, std::min(BlockSize, size_t(16)), L' '), - L"\nhr: "_sv, FindStr(UserAddress, BlockSize), L'\n'); + L"\nData: "_sv, BlobToHexWString(UserAddress, std::min(BlockSize, Width), L' '), + L"\nText: "_sv, FindStr(UserAddress, std::min(BlockSize, Width * 3)), L'\n'); std::wcerr << Message; OutputDebugString(Message.data()); diff --git a/far/mix.cpp b/far/mix.cpp index d6ba3ace74..ea2fd1b867 100644 --- a/far/mix.cpp +++ b/far/mix.cpp @@ -140,7 +140,7 @@ void FindDataExToPluginPanelItemHolder(const os::FAR_FIND_DATA& Src, PluginPanel Dest.FileAttributes = Src.dwFileAttributes; Dest.NumberOfLinks = 1; Dest.CRC32 = 0; - ClearArray(Dest.Reserved); + std::fill(ALL_RANGE(Dest.Reserved), 0); } PluginPanelItemHolder::~PluginPanelItemHolder() diff --git a/far/mix.hpp b/far/mix.hpp index c9fd684c20..482a2c7119 100644 --- a/far/mix.hpp +++ b/far/mix.hpp @@ -109,15 +109,6 @@ struct uuid_hash } }; -struct uuid_equal -{ - bool operator ()(const GUID& a, const GUID& b) const - { - // In WinSDK's older than 8.0 operator== for GUIDs declared as int (sic!), This will suppress the warning: - return (a == b) != 0; - } -}; - void ReloadEnvironment(); unsigned int CRC32(unsigned int crc, const void* buffer, size_t size); diff --git a/far/plugapi.cpp b/far/plugapi.cpp index 6512365ca0..30b6f62567 100644 --- a/far/plugapi.cpp +++ b/far/plugapi.cpp @@ -2308,10 +2308,10 @@ BOOL WINAPI apiCopyToClipboard(enum FARCLIPBOARD_TYPE Type, const wchar_t *Data) switch (Type) { case FCT_STREAM: - return SetClipboardText(Data, Data? wcslen(Data) : 0); + return SetClipboardText({ NullToEmpty(Data) }); case FCT_COLUMN: - return SetClipboardVText(Data, Data? wcslen(Data) : 0); + return SetClipboardVText({ NullToEmpty(Data) }); default: return FALSE; diff --git a/far/plugins.cpp b/far/plugins.cpp index 342bcc76d6..5d9a5a38fa 100644 --- a/far/plugins.cpp +++ b/far/plugins.cpp @@ -69,7 +69,6 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "string_utils.hpp" #include "cvtname.hpp" #include "delete.hpp" -#include "legacy_cpu_check.hpp" static const wchar_t PluginsFolderName[] = L"Plugins"; @@ -130,12 +129,15 @@ static void CallPluginSynchroEvent(const any& Payload) static void EnsureLuaCpuCompatibility() { - if (!IsLegacyCPU()) +// All AMD64 processors have SSE2 +#ifndef _WIN64 + if (IsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE)) return; static os::rtdl::module LuaModule(Global->g_strFarPath + L"\\legacy\\lua51.dll"); // modules are lazy loaded LuaModule.operator bool(); +#endif } PluginManager::PluginManager(): @@ -817,7 +819,7 @@ int PluginManager::ProcessEditorEvent(int Event, void *Param, const Editor* Edit } -int PluginManager::ProcessSubscribedEditorEvent(int Event, void *Param, const Editor* EditorInstance, const std::unordered_set& PluginIds) const +int PluginManager::ProcessSubscribedEditorEvent(int Event, void *Param, const Editor* EditorInstance, const std::unordered_set& PluginIds) const { int nResult = 0; if (const auto Container = EditorInstance->GetOwner()) diff --git a/far/plugins.hpp b/far/plugins.hpp index 907f1c3233..2568818ad3 100644 --- a/far/plugins.hpp +++ b/far/plugins.hpp @@ -144,7 +144,7 @@ class PluginManager: noncopyable static int Compare(const plugin_panel* hPlugin,const PluginPanelItem *Item1,const PluginPanelItem *Item2,unsigned int Mode); int ProcessEditorInput(const INPUT_RECORD *Rec) const; int ProcessEditorEvent(int Event, void *Param, const Editor* EditorInstance) const; - int ProcessSubscribedEditorEvent(int Event, void *Param, const Editor* EditorInstance, const std::unordered_set& PluginIds) const; + int ProcessSubscribedEditorEvent(int Event, void *Param, const Editor* EditorInstance, const std::unordered_set& PluginIds) const; int ProcessViewerEvent(int Event, void *Param, const Viewer* ViewerInstance) const; int ProcessDialogEvent(int Event,FarDialogEvent *Param) const; int ProcessConsoleInput(ProcessConsoleInputInfo *Info) const; @@ -221,7 +221,7 @@ class PluginManager: noncopyable void LoadPluginsFromCache(); std::vector> PluginFactories; - std::unordered_map, uuid_hash, uuid_equal> m_Plugins; + std::unordered_map, uuid_hash> m_Plugins; plugins_set SortedPlugins; std::list UnloadedPlugins; listener_ex m_PluginSynchro; diff --git a/far/vbuild.m4 b/far/vbuild.m4 index 0a9b682308..151afabb2e 100644 --- a/far/vbuild.m4 +++ b/far/vbuild.m4 @@ -1 +1 @@ -m4_define(BUILD,5019)m4_dnl +m4_define(BUILD,5020)m4_dnl diff --git a/far/viewer.cpp b/far/viewer.cpp index a0c23897aa..9c2025bafe 100644 --- a/far/viewer.cpp +++ b/far/viewer.cpp @@ -1588,7 +1588,7 @@ bool Viewer::process_key(const Manager::Key& Key) long long CurFilePos=vtell(); vseek(SelectPos, FILE_BEGIN); vread(SelData.get(), (int)SelectSize); - SetClipboardText(SelData.get(), SelectSize); + SetClipboardText({ SelData.get(), static_cast(SelectSize) }); vseek(CurFilePos, FILE_BEGIN); } return true;