From 86bb01ba9eac879d3685c439ac9da0028bc4bc80 Mon Sep 17 00:00:00 2001 From: Mikaƫl Capelle Date: Tue, 17 May 2022 11:37:19 +0200 Subject: Convert everything to CRLF. --- src/shared/util.cpp | 888 ++++++++++++++++++++++++++-------------------------- 1 file changed, 444 insertions(+), 444 deletions(-) (limited to 'src/shared/util.cpp') diff --git a/src/shared/util.cpp b/src/shared/util.cpp index 54c6b841..e2faaec5 100644 --- a/src/shared/util.cpp +++ b/src/shared/util.cpp @@ -1,444 +1,444 @@ -/* -Copyright (C) 2012 Sebastian Herbord. All rights reserved. - -This file is part of Mod Organizer. - -Mod Organizer is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -Mod Organizer is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Mod Organizer. If not, see . -*/ - -#include "util.h" -#include "windows_error.h" -#include "../mainwindow.h" -#include "../env.h" -#include -#include -#include - -using namespace MOBase; - -namespace MOShared -{ - -bool FileExists(const std::string &filename) -{ - DWORD dwAttrib = ::GetFileAttributesA(filename.c_str()); - - return (dwAttrib != INVALID_FILE_ATTRIBUTES); -} - -bool FileExists(const std::wstring &filename) -{ - DWORD dwAttrib = ::GetFileAttributesW(filename.c_str()); - - return (dwAttrib != INVALID_FILE_ATTRIBUTES); -} - -bool FileExists(const std::wstring &searchPath, const std::wstring &filename) -{ - std::wstringstream stream; - stream << searchPath << "\\" << filename; - return FileExists(stream.str()); -} - -std::string ToString(const std::wstring &source, bool utf8) -{ - std::string result; - if (source.length() > 0) { - UINT codepage = CP_UTF8; - if (!utf8) { - codepage = AreFileApisANSI() ? GetACP() : GetOEMCP(); - } - int sizeRequired = ::WideCharToMultiByte(codepage, 0, &source[0], -1, nullptr, 0, nullptr, nullptr); - if (sizeRequired == 0) { - throw windows_error("failed to convert string to multibyte"); - } - // the size returned by WideCharToMultiByte contains zero termination IF -1 is specified for the length. - // we don't want that \0 in the string because then the length field would be wrong. Because madness - result.resize(sizeRequired - 1, '\0'); - ::WideCharToMultiByte(codepage, 0, &source[0], (int)source.size(), &result[0], sizeRequired, nullptr, nullptr); - } - - return result; -} - -std::wstring ToWString(const std::string &source, bool utf8) -{ - std::wstring result; - if (source.length() > 0) { - UINT codepage = CP_UTF8; - if (!utf8) { - codepage = AreFileApisANSI() ? GetACP() : GetOEMCP(); - } - int sizeRequired - = ::MultiByteToWideChar(codepage, 0, source.c_str(), - static_cast(source.length()), nullptr, 0); - if (sizeRequired == 0) { - throw windows_error("failed to convert string to wide character"); - } - result.resize(sizeRequired, L'\0'); - ::MultiByteToWideChar(codepage, 0, source.c_str(), - static_cast(source.length()), &result[0], - sizeRequired); - } - - return result; -} - -static std::locale loc(""); -static auto locToLowerW = [] (wchar_t in) -> wchar_t { - return std::tolower(in, loc); -}; - -static auto locToLower = [] (char in) -> char { - return std::tolower(in, loc); -}; - -std::string& ToLowerInPlace(std::string& text) -{ - CharLowerBuffA(const_cast(text.c_str()), static_cast(text.size())); - return text; -} - -std::string ToLowerCopy(const std::string& text) -{ - std::string result(text); - CharLowerBuffA(const_cast(result.c_str()), static_cast(result.size())); - return result; -} - -std::wstring& ToLowerInPlace(std::wstring& text) -{ - CharLowerBuffW(const_cast(text.c_str()), static_cast(text.size())); - return text; -} - -std::wstring ToLowerCopy(const std::wstring& text) -{ - std::wstring result(text); - CharLowerBuffW(const_cast(result.c_str()), static_cast(result.size())); - return result; -} - -std::wstring ToLowerCopy(std::wstring_view text) -{ - std::wstring result(text.begin(), text.end()); - ToLowerInPlace(result); - return result; -} - -bool CaseInsenstiveComparePred(wchar_t lhs, wchar_t rhs) -{ - return std::tolower(lhs, loc) == std::tolower(rhs, loc); -} - -bool CaseInsensitiveEqual(const std::wstring &lhs, const std::wstring &rhs) -{ - return (lhs.length() == rhs.length()) - && std::equal(lhs.begin(), lhs.end(), - rhs.begin(), - [] (wchar_t lhs, wchar_t rhs) -> bool { - return std::tolower(lhs, loc) == std::tolower(rhs, loc); - }); -} - -VS_FIXEDFILEINFO GetFileVersion(const std::wstring &fileName) -{ - DWORD handle = 0UL; - DWORD size = ::GetFileVersionInfoSizeW(fileName.c_str(), &handle); - if (size == 0) { - throw windows_error("failed to determine file version info size"); - } - - boost::scoped_array buffer(new char[size]); - try { - handle = 0UL; - if (!::GetFileVersionInfoW(fileName.c_str(), handle, size, buffer.get())) { - throw windows_error("failed to determine file version info"); - } - - void *versionInfoPtr = nullptr; - UINT versionInfoLength = 0; - if (!::VerQueryValue(buffer.get(), L"\\", &versionInfoPtr, &versionInfoLength)) { - throw windows_error("failed to determine file version"); - } - - VS_FIXEDFILEINFO result = *(VS_FIXEDFILEINFO*)versionInfoPtr; - return result; - } catch (...) { - throw; - } -} - -std::wstring GetFileVersionString(const std::wstring &fileName) -{ - DWORD handle = 0UL; - DWORD size = ::GetFileVersionInfoSizeW(fileName.c_str(), &handle); - if (size == 0) { - throw windows_error("failed to determine file version info size"); - } - - boost::scoped_array buffer(new char[size]); - try { - handle = 0UL; - if (!::GetFileVersionInfoW(fileName.c_str(), handle, size, buffer.get())) { - throw windows_error("failed to determine file version info"); - } - - LPVOID strBuffer = nullptr; - UINT strLength = 0; - if (!::VerQueryValue(buffer.get(), L"\\StringFileInfo\\040904B0\\ProductVersion", &strBuffer, &strLength)) { - throw windows_error("failed to determine file version"); - } - - return std::wstring((LPCTSTR)strBuffer); - } - catch (...) { - throw; - } -} - -VersionInfo createVersionInfo() -{ - VS_FIXEDFILEINFO version = GetFileVersion(env::thisProcessPath().native()); - - if (version.dwFileFlags & VS_FF_PRERELEASE) - { - // Pre-release builds need annotating - QString versionString = QString::fromStdWString( - GetFileVersionString(env::thisProcessPath().native())); - - // The pre-release flag can be set without the string specifying what type of pre-release - bool noLetters = true; - for (QChar character : versionString) - { - if (character.isLetter()) - { - noLetters = false; - break; - } - } - - if (noLetters) - { - // Default to pre-alpha when release type is unspecified - return VersionInfo(version.dwFileVersionMS >> 16, - version.dwFileVersionMS & 0xFFFF, - version.dwFileVersionLS >> 16, - version.dwFileVersionLS & 0xFFFF, - VersionInfo::RELEASE_PREALPHA); - } - else - { - // Trust the string to make sense - return VersionInfo(versionString); - } - } - else - { - // Non-pre-release builds just need their version numbers reading - return VersionInfo(version.dwFileVersionMS >> 16, - version.dwFileVersionMS & 0xFFFF, - version.dwFileVersionLS >> 16, - version.dwFileVersionLS & 0xFFFF); - } -} - -QString getUsvfsDLLVersion() -{ - // once 2.2.2 is released, this can be changed to call USVFSVersionString() - // directly; until then, using GetProcAddress() allows for mixing up devbuilds - // and usvfs dlls - - using USVFSVersionStringType = const char* WINAPI (); - - QString s; - - const auto m = ::LoadLibraryW(L"usvfs_x64.dll"); - - if (m) { - auto* f = reinterpret_cast( - ::GetProcAddress(m, "USVFSVersionString")); - - if (f) { - s = f(); - } - - ::FreeLibrary(m); - } - - if (s.isEmpty()) { - s = "?"; - } - - return s; -} - -QString getUsvfsVersionString() -{ - const QString dll = getUsvfsDLLVersion(); - const QString header = USVFS_VERSION_STRING; - - QString usvfsVersion; - - if (dll == header) { - return dll; - } else { - return "dll is " + dll + ", compiled against " + header; - } -} - -void SetThisThreadName(const QString& s) -{ - using SetThreadDescriptionType = HRESULT ( - HANDLE hThread, - PCWSTR lpThreadDescription - ); - - static SetThreadDescriptionType* SetThreadDescription = [] { - SetThreadDescriptionType* p = nullptr; - - env::LibraryPtr kernel32(LoadLibraryW(L"kernel32.dll")); - if (!kernel32) { - return p; - } - - p = reinterpret_cast( - GetProcAddress(kernel32.get(), "SetThreadDescription")); - - return p; - }(); - - if (SetThreadDescription) { - SetThreadDescription(GetCurrentThread(), s.toStdWString().c_str()); - } -} - - -char shortcutChar(const QAction* a) -{ - const auto text = a->text(); - char shortcut = 0; - - for (int i=0; i= (text.size() - 1)) { - log::error("ampersand at the end"); - return 0; - } - - return text[i + 1].toLatin1(); - } - } - - log::error("action {} has no shortcut", text); - return 0; -} - -void checkDuplicateShortcuts(const QMenu& m) -{ - const auto actions = m.actions(); - - for (int i=0; iisSeparator()) { - continue; - } - - const char shortcut1 = shortcutChar(action1); - if (shortcut1 == 0) { - continue; - } - - for (int j=i+1; jisSeparator()) { - continue; - } - - const char shortcut2 = shortcutChar(action2); - - if (shortcut1 == shortcut2) { - log::error( - "duplicate shortcut {} for {} and {}", - shortcut1, action1->text(), action2->text()); - - break; - } - } - } -} - -} // namespace MOShared - - -static bool g_exiting = false; -static bool g_canClose = false; - -MainWindow* findMainWindow() -{ - for (auto* tl : qApp->topLevelWidgets()) { - if (auto* mw=dynamic_cast(tl)) { - return mw; - } - } - - return nullptr; -} - -bool ExitModOrganizer(ExitFlags e) -{ - if (g_exiting) { - return true; - } - - g_exiting = true; - Guard g([&]{ g_exiting = false; }); - - if (!e.testFlag(Exit::Force)) { - if (auto* mw=findMainWindow()) { - if (!mw->canExit()) { - return false; - } - } - } - - g_canClose = true; - - const int code = (e.testFlag(Exit::Restart) ? RestartExitCode : 0); - qApp->exit(code); - - return true; -} - -bool ModOrganizerCanCloseNow() -{ - return g_canClose; -} - -bool ModOrganizerExiting() -{ - return g_exiting; -} - -void ResetExitFlag() -{ - g_exiting = false; -} - - -bool isNxmLink(const QString& link) -{ - return link.startsWith("nxm://", Qt::CaseInsensitive); -} +/* +Copyright (C) 2012 Sebastian Herbord. All rights reserved. + +This file is part of Mod Organizer. + +Mod Organizer is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Mod Organizer is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Mod Organizer. If not, see . +*/ + +#include "util.h" +#include "windows_error.h" +#include "../mainwindow.h" +#include "../env.h" +#include +#include +#include + +using namespace MOBase; + +namespace MOShared +{ + +bool FileExists(const std::string &filename) +{ + DWORD dwAttrib = ::GetFileAttributesA(filename.c_str()); + + return (dwAttrib != INVALID_FILE_ATTRIBUTES); +} + +bool FileExists(const std::wstring &filename) +{ + DWORD dwAttrib = ::GetFileAttributesW(filename.c_str()); + + return (dwAttrib != INVALID_FILE_ATTRIBUTES); +} + +bool FileExists(const std::wstring &searchPath, const std::wstring &filename) +{ + std::wstringstream stream; + stream << searchPath << "\\" << filename; + return FileExists(stream.str()); +} + +std::string ToString(const std::wstring &source, bool utf8) +{ + std::string result; + if (source.length() > 0) { + UINT codepage = CP_UTF8; + if (!utf8) { + codepage = AreFileApisANSI() ? GetACP() : GetOEMCP(); + } + int sizeRequired = ::WideCharToMultiByte(codepage, 0, &source[0], -1, nullptr, 0, nullptr, nullptr); + if (sizeRequired == 0) { + throw windows_error("failed to convert string to multibyte"); + } + // the size returned by WideCharToMultiByte contains zero termination IF -1 is specified for the length. + // we don't want that \0 in the string because then the length field would be wrong. Because madness + result.resize(sizeRequired - 1, '\0'); + ::WideCharToMultiByte(codepage, 0, &source[0], (int)source.size(), &result[0], sizeRequired, nullptr, nullptr); + } + + return result; +} + +std::wstring ToWString(const std::string &source, bool utf8) +{ + std::wstring result; + if (source.length() > 0) { + UINT codepage = CP_UTF8; + if (!utf8) { + codepage = AreFileApisANSI() ? GetACP() : GetOEMCP(); + } + int sizeRequired + = ::MultiByteToWideChar(codepage, 0, source.c_str(), + static_cast(source.length()), nullptr, 0); + if (sizeRequired == 0) { + throw windows_error("failed to convert string to wide character"); + } + result.resize(sizeRequired, L'\0'); + ::MultiByteToWideChar(codepage, 0, source.c_str(), + static_cast(source.length()), &result[0], + sizeRequired); + } + + return result; +} + +static std::locale loc(""); +static auto locToLowerW = [] (wchar_t in) -> wchar_t { + return std::tolower(in, loc); +}; + +static auto locToLower = [] (char in) -> char { + return std::tolower(in, loc); +}; + +std::string& ToLowerInPlace(std::string& text) +{ + CharLowerBuffA(const_cast(text.c_str()), static_cast(text.size())); + return text; +} + +std::string ToLowerCopy(const std::string& text) +{ + std::string result(text); + CharLowerBuffA(const_cast(result.c_str()), static_cast(result.size())); + return result; +} + +std::wstring& ToLowerInPlace(std::wstring& text) +{ + CharLowerBuffW(const_cast(text.c_str()), static_cast(text.size())); + return text; +} + +std::wstring ToLowerCopy(const std::wstring& text) +{ + std::wstring result(text); + CharLowerBuffW(const_cast(result.c_str()), static_cast(result.size())); + return result; +} + +std::wstring ToLowerCopy(std::wstring_view text) +{ + std::wstring result(text.begin(), text.end()); + ToLowerInPlace(result); + return result; +} + +bool CaseInsenstiveComparePred(wchar_t lhs, wchar_t rhs) +{ + return std::tolower(lhs, loc) == std::tolower(rhs, loc); +} + +bool CaseInsensitiveEqual(const std::wstring &lhs, const std::wstring &rhs) +{ + return (lhs.length() == rhs.length()) + && std::equal(lhs.begin(), lhs.end(), + rhs.begin(), + [] (wchar_t lhs, wchar_t rhs) -> bool { + return std::tolower(lhs, loc) == std::tolower(rhs, loc); + }); +} + +VS_FIXEDFILEINFO GetFileVersion(const std::wstring &fileName) +{ + DWORD handle = 0UL; + DWORD size = ::GetFileVersionInfoSizeW(fileName.c_str(), &handle); + if (size == 0) { + throw windows_error("failed to determine file version info size"); + } + + boost::scoped_array buffer(new char[size]); + try { + handle = 0UL; + if (!::GetFileVersionInfoW(fileName.c_str(), handle, size, buffer.get())) { + throw windows_error("failed to determine file version info"); + } + + void *versionInfoPtr = nullptr; + UINT versionInfoLength = 0; + if (!::VerQueryValue(buffer.get(), L"\\", &versionInfoPtr, &versionInfoLength)) { + throw windows_error("failed to determine file version"); + } + + VS_FIXEDFILEINFO result = *(VS_FIXEDFILEINFO*)versionInfoPtr; + return result; + } catch (...) { + throw; + } +} + +std::wstring GetFileVersionString(const std::wstring &fileName) +{ + DWORD handle = 0UL; + DWORD size = ::GetFileVersionInfoSizeW(fileName.c_str(), &handle); + if (size == 0) { + throw windows_error("failed to determine file version info size"); + } + + boost::scoped_array buffer(new char[size]); + try { + handle = 0UL; + if (!::GetFileVersionInfoW(fileName.c_str(), handle, size, buffer.get())) { + throw windows_error("failed to determine file version info"); + } + + LPVOID strBuffer = nullptr; + UINT strLength = 0; + if (!::VerQueryValue(buffer.get(), L"\\StringFileInfo\\040904B0\\ProductVersion", &strBuffer, &strLength)) { + throw windows_error("failed to determine file version"); + } + + return std::wstring((LPCTSTR)strBuffer); + } + catch (...) { + throw; + } +} + +VersionInfo createVersionInfo() +{ + VS_FIXEDFILEINFO version = GetFileVersion(env::thisProcessPath().native()); + + if (version.dwFileFlags & VS_FF_PRERELEASE) + { + // Pre-release builds need annotating + QString versionString = QString::fromStdWString( + GetFileVersionString(env::thisProcessPath().native())); + + // The pre-release flag can be set without the string specifying what type of pre-release + bool noLetters = true; + for (QChar character : versionString) + { + if (character.isLetter()) + { + noLetters = false; + break; + } + } + + if (noLetters) + { + // Default to pre-alpha when release type is unspecified + return VersionInfo(version.dwFileVersionMS >> 16, + version.dwFileVersionMS & 0xFFFF, + version.dwFileVersionLS >> 16, + version.dwFileVersionLS & 0xFFFF, + VersionInfo::RELEASE_PREALPHA); + } + else + { + // Trust the string to make sense + return VersionInfo(versionString); + } + } + else + { + // Non-pre-release builds just need their version numbers reading + return VersionInfo(version.dwFileVersionMS >> 16, + version.dwFileVersionMS & 0xFFFF, + version.dwFileVersionLS >> 16, + version.dwFileVersionLS & 0xFFFF); + } +} + +QString getUsvfsDLLVersion() +{ + // once 2.2.2 is released, this can be changed to call USVFSVersionString() + // directly; until then, using GetProcAddress() allows for mixing up devbuilds + // and usvfs dlls + + using USVFSVersionStringType = const char* WINAPI (); + + QString s; + + const auto m = ::LoadLibraryW(L"usvfs_x64.dll"); + + if (m) { + auto* f = reinterpret_cast( + ::GetProcAddress(m, "USVFSVersionString")); + + if (f) { + s = f(); + } + + ::FreeLibrary(m); + } + + if (s.isEmpty()) { + s = "?"; + } + + return s; +} + +QString getUsvfsVersionString() +{ + const QString dll = getUsvfsDLLVersion(); + const QString header = USVFS_VERSION_STRING; + + QString usvfsVersion; + + if (dll == header) { + return dll; + } else { + return "dll is " + dll + ", compiled against " + header; + } +} + +void SetThisThreadName(const QString& s) +{ + using SetThreadDescriptionType = HRESULT ( + HANDLE hThread, + PCWSTR lpThreadDescription + ); + + static SetThreadDescriptionType* SetThreadDescription = [] { + SetThreadDescriptionType* p = nullptr; + + env::LibraryPtr kernel32(LoadLibraryW(L"kernel32.dll")); + if (!kernel32) { + return p; + } + + p = reinterpret_cast( + GetProcAddress(kernel32.get(), "SetThreadDescription")); + + return p; + }(); + + if (SetThreadDescription) { + SetThreadDescription(GetCurrentThread(), s.toStdWString().c_str()); + } +} + + +char shortcutChar(const QAction* a) +{ + const auto text = a->text(); + char shortcut = 0; + + for (int i=0; i= (text.size() - 1)) { + log::error("ampersand at the end"); + return 0; + } + + return text[i + 1].toLatin1(); + } + } + + log::error("action {} has no shortcut", text); + return 0; +} + +void checkDuplicateShortcuts(const QMenu& m) +{ + const auto actions = m.actions(); + + for (int i=0; iisSeparator()) { + continue; + } + + const char shortcut1 = shortcutChar(action1); + if (shortcut1 == 0) { + continue; + } + + for (int j=i+1; jisSeparator()) { + continue; + } + + const char shortcut2 = shortcutChar(action2); + + if (shortcut1 == shortcut2) { + log::error( + "duplicate shortcut {} for {} and {}", + shortcut1, action1->text(), action2->text()); + + break; + } + } + } +} + +} // namespace MOShared + + +static bool g_exiting = false; +static bool g_canClose = false; + +MainWindow* findMainWindow() +{ + for (auto* tl : qApp->topLevelWidgets()) { + if (auto* mw=dynamic_cast(tl)) { + return mw; + } + } + + return nullptr; +} + +bool ExitModOrganizer(ExitFlags e) +{ + if (g_exiting) { + return true; + } + + g_exiting = true; + Guard g([&]{ g_exiting = false; }); + + if (!e.testFlag(Exit::Force)) { + if (auto* mw=findMainWindow()) { + if (!mw->canExit()) { + return false; + } + } + } + + g_canClose = true; + + const int code = (e.testFlag(Exit::Restart) ? RestartExitCode : 0); + qApp->exit(code); + + return true; +} + +bool ModOrganizerCanCloseNow() +{ + return g_canClose; +} + +bool ModOrganizerExiting() +{ + return g_exiting; +} + +void ResetExitFlag() +{ + g_exiting = false; +} + + +bool isNxmLink(const QString& link) +{ + return link.startsWith("nxm://", Qt::CaseInsensitive); +} -- cgit v1.3.1