diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp --- a/src/aircraft_cmd.cpp +++ b/src/aircraft_cmd.cpp @@ -309,7 +309,7 @@ CommandCost CmdBuildAircraft(TileIndex t v->cargo_type = e->GetDefaultCargoType(); u->cargo_type = CT_MAIL; - v->name = nullptr; + v->name.clear(); v->last_station_visited = INVALID_STATION; v->last_loading_station = INVALID_STATION; diff --git a/src/base_consist.cpp b/src/base_consist.cpp --- a/src/base_consist.cpp +++ b/src/base_consist.cpp @@ -14,10 +14,6 @@ #include "safeguards.h" -BaseConsist::~BaseConsist() -{ - free(this->name); -} /** * Copy properties of other BaseConsist. @@ -27,8 +23,7 @@ void BaseConsist::CopyConsistPropertiesF { if (this == src) return; - free(this->name); - this->name = src->name != nullptr ? stredup(src->name) : nullptr; + this->name = src->name; this->current_order_time = src->current_order_time; this->lateness_counter = src->lateness_counter; diff --git a/src/base_consist.h b/src/base_consist.h --- a/src/base_consist.h +++ b/src/base_consist.h @@ -12,10 +12,11 @@ #include "order_type.h" #include "date_type.h" +#include /** Various front vehicle properties that are preserved when autoreplacing, using order-backup or switching front engines within a consist. */ struct BaseConsist { - char *name; ///< Name of vehicle + std::string name; ///< Name of vehicle /* Used for timetabling. */ uint32 current_order_time; ///< How many ticks have passed since this order started. @@ -29,8 +30,7 @@ struct BaseConsist { uint16 vehicle_flags; ///< Used for gradual loading and other miscellaneous things (@see VehicleFlags enum) - BaseConsist() : name(nullptr) {} - virtual ~BaseConsist(); + virtual ~BaseConsist() {} void CopyConsistPropertiesFrom(const BaseConsist *src); }; diff --git a/src/base_station_base.h b/src/base_station_base.h --- a/src/base_station_base.h +++ b/src/base_station_base.h @@ -54,7 +54,7 @@ struct BaseStation : StationPool::PoolIt TrackedViewportSign sign; ///< NOSAVE: Dimensions of sign byte delete_ctr; ///< Delete counter. If greater than 0 then it is decremented until it reaches 0; the waypoint is then is deleted. - char *name; ///< Custom name + std::string name; ///< Custom name StringID string_id; ///< Default name (town area) of station mutable std::string cached_name; ///< NOSAVE: Cache of the resolved name of the station, if not using a custom name @@ -111,7 +111,7 @@ struct BaseStation : StationPool::PoolIt inline const char *GetCachedName() const { - if (this->name != nullptr) return this->name; + if (!this->name.empty()) return this->name.c_str(); if (this->cached_name.empty()) this->FillCachedName(); return this->cached_name.c_str(); } diff --git a/src/company_base.h b/src/company_base.h --- a/src/company_base.h +++ b/src/company_base.h @@ -16,6 +16,7 @@ #include "tile_type.h" #include "settings_type.h" #include "group.h" +#include /** Statistics about the economy. */ struct CompanyEconomyEntry { @@ -54,11 +55,11 @@ extern CompanyPool _company_pool; struct CompanyProperties { uint32 name_2; ///< Parameter of #name_1. StringID name_1; ///< Name of the company if the user did not change it. - char *name; ///< Name of the company if the user changed it. + std::string name; ///< Name of the company if the user changed it. StringID president_name_1; ///< Name of the president if the user did not change it. uint32 president_name_2; ///< Parameter of #president_name_1 - char *president_name; ///< Name of the president if the user changed it. + std::string president_name; ///< Name of the president if the user changed it. CompanyManagerFace face; ///< Face description of the president. @@ -99,17 +100,11 @@ struct CompanyProperties { // TODO: Change some of these member variables to use relevant INVALID_xxx constants CompanyProperties() - : name_2(0), name_1(0), name(nullptr), president_name_1(0), president_name_2(0), president_name(nullptr), + : name_2(0), name_1(0), president_name_1(0), president_name_2(0), face(0), money(0), money_fraction(0), current_loan(0), colour(0), block_preview(0), location_of_HQ(0), last_build_coordinate(0), share_owners(), inaugurated_year(0), months_of_bankruptcy(0), bankrupt_asked(0), bankrupt_timeout(0), bankrupt_value(0), terraform_limit(0), clear_limit(0), tree_limit(0), is_ai(false) {} - - ~CompanyProperties() - { - free(this->name); - free(this->president_name); - } }; struct Company : CompanyPool::PoolItem<&_company_pool>, CompanyProperties { diff --git a/src/company_cmd.cpp b/src/company_cmd.cpp --- a/src/company_cmd.cpp +++ b/src/company_cmd.cpp @@ -353,7 +353,7 @@ static void GenerateCompanyName(Company StringID str; uint32 strp; - if (t->name == nullptr && IsInsideMM(t->townnametype, SPECSTR_TOWNNAME_START, SPECSTR_TOWNNAME_LAST + 1)) { + if (t->name.empty() && IsInsideMM(t->townnametype, SPECSTR_TOWNNAME_START, SPECSTR_TOWNNAME_LAST + 1)) { str = t->townnametype - SPECSTR_TOWNNAME_START + SPECSTR_COMPANY_NAME_START; strp = t->townnameparts; @@ -1043,7 +1043,7 @@ CommandCost CmdSetCompanyColour(TileInde static bool IsUniqueCompanyName(const char *name) { for (const Company *c : Company::Iterate()) { - if (c->name != nullptr && strcmp(c->name, name) == 0) return false; + if (!c->name.empty() && c->name == name) return false; } return true; @@ -1069,8 +1069,11 @@ CommandCost CmdRenameCompany(TileIndex t if (flags & DC_EXEC) { Company *c = Company::Get(_current_company); - free(c->name); - c->name = reset ? nullptr : stredup(text); + if (reset) { + c->name.clear(); + } else { + c->name = text; + } MarkWholeScreenDirty(); CompanyAdminUpdate(c); } @@ -1086,7 +1089,7 @@ CommandCost CmdRenameCompany(TileIndex t static bool IsUniquePresidentName(const char *name) { for (const Company *c : Company::Iterate()) { - if (c->president_name != nullptr && strcmp(c->president_name, name) == 0) return false; + if (!c->president_name.empty() && c->president_name == name) return false; } return true; @@ -1112,14 +1115,13 @@ CommandCost CmdRenamePresident(TileIndex if (flags & DC_EXEC) { Company *c = Company::Get(_current_company); - free(c->president_name); if (reset) { - c->president_name = nullptr; + c->president_name.clear(); } else { - c->president_name = stredup(text); + c->president_name = text; - if (c->name_1 == STR_SV_UNNAMED && c->name == nullptr) { + if (c->name_1 == STR_SV_UNNAMED && c->name.empty()) { char buf[80]; seprintf(buf, lastof(buf), "%s Transport", text); diff --git a/src/depot.cpp b/src/depot.cpp --- a/src/depot.cpp +++ b/src/depot.cpp @@ -27,8 +27,6 @@ INSTANTIATE_POOL_METHODS(Depot) */ Depot::~Depot() { - free(this->name); - if (CleaningPool()) return; if (!IsDepotTile(this->xy) || GetDepotIndex(this->xy) != this->index) { diff --git a/src/depot_base.h b/src/depot_base.h --- a/src/depot_base.h +++ b/src/depot_base.h @@ -18,7 +18,7 @@ extern DepotPool _depot_pool; struct Depot : DepotPool::PoolItem<&_depot_pool> { Town *town; - char *name; + std::string name; TileIndex xy; uint16 town_cn; ///< The N-1th depot for this town (consecutive number) diff --git a/src/depot_cmd.cpp b/src/depot_cmd.cpp --- a/src/depot_cmd.cpp +++ b/src/depot_cmd.cpp @@ -29,7 +29,7 @@ static bool IsUniqueDepotName(const char *name) { for (const Depot *d : Depot::Iterate()) { - if (d->name != nullptr && strcmp(d->name, name) == 0) return false; + if (!d->name.empty() && d->name == name) return false; } return true; @@ -60,13 +60,11 @@ CommandCost CmdRenameDepot(TileIndex til } if (flags & DC_EXEC) { - free(d->name); - if (reset) { - d->name = nullptr; + d->name.clear(); MakeDefaultName(d); } else { - d->name = stredup(text); + d->name = text; } /* Update the orders and depot */ diff --git a/src/engine.cpp b/src/engine.cpp --- a/src/engine.cpp +++ b/src/engine.cpp @@ -67,7 +67,6 @@ assert_compile(lengthof(_orig_rail_vehic const uint EngineOverrideManager::NUM_DEFAULT_ENGINES = _engine_counts[VEH_TRAIN] + _engine_counts[VEH_ROAD] + _engine_counts[VEH_SHIP] + _engine_counts[VEH_AIRCRAFT]; Engine::Engine() : - name(nullptr), overrides_count(0), overrides(nullptr) { @@ -140,7 +139,6 @@ Engine::Engine(VehicleType type, EngineI Engine::~Engine() { UnloadWagonOverrides(this); - free(this->name); } /** @@ -1069,7 +1067,7 @@ void EnginesMonthlyLoop() static bool IsUniqueEngineName(const char *name) { for (const Engine *e : Engine::Iterate()) { - if (e->name != nullptr && strcmp(e->name, name) == 0) return false; + if (!e->name.empty() && e->name == name) return false; } return true; @@ -1097,12 +1095,10 @@ CommandCost CmdRenameEngine(TileIndex ti } if (flags & DC_EXEC) { - free(e->name); - if (reset) { - e->name = nullptr; + e->name.clear(); } else { - e->name = stredup(text); + e->name = text; } MarkWholeScreenDirty(); diff --git a/src/engine_base.h b/src/engine_base.h --- a/src/engine_base.h +++ b/src/engine_base.h @@ -19,7 +19,7 @@ typedef Pool { - char *name; ///< Custom name of engine. + std::string name; ///< Custom name of engine. Date intro_date; ///< Date of introduction of the engine. Date age; uint16 reliability; ///< Current reliability of the engine. diff --git a/src/fios_gui.cpp b/src/fios_gui.cpp --- a/src/fios_gui.cpp +++ b/src/fios_gui.cpp @@ -533,9 +533,9 @@ public: for (auto &pair : _load_check_data.companies) { SetDParam(0, pair.first + 1); const CompanyProperties &c = *pair.second; - if (c.name != nullptr) { + if (!c.name.empty()) { SetDParam(1, STR_JUST_RAW_STRING); - SetDParamStr(2, c.name); + SetDParamStr(2, c.name.c_str()); } else { SetDParam(1, c.name_1); SetDParam(2, c.name_2); diff --git a/src/group.h b/src/group.h --- a/src/group.h +++ b/src/group.h @@ -16,6 +16,7 @@ #include "vehicle_type.h" #include "engine_type.h" #include "livery.h" +#include typedef Pool GroupPool; extern GroupPool _group_pool; ///< Pool of groups. @@ -63,7 +64,7 @@ struct GroupStatistics { /** Group data. */ struct Group : GroupPool::PoolItem<&_group_pool> { - char *name; ///< Group Name + std::string name; ///< Group Name Owner owner; ///< Group Owner VehicleType vehicle_type; ///< Vehicle type of the group @@ -76,7 +77,6 @@ struct Group : GroupPool::PoolItem<&_gro GroupID parent; ///< Parent group Group(CompanyID owner = INVALID_COMPANY); - ~Group(); }; diff --git a/src/group_cmd.cpp b/src/group_cmd.cpp --- a/src/group_cmd.cpp +++ b/src/group_cmd.cpp @@ -290,11 +290,6 @@ Group::Group(Owner owner) this->folded = false; } -Group::~Group() -{ - free(this->name); -} - /** * Create a new vehicle group. @@ -422,10 +417,12 @@ CommandCost CmdAlterGroup(TileIndex tile } if (flags & DC_EXEC) { - /* Delete the old name */ - free(g->name); /* Assign the new one */ - g->name = reset ? nullptr : stredup(text); + if (reset) { + g->name.clear(); + } else { + g->name = text; + } } } else { /* Set group parent */ diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -645,20 +645,20 @@ bool AfterLoadGame() if (IsSavegameVersionBefore(SLV_84)) { for (Company *c : Company::Iterate()) { c->name = CopyFromOldName(c->name_1); - if (c->name != nullptr) c->name_1 = STR_SV_UNNAMED; + if (!c->name.empty()) c->name_1 = STR_SV_UNNAMED; c->president_name = CopyFromOldName(c->president_name_1); - if (c->president_name != nullptr) c->president_name_1 = SPECSTR_PRESIDENT_NAME; + if (!c->president_name.empty()) c->president_name_1 = SPECSTR_PRESIDENT_NAME; } for (Station *st : Station::Iterate()) { st->name = CopyFromOldName(st->string_id); /* generating new name would be too much work for little effect, use the station name fallback */ - if (st->name != nullptr) st->string_id = STR_SV_STNAME_FALLBACK; + if (!st->name.empty()) st->string_id = STR_SV_STNAME_FALLBACK; } for (Town *t : Town::Iterate()) { t->name = CopyFromOldName(t->townnametype); - if (t->name != nullptr) t->townnametype = SPECSTR_TOWNNAME_START + _settings_game.game_creation.town_name; + if (!t->name.empty()) t->townnametype = SPECSTR_TOWNNAME_START + _settings_game.game_creation.town_name; } } @@ -2502,11 +2502,11 @@ bool AfterLoadGame() * highest possible number to get them numbered in the * order they have in the pool. */ for (Waypoint *wp : Waypoint::Iterate()) { - if (wp->name != nullptr) wp->town_cn = UINT16_MAX; + if (!wp->name.empty()) wp->town_cn = UINT16_MAX; } for (Waypoint* wp : Waypoint::Iterate()) { - if (wp->name != nullptr) MakeDefaultName(wp); + if (!wp->name.empty()) MakeDefaultName(wp); } } diff --git a/src/saveload/company_sl.cpp b/src/saveload/company_sl.cpp --- a/src/saveload/company_sl.cpp +++ b/src/saveload/company_sl.cpp @@ -242,11 +242,11 @@ void AfterLoadCompanyStats() static const SaveLoad _company_desc[] = { SLE_VAR(CompanyProperties, name_2, SLE_UINT32), SLE_VAR(CompanyProperties, name_1, SLE_STRINGID), - SLE_CONDSTR(CompanyProperties, name, SLE_STR | SLF_ALLOW_CONTROL, 0, SLV_84, SL_MAX_VERSION), + SLE_CONDSSTR(CompanyProperties, name, SLE_STR | SLF_ALLOW_CONTROL, SLV_84, SL_MAX_VERSION), SLE_VAR(CompanyProperties, president_name_1, SLE_STRINGID), SLE_VAR(CompanyProperties, president_name_2, SLE_UINT32), - SLE_CONDSTR(CompanyProperties, president_name, SLE_STR | SLF_ALLOW_CONTROL, 0, SLV_84, SL_MAX_VERSION), + SLE_CONDSSTR(CompanyProperties, president_name, SLE_STR | SLF_ALLOW_CONTROL, SLV_84, SL_MAX_VERSION), SLE_VAR(CompanyProperties, face, SLE_UINT32), @@ -519,7 +519,7 @@ static void Check_PLYR() } } - if (cprops->name == nullptr && !IsInsideMM(cprops->name_1, SPECSTR_COMPANY_NAME_START, SPECSTR_COMPANY_NAME_LAST + 1) && + if (cprops->name.empty() && !IsInsideMM(cprops->name_1, SPECSTR_COMPANY_NAME_START, SPECSTR_COMPANY_NAME_LAST + 1) && cprops->name_1 != STR_GAME_SAVELOAD_NOT_AVAILABLE && cprops->name_1 != STR_SV_UNNAMED && cprops->name_1 != SPECSTR_ANDCO_NAME && cprops->name_1 != SPECSTR_PRESIDENT_NAME && cprops->name_1 != SPECSTR_SILLY_NAME) { diff --git a/src/saveload/depot_sl.cpp b/src/saveload/depot_sl.cpp --- a/src/saveload/depot_sl.cpp +++ b/src/saveload/depot_sl.cpp @@ -23,7 +23,7 @@ static const SaveLoad _depot_desc[] = { SLEG_CONDVAR(_town_index, SLE_UINT16, SL_MIN_VERSION, SLV_141), SLE_CONDREF(Depot, town, REF_TOWN, SLV_141, SL_MAX_VERSION), SLE_CONDVAR(Depot, town_cn, SLE_UINT16, SLV_141, SL_MAX_VERSION), - SLE_CONDSTR(Depot, name, SLE_STR, 0, SLV_141, SL_MAX_VERSION), + SLE_CONDSSTR(Depot, name, SLE_STR, SLV_141, SL_MAX_VERSION), SLE_CONDVAR(Depot, build_date, SLE_INT32, SLV_142, SL_MAX_VERSION), SLE_END() }; diff --git a/src/saveload/engine_sl.cpp b/src/saveload/engine_sl.cpp --- a/src/saveload/engine_sl.cpp +++ b/src/saveload/engine_sl.cpp @@ -39,7 +39,7 @@ static const SaveLoad _engine_desc[] = { SLE_CONDVAR(Engine, company_avail, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_104), SLE_CONDVAR(Engine, company_avail, SLE_UINT16, SLV_104, SL_MAX_VERSION), SLE_CONDVAR(Engine, company_hidden, SLE_UINT16, SLV_193, SL_MAX_VERSION), - SLE_CONDSTR(Engine, name, SLE_STR, 0, SLV_84, SL_MAX_VERSION), + SLE_CONDSSTR(Engine, name, SLE_STR, SLV_84, SL_MAX_VERSION), SLE_CONDNULL(16, SLV_2, SLV_144), // old reserved space @@ -137,7 +137,7 @@ void CopyTempEngineData() e->preview_wait = se->preview_wait; e->company_avail = se->company_avail; e->company_hidden = se->company_hidden; - if (se->name != nullptr) e->name = stredup(se->name); + e->name = se->name; } ResetTempEngineData(); diff --git a/src/saveload/group_sl.cpp b/src/saveload/group_sl.cpp --- a/src/saveload/group_sl.cpp +++ b/src/saveload/group_sl.cpp @@ -17,7 +17,7 @@ static const SaveLoad _group_desc[] = { SLE_CONDVAR(Group, name, SLE_NAME, SL_MIN_VERSION, SLV_84), - SLE_CONDSTR(Group, name, SLE_STR | SLF_ALLOW_CONTROL, 0, SLV_84, SL_MAX_VERSION), + SLE_CONDSSTR(Group, name, SLE_STR | SLF_ALLOW_CONTROL, SLV_84, SL_MAX_VERSION), SLE_CONDNULL(2, SL_MIN_VERSION, SLV_164), // num_vehicle SLE_VAR(Group, owner, SLE_UINT8), SLE_VAR(Group, vehicle_type, SLE_UINT8), diff --git a/src/saveload/saveload.cpp b/src/saveload/saveload.cpp --- a/src/saveload/saveload.cpp +++ b/src/saveload/saveload.cpp @@ -793,7 +793,7 @@ void WriteValue(void *ptr, VarType conv, case SLE_VAR_U32: *(uint32*)ptr = val; break; case SLE_VAR_I64: *(int64 *)ptr = val; break; case SLE_VAR_U64: *(uint64*)ptr = val; break; - case SLE_VAR_NAME: *(char**)ptr = CopyFromOldName(val); break; + case SLE_VAR_NAME: *reinterpret_cast(ptr) = CopyFromOldName(val); break; case SLE_VAR_NULL: break; default: NOT_REACHED(); } @@ -1515,6 +1515,8 @@ static bool IsVariableSizeRight(const Sa case SLE_VAR_I64: case SLE_VAR_U64: return sld->size == sizeof(int64); + case SLE_VAR_NAME: + return sld->size == sizeof(std::string); default: return sld->size == sizeof(void *); } diff --git a/src/saveload/saveload_internal.h b/src/saveload/saveload_internal.h --- a/src/saveload/saveload_internal.h +++ b/src/saveload/saveload_internal.h @@ -17,7 +17,7 @@ void InitializeOldNames(); StringID RemapOldStringID(StringID s); -char *CopyFromOldName(StringID id); +std::string CopyFromOldName(StringID id); void ResetOldNames(); void ResetOldWaypoints(); diff --git a/src/saveload/signs_sl.cpp b/src/saveload/signs_sl.cpp --- a/src/saveload/signs_sl.cpp +++ b/src/saveload/signs_sl.cpp @@ -18,7 +18,7 @@ /** Description of a sign within the savegame. */ static const SaveLoad _sign_desc[] = { SLE_CONDVAR(Sign, name, SLE_NAME, SL_MIN_VERSION, SLV_84), - SLE_CONDSTR(Sign, name, SLE_STR | SLF_ALLOW_CONTROL, 0, SLV_84, SL_MAX_VERSION), + SLE_CONDSSTR(Sign, name, SLE_STR | SLF_ALLOW_CONTROL, SLV_84, SL_MAX_VERSION), SLE_CONDVAR(Sign, x, SLE_FILE_I16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_5), SLE_CONDVAR(Sign, y, SLE_FILE_I16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_5), SLE_CONDVAR(Sign, x, SLE_INT32, SLV_5, SL_MAX_VERSION), diff --git a/src/saveload/station_sl.cpp b/src/saveload/station_sl.cpp --- a/src/saveload/station_sl.cpp +++ b/src/saveload/station_sl.cpp @@ -62,8 +62,7 @@ void MoveBuoysToWaypoints() TileIndex xy = st->xy; Town *town = st->town; StringID string_id = st->string_id; - char *name = st->name; - st->name = nullptr; + std::string name = st->name; Date build_date = st->build_date; /* TTDPatch could use "buoys with rail station" for rail waypoints */ bool train = st->train_station.tile != INVALID_TILE; @@ -176,7 +175,7 @@ static const SaveLoad _old_station_desc[ SLE_CONDNULL(1, SL_MIN_VERSION, SLV_4), ///< alpha_order SLE_VAR(Station, string_id, SLE_STRINGID), - SLE_CONDSTR(Station, name, SLE_STR | SLF_ALLOW_CONTROL, 0, SLV_84, SL_MAX_VERSION), + SLE_CONDSSTR(Station, name, SLE_STR | SLF_ALLOW_CONTROL, SLV_84, SL_MAX_VERSION), SLE_CONDVAR(Station, indtype, SLE_UINT8, SLV_103, SL_MAX_VERSION), SLE_CONDVAR(Station, had_vehicle_of_type, SLE_FILE_U16 | SLE_VAR_U8, SL_MIN_VERSION, SLV_122), SLE_CONDVAR(Station, had_vehicle_of_type, SLE_UINT8, SLV_122, SL_MAX_VERSION), @@ -389,7 +388,7 @@ static const SaveLoad _base_station_desc SLE_VAR(BaseStation, xy, SLE_UINT32), SLE_REF(BaseStation, town, REF_TOWN), SLE_VAR(BaseStation, string_id, SLE_STRINGID), - SLE_STR(BaseStation, name, SLE_STR | SLF_ALLOW_CONTROL, 0), + SLE_SSTR(BaseStation, name, SLE_STR | SLF_ALLOW_CONTROL), SLE_VAR(BaseStation, delete_ctr, SLE_UINT8), SLE_VAR(BaseStation, owner, SLE_UINT8), SLE_VAR(BaseStation, facilities, SLE_UINT8), diff --git a/src/saveload/strings_sl.cpp b/src/saveload/strings_sl.cpp --- a/src/saveload/strings_sl.cpp +++ b/src/saveload/strings_sl.cpp @@ -11,6 +11,7 @@ #include "../string_func.h" #include "../strings_func.h" #include "saveload_internal.h" +#include #include "table/strings.h" @@ -56,18 +57,17 @@ char *_old_name_array = nullptr; * @param id the StringID of the custom name to clone. * @return the clones custom name. */ -char *CopyFromOldName(StringID id) +std::string CopyFromOldName(StringID id) { /* Is this name an (old) custom name? */ - if (GetStringTab(id) != TEXT_TAB_OLD_CUSTOM) return nullptr; + if (GetStringTab(id) != TEXT_TAB_OLD_CUSTOM) return std::string(); if (IsSavegameVersionBefore(SLV_37)) { - /* Allow for expansion when converted to UTF-8. */ - char tmp[LEN_OLD_STRINGS * MAX_CHAR_LENGTH]; uint offs = _savegame_type == SGT_TTO ? LEN_OLD_STRINGS_TTO * GB(id, 0, 8) : LEN_OLD_STRINGS * GB(id, 0, 9); const char *strfrom = &_old_name_array[offs]; - char *strto = tmp; + std::ostringstream tmp; + std::ostreambuf_iterator strto(tmp); for (; *strfrom != '\0'; strfrom++) { WChar c = (byte)*strfrom; @@ -84,19 +84,13 @@ char *CopyFromOldName(StringID id) default: break; } - /* Check character will fit into our buffer. */ - if (strto + Utf8CharLen(c) > lastof(tmp)) break; - - strto += Utf8Encode(strto, c); + Utf8Encode(strto, c); } - /* Terminate the new string and copy it back to the name array */ - *strto = '\0'; - - return stredup(tmp); + return tmp.str(); } else { /* Name will already be in UTF-8. */ - return stredup(&_old_name_array[LEN_OLD_STRINGS * GB(id, 0, 9)]); + return std::string(&_old_name_array[LEN_OLD_STRINGS * GB(id, 0, 9)]); } } diff --git a/src/saveload/town_sl.cpp b/src/saveload/town_sl.cpp --- a/src/saveload/town_sl.cpp +++ b/src/saveload/town_sl.cpp @@ -124,7 +124,7 @@ static const SaveLoad _town_desc[] = { SLE_CONDVAR(Town, townnamegrfid, SLE_UINT32, SLV_66, SL_MAX_VERSION), SLE_VAR(Town, townnametype, SLE_UINT16), SLE_VAR(Town, townnameparts, SLE_UINT32), - SLE_CONDSTR(Town, name, SLE_STR | SLF_ALLOW_CONTROL, 0, SLV_84, SL_MAX_VERSION), + SLE_CONDSSTR(Town, name, SLE_STR | SLF_ALLOW_CONTROL, SLV_84, SL_MAX_VERSION), SLE_VAR(Town, flags, SLE_UINT8), SLE_CONDVAR(Town, statues, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_104), @@ -167,7 +167,7 @@ static const SaveLoad _town_desc[] = { SLE_CONDARR(Town, goal, SLE_UINT32, NUM_TE, SLV_165, SL_MAX_VERSION), - SLE_CONDSTR(Town, text, SLE_STR | SLF_ALLOW_CONTROL, 0, SLV_168, SL_MAX_VERSION), + SLE_CONDSSTR(Town, text, SLE_STR | SLF_ALLOW_CONTROL, SLV_168, SL_MAX_VERSION), SLE_CONDVAR(Town, time_until_rebuild, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_54), SLE_CONDVAR(Town, grow_counter, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_54), diff --git a/src/saveload/vehicle_sl.cpp b/src/saveload/vehicle_sl.cpp --- a/src/saveload/vehicle_sl.cpp +++ b/src/saveload/vehicle_sl.cpp @@ -585,7 +585,7 @@ const SaveLoad *GetVehicleDescription(Ve SLE_REF(Vehicle, next, REF_VEHICLE_OLD), SLE_CONDVAR(Vehicle, name, SLE_NAME, SL_MIN_VERSION, SLV_84), - SLE_CONDSTR(Vehicle, name, SLE_STR | SLF_ALLOW_CONTROL, 0, SLV_84, SL_MAX_VERSION), + SLE_CONDSSTR(Vehicle, name, SLE_STR | SLF_ALLOW_CONTROL, SLV_84, SL_MAX_VERSION), SLE_CONDVAR(Vehicle, unitnumber, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_8), SLE_CONDVAR(Vehicle, unitnumber, SLE_UINT16, SLV_8, SL_MAX_VERSION), SLE_VAR(Vehicle, owner, SLE_UINT8), diff --git a/src/saveload/waypoint_sl.cpp b/src/saveload/waypoint_sl.cpp --- a/src/saveload/waypoint_sl.cpp +++ b/src/saveload/waypoint_sl.cpp @@ -29,7 +29,7 @@ struct OldWaypoint { Town *town; uint16 town_cn; StringID string_id; - char *name; + std::string name; uint8 delete_ctr; Date build_date; uint8 localidx; @@ -172,7 +172,7 @@ static const SaveLoad _old_waypoint_desc SLE_CONDVAR(OldWaypoint, town_cn, SLE_FILE_U8 | SLE_VAR_U16, SLV_12, SLV_89), SLE_CONDVAR(OldWaypoint, town_cn, SLE_UINT16, SLV_89, SL_MAX_VERSION), SLE_CONDVAR(OldWaypoint, string_id, SLE_STRINGID, SL_MIN_VERSION, SLV_84), - SLE_CONDSTR(OldWaypoint, name, SLE_STR, 0, SLV_84, SL_MAX_VERSION), + SLE_CONDSSTR(OldWaypoint, name, SLE_STR, SLV_84, SL_MAX_VERSION), SLE_VAR(OldWaypoint, delete_ctr, SLE_UINT8), SLE_CONDVAR(OldWaypoint, build_date, SLE_FILE_U16 | SLE_VAR_I32, SLV_3, SLV_31), @@ -194,7 +194,6 @@ static void Load_WAYP() while ((index = SlIterateArray()) != -1) { /*C++17: OldWaypoint *wp = &*/ _old_waypoints.emplace_back(); OldWaypoint *wp = &_old_waypoints.back(); - memset(wp, 0, sizeof(*wp)); wp->index = index; SlObject(wp, _old_waypoint_desc); diff --git a/src/signs.cpp b/src/signs.cpp --- a/src/signs.cpp +++ b/src/signs.cpp @@ -34,8 +34,6 @@ Sign::Sign(Owner owner) /** Destroy the sign */ Sign::~Sign() { - free(this->name); - if (CleaningPool()) return; DeleteRenameSignWindow(this->index); diff --git a/src/signs_base.h b/src/signs_base.h --- a/src/signs_base.h +++ b/src/signs_base.h @@ -14,12 +14,13 @@ #include "viewport_type.h" #include "core/pool_type.hpp" #include "company_type.h" +#include typedef Pool SignPool; extern SignPool _sign_pool; struct Sign : SignPool::PoolItem<&_sign_pool> { - char *name; + std::string name; TrackedViewportSign sign; int32 x; int32 y; diff --git a/src/signs_cmd.cpp b/src/signs_cmd.cpp --- a/src/signs_cmd.cpp +++ b/src/signs_cmd.cpp @@ -86,10 +86,8 @@ CommandCost CmdRenameSign(TileIndex tile if (Utf8StringLength(text) >= MAX_LENGTH_SIGN_NAME_CHARS) return CMD_ERROR; if (flags & DC_EXEC) { - /* Delete the old name */ - free(si->name); /* Assign the new one */ - si->name = stredup(text); + si->name = text; if (_game_mode != GM_EDITOR) si->owner = _current_company; si->UpdateVirtCoord(); diff --git a/src/signs_gui.cpp b/src/signs_gui.cpp --- a/src/signs_gui.cpp +++ b/src/signs_gui.cpp @@ -75,11 +75,8 @@ struct SignList { * a lot of them. Therefore a worthwhile performance gain can be made by * directly comparing Sign::name instead of going through the string * system for each comparison. */ - const char *a_name = a->name; - const char *b_name = b->name; - - if (a_name == nullptr) a_name = SignList::default_name; - if (b_name == nullptr) b_name = SignList::default_name; + const char *a_name = a->name.empty() ? SignList::default_name : a->name.c_str(); + const char *b_name = b->name.empty() ? SignList::default_name : b->name.c_str(); int r = strnatcmp(a_name, b_name); // Sort by name (natural sorting). @@ -95,9 +92,7 @@ struct SignList { static bool CDECL SignNameFilter(const Sign * const *a, StringFilter &filter) { /* Same performance benefit as above for sorting. */ - const char *a_name = (*a)->name; - - if (a_name == nullptr) a_name = SignList::default_name; + const char *a_name = (*a)->name.empty() ? SignList::default_name : (*a)->name.c_str(); filter.ResetState(); filter.AddLine(a_name); @@ -439,7 +434,7 @@ struct SignWindow : Window, SignList { void UpdateSignEditWindow(const Sign *si) { /* Display an empty string when the sign hasn't been edited yet */ - if (si->name != nullptr) { + if (!si->name.empty()) { SetDParam(0, si->index); this->name_editbox.text.Assign(STR_SIGN_NAME); } else { diff --git a/src/station.cpp b/src/station.cpp --- a/src/station.cpp +++ b/src/station.cpp @@ -51,7 +51,6 @@ void RebuildStationKdtree() BaseStation::~BaseStation() { - free(this->name); free(this->speclist); if (CleaningPool()) return; diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -3917,7 +3917,7 @@ static uint UpdateStationWaiting(Station static bool IsUniqueStationName(const char *name) { for (const Station *st : Station::Iterate()) { - if (st->name != nullptr && strcmp(st->name, name) == 0) return false; + if (!st->name.empty() && st->name == name) return false; } return true; @@ -3949,8 +3949,11 @@ CommandCost CmdRenameStation(TileIndex t if (flags & DC_EXEC) { st->cached_name.clear(); - free(st->name); - st->name = reset ? nullptr : stredup(text); + if (reset) { + st->name.clear(); + } else { + st->name = text; + } st->UpdateVirtCoord(); InvalidateWindowData(WC_STATION_LIST, st->owner, 1); diff --git a/src/strings.cpp b/src/strings.cpp --- a/src/strings.cpp +++ b/src/strings.cpp @@ -1270,8 +1270,8 @@ static char *FormatString(char *buff, co const Company *c = Company::GetIfValid(args->GetInt32()); if (c == nullptr) break; - if (c->name != nullptr) { - int64 args_array[] = {(int64)(size_t)c->name}; + if (!c->name.empty()) { + int64 args_array[] = {(int64)(size_t)c->name.c_str()}; StringParameters tmp_params(args_array); buff = GetStringWithArgs(buff, STR_JUST_RAW_STRING, &tmp_params, last); } else { @@ -1305,8 +1305,8 @@ static char *FormatString(char *buff, co } const Depot *d = Depot::Get(args->GetInt32()); - if (d->name != nullptr) { - int64 args_array[] = {(int64)(size_t)d->name}; + if (!d->name.empty()) { + int64 args_array[] = {(int64)(size_t)d->name.c_str()}; StringParameters tmp_params(args_array); buff = GetStringWithArgs(buff, STR_JUST_RAW_STRING, &tmp_params, last); } else { @@ -1321,8 +1321,8 @@ static char *FormatString(char *buff, co const Engine *e = Engine::GetIfValid(args->GetInt32(SCC_ENGINE_NAME)); if (e == nullptr) break; - if (e->name != nullptr && e->IsEnabled()) { - int64 args_array[] = {(int64)(size_t)e->name}; + if (!e->name.empty() && e->IsEnabled()) { + int64 args_array[] = {(int64)(size_t)e->name.c_str()}; StringParameters tmp_params(args_array); buff = GetStringWithArgs(buff, STR_JUST_RAW_STRING, &tmp_params, last); } else { @@ -1336,8 +1336,8 @@ static char *FormatString(char *buff, co const Group *g = Group::GetIfValid(args->GetInt32()); if (g == nullptr) break; - if (g->name != nullptr) { - int64 args_array[] = {(int64)(size_t)g->name}; + if (!g->name.empty()) { + int64 args_array[] = {(int64)(size_t)g->name.c_str()}; StringParameters tmp_params(args_array); buff = GetStringWithArgs(buff, STR_JUST_RAW_STRING, &tmp_params, last); } else { @@ -1373,8 +1373,8 @@ static char *FormatString(char *buff, co const Company *c = Company::GetIfValid(args->GetInt32(SCC_PRESIDENT_NAME)); if (c == nullptr) break; - if (c->president_name != nullptr) { - int64 args_array[] = {(int64)(size_t)c->president_name}; + if (!c->president_name.empty()) { + int64 args_array[] = {(int64)(size_t)c->president_name.c_str()}; StringParameters tmp_params(args_array); buff = GetStringWithArgs(buff, STR_JUST_RAW_STRING, &tmp_params, last); } else { @@ -1398,8 +1398,8 @@ static char *FormatString(char *buff, co break; } - if (st->name != nullptr) { - int64 args_array[] = {(int64)(size_t)st->name}; + if (!st->name.empty()) { + int64 args_array[] = {(int64)(size_t)st->name.c_str()}; StringParameters tmp_params(args_array); buff = GetStringWithArgs(buff, STR_JUST_RAW_STRING, &tmp_params, last); } else { @@ -1428,8 +1428,8 @@ static char *FormatString(char *buff, co const Town *t = Town::GetIfValid(args->GetInt32(SCC_TOWN_NAME)); if (t == nullptr) break; - if (t->name != nullptr) { - int64 args_array[] = {(int64)(size_t)t->name}; + if (!t->name.empty()) { + int64 args_array[] = {(int64)(size_t)t->name.c_str()}; StringParameters tmp_params(args_array); buff = GetStringWithArgs(buff, STR_JUST_RAW_STRING, &tmp_params, last); } else { @@ -1442,8 +1442,8 @@ static char *FormatString(char *buff, co Waypoint *wp = Waypoint::GetIfValid(args->GetInt32(SCC_WAYPOINT_NAME)); if (wp == nullptr) break; - if (wp->name != nullptr) { - int64 args_array[] = {(int64)(size_t)wp->name}; + if (!wp->name.empty()) { + int64 args_array[] = {(int64)(size_t)wp->name.c_str()}; StringParameters tmp_params(args_array); buff = GetStringWithArgs(buff, STR_JUST_RAW_STRING, &tmp_params, last); } else { @@ -1460,8 +1460,8 @@ static char *FormatString(char *buff, co const Vehicle *v = Vehicle::GetIfValid(args->GetInt32(SCC_VEHICLE_NAME)); if (v == nullptr) break; - if (v->name != nullptr) { - int64 args_array[] = {(int64)(size_t)v->name}; + if (!v->name.empty()) { + int64 args_array[] = {(int64)(size_t)v->name.c_str()}; StringParameters tmp_params(args_array); buff = GetStringWithArgs(buff, STR_JUST_RAW_STRING, &tmp_params, last); } else { @@ -1486,8 +1486,8 @@ static char *FormatString(char *buff, co const Sign *si = Sign::GetIfValid(args->GetInt32()); if (si == nullptr) break; - if (si->name != nullptr) { - int64 args_array[] = {(int64)(size_t)si->name}; + if (!si->name.empty()) { + int64 args_array[] = {(int64)(size_t)si->name.c_str()}; StringParameters tmp_params(args_array); buff = GetStringWithArgs(buff, STR_JUST_RAW_STRING, &tmp_params, last); } else { diff --git a/src/town.h b/src/town.h --- a/src/town.h +++ b/src/town.h @@ -59,7 +59,7 @@ struct Town : TownPool::PoolItem<&_town_ uint32 townnamegrfid; uint16 townnametype; uint32 townnameparts; - char *name; ///< Custom town name. If nullptr, the town was not renamed and uses the generated name. + std::string name; ///< Custom town name. If empty, the town was not renamed and uses the generated name. mutable std::string cached_name; ///< NOSAVE: Cache of the resolved name of the town, if not using a custom town name byte flags; ///< See #TownFlags. @@ -79,7 +79,7 @@ struct Town : TownPool::PoolItem<&_town_ TransportedCargoStat received[NUM_TE]; ///< Cargo statistics about received cargotypes. uint32 goal[NUM_TE]; ///< Amount of cargo required for the town to grow. - char *text; ///< General text with additional information. + std::string text; ///< General text with additional information. inline byte GetPercentTransported(CargoID cid) const { return this->supplied[cid].old_act * 256 / (this->supplied[cid].old_max + 1); } @@ -133,7 +133,7 @@ struct Town : TownPool::PoolItem<&_town_ inline const char *GetCachedName() const { - if (this->name != nullptr) return this->name; + if (!this->name.empty()) return this->name.c_str(); if (this->cached_name.empty()) this->FillCachedName(); return this->cached_name.c_str(); } @@ -249,7 +249,7 @@ template void MakeDefaultName(T *obj) { /* We only want to set names if it hasn't been set before, or when we're calling from afterload. */ - assert(obj->name == nullptr || obj->town_cn == UINT16_MAX); + assert(obj->name.empty() || obj->town_cn == UINT16_MAX); obj->town = ClosestTownFromTile(obj->xy, UINT_MAX); diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -101,9 +101,6 @@ static bool TestTownOwnsBridge(TileIndex Town::~Town() { - free(this->name); - free(this->text); - if (CleaningPool()) return; /* Delete town authority window @@ -1854,7 +1851,7 @@ static CommandCost TownCanBePlacedHere(T static bool IsUniqueTownName(const char *name) { for (const Town *t : Town::Iterate()) { - if (t->name != nullptr && strcmp(t->name, name) == 0) return false; + if (!t->name.empty() && t->name == name) return false; } return true; @@ -2706,8 +2703,11 @@ CommandCost CmdRenameTown(TileIndex tile if (flags & DC_EXEC) { t->cached_name.clear(); - free(t->name); - t->name = reset ? nullptr : stredup(text); + if (reset) { + t->name.clear(); + } else { + t->name = text; + } t->UpdateVirtCoord(); InvalidateWindowData(WC_TOWN_DIRECTORY, 0, TDIWD_FORCE_RESORT); @@ -2783,8 +2783,8 @@ CommandCost CmdTownSetText(TileIndex til if (t == nullptr) return CMD_ERROR; if (flags & DC_EXEC) { - free(t->text); - t->text = StrEmpty(text) ? nullptr : stredup(text); + t->text.clear(); + if (!StrEmpty(text)) t->text = text; InvalidateWindowData(WC_TOWN_VIEW, p1); } diff --git a/src/town_gui.cpp b/src/town_gui.cpp --- a/src/town_gui.cpp +++ b/src/town_gui.cpp @@ -434,8 +434,8 @@ public: DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_LEFT, y += FONT_HEIGHT_NORMAL, STR_TOWN_VIEW_NOISE_IN_TOWN); } - if (this->town->text != nullptr) { - SetDParamStr(0, this->town->text); + if (!this->town->text.empty()) { + SetDParamStr(0, this->town->text.c_str()); DrawStringMultiLine(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y += FONT_HEIGHT_NORMAL, UINT16_MAX, STR_JUST_RAW_STRING, TC_BLACK); } } @@ -516,8 +516,8 @@ public: if (_settings_game.economy.station_noise_level) aimed_height += FONT_HEIGHT_NORMAL; - if (this->town->text != nullptr) { - SetDParamStr(0, this->town->text); + if (!this->town->text.empty()) { + SetDParamStr(0, this->town->text.c_str()); aimed_height += GetStringHeight(STR_JUST_RAW_STRING, width - WD_FRAMERECT_LEFT - WD_FRAMERECT_RIGHT); } diff --git a/src/townname.cpp b/src/townname.cpp --- a/src/townname.cpp +++ b/src/townname.cpp @@ -97,7 +97,7 @@ bool VerifyTownName(uint32 r, const Town for (const Town *t : Town::Iterate()) { /* We can't just compare the numbers since * several numbers may map to a single name. */ - const char *buf = t->name; + const char *buf = t->name.empty() ? nullptr : t->name.c_str(); if (buf == nullptr) { GetTownName(buf2, t, lastof(buf2)); buf = buf2; diff --git a/src/vehicle_cmd.cpp b/src/vehicle_cmd.cpp --- a/src/vehicle_cmd.cpp +++ b/src/vehicle_cmd.cpp @@ -30,6 +30,8 @@ #include "newgrf.h" #include "company_base.h" #include "core/random_func.hpp" +#include +#include #include "table/strings.h" @@ -749,7 +751,7 @@ CommandCost CmdDepotMassAutoReplace(Tile static bool IsUniqueVehicleName(const char *name) { for (const Vehicle *v : Vehicle::Iterate()) { - if (v->name != nullptr && strcmp(v->name, name) == 0) return false; + if (!v->name.empty() && v->name == name) return false; } return true; @@ -762,42 +764,48 @@ static bool IsUniqueVehicleName(const ch */ static void CloneVehicleName(const Vehicle *src, Vehicle *dst) { - char buf[256]; + std::string buf; /* Find the position of the first digit in the last group of digits. */ size_t number_position; - for (number_position = strlen(src->name); number_position > 0; number_position--) { + for (number_position = src->name.length(); number_position > 0; number_position--) { /* The design of UTF-8 lets this work simply without having to check * for UTF-8 sequences. */ if (src->name[number_position - 1] < '0' || src->name[number_position - 1] > '9') break; } /* Format buffer and determine starting number. */ - int num; + long num; byte padding = 0; - if (number_position == strlen(src->name)) { + if (number_position == src->name.length()) { /* No digit at the end, so start at number 2. */ - strecpy(buf, src->name, lastof(buf)); - strecat(buf, " ", lastof(buf)); - number_position = strlen(buf); + buf = src->name; + buf += " "; + number_position = buf.length(); num = 2; } else { /* Found digits, parse them and start at the next number. */ - strecpy(buf, src->name, lastof(buf)); - buf[number_position] = '\0'; - char *endptr; - num = strtol(&src->name[number_position], &endptr, 10) + 1; - padding = endptr - &src->name[number_position]; + buf = src->name.substr(0, number_position); + + auto num_str = src->name.substr(number_position); + padding = (byte)num_str.length(); + + std::istringstream iss(num_str); + iss >> num; + num++; } /* Check if this name is already taken. */ for (int max_iterations = 1000; max_iterations > 0; max_iterations--, num++) { + std::ostringstream oss; + /* Attach the number to the temporary name. */ - seprintf(&buf[number_position], lastof(buf), "%0*d", padding, num); + oss << buf << std::setw(padding) << std::setfill('0') << std::internal << num; /* Check the name is unique. */ - if (IsUniqueVehicleName(buf)) { - dst->name = stredup(buf); + auto new_name = oss.str(); + if (IsUniqueVehicleName(new_name.c_str())) { + dst->name = new_name; break; } } @@ -973,7 +981,7 @@ CommandCost CmdCloneVehicle(TileIndex ti DoCommand(0, w_front->index | (p2 & 1 ? CO_SHARE : CO_COPY) << 30, v_front->index, flags, CMD_CLONE_ORDER); /* Now clone the vehicle's name, if it has one. */ - if (v_front->name != nullptr) CloneVehicleName(v_front, w_front); + if (!v_front->name.empty()) CloneVehicleName(v_front, w_front); } /* Since we can't estimate the cost of cloning a vehicle accurately we must @@ -1074,8 +1082,11 @@ CommandCost CmdRenameVehicle(TileIndex t } if (flags & DC_EXEC) { - free(v->name); - v->name = reset ? nullptr : stredup(text); + if (reset) { + v->name.clear(); + } else { + v->name = text; + } InvalidateWindowClassesData(GetWindowClassForVehicleType(v->type), 1); MarkWholeScreenDirty(); } diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -1395,7 +1395,7 @@ void BaseVehicleListWindow::DrawVehicleL DrawVehicleImage(v, image_left, image_right, y + FONT_HEIGHT_SMALL - 1, selected_vehicle, EIT_IN_LIST, 0); DrawString(text_left, text_right, y + line_height - FONT_HEIGHT_SMALL - WD_FRAMERECT_BOTTOM - 1, STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR); - if (v->name != nullptr) { + if (!v->name.empty()) { /* The vehicle got a name so we will print it */ SetDParam(0, v->index); DrawString(text_left, text_right, y, STR_TINY_BLACK_VEHICLE); diff --git a/src/waypoint_cmd.cpp b/src/waypoint_cmd.cpp --- a/src/waypoint_cmd.cpp +++ b/src/waypoint_cmd.cpp @@ -398,7 +398,7 @@ CommandCost RemoveBuoy(TileIndex tile, D static bool IsUniqueWaypointName(const char *name) { for (const Waypoint *wp : Waypoint::Iterate()) { - if (wp->name != nullptr && strcmp(wp->name, name) == 0) return false; + if (!wp->name.empty() && wp->name == name) return false; } return true; @@ -431,8 +431,11 @@ CommandCost CmdRenameWaypoint(TileIndex } if (flags & DC_EXEC) { - free(wp->name); - wp->name = reset ? nullptr : stredup(text); + if (reset) { + wp->name.clear(); + } else { + wp->name = text; + } wp->UpdateVirtCoord(); }