Common: Use fmt where applicable

Begins the transition to using fmt for string formatting where
applicable. Given fmt supports formatting std::string instances out of
the box, we can remove now-unnecessary calls to .c_str() and .data().

Note that this change does not touch the actual logging subsystem aside
from converting the final StringFromFormat call in the process over to
fmt::format. Given our logging system is heavily used throughout the
entire codebase, and converting that over will be quite a large change
by itself, this will be tackled near the end of the conversion process.
This commit is contained in:
Lioncash
2019-06-14 15:04:09 -04:00
parent 925afcae3b
commit 5b92d5076a
13 changed files with 287 additions and 263 deletions
+4 -3
View File
@@ -10,10 +10,11 @@
#include <sys/auxv.h>
#include <unistd.h>
#include <fmt/format.h>
#include "Common/CPUDetect.h"
#include "Common/CommonTypes.h"
#include "Common/FileUtil.h"
#include "Common/StringUtil.h"
const char procfile[] = "/proc/cpuinfo";
@@ -77,9 +78,9 @@ std::string CPUInfo::Summarize()
{
std::string sum;
if (num_cores == 1)
sum = StringFromFormat("%s, %i core", cpu_string, num_cores);
sum = fmt::format("{}, 1 core", cpu_string);
else
sum = StringFromFormat("%s, %i cores", cpu_string, num_cores);
sum = fmt::format("{}, {} cores", cpu_string, num_cores);
if (bAES)
sum += ", AES";
+13 -8
View File
@@ -9,6 +9,8 @@
#include <string>
#include <vector>
#include <fmt/format.h>
#include "Common/CDUtils.h"
#include "Common/Common.h"
#include "Common/CommonTypes.h"
@@ -134,20 +136,23 @@ std::vector<std::string> GetCDDevices()
}
#else
// checklist: /dev/cdrom, /dev/dvd /dev/hd?, /dev/scd? /dev/sr?
static struct
struct CheckListEntry
{
const char* format;
unsigned int num_min;
unsigned int num_max;
} checklist[] = {
};
constexpr CheckListEntry checklist[] = {
#ifdef __linux__
{"/dev/cdrom", 0, 0}, {"/dev/dvd", 0, 0}, {"/dev/hd%c", 'a', 'z'},
{"/dev/scd%d", 0, 27}, {"/dev/sr%d", 0, 27},
{"/dev/cdrom", 0, 0}, {"/dev/dvd", 0, 0}, {"/dev/hd{}", 'a', 'z'},
{"/dev/scd{}", 0, 27}, {"/dev/sr{}", 0, 27},
#else
{"/dev/acd%d", 0, 27},
{"/dev/cd%d", 0, 27},
{"/dev/acd{}", 0, 27},
{"/dev/cd{}", 0, 27},
#endif
{nullptr, 0, 0}};
{nullptr, 0, 0},
};
// Returns true if a device is a block or char device and not a symbolic link
static bool IsDevice(const std::string& source_name)
@@ -189,7 +194,7 @@ std::vector<std::string> GetCDDevices()
{
for (unsigned int j = checklist[i].num_min; j <= checklist[i].num_max; ++j)
{
std::string drive = StringFromFormat(checklist[i].format, j);
std::string drive = fmt::format(checklist[i].format, j);
if (IsCDROM(drive))
{
drives.push_back(std::move(drive));
+37 -35
View File
@@ -8,6 +8,8 @@
#include <vector>
#include <winternl.h>
#include <fmt/format.h>
#include "Common/CommonTypes.h"
#include "Common/LdrWatcher.h"
#include "Common/StringUtil.h"
@@ -213,41 +215,41 @@ void CompatPatchesInstall(LdrWatcher* watcher)
auto patcher = ImportPatcher(event.base_address);
patcher.PatchIAT("kernel32.dll", "HeapCreate", HeapCreateLow4GB);
}});
watcher->Install({{L"ucrtbase.dll"}, [](const LdrDllLoadEvent& event) {
// ucrtbase implements caching between fseek/fread, old versions have a bug
// such that some reads return incorrect data. This causes noticable bugs
// in dolphin since we use these APIs for reading game images.
Version version;
if (!GetModuleVersion(event.name.c_str(), &version))
return;
const u16 fixed_build = 10548;
if (version.build >= fixed_build)
return;
const UcrtPatchInfo patches[] = {
// 10.0.10240.16384 (th1.150709-1700)
{0xF61ED, 0x6AE7B, 5},
// 10.0.10240.16390 (th1_st1.150714-1601)
{0xF5ED9, 0x6AE7B, 5},
// 10.0.10137.0 (th1.150602-2238)
{0xF8B5E, 0x63ED6, 2},
};
for (const auto& patch : patches)
{
if (ApplyUcrtPatch(event.name.c_str(), patch))
return;
}
// If we reach here, the version is buggy (afaik) and patching failed
auto msg = StringFromFormat(
"You are running %S version %d.%d.%d.%d.\n"
"An important fix affecting Dolphin was introduced in build %d.\n"
"You can use Dolphin, but there will be known bugs.\n"
"Please update this file by installing the latest Universal C Runtime.\n",
event.name.c_str(), version.major, version.minor, version.build,
version.qfe, fixed_build);
// Use MessageBox for maximal user annoyance
MessageBoxA(nullptr, msg.c_str(), "WARNING: BUGGY UCRT VERSION",
MB_ICONEXCLAMATION);
}});
watcher->Install(
{{L"ucrtbase.dll"}, [](const LdrDllLoadEvent& event) {
// ucrtbase implements caching between fseek/fread, old versions have a bug
// such that some reads return incorrect data. This causes noticable bugs
// in dolphin since we use these APIs for reading game images.
Version version;
if (!GetModuleVersion(event.name.c_str(), &version))
return;
const u16 fixed_build = 10548;
if (version.build >= fixed_build)
return;
const UcrtPatchInfo patches[] = {
// 10.0.10240.16384 (th1.150709-1700)
{0xF61ED, 0x6AE7B, 5},
// 10.0.10240.16390 (th1_st1.150714-1601)
{0xF5ED9, 0x6AE7B, 5},
// 10.0.10137.0 (th1.150602-2238)
{0xF8B5E, 0x63ED6, 2},
};
for (const auto& patch : patches)
{
if (ApplyUcrtPatch(event.name.c_str(), patch))
return;
}
// If we reach here, the version is buggy (afaik) and patching failed
const auto msg =
fmt::format("You are running {} version {}.{}.{}.{}.\n"
"An important fix affecting Dolphin was introduced in build {}.\n"
"You can use Dolphin, but there will be known bugs.\n"
"Please update this file by installing the latest Universal C Runtime.\n",
UTF16ToUTF8(event.name), version.major, version.minor, version.build,
version.qfe, fixed_build);
// Use MessageBox for maximal user annoyance
MessageBoxA(nullptr, msg.c_str(), "WARNING: BUGGY UCRT VERSION", MB_ICONEXCLAMATION);
}});
}
int __cdecl EnableCompatPatches()
+13 -10
View File
@@ -3,9 +3,12 @@
// Refer to the license.txt file included.
#include "Common/DynamicLibrary.h"
#include <cstring>
#include <fmt/format.h>
#include "Common/Assert.h"
#include "Common/StringUtil.h"
#ifdef _WIN32
#include <Windows.h>
@@ -42,27 +45,27 @@ std::string DynamicLibrary::GetVersionedFilename(const char* libname, int major,
{
#if defined(_WIN32)
if (major >= 0 && minor >= 0)
return StringFromFormat("%s-%d-%d.dll", libname, major, minor);
return fmt::format("{}-{}-{}.dll", libname, major, minor);
else if (major >= 0)
return StringFromFormat("%s-%d.dll", libname, major);
return fmt::format("{}-{}.dll", libname, major);
else
return StringFromFormat("%s.dll", libname);
return fmt::format("{}.dll", libname);
#elif defined(__APPLE__)
const char* prefix = std::strncmp(libname, "lib", 3) ? "lib" : "";
if (major >= 0 && minor >= 0)
return StringFromFormat("%s%s.%d.%d.dylib", prefix, libname, major, minor);
return fmt::format("{}{}.{}.{}.dylib", prefix, libname, major, minor);
else if (major >= 0)
return StringFromFormat("%s%s.%d.dylib", prefix, libname, major);
return fmt::format("{}{}.{}.dylib", prefix, libname, major);
else
return StringFromFormat("%s%s.dylib", prefix, libname);
return fmt::format("{}{}.dylib", prefix, libname);
#else
const char* prefix = std::strncmp(libname, "lib", 3) ? "lib" : "";
if (major >= 0 && minor >= 0)
return StringFromFormat("%s%s.so.%d.%d", prefix, libname, major, minor);
return fmt::format("{}{}.so.{}.{}", prefix, libname, major, minor);
else if (major >= 0)
return StringFromFormat("%s%s.so.%d", prefix, libname, major);
return fmt::format("{}{}.so.{}", prefix, libname, major);
else
return StringFromFormat("%s%s.so", prefix, libname);
return fmt::format("{}{}.so", prefix, libname);
#endif
}
File diff suppressed because it is too large Load Diff
-36
View File
@@ -93,42 +93,6 @@ private:
static u32* DoDisassembly(bool big_endian);
static u32 HelperRotateMask(int r, int mb, int me)
{
// first make 001111111111111 part
unsigned int begin = 0xFFFFFFFF >> mb;
// then make 000000000001111 part, which is used to flip the bits of the first one
unsigned int end = me < 31 ? (0xFFFFFFFF >> (me + 1)) : 0;
// do the bitflip
unsigned int mask = begin ^ end;
// and invert if backwards
if (me < mb)
mask = ~mask;
// rotate the mask so it can be applied to source reg
// return _rotl(mask, 32 - r);
return (mask << (32 - r)) | (mask >> r);
}
static std::string ldst_offs(u32 val)
{
if (val == 0)
{
return "0";
}
else
{
if (val & 0x8000)
{
return StringFromFormat("-0x%.4X", ((~val) & 0xffff) + 1);
}
else
{
return StringFromFormat("0x%.4X", val);
}
}
}
static int SEX12(u32 x) { return x & 0x800 ? (x | 0xFFFFF000) : x; }
enum InstructionType
{
PPCINSTR_OTHER = 0, // No additional info for other instr.
+13 -12
View File
@@ -2,16 +2,18 @@
// Licensed under GPLv2+
// Refer to the license.txt file included.
#include <cinttypes>
#include "Common/JitRegister.h"
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <fstream>
#include <string>
#include <fmt/format.h>
#include "Common/CommonTypes.h"
#include "Common/File.h"
#include "Common/JitRegister.h"
#include "Common/StringUtil.h"
#ifdef _WIN32
@@ -48,8 +50,8 @@ void Init(const std::string& perf_dir)
if (!perf_dir.empty() || getenv("PERF_BUILDID_DIR"))
{
std::string dir = perf_dir.empty() ? "/tmp" : perf_dir;
std::string filename = StringFromFormat("%s/perf-%d.map", dir.data(), getpid());
const std::string dir = perf_dir.empty() ? "/tmp" : perf_dir;
const std::string filename = fmt::format("{}/perf-{}.map", dir, getpid());
s_perf_map_file.Open(filename, "w");
// Disable buffering in order to avoid missing some mappings
// if the event of a crash:
@@ -90,7 +92,7 @@ void RegisterV(const void* base_address, u32 code_size, const char* format, va_l
std::string symbol_name = StringFromFormatV(format, args);
#if defined USE_OPROFILE && USE_OPROFILE
op_write_native_code(s_agent, symbol_name.data(), (u64)base_address, base_address, code_size);
op_write_native_code(s_agent, symbol_name.c_str(), (u64)base_address, base_address, code_size);
#endif
#ifdef USE_VTUNE
@@ -98,16 +100,15 @@ void RegisterV(const void* base_address, u32 code_size, const char* format, va_l
jmethod.method_id = iJIT_GetNewMethodID();
jmethod.method_load_address = const_cast<void*>(base_address);
jmethod.method_size = code_size;
jmethod.method_name = const_cast<char*>(symbol_name.data());
jmethod.method_name = const_cast<char*>(symbol_name.c_str());
iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, (void*)&jmethod);
#endif
// Linux perf /tmp/perf-$pid.map:
if (s_perf_map_file.IsOpen())
{
std::string entry =
StringFromFormat("%" PRIx64 " %x %s\n", (u64)base_address, code_size, symbol_name.data());
s_perf_map_file.WriteBytes(entry.data(), entry.size());
}
if (!s_perf_map_file.IsOpen())
return;
const auto entry = fmt::format("{} {:x} {}\n", fmt::ptr(base_address), code_size, symbol_name);
s_perf_map_file.WriteBytes(entry.data(), entry.size());
}
} // namespace JitRegister
+7 -4
View File
@@ -2,6 +2,8 @@
// Licensed under GPLv2+
// Refer to the license.txt file included.
#include "Common/Logging/LogManager.h"
#include <algorithm>
#include <cstdarg>
#include <cstring>
@@ -10,12 +12,13 @@
#include <ostream>
#include <string>
#include <fmt/format.h>
#include "Common/CommonPaths.h"
#include "Common/Config/Config.h"
#include "Common/FileUtil.h"
#include "Common/Logging/ConsoleListener.h"
#include "Common/Logging/Log.h"
#include "Common/Logging/LogManager.h"
#include "Common/StringUtil.h"
#include "Common/Timer.h"
@@ -207,9 +210,9 @@ void LogManager::LogWithFullPath(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE
char temp[MAX_MSGLEN];
CharArrayFromFormatV(temp, MAX_MSGLEN, format, args);
std::string msg =
StringFromFormat("%s %s:%u %c[%s]: %s\n", Common::Timer::GetTimeFormatted().c_str(), file,
line, LogTypes::LOG_LEVEL_TO_CHAR[(int)level], GetShortName(type), temp);
const std::string msg =
fmt::format("{} {}:{} {}[{}]: {}\n", Common::Timer::GetTimeFormatted(), file, line,
LogTypes::LOG_LEVEL_TO_CHAR[(int)level], GetShortName(type), temp);
for (auto listener_id : m_listener_ids)
if (m_listeners[listener_id])
+5 -2
View File
@@ -2,12 +2,15 @@
// Licensed under GPLv2+
// Refer to the license.txt file included.
#include "Common/MD5.h"
#include <fstream>
#include <functional>
#include <mbedtls/md5.h>
#include <string>
#include "Common/MD5.h"
#include <fmt/format.h>
#include "Common/StringUtil.h"
#include "DiscIO/Blob.h"
@@ -45,7 +48,7 @@ std::string MD5Sum(const std::string& file_path, std::function<bool(int)> report
// Convert to hex
for (u8 n : output)
output_string += StringFromFormat("%02x", n);
output_string += fmt::format("{:02x}", n);
return output_string;
}
+10 -9
View File
@@ -9,6 +9,8 @@
#include <unordered_set>
#include <vector>
#include <fmt/format.h>
#include "Common/CommonTypes.h"
#include "Common/FileUtil.h"
#include "Common/StringUtil.h"
@@ -28,21 +30,20 @@ static std::string RootUserPath(std::optional<FromWhichRoot> from)
std::string GetImportTitlePath(u64 title_id, std::optional<FromWhichRoot> from)
{
return RootUserPath(from) + StringFromFormat("/import/%08x/%08x",
static_cast<u32>(title_id >> 32),
static_cast<u32>(title_id));
return RootUserPath(from) + fmt::format("/import/{:08x}/{:08x}", static_cast<u32>(title_id >> 32),
static_cast<u32>(title_id));
}
std::string GetTicketFileName(u64 title_id, std::optional<FromWhichRoot> from)
{
return StringFromFormat("%s/ticket/%08x/%08x.tik", RootUserPath(from).c_str(),
static_cast<u32>(title_id >> 32), static_cast<u32>(title_id));
return fmt::format("{}/ticket/{:08x}/{:08x}.tik", RootUserPath(from),
static_cast<u32>(title_id >> 32), static_cast<u32>(title_id));
}
std::string GetTitlePath(u64 title_id, std::optional<FromWhichRoot> from)
{
return StringFromFormat("%s/title/%08x/%08x", RootUserPath(from).c_str(),
static_cast<u32>(title_id >> 32), static_cast<u32>(title_id));
return fmt::format("{}/title/{:08x}/{:08x}", RootUserPath(from), static_cast<u32>(title_id >> 32),
static_cast<u32>(title_id));
}
std::string GetTitleDataPath(u64 title_id, std::optional<FromWhichRoot> from)
@@ -62,7 +63,7 @@ std::string GetTMDFileName(u64 title_id, std::optional<FromWhichRoot> from)
std::string GetMiiDatabasePath(std::optional<FromWhichRoot> from)
{
return StringFromFormat("%s/shared2/menu/FaceLib/RFL_DB.dat", RootUserPath(from).c_str());
return fmt::format("{}/shared2/menu/FaceLib/RFL_DB.dat", RootUserPath(from));
}
bool IsTitlePath(const std::string& path, std::optional<FromWhichRoot> from, u64* title_id)
@@ -111,7 +112,7 @@ std::string EscapeFileName(const std::string& filename)
for (char c : filename_with_escaped_double_underscores)
{
if ((c >= 0 && c <= 0x1F) || chars_to_replace.find(c) != chars_to_replace.end())
result.append(StringFromFormat("__%02x__", c));
result.append(fmt::format("__{:02x}__", c));
else
result.push_back(c);
}
+4 -3
View File
@@ -9,8 +9,9 @@
#include <cstring>
#include <ctime>
#include <fmt/format.h>
#include "Common/Random.h"
#include "Common/StringUtil.h"
namespace Common
{
@@ -38,8 +39,8 @@ MACAddress GenerateMacAddress(const MACConsumer type)
std::string MacAddressToString(const MACAddress& mac)
{
return StringFromFormat("%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4],
mac[5]);
return fmt::format("{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}", mac[0], mac[1], mac[2], mac[3],
mac[4], mac[5]);
}
std::optional<MACAddress> StringToMacAddress(const std::string& mac_string)
+12 -10
View File
@@ -2,8 +2,9 @@
// Licensed under GPLv2+
// Refer to the license.txt file included.
#include "Common/StringUtil.h"
#include <algorithm>
#include <cinttypes>
#include <cstdarg>
#include <cstddef>
#include <cstdio>
@@ -18,11 +19,12 @@
#include <string>
#include <vector>
#include <fmt/format.h>
#include "Common/CommonFuncs.h"
#include "Common/CommonPaths.h"
#include "Common/CommonTypes.h"
#include "Common/Logging/Log.h"
#include "Common/StringUtil.h"
#include "Common/Swap.h"
#ifdef _WIN32
@@ -51,12 +53,12 @@ std::string HexDump(const u8* data, size_t size)
std::string out;
for (size_t row_start = 0; row_start < size; row_start += BYTES_PER_LINE)
{
out += StringFromFormat("%06zx: ", row_start);
out += fmt::format("{:06x}: ", row_start);
for (size_t i = 0; i < BYTES_PER_LINE; ++i)
{
if (row_start + i < size)
{
out += StringFromFormat("%02hhx ", data[row_start + i]);
out += fmt::format("{:02x} ", data[row_start + i]);
}
else
{
@@ -294,27 +296,27 @@ bool TryParse(const std::string& str, bool* const output)
std::string ValueToString(u16 value)
{
return StringFromFormat("0x%04x", value);
return fmt::format("0x{:04x}", value);
}
std::string ValueToString(u32 value)
{
return StringFromFormat("0x%08x", value);
return fmt::format("0x{:08x}", value);
}
std::string ValueToString(u64 value)
{
return StringFromFormat("0x%016" PRIx64, value);
return fmt::format("0x{:016x}", value);
}
std::string ValueToString(float value)
{
return StringFromFormat("%#.9g", value);
return fmt::format("{:#.9g}", value);
}
std::string ValueToString(double value)
{
return StringFromFormat("%#.17g", value);
return fmt::format("{:#.17g}", value);
}
std::string ValueToString(int value)
@@ -324,7 +326,7 @@ std::string ValueToString(int value)
std::string ValueToString(s64 value)
{
return StringFromFormat("%" PRId64, value);
return std::to_string(value);
}
std::string ValueToString(bool value)
+9 -8
View File
@@ -2,7 +2,8 @@
// Licensed under GPLv2+
// Refer to the license.txt file included.
#include <cinttypes>
#include "Common/Timer.h"
#include <ctime>
#include <string>
@@ -16,9 +17,10 @@
#include <sys/time.h>
#endif
#include <fmt/format.h>
#include "Common/CommonTypes.h"
#include "Common/StringUtil.h"
#include "Common/Timer.h"
namespace Common
{
@@ -149,9 +151,8 @@ std::string Timer::GetTimeElapsedFormatted() const
// Hours
u32 Hours = Minutes / 60;
std::string TmpStr = StringFromFormat("%02i:%02i:%02i:%03" PRIu64, Hours, Minutes % 60,
Seconds % 60, Milliseconds % 1000);
return TmpStr;
return fmt::format("{:02}:{:02}:{:02}:{:03}", Hours, Minutes % 60, Seconds % 60,
Milliseconds % 1000);
}
// Get current time
@@ -217,15 +218,15 @@ std::string Timer::GetTimeFormatted()
#ifdef _WIN32
struct timeb tp;
(void)::ftime(&tp);
return UTF16ToUTF8(tmp) + StringFromFormat(":%03i", tp.millitm);
return UTF16ToUTF8(tmp) + fmt::format(":{:03}", tp.millitm);
#elif defined __APPLE__
struct timeval t;
(void)gettimeofday(&t, nullptr);
return StringFromFormat("%s:%03d", tmp, (int)(t.tv_usec / 1000));
return fmt::format("{}:{:03}", tmp, t.tv_usec / 1000);
#else
struct timespec t;
(void)clock_gettime(CLOCK_MONOTONIC, &t);
return StringFromFormat("%s:%03d", tmp, (int)(t.tv_nsec / 1000000));
return fmt::format("{}:{:03}", tmp, t.tv_nsec / 1000000);
#endif
}