From 11a111f0e8a8feec89048e772fbb6c63ce1d21c5 Mon Sep 17 00:00:00 2001 From: Nikhil Narayana Date: Sat, 5 Aug 2023 20:34:15 -0700 Subject: [PATCH] working build on linux --- .github/workflows/main.yml | 2 +- Source/Core/Common/NandPaths.cpp | 8 +- Source/Core/Common/StringUtil.cpp | 41 ++----- Source/Core/Common/StringUtil.h | 109 +++++++++++++----- Source/Core/Core/Core.cpp | 2 +- Source/Core/Core/HW/DVD/FileMonitor.cpp | 2 +- Source/Core/Core/HW/EXI/EXI_DeviceSlippi.cpp | 3 - Source/Core/Core/HW/HW.cpp | 2 + Source/Core/Core/HotkeyManager.cpp | 2 +- Source/Core/Core/IOS/ES/Formats.cpp | 4 +- Source/Core/Core/IOS/FS/HostBackend/FS.cpp | 2 +- Source/Core/Core/IOS/USB/USBV4.cpp | 2 +- Source/Core/Core/Slippi/SlippiPlayback.cpp | 2 +- Source/Core/DiscIO/VolumeWad.cpp | 2 +- .../DolphinQt/Config/FilesystemWidget.cpp | 2 +- .../DolphinQt/Debugger/MemoryViewWidget.cpp | 2 +- Source/Core/DolphinQt/Main.cpp | 2 +- .../ControllerInterface/MappingCommon.cpp | 2 +- Source/Core/UICommon/AutoUpdate.cpp | 2 +- build-linux.sh | 0 20 files changed, 109 insertions(+), 84 deletions(-) mode change 100644 => 100755 build-linux.sh diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 26e1617b9e..f247e4236d 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -119,7 +119,7 @@ jobs: artifact_name: linux-playback build_config: playback name: "Linux ${{ matrix.build_type }}" - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - name: "Checkout" uses: actions/checkout@v2 diff --git a/Source/Core/Common/NandPaths.cpp b/Source/Core/Common/NandPaths.cpp index 9b08cd263d..f933cc03dd 100644 --- a/Source/Core/Common/NandPaths.cpp +++ b/Source/Core/Common/NandPaths.cpp @@ -90,7 +90,8 @@ bool IsTitlePath(const std::string& path, std::optional from, u64 } u32 title_id_high, title_id_low; - if (!AsciiToHex(components[0], title_id_high) || !AsciiToHex(components[1], title_id_low)) + if (Common::FromChars(components[0], title_id_high, 16).ec != std::errc{} || + Common::FromChars(components[1], title_id_low, 16).ec != std::errc{}) { return false; } @@ -155,8 +156,11 @@ std::string UnescapeFileName(const std::string& filename) { u32 character; if (pos + 6 <= result.size() && result[pos + 4] == '_' && result[pos + 5] == '_') - if (AsciiToHex(result.substr(pos + 2, 2), character)) + if (Common::FromChars(std::string_view{result}.substr(pos + 2, 2), character, 16).ec == + std::errc{}) + { result.replace(pos, 6, {static_cast(character)}); + } ++pos; } diff --git a/Source/Core/Common/StringUtil.cpp b/Source/Core/Common/StringUtil.cpp index c2f7d3f9e4..01ff841cfa 100644 --- a/Source/Core/Common/StringUtil.cpp +++ b/Source/Core/Common/StringUtil.cpp @@ -19,7 +19,6 @@ #include #include #include -#include #include #include @@ -78,7 +77,7 @@ std::string HexDump(const u8* data, size_t size) if (row_start + i < size) { char c = static_cast(data[row_start + i]); - out += IsPrintableCharacter(c) ? c : '.'; + out += Common::IsPrintableCharacter(c) ? c : '.'; } } out += "\n"; @@ -86,25 +85,6 @@ std::string HexDump(const u8* data, size_t size) return out; } -// faster than sscanf -bool AsciiToHex(const std::string& _szValue, u32& result) -{ - // Set errno to a good state. - errno = 0; - - char* endptr = nullptr; - const u32 value = strtoul(_szValue.c_str(), &endptr, 16); - - if (!endptr || *endptr) - return false; - - if (errno == ERANGE) - return false; - - result = value; - return true; -} - bool CharArrayFromFormatV(char* out, int outsize, const char* format, va_list args) { int writtenCount; @@ -615,7 +595,7 @@ template std::string CodeToWithFallbacks(const char* tocode, const char* fromcode, const std::basic_string& input, iconv_fallbacks* fallbacks) #else -std::string CodeTo(const char* tocode, const char* fromcode, const std::basic_string& input) +std::string CodeTo(const char* tocode, const char* fromcode, std::basic_string_view input) #endif { std::string result; @@ -650,7 +630,7 @@ std::string CodeTo(const char* tocode, const char* fromcode, const std::basic_st while (src_bytes != 0) { size_t const iconv_result = -#if defined(__OpenBSD__) || defined(__NetBSD__) +#if defined(__NetBSD__) iconv(conv_desc, reinterpret_cast(&src_buffer), &src_bytes, &dst_buffer, &dst_bytes); #else @@ -685,14 +665,6 @@ std::string CodeTo(const char* tocode, const char* fromcode, const std::basic_st return result; } -#ifdef __APPLE__ -template -std::string CodeTo(const char* tocode, const char* fromcode, const std::basic_string& input) -{ - return CodeToWithFallbacks(tocode, fromcode, input, nullptr); -} -#endif - template std::string CodeToUTF8(const char* fromcode, std::basic_string_view input) { @@ -764,7 +736,7 @@ void uc_to_mb_fb(unsigned int code, } #endif -std::string UTF8ToSHIFTJIS(const std::string& input) +std::string UTF8ToSHIFTJIS(std::string_view input) { #ifdef __APPLE__ // Set SHIFTJIS callbacks only if converting to shift jis @@ -846,6 +818,8 @@ std::string PathToString(const std::filesystem::path& path) #endif } +namespace Common +{ #ifdef _WIN32 std::vector CommandLineToUtf8Argv(const wchar_t* command_line) { @@ -883,8 +857,6 @@ std::string GetEscapedHtml(std::string html) return html; } -namespace Common -{ void ToLower(std::string* str) { std::transform(str->begin(), str->end(), str->begin(), [](char c) { return Common::ToLower(c); }); @@ -903,3 +875,4 @@ bool CaseInsensitiveEquals(std::string_view a, std::string_view b) [](char ca, char cb) { return Common::ToLower(ca) == Common::ToLower(cb); }); } } // namespace Common + diff --git a/Source/Core/Common/StringUtil.h b/Source/Core/Common/StringUtil.h index 93e26f225c..6c0a3b003d 100644 --- a/Source/Core/Common/StringUtil.h +++ b/Source/Core/Common/StringUtil.h @@ -3,6 +3,7 @@ #pragma once +#include #include #include #include @@ -17,6 +18,22 @@ #include "Common/CommonTypes.h" +namespace detail +{ +template +constexpr bool IsBooleanEnum() +{ + if constexpr (std::is_enum_v) + { + return std::is_same_v, bool>; + } + else + { + return false; + } +} +} // namespace detail + std::string StringFromFormatV(const char* format, va_list args); std::string StringFromFormat(const char* format, ...) @@ -54,8 +71,10 @@ void TruncateToCString(std::string* s); bool TryParse(const std::string& str, bool* output); -template || std::is_enum_v>* = nullptr> -bool TryParse(const std::string& str, T* output, int base = 0) +template +requires(std::is_integral_v || + (std::is_enum_v && !detail::IsBooleanEnum())) bool TryParse(const std::string& str, + T* output, int base = 0) { char* end_ptr = nullptr; @@ -92,6 +111,17 @@ bool TryParse(const std::string& str, T* output, int base = 0) return true; } +template +requires(detail::IsBooleanEnum()) bool TryParse(const std::string& str, T* output) +{ + bool value; + if (!TryParse(str, &value)) + return false; + + *output = static_cast(value); + return true; +} + template >* = nullptr> bool TryParse(std::string str, T* const output) { @@ -147,8 +177,24 @@ std::string ValueToString(T value) // Generates an hexdump-like representation of a binary data blob. std::string HexDump(const u8* data, size_t size); -// TODO: kill this -bool AsciiToHex(const std::string& _szValue, u32& result); +namespace Common +{ +template >* = nullptr> +std::from_chars_result FromChars(std::string_view sv, T& value, int base = 10) +{ + const char* const first = sv.data(); + const char* const last = first + sv.size(); + return std::from_chars(first, last, value, base); +} +template >* = nullptr> +std::from_chars_result FromChars(std::string_view sv, T& value, + std::chars_format fmt = std::chars_format::general) +{ + const char* const first = sv.data(); + const char* const last = first + sv.size(); + return std::from_chars(first, last, value, fmt); +} +}; // namespace Common std::string TabsToSpaces(int tab_size, std::string str); @@ -230,6 +276,34 @@ inline std::string UTF8ToTStr(std::string_view str) std::filesystem::path StringToPath(std::string_view path); std::string PathToString(const std::filesystem::path& path); +namespace Common +{ +/// Returns whether a character is printable, i.e. whether 0x20 <= c <= 0x7e is true. +/// Use this instead of calling std::isprint directly to ensure +/// the C locale is being used and to avoid possibly undefined behaviour. +inline bool IsPrintableCharacter(char c) +{ + return std::isprint(c, std::locale::classic()); +} + +/// Returns whether a character is a letter, i.e. whether 'a' <= c <= 'z' || 'A' <= c <= 'Z' +/// is true. Use this instead of calling std::isalpha directly to ensure +/// the C locale is being used and to avoid possibly undefined behaviour. +inline bool IsAlpha(char c) +{ + return std::isalpha(c, std::locale::classic()); +} + +inline char ToLower(char ch) +{ + return std::tolower(ch, std::locale::classic()); +} + +inline char ToUpper(char ch) +{ + return std::toupper(ch, std::locale::classic()); +} + // Thousand separator. Turns 12345678 into 12,345,678 template std::string ThousandSeparate(I value, int spaces = 0) @@ -249,39 +323,14 @@ std::string ThousandSeparate(I value, int spaces = 0) #endif } -/// Returns whether a character is printable, i.e. whether 0x20 <= c <= 0x7e is true. -/// Use this instead of calling std::isprint directly to ensure -/// the C locale is being used and to avoid possibly undefined behaviour. -inline bool IsPrintableCharacter(char c) -{ - return std::isprint(c, std::locale::classic()); -} - -/// Returns whether a character is a letter, i.e. whether 'a' <= c <= 'z' || 'A' <= c <= 'Z' -/// is true. Use this instead of calling std::isalpha directly to ensure -/// the C locale is being used and to avoid possibly undefined behaviour. -inline bool IsAlpha(char c) -{ - return std::isalpha(c, std::locale::classic()); -} - #ifdef _WIN32 std::vector CommandLineToUtf8Argv(const wchar_t* command_line); #endif std::string GetEscapedHtml(std::string html); -namespace Common -{ -inline char ToLower(char ch) -{ - return std::tolower(ch, std::locale::classic()); -} -inline char ToUpper(char ch) -{ - return std::toupper(ch, std::locale::classic()); -} void ToLower(std::string* str); void ToUpper(std::string* str); bool CaseInsensitiveEquals(std::string_view a, std::string_view b); } // namespace Common + diff --git a/Source/Core/Core/Core.cpp b/Source/Core/Core/Core.cpp index 4530f78af6..bf7ee6f687 100644 --- a/Source/Core/Core/Core.cpp +++ b/Source/Core/Core/Core.cpp @@ -193,7 +193,7 @@ void DisplayMessage(std::string message, int time_in_ms) return; // Actually displaying non-ASCII could cause things to go pear-shaped - if (!std::all_of(message.begin(), message.end(), IsPrintableCharacter)) + if (!std::all_of(message.begin(), message.end(), Common::IsPrintableCharacter)) return; OSD::AddMessage(std::move(message), time_in_ms); diff --git a/Source/Core/Core/HW/DVD/FileMonitor.cpp b/Source/Core/Core/HW/DVD/FileMonitor.cpp index 6e08006a6a..f4bc53a097 100644 --- a/Source/Core/Core/HW/DVD/FileMonitor.cpp +++ b/Source/Core/Core/HW/DVD/FileMonitor.cpp @@ -77,7 +77,7 @@ void FileLogger::Log(const DiscIO::Volume& volume, const DiscIO::Partition& part if (m_previous_partition == partition && m_previous_file_offset == file_offset) return; - const std::string size_string = ThousandSeparate(file_info->GetSize() / 1000, 7); + const std::string size_string = Common::ThousandSeparate(file_info->GetSize() / 1000, 7); const std::string path = file_info->GetPath(); const std::string log_string = fmt::format("{} kB {}", size_string, path); if (IsSoundFile(path)) diff --git a/Source/Core/Core/HW/EXI/EXI_DeviceSlippi.cpp b/Source/Core/Core/HW/EXI/EXI_DeviceSlippi.cpp index bd04302983..b36b708c4f 100644 --- a/Source/Core/Core/HW/EXI/EXI_DeviceSlippi.cpp +++ b/Source/Core/Core/HW/EXI/EXI_DeviceSlippi.cpp @@ -2698,9 +2698,6 @@ void CEXISlippi::handleLogInRequest() bool logInRes = user->AttemptLogin(); if (!logInRes) { - if (Host_RendererIsFullscreen()) - Host_Fullscreen(); - Host_LowerWindow(); user->OpenLogInPage(); user->ListenForLogIn(); } diff --git a/Source/Core/Core/HW/HW.cpp b/Source/Core/Core/HW/HW.cpp index debbf8d5da..48c5378fed 100644 --- a/Source/Core/Core/HW/HW.cpp +++ b/Source/Core/Core/HW/HW.cpp @@ -1,6 +1,8 @@ // Copyright 2008 Dolphin Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include + #include "Core/HW/HW.h" #include "Common/ChunkFile.h" diff --git a/Source/Core/Core/HotkeyManager.cpp b/Source/Core/Core/HotkeyManager.cpp index 82cfc051f2..683d8081f8 100644 --- a/Source/Core/Core/HotkeyManager.cpp +++ b/Source/Core/Core/HotkeyManager.cpp @@ -15,7 +15,7 @@ #include "Common/FileUtil.h" #include "Common/IniFile.h" #include "Common/StringUtil.h" -#include "Core/Config/Mainsettings.h" +#include "Core/Config/MainSettings.h" #include "Core/ConfigManager.h" #include "InputCommon/ControllerEmu/Control/Input.h" diff --git a/Source/Core/Core/IOS/ES/Formats.cpp b/Source/Core/Core/IOS/ES/Formats.cpp index cccf5086b8..be932cd29a 100644 --- a/Source/Core/Core/IOS/ES/Formats.cpp +++ b/Source/Core/Core/IOS/ES/Formats.cpp @@ -302,7 +302,7 @@ std::string TMDReader::GetGameID() const std::memcpy(game_id, m_bytes.data() + offsetof(TMDHeader, title_id) + 4, 4); std::memcpy(game_id + 4, m_bytes.data() + offsetof(TMDHeader, group_id), 2); - if (std::all_of(std::begin(game_id), std::end(game_id), IsPrintableCharacter)) + if (std::all_of(std::begin(game_id), std::end(game_id), Common::IsPrintableCharacter)) return std::string(game_id, sizeof(game_id)); return fmt::format("{:016x}", GetTitleId()); @@ -313,7 +313,7 @@ std::string TMDReader::GetGameTDBID() const const u8* begin = m_bytes.data() + offsetof(TMDHeader, title_id) + 4; const u8* end = begin + 4; - if (std::all_of(begin, end, IsPrintableCharacter)) + if (std::all_of(begin, end, Common::IsPrintableCharacter)) return std::string(begin, end); return fmt::format("{:016x}", GetTitleId()); diff --git a/Source/Core/Core/IOS/FS/HostBackend/FS.cpp b/Source/Core/Core/IOS/FS/HostBackend/FS.cpp index 2b2cf16be1..4e6d785945 100644 --- a/Source/Core/Core/IOS/FS/HostBackend/FS.cpp +++ b/Source/Core/Core/IOS/FS/HostBackend/FS.cpp @@ -433,7 +433,7 @@ ResultCode HostFileSystem::Format(Uid uid) ResultCode HostFileSystem::CreateFileOrDirectory(Uid uid, Gid gid, const std::string& path, FileAttribute attr, Modes modes, bool is_file) { - if (!IsValidNonRootPath(path) || !std::all_of(path.begin(), path.end(), IsPrintableCharacter)) + if (!IsValidNonRootPath(path) || !std::all_of(path.begin(), path.end(), Common::IsPrintableCharacter)) return ResultCode::Invalid; if (!is_file && std::count(path.begin(), path.end(), '/') > int(MaxPathDepth)) diff --git a/Source/Core/Core/IOS/USB/USBV4.cpp b/Source/Core/Core/IOS/USB/USBV4.cpp index 973f15f739..0d2cca9c7f 100644 --- a/Source/Core/Core/IOS/USB/USBV4.cpp +++ b/Source/Core/Core/IOS/USB/USBV4.cpp @@ -86,7 +86,7 @@ void V4GetUSStringMessage::OnTransferComplete(s32 return_value) const auto& memory = system.GetMemory(); std::string message = memory.GetString(data_address); - std::replace_if(message.begin(), message.end(), std::not_fn(IsPrintableCharacter), '?'); + std::replace_if(message.begin(), message.end(), std::not_fn(Common::IsPrintableCharacter), '?'); memory.CopyToEmu(data_address, message.c_str(), message.size()); TransferCommand::OnTransferComplete(return_value); } diff --git a/Source/Core/Core/Slippi/SlippiPlayback.cpp b/Source/Core/Core/Slippi/SlippiPlayback.cpp index ce9a55a2f1..4fe9e1c5ab 100644 --- a/Source/Core/Core/Slippi/SlippiPlayback.cpp +++ b/Source/Core/Core/Slippi/SlippiPlayback.cpp @@ -456,7 +456,7 @@ void SlippiPlaybackStatus::generateDenylist() // Add injection to denylist u32 address; auto addressStr = readString(injection, "InjectionAddress"); - if (!AsciiToHex(addressStr, address)) + if (Common::FromChars(addressStr, address, 16).ec != std::errc{}) { ERROR_LOG_FMT(SLIPPI, "Injection list file {}: Could not parse address: {}", entry.physicalName, addressStr); diff --git a/Source/Core/DiscIO/VolumeWad.cpp b/Source/Core/DiscIO/VolumeWad.cpp index 81e2912671..4058497546 100644 --- a/Source/Core/DiscIO/VolumeWad.cpp +++ b/Source/Core/DiscIO/VolumeWad.cpp @@ -256,7 +256,7 @@ std::string VolumeWAD::GetMakerID(const Partition& partition) const return "00"; // Some weird channels use 0x0000 in place of the MakerID, so we need a check here - if (!IsPrintableCharacter(temp[0]) || !IsPrintableCharacter(temp[1])) + if (!Common::IsPrintableCharacter(temp[0]) || !Common::IsPrintableCharacter(temp[1])) return "00"; return DecodeString(temp); diff --git a/Source/Core/DolphinQt/Config/FilesystemWidget.cpp b/Source/Core/DolphinQt/Config/FilesystemWidget.cpp index d9d053f0b1..cff2bf4215 100644 --- a/Source/Core/DolphinQt/Config/FilesystemWidget.cpp +++ b/Source/Core/DolphinQt/Config/FilesystemWidget.cpp @@ -167,7 +167,7 @@ void FilesystemWidget::PopulateDirectory(int partition_id, QStandardItem* root, for (u32 i = 0; i < 4; i++) { char c = static_cast(title_id.value() >> 8 * (3 - i)); - if (IsPrintableCharacter(c)) + if (Common::IsPrintableCharacter(c)) text += QLatin1Char(c); else text += QLatin1Char('.'); diff --git a/Source/Core/DolphinQt/Debugger/MemoryViewWidget.cpp b/Source/Core/DolphinQt/Debugger/MemoryViewWidget.cpp index 46db6477d4..b83abb0b08 100644 --- a/Source/Core/DolphinQt/Debugger/MemoryViewWidget.cpp +++ b/Source/Core/DolphinQt/Debugger/MemoryViewWidget.cpp @@ -495,7 +495,7 @@ QString MemoryViewWidget::ValueToString(const Core::CPUThreadGuard& guard, u32 a case Type::ASCII: { const char value = accessors->ReadU8(guard, address); - return IsPrintableCharacter(value) ? QString{QChar::fromLatin1(value)} : + return Common::IsPrintableCharacter(value) ? QString{QChar::fromLatin1(value)} : QString{QChar::fromLatin1('.')}; } case Type::Hex16: diff --git a/Source/Core/DolphinQt/Main.cpp b/Source/Core/DolphinQt/Main.cpp index 2d547037a8..cf88a0c690 100644 --- a/Source/Core/DolphinQt/Main.cpp +++ b/Source/Core/DolphinQt/Main.cpp @@ -296,7 +296,7 @@ int main(int argc, char* argv[]) #ifdef _WIN32 int WINAPI wWinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ LPWSTR, _In_ int) { - std::vector args = CommandLineToUtf8Argv(GetCommandLineW()); + std::vector args = Common::CommandLineToUtf8Argv(GetCommandLineW()); const int argc = static_cast(args.size()); std::vector argv(args.size()); for (size_t i = 0; i < args.size(); ++i) diff --git a/Source/Core/InputCommon/ControllerInterface/MappingCommon.cpp b/Source/Core/InputCommon/ControllerInterface/MappingCommon.cpp index 1c3e997769..e28e044866 100644 --- a/Source/Core/InputCommon/ControllerInterface/MappingCommon.cpp +++ b/Source/Core/InputCommon/ControllerInterface/MappingCommon.cpp @@ -43,7 +43,7 @@ std::string GetExpressionForControl(const std::string& control_name, { // If our expression contains any non-alpha characters // we should quote it - if (!std::all_of(expr.begin(), expr.end(), IsAlpha)) + if (!std::all_of(expr.begin(), expr.end(), Common::IsAlpha)) expr = fmt::format("`{}`", expr); } diff --git a/Source/Core/UICommon/AutoUpdate.cpp b/Source/Core/UICommon/AutoUpdate.cpp index b67c499c14..0c833ae582 100644 --- a/Source/Core/UICommon/AutoUpdate.cpp +++ b/Source/Core/UICommon/AutoUpdate.cpp @@ -116,7 +116,7 @@ std::string GenerateChangelog(const picojson::array& versions) changelog += ver_obj["shortrev"].get(); } const std::string escaped_description = - GetEscapedHtml(ver_obj["short_descr"].get()); + Common::GetEscapedHtml(ver_obj["short_descr"].get()); changelog += " by () + "\">" + ver_obj["author"].get() + " — " + escaped_description; } diff --git a/build-linux.sh b/build-linux.sh old mode 100644 new mode 100755