Changeset - r4912:d420151de4c6
[Not reviewed]
master
0 33 0
Darkvater - 18 years ago 2006-10-21 23:31:34
darkvater@openttd.org
(svn r6884) -Codechange: Add strict bounds checking in string formatting system.
The last parameter should point to the end of the buffer (eg lastof(buf))
Courtesy of Tron.
33 files changed with 248 insertions and 239 deletions:
0 comments (0 inline, 0 general)
build_vehicle_gui.c
Show inline comments
 
@@ -99,12 +99,12 @@ static int CDECL EngineNameSorter(const 
 

	
 
	if (va != last_engine[0]) {
 
		last_engine[0] = va;
 
		GetString(last_name[0], GetCustomEngineName(va));
 
		GetString(last_name[0], GetCustomEngineName(va), lastof(last_name[0]));
 
	}
 

	
 
	if (vb != last_engine[1]) {
 
		last_engine[1] = vb;
 
		GetString(last_name[1], GetCustomEngineName(vb));
 
		GetString(last_name[1], GetCustomEngineName(vb), lastof(last_name[1]));
 
	}
 

	
 
	r = strcmp(last_name[0], last_name[1]); // sort by name
console_cmds.c
Show inline comments
 
@@ -1217,7 +1217,7 @@ DEF_CONSOLE_CMD(ConPlayers)
 

	
 
		if (!p->is_active) continue;
 

	
 
		GetString(buffer, STR_00D1_DARK_BLUE + _player_colors[p->index]);
 
		GetString(buffer, STR_00D1_DARK_BLUE + _player_colors[p->index], lastof(buffer));
 
		IConsolePrintF(8, "#:%d(%s) Company Name: '%s'  Year Founded: %d  Money: %d  Loan: %d  Value: %" OTTD_PRINTF64 "d  (T:%d, R:%d, P:%d, S:%d)",
 
			p->index + 1, buffer, _network_player_info[p->index].company_name, p->inaugurated_year, p->player_money, p->current_loan, CalculateCompanyValue(p),
 
			/* trains      */ _network_player_info[p->index].num_vehicle[0],
functions.h
Show inline comments
 
@@ -140,7 +140,7 @@ void InitializeLandscapeVariables(bool o
 
/* misc.c */
 
bool IsCustomName(StringID id);
 
void DeleteName(StringID id);
 
char *GetName(int id, char *buff);
 
char *GetName(char *buff, StringID id, const char* last);
 

	
 
// AllocateNameUnique also tests if the name used is not used anywere else
 
//  and if it is used, it returns an error.
genworld_gui.c
Show inline comments
 
@@ -284,7 +284,7 @@ void GenerateLandscapeWndProc(Window *w,
 
				SetDParam(0, _heightmap_x);
 
				SetDParam(1, _heightmap_y);
 
			}
 
			GetString(buffer, STR_HEIGHTMAP_SIZE);
 
			GetString(buffer, STR_HEIGHTMAP_SIZE, lastof(buffer));
 
			DrawStringRightAligned(326, 91, STR_HEIGHTMAP_SIZE, 0x10);
 

	
 
			DrawString( 12,  91, STR_HEIGHTMAP_NAME, 0x10);
gfx.c
Show inline comments
 
@@ -329,9 +329,9 @@ static int TruncateString(char *str, int
 
	return w;
 
}
 

	
 
static inline int TruncateStringID(StringID src, char *dest, int maxw)
 
static inline int TruncateStringID(StringID src, char *dest, int maxw, const char* last)
 
{
 
	GetString(dest, src);
 
	GetString(dest, src, last);
 
	return TruncateString(dest, maxw);
 
}
 

	
 
@@ -340,14 +340,14 @@ int DrawString(int x, int y, StringID st
 
{
 
	char buffer[512];
 

	
 
	GetString(buffer, str);
 
	GetString(buffer, str, lastof(buffer));
 
	return DoDrawString(buffer, x, y, color);
 
}
 

	
 
int DrawStringTruncated(int x, int y, StringID str, uint16 color, uint maxw)
 
{
 
	char buffer[512];
 
	TruncateStringID(str, buffer, maxw);
 
	TruncateStringID(str, buffer, maxw, lastof(buffer));
 
	return DoDrawString(buffer, x, y, color);
 
}
 

	
 
@@ -357,7 +357,7 @@ int DrawStringRightAligned(int x, int y,
 
	char buffer[512];
 
	int w;
 

	
 
	GetString(buffer, str);
 
	GetString(buffer, str, lastof(buffer));
 
	w = GetStringBoundingBox(buffer).width;
 
	DoDrawString(buffer, x - w, y, color);
 

	
 
@@ -368,7 +368,7 @@ void DrawStringRightAlignedTruncated(int
 
{
 
	char buffer[512];
 

	
 
	TruncateStringID(str, buffer, maxw);
 
	TruncateStringID(str, buffer, maxw, lastof(buffer));
 
	DoDrawString(buffer, x - GetStringBoundingBox(buffer).width, y, color);
 
}
 

	
 
@@ -384,7 +384,7 @@ int DrawStringCentered(int x, int y, Str
 
	char buffer[512];
 
	int w;
 

	
 
	GetString(buffer, str);
 
	GetString(buffer, str, lastof(buffer));
 

	
 
	w = GetStringBoundingBox(buffer).width;
 
	DoDrawString(buffer, x - w / 2, y, color);
 
@@ -395,7 +395,7 @@ int DrawStringCentered(int x, int y, Str
 
int DrawStringCenteredTruncated(int xl, int xr, int y, StringID str, uint16 color)
 
{
 
	char buffer[512];
 
	int w = TruncateStringID(str, buffer, xr - xl);
 
	int w = TruncateStringID(str, buffer, xr - xl, lastof(buffer));
 
	return DoDrawString(buffer, (xl + xr - w) / 2, y, color);
 
}
 

	
 
@@ -466,7 +466,7 @@ void DrawStringMultiCenter(int x, int y,
 
	const char *src;
 
	byte c;
 

	
 
	GetString(buffer, str);
 
	GetString(buffer, str, lastof(buffer));
 

	
 
	tmp = FormatStringLinebreaks(buffer, maxw);
 
	num = GB(tmp, 0, 16);
 
@@ -508,7 +508,7 @@ void DrawStringMultiLine(int x, int y, S
 
	const char *src;
 
	byte c;
 

	
 
	GetString(buffer, str);
 
	GetString(buffer, str, lastof(buffer));
 

	
 
	tmp = FormatStringLinebreaks(buffer, maxw);
 
	num = GB(tmp, 0, 16);
graph_gui.c
Show inline comments
 
@@ -1135,11 +1135,11 @@ static int CDECL SignNameSorter(const vo
 
	const Sign *sign1 = *(const Sign**)b;
 
	char buf1[64];
 

	
 
	GetString(buf1, sign0->str);
 
	GetString(buf1, sign0->str, lastof(buf1));
 

	
 
	if (sign1 != _last_sign) {
 
		_last_sign = sign1;
 
		GetString(_bufcache, sign1->str);
 
		GetString(_bufcache, sign1->str, lastof(_bufcache));
 
	}
 

	
 
	return strcmp(buf1, _bufcache); // sort by name
industry_gui.c
Show inline comments
 
@@ -536,12 +536,12 @@ static int CDECL GeneralIndustrySorter(c
 
		char buf1[96];
 

	
 
		SetDParam(0, i->town->index);
 
		GetString(buf1, STR_TOWN);
 
		GetString(buf1, STR_TOWN, lastof(buf1));
 

	
 
		if (j != _last_industry) {
 
			_last_industry = j;
 
			SetDParam(0, j->town->index);
 
			GetString(_bufcache, STR_TOWN);
 
			GetString(_bufcache, STR_TOWN, lastof(_bufcache));
 
		}
 
		r = strcmp(buf1, _bufcache);
 
	}
main_gui.c
Show inline comments
 
@@ -658,7 +658,7 @@ static int GetStringListMaxWidth(StringI
 

	
 
	max_width = 0;
 
	for (i = 0; i != count; i++) {
 
		GetString(buffer, base_string + i);
 
		GetString(buffer, base_string + i, lastof(buffer));
 
		width = GetStringBoundingBox(buffer).width;
 
		if (width > max_width) max_width = width;
 
	}
 
@@ -2108,7 +2108,7 @@ static bool DrawScrollingStatusText(cons
 
		str = ni->string_id;
 
	}
 

	
 
	GetString(buf, str);
 
	GetString(buf, str, lastof(buf));
 

	
 
	s = buf;
 
	d = buffer;
misc.c
Show inline comments
 
@@ -162,9 +162,9 @@ void DeleteName(StringID id)
 
	}
 
}
 

	
 
char *GetName(int id, char *buff)
 
char *GetName(char *buff, StringID id, const char* last)
 
{
 
	return strecpy(buff, _name_array[id & ~0x600], NULL);
 
	return strecpy(buff, _name_array[id & ~0x600], last);
 
}
 

	
 

	
misc_gui.c
Show inline comments
 
@@ -92,7 +92,7 @@ static void LandInfoWndProc(Window *w, W
 

	
 
		{
 
			char buf[512];
 
			char *p = GetString(buf, STR_01CE_CARGO_ACCEPTED);
 
			char *p = GetString(buf, STR_01CE_CARGO_ACCEPTED, lastof(buf));
 
			bool found = false;
 

	
 
			for (i = 0; i < NUM_CARGO; ++i) {
 
@@ -108,9 +108,9 @@ static void LandInfoWndProc(Window *w, W
 
					if (lid->ac[i] < 8) {
 
						SetDParam(0, lid->ac[i]);
 
						SetDParam(1, _cargoc.names_s[i]);
 
						p = GetString(p, STR_01D1_8);
 
						p = GetString(p, STR_01D1_8, lastof(buf));
 
					} else {
 
						p = GetString(p, _cargoc.names_s[i]);
 
						p = GetString(p, _cargoc.names_s[i], lastof(buf));
 
					}
 
				}
 
			}
 
@@ -679,7 +679,7 @@ void GuiShowTooltipsWithArgs(StringID st
 
	if (str == STR_NULL || (paramcount != 0 && !_patches.measure_tooltip)) return;
 

	
 
	for (i = 0; i != paramcount; i++) SetDParam(i, params[i]);
 
	GetString(buffer, str);
 
	GetString(buffer, str, lastof(buffer));
 

	
 
	br = GetStringBoundingBox(buffer);
 
	br.width += 6; br.height += 4; // increase slightly to have some space around the box
 
@@ -1076,7 +1076,7 @@ void ShowQueryString(StringID str, Strin
 

	
 
	w = AllocateWindowDesc(&_query_string_desc);
 

	
 
	GetString(_edit_str_buf, str);
 
	GetString(_edit_str_buf, str, lastof(_edit_str_buf));
 
	_edit_str_buf[realmaxlen-1] = '\0';
 

	
 
	if (maxlen & 0x1000) {
 
@@ -1311,7 +1311,7 @@ static void GenerateFileName(void)
 
	SetDParam(0, p->name_1);
 
	SetDParam(1, p->name_2);
 
	SetDParam(2, _date);
 
	GetString(_edit_str_buf, STR_4004);
 
	GetString(_edit_str_buf, STR_4004, lastof(_edit_str_buf));
 
}
 

	
 
extern void StartupEngines(void);
 
@@ -1777,7 +1777,7 @@ static void CheatsWndProc(Window *w, Win
 
				/* Draw colored flag for change player cheat */
 
				case STR_CHEAT_CHANGE_PLAYER:
 
					SetDParam(0, val);
 
					GetString(buf, STR_CHEAT_CHANGE_PLAYER);
 
					GetString(buf, STR_CHEAT_CHANGE_PLAYER, lastof(buf));
 
					DrawPlayerIcon(_current_player, 60 + GetStringBoundingBox(buf).width, y + 2);
 
					break;
 
				/* Set correct string for switch climate cheat */
network.c
Show inline comments
 
@@ -131,54 +131,54 @@ void CDECL NetworkTextMessage(NetworkAct
 

	
 
	switch (action) {
 
		case NETWORK_ACTION_JOIN:
 
			GetString(temp, STR_NETWORK_CLIENT_JOINED);
 
			GetString(temp, STR_NETWORK_CLIENT_JOINED, lastof(temp));
 
			snprintf(message, sizeof(message), "*** %s %s", name, temp);
 
			break;
 
		case NETWORK_ACTION_LEAVE:
 
			GetString(temp, STR_NETWORK_ERR_LEFT);
 
			GetString(temp, STR_NETWORK_ERR_LEFT, lastof(temp));
 
			snprintf(message, sizeof(message), "*** %s %s (%s)", name, temp, buf);
 
			break;
 
		case NETWORK_ACTION_GIVE_MONEY:
 
			if (self_send) {
 
				SetDParamStr(0, name);
 
				SetDParam(1, atoi(buf));
 
				GetString(temp, STR_NETWORK_GAVE_MONEY_AWAY);
 
				GetString(temp, STR_NETWORK_GAVE_MONEY_AWAY, lastof(temp));
 
				snprintf(message, sizeof(message), "*** %s", temp);
 
			} else {
 
				SetDParam(0, atoi(buf));
 
				GetString(temp, STR_NETWORK_GIVE_MONEY);
 
				GetString(temp, STR_NETWORK_GIVE_MONEY, lastof(temp));
 
				snprintf(message, sizeof(message), "*** %s %s", name, temp);
 
			}
 
			break;
 
		case NETWORK_ACTION_CHAT_COMPANY:
 
			if (self_send) {
 
				SetDParamStr(0, name);
 
				GetString(temp, STR_NETWORK_CHAT_TO_COMPANY);
 
				GetString(temp, STR_NETWORK_CHAT_TO_COMPANY, lastof(temp));
 
				snprintf(message, sizeof(message), "%s %s", temp, buf);
 
			} else {
 
				SetDParamStr(0, name);
 
				GetString(temp, STR_NETWORK_CHAT_COMPANY);
 
				GetString(temp, STR_NETWORK_CHAT_COMPANY, lastof(temp));
 
				snprintf(message, sizeof(message), "%s %s", temp, buf);
 
			}
 
			break;
 
		case NETWORK_ACTION_CHAT_CLIENT:
 
			if (self_send) {
 
				SetDParamStr(0, name);
 
				GetString(temp, STR_NETWORK_CHAT_TO_CLIENT);
 
				GetString(temp, STR_NETWORK_CHAT_TO_CLIENT, lastof(temp));
 
				snprintf(message, sizeof(message), "%s %s", temp, buf);
 
			} else {
 
				SetDParamStr(0, name);
 
				GetString(temp, STR_NETWORK_CHAT_CLIENT);
 
				GetString(temp, STR_NETWORK_CHAT_CLIENT, lastof(temp));
 
				snprintf(message, sizeof(message), "%s %s", temp, buf);
 
			}
 
			break;
 
		case NETWORK_ACTION_NAME_CHANGE:
 
			GetString(temp, STR_NETWORK_NAME_CHANGE);
 
			GetString(temp, STR_NETWORK_NAME_CHANGE, lastof(temp));
 
			snprintf(message, sizeof(message), "*** %s %s %s", name, temp, buf);
 
			break;
 
		default:
 
			SetDParamStr(0, name);
 
			GetString(temp, STR_NETWORK_CHAT_ALL);
 
			GetString(temp, STR_NETWORK_CHAT_ALL, lastof(temp));
 
			snprintf(message, sizeof(message), "%s %s", temp, buf);
 
			break;
 
	}
 
@@ -260,7 +260,7 @@ static void NetworkClientError(NetworkRe
 
 * @param buf buffer where the error message will be stored
 
 * @param err NetworkErrorCode
 
 * @return returns a pointer to the error message (buf) */
 
char *GetNetworkErrorMsg(char *buf, NetworkErrorCode err)
 
char* GetNetworkErrorMsg(char* buf, NetworkErrorCode err, const char* last)
 
{
 
	/* List of possible network errors, used by
 
	 * PACKET_SERVER_ERROR and PACKET_CLIENT_ERROR */
 
@@ -283,7 +283,7 @@ char *GetNetworkErrorMsg(char *buf, Netw
 

	
 
	if (err >= lengthof(network_error_strings)) err = 0;
 

	
 
	return GetString(buf, network_error_strings[err]);
 
	return GetString(buf, network_error_strings[err], last);
 
}
 

	
 
/* Count the number of active clients connected */
 
@@ -599,7 +599,7 @@ void NetworkCloseClient(NetworkClientSta
 

	
 
		NetworkGetClientName(client_name, sizeof(client_name), cs);
 

	
 
		GetNetworkErrorMsg(str, errorno);
 
		GetNetworkErrorMsg(str, errorno, lastof(str));
 

	
 
		NetworkTextMessage(NETWORK_ACTION_LEAVE, 1, false, client_name, "%s", str);
 

	
network_client.c
Show inline comments
 
@@ -628,7 +628,7 @@ DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER
 
				/* For speaking to player or give money, we need the player-name */
 
				if (!IsValidPlayer(ci_to->client_playas)) return NETWORK_RECV_STATUS_OKAY; // This should never happen
 

	
 
				GetString(name, GetPlayer(ci_to->client_playas)->name_1);
 
				GetString(name, GetPlayer(ci_to->client_playas)->name_1, lastof(name));
 
				ci = NetworkFindClientInfoFromIndex(_network_own_client_index);
 
				break;
 
			default:
 
@@ -654,7 +654,7 @@ DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER
 
	NetworkClientInfo *ci;
 

	
 
	index = NetworkRecv_uint16(MY_CLIENT, p);
 
	GetNetworkErrorMsg(str, NetworkRecv_uint8(MY_CLIENT, p));
 
	GetNetworkErrorMsg(str, NetworkRecv_uint8(MY_CLIENT, p), lastof(str));
 

	
 
	ci = NetworkFindClientInfoFromIndex(index);
 
	if (ci != NULL) {
network_data.h
Show inline comments
 
@@ -230,7 +230,7 @@ NetworkClientInfo *NetworkFindClientInfo
 
NetworkClientInfo *NetworkFindClientInfoFromIP(const char *ip);
 
NetworkClientState *NetworkFindClientStateFromIndex(uint16 client_index);
 
unsigned long NetworkResolveHost(const char *hostname);
 
char *GetNetworkErrorMsg(char *buf, NetworkErrorCode err);
 
char* GetNetworkErrorMsg(char* buf, NetworkErrorCode err, const char* last);
 

	
 
#endif /* ENABLE_NETWORK */
 

	
network_gui.c
Show inline comments
 
@@ -1181,36 +1181,36 @@ static Window *PopupClientList(Window *w
 

	
 
	i = 0;
 
	if (_network_own_client_index != ci->client_index) {
 
		GetString(_clientlist_action[i], STR_NETWORK_CLIENTLIST_SPEAK_TO_CLIENT);
 
		GetString(_clientlist_action[i], STR_NETWORK_CLIENTLIST_SPEAK_TO_CLIENT, lastof(_clientlist_action[i]));
 
		_clientlist_proc[i++] = &ClientList_SpeakToClient;
 
	}
 

	
 
	if (IsValidPlayer(ci->client_playas)) {
 
		GetString(_clientlist_action[i], STR_NETWORK_CLIENTLIST_SPEAK_TO_COMPANY);
 
		GetString(_clientlist_action[i], STR_NETWORK_CLIENTLIST_SPEAK_TO_COMPANY, lastof(_clientlist_action[i]));
 
		_clientlist_proc[i++] = &ClientList_SpeakToCompany;
 
	}
 
	GetString(_clientlist_action[i], STR_NETWORK_CLIENTLIST_SPEAK_TO_ALL);
 
	GetString(_clientlist_action[i], STR_NETWORK_CLIENTLIST_SPEAK_TO_ALL, lastof(_clientlist_action[i]));
 
	_clientlist_proc[i++] = &ClientList_SpeakToAll;
 

	
 
	if (_network_own_client_index != ci->client_index) {
 
		/* We are no spectator and the player we want to give money to is no spectator */
 
		if (IsValidPlayer(_network_playas) && IsValidPlayer(ci->client_playas)) {
 
			GetString(_clientlist_action[i], STR_NETWORK_CLIENTLIST_GIVE_MONEY);
 
			GetString(_clientlist_action[i], STR_NETWORK_CLIENTLIST_GIVE_MONEY, lastof(_clientlist_action[i]));
 
			_clientlist_proc[i++] = &ClientList_GiveMoney;
 
		}
 
	}
 

	
 
	// A server can kick clients (but not himself)
 
	if (_network_server && _network_own_client_index != ci->client_index) {
 
		GetString(_clientlist_action[i], STR_NETWORK_CLIENTLIST_KICK);
 
		GetString(_clientlist_action[i], STR_NETWORK_CLIENTLIST_KICK, lastof(_clientlist_action[i]));
 
		_clientlist_proc[i++] = &ClientList_Kick;
 

	
 
		sprintf(_clientlist_action[i],"Ban");
 
		sprintf(_clientlist_action[i],"Ban"); // XXX GetString?
 
		_clientlist_proc[i++] = &ClientList_Ban;
 
	}
 

	
 
	if (i == 0) {
 
		GetString(_clientlist_action[i], STR_NETWORK_CLIENTLIST_NONE);
 
		GetString(_clientlist_action[i], STR_NETWORK_CLIENTLIST_NONE, lastof(_clientlist_action[i]));
 
		_clientlist_proc[i++] = &ClientList_None;
 
	}
 

	
 
@@ -1511,7 +1511,7 @@ static const char *ChatTabCompletionNext
 
		FOR_ALL_TOWNS_FROM(t, *item - MAX_CLIENT_INFO) {
 
			/* Get the town-name via the string-system */
 
			SetDParam(0, t->townnameparts);
 
			GetString(chat_tab_temp_buffer, t->townnametype);
 
			GetString(chat_tab_temp_buffer, t->townnametype, lastof(chat_tab_temp_buffer));
 
			return &chat_tab_temp_buffer[0];
 
		}
 
	}
network_server.c
Show inline comments
 
@@ -3,6 +3,7 @@
 
#ifdef ENABLE_NETWORK
 

	
 
#include "stdafx.h"
 
#include "openttd.h" // XXX StringID
 
#include "debug.h"
 
#include "string.h"
 
#include "strings.h"
 
@@ -144,7 +145,7 @@ DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SER
 
	NetworkSend_uint8(p, error);
 
	NetworkSend_Packet(p, cs);
 

	
 
	GetNetworkErrorMsg(str, error);
 
	GetNetworkErrorMsg(str, error, lastof(str));
 

	
 
	// Only send when the current client was in game
 
	if (cs->status > STATUS_AUTH) {
 
@@ -899,7 +900,7 @@ DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT
 

	
 
	NetworkGetClientName(client_name, sizeof(client_name), cs);
 

	
 
	GetNetworkErrorMsg(str, errorno);
 
	GetNetworkErrorMsg(str, errorno, lastof(str));
 

	
 
	DEBUG(net, 2)("[NET] %s reported an error and is closing his connection (%s)", client_name, str);
 

	
 
@@ -1043,7 +1044,7 @@ void NetworkServer_HandleChat(NetworkAct
 
		if (ci != NULL && show_local) {
 
			if (from_index == NETWORK_SERVER_INDEX) {
 
				char name[NETWORK_NAME_LENGTH];
 
				GetString(name, GetPlayer(ci_to->client_playas)->name_1);
 
				GetString(name, GetPlayer(ci_to->client_playas)->name_1, lastof(name));
 
				NetworkTextMessage(action, GetDrawStringPlayerColor(ci_own->client_playas), true, name, "%s", msg);
 
			} else {
 
				FOR_ALL_CLIENTS(cs) {
 
@@ -1211,7 +1212,7 @@ void NetworkPopulateCompanyInfo(void)
 
		// Grap the company name
 
		SetDParam(0, p->name_1);
 
		SetDParam(1, p->name_2);
 
		GetString(_network_player_info[p->index].company_name, STR_JUST_STRING);
 
		GetString(_network_player_info[p->index].company_name, STR_JUST_STRING, lastof(_network_player_info[p->index].company_name));
 

	
 
		// Check the income
 
		if (_cur_year - 1 == p->inaugurated_year) {
newgrf_text.c
Show inline comments
 
@@ -292,7 +292,7 @@ StringID GetGRFStringID(uint32 grfid, ui
 
}
 

	
 

	
 
char *GetGRFString(char *buff, uint16 stringid)
 
char *GetGRFString(char *buff, uint16 stringid, const char* last)
 
{
 
	const GRFText *default_text = NULL;
 
	const GRFText *search_text;
 
@@ -319,7 +319,7 @@ char *GetGRFString(char *buff, uint16 st
 
	if (default_text != NULL) return strecpy(buff, default_text->text, NULL);
 

	
 
	/* Use the default string ID if the fallback string isn't available */
 
	return GetString(buff, _grf_text[stringid].def_string);
 
	return GetString(buff, _grf_text[stringid].def_string, last);
 
}
 

	
 
/**
newgrf_text.h
Show inline comments
 
@@ -8,7 +8,7 @@
 

	
 
StringID AddGRFString(uint32 grfid, uint16 stringid, byte langid, bool new_scheme, const char *text_to_add, StringID def_string);
 
StringID GetGRFStringID(uint32 grfid, uint16 stringid);
 
char *GetGRFString(char *buff, uint16 stringid);
 
char *GetGRFString(char *buff, uint16 stringid, const char* last);
 
void CleanUpStrings(void);
 
void SetCurrentGrfLangID(const char *iso_name);
 

	
news_gui.c
Show inline comments
 
@@ -579,7 +579,7 @@ static void DrawNewsString(int x, int y,
 
		str = ni->string_id;
 
	}
 

	
 
	GetString(buffer, str);
 
	GetString(buffer, str, lastof(buffer));
 
	/* Copy the just gotten string to another buffer to remove any formatting
 
	 * from it such as big fonts, etc. */
 
	for (ptr = buffer, dest = buffer2; *ptr != '\0'; ptr++) {
openttd.c
Show inline comments
 
@@ -17,6 +17,7 @@
 
#include "functions.h"
 
#include "mixer.h"
 
#include "spritecache.h"
 
#include "strings.h"
 
#include "gfx.h"
 
#include "gfxinit.h"
 
#include "gui.h"
 
@@ -878,16 +879,17 @@ static void DoAutosave(void)
 

	
 
	if (_patches.keep_all_autosave && _local_player != PLAYER_SPECTATOR) {
 
		const Player *p = GetPlayer(_local_player);
 
		char *s;
 
		sprintf(buf, "%s%s", _path.autosave_dir, PATHSEP);
 
		char* s = buf;
 

	
 
		s += snprintf(buf, lengthof(buf), "%s%s", _path.autosave_dir, PATHSEP);
 

	
 
		SetDParam(0, p->name_1);
 
		SetDParam(1, p->name_2);
 
		SetDParam(2, _date);
 
		s = GetString(buf + strlen(_path.autosave_dir) + strlen(PATHSEP), STR_4004);
 
		strcpy(s, ".sav");
 
		s = GetString(s, STR_4004, lastof(buf));
 
		strecpy(s, ".sav", lastof(buf));
 
	} else { /* generate a savegame name and number according to _patches.max_num_autosaves */
 
		sprintf(buf, "%s%sautosave%d.sav", _path.autosave_dir, PATHSEP, _autosave_ctr);
 
		snprintf(buf, lengthof(buf), "%s%sautosave%d.sav", _path.autosave_dir, PATHSEP, _autosave_ctr);
 

	
 
		_autosave_ctr++;
 
		if (_autosave_ctr >= _patches.max_num_autosaves) {
order_cmd.c
Show inline comments
 
@@ -826,7 +826,7 @@ void BackupVehicleOrders(const Vehicle *
 
	if (!IsCustomName(v->string_id)) {
 
		bak->name[0] = '\0';
 
	} else {
 
		GetName(v->string_id & 0x7FF, bak->name);
 
		GetName(bak->name, v->string_id & 0x7FF, lastof(bak->name));
 
	}
 

	
 
	/* If we have shared orders, store it on a special way */
players.c
Show inline comments
 
@@ -331,7 +331,7 @@ verify_name:;
 
			if (pp->name_1 == str && pp->name_2 == strp) goto bad_town_name;
 
		}
 

	
 
		GetString(buffer, str);
 
		GetString(buffer, str, lastof(buffer));
 
		if (strlen(buffer) >= 32 || GetStringBoundingBox(buffer).width >= 150)
 
			goto bad_town_name;
 

	
 
@@ -438,14 +438,14 @@ restart:;
 
		p->president_name_1 = SPECSTR_PRESIDENT_NAME;
 

	
 
		SetDParam(0, p->president_name_2);
 
		GetString(buffer, p->president_name_1);
 
		GetString(buffer, p->president_name_1, lastof(buffer));
 
		if (strlen(buffer) >= 32 || GetStringBoundingBox(buffer).width >= 94)
 
			continue;
 

	
 
		FOR_ALL_PLAYERS(pp) {
 
			if (pp->is_active && p != pp) {
 
				SetDParam(0, pp->president_name_2);
 
				GetString(buffer2, pp->president_name_1);
 
				GetString(buffer2, pp->president_name_1, lastof(buffer));
 
				if (strcmp(buffer2, buffer) == 0)
 
					goto restart;
 
			}
 
@@ -998,7 +998,7 @@ int8 SaveHighScoreValue(const Player *p)
 
			SetDParam(1, p->president_name_2);
 
			SetDParam(2, p->name_1);
 
			SetDParam(3, p->name_2);
 
			GetString(hs[i].company, STR_HIGHSCORE_NAME); // get manager/company name string
 
			GetString(hs[i].company, STR_HIGHSCORE_NAME, lastof(hs[i].company)); // get manager/company name string
 
			hs[i].score = score;
 
			hs[i].title = EndGameGetPerformanceTitleFromValue(score);
 
			return i;
 
@@ -1043,7 +1043,7 @@ int8 SaveHighScoreValueNetwork(void)
 
			SetDParam(1, pl[i]->president_name_2);
 
			SetDParam(2, pl[i]->name_1);
 
			SetDParam(3, pl[i]->name_2);
 
			GetString(hs->company, STR_HIGHSCORE_NAME); // get manager/company name string
 
			GetString(hs->company, STR_HIGHSCORE_NAME, lastof(hs->company)); // get manager/company name string
 
			hs->score = pl[i]->old_economy[0].performance_history;
 
			hs->title = EndGameGetPerformanceTitleFromValue(hs->score);
 

	
screenshot.c
Show inline comments
 
@@ -504,7 +504,7 @@ static char *MakeScreenshotName(const ch
 
		SetDParam(0, p->name_1);
 
		SetDParam(1, p->name_2);
 
		SetDParam(2, _date);
 
		GetString(_screenshot_name, STR_4004);
 
		GetString(_screenshot_name, STR_4004, lastof(_screenshot_name));
 
	}
 

	
 
	base = strchr(_screenshot_name, 0);
station_gui.c
Show inline comments
 
@@ -81,12 +81,12 @@ static int CDECL StationNameSorter(const
 
	int r;
 

	
 
	SetDParam(0, st1->index);
 
	GetString(buf1, STR_STATION);
 
	GetString(buf1, STR_STATION, lastof(buf1));
 

	
 
	if (st2 != _last_station) {
 
		_last_station = st2;
 
		SetDParam(0, st2->index);
 
		GetString(_bufcache, STR_STATION);
 
		GetString(_bufcache, STR_STATION, lastof(_bufcache));
 
	}
 

	
 
	r =  strcmp(buf1, _bufcache); // sort by name
string.c
Show inline comments
 
/* $Id$ */
 

	
 
#include "stdafx.h"
 
#include "openttd.h"
 
#include "functions.h"
 
#include "string.h"
 

	
 
#include <stdarg.h>
 
@@ -26,7 +28,7 @@ void ttd_strlcpy(char *dst, const char *
 

	
 
char* strecat(char* dst, const char* src, const char* last)
 
{
 
	assert(last == NULL || dst <= last);
 
	assert(dst <= last);
 
	for (; *dst != '\0'; ++dst)
 
		if (dst == last) return dst;
 
	for (; *src != '\0' && dst != last; ++dst, ++src) *dst = *src;
 
@@ -37,9 +39,14 @@ char* strecat(char* dst, const char* src
 

	
 
char* strecpy(char* dst, const char* src, const char* last)
 
{
 
	assert(last == NULL || dst <= last);
 
	assert(dst <= last);
 
	for (; *src != '\0' && dst != last; ++dst, ++src) *dst = *src;
 
	*dst = '\0';
 
#if 0
 
	if (dst == last && *src != '\0') {
 
		error("String too long for destination buffer");
 
	}
 
#endif
 
	return dst;
 
}
 

	
strings.c
Show inline comments
 
@@ -31,11 +31,11 @@
 

	
 
char _userstring[128];
 

	
 
static char *StationGetSpecialString(char *buff, int x);
 
static char *GetSpecialTownNameString(char *buff, int ind, uint32 seed);
 
static char *GetSpecialPlayerNameString(char *buff, int ind, const int32 *argv);
 
static char *StationGetSpecialString(char *buff, int x, const char* last);
 
static char *GetSpecialTownNameString(char *buff, int ind, uint32 seed, const char* last);
 
static char *GetSpecialPlayerNameString(char *buff, int ind, const int32 *argv, const char* last);
 

	
 
static char *FormatString(char *buff, const char *str, const int32 *argv, uint casei);
 
static char *FormatString(char *buff, const char *str, const int32 *argv, uint casei, const char* last);
 

	
 
typedef struct LanguagePack {
 
	uint32 ident;
 
@@ -166,7 +166,7 @@ static const char *GetStringPtr(StringID
 
// These 8 bits will only be set when FormatString wants to print
 
// the string in a different case. No one else except FormatString
 
// should set those bits, therefore string CANNOT be StringID, but uint32.
 
static char *GetStringWithArgs(char *buffr, uint string, const int32 *argv)
 
static char *GetStringWithArgs(char *buffr, uint string, const int32 *argv, const char* last)
 
{
 
	uint index = GB(string,  0, 11);
 
	uint tab   = GB(string, 11,  5);
 
@@ -177,46 +177,46 @@ static char *GetStringWithArgs(char *buf
 
	switch (tab) {
 
		case 4:
 
			if (index >= 0xC0)
 
				return GetSpecialTownNameString(buffr, index - 0xC0, GetInt32(&argv));
 
				return GetSpecialTownNameString(buffr, index - 0xC0, GetInt32(&argv), last);
 
			break;
 

	
 
		case 14:
 
			if (index >= 0xE4)
 
				return GetSpecialPlayerNameString(buffr, index - 0xE4, argv);
 
				return GetSpecialPlayerNameString(buffr, index - 0xE4, argv, last);
 
			break;
 

	
 
		// User defined name
 
		case 15:
 
			return GetName(index, buffr);
 
			return GetName(buffr, index, last);
 

	
 
		case 26:
 
			/* Include string within newgrf text (format code 81) */
 
			if (HASBIT(index, 10)) {
 
				StringID string = GetGRFStringID(0, 0xD000 + GB(index, 0, 10));
 
				return GetStringWithArgs(buffr, string, argv);
 
				return GetStringWithArgs(buffr, string, argv, last);
 
			}
 
			break;
 

	
 
		case 28:
 
			GetGRFString(buff, index);
 
			return FormatString(buffr, buff, argv, 0);
 
			GetGRFString(buff, index, last);
 
			return FormatString(buffr, buff, argv, 0, last);
 

	
 
		case 29:
 
			GetGRFString(buff, index + 0x800);
 
			return FormatString(buffr, buff, argv, 0);
 
			GetGRFString(buff, index + 0x800, last);
 
			return FormatString(buffr, buff, argv, 0, last);
 

	
 
		case 30:
 
			GetGRFString(buff, index + 0x1000);
 
			return FormatString(buffr, buff, argv, 0);
 
			GetGRFString(buff, index + 0x1000, last);
 
			return FormatString(buffr, buff, argv, 0, last);
 

	
 
		case 31:
 
			// dynamic strings. These are NOT to be passed through the formatter,
 
			// but passed through verbatim.
 
			if (index < (STR_SPEC_USERSTRING & 0x7FF)) {
 
				return strecpy(buffr, _bound_strings[index], NULL);
 
				return strecpy(buffr, _bound_strings[index], last);
 
			}
 

	
 
			return FormatString(buffr, _userstring, NULL, 0);
 
			return FormatString(buffr, _userstring, NULL, 0, last);
 
	}
 

	
 
	if (index >= _langtab_num[tab]) {
 
@@ -226,12 +226,12 @@ static char *GetStringWithArgs(char *buf
 
		);
 
	}
 

	
 
	return FormatString(buffr, GetStringPtr(GB(string, 0, 16)), argv, GB(string, 24, 8));
 
	return FormatString(buffr, GetStringPtr(GB(string, 0, 16)), argv, GB(string, 24, 8), last);
 
}
 

	
 
char *GetString(char *buffr, StringID string)
 
char *GetString(char *buffr, StringID string, const char* last)
 
{
 
	return GetStringWithArgs(buffr, string, (int32*)_decode_parameters);
 
	return GetStringWithArgs(buffr, string, (int32*)_decode_parameters, last);
 
}
 

	
 

	
 
@@ -270,7 +270,8 @@ static const uint32 _divisor_table[] = {
 
	1
 
};
 

	
 
static char *FormatCommaNumber(char *buff, int32 number)
 
// TODO
 
static char *FormatCommaNumber(char *buff, int32 number, const char* last)
 
{
 
	uint32 quot,divisor;
 
	int i;
 
@@ -303,7 +304,8 @@ static char *FormatCommaNumber(char *buf
 
	return buff;
 
}
 

	
 
static char *FormatNoCommaNumber(char *buff, int32 number)
 
// TODO
 
static char *FormatNoCommaNumber(char *buff, int32 number, const char* last)
 
{
 
	uint32 quot,divisor;
 
	int i;
 
@@ -311,7 +313,7 @@ static char *FormatNoCommaNumber(char *b
 
	uint32 num;
 

	
 
	if (number < 0) {
 
		*buff++ = '-';
 
		buff = strecpy(buff, "-", last);
 
		number = -number;
 
	}
 

	
 
@@ -336,50 +338,50 @@ static char *FormatNoCommaNumber(char *b
 
}
 

	
 

	
 
static char *FormatYmdString(char *buff, Date date)
 
static char *FormatYmdString(char *buff, Date date, const char* last)
 
{
 
	const char *src;
 
	YearMonthDay ymd;
 

	
 
	ConvertDateToYMD(date, &ymd);
 

	
 
	buff = strecpy(buff, GetStringPtr(ymd.day + STR_01AC_1ST - 1), last);
 
	buff = strecpy(buff, " ", last);
 
	buff = strecpy(buff, GetStringPtr(STR_0162_JAN + ymd.month), last);
 
	buff = strecpy(buff, " ", last);
 

	
 
	return FormatNoCommaNumber(buff, ymd.year, last);
 
}
 

	
 
static char *FormatMonthAndYear(char *buff, Date date, const char* last)
 
{
 
	YearMonthDay ymd;
 

	
 
	ConvertDateToYMD(date, &ymd);
 

	
 
	for (src = GetStringPtr(ymd.day + STR_01AC_1ST - 1); (*buff++ = *src++) != '\0';) {}
 
	buff[-1] = ' ';
 
	buff = strecpy(buff, GetStringPtr(STR_MONTH_JAN + ymd.month), last);
 
	buff = strecpy(buff, " ", last);
 

	
 
	for (src = GetStringPtr(STR_0162_JAN + ymd.month); (*buff++ = *src++) != '\0';) {}
 
	buff[-1] = ' ';
 

	
 
	return FormatNoCommaNumber(buff, ymd.year);
 
	return FormatNoCommaNumber(buff, ymd.year, last);
 
}
 

	
 
static char *FormatMonthAndYear(char *buff, Date date)
 
{
 
	const char *src;
 
	YearMonthDay ymd;
 

	
 
	ConvertDateToYMD(date, &ymd);
 

	
 
	for (src = GetStringPtr(STR_MONTH_JAN + ymd.month); (*buff++ = *src++) != '\0';) {}
 
	buff[-1] = ' ';
 

	
 
	return FormatNoCommaNumber(buff, ymd.year);
 
}
 

	
 
static char *FormatTinyDate(char *buff, Date date)
 
static char *FormatTinyDate(char *buff, Date date, const char* last)
 
{
 
	YearMonthDay ymd;
 

	
 
	ConvertDateToYMD(date, &ymd);
 
	buff += sprintf(buff, " %02i-%02i-%04i", ymd.day, ymd.month + 1, ymd.year);
 
	buff += snprintf(
 
		buff, last - buff + 1,
 
		" %02i-%02i-%04i", ymd.day, ymd.month + 1, ymd.year
 
	);
 

	
 
	return buff;
 
}
 

	
 
static char *FormatGenericCurrency(char *buff, const CurrencySpec *spec, int64 number, bool compact)
 
static char *FormatGenericCurrency(char *buff, const CurrencySpec *spec, int64 number, bool compact, const char* last)
 
{
 
	const char *s;
 
	char c;
 
	char buf[40], *p;
 
	const char* multiplier = "";
 
	char buf[40];
 
	char* p;
 
	int j;
 

	
 
	// multiply by exchange rate
 
@@ -387,51 +389,45 @@ static char *FormatGenericCurrency(char 
 

	
 
	// convert from negative
 
	if (number < 0) {
 
		*buff++ = '-';
 
		buff = strecpy(buff, "-", last);
 
		number = -number;
 
	}
 

	
 
	/* Add prefix part, folowing symbol_pos specification.
 
	 * Here, it can can be either 0 (prefix) or 2 (both prefix anf suffix).
 
	 * The only remaining value is 1 (suffix), so everything that is not 1 */
 
	if (spec->symbol_pos != 1){
 
		s = spec->prefix;
 
		while (s != spec->prefix + lengthof(spec->prefix) && (c = *(s++)) != '\0') *(buff)++ = c;
 
	}
 
	if (spec->symbol_pos != 1) buff = strecpy(buff, spec->prefix, last);
 

	
 
	// for huge numbers, compact the number into k or M
 
	if (compact) {
 
		compact = 0;
 
		if (number >= 1000000000) {
 
			number = (number + 500000) / 1000000;
 
			compact = 'M';
 
			multiplier = "M";
 
		} else if (number >= 1000000) {
 
			number = (number + 500) / 1000;
 
			compact = 'k';
 
			multiplier = "k";
 
		}
 
	}
 

	
 
	// convert to ascii number and add commas
 
	p = buf;
 
	p = endof(buf);
 
	*--p = '\0';
 
	j = 4;
 
	do {
 
		if (--j == 0) {
 
			*p++ = spec->separator;
 
			*--p = spec->separator;
 
			j = 3;
 
		}
 
		*p++ = '0' + number % 10;
 
	} while (number /= 10);
 
	do *buff++ = *--p; while (p != buf);
 
		*--p = '0' + number % 10;
 
	} while ((number /= 10) != 0);
 
	buff = strecpy(buff, p, last);
 

	
 
	if (compact) *buff++ = compact;
 
	buff = strecpy(buff, multiplier, last);
 

	
 
	/* Add suffix part, folowing symbol_pos specification.
 
	 * Here, it can can be either 1 (suffix) or 2 (both prefix anf suffix).
 
	 * The only remaining value is 1 (prefix), so everything that is not 0 */
 
	if (spec->symbol_pos != 0) {
 
		s = spec->suffix;
 
		while (s != spec->suffix + lengthof(spec->suffix) && (c = *(s++)) != '\0') *(buff++) = c;
 
	}
 
	if (spec->symbol_pos != 0) buff = strecpy(buff, spec->suffix, last);
 

	
 
	return buff;
 
}
 
@@ -564,7 +560,7 @@ static const Units units[] = {
 
	},
 
};
 

	
 
static char *FormatString(char *buff, const char *str, const int32 *argv, uint casei)
 
static char* FormatString(char* buff, const char* str, const int32* argv, uint casei, const char* last)
 
{
 
	extern const char _openttd_revision[];
 
	byte b;
 
@@ -574,30 +570,34 @@ static char *FormatString(char *buff, co
 
	while ((b = *str++) != '\0') {
 
		switch (b) {
 
		case 0x1: // {SETX}
 
			*buff++ = b;
 
			*buff++ = *str++;
 
			if (buff != last && buff + 1 != last) {
 
				*buff++ = b;
 
				*buff++ = *str++;
 
			}
 
			break;
 
		case 0x2: // {SETXY}
 
			*buff++ = b;
 
			*buff++ = *str++;
 
			*buff++ = *str++;
 
			if (buff != last && buff + 1 != last && buff + 2 != last) {
 
				*buff++ = b;
 
				*buff++ = *str++;
 
				*buff++ = *str++;
 
			}
 
			break;
 

	
 
		case 0x81: // {STRINL}
 
			buff = GetStringWithArgs(buff, ReadLE16Unaligned(str), argv);
 
			buff = GetStringWithArgs(buff, ReadLE16Unaligned(str), argv, last);
 
			str += 2;
 
			break;
 
		case 0x82: // {DATE_LONG}
 
			buff = FormatYmdString(buff, GetInt32(&argv));
 
			buff = FormatYmdString(buff, GetInt32(&argv), last);
 
			break;
 
		case 0x83: // {DATE_SHORT}
 
			buff = FormatMonthAndYear(buff, GetInt32(&argv));
 
			buff = FormatMonthAndYear(buff, GetInt32(&argv), last);
 
			break;
 
		case 0x84: {// {VELOCITY}
 
			int32 args[1];
 
			assert(_opt_ptr->units < lengthof(units));
 
			args[0] = GetInt32(&argv) * units[_opt_ptr->units].s_m >> units[_opt_ptr->units].s_s;
 
			buff = FormatString(buff, GetStringPtr(units[_opt_ptr->units].velocity), args, modifier >> 24);
 
			buff = FormatString(buff, GetStringPtr(units[_opt_ptr->units].velocity), args, modifier >> 24, last);
 
			modifier = 0;
 
			break;
 
		}
 
@@ -605,10 +605,10 @@ static char *FormatString(char *buff, co
 
		case 0x85:
 
			switch (*str++) {
 
			case 0: /* {CURRCOMPACT} */
 
				buff = FormatGenericCurrency(buff, _currency, GetInt32(&argv), true);
 
				buff = FormatGenericCurrency(buff, _currency, GetInt32(&argv), true, last);
 
				break;
 
			case 2: /* {REV} */
 
				buff = strecpy(buff, _openttd_revision, NULL);
 
				buff = strecpy(buff, _openttd_revision, last);
 
				break;
 
			case 3: { /* {SHORTCARGO} */
 
				// Short description of cargotypes. Layout:
 
@@ -620,7 +620,7 @@ static char *FormatString(char *buff, co
 
						int32 args[1];
 
						assert(_opt_ptr->units < lengthof(units));
 
						args[0] = GetInt32(&argv) * units[_opt_ptr->units].w_m >> units[_opt_ptr->units].w_s;
 
						buff = FormatString(buff, GetStringPtr(units[_opt_ptr->units].l_weight), args, modifier >> 24);
 
						buff = FormatString(buff, GetStringPtr(units[_opt_ptr->units].l_weight), args, modifier >> 24, last);
 
						modifier = 0;
 
						break;
 
					}
 
@@ -629,61 +629,61 @@ static char *FormatString(char *buff, co
 
						int32 args[1];
 
						assert(_opt_ptr->units < lengthof(units));
 
						args[0] = GetInt32(&argv) * units[_opt_ptr->units].v_m >> units[_opt_ptr->units].v_s;
 
						buff = FormatString(buff, GetStringPtr(units[_opt_ptr->units].l_volume), args, modifier >> 24);
 
						buff = FormatString(buff, GetStringPtr(units[_opt_ptr->units].l_volume), args, modifier >> 24, last);
 
						modifier = 0;
 
						break;
 
					}
 

	
 
					default:
 
						buff = FormatCommaNumber(buff, GetInt32(&argv));
 
						buff = strecpy(buff, " ", NULL);
 
						buff = strecpy(buff, GetStringPtr(cargo_str), NULL);
 
						buff = FormatCommaNumber(buff, GetInt32(&argv), last);
 
						buff = strecpy(buff, " ", last);
 
						buff = strecpy(buff, GetStringPtr(cargo_str), last);
 
						break;
 
				}
 
			} break;
 
			case 4: {/* {CURRCOMPACT64} */
 
				// 64 bit compact currency-unit
 
				buff = FormatGenericCurrency(buff, _currency, GetInt64(&argv), true);
 
				buff = FormatGenericCurrency(buff, _currency, GetInt64(&argv), true, last);
 
				break;
 
			}
 
			case 5: { /* {STRING1} */
 
				// String that consumes ONE argument
 
				uint str = modifier + GetInt32(&argv);
 
				buff = GetStringWithArgs(buff, str, GetArgvPtr(&argv, 1));
 
				buff = GetStringWithArgs(buff, str, GetArgvPtr(&argv, 1), last);
 
				modifier = 0;
 
				break;
 
			}
 
			case 6: { /* {STRING2} */
 
				// String that consumes TWO arguments
 
				uint str = modifier + GetInt32(&argv);
 
				buff = GetStringWithArgs(buff, str, GetArgvPtr(&argv, 2));
 
				buff = GetStringWithArgs(buff, str, GetArgvPtr(&argv, 2), last);
 
				modifier = 0;
 
				break;
 
			}
 
			case 7: { /* {STRING3} */
 
				// String that consumes THREE arguments
 
				uint str = modifier + GetInt32(&argv);
 
				buff = GetStringWithArgs(buff, str, GetArgvPtr(&argv, 3));
 
				buff = GetStringWithArgs(buff, str, GetArgvPtr(&argv, 3), last);
 
				modifier = 0;
 
				break;
 
			}
 
			case 8: { /* {STRING4} */
 
				// String that consumes FOUR arguments
 
				uint str = modifier + GetInt32(&argv);
 
				buff = GetStringWithArgs(buff, str, GetArgvPtr(&argv, 4));
 
				buff = GetStringWithArgs(buff, str, GetArgvPtr(&argv, 4), last);
 
				modifier = 0;
 
				break;
 
			}
 
			case 9: { /* {STRING5} */
 
				// String that consumes FIVE arguments
 
				uint str = modifier + GetInt32(&argv);
 
				buff = GetStringWithArgs(buff, str, GetArgvPtr(&argv, 5));
 
				buff = GetStringWithArgs(buff, str, GetArgvPtr(&argv, 5), last);
 
				modifier = 0;
 
				break;
 
			}
 

	
 
			case 10: { /* {STATIONFEATURES} */
 
				buff = StationGetSpecialString(buff, GetInt32(&argv));
 
				buff = StationGetSpecialString(buff, GetInt32(&argv), last);
 
				break;
 
			}
 

	
 
@@ -698,7 +698,7 @@ static char *FormatString(char *buff, co
 
				// The string STR_INDUSTRY_PATTERN controls the formatting
 
				args[0] = i->town->index;
 
				args[1] = i->type + STR_4802_COAL_MINE;
 
				buff = FormatString(buff, GetStringPtr(STR_INDUSTRY_FORMAT), args, modifier >> 24);
 
				buff = FormatString(buff, GetStringPtr(STR_INDUSTRY_FORMAT), args, modifier >> 24, last);
 
				modifier = 0;
 
				break;
 
			}
 
@@ -707,7 +707,7 @@ static char *FormatString(char *buff, co
 
				int32 args[1];
 
				assert(_opt_ptr->units < lengthof(units));
 
				args[0] = GetInt32(&argv) * units[_opt_ptr->units].v_m >> units[_opt_ptr->units].v_s;
 
				buff = FormatString(buff, GetStringPtr(units[_opt_ptr->units].l_volume), args, modifier >> 24);
 
				buff = FormatString(buff, GetStringPtr(units[_opt_ptr->units].l_volume), args, modifier >> 24, last);
 
				modifier = 0;
 
				break;
 
			}
 
@@ -723,7 +723,7 @@ static char *FormatString(char *buff, co
 
			}
 

	
 
			case 14: { // {DATE_TINY}
 
				buff = FormatTinyDate(buff, GetInt32(&argv));
 
				buff = FormatTinyDate(buff, GetInt32(&argv), last);
 
				break;
 
			}
 

	
 
@@ -733,7 +733,7 @@ static char *FormatString(char *buff, co
 
				//   16-bit - cargo count
 
				CargoID cargo = GetInt32(&argv);
 
				StringID cargo_str = (cargo == CT_INVALID) ? STR_8838_N_A : _cargoc.names_long[cargo];
 
				buff = GetStringWithArgs(buff, cargo_str, argv++);
 
				buff = GetStringWithArgs(buff, cargo_str, argv++, last);
 
				break;
 
			}
 

	
 
@@ -741,7 +741,7 @@ static char *FormatString(char *buff, co
 
				int32 args[1];
 
				assert(_opt_ptr->units < lengthof(units));
 
				args[0] = GetInt32(&argv) * units[_opt_ptr->units].p_m >> units[_opt_ptr->units].p_s;
 
				buff = FormatString(buff, GetStringPtr(units[_opt_ptr->units].power), args, modifier >> 24);
 
				buff = FormatString(buff, GetStringPtr(units[_opt_ptr->units].power), args, modifier >> 24, last);
 
				modifier = 0;
 
				break;
 
			}
 
@@ -750,7 +750,7 @@ static char *FormatString(char *buff, co
 
				int32 args[1];
 
				assert(_opt_ptr->units < lengthof(units));
 
				args[0] = GetInt32(&argv) * units[_opt_ptr->units].v_m >> units[_opt_ptr->units].v_s;
 
				buff = FormatString(buff, GetStringPtr(units[_opt_ptr->units].s_volume), args, modifier >> 24);
 
				buff = FormatString(buff, GetStringPtr(units[_opt_ptr->units].s_volume), args, modifier >> 24, last);
 
				modifier = 0;
 
				break;
 
			}
 
@@ -759,7 +759,7 @@ static char *FormatString(char *buff, co
 
				int32 args[1];
 
				assert(_opt_ptr->units < lengthof(units));
 
				args[0] = GetInt32(&argv) * units[_opt_ptr->units].w_m >> units[_opt_ptr->units].w_s;
 
				buff = FormatString(buff, GetStringPtr(units[_opt_ptr->units].l_weight), args, modifier >> 24);
 
				buff = FormatString(buff, GetStringPtr(units[_opt_ptr->units].l_weight), args, modifier >> 24, last);
 
				modifier = 0;
 
				break;
 
			}
 
@@ -768,7 +768,7 @@ static char *FormatString(char *buff, co
 
				int32 args[1];
 
				assert(_opt_ptr->units < lengthof(units));
 
				args[0] = GetInt32(&argv) * units[_opt_ptr->units].w_m >> units[_opt_ptr->units].w_s;
 
				buff = FormatString(buff, GetStringPtr(units[_opt_ptr->units].s_weight), args, modifier >> 24);
 
				buff = FormatString(buff, GetStringPtr(units[_opt_ptr->units].s_weight), args, modifier >> 24, last);
 
				modifier = 0;
 
				break;
 
			}
 
@@ -777,7 +777,7 @@ static char *FormatString(char *buff, co
 
				int32 args[1];
 
				assert(_opt_ptr->units < lengthof(units));
 
				args[0] = GetInt32(&argv) * units[_opt_ptr->units].f_m >> units[_opt_ptr->units].f_s;
 
				buff = FormatString(buff, GetStringPtr(units[_opt_ptr->units].force), args, modifier >> 24);
 
				buff = FormatString(buff, GetStringPtr(units[_opt_ptr->units].force), args, modifier >> 24, last);
 
				modifier = 0;
 
				break;
 
			}
 
@@ -802,13 +802,13 @@ static char *FormatString(char *buff, co
 
			// WARNING. It's prohibited for the included string to consume any arguments.
 
			// For included strings that consume argument, you should use STRING1, STRING2 etc.
 
			// To debug stuff you can set argv to NULL and it will tell you
 
			buff = GetStringWithArgs(buff, str, argv);
 
			buff = GetStringWithArgs(buff, str, argv, last);
 
			modifier = 0;
 
			break;
 
		}
 

	
 
		case 0x8B: // {COMMA}
 
			buff = FormatCommaNumber(buff, GetInt32(&argv));
 
			buff = FormatCommaNumber(buff, GetInt32(&argv), last);
 
			break;
 

	
 
		case 0x8C: // Move argument pointer
 
@@ -824,11 +824,11 @@ static char *FormatString(char *buff, co
 
		}
 

	
 
		case 0x8E: // {NUM}
 
			buff = FormatNoCommaNumber(buff, GetInt32(&argv));
 
			buff = FormatNoCommaNumber(buff, GetInt32(&argv), last);
 
			break;
 

	
 
		case 0x8F: // {CURRENCY}
 
			buff = FormatGenericCurrency(buff, _currency, GetInt32(&argv), false);
 
			buff = FormatGenericCurrency(buff, _currency, GetInt32(&argv), false, last);
 
			break;
 

	
 
		case 0x99: { // {WAYPOINT}
 
@@ -842,20 +842,20 @@ static char *FormatString(char *buff, co
 
				temp[1] = wp->town_cn + 1;
 
				str = wp->town_cn == 0 ? STR_WAYPOINTNAME_CITY : STR_WAYPOINTNAME_CITY_SERIAL;
 
			}
 
			buff = GetStringWithArgs(buff, str, temp);
 
			buff = GetStringWithArgs(buff, str, temp, last);
 
		} break;
 

	
 
		case 0x9A: { // {STATION}
 
			const Station* st = GetStation(GetInt32(&argv));
 
			int32 temp[2];
 

	
 
			if (!IsValidStation(st)) { // station doesn't exist anymore
 
				buff = GetStringWithArgs(buff, STR_UNKNOWN_DESTINATION, NULL);
 
				break;
 
				buff = GetStringWithArgs(buff, STR_UNKNOWN_DESTINATION, NULL, last);
 
			} else {
 
				int32 temp[2];
 
				temp[0] = st->town->townnametype;
 
				temp[1] = st->town->townnameparts;
 
				buff = GetStringWithArgs(buff, st->string_id, temp, last);
 
			}
 
			temp[0] = st->town->townnametype;
 
			temp[1] = st->town->townnameparts;
 
			buff = GetStringWithArgs(buff, st->string_id, temp);
 
			break;
 
		}
 
		case 0x9B: { // {TOWN}
 
@@ -865,12 +865,12 @@ static char *FormatString(char *buff, co
 
			assert(IsValidTown(t));
 

	
 
			temp[0] = t->townnameparts;
 
			buff = GetStringWithArgs(buff, t->townnametype, temp);
 
			buff = GetStringWithArgs(buff, t->townnametype, temp, last);
 
			break;
 
		}
 

	
 
		case 0x9C: { // {CURRENCY64}
 
			buff = FormatGenericCurrency(buff, _currency, GetInt64(&argv), false);
 
			buff = FormatGenericCurrency(buff, _currency, GetInt64(&argv), false, last);
 
			break;
 
		}
 

	
 
@@ -899,7 +899,7 @@ static char *FormatString(char *buff, co
 
		}
 

	
 
		default:
 
			*buff++ = b;
 
			if (buff != last) *buff++ = b;
 
		}
 
	}
 
	*buff = '\0';
 
@@ -907,23 +907,22 @@ static char *FormatString(char *buff, co
 
}
 

	
 

	
 
static char *StationGetSpecialString(char *buff, int x)
 
static char *StationGetSpecialString(char *buff, int x, const char* last)
 
{
 
	if (x & 0x01) *buff++ = '\x94';
 
	if (x & 0x02) *buff++ = '\x95';
 
	if (x & 0x04) *buff++ = '\x96';
 
	if (x & 0x08) *buff++ = '\x97';
 
	if (x & 0x10) *buff++ = '\x98';
 
	*buff = '\0';
 
	if (x & 0x01) buff = strecpy(buff, "\x94", last);
 
	if (x & 0x02) buff = strecpy(buff, "\x95", last);
 
	if (x & 0x04) buff = strecpy(buff, "\x96", last);
 
	if (x & 0x08) buff = strecpy(buff, "\x97", last);
 
	if (x & 0x10) buff = strecpy(buff, "\x98", last);
 
	return buff;
 
}
 

	
 
static char *GetSpecialTownNameString(char *buff, int ind, uint32 seed)
 
static char *GetSpecialTownNameString(char *buff, int ind, uint32 seed, const char* last)
 
{
 
	_town_name_generators[ind](buff, seed);
 
	char name[512];
 

	
 
	while (*buff != '\0') buff++;
 
	return buff;
 
	_town_name_generators[ind](name, seed); // TODO
 
	return strecpy(buff, name, last);
 
}
 

	
 
static const char* const _silly_company_names[] = {
 
@@ -994,7 +993,7 @@ static const char _initial_name_letters[
 
	'K', 'L', 'M', 'N', 'P', 'R', 'S', 'T', 'W',
 
};
 

	
 
static char *GenAndCoName(char *buff, uint32 arg)
 
static char *GenAndCoName(char *buff, uint32 arg, const char* last)
 
{
 
	const char* const* base;
 
	uint num;
 
@@ -1007,29 +1006,26 @@ static char *GenAndCoName(char *buff, ui
 
		num  = lengthof(_surname_list);
 
	}
 

	
 
	buff = strecpy(buff, base[num * GB(arg, 16, 8) >> 8], NULL);
 
	buff = strecpy(buff, " & Co.", NULL);
 
	buff = strecpy(buff, base[num * GB(arg, 16, 8) >> 8], last);
 
	buff = strecpy(buff, " & Co.", last);
 

	
 
	return buff;
 
}
 

	
 
static char *GenPresidentName(char *buff, uint32 x)
 
static char *GenPresidentName(char *buff, uint32 x, const char* last)
 
{
 
	char initial[] = "?. ";
 
	const char* const* base;
 
	uint num;
 
	uint i;
 

	
 
	buff[0] = _initial_name_letters[sizeof(_initial_name_letters) * GB(x, 0, 8) >> 8];
 
	buff[1] = '.';
 
	buff[2] = ' '; // Insert a space after initial and period "I. Firstname" instead of "I.Firstname"
 
	buff += 3;
 
	initial[0] = _initial_name_letters[sizeof(_initial_name_letters) * GB(x, 0, 8) >> 8];
 
	buff = strecpy(buff, initial, last);
 

	
 
	i = (sizeof(_initial_name_letters) + 35) * GB(x, 8, 8) >> 8;
 
	if (i < sizeof(_initial_name_letters)) {
 
		buff[0] = _initial_name_letters[i];
 
		buff[1] = '.';
 
		buff[2] = ' '; // Insert a space after initial and period "I. J. Firstname" instead of "I.J.Firstname"
 
		buff += 3;
 
		initial[0] = _initial_name_letters[i];
 
		buff = strecpy(buff, initial, last);
 
	}
 

	
 
	if (_opt_ptr->landscape == LT_CANDY) {
 
@@ -1040,50 +1036,53 @@ static char *GenPresidentName(char *buff
 
		num  = lengthof(_surname_list);
 
	}
 

	
 
	buff = strecpy(buff, base[num * GB(x, 16, 8) >> 8], NULL);
 
	buff = strecpy(buff, base[num * GB(x, 16, 8) >> 8], last);
 

	
 
	return buff;
 
}
 

	
 
static char *GetSpecialPlayerNameString(char *buff, int ind, const int32 *argv)
 
static char *GetSpecialPlayerNameString(char *buff, int ind, const int32 *argv, const char* last)
 
{
 
	switch (ind) {
 
		case 1: // not used
 
			return strecpy(buff, _silly_company_names[GetInt32(&argv) & 0xFFFF], NULL);
 
			return strecpy(buff, _silly_company_names[GetInt32(&argv) & 0xFFFF], last);
 

	
 
		case 2: // used for Foobar & Co company names
 
			return GenAndCoName(buff, GetInt32(&argv));
 
			return GenAndCoName(buff, GetInt32(&argv), last);
 

	
 
		case 3: // President name
 
			return GenPresidentName(buff, GetInt32(&argv));
 
			return GenPresidentName(buff, GetInt32(&argv), last);
 

	
 
		case 4: // song names
 
			return strecpy(buff, origin_songs_specs[GetInt32(&argv) - 1].song_name, NULL);
 
			return strecpy(buff, origin_songs_specs[GetInt32(&argv) - 1].song_name, last);
 
	}
 

	
 
	// town name?
 
	if (IS_INT_INSIDE(ind - 6, 0, SPECSTR_TOWNNAME_LAST-SPECSTR_TOWNNAME_START + 1)) {
 
		buff = GetSpecialTownNameString(buff, ind - 6, GetInt32(&argv));
 
		return strecpy(buff, " Transport", NULL);
 
		buff = GetSpecialTownNameString(buff, ind - 6, GetInt32(&argv), last);
 
		return strecpy(buff, " Transport", last);
 
	}
 

	
 
	// language name?
 
	if (IS_INT_INSIDE(ind, (SPECSTR_LANGUAGE_START - 0x70E4), (SPECSTR_LANGUAGE_END - 0x70E4) + 1)) {
 
		int i = ind - (SPECSTR_LANGUAGE_START - 0x70E4);
 
		return strecpy(buff,
 
			i == _dynlang.curr ? _langpack->own_name : _dynlang.ent[i].name, NULL);
 
			i == _dynlang.curr ? _langpack->own_name : _dynlang.ent[i].name, last);
 
	}
 

	
 
	// resolution size?
 
	if (IS_INT_INSIDE(ind, (SPECSTR_RESOLUTION_START - 0x70E4), (SPECSTR_RESOLUTION_END - 0x70E4) + 1)) {
 
		int i = ind - (SPECSTR_RESOLUTION_START - 0x70E4);
 
		return buff + sprintf(buff, "%dx%d", _resolutions[i][0], _resolutions[i][1]);
 
		buff += snprintf(
 
			buff, last - buff + 1, "%dx%d", _resolutions[i][0], _resolutions[i][1]
 
		);
 
		return buff;
 
	}
 

	
 
	// screenshot format name?
 
	if (IS_INT_INSIDE(ind, (SPECSTR_SCREENSHOT_START - 0x70E4), (SPECSTR_SCREENSHOT_END - 0x70E4) + 1)) {
 
		int i = ind - (SPECSTR_SCREENSHOT_START - 0x70E4);
 
		return strecpy(buff, GetScreenshotFormatDesc(i), NULL);
 
		return strecpy(buff, GetScreenshotFormatDesc(i), last);
 
	}
 

	
 
	assert(0);
strings.h
Show inline comments
 
@@ -11,7 +11,7 @@ static inline char* InlineString(char* b
 
	return buf;
 
}
 

	
 
char *GetString(char *buffr, uint16 string);
 
char *GetString(char *buffr, uint16 string, const char* last);
 

	
 
extern char _userstring[128];
 

	
texteff.c
Show inline comments
 
@@ -246,7 +246,7 @@ void AddTextEffect(StringID msg, int x, 
 
	te->params_1 = GetDParam(0);
 
	te->params_2 = GetDParam(4);
 

	
 
	GetString(buffer, msg);
 
	GetString(buffer, msg, lastof(buffer));
 
	w = GetStringBoundingBox(buffer).width;
 

	
 
	te->x = x - (w >> 1);
town_cmd.c
Show inline comments
 
@@ -886,7 +886,7 @@ restart:
 
		r = Random();
 

	
 
		SetDParam(0, r);
 
		GetString(buf1, townnametype);
 
		GetString(buf1, townnametype, lastof(buf1));
 

	
 
		// Check size and width
 
		if (strlen(buf1) >= 31 || GetStringBoundingBox(buf1).width > 130) continue;
 
@@ -895,7 +895,7 @@ restart:
 
			// We can't just compare the numbers since
 
			// several numbers may map to a single name.
 
			SetDParam(0, t2->index);
 
			GetString(buf2, STR_TOWN);
 
			GetString(buf2, STR_TOWN, lastof(buf2));
 
			if (strcmp(buf1, buf2) == 0) {
 
				if (tries-- < 0) return false;
 
				goto restart;
town_gui.c
Show inline comments
 
@@ -378,7 +378,7 @@ static int CDECL TownNameSorter(const vo
 
	int r;
 

	
 
	SetDParam(0, ta->index);
 
	GetString(buf1, STR_TOWN);
 
	GetString(buf1, STR_TOWN, lastof(buf1));
 

	
 
	/* If 'b' is the same town as in the last round, use the cached value
 
	 *  We do this to speed stuff up ('b' is called with the same value a lot of
 
@@ -386,7 +386,7 @@ static int CDECL TownNameSorter(const vo
 
	if (tb != _last_town) {
 
		_last_town = tb;
 
		SetDParam(0, tb->index);
 
		GetString(_bufcache, STR_TOWN);
 
		GetString(_bufcache, STR_TOWN, lastof(_bufcache));
 
	}
 

	
 
	r = strcmp(buf1, _bufcache);
train_gui.c
Show inline comments
 
@@ -135,13 +135,13 @@ static int CDECL TrainEngineNameSorter(c
 
	char buf1[64];
 
	int r;
 

	
 
	GetString(buf1, GetCustomEngineName(va));
 
	GetString(buf1, GetCustomEngineName(va), lastof(buf1));
 

	
 
	if (vb != _last_engine) {
 
		_last_engine = vb;
 
		_bufcache[0] = '\0';
 

	
 
		GetString(_bufcache, GetCustomEngineName(vb));
 
		GetString(_bufcache, GetCustomEngineName(vb), lastof(_bufcache));
 
	}
 

	
 
	r =  strcasecmp(buf1, _bufcache); // sort by name
vehicle.c
Show inline comments
 
@@ -2076,7 +2076,7 @@ static int32 ReplaceVehicle(Vehicle **w,
 
		if (!IsCustomName(old_v->string_id)) {
 
			vehicle_name[0] = '\0';
 
		} else {
 
			GetName(old_v->string_id & 0x7FF, vehicle_name);
 
			GetName(vehicle_name, old_v->string_id & 0x7FF, lastof(vehicle_name));
 
		}
 
	} else { // flags & DC_EXEC not set
 
		/* Ensure that the player will not end up having negative money while autoreplacing
vehicle_gui.c
Show inline comments
 
@@ -516,7 +516,7 @@ static int CDECL VehicleNameSorter(const
 
	if (va != last_vehicle[0]) {
 
		last_vehicle[0] = va;
 
		if (IsCustomName(va->string_id)) {
 
			GetString(last_name[0], va->string_id);
 
			GetString(last_name[0], va->string_id, lastof(last_name[0]));
 
		} else {
 
			last_name[0][0] = '\0';
 
		}
 
@@ -525,7 +525,7 @@ static int CDECL VehicleNameSorter(const
 
	if (vb != last_vehicle[1]) {
 
		last_vehicle[1] = vb;
 
		if (IsCustomName(vb->string_id)) {
 
			GetString(last_name[1], vb->string_id);
 
			GetString(last_name[1], vb->string_id, lastof(last_name[1]));
 
		} else {
 
			last_name[1][0] = '\0';
 
		}
viewport.c
Show inline comments
 
@@ -1017,7 +1017,7 @@ void UpdateViewportSignPos(ViewportSign 
 

	
 
	sign->top = top;
 

	
 
	GetString(buffer, str);
 
	GetString(buffer, str, lastof(buffer));
 
	w = GetStringBoundingBox(buffer).width + 3;
 
	sign->width_1 = w;
 
	sign->left = left - w / 2;
0 comments (0 inline, 0 general)