1
0
Fork 0

Codechange: Remove create parameter from IniLoadFile::GetGroup.

GetGroup now only returns nullptr if the group does not exist.
Use GetOrCreateGroup to create a group.

This avoids creating groups while reading ini files.
pull/11385/head
Peter Nelson 2023-10-10 19:25:59 +01:00 committed by Peter Nelson
parent c47a0e1578
commit 1fecbeff76
8 changed files with 37 additions and 30 deletions

View File

@ -42,6 +42,11 @@ template <class T, size_t Tnum_files, bool Tsearch_in_tars>
bool BaseSet<T, Tnum_files, Tsearch_in_tars>::FillSetDetails(IniFile &ini, const std::string &path, const std::string &full_filename, bool allow_empty_filename) bool BaseSet<T, Tnum_files, Tsearch_in_tars>::FillSetDetails(IniFile &ini, const std::string &path, const std::string &full_filename, bool allow_empty_filename)
{ {
IniGroup *metadata = ini.GetGroup("metadata"); IniGroup *metadata = ini.GetGroup("metadata");
if (metadata == nullptr) {
Debug(grf, 0, "Base " SET_TYPE "set detail loading: metadata missing.");
Debug(grf, 0, " Is {} readable for the user running OpenTTD?", full_filename);
return false;
}
IniItem *item; IniItem *item;
fetch_metadata("name"); fetch_metadata("name");
@ -75,7 +80,7 @@ bool BaseSet<T, Tnum_files, Tsearch_in_tars>::FillSetDetails(IniFile &ini, const
for (uint i = 0; i < Tnum_files; i++) { for (uint i = 0; i < Tnum_files; i++) {
MD5File *file = &this->files[i]; MD5File *file = &this->files[i];
/* Find the filename first. */ /* Find the filename first. */
item = files->GetItem(BaseSet<T, Tnum_files, Tsearch_in_tars>::file_names[i]); item = files != nullptr ? files->GetItem(BaseSet<T, Tnum_files, Tsearch_in_tars>::file_names[i]) : nullptr;
if (item == nullptr || (!item->value.has_value() && !allow_empty_filename)) { if (item == nullptr || (!item->value.has_value() && !allow_empty_filename)) {
Debug(grf, 0, "No " SET_TYPE " file for: {} (in {})", BaseSet<T, Tnum_files, Tsearch_in_tars>::file_names[i], full_filename); Debug(grf, 0, "No " SET_TYPE " file for: {} (in {})", BaseSet<T, Tnum_files, Tsearch_in_tars>::file_names[i], full_filename);
return false; return false;
@ -93,7 +98,7 @@ bool BaseSet<T, Tnum_files, Tsearch_in_tars>::FillSetDetails(IniFile &ini, const
file->filename = path + filename; file->filename = path + filename;
/* Then find the MD5 checksum */ /* Then find the MD5 checksum */
item = md5s->GetItem(filename); item = md5s != nullptr ? md5s->GetItem(filename) : nullptr;
if (item == nullptr || !item->value.has_value()) { if (item == nullptr || !item->value.has_value()) {
Debug(grf, 0, "No MD5 checksum specified for: {} (in {})", filename, full_filename); Debug(grf, 0, "No MD5 checksum specified for: {} (in {})", filename, full_filename);
return false; return false;
@ -119,8 +124,8 @@ bool BaseSet<T, Tnum_files, Tsearch_in_tars>::FillSetDetails(IniFile &ini, const
} }
/* Then find the warning message when the file's missing */ /* Then find the warning message when the file's missing */
item = origin->GetItem(filename); item = origin != nullptr ? origin->GetItem(filename) : nullptr;
if (item == nullptr) item = origin->GetItem("default"); if (item == nullptr) item = origin != nullptr ? origin->GetItem("default") : nullptr;
if (item == nullptr || !item->value.has_value()) { if (item == nullptr || !item->value.has_value()) {
Debug(grf, 1, "No origin warning message specified for: {}", filename); Debug(grf, 1, "No origin warning message specified for: {}", filename);
file->missing_warning.clear(); file->missing_warning.clear();

View File

@ -352,6 +352,7 @@ bool GraphicsSet::FillSetDetails(IniFile &ini, const std::string &path, const st
bool ret = this->BaseSet<GraphicsSet, MAX_GFT, true>::FillSetDetails(ini, path, full_filename, false); bool ret = this->BaseSet<GraphicsSet, MAX_GFT, true>::FillSetDetails(ini, path, full_filename, false);
if (ret) { if (ret) {
IniGroup *metadata = ini.GetGroup("metadata"); IniGroup *metadata = ini.GetGroup("metadata");
assert(metadata != nullptr); /* ret can't be true if metadata isn't present. */
IniItem *item; IniItem *item;
fetch_metadata("palette"); fetch_metadata("palette");

View File

@ -277,6 +277,7 @@ HotkeyList::~HotkeyList()
void HotkeyList::Load(IniFile &ini) void HotkeyList::Load(IniFile &ini)
{ {
IniGroup *group = ini.GetGroup(this->ini_group); IniGroup *group = ini.GetGroup(this->ini_group);
if (group == nullptr) return;
for (Hotkey &hotkey : this->items) { for (Hotkey &hotkey : this->items) {
IniItem *item = group->GetItem(hotkey.name); IniItem *item = group->GetItem(hotkey.name);
if (item != nullptr) { if (item != nullptr) {

View File

@ -174,23 +174,17 @@ IniLoadFile::~IniLoadFile()
} }
/** /**
* Get the group with the given name. If it doesn't exist * Get the group with the given name.
* and \a create_new is \c true create a new group.
* @param name name of the group to find. * @param name name of the group to find.
* @param create_new Allow creation of group if it does not exist. * @return The requested group or \c nullptr if not found.
* @return The requested group if it exists or was created, else \c nullptr.
*/ */
IniGroup *IniLoadFile::GetGroup(const std::string &name, bool create_new) IniGroup *IniLoadFile::GetGroup(const std::string &name) const
{ {
/* does it exist already? */
for (IniGroup *group = this->group; group != nullptr; group = group->next) { for (IniGroup *group = this->group; group != nullptr; group = group->next) {
if (group->name == name) return group; if (group->name == name) return group;
} }
if (!create_new) return nullptr; return nullptr;
/* otherwise make a new one */
return &this->CreateGroup(name);
} }
/** /**

View File

@ -62,7 +62,7 @@ struct IniLoadFile {
IniLoadFile(const char * const *list_group_names = nullptr, const char * const *seq_group_names = nullptr); IniLoadFile(const char * const *list_group_names = nullptr, const char * const *seq_group_names = nullptr);
virtual ~IniLoadFile(); virtual ~IniLoadFile();
IniGroup *GetGroup(const std::string &name, bool create_new = true); IniGroup *GetGroup(const std::string &name) const;
IniGroup &GetOrCreateGroup(const std::string &name); IniGroup &GetOrCreateGroup(const std::string &name);
IniGroup &CreateGroup(const std::string &name); IniGroup &CreateGroup(const std::string &name);
void RemoveGroup(const std::string &name); void RemoveGroup(const std::string &name);

View File

@ -133,7 +133,7 @@ bool MusicSet::FillSetDetails(IniFile &ini, const std::string &path, const std::
this->songinfo[i].filename = filename; // non-owned pointer this->songinfo[i].filename = filename; // non-owned pointer
IniItem *item = catindex->GetItem(_music_file_names[i]); IniItem *item = catindex != nullptr ? catindex->GetItem(_music_file_names[i]) : nullptr;
if (item != nullptr && item->value.has_value() && !item->value->empty()) { if (item != nullptr && item->value.has_value() && !item->value->empty()) {
/* Song has a CAT file index, assume it's MPS MIDI format */ /* Song has a CAT file index, assume it's MPS MIDI format */
this->songinfo[i].filetype = MTT_MPSMIDI; this->songinfo[i].filetype = MTT_MPSMIDI;
@ -158,7 +158,7 @@ bool MusicSet::FillSetDetails(IniFile &ini, const std::string &path, const std::
* the beginning, so we don't start reading e.g. root. */ * the beginning, so we don't start reading e.g. root. */
while (*trimmed_filename == PATHSEPCHAR) trimmed_filename++; while (*trimmed_filename == PATHSEPCHAR) trimmed_filename++;
item = names->GetItem(trimmed_filename); item = names != nullptr ? names->GetItem(trimmed_filename) : nullptr;
if (item != nullptr && item->value.has_value() && !item->value->empty()) break; if (item != nullptr && item->value.has_value() && !item->value->empty()) break;
} }
@ -179,7 +179,7 @@ bool MusicSet::FillSetDetails(IniFile &ini, const std::string &path, const std::
this->songinfo[i].tracknr = tracknr++; this->songinfo[i].tracknr = tracknr++;
} }
item = trimmed_filename != nullptr ? timingtrim->GetItem(trimmed_filename) : nullptr; item = trimmed_filename != nullptr && timingtrim != nullptr ? timingtrim->GetItem(trimmed_filename) : nullptr;
if (item != nullptr && item->value.has_value() && !item->value->empty()) { if (item != nullptr && item->value.has_value() && !item->value->empty()) {
auto endpos = item->value->find(':'); auto endpos = item->value->find(':');
if (endpos != std::string::npos) { if (endpos != std::string::npos) {

View File

@ -600,13 +600,15 @@ static void IniLoadSettings(IniFile &ini, const SettingTable &settings_table, co
auto sc = s.find('.'); auto sc = s.find('.');
if (sc != std::string::npos) { if (sc != std::string::npos) {
group = ini.GetGroup(s.substr(0, sc)); group = ini.GetGroup(s.substr(0, sc));
if (group == nullptr) group = group_def;
s = s.substr(sc + 1); s = s.substr(sc + 1);
} else { } else {
group = group_def; group = group_def;
} }
IniItem *item = group->GetItem(s); IniItem *item = nullptr;
if (item == nullptr && group != group_def) { if (group != nullptr) item = group->GetItem(s);
if (item == nullptr && group != group_def && group_def != nullptr) {
/* For settings.xx.yy load the settings from [settings] yy = ? in case the previous /* For settings.xx.yy load the settings from [settings] yy = ? in case the previous
* did not exist (e.g. loading old config files with a [settings] section */ * did not exist (e.g. loading old config files with a [settings] section */
item = group_def->GetItem(s); item = group_def->GetItem(s);
@ -615,7 +617,9 @@ static void IniLoadSettings(IniFile &ini, const SettingTable &settings_table, co
/* For settings.xx.zz.yy load the settings from [zz] yy = ? in case the previous /* For settings.xx.zz.yy load the settings from [zz] yy = ? in case the previous
* did not exist (e.g. loading old config files with a [yapf] section */ * did not exist (e.g. loading old config files with a [yapf] section */
sc = s.find('.'); sc = s.find('.');
if (sc != std::string::npos) item = ini.GetGroup(s.substr(0, sc))->GetItem(s.substr(sc + 1)); if (sc != std::string::npos) {
if (group = ini.GetGroup(s.substr(0, sc)); group != nullptr) item = group->GetItem(s.substr(sc + 1));
}
} }
sd->ParseValue(item, object); sd->ParseValue(item, object);
@ -1087,6 +1091,7 @@ static GRFConfig *GRFLoadConfig(IniFile &ini, const char *grpname, bool is_stati
static IniFileVersion LoadVersionFromConfig(IniFile &ini) static IniFileVersion LoadVersionFromConfig(IniFile &ini)
{ {
IniGroup *group = ini.GetGroup("version"); IniGroup *group = ini.GetGroup("version");
if (group == nullptr) return IFV_0;
auto version_number = group->GetItem("ini_version"); auto version_number = group->GetItem("ini_version");
/* Older ini-file versions don't have this key yet. */ /* Older ini-file versions don't have this key yet. */
@ -1212,6 +1217,7 @@ static void RemoveEntriesFromIni(IniFile &ini, const SettingTable &table)
if (sc == std::string::npos) continue; if (sc == std::string::npos) continue;
IniGroup *group = ini.GetGroup(s.substr(0, sc)); IniGroup *group = ini.GetGroup(s.substr(0, sc));
if (group == nullptr) continue;
s = s.substr(sc + 1); s = s.substr(sc + 1);
group->RemoveItem(s); group->RemoveItem(s);
@ -1245,7 +1251,7 @@ bool IsConversionNeeded(ConfigIniFile &ini, std::string group, std::string old_v
{ {
*old_item = nullptr; *old_item = nullptr;
IniGroup *igroup = ini.GetGroup(group, false); IniGroup *igroup = ini.GetGroup(group);
/* If the group doesn't exist, there is nothing to convert. */ /* If the group doesn't exist, there is nothing to convert. */
if (igroup == nullptr) return false; if (igroup == nullptr) return false;
@ -1295,7 +1301,7 @@ void LoadFromConfig(bool startup)
/* Move no_http_content_downloads and use_relay_service from generic_ini to private_ini. */ /* Move no_http_content_downloads and use_relay_service from generic_ini to private_ini. */
if (generic_version < IFV_NETWORK_PRIVATE_SETTINGS) { if (generic_version < IFV_NETWORK_PRIVATE_SETTINGS) {
IniGroup *network = generic_ini.GetGroup("network", false); IniGroup *network = generic_ini.GetGroup("network");
if (network != nullptr) { if (network != nullptr) {
IniItem *no_http_content_downloads = network->GetItem("no_http_content_downloads"); IniItem *no_http_content_downloads = network->GetItem("no_http_content_downloads");
if (no_http_content_downloads != nullptr) { if (no_http_content_downloads != nullptr) {
@ -1377,8 +1383,8 @@ void SaveToConfig()
* just so we can add a comment before it (that is how IniFile works). * just so we can add a comment before it (that is how IniFile works).
* This to explain what the file is about. After doing it once, never touch * This to explain what the file is about. After doing it once, never touch
* it again, as otherwise we might be reverting user changes. */ * it again, as otherwise we might be reverting user changes. */
if (IniGroup *group = private_ini.GetGroup("private", false); group != nullptr) group->comment = "; This file possibly contains private information which can identify you as person.\n"; if (IniGroup *group = private_ini.GetGroup("private"); group != nullptr) group->comment = "; This file possibly contains private information which can identify you as person.\n";
if (IniGroup *group = secrets_ini.GetGroup("secrets", false); group != nullptr) group->comment = "; Do not share this file with others, not even if they claim to be technical support.\n; This file contains saved passwords and other secrets that should remain private to you!\n"; if (IniGroup *group = secrets_ini.GetGroup("secrets"); group != nullptr) group->comment = "; Do not share this file with others, not even if they claim to be technical support.\n; This file contains saved passwords and other secrets that should remain private to you!\n";
if (generic_version == IFV_0) { if (generic_version == IFV_0) {
/* Remove some obsolete groups. These have all been loaded into other groups. */ /* Remove some obsolete groups. These have all been loaded into other groups. */
@ -1402,7 +1408,7 @@ void SaveToConfig()
/* These variables are migrated from generic ini to private ini now. */ /* These variables are migrated from generic ini to private ini now. */
if (generic_version < IFV_NETWORK_PRIVATE_SETTINGS) { if (generic_version < IFV_NETWORK_PRIVATE_SETTINGS) {
IniGroup *network = generic_ini.GetGroup("network", false); IniGroup *network = generic_ini.GetGroup("network");
if (network != nullptr) { if (network != nullptr) {
network->RemoveItem("no_http_content_downloads"); network->RemoveItem("no_http_content_downloads");
network->RemoveItem("use_relay_service"); network->RemoveItem("use_relay_service");

View File

@ -195,7 +195,7 @@ static const char *DEFAULTS_GROUP_NAME = "defaults"; ///< Name of the group con
*/ */
static void DumpGroup(IniLoadFile &ifile, const char * const group_name) static void DumpGroup(IniLoadFile &ifile, const char * const group_name)
{ {
IniGroup *grp = ifile.GetGroup(group_name, false); IniGroup *grp = ifile.GetGroup(group_name);
if (grp != nullptr && grp->type == IGT_SEQUENCE) { if (grp != nullptr && grp->type == IGT_SEQUENCE) {
for (IniItem *item = grp->item; item != nullptr; item = item->next) { for (IniItem *item = grp->item; item != nullptr; item = item->next) {
if (!item->name.empty()) { if (!item->name.empty()) {
@ -296,9 +296,9 @@ static void DumpSections(IniLoadFile &ifile)
{ {
static const char * const special_group_names[] = {PREAMBLE_GROUP_NAME, POSTAMBLE_GROUP_NAME, DEFAULTS_GROUP_NAME, TEMPLATES_GROUP_NAME, VALIDATION_GROUP_NAME, nullptr}; static const char * const special_group_names[] = {PREAMBLE_GROUP_NAME, POSTAMBLE_GROUP_NAME, DEFAULTS_GROUP_NAME, TEMPLATES_GROUP_NAME, VALIDATION_GROUP_NAME, nullptr};
IniGroup *default_grp = ifile.GetGroup(DEFAULTS_GROUP_NAME, false); IniGroup *default_grp = ifile.GetGroup(DEFAULTS_GROUP_NAME);
IniGroup *templates_grp = ifile.GetGroup(TEMPLATES_GROUP_NAME, false); IniGroup *templates_grp = ifile.GetGroup(TEMPLATES_GROUP_NAME);
IniGroup *validation_grp = ifile.GetGroup(VALIDATION_GROUP_NAME, false); IniGroup *validation_grp = ifile.GetGroup(VALIDATION_GROUP_NAME);
if (templates_grp == nullptr) return; if (templates_grp == nullptr) return;
/* Output every group, using its name as template name. */ /* Output every group, using its name as template name. */