Codechange: Use std::string for most of the user-settable custom names.

desync-debugging
Michael Lutz 4 years ago
parent 9b6f5e3bb8
commit 63ccb36ef3

@ -309,7 +309,7 @@ CommandCost CmdBuildAircraft(TileIndex tile, DoCommandFlag flags, const Engine *
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;

@ -14,10 +14,6 @@
#include "safeguards.h"
BaseConsist::~BaseConsist()
{
free(this->name);
}
/**
* Copy properties of other BaseConsist.
@ -27,8 +23,7 @@ void BaseConsist::CopyConsistPropertiesFrom(const BaseConsist *src)
{
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;

@ -12,10 +12,11 @@
#include "order_type.h"
#include "date_type.h"
#include <string>
/** 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);
};

@ -54,7 +54,7 @@ struct BaseStation : StationPool::PoolItem<&_station_pool> {
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::PoolItem<&_station_pool> {
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();
}

@ -16,6 +16,7 @@
#include "tile_type.h"
#include "settings_type.h"
#include "group.h"
#include <string>
/** 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 {

@ -353,7 +353,7 @@ static void GenerateCompanyName(Company *c)
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(TileIndex tile, DoCommandFlag flags, uint32 p1,
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 tile, DoCommandFlag flags, uint32 p1, uin
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 tile, DoCommandFlag flags, uint32 p1, uin
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 tile, DoCommandFlag flags, uint32 p1, u
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);

@ -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) {

@ -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)

@ -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 tile, DoCommandFlag flags, uint32 p1, uint3
}
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 */

@ -67,7 +67,6 @@ assert_compile(lengthof(_orig_rail_vehicle_info) + lengthof(_orig_road_vehicle_i
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, EngineID base)
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 tile, DoCommandFlag flags, uint32 p1, uint
}
if (flags & DC_EXEC) {
free(e->name);
if (reset) {
e->name = nullptr;
e->name.clear();
} else {
e->name = stredup(text);
e->name = text;
}
MarkWholeScreenDirty();

@ -19,7 +19,7 @@ typedef Pool<Engine, EngineID, 64, 64000> EnginePool;
extern EnginePool _engine_pool;
struct Engine : EnginePool::PoolItem<&_engine_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.

@ -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);

@ -16,6 +16,7 @@
#include "vehicle_type.h"
#include "engine_type.h"
#include "livery.h"
#include <string>
typedef Pool<Group, GroupID, 16, 64000> 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<&_group_pool> {
GroupID parent; ///< Parent group
Group(CompanyID owner = INVALID_COMPANY);
~Group();
};

@ -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, DoCommandFlag flags, uint32 p1, uint32
}
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 */

@ -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);
}
}

@ -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) {

@ -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()
};

@ -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();

@ -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),

@ -793,7 +793,7 @@ void WriteValue(void *ptr, VarType conv, int64 val)
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<std::string *>(ptr) = CopyFromOldName(val); break;
case SLE_VAR_NULL: break;
default: NOT_REACHED();
}
@ -1515,6 +1515,8 @@ static bool IsVariableSizeRight(const SaveLoad *sld)
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 *);
}

@ -17,7 +17,7 @@
void InitializeOldNames();
StringID RemapOldStringID(StringID s);
char *CopyFromOldName(StringID id);
std::string CopyFromOldName(StringID id);
void ResetOldNames();
void ResetOldWaypoints();

@ -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),

@ -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),

@ -11,6 +11,7 @@
#include "../string_func.h"
#include "../strings_func.h"
#include "saveload_internal.h"
#include <sstream>
#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<char> 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)]);
}
}

@ -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),

@ -585,7 +585,7 @@ const SaveLoad *GetVehicleDescription(VehicleType vt)
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),

@ -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);

@ -34,8 +34,6 @@ Sign::Sign(Owner owner)
/** Destroy the sign */
Sign::~Sign()
{
free(this->name);
if (CleaningPool()) return;
DeleteRenameSignWindow(this->index);

@ -14,12 +14,13 @@
#include "viewport_type.h"
#include "core/pool_type.hpp"
#include "company_type.h"
#include <string>
typedef Pool<Sign, SignID, 16, 64000> SignPool;
extern SignPool _sign_pool;
struct Sign : SignPool::PoolItem<&_sign_pool> {
char *name;
std::string name;
TrackedViewportSign sign;
int32 x;
int32 y;

@ -86,10 +86,8 @@ CommandCost CmdRenameSign(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
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();

@ -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 {

@ -51,7 +51,6 @@ void RebuildStationKdtree()
BaseStation::~BaseStation()
{
free(this->name);
free(this->speclist);
if (CleaningPool()) return;

@ -3917,7 +3917,7 @@ static uint UpdateStationWaiting(Station *st, CargoID type, uint amount, SourceT
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 tile, DoCommandFlag flags, uint32 p1, uin
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);

@ -1270,8 +1270,8 @@ static char *FormatString(char *buff, const char *str_arg, StringParameters *arg
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, const char *str_arg, StringParameters *arg
}
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, const char *str_arg, StringParameters *arg
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, const char *str_arg, StringParameters *arg
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, const char *str_arg, StringParameters *arg
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, const char *str_arg, StringParameters *arg
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, const char *str_arg, StringParameters *arg
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, const char *str_arg, StringParameters *arg
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, const char *str_arg, StringParameters *arg
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, const char *str_arg, StringParameters *arg
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 {

@ -59,7 +59,7 @@ struct Town : TownPool::PoolItem<&_town_pool> {
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_pool> {
TransportedCargoStat<uint16> 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_pool> {
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 <class T>
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);

@ -101,9 +101,6 @@ static bool TestTownOwnsBridge(TileIndex tile, const Town *t)
Town::~Town()
{
free(this->name);
free(this->text);
if (CleaningPool()) return;
/* Delete town authority window
@ -1854,7 +1851,7 @@ static CommandCost TownCanBePlacedHere(TileIndex tile)
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, DoCommandFlag flags, uint32 p1, uint32
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 tile, DoCommandFlag flags, uint32 p1, uint3
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);
}

@ -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);
}

@ -97,7 +97,7 @@ bool VerifyTownName(uint32 r, const TownNameParams *par, TownNames *town_names)
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;

@ -30,6 +30,8 @@
#include "newgrf.h"
#include "company_base.h"
#include "core/random_func.hpp"
#include <sstream>
#include <iomanip>
#include "table/strings.h"
@ -749,7 +751,7 @@ CommandCost CmdDepotMassAutoReplace(TileIndex tile, DoCommandFlag flags, uint32
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 char *name)
*/
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 tile, DoCommandFlag flags, uint32 p1, uint
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 tile, DoCommandFlag flags, uint32 p1, uin
}
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();
}

@ -1395,7 +1395,7 @@ void BaseVehicleListWindow::DrawVehicleListItems(VehicleID selected_vehicle, int
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);

@ -398,7 +398,7 @@ CommandCost RemoveBuoy(TileIndex tile, DoCommandFlag flags)
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 tile, DoCommandFlag flags, uint32 p1, ui
}
if (flags & DC_EXEC) {
free(wp->name);
wp->name = reset ? nullptr : stredup(text);
if (reset) {
wp->name.clear();
} else {
wp->name = text;
}
wp->UpdateVirtCoord();
}

Loading…
Cancel
Save