Some code cleanup.

This commit is contained in:
Leon Styhre 2022-12-14 17:30:34 +01:00
parent 59d5e1b5b8
commit ab31eafaca
4 changed files with 302 additions and 290 deletions

View file

@ -40,6 +40,7 @@ FileData::FileData(FileType type,
, mEnvData {envData} , mEnvData {envData}
, mSystem {system} , mSystem {system}
, mOnlyFolders {false} , mOnlyFolders {false}
, mHasFolders {false}
, mUpdateChildrenLastPlayed {false} , mUpdateChildrenLastPlayed {false}
, mUpdateChildrenMostPlayed {false} , mUpdateChildrenMostPlayed {false}
, mDeletionFlag {false} , mDeletionFlag {false}
@ -76,7 +77,7 @@ FileData::~FileData()
std::string FileData::getDisplayName() const std::string FileData::getDisplayName() const
{ {
std::string stem {Utils::FileSystem::getStem(mPath)}; const std::string& stem {Utils::FileSystem::getStem(mPath)};
return stem; return stem;
} }
@ -167,7 +168,7 @@ const std::vector<FileData*> FileData::getChildrenRecursive() const
const std::string FileData::getROMDirectory() const std::string FileData::getROMDirectory()
{ {
std::string romDirSetting {Settings::getInstance()->getString("ROMDirectory")}; const std::string& romDirSetting {Settings::getInstance()->getString("ROMDirectory")};
std::string romDirPath; std::string romDirPath;
if (romDirSetting == "") { if (romDirSetting == "") {
@ -196,7 +197,7 @@ const std::string FileData::getROMDirectory()
const std::string FileData::getMediaDirectory() const std::string FileData::getMediaDirectory()
{ {
std::string mediaDirSetting {Settings::getInstance()->getString("MediaDirectory")}; const std::string& mediaDirSetting {Settings::getInstance()->getString("MediaDirectory")};
std::string mediaDirPath; std::string mediaDirPath;
if (mediaDirSetting == "") { if (mediaDirSetting == "") {
@ -233,7 +234,7 @@ const std::string FileData::getMediafilePath(const std::string& subdirectory) co
subFolders + "/" + getDisplayName()}; subFolders + "/" + getDisplayName()};
// Look for an image file in the media directory. // Look for an image file in the media directory.
for (size_t i = 0; i < extList.size(); ++i) { for (size_t i {0}; i < extList.size(); ++i) {
std::string mediaPath {tempPath + extList[i]}; std::string mediaPath {tempPath + extList[i]};
if (Utils::FileSystem::exists(mediaPath)) if (Utils::FileSystem::exists(mediaPath))
return mediaPath; return mediaPath;
@ -332,7 +333,7 @@ const std::string FileData::getVideoPath() const
getDisplayName()}; getDisplayName()};
// Look for media in the media directory. // Look for media in the media directory.
for (size_t i = 0; i < extList.size(); ++i) { for (size_t i {0}; i < extList.size(); ++i) {
std::string mediaPath {tempPath + extList[i]}; std::string mediaPath {tempPath + extList[i]};
if (Utils::FileSystem::exists(mediaPath)) if (Utils::FileSystem::exists(mediaPath))
return mediaPath; return mediaPath;
@ -424,7 +425,7 @@ std::vector<FileData*> FileData::getScrapeFilesRecursive(bool includeFolders,
const bool FileData::isArcadeAsset() const const bool FileData::isArcadeAsset() const
{ {
const std::string stem {Utils::FileSystem::getStem(mPath)}; const std::string& stem {Utils::FileSystem::getStem(mPath)};
return ((mSystem && (mSystem->hasPlatformId(PlatformIds::ARCADE) || return ((mSystem && (mSystem->hasPlatformId(PlatformIds::ARCADE) ||
mSystem->hasPlatformId(PlatformIds::SNK_NEO_GEO))) && mSystem->hasPlatformId(PlatformIds::SNK_NEO_GEO))) &&
(MameNames::getInstance().isBios(stem) || MameNames::getInstance().isDevice(stem))); (MameNames::getInstance().isBios(stem) || MameNames::getInstance().isDevice(stem)));
@ -432,7 +433,7 @@ const bool FileData::isArcadeAsset() const
const bool FileData::isArcadeGame() const const bool FileData::isArcadeGame() const
{ {
const std::string stem {Utils::FileSystem::getStem(mPath)}; const std::string& stem {Utils::FileSystem::getStem(mPath)};
return ((mSystem && (mSystem->hasPlatformId(PlatformIds::ARCADE) || return ((mSystem && (mSystem->hasPlatformId(PlatformIds::ARCADE) ||
mSystem->hasPlatformId(PlatformIds::SNK_NEO_GEO))) && mSystem->hasPlatformId(PlatformIds::SNK_NEO_GEO))) &&
(!MameNames::getInstance().isBios(stem) && !MameNames::getInstance().isDevice(stem))); (!MameNames::getInstance().isBios(stem) && !MameNames::getInstance().isDevice(stem)));
@ -444,7 +445,7 @@ void FileData::addChild(FileData* file)
if (!mSystem->getFlattenFolders()) if (!mSystem->getFlattenFolders())
assert(file->getParent() == nullptr); assert(file->getParent() == nullptr);
const std::string key = file->getKey(); const std::string& key {file->getKey()};
if (mChildrenByFilename.find(key) == mChildrenByFilename.cend()) { if (mChildrenByFilename.find(key) == mChildrenByFilename.cend()) {
mChildrenByFilename[key] = file; mChildrenByFilename[key] = file;
mChildren.emplace_back(file); mChildren.emplace_back(file);
@ -481,7 +482,7 @@ void FileData::sort(ComparisonFunction& comparator,
std::vector<FileData*> mChildrenOthers; std::vector<FileData*> mChildrenOthers;
if (mSystem->isGroupedCustomCollection()) if (mSystem->isGroupedCustomCollection())
gameCount = {}; gameCount = {0, 0};
if (!showHiddenGames) { if (!showHiddenGames) {
for (auto it = mChildren.begin(); it != mChildren.end();) { for (auto it = mChildren.begin(); it != mChildren.end();) {
@ -505,20 +506,20 @@ void FileData::sort(ComparisonFunction& comparator,
// The main custom collections view is sorted during startup in CollectionSystemsManager. // The main custom collections view is sorted during startup in CollectionSystemsManager.
// The individual collections are however sorted as any normal systems/folders. // The individual collections are however sorted as any normal systems/folders.
if (mSystem->isCollection() && mSystem->getFullName() == "collections") { if (mSystem->isCollection() && mSystem->getFullName() == "collections") {
std::pair<unsigned int, unsigned int> tempGameCount {}; std::pair<unsigned int, unsigned int> tempGameCount {0, 0};
for (auto it = mChildren.cbegin(); it != mChildren.cend(); ++it) { for (auto it = mChildren.cbegin(); it != mChildren.cend(); ++it) {
if ((*it)->getChildren().size() > 0) if ((*it)->getChildren().size() > 0)
(*it)->sort(comparator, gameCount); (*it)->sort(comparator, gameCount);
tempGameCount.first += gameCount.first; tempGameCount.first += gameCount.first;
tempGameCount.second += gameCount.second; tempGameCount.second += gameCount.second;
gameCount = {}; gameCount = {0, 0};
} }
gameCount = tempGameCount; gameCount = tempGameCount;
return; return;
} }
if (foldersOnTop) { if (foldersOnTop) {
for (unsigned int i = 0; i < mChildren.size(); ++i) { for (unsigned int i {0}; i < mChildren.size(); ++i) {
if (mChildren[i]->getType() == FOLDER) { if (mChildren[i]->getType() == FOLDER) {
mChildrenFolders.emplace_back(mChildren[i]); mChildrenFolders.emplace_back(mChildren[i]);
} }
@ -597,24 +598,24 @@ void FileData::sortFavoritesOnTop(ComparisonFunction& comparator,
std::vector<FileData*> mChildrenOthers; std::vector<FileData*> mChildrenOthers;
if (mSystem->isGroupedCustomCollection()) if (mSystem->isGroupedCustomCollection())
gameCount = {}; gameCount = {0, 0};
// The main custom collections view is sorted during startup in CollectionSystemsManager. // The main custom collections view is sorted during startup in CollectionSystemsManager.
// The individual collections are however sorted as any normal systems/folders. // The individual collections are however sorted as any normal systems/folders.
if (mSystem->isCollection() && mSystem->getFullName() == "collections") { if (mSystem->isCollection() && mSystem->getFullName() == "collections") {
std::pair<unsigned int, unsigned int> tempGameCount = {}; std::pair<unsigned int, unsigned int> tempGameCount = {0, 0};
for (auto it = mChildren.cbegin(); it != mChildren.cend(); ++it) { for (auto it = mChildren.cbegin(); it != mChildren.cend(); ++it) {
if ((*it)->getChildren().size() > 0) if ((*it)->getChildren().size() > 0)
(*it)->sortFavoritesOnTop(comparator, gameCount); (*it)->sortFavoritesOnTop(comparator, gameCount);
tempGameCount.first += gameCount.first; tempGameCount.first += gameCount.first;
tempGameCount.second += gameCount.second; tempGameCount.second += gameCount.second;
gameCount = {}; gameCount = {0, 0};
} }
gameCount = tempGameCount; gameCount = tempGameCount;
return; return;
} }
for (unsigned int i = 0; i < mChildren.size(); ++i) { for (unsigned int i {0}; i < mChildren.size(); ++i) {
// If the option to hide hidden games has been set and the game is hidden, // If the option to hide hidden games has been set and the game is hidden,
// then skip it. Normally games are hidden during loading of the gamelists in // then skip it. Normally games are hidden during loading of the gamelists in
// Gamelist::parseGamelist() and this code should only run when a user has marked // Gamelist::parseGamelist() and this code should only run when a user has marked
@ -745,7 +746,7 @@ void FileData::countGames(std::pair<unsigned int, unsigned int>& gameCount)
bool isKidMode {(Settings::getInstance()->getString("UIMode") == "kid" || bool isKidMode {(Settings::getInstance()->getString("UIMode") == "kid" ||
Settings::getInstance()->getBool("ForceKid"))}; Settings::getInstance()->getBool("ForceKid"))};
for (unsigned int i = 0; i < mChildren.size(); ++i) { for (unsigned int i {0}; i < mChildren.size(); ++i) {
if (mChildren[i]->getType() == GAME && mChildren[i]->getCountAsGame()) { if (mChildren[i]->getType() == GAME && mChildren[i]->getCountAsGame()) {
if (!isKidMode || (isKidMode && mChildren[i]->getKidgame())) { if (!isKidMode || (isKidMode && mChildren[i]->getKidgame())) {
++gameCount.first; ++gameCount.first;
@ -798,9 +799,9 @@ void FileData::updateMostPlayedList()
const FileData::SortType& FileData::getSortTypeFromString(const std::string& desc) const const FileData::SortType& FileData::getSortTypeFromString(const std::string& desc) const
{ {
std::vector<FileData::SortType> SortTypes = FileSorts::SortTypes; std::vector<FileData::SortType> SortTypes {FileSorts::SortTypes};
for (unsigned int i = 0; i < FileSorts::SortTypes.size(); ++i) { for (unsigned int i {0}; i < FileSorts::SortTypes.size(); ++i) {
const FileData::SortType& sort {FileSorts::SortTypes.at(i)}; const FileData::SortType& sort {FileSorts::SortTypes.at(i)};
if (sort.description == desc) if (sort.description == desc)
return sort; return sort;
@ -983,11 +984,11 @@ void FileData::launchGame()
command = Utils::FileSystem::expandHomePath(command); command = Utils::FileSystem::expandHomePath(command);
// Check that the emulator binary actually exists, and if so, get its path. // Check that the emulator binary actually exists, and if so, get its path.
std::string binaryPath {findEmulatorPath(command)}; const std::string& binaryPath {findEmulatorPath(command)};
// Hack to show an error message if there was no emulator entry in es_find_rules.xml. // Hack to show an error message if there was no emulator entry in es_find_rules.xml.
if (binaryPath.substr(0, 18) == "NO EMULATOR RULE: ") { if (binaryPath.substr(0, 18) == "NO EMULATOR RULE: ") {
std::string emulatorEntry {binaryPath.substr(18, binaryPath.size() - 18)}; const std::string& emulatorEntry {binaryPath.substr(18, binaryPath.size() - 18)};
LOG(LogError) << "Couldn't launch game, either there is no emulator entry for \"" LOG(LogError) << "Couldn't launch game, either there is no emulator entry for \""
<< emulatorEntry << "\" in es_find_rules.xml or there are no rules defined"; << emulatorEntry << "\" in es_find_rules.xml or there are no rules defined";
LOG(LogError) << "Raw emulator launch command:"; LOG(LogError) << "Raw emulator launch command:";
@ -1051,7 +1052,7 @@ void FileData::launchGame()
quotationMarkPos = quotationMarkPos =
static_cast<unsigned int>(command.find("\"", emuPathPos + 9) - emuPathPos); static_cast<unsigned int>(command.find("\"", emuPathPos + 9) - emuPathPos);
} }
size_t spacePos {command.find(" ", emuPathPos + quotationMarkPos)}; const size_t spacePos {command.find(" ", emuPathPos + quotationMarkPos)};
std::string coreRaw; std::string coreRaw;
std::string coreFile; std::string coreFile;
if (spacePos != std::string::npos) { if (spacePos != std::string::npos) {
@ -1120,7 +1121,7 @@ void FileData::launchGame()
// If a %CORE_ find rule entry is used in es_systems.xml for this system, then try to find // If a %CORE_ find rule entry is used in es_systems.xml for this system, then try to find
// the emulator core using the rules defined in es_find_rules.xml. // the emulator core using the rules defined in es_find_rules.xml.
for (std::string path : emulatorCorePaths) { for (std::string& path : emulatorCorePaths) {
// The position of the %CORE_ variable could have changed as there may have been an // The position of the %CORE_ variable could have changed as there may have been an
// %EMULATOR_ variable that was substituted for the actual emulator binary. // %EMULATOR_ variable that was substituted for the actual emulator binary.
coreEntryPos = command.find("%CORE_"); coreEntryPos = command.find("%CORE_");
@ -1210,7 +1211,7 @@ void FileData::launchGame()
} }
std::string startDirectory; std::string startDirectory;
size_t startDirPos {command.find("%STARTDIR%")}; const size_t startDirPos {command.find("%STARTDIR%")};
if (startDirPos != std::string::npos) { if (startDirPos != std::string::npos) {
bool invalidEntry {false}; bool invalidEntry {false};
@ -1233,7 +1234,7 @@ void FileData::launchGame()
} }
} }
else if (!invalidEntry) { else if (!invalidEntry) {
size_t spacePos {command.find(" ", startDirPos)}; const size_t spacePos {command.find(" ", startDirPos)};
if (spacePos != std::string::npos) { if (spacePos != std::string::npos) {
startDirectory = command.substr(startDirPos + 11, spacePos - startDirPos - 11); startDirectory = command.substr(startDirPos + 11, spacePos - startDirPos - 11);
command = command.replace(startDirPos, spacePos - startDirPos + 1, ""); command = command.replace(startDirPos, spacePos - startDirPos + 1, "");
@ -1331,7 +1332,7 @@ void FileData::launchGame()
} }
} }
else if (!invalidEntry) { else if (!invalidEntry) {
size_t spacePos {command.find(" ", injectPos)}; const size_t spacePos {command.find(" ", injectPos)};
if (spacePos != std::string::npos) { if (spacePos != std::string::npos) {
injectFile = command.substr(injectPos + 9, spacePos - injectPos - 9); injectFile = command.substr(injectPos + 9, spacePos - injectPos - 9);
command = command.replace(injectPos, spacePos - injectPos + 1, ""); command = command.replace(injectPos, spacePos - injectPos + 1, "");
@ -1407,8 +1408,8 @@ void FileData::launchGame()
// The special characters need to be procesed in this order. // The special characters need to be procesed in this order.
std::string specialCharacters {"^&()=;,"}; std::string specialCharacters {"^&()=;,"};
for (size_t i = 0; i < specialCharacters.size(); ++i) { for (size_t i {0}; i < specialCharacters.size(); ++i) {
std::string special(1, specialCharacters[i]); const std::string& special {1, specialCharacters[i]};
if (romPath.find(special) != std::string::npos) { if (romPath.find(special) != std::string::npos) {
romPath = Utils::String::replace(romPath, special, "^" + special); romPath = Utils::String::replace(romPath, special, "^" + special);
foundSpecial = true; foundSpecial = true;
@ -1701,15 +1702,15 @@ const std::string FileData::findEmulatorPath(std::string& command)
return "NO EMULATOR RULE: " + emulatorEntry; return "NO EMULATOR RULE: " + emulatorEntry;
#if defined(_WIN64) #if defined(_WIN64)
for (std::string path : emulatorWinRegistryPaths) { for (std::string& path : emulatorWinRegistryPaths) {
// Search for the emulator using the App Paths keys in the Windows Registry. // Search for the emulator using the App Paths keys in the Windows Registry.
std::string registryKeyPath {"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\" + const std::string& registryKeyPath {
path}; "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\" + path};
HKEY registryKey; HKEY registryKey;
LSTATUS keyStatus {-1}; LSTATUS keyStatus {-1};
LSTATUS pathStatus {-1}; LSTATUS pathStatus {-1};
char registryPath[1024] {}; char registryPath[1024] {0};
DWORD pathSize {1024}; DWORD pathSize {1024};
// First look in HKEY_CURRENT_USER. // First look in HKEY_CURRENT_USER.
@ -1746,11 +1747,11 @@ const std::string FileData::findEmulatorPath(std::string& command)
RegCloseKey(registryKey); RegCloseKey(registryKey);
} }
for (std::string value : emulatorWinRegistryValues) { for (std::string& value : emulatorWinRegistryValues) {
// If the pipe character is found, then the string following this should be appended // If the pipe character is found, then the string following this should be appended
// to the key value, assuming the key is found. // to the key value, assuming the key is found.
std::string appendString; std::string appendString;
size_t pipePos {value.find('|')}; const size_t pipePos {value.find('|')};
if (pipePos != std::string::npos) { if (pipePos != std::string::npos) {
appendString = value.substr(pipePos + 1, std::string::npos); appendString = value.substr(pipePos + 1, std::string::npos);
@ -1758,14 +1759,14 @@ const std::string FileData::findEmulatorPath(std::string& command)
} }
// Search for the defined value in the Windows Registry. // Search for the defined value in the Windows Registry.
std::string registryValueKey { const std::string& registryValueKey {
Utils::String::replace(Utils::FileSystem::getParent(value), "/", "\\")}; Utils::String::replace(Utils::FileSystem::getParent(value), "/", "\\")};
std::string registryValue {Utils::FileSystem::getFileName(value)}; const std::string& registryValue {Utils::FileSystem::getFileName(value)};
HKEY registryKey; HKEY registryKey;
LSTATUS keyStatus {-1}; LSTATUS keyStatus {-1};
LSTATUS pathStatus {-1}; LSTATUS pathStatus {-1};
char path[1024] {}; char path[1024] {0};
DWORD pathSize {1024}; DWORD pathSize {1024};
// First look in HKEY_CURRENT_USER. // First look in HKEY_CURRENT_USER.
@ -1811,7 +1812,7 @@ const std::string FileData::findEmulatorPath(std::string& command)
} }
#endif #endif
for (std::string path : emulatorSystemPaths) { for (std::string& path : emulatorSystemPaths) {
#if defined(_WIN64) #if defined(_WIN64)
std::wstring pathWide {Utils::String::stringToWideString(path)}; std::wstring pathWide {Utils::String::stringToWideString(path)};
// Search for the emulator using the PATH environment variable. // Search for the emulator using the PATH environment variable.
@ -1846,11 +1847,11 @@ const std::string FileData::findEmulatorPath(std::string& command)
#endif #endif
} }
for (std::string path : emulatorStaticPaths) { for (std::string& path : emulatorStaticPaths) {
// If a pipe character is present in the staticpath entry it means we should substitute // If a pipe character is present in the staticpath entry it means we should substitute
// the emulator binary with whatever is defined after the pipe character. // the emulator binary with whatever is defined after the pipe character.
std::string replaceCommand; std::string replaceCommand;
size_t pipePos {path.find('|')}; const size_t pipePos {path.find('|')};
if (pipePos != std::string::npos) { if (pipePos != std::string::npos) {
replaceCommand = path.substr(pipePos + 1); replaceCommand = path.substr(pipePos + 1);
@ -1899,7 +1900,7 @@ const std::string FileData::findEmulatorPath(std::string& command)
// If the first character is a quotation mark, then we need to extract up to the // If the first character is a quotation mark, then we need to extract up to the
// next quotation mark, otherwise we'll only extract up to the first space character. // next quotation mark, otherwise we'll only extract up to the first space character.
if (command.front() == '\"') { if (command.front() == '\"') {
std::string emuTemp {command.substr(1, std::string::npos)}; const std::string& emuTemp {command.substr(1, std::string::npos)};
emuExecutable = emuTemp.substr(0, emuTemp.find('"')); emuExecutable = emuTemp.substr(0, emuTemp.find('"'));
} }
else { else {
@ -1917,7 +1918,8 @@ const std::string FileData::findEmulatorPath(std::string& command)
#if defined(_WIN64) #if defined(_WIN64)
std::wstring emuExecutableWide {Utils::String::stringToWideString(emuExecutable)}; std::wstring emuExecutableWide {Utils::String::stringToWideString(emuExecutable)};
// Search for the emulator using the PATH environment variable. // Search for the emulator using the PATH environment variable.
DWORD size {SearchPathW(nullptr, emuExecutableWide.c_str(), L".exe", 0, nullptr, nullptr)}; const DWORD size {
SearchPathW(nullptr, emuExecutableWide.c_str(), L".exe", 0, nullptr, nullptr)};
if (size) { if (size) {
std::vector<wchar_t> pathBuffer(static_cast<size_t>(size) + 1); std::vector<wchar_t> pathBuffer(static_cast<size_t>(size) + 1);

View file

@ -32,19 +32,19 @@ namespace GamelistFileParser
return nullptr; return nullptr;
} }
Utils::FileSystem::StringList pathList = Utils::FileSystem::getPathList(relative); const Utils::FileSystem::StringList& pathList {Utils::FileSystem::getPathList(relative)};
auto path_it = pathList.begin(); auto path_it = pathList.begin();
FileData* treeNode = root; FileData* treeNode {root};
bool found = false; bool found {false};
while (path_it != pathList.end()) {
const std::unordered_map<std::string, FileData*>& children =
treeNode->getChildrenByFilename();
std::string key = *path_it; while (path_it != pathList.end()) {
const std::unordered_map<std::string, FileData*>& children {
treeNode->getChildrenByFilename()};
const std::string key {*path_it};
found = children.find(key) != children.cend(); found = children.find(key) != children.cend();
if (found) { if (found)
treeNode = children.at(key); treeNode = children.at(key);
}
// This is the end. // This is the end.
if (path_it == --pathList.end()) { if (path_it == --pathList.end()) {
@ -58,8 +58,8 @@ namespace GamelistFileParser
// Handle the special situation where a file exists and has an entry in the // Handle the special situation where a file exists and has an entry in the
// gamelist.xml file but the file extension is not configured in es_systems.xml. // gamelist.xml file but the file extension is not configured in es_systems.xml.
const std::vector<std::string> extensions = const std::vector<std::string>& extensions {
system->getSystemEnvData()->mSearchExtensions; system->getSystemEnvData()->mSearchExtensions};
if (std::find(extensions.cbegin(), extensions.cend(), if (std::find(extensions.cbegin(), extensions.cend(),
Utils::FileSystem::getExtension(path)) == extensions.cend()) { Utils::FileSystem::getExtension(path)) == extensions.cend()) {
@ -69,7 +69,7 @@ namespace GamelistFileParser
return nullptr; return nullptr;
} }
FileData* file = new FileData(type, path, system->getSystemEnvData(), system); FileData* file {new FileData(type, path, system->getSystemEnvData(), system)};
// Skipping arcade assets from gamelist. // Skipping arcade assets from gamelist.
if (!file->isArcadeAsset()) if (!file->isArcadeAsset())
@ -103,8 +103,8 @@ namespace GamelistFileParser
void parseGamelist(SystemData* system) void parseGamelist(SystemData* system)
{ {
bool trustGamelist = Settings::getInstance()->getBool("ParseGamelistOnly"); const bool trustGamelist {Settings::getInstance()->getBool("ParseGamelistOnly")};
std::string xmlpath = system->getGamelistPath(false); const std::string& xmlpath {system->getGamelistPath(false)};
if (!Utils::FileSystem::exists(xmlpath)) { if (!Utils::FileSystem::exists(xmlpath)) {
LOG(LogDebug) << "GamelistFileParser::parseGamelist(): System \"" << system->getName() LOG(LogDebug) << "GamelistFileParser::parseGamelist(): System \"" << system->getName()
@ -121,10 +121,10 @@ namespace GamelistFileParser
pugi::xml_document doc; pugi::xml_document doc;
#if defined(_WIN64) #if defined(_WIN64)
pugi::xml_parse_result result = const pugi::xml_parse_result& result {
doc.load_file(Utils::String::stringToWideString(xmlpath).c_str()); doc.load_file(Utils::String::stringToWideString(xmlpath).c_str())};
#else #else
pugi::xml_parse_result result = doc.load_file(xmlpath.c_str()); const pugi::xml_parse_result& result {doc.load_file(xmlpath.c_str())};
#endif #endif
if (!result) { if (!result) {
@ -133,18 +133,18 @@ namespace GamelistFileParser
return; return;
} }
pugi::xml_node root = doc.child("gameList"); const pugi::xml_node& root {doc.child("gameList")};
if (!root) { if (!root) {
LOG(LogError) << "Couldn't find <gameList> node in gamelist \"" << xmlpath << "\""; LOG(LogError) << "Couldn't find <gameList> node in gamelist \"" << xmlpath << "\"";
return; return;
} }
pugi::xml_node alternativeEmulator = doc.child("alternativeEmulator"); const pugi::xml_node& alternativeEmulator {doc.child("alternativeEmulator")};
if (alternativeEmulator) { if (alternativeEmulator) {
std::string label = alternativeEmulator.child("label").text().get(); const std::string& label {alternativeEmulator.child("label").text().get()};
if (label != "") { if (label != "") {
bool validLabel = false; bool validLabel {false};
for (auto command : system->getSystemEnvData()->mLaunchCommands) { for (auto& command : system->getSystemEnvData()->mLaunchCommands) {
if (command.second == label) if (command.second == label)
validLabel = true; validLabel = true;
} }
@ -165,18 +165,19 @@ namespace GamelistFileParser
} }
} }
std::string relativeTo = system->getStartPath(); const std::string& relativeTo {system->getStartPath()};
bool showHiddenFiles = Settings::getInstance()->getBool("ShowHiddenFiles"); const bool showHiddenFiles {Settings::getInstance()->getBool("ShowHiddenFiles")};
std::vector<std::string> tagList = {"game", "folder"}; const std::vector<std::string> tagList {"game", "folder"};
FileType typeList[2] = {GAME, FOLDER}; const FileType typeList[2] = {GAME, FOLDER};
for (int i = 0; i < 2; ++i) {
std::string tag = tagList[i]; for (int i {0}; i < 2; ++i) {
FileType type = typeList[i]; std::string tag {tagList[i]};
for (pugi::xml_node fileNode = root.child(tag.c_str()); fileNode; FileType type {typeList[i]};
for (pugi::xml_node fileNode {root.child(tag.c_str())}; fileNode;
fileNode = fileNode.next_sibling(tag.c_str())) { fileNode = fileNode.next_sibling(tag.c_str())) {
const std::string path = Utils::FileSystem::resolveRelativePath( const std::string& path {Utils::FileSystem::resolveRelativePath(
fileNode.child("path").text().get(), relativeTo, false); fileNode.child("path").text().get(), relativeTo, false)};
if (!trustGamelist && !Utils::FileSystem::exists(path)) { if (!trustGamelist && !Utils::FileSystem::exists(path)) {
#if defined(_WIN64) #if defined(_WIN64)
@ -199,7 +200,7 @@ namespace GamelistFileParser
continue; continue;
} }
FileData* file = findOrCreateFile(system, path, type); FileData* file {findOrCreateFile(system, path, type)};
// Don't load entries with the wrong type. This should very rarely (if ever) happen. // Don't load entries with the wrong type. This should very rarely (if ever) happen.
if (file != nullptr && ((tag == "game" && file->getType() == FOLDER) || if (file != nullptr && ((tag == "game" && file->getType() == FOLDER) ||
@ -214,7 +215,7 @@ namespace GamelistFileParser
continue; continue;
} }
else if (!file->isArcadeAsset()) { else if (!file->isArcadeAsset()) {
std::string defaultName = file->metadata.get("name"); const std::string& defaultName {file->metadata.get("name")};
if (file->getType() == FOLDER) { if (file->getType() == FOLDER) {
file->metadata = file->metadata =
MetaDataList::createFromXML(FOLDER_METADATA, fileNode, relativeTo); MetaDataList::createFromXML(FOLDER_METADATA, fileNode, relativeTo);
@ -265,7 +266,7 @@ namespace GamelistFileParser
SystemData* system) SystemData* system)
{ {
// Create game and add to parent node. // Create game and add to parent node.
pugi::xml_node newNode = parent.append_child(tag.c_str()); pugi::xml_node newNode {parent.append_child(tag.c_str())};
// Write metadata. // Write metadata.
file->metadata.appendToXML(newNode, true, system->getStartPath()); file->metadata.appendToXML(newNode, true, system->getStartPath());
@ -303,17 +304,17 @@ namespace GamelistFileParser
pugi::xml_document doc; pugi::xml_document doc;
pugi::xml_node root; pugi::xml_node root;
std::string xmlReadPath = system->getGamelistPath(false); const std::string& xmlReadPath {system->getGamelistPath(false)};
bool hasAlternativeEmulatorTag = false; bool hasAlternativeEmulatorTag {false};
if (Utils::FileSystem::exists(xmlReadPath)) { if (Utils::FileSystem::exists(xmlReadPath)) {
// Parse an existing file first. // Parse an existing file first.
#if defined(_WIN64) #if defined(_WIN64)
pugi::xml_parse_result result = const pugi::xml_parse_result& result {
doc.load_file(Utils::String::stringToWideString(xmlReadPath).c_str()); doc.load_file(Utils::String::stringToWideString(xmlReadPath).c_str())};
#else #else
pugi::xml_parse_result result = doc.load_file(xmlReadPath.c_str()); const pugi::xml_parse_result& result {doc.load_file(xmlReadPath.c_str())};
#endif #endif
if (!result) { if (!result) {
@ -329,7 +330,7 @@ namespace GamelistFileParser
return; return;
} }
if (updateAlternativeEmulator) { if (updateAlternativeEmulator) {
pugi::xml_node alternativeEmulator = doc.child("alternativeEmulator"); pugi::xml_node alternativeEmulator {doc.child("alternativeEmulator")};
if (alternativeEmulator) if (alternativeEmulator)
hasAlternativeEmulatorTag = true; hasAlternativeEmulatorTag = true;
@ -340,7 +341,7 @@ namespace GamelistFileParser
alternativeEmulator = doc.child("alternativeEmulator"); alternativeEmulator = doc.child("alternativeEmulator");
} }
pugi::xml_node label = alternativeEmulator.child("label"); const pugi::xml_node& label {alternativeEmulator.child("label")};
if (label && system->getAlternativeEmulator() != if (label && system->getAlternativeEmulator() !=
alternativeEmulator.child("label").text().get()) { alternativeEmulator.child("label").text().get()) {
@ -360,7 +361,7 @@ namespace GamelistFileParser
} }
else { else {
if (updateAlternativeEmulator && system->getAlternativeEmulator() != "") { if (updateAlternativeEmulator && system->getAlternativeEmulator() != "") {
pugi::xml_node alternativeEmulator = doc.prepend_child("alternativeEmulator"); pugi::xml_node alternativeEmulator {doc.prepend_child("alternativeEmulator")};
alternativeEmulator.prepend_child("label").text().set( alternativeEmulator.prepend_child("label").text().set(
system->getAlternativeEmulator().c_str()); system->getAlternativeEmulator().c_str());
} }
@ -372,14 +373,14 @@ namespace GamelistFileParser
// through all our games and add the information from there. // through all our games and add the information from there.
FileData* rootFolder {system->getRootFolder()}; FileData* rootFolder {system->getRootFolder()};
if (rootFolder != nullptr) { if (rootFolder != nullptr) {
int numUpdated = 0; int numUpdated {0};
// Get only files, no folders. // Get only files, no folders.
std::vector<FileData*> files = rootFolder->getFilesRecursive(GAME | FOLDER); std::vector<FileData*> files {rootFolder->getFilesRecursive(GAME | FOLDER)};
// Iterate through all files, checking if they're already in the XML file. // Iterate through all files, checking if they're already in the XML file.
for (std::vector<FileData*>::const_iterator fit = files.cbegin(); // Line break. for (std::vector<FileData*>::const_iterator fit {files.cbegin()}; // Line break.
fit != files.cend(); ++fit) { fit != files.cend(); ++fit) {
const std::string tag = ((*fit)->getType() == GAME) ? "game" : "folder"; const std::string& tag {((*fit)->getType() == GAME) ? "game" : "folder"};
// Do not touch if it wasn't changed and is not flagged for deletion. // Do not touch if it wasn't changed and is not flagged for deletion.
if (!(*fit)->metadata.wasChanged() && !(*fit)->getDeletionFlag()) if (!(*fit)->metadata.wasChanged() && !(*fit)->getDeletionFlag())
@ -387,18 +388,19 @@ namespace GamelistFileParser
// Check if the file already exists in the XML file. // Check if the file already exists in the XML file.
// If it does, remove the entry before adding it back. // If it does, remove the entry before adding it back.
for (pugi::xml_node fileNode = root.child(tag.c_str()); fileNode; for (pugi::xml_node fileNode {root.child(tag.c_str())}; fileNode;
fileNode = fileNode.next_sibling(tag.c_str())) { fileNode = fileNode.next_sibling(tag.c_str())) {
pugi::xml_node pathNode = fileNode.child("path"); const pugi::xml_node& pathNode {fileNode.child("path")};
if (!pathNode) { if (!pathNode) {
LOG(LogError) << "<" << tag << "> node contains no <path> child"; LOG(LogError) << "<" << tag << "> node contains no <path> child";
continue; continue;
} }
std::string nodePath = const std::string& nodePath {
Utils::FileSystem::getCanonicalPath(Utils::FileSystem::resolveRelativePath( Utils::FileSystem::getCanonicalPath(Utils::FileSystem::resolveRelativePath(
pathNode.text().get(), system->getStartPath(), true)); pathNode.text().get(), system->getStartPath(), true))};
std::string gamePath = Utils::FileSystem::getCanonicalPath((*fit)->getPath()); const std::string& gamePath {
Utils::FileSystem::getCanonicalPath((*fit)->getPath())};
if (nodePath == gamePath) { if (nodePath == gamePath) {
// Found it // Found it
@ -420,7 +422,7 @@ namespace GamelistFileParser
// Now write the file. // Now write the file.
if (numUpdated > 0 || updateAlternativeEmulator) { if (numUpdated > 0 || updateAlternativeEmulator) {
// Make sure the folders leading up to this path exist (or the write will fail). // Make sure the folders leading up to this path exist (or the write will fail).
std::string xmlWritePath(system->getGamelistPath(true)); const std::string& xmlWritePath {system->getGamelistPath(true)};
Utils::FileSystem::createDirectory(Utils::FileSystem::getParent(xmlWritePath)); Utils::FileSystem::createDirectory(Utils::FileSystem::getParent(xmlWritePath));
if (updateAlternativeEmulator) { if (updateAlternativeEmulator) {

View file

@ -40,7 +40,7 @@ FindRules::FindRules()
void FindRules::loadFindRules() void FindRules::loadFindRules()
{ {
std::string customSystemsDirectory {Utils::FileSystem::getHomePath() + const std::string& customSystemsDirectory {Utils::FileSystem::getHomePath() +
"/.emulationstation/custom_systems"}; "/.emulationstation/custom_systems"};
std::string path {customSystemsDirectory + "/es_find_rules.xml"}; std::string path {customSystemsDirectory + "/es_find_rules.xml"};
@ -75,9 +75,10 @@ void FindRules::loadFindRules()
pugi::xml_document doc; pugi::xml_document doc;
#if defined(_WIN64) #if defined(_WIN64)
pugi::xml_parse_result res = doc.load_file(Utils::String::stringToWideString(path).c_str()); const pugi::xml_parse_result& res {
doc.load_file(Utils::String::stringToWideString(path).c_str())};
#else #else
pugi::xml_parse_result res = doc.load_file(path.c_str()); const pugi::xml_parse_result& res {doc.load_file(path.c_str())};
#endif #endif
if (!res) { if (!res) {
@ -86,7 +87,7 @@ void FindRules::loadFindRules()
} }
// Actually read the file. // Actually read the file.
pugi::xml_node ruleList = doc.child("ruleList"); const pugi::xml_node& ruleList {doc.child("ruleList")};
if (!ruleList) { if (!ruleList) {
LOG(LogError) << "es_find_rules.xml is missing the <ruleList> tag"; LOG(LogError) << "es_find_rules.xml is missing the <ruleList> tag";
@ -96,9 +97,9 @@ void FindRules::loadFindRules()
EmulatorRules emulatorRules; EmulatorRules emulatorRules;
CoreRules coreRules; CoreRules coreRules;
for (pugi::xml_node emulator = ruleList.child("emulator"); emulator; for (pugi::xml_node emulator {ruleList.child("emulator")}; emulator;
emulator = emulator.next_sibling("emulator")) { emulator = emulator.next_sibling("emulator")) {
std::string emulatorName = emulator.attribute("name").as_string(); const std::string& emulatorName {emulator.attribute("name").as_string()};
if (emulatorName.empty()) { if (emulatorName.empty()) {
LOG(LogWarning) << "Found emulator tag without name attribute, skipping entry"; LOG(LogWarning) << "Found emulator tag without name attribute, skipping entry";
continue; continue;
@ -109,7 +110,7 @@ void FindRules::loadFindRules()
continue; continue;
} }
for (pugi::xml_node rule = emulator.child("rule"); rule; rule = rule.next_sibling("rule")) { for (pugi::xml_node rule = emulator.child("rule"); rule; rule = rule.next_sibling("rule")) {
std::string ruleType = rule.attribute("type").as_string(); const std::string& ruleType {rule.attribute("type").as_string()};
if (ruleType.empty()) { if (ruleType.empty()) {
LOG(LogWarning) << "Found rule tag without type attribute for emulator \"" LOG(LogWarning) << "Found rule tag without type attribute for emulator \""
<< emulatorName << "\", skipping entry"; << emulatorName << "\", skipping entry";
@ -125,18 +126,18 @@ void FindRules::loadFindRules()
<< emulatorName << "\", skipping entry"; << emulatorName << "\", skipping entry";
continue; continue;
} }
for (pugi::xml_node entry = rule.child("entry"); entry; for (pugi::xml_node entry {rule.child("entry")}; entry;
entry = entry.next_sibling("entry")) { entry = entry.next_sibling("entry")) {
std::string entryValue = entry.text().get(); const std::string& entryValue {entry.text().get()};
if (ruleType == "systempath") if (ruleType == "systempath")
emulatorRules.systemPaths.push_back(entryValue); emulatorRules.systemPaths.emplace_back(entryValue);
else if (ruleType == "staticpath") else if (ruleType == "staticpath")
emulatorRules.staticPaths.push_back(entryValue); emulatorRules.staticPaths.emplace_back(entryValue);
#if defined(_WIN64) #if defined(_WIN64)
else if (ruleType == "winregistrypath") else if (ruleType == "winregistrypath")
emulatorRules.winRegistryPaths.push_back(entryValue); emulatorRules.winRegistryPaths.emplace_back(entryValue);
else if (ruleType == "winregistryvalue") else if (ruleType == "winregistryvalue")
emulatorRules.winRegistryValues.push_back(entryValue); emulatorRules.winRegistryValues.emplace_back(entryValue);
#endif #endif
} }
} }
@ -149,8 +150,8 @@ void FindRules::loadFindRules()
#endif #endif
} }
for (pugi::xml_node core = ruleList.child("core"); core; core = core.next_sibling("core")) { for (pugi::xml_node core {ruleList.child("core")}; core; core = core.next_sibling("core")) {
std::string coreName = core.attribute("name").as_string(); const std::string& coreName {core.attribute("name").as_string()};
if (coreName.empty()) { if (coreName.empty()) {
LOG(LogWarning) << "Found core tag without name attribute, skipping entry"; LOG(LogWarning) << "Found core tag without name attribute, skipping entry";
continue; continue;
@ -159,8 +160,8 @@ void FindRules::loadFindRules()
LOG(LogWarning) << "Found repeating core tag \"" << coreName << "\", skipping entry"; LOG(LogWarning) << "Found repeating core tag \"" << coreName << "\", skipping entry";
continue; continue;
} }
for (pugi::xml_node rule = core.child("rule"); rule; rule = rule.next_sibling("rule")) { for (pugi::xml_node rule {core.child("rule")}; rule; rule = rule.next_sibling("rule")) {
std::string ruleType = rule.attribute("type").as_string(); const std::string& ruleType {rule.attribute("type").as_string()};
if (ruleType.empty()) { if (ruleType.empty()) {
LOG(LogWarning) << "Found rule tag without type attribute for core \"" << coreName LOG(LogWarning) << "Found rule tag without type attribute for core \"" << coreName
<< "\", skipping entry"; << "\", skipping entry";
@ -171,11 +172,11 @@ void FindRules::loadFindRules()
<< coreName << "\", skipping entry"; << coreName << "\", skipping entry";
continue; continue;
} }
for (pugi::xml_node entry = rule.child("entry"); entry; for (pugi::xml_node entry {rule.child("entry")}; entry;
entry = entry.next_sibling("entry")) { entry = entry.next_sibling("entry")) {
std::string entryValue = entry.text().get(); const std::string& entryValue {entry.text().get()};
if (ruleType == "corepath") if (ruleType == "corepath")
coreRules.corePaths.push_back(entryValue); coreRules.corePaths.emplace_back(entryValue);
} }
} }
mCores[coreName] = coreRules; mCores[coreName] = coreRules;
@ -265,13 +266,12 @@ void SystemData::setIsGameSystemStatus()
bool SystemData::populateFolder(FileData* folder) bool SystemData::populateFolder(FileData* folder)
{ {
const std::string& folderPath = folder->getPath();
std::string filePath; std::string filePath;
std::string extension; std::string extension;
bool isGame; const std::string& folderPath {folder->getPath()};
bool showHiddenFiles = Settings::getInstance()->getBool("ShowHiddenFiles"); const bool showHiddenFiles {Settings::getInstance()->getBool("ShowHiddenFiles")};
Utils::FileSystem::StringList dirContent = Utils::FileSystem::getDirContent(folderPath); const Utils::FileSystem::StringList& dirContent {Utils::FileSystem::getDirContent(folderPath)};
bool isGame {false};
// If system directory exists but contains no games, return as error. // If system directory exists but contains no games, return as error.
if (dirContent.size() == 0) if (dirContent.size() == 0)
@ -290,9 +290,10 @@ bool SystemData::populateFolder(FileData* folder)
mFlattenFolders = true; mFlattenFolders = true;
} }
for (Utils::FileSystem::StringList::const_iterator it = dirContent.cbegin(); for (Utils::FileSystem::StringList::const_iterator it {dirContent.cbegin()};
it != dirContent.cend(); ++it) { it != dirContent.cend(); ++it) {
filePath = *it; filePath = *it;
const bool isDirectory {Utils::FileSystem::isDirectory(filePath)};
// Skip any recursive symlinks as those would hang the application at various places. // Skip any recursive symlinks as those would hang the application at various places.
if (Utils::FileSystem::isSymlink(filePath)) { if (Utils::FileSystem::isSymlink(filePath)) {
@ -306,8 +307,7 @@ bool SystemData::populateFolder(FileData* folder)
// Skip hidden files and folders. // Skip hidden files and folders.
if (!showHiddenFiles && Utils::FileSystem::isHidden(filePath)) { if (!showHiddenFiles && Utils::FileSystem::isHidden(filePath)) {
LOG(LogDebug) << "SystemData::populateFolder(): Skipping hidden " LOG(LogDebug) << "SystemData::populateFolder(): Skipping hidden "
<< (Utils::FileSystem::isDirectory(filePath) ? "directory \"" : "file \"") << (isDirectory ? "directory \"" : "file \"") << filePath << "\"";
<< filePath << "\"";
continue; continue;
} }
@ -317,17 +317,18 @@ bool SystemData::populateFolder(FileData* folder)
extension = Utils::FileSystem::getExtension(filePath); extension = Utils::FileSystem::getExtension(filePath);
isGame = false; isGame = false;
if (std::find(mEnvData->mSearchExtensions.cbegin(), mEnvData->mSearchExtensions.cend(), if (std::find(mEnvData->mSearchExtensions.cbegin(), mEnvData->mSearchExtensions.cend(),
extension) != mEnvData->mSearchExtensions.cend()) { extension) != mEnvData->mSearchExtensions.cend()) {
FileData* newGame = new FileData(GAME, filePath, mEnvData, this); FileData* newGame {new FileData(GAME, filePath, mEnvData, this)};
// If adding a configured file extension to a directory it will get interpreted as // If adding a configured file extension to a directory it will get interpreted as
// a regular file. This is useful for displaying multi-file/multi-disc games as single // a regular file. This is useful for displaying multi-file/multi-disc games as single
// entries or for emulators that can get directories passed to them as command line // entries or for emulators that can get directories passed to them as command line
// parameters instead of regular files. In these instances we remove the extension // parameters instead of regular files. In these instances we remove the extension
// from the metadata name so it does not show up in the gamelists and similar. // from the metadata name so it does not show up in the gamelists and similar.
if (Utils::FileSystem::isDirectory(filePath)) { if (isDirectory) {
const std::string folderName = newGame->metadata.get("name"); const std::string& folderName {newGame->metadata.get("name")};
newGame->metadata.set( newGame->metadata.set(
"name", folderName.substr(0, folderName.length() - extension.length())); "name", folderName.substr(0, folderName.length() - extension.length()));
} }
@ -343,15 +344,15 @@ bool SystemData::populateFolder(FileData* folder)
} }
// Add directories that also do not match an extension as folders. // Add directories that also do not match an extension as folders.
if (!isGame && Utils::FileSystem::isDirectory(filePath)) { if (!isGame && isDirectory) {
// Make sure that it's not a recursive symlink pointing to a location higher in the // Make sure that it's not a recursive symlink pointing to a location higher in the
// hierarchy as the application would run forever trying to resolve the link. // hierarchy as the application would run forever trying to resolve the link.
if (Utils::FileSystem::isSymlink(filePath)) { if (Utils::FileSystem::isSymlink(filePath)) {
const std::string canonicalPath {Utils::FileSystem::getCanonicalPath(filePath)}; const std::string& canonicalPath {Utils::FileSystem::getCanonicalPath(filePath)};
const std::string canonicalStartPath { const std::string& canonicalStartPath {
Utils::FileSystem::getCanonicalPath(mEnvData->mStartPath)}; Utils::FileSystem::getCanonicalPath(mEnvData->mStartPath)};
if (canonicalPath.size() >= canonicalStartPath.size()) { if (canonicalPath.size() >= canonicalStartPath.size()) {
const std::string combinedPath { const std::string& combinedPath {
mEnvData->mStartPath + mEnvData->mStartPath +
canonicalPath.substr(canonicalStartPath.size(), canonicalPath.substr(canonicalStartPath.size(),
canonicalStartPath.size() - canonicalPath.size())}; canonicalStartPath.size() - canonicalPath.size())};
@ -384,9 +385,9 @@ bool SystemData::populateFolder(FileData* folder)
void SystemData::indexAllGameFilters(const FileData* folder) void SystemData::indexAllGameFilters(const FileData* folder)
{ {
const std::vector<FileData*>& children = folder->getChildren(); const std::vector<FileData*>& children {folder->getChildren()};
for (std::vector<FileData*>::const_iterator it = children.cbegin(); // Line break. for (std::vector<FileData*>::const_iterator it {children.cbegin()}; // Line break.
it != children.cend(); ++it) { it != children.cend(); ++it) {
switch ((*it)->getType()) { switch ((*it)->getType()) {
case GAME: case GAME:
@ -405,10 +406,10 @@ std::vector<std::string> readList(const std::string& str, const std::string& del
{ {
std::vector<std::string> ret; std::vector<std::string> ret;
size_t prevOff = str.find_first_not_of(delims, 0); size_t prevOff {str.find_first_not_of(delims, 0)};
size_t off = str.find_first_of(delims, prevOff); size_t off {str.find_first_of(delims, prevOff)};
while (off != std::string::npos || prevOff != std::string::npos) { while (off != std::string::npos || prevOff != std::string::npos) {
ret.push_back(str.substr(prevOff, off - prevOff)); ret.emplace_back(str.substr(prevOff, off - prevOff));
prevOff = str.find_first_not_of(delims, off); prevOff = str.find_first_not_of(delims, off);
off = str.find_first_of(delims, prevOff); off = str.find_first_of(delims, prevOff);
@ -430,12 +431,12 @@ bool SystemData::loadConfig()
LOG(LogInfo) << "Only parsing the gamelist.xml files, not scanning system directories"; LOG(LogInfo) << "Only parsing the gamelist.xml files, not scanning system directories";
} }
std::vector<std::string> configPaths = getConfigPath(true); const std::vector<std::string>& configPaths {getConfigPath(true)};
const std::string rompath = FileData::getROMDirectory(); const std::string& rompath {FileData::getROMDirectory()};
bool onlyProcessCustomFile = false; bool onlyProcessCustomFile {false};
for (auto configPath : configPaths) { for (auto& configPath : configPaths) {
// If the loadExclusive tag is present in the custom es_systems.xml file, then skip // If the loadExclusive tag is present in the custom es_systems.xml file, then skip
// processing of the bundled configuration file. // processing of the bundled configuration file.
if (onlyProcessCustomFile) if (onlyProcessCustomFile)
@ -450,10 +451,10 @@ bool SystemData::loadConfig()
pugi::xml_document doc; pugi::xml_document doc;
#if defined(_WIN64) #if defined(_WIN64)
pugi::xml_parse_result res = const pugi::xml_parse_result& res {
doc.load_file(Utils::String::stringToWideString(configPath).c_str()); doc.load_file(Utils::String::stringToWideString(configPath).c_str())};
#else #else
pugi::xml_parse_result res = doc.load_file(configPath.c_str()); const pugi::xml_parse_result& res {doc.load_file(configPath.c_str())};
#endif #endif
if (!res) { if (!res) {
@ -461,7 +462,7 @@ bool SystemData::loadConfig()
return true; return true;
} }
pugi::xml_node loadExclusive = doc.child("loadExclusive"); const pugi::xml_node& loadExclusive {doc.child("loadExclusive")};
if (loadExclusive) { if (loadExclusive) {
if (configPath == configPaths.front() && configPaths.size() > 1) { if (configPath == configPaths.front() && configPaths.size() > 1) {
LOG(LogInfo) << "Only loading custom file as the <loadExclusive> tag is present"; LOG(LogInfo) << "Only loading custom file as the <loadExclusive> tag is present";
@ -475,14 +476,14 @@ bool SystemData::loadConfig()
} }
// Actually read the file. // Actually read the file.
pugi::xml_node systemList = doc.child("systemList"); const pugi::xml_node& systemList {doc.child("systemList")};
if (!systemList) { if (!systemList) {
LOG(LogError) << "es_systems.xml is missing the <systemList> tag"; LOG(LogError) << "es_systems.xml is missing the <systemList> tag";
return true; return true;
} }
for (pugi::xml_node system = systemList.child("system"); system; for (pugi::xml_node system {systemList.child("system")}; system;
system = system.next_sibling("system")) { system = system.next_sibling("system")) {
std::string name; std::string name;
std::string fullname; std::string fullname;
@ -545,7 +546,7 @@ bool SystemData::loadConfig()
if (Utils::FileSystem::isSymlink(path)) { if (Utils::FileSystem::isSymlink(path)) {
// Make sure that the symlink is not pointing to somewhere higher in the hierarchy // Make sure that the symlink is not pointing to somewhere higher in the hierarchy
// as that would lead to an infite loop, meaning the application would never start. // as that would lead to an infite loop, meaning the application would never start.
std::string resolvedRompath = Utils::FileSystem::getCanonicalPath(rompath); const std::string& resolvedRompath {Utils::FileSystem::getCanonicalPath(rompath)};
if (resolvedRompath.find(Utils::FileSystem::getCanonicalPath(path)) == 0) { if (resolvedRompath.find(Utils::FileSystem::getCanonicalPath(path)) == 0) {
LOG(LogWarning) LOG(LogWarning)
<< "Skipping system \"" << name << "\" as the defined ROM directory \"" << "Skipping system \"" << name << "\" as the defined ROM directory \""
@ -561,7 +562,7 @@ bool SystemData::loadConfig()
// the label attribute needs to be set on all entries as it's a requirement for the // the label attribute needs to be set on all entries as it's a requirement for the
// alternative emulator logic. // alternative emulator logic.
std::vector<std::pair<std::string, std::string>> commands; std::vector<std::pair<std::string, std::string>> commands;
for (pugi::xml_node entry = system.child("command"); entry; for (pugi::xml_node entry {system.child("command")}; entry;
entry = entry.next_sibling("command")) { entry = entry.next_sibling("command")) {
if (!entry.attribute("label")) { if (!entry.attribute("label")) {
if (commands.size() == 1) { if (commands.size() == 1) {
@ -589,29 +590,29 @@ bool SystemData::loadConfig()
<< name << "\""; << name << "\"";
break; break;
} }
commands.push_back( commands.emplace_back(
std::make_pair(entry.text().get(), entry.attribute("label").as_string())); std::make_pair(entry.text().get(), entry.attribute("label").as_string()));
} }
// Platform ID list // Platform ID list
const std::string platformList = const std::string& platformList {
Utils::String::toLower(system.child("platform").text().get()); Utils::String::toLower(system.child("platform").text().get())};
if (platformList == "") { if (platformList == "") {
LOG(LogWarning) << "No platform defined for system \"" << name LOG(LogWarning) << "No platform defined for system \"" << name
<< "\", scraper searches will be inaccurate"; << "\", scraper searches will be inaccurate";
} }
std::vector<std::string> platformStrs = readList(platformList); const std::vector<std::string>& platformStrs {readList(platformList)};
std::vector<PlatformIds::PlatformId> platformIds; std::vector<PlatformIds::PlatformId> platformIds;
for (auto it = platformStrs.cbegin(); it != platformStrs.cend(); ++it) { for (auto it = platformStrs.cbegin(); it != platformStrs.cend(); ++it) {
std::string str = *it; std::string str {*it};
PlatformIds::PlatformId platformId = PlatformIds::getPlatformId(str); const PlatformIds::PlatformId platformId {PlatformIds::getPlatformId(str)};
if (platformId == PlatformIds::PLATFORM_IGNORE) { if (platformId == PlatformIds::PLATFORM_IGNORE) {
// When platform is PLATFORM_IGNORE, do not allow other platforms. // When platform is PLATFORM_IGNORE, do not allow other platforms.
platformIds.clear(); platformIds.clear();
platformIds.push_back(platformId); platformIds.emplace_back(platformId);
break; break;
} }
@ -621,7 +622,7 @@ bool SystemData::loadConfig()
LOG(LogWarning) << "Unknown platform \"" << str << "\" defined for system \"" LOG(LogWarning) << "Unknown platform \"" << str << "\" defined for system \""
<< name << "\", scraper searches will be inaccurate"; << name << "\", scraper searches will be inaccurate";
else if (platformId != PlatformIds::PLATFORM_UNKNOWN) else if (platformId != PlatformIds::PLATFORM_UNKNOWN)
platformIds.push_back(platformId); platformIds.emplace_back(platformId);
} }
// Theme folder. // Theme folder.
@ -662,20 +663,20 @@ bool SystemData::loadConfig()
#endif #endif
// Create the system runtime environment data. // Create the system runtime environment data.
SystemEnvironmentData* envData = new SystemEnvironmentData; SystemEnvironmentData* envData {new SystemEnvironmentData};
envData->mStartPath = path; envData->mStartPath = path;
envData->mSearchExtensions = extensions; envData->mSearchExtensions = extensions;
envData->mLaunchCommands = commands; envData->mLaunchCommands = commands;
envData->mPlatformIds = platformIds; envData->mPlatformIds = platformIds;
SystemData* newSys = new SystemData(name, fullname, sortName, envData, themeFolder); SystemData* newSys {new SystemData(name, fullname, sortName, envData, themeFolder)};
bool onlyHidden = false; bool onlyHidden {false};
// If the option to show hidden games has been disabled, then check whether all // If the option to show hidden games has been disabled, then check whether all
// games for the system are hidden. That will flag the system as empty. // games for the system are hidden. That will flag the system as empty.
if (!Settings::getInstance()->getBool("ShowHiddenGames")) { if (!Settings::getInstance()->getBool("ShowHiddenGames")) {
std::vector<FileData*> recursiveGames = std::vector<FileData*> recursiveGames {
newSys->getRootFolder()->getChildrenRecursive(); newSys->getRootFolder()->getChildrenRecursive()};
onlyHidden = true; onlyHidden = true;
for (auto it = recursiveGames.cbegin(); it != recursiveGames.cend(); ++it) { for (auto it = recursiveGames.cbegin(); it != recursiveGames.cend(); ++it) {
if ((*it)->getType() != FOLDER) { if ((*it)->getType() != FOLDER) {
@ -692,7 +693,7 @@ bool SystemData::loadConfig()
delete newSys; delete newSys;
} }
else { else {
sSystemVector.push_back(newSys); sSystemVector.emplace_back(newSys);
} }
} }
} }
@ -723,7 +724,7 @@ std::string SystemData::getLaunchCommandFromLabel(const std::string& label)
void SystemData::deleteSystems() void SystemData::deleteSystems()
{ {
for (unsigned int i = 0; i < sSystemVector.size(); ++i) for (unsigned int i {0}; i < sSystemVector.size(); ++i)
delete sSystemVector.at(i); delete sSystemVector.at(i);
sSystemVector.clear(); sSystemVector.clear();
@ -734,8 +735,8 @@ std::vector<std::string> SystemData::getConfigPath(bool legacyWarning)
std::vector<std::string> paths; std::vector<std::string> paths;
if (legacyWarning) { if (legacyWarning) {
std::string legacyConfigFile = const std::string& legacyConfigFile {Utils::FileSystem::getHomePath() +
Utils::FileSystem::getHomePath() + "/.emulationstation/es_systems.cfg"; "/.emulationstation/es_systems.cfg"};
if (Utils::FileSystem::exists(legacyConfigFile)) { if (Utils::FileSystem::exists(legacyConfigFile)) {
#if defined(_WIN64) #if defined(_WIN64)
@ -751,8 +752,8 @@ std::vector<std::string> SystemData::getConfigPath(bool legacyWarning)
} }
} }
std::string customSystemsDirectory = const std::string& customSystemsDirectory {Utils::FileSystem::getHomePath() +
Utils::FileSystem::getHomePath() + "/.emulationstation/custom_systems"; "/.emulationstation/custom_systems"};
if (!Utils::FileSystem::exists(customSystemsDirectory)) { if (!Utils::FileSystem::exists(customSystemsDirectory)) {
LOG(LogInfo) << "Creating custom systems directory \"" << customSystemsDirectory << "\"..."; LOG(LogInfo) << "Creating custom systems directory \"" << customSystemsDirectory << "\"...";
@ -766,7 +767,7 @@ std::vector<std::string> SystemData::getConfigPath(bool legacyWarning)
if (Utils::FileSystem::exists(path)) { if (Utils::FileSystem::exists(path)) {
LOG(LogInfo) << "Found custom systems configuration file"; LOG(LogInfo) << "Found custom systems configuration file";
paths.push_back(path); paths.emplace_back(path);
} }
#if defined(_WIN64) #if defined(_WIN64)
@ -777,14 +778,14 @@ std::vector<std::string> SystemData::getConfigPath(bool legacyWarning)
path = ResourceManager::getInstance().getResourcePath(":/systems/unix/es_systems.xml", true); path = ResourceManager::getInstance().getResourcePath(":/systems/unix/es_systems.xml", true);
#endif #endif
paths.push_back(path); paths.emplace_back(path);
return paths; return paths;
} }
bool SystemData::createSystemDirectories() bool SystemData::createSystemDirectories()
{ {
std::vector<std::string> configPaths = getConfigPath(true); std::vector<std::string> configPaths {getConfigPath(true)};
const std::string rompath = FileData::getROMDirectory(); const std::string& rompath {FileData::getROMDirectory()};
bool onlyProcessCustomFile = false; bool onlyProcessCustomFile = false;
@ -831,13 +832,13 @@ bool SystemData::createSystemDirectories()
// processing of the bundled configuration file. // processing of the bundled configuration file.
pugi::xml_document doc; pugi::xml_document doc;
#if defined(_WIN64) #if defined(_WIN64)
pugi::xml_parse_result res = const pugi::xml_parse_result& res {
doc.load_file(Utils::String::stringToWideString(configPaths.front()).c_str()); doc.load_file(Utils::String::stringToWideString(configPaths.front()).c_str())};
#else #else
pugi::xml_parse_result res = doc.load_file(configPaths.front().c_str()); const pugi::xml_parse_result& res {doc.load_file(configPaths.front().c_str())};
#endif #endif
if (res) { if (res) {
pugi::xml_node loadExclusive = doc.child("loadExclusive"); const pugi::xml_node& loadExclusive {doc.child("loadExclusive")};
if (loadExclusive) if (loadExclusive)
onlyProcessCustomFile = true; onlyProcessCustomFile = true;
} }
@ -849,7 +850,7 @@ bool SystemData::createSystemDirectories()
std::vector<std::pair<std::string, std::string>> systemsVector; std::vector<std::pair<std::string, std::string>> systemsVector;
for (auto configPath : configPaths) { for (auto& configPath : configPaths) {
// If the loadExclusive tag is present. // If the loadExclusive tag is present.
if (onlyProcessCustomFile && configPath == configPaths.front()) if (onlyProcessCustomFile && configPath == configPaths.front())
continue; continue;
@ -863,10 +864,10 @@ bool SystemData::createSystemDirectories()
pugi::xml_document doc; pugi::xml_document doc;
#if defined(_WIN64) #if defined(_WIN64)
pugi::xml_parse_result res = const pugi::xml_parse_result& res {
doc.load_file(Utils::String::stringToWideString(configPath).c_str()); doc.load_file(Utils::String::stringToWideString(configPath).c_str())};
#else #else
pugi::xml_parse_result res = doc.load_file(configPath.c_str()); const pugi::xml_parse_result& res {doc.load_file(configPath.c_str())};
#endif #endif
if (!res) { if (!res) {
@ -876,14 +877,14 @@ bool SystemData::createSystemDirectories()
} }
// Actually read the file. // Actually read the file.
pugi::xml_node systemList = doc.child("systemList"); const pugi::xml_node& systemList {doc.child("systemList")};
if (!systemList) { if (!systemList) {
LOG(LogError) << "es_systems.xml is missing the <systemList> tag"; LOG(LogError) << "es_systems.xml is missing the <systemList> tag";
return true; return true;
} }
for (pugi::xml_node system = systemList.child("system"); system; for (pugi::xml_node system {systemList.child("system")}; system;
system = system.next_sibling("system")) { system = system.next_sibling("system")) {
std::string systemDir; std::string systemDir;
std::string name; std::string name;
@ -893,7 +894,7 @@ bool SystemData::createSystemDirectories()
std::vector<std::string> commands; std::vector<std::string> commands;
std::string platform; std::string platform;
std::string themeFolder; std::string themeFolder;
const std::string systemInfoFileName = "/systeminfo.txt"; const std::string systemInfoFileName {"/systeminfo.txt"};
bool replaceInfoFile = false; bool replaceInfoFile = false;
std::ofstream systemInfoFile; std::ofstream systemInfoFile;
@ -901,9 +902,9 @@ bool SystemData::createSystemDirectories()
fullname = system.child("fullname").text().get(); fullname = system.child("fullname").text().get();
path = system.child("path").text().get(); path = system.child("path").text().get();
extensions = system.child("extension").text().get(); extensions = system.child("extension").text().get();
for (pugi::xml_node entry = system.child("command"); entry; for (pugi::xml_node entry {system.child("command")}; entry;
entry = entry.next_sibling("command")) { entry = entry.next_sibling("command")) {
commands.push_back(entry.text().get()); commands.emplace_back(entry.text().get());
} }
platform = Utils::String::toLower(system.child("platform").text().get()); platform = Utils::String::toLower(system.child("platform").text().get());
themeFolder = system.child("theme").text().as_string(name.c_str()); themeFolder = system.child("theme").text().as_string(name.c_str());
@ -1000,9 +1001,10 @@ bool SystemData::createSystemDirectories()
systemsVector.erase(systemIter); systemsVector.erase(systemIter);
if (configPaths.size() != 1 && configPath == configPaths.back()) if (configPaths.size() != 1 && configPath == configPaths.back())
systemsVector.push_back(std::make_pair(systemDir + " (custom system)", fullname)); systemsVector.emplace_back(
std::make_pair(systemDir + " (custom system)", fullname));
else else
systemsVector.push_back(std::make_pair(systemDir, fullname)); systemsVector.emplace_back(std::make_pair(systemDir, fullname));
if (replaceInfoFile) { if (replaceInfoFile) {
LOG(LogInfo) << "Replaced existing system information file \"" LOG(LogInfo) << "Replaced existing system information file \""
@ -1019,8 +1021,8 @@ bool SystemData::createSystemDirectories()
// mappings between the system directory names and the full system names. This makes it // mappings between the system directory names and the full system names. This makes it
// easier for the users to identify the correct directories for their games. // easier for the users to identify the correct directories for their games.
if (!systemsVector.empty()) { if (!systemsVector.empty()) {
const std::string systemsFileName = "/systems.txt"; const std::string& systemsFileName {"/systems.txt"};
bool systemsFileSuccess = true; bool systemsFileSuccess {true};
if (Utils::FileSystem::exists(rompath + systemsFileName)) { if (Utils::FileSystem::exists(rompath + systemsFileName)) {
if (Utils::FileSystem::removeFile(rompath + systemsFileName)) if (Utils::FileSystem::removeFile(rompath + systemsFileName))
@ -1133,7 +1135,7 @@ std::string SystemData::getThemePath() const
SystemData* SystemData::getRandomSystem(const SystemData* currentSystem) SystemData* SystemData::getRandomSystem(const SystemData* currentSystem)
{ {
unsigned int total = 0; int total {0};
for (auto it = sSystemVector.cbegin(); it != sSystemVector.cend(); ++it) { for (auto it = sSystemVector.cbegin(); it != sSystemVector.cend(); ++it) {
if ((*it)->isGameSystem()) if ((*it)->isGameSystem())
++total; ++total;
@ -1142,15 +1144,15 @@ SystemData* SystemData::getRandomSystem(const SystemData* currentSystem)
if (total < 2) if (total < 2)
return nullptr; return nullptr;
SystemData* randomSystem = nullptr; SystemData* randomSystem {nullptr};
do { do {
// Get a random number in range. // Get a random number in range.
std::random_device randDev; std::random_device randDev;
// Mersenne Twister pseudorandom number generator. // Mersenne Twister pseudorandom number generator.
std::mt19937 engine {randDev()}; std::mt19937 engine {randDev()};
std::uniform_int_distribution<int> uniform_dist(0, total - 1); std::uniform_int_distribution<int> uniform_dist {0, total - 1};
int target = uniform_dist(engine); int target {uniform_dist(engine)};
for (auto it = sSystemVector.cbegin(); it != sSystemVector.cend(); ++it) { for (auto it = sSystemVector.cbegin(); it != sSystemVector.cend(); ++it) {
if ((*it)->isGameSystem()) { if ((*it)->isGameSystem()) {
@ -1171,8 +1173,8 @@ SystemData* SystemData::getRandomSystem(const SystemData* currentSystem)
FileData* SystemData::getRandomGame(const FileData* currentGame, bool gameSelectorMode) FileData* SystemData::getRandomGame(const FileData* currentGame, bool gameSelectorMode)
{ {
std::vector<FileData*> gameList; std::vector<FileData*> gameList;
bool onlyFolders = false; bool onlyFolders {false};
bool hasFolders = false; bool hasFolders {false};
// If we're in the custom collection group list, then get the list of collections, // If we're in the custom collection group list, then get the list of collections,
// otherwise get a list of all the folder and file entries in the view. // otherwise get a list of all the folder and file entries in the view.
@ -1203,7 +1205,7 @@ FileData* SystemData::getRandomGame(const FileData* currentGame, bool gameSelect
// If this is a mixed view of folders and files, then remove all the folder entries // If this is a mixed view of folders and files, then remove all the folder entries
// as we want to exclude them from the random selection. // as we want to exclude them from the random selection.
if (!onlyFolders && hasFolders) { if (!onlyFolders && hasFolders) {
unsigned int i = 0; unsigned int i {0};
do { do {
if (gameList[i]->getType() == FOLDER) if (gameList[i]->getType() == FOLDER)
gameList.erase(gameList.begin() + i); gameList.erase(gameList.begin() + i);
@ -1222,8 +1224,8 @@ FileData* SystemData::getRandomGame(const FileData* currentGame, bool gameSelect
if (currentGame && currentGame->getType() == PLACEHOLDER) if (currentGame && currentGame->getType() == PLACEHOLDER)
return nullptr; return nullptr;
unsigned int total = static_cast<int>(gameList.size()); int total {static_cast<int>(gameList.size())};
int target = 0; int target {0};
if (total < 2) if (total < 2)
return nullptr; return nullptr;
@ -1233,7 +1235,7 @@ FileData* SystemData::getRandomGame(const FileData* currentGame, bool gameSelect
std::random_device randDev; std::random_device randDev;
// Mersenne Twister pseudorandom number generator. // Mersenne Twister pseudorandom number generator.
std::mt19937 engine {randDev()}; std::mt19937 engine {randDev()};
std::uniform_int_distribution<int> uniform_dist(0, total - 1); std::uniform_int_distribution<int> uniform_dist {0, total - 1};
target = uniform_dist(engine); target = uniform_dist(engine);
} while (currentGame && gameList.at(target) == currentGame); } while (currentGame && gameList.at(target) == currentGame);
@ -1245,7 +1247,7 @@ void SystemData::sortSystem(bool reloadGamelist, bool jumpToFirstRow)
if (getName() == "recent") if (getName() == "recent")
return; return;
bool favoritesSorting; bool favoritesSorting {false};
if (this->isCustomCollection() || if (this->isCustomCollection() ||
(this->isCollection() && this->getFullName() == "collections")) { (this->isCollection() && this->getFullName() == "collections")) {
@ -1255,7 +1257,7 @@ void SystemData::sortSystem(bool reloadGamelist, bool jumpToFirstRow)
favoritesSorting = Settings::getInstance()->getBool("FavoritesFirst"); favoritesSorting = Settings::getInstance()->getBool("FavoritesFirst");
} }
FileData* rootFolder = getRootFolder(); FileData* rootFolder {getRootFolder()};
// Assign the sort type to all grouped custom collections. // Assign the sort type to all grouped custom collections.
if (mIsCollectionSystem && mFullName == "collections") { if (mIsCollectionSystem && mFullName == "collections") {
for (auto it = rootFolder->getChildren().begin(); // Line break. for (auto it = rootFolder->getChildren().begin(); // Line break.
@ -1289,7 +1291,7 @@ void SystemData::loadTheme()
{ {
mTheme = std::make_shared<ThemeData>(); mTheme = std::make_shared<ThemeData>();
std::string path {getThemePath()}; const std::string& path {getThemePath()};
if (!Utils::FileSystem::exists(path)) { if (!Utils::FileSystem::exists(path)) {
// No theme available for this platform. // No theme available for this platform.
@ -1364,7 +1366,7 @@ void SystemData::setupSystemSortType(FileData* rootFolder)
{ {
// If DefaultSortOrder is set to something, check that it is actually a valid value. // If DefaultSortOrder is set to something, check that it is actually a valid value.
if (Settings::getInstance()->getString("DefaultSortOrder") != "") { if (Settings::getInstance()->getString("DefaultSortOrder") != "") {
for (unsigned int i = 0; i < FileSorts::SortTypes.size(); ++i) { for (unsigned int i {0}; i < FileSorts::SortTypes.size(); ++i) {
if (FileSorts::SortTypes.at(i).description == if (FileSorts::SortTypes.at(i).description ==
Settings::getInstance()->getString("DefaultSortOrder")) { Settings::getInstance()->getString("DefaultSortOrder")) {
rootFolder->setSortTypeString( rootFolder->setSortTypeString(

View file

@ -47,14 +47,14 @@
// build environment is broken. // build environment is broken.
#if defined(__unix__) #if defined(__unix__)
#if defined(ES_INSTALL_PREFIX) #if defined(ES_INSTALL_PREFIX)
std::string installPrefix = ES_INSTALL_PREFIX; const std::string installPrefix {ES_INSTALL_PREFIX};
#else #else
#if defined(__linux__) #if defined(__linux__)
std::string installPrefix = "/usr"; const std::string installPrefix {"/usr"};
#elif defined(__NetBSD__) #elif defined(__NetBSD__)
std::string installPrefix = "/usr/pkg"; const std::string installPrefix {"/usr/pkg"};
#else #else
std::string installPrefix = "/usr/local"; const std::string installPrefix {"/usr/local"};
#endif #endif
#endif #endif
#endif #endif
@ -63,12 +63,12 @@ namespace Utils
{ {
namespace FileSystem namespace FileSystem
{ {
static std::string homePath = ""; static std::string homePath;
static std::string exePath = ""; static std::string exePath;
StringList getDirContent(const std::string& path, const bool recursive) StringList getDirContent(const std::string& path, const bool recursive)
{ {
std::string genericPath = getGenericPath(path); const std::string& genericPath {getGenericPath(path)};
StringList contentList; StringList contentList;
// Only parse the directory, if it's a directory. // Only parse the directory, if it's a directory.
@ -76,17 +76,19 @@ namespace Utils
#if defined(_WIN64) #if defined(_WIN64)
WIN32_FIND_DATAW findData; WIN32_FIND_DATAW findData;
std::wstring wildcard = Utils::String::stringToWideString(genericPath) + L"/*"; const std::wstring& wildcard {Utils::String::stringToWideString(genericPath) +
HANDLE hFind = FindFirstFileW(wildcard.c_str(), &findData); L"/*"};
const HANDLE hFind {FindFirstFileW(wildcard.c_str(), &findData)};
if (hFind != INVALID_HANDLE_VALUE) { if (hFind != INVALID_HANDLE_VALUE) {
// Loop over all files in the directory. // Loop over all files in the directory.
do { do {
std::string name = Utils::String::wideStringToString(findData.cFileName); const std::string& name {
Utils::String::wideStringToString(findData.cFileName)};
// Ignore "." and ".." // Ignore "." and ".."
if ((name != ".") && (name != "..")) { if ((name != ".") && (name != "..")) {
std::string fullName(getGenericPath(genericPath + "/" + name)); const std::string& fullName {getGenericPath(genericPath + "/" + name)};
contentList.push_back(fullName); contentList.emplace_back(fullName);
if (recursive && isDirectory(fullName)) { if (recursive && isDirectory(fullName)) {
contentList.sort(); contentList.sort();
@ -97,18 +99,18 @@ namespace Utils
FindClose(hFind); FindClose(hFind);
} }
#else #else
DIR* dir = opendir(genericPath.c_str()); DIR* dir {opendir(genericPath.c_str())};
if (dir != nullptr) { if (dir != nullptr) {
struct dirent* entry; struct dirent* entry;
// Loop over all files in the directory. // Loop over all files in the directory.
while ((entry = readdir(dir)) != nullptr) { while ((entry = readdir(dir)) != nullptr) {
std::string name(entry->d_name); const std::string& name(entry->d_name);
// Ignore "." and ".." // Ignore "." and ".."
if ((name != ".") && (name != "..")) { if ((name != ".") && (name != "..")) {
std::string fullName(getGenericPath(genericPath + "/" + name)); const std::string& fullName {getGenericPath(genericPath + "/" + name)};
contentList.push_back(fullName); contentList.emplace_back(fullName);
if (recursive && isDirectory(fullName)) { if (recursive && isDirectory(fullName)) {
contentList.sort(); contentList.sort();
@ -132,13 +134,13 @@ namespace Utils
if (entry == std::string::npos) if (entry == std::string::npos)
return files; return files;
std::string parent {getParent(pattern)}; const std::string& parent {getParent(pattern)};
// Don't allow wildcard matching for the parent directory. // Don't allow wildcard matching for the parent directory.
if (entry <= parent.size()) if (entry <= parent.size())
return files; return files;
StringList dirContent {getDirContent(parent)}; const StringList& dirContent {getDirContent(parent)};
if (dirContent.size() == 0) if (dirContent.size() == 0)
return files; return files;
@ -172,19 +174,19 @@ namespace Utils
StringList getPathList(const std::string& path) StringList getPathList(const std::string& path)
{ {
StringList pathList; StringList pathList;
std::string genericPath = getGenericPath(path); const std::string& genericPath {getGenericPath(path)};
size_t start = 0; size_t start {0};
size_t end = 0; size_t end {0};
// Split at '/' // Split at '/'
while ((end = genericPath.find("/", start)) != std::string::npos) { while ((end = genericPath.find("/", start)) != std::string::npos) {
if (end != start) if (end != start)
pathList.push_back(std::string(genericPath, start, end - start)); pathList.emplace_back(std::string {genericPath, start, end - start});
start = end + 1; start = end + 1;
} }
// Add last folder / file to pathList. // Add last folder / file to pathList.
if (start != genericPath.size()) if (start != genericPath.size())
pathList.push_back(std::string(genericPath, start, genericPath.size() - start)); pathList.emplace_back(std::string {genericPath, start, genericPath.size() - start});
return pathList; return pathList;
} }
@ -223,7 +225,7 @@ namespace Utils
#else #else
if (!homePath.length()) { if (!homePath.length()) {
std::string envHome = getenv("HOME"); const std::string& envHome {getenv("HOME")};
if (envHome.length()) if (envHome.length())
homePath = getGenericPath(envHome); homePath = getGenericPath(envHome);
} }
@ -260,16 +262,17 @@ namespace Utils
// Ugly hack to compensate for the Flatpak sandbox restrictions. We traverse // Ugly hack to compensate for the Flatpak sandbox restrictions. We traverse
// this hardcoded list of paths and use the "which" command to check outside the // this hardcoded list of paths and use the "which" command to check outside the
// sandbox if the emulator binary exists. // sandbox if the emulator binary exists.
std::string pathVariable {"/var/lib/flatpak/exports/bin:/usr/bin:/usr/local/" const std::string& pathVariable {
"/var/lib/flatpak/exports/bin:/usr/bin:/usr/local/"
"bin:/usr/local/sbin:/usr/sbin:/sbin:/bin:/usr/games:/usr/" "bin:/usr/local/sbin:/usr/sbin:/sbin:/bin:/usr/games:/usr/"
"local/games:/snap/bin:/var/lib/snapd/snap/bin"}; "local/games:/snap/bin:/var/lib/snapd/snap/bin"};
std::vector<std::string> pathList { const std::vector<std::string>& pathList {
Utils::String::delimitedStringToVector(pathVariable, ":")}; Utils::String::delimitedStringToVector(pathVariable, ":")};
// Using a temporary file is the only viable solution I've found to communicate // Using a temporary file is the only viable solution I've found to communicate
// between the sandbox and the outside world. // between the sandbox and the outside world.
std::string tempFile {Utils::FileSystem::getHomePath() + "/.emulationstation/" + const std::string& tempFile {Utils::FileSystem::getHomePath() + "/.emulationstation/" +
".flatpak_emulator_binary_path.tmp"}; ".flatpak_emulator_binary_path.tmp"};
std::string emulatorPath; std::string emulatorPath;
@ -293,9 +296,9 @@ namespace Utils
return emulatorPath; return emulatorPath;
#else #else
std::string pathVariable {std::string(getenv("PATH"))}; const std::string& pathVariable {std::string {getenv("PATH")}};
std::vector<std::string> pathList { const std::vector<std::string>& pathList {
Utils::String::delimitedStringToVector(pathVariable, ":")}; Utils::String::delimitedStringToVector(pathVariable, ":")};
std::string pathTest; std::string pathTest;
@ -313,7 +316,7 @@ namespace Utils
void setExePath(const std::string& path) void setExePath(const std::string& path)
{ {
constexpr int pathMax = 32767; constexpr int pathMax {32767};
#if defined(_WIN64) #if defined(_WIN64)
std::wstring result(pathMax, 0); std::wstring result(pathMax, 0);
if (GetModuleFileNameW(nullptr, &result[0], pathMax) != 0) if (GetModuleFileNameW(nullptr, &result[0], pathMax) != 0)
@ -349,20 +352,22 @@ namespace Utils
std::string getPreferredPath(const std::string& path) std::string getPreferredPath(const std::string& path)
{ {
std::string preferredPath = path;
#if defined(_WIN64) #if defined(_WIN64)
size_t offset = std::string::npos; std::string preferredPath {path};
size_t offset {std::string::npos};
// Convert '/' to '\\' // Convert '/' to '\\'
while ((offset = preferredPath.find('/')) != std::string::npos) while ((offset = preferredPath.find('/')) != std::string::npos)
preferredPath.replace(offset, 1, "\\"); preferredPath.replace(offset, 1, "\\");
#else
const std::string& preferredPath {path};
#endif #endif
return preferredPath; return preferredPath;
} }
std::string getGenericPath(const std::string& path) std::string getGenericPath(const std::string& path)
{ {
std::string genericPath = path; std::string genericPath {path};
size_t offset = std::string::npos; size_t offset {std::string::npos};
// Remove "\\\\?\\" // Remove "\\\\?\\"
if ((genericPath.find("\\\\?\\")) == 0) if ((genericPath.find("\\\\?\\")) == 0)
@ -386,7 +391,7 @@ namespace Utils
std::string getEscapedPath(const std::string& path) std::string getEscapedPath(const std::string& path)
{ {
std::string escapedPath = getGenericPath(path); std::string escapedPath {getGenericPath(path)};
#if defined(_WIN64) #if defined(_WIN64)
// Windows escapes stuff by just putting everything in quotes. // Windows escapes stuff by just putting everything in quotes.
@ -396,12 +401,12 @@ namespace Utils
return getPreferredPath(escapedPath); return getPreferredPath(escapedPath);
#else #else
// Insert a backslash before most characters that would mess up a bash path. // Insert a backslash before most characters that would mess up a bash path.
const char* invalidChars = "\\ '\"!$^&*(){}[]?;<>"; const char* invalidChars {"\\ '\"!$^&*(){}[]?;<>"};
const char* invalidChar = invalidChars; const char* invalidChar {invalidChars};
while (*invalidChar) { while (*invalidChar) {
size_t start = 0; size_t start {0};
size_t offset = 0; size_t offset {0};
while ((offset = escapedPath.find(*invalidChar, start)) != std::string::npos) { while ((offset = escapedPath.find(*invalidChar, start)) != std::string::npos) {
start = offset + 1; start = offset + 1;
@ -423,17 +428,17 @@ namespace Utils
if ((path[0] == ':') && (path[1] == '/')) if ((path[0] == ':') && (path[1] == '/'))
return path; return path;
std::string canonicalPath = exists(path) ? getAbsolutePath(path) : getGenericPath(path); std::string canonicalPath {exists(path) ? getAbsolutePath(path) : getGenericPath(path)};
// Cleanup path. // Cleanup path.
bool scan = true; bool scan {true};
while (scan) { while (scan) {
StringList pathList = getPathList(canonicalPath); const StringList& pathList {getPathList(canonicalPath)};
canonicalPath.clear(); canonicalPath.clear();
scan = false; scan = false;
for (StringList::const_iterator it = pathList.cbegin(); it != pathList.cend(); for (StringList::const_iterator it {pathList.cbegin()}; it != pathList.cend();
++it) { ++it) {
// Ignore empty. // Ignore empty.
if ((*it).empty()) if ((*it).empty())
@ -458,7 +463,7 @@ namespace Utils
#endif #endif
if (isSymlink(canonicalPath)) { if (isSymlink(canonicalPath)) {
std::string resolved = resolveSymlink(canonicalPath); const std::string& resolved {resolveSymlink(canonicalPath)};
if (resolved.empty()) if (resolved.empty())
return ""; return "";
@ -481,8 +486,9 @@ namespace Utils
std::string getAbsolutePath(const std::string& path, const std::string& base) std::string getAbsolutePath(const std::string& path, const std::string& base)
{ {
std::string absolutePath = getGenericPath(path); const std::string& absolutePath {getGenericPath(path)};
std::string baseVar = isAbsolute(base) ? getGenericPath(base) : getAbsolutePath(base); const std::string& baseVar {isAbsolute(base) ? getGenericPath(base) :
getAbsolutePath(base)};
return isAbsolute(absolutePath) ? absolutePath : return isAbsolute(absolutePath) ? absolutePath :
getGenericPath(baseVar + "/" + absolutePath); getGenericPath(baseVar + "/" + absolutePath);
@ -490,8 +496,8 @@ namespace Utils
std::string getParent(const std::string& path) std::string getParent(const std::string& path)
{ {
std::string genericPath = getGenericPath(path); std::string genericPath {getGenericPath(path)};
size_t offset = std::string::npos; size_t offset {std::string::npos};
// Find last '/' and erase it. // Find last '/' and erase it.
if ((offset = genericPath.find_last_of('/')) != std::string::npos) if ((offset = genericPath.find_last_of('/')) != std::string::npos)
@ -503,13 +509,13 @@ namespace Utils
std::string getFileName(const std::string& path) std::string getFileName(const std::string& path)
{ {
std::string genericPath = getGenericPath(path); const std::string& genericPath {getGenericPath(path)};
size_t offset = std::string::npos; size_t offset {std::string::npos};
// Find last '/' and return the filename. // Find last '/' and return the filename.
if ((offset = genericPath.find_last_of('/')) != std::string::npos) if ((offset = genericPath.find_last_of('/')) != std::string::npos)
return ((genericPath[offset + 1] == 0) ? "." : return ((genericPath[offset + 1] == 0) ? "." :
std::string(genericPath, offset + 1)); std::string {genericPath, offset + 1});
// No '/' found, entire path is a filename. // No '/' found, entire path is a filename.
return genericPath; return genericPath;
@ -517,8 +523,8 @@ namespace Utils
std::string getStem(const std::string& path) std::string getStem(const std::string& path)
{ {
std::string fileName = getFileName(path); std::string fileName {getFileName(path)};
size_t offset = std::string::npos; size_t offset {std::string::npos};
// Empty fileName. // Empty fileName.
if (fileName == ".") if (fileName == ".")
@ -536,8 +542,8 @@ namespace Utils
std::string getExtension(const std::string& path) std::string getExtension(const std::string& path)
{ {
std::string fileName = getFileName(path); const std::string& fileName {getFileName(path)};
size_t offset = std::string::npos; size_t offset {std::string::npos};
// Empty fileName. // Empty fileName.
if (fileName == ".") if (fileName == ".")
@ -545,7 +551,7 @@ namespace Utils
// Find last '.' and return the extension. // Find last '.' and return the extension.
if ((offset = fileName.find_last_of('.')) != std::string::npos) if ((offset = fileName.find_last_of('.')) != std::string::npos)
return std::string(fileName, offset); return std::string {fileName, offset};
// No '.' found, filename has no extension. // No '.' found, filename has no extension.
return "."; return ".";
@ -561,9 +567,9 @@ namespace Utils
const std::string& relativeTo, const std::string& relativeTo,
const bool allowHome) const bool allowHome)
{ {
std::string genericPath = getGenericPath(path); const std::string& genericPath {getGenericPath(path)};
std::string relativeToVar = const std::string& relativeToVar {isDirectory(relativeTo) ? getGenericPath(relativeTo) :
isDirectory(relativeTo) ? getGenericPath(relativeTo) : getParent(relativeTo); getParent(relativeTo)};
// Nothing to resolve. // Nothing to resolve.
if (!genericPath.length()) if (!genericPath.length())
@ -585,8 +591,8 @@ namespace Utils
const std::string& relativeTo, const std::string& relativeTo,
const bool allowHome) const bool allowHome)
{ {
bool contains = false; bool contains {false};
std::string relativePath = removeCommonPath(path, relativeTo, contains); std::string relativePath {removeCommonPath(path, relativeTo, contains)};
if (contains) if (contains)
return ("./" + relativePath); return ("./" + relativePath);
@ -604,9 +610,9 @@ namespace Utils
const std::string& commonArg, const std::string& commonArg,
bool& contains) bool& contains)
{ {
std::string genericPath = getGenericPath(path); const std::string& genericPath {getGenericPath(path)};
std::string common = const std::string& common {isDirectory(commonArg) ? getGenericPath(commonArg) :
isDirectory(commonArg) ? getGenericPath(commonArg) : getParent(commonArg); getParent(commonArg)};
if (genericPath.find(common) == 0) { if (genericPath.find(common) == 0) {
contains = true; contains = true;
@ -619,7 +625,7 @@ namespace Utils
std::string resolveSymlink(const std::string& path) std::string resolveSymlink(const std::string& path)
{ {
std::string genericPath = getGenericPath(path); const std::string& genericPath {getGenericPath(path)};
std::string resolved; std::string resolved;
#if defined(_WIN64) #if defined(_WIN64)
@ -675,10 +681,10 @@ namespace Utils
} }
#if defined(_WIN64) #if defined(_WIN64)
std::ifstream sourceFile(Utils::String::stringToWideString(sourcePath).c_str(), std::ifstream sourceFile {Utils::String::stringToWideString(sourcePath).c_str(),
std::ios::binary); std::ios::binary};
#else #else
std::ifstream sourceFile(sourcePath, std::ios::binary); std::ifstream sourceFile {sourcePath, std::ios::binary};
#endif #endif
if (sourceFile.fail()) { if (sourceFile.fail()) {
@ -689,10 +695,10 @@ namespace Utils
} }
#if defined(_WIN64) #if defined(_WIN64)
std::ofstream targetFile(Utils::String::stringToWideString(destinationPath).c_str(), std::ofstream targetFile {Utils::String::stringToWideString(destinationPath).c_str(),
std::ios::binary); std::ios::binary};
#else #else
std::ofstream targetFile(destinationPath, std::ios::binary); std::ofstream targetFile {destinationPath, std::ios::binary};
#endif #endif
if (targetFile.fail()) { if (targetFile.fail()) {
@ -744,7 +750,7 @@ namespace Utils
bool removeFile(const std::string& path) bool removeFile(const std::string& path)
{ {
std::string genericPath = getGenericPath(path); const std::string& genericPath {getGenericPath(path)};
// Don't remove if it doesn't exists. // Don't remove if it doesn't exists.
if (!exists(genericPath)) if (!exists(genericPath))
@ -798,7 +804,7 @@ namespace Utils
bool createDirectory(const std::string& path) bool createDirectory(const std::string& path)
{ {
std::string genericPath = getGenericPath(path); const std::string& genericPath {getGenericPath(path)};
if (exists(genericPath)) if (exists(genericPath))
return true; return true;
@ -812,7 +818,7 @@ namespace Utils
#endif #endif
// Failed to create directory, try to create the parent. // Failed to create directory, try to create the parent.
std::string parent = getParent(genericPath); const std::string& parent {getParent(genericPath)};
// Only try to create parent if it's not identical to genericPath. // Only try to create parent if it's not identical to genericPath.
if (parent != genericPath) if (parent != genericPath)
@ -829,7 +835,7 @@ namespace Utils
bool exists(const std::string& path) bool exists(const std::string& path)
{ {
std::string genericPath = getGenericPath(path); const std::string& genericPath {getGenericPath(path)};
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
struct stat info; struct stat info;
@ -846,7 +852,7 @@ namespace Utils
bool driveExists(const std::string& path) bool driveExists(const std::string& path)
{ {
#if defined(_WIN64) #if defined(_WIN64)
std::string genericPath = getGenericPath(path); std::string genericPath {getGenericPath(path)};
// Try to add a dot or a backslash and a dot depending on how the drive // Try to add a dot or a backslash and a dot depending on how the drive
// letter was defined by the user. // letter was defined by the user.
if (genericPath.length() == 2 && genericPath.at(1) == ':') if (genericPath.length() == 2 && genericPath.at(1) == ':')
@ -864,7 +870,7 @@ namespace Utils
bool isAbsolute(const std::string& path) bool isAbsolute(const std::string& path)
{ {
std::string genericPath = getGenericPath(path); const std::string& genericPath {getGenericPath(path)};
#if defined(_WIN64) #if defined(_WIN64)
return ((genericPath.size() > 1) && (genericPath[1] == ':')); return ((genericPath.size() > 1) && (genericPath[1] == ':'));
@ -875,7 +881,7 @@ namespace Utils
bool isRegularFile(const std::string& path) bool isRegularFile(const std::string& path)
{ {
std::string genericPath = getGenericPath(path); const std::string& genericPath {getGenericPath(path)};
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
struct stat info; struct stat info;
@ -897,7 +903,7 @@ namespace Utils
bool isDirectory(const std::string& path) bool isDirectory(const std::string& path)
{ {
std::string genericPath = getGenericPath(path); const std::string& genericPath {getGenericPath(path)};
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
struct stat info; struct stat info;
@ -919,12 +925,12 @@ namespace Utils
bool isSymlink(const std::string& path) bool isSymlink(const std::string& path)
{ {
std::string genericPath = getGenericPath(path); const std::string& genericPath {getGenericPath(path)};
#if defined(_WIN64) #if defined(_WIN64)
// Check for symlink attribute. // Check for symlink attribute.
const DWORD Attributes = const DWORD Attributes {
GetFileAttributesW(Utils::String::stringToWideString(genericPath).c_str()); GetFileAttributesW(Utils::String::stringToWideString(genericPath).c_str())};
if ((Attributes != INVALID_FILE_ATTRIBUTES) && if ((Attributes != INVALID_FILE_ATTRIBUTES) &&
(Attributes & FILE_ATTRIBUTE_REPARSE_POINT)) (Attributes & FILE_ATTRIBUTE_REPARSE_POINT))
return true; return true;
@ -952,12 +958,12 @@ namespace Utils
bool isHidden(const std::string& path) bool isHidden(const std::string& path)
{ {
std::string genericPath = getGenericPath(path); const std::string& genericPath {getGenericPath(path)};
#if defined(_WIN64) #if defined(_WIN64)
// Check for hidden attribute. // Check for hidden attribute.
const DWORD Attributes = const DWORD Attributes {
GetFileAttributesW(Utils::String::stringToWideString(genericPath).c_str()); GetFileAttributesW(Utils::String::stringToWideString(genericPath).c_str())};
if ((Attributes != INVALID_FILE_ATTRIBUTES) && (Attributes & FILE_ATTRIBUTE_HIDDEN)) if ((Attributes != INVALID_FILE_ATTRIBUTES) && (Attributes & FILE_ATTRIBUTE_HIDDEN))
return true; return true;
#endif #endif