diff --git a/src/ai/api/ai_tile.hpp b/src/ai/api/ai_tile.hpp
index d50fb54eea..7832384d81 100644
--- a/src/ai/api/ai_tile.hpp
+++ b/src/ai/api/ai_tile.hpp
@@ -340,7 +340,10 @@ public:
/**
* Raise the given corners of the tile. The corners can be combined,
- * for example: SLOPE_N | SLOPE_W (= SLOPE_NW)
+ * for example: SLOPE_N | SLOPE_W (= SLOPE_NW) will raise the west and the north corner.
+ * @note The corners will be modified in the order west (first), south, east, north (last).
+ * Changing one corner might cause another corner to be changed too. So modifiing
+ * multiple corners may result in changing some corners by multiple steps.
* @param tile The tile to raise.
* @param slope Corners to raise (SLOPE_xxx).
* @pre tile < AIMap::GetMapSize().
@@ -353,7 +356,10 @@ public:
/**
* Lower the given corners of the tile. The corners can be combined,
- * for example: SLOPE_N | SLOPE_W (= SLOPE_NW)
+ * for example: SLOPE_N | SLOPE_W (= SLOPE_NW) will lower the west and the north corner.
+ * @note The corners will be modified in the order west (first), south, east, north (last).
+ * Changing one corner might cause another corner to be changed too. So modifiing
+ * multiple corners may result in changing some corners by multiple steps.
* @param tile The tile to lower.
* @param slope Corners to lower (SLOPE_xxx).
* @pre tile < AIMap::GetMapSize().
diff --git a/src/ai/api/ai_types.hpp b/src/ai/api/ai_types.hpp
index 2ccd1d27d8..7057c319f6 100644
--- a/src/ai/api/ai_types.hpp
+++ b/src/ai/api/ai_types.hpp
@@ -1,6 +1,75 @@
/* $Id$ */
-/** @file ai_types.hpp Defines all the types of the game, like VehicleID, .... */
+/** @file ai_types.hpp Defines all the types of the game, like IDs of various objects.
+ *
+ * IDs are used to identify certain objects. They are only unique within the object type, so for example a vehicle may have VehicleID 2009,
+ * while a station has StationID 2009 at the same time. Also IDs are assigned arbitrary, you cannot assume them to be consecutive.
+ * Also note, that some IDs are static and never change, while others are allocated dynamically and might be
+ * reused for other objects once they are released. So be careful, which IDs you store for which purpose and whether they stay valid all the time.
+ *
+ *
+ * type | object |
+ * acquired |
+ * released |
+ * reused |
+ * #BridgeID | bridge type |
+ * introduction \ref newgrf_changes "(1)" |
+ * never \ref newgrf_changes "(1)" |
+ * no \ref newgrf_changes "(1)" |
+ * #CargoID | cargo type |
+ * game start \ref newgrf_changes "(1)" |
+ * never \ref newgrf_changes "(1)" |
+ * no \ref newgrf_changes "(1)" |
+ * #EngineID | engine type |
+ * introduction, preview \ref dynamic_engines "(2)" |
+ * engines retires \ref dynamic_engines "(2)" |
+ * no \ref dynamic_engines "(2)" |
+ * #GroupID | vehicle group |
+ * creation |
+ * deletion |
+ * yes |
+ * #IndustyID | industry |
+ * construction |
+ * closure |
+ * yes |
+ * #IndustyType | industry type |
+ * game start \ref newgrf_changes "(1)" |
+ * never \ref newgrf_changes "(1)" |
+ * no |
+ * #SignID | sign |
+ * construction |
+ * deletion |
+ * yes |
+ * #StationID | station |
+ * construction |
+ * expiration of 'grey' station sign after deletion |
+ * yes |
+ * #SubsidyID | subsidy |
+ * offer announcement |
+ * (offer) expiration |
+ * yes |
+ * #TileIndex | tile on map |
+ * game start |
+ * never |
+ * no |
+ * #TownID | town |
+ * game start |
+ * never |
+ * no |
+ * #VehicleID | vehicle |
+ * construction, autorenew, autoreplace |
+ * destruction, autorenew, autoreplace |
+ * yes |
+ * #WaypointID | waypoint |
+ * construction |
+ * destruction |
+ * yes |
+ *
+ *
+ * @remarks
+ * \li \anchor newgrf_changes (1) in-game changes of newgrfs may reassign/invalidate IDs (will also cause other trouble though).
+ * \li \anchor dynamic_engines (2) engine IDs are reassigned/invalidated on changing 'allow multiple newgrf engine sets' (only allowed as long as no vehicles are built).
+ */
#ifndef AI_TYPES_HPP
#define AI_TYPES_HPP
diff --git a/src/console.cpp b/src/console.cpp
index 161a7b1791..2f9553aa02 100644
--- a/src/console.cpp
+++ b/src/console.cpp
@@ -116,13 +116,13 @@ void IConsolePrint(ConsoleColour colour_code, const char *string)
* by any other means. Uses printf() style format, for more information look
* at IConsolePrint()
*/
-void CDECL IConsolePrintF(ConsoleColour colour_code, const char *s, ...)
+void CDECL IConsolePrintF(ConsoleColour colour_code, const char *format, ...)
{
va_list va;
char buf[ICON_MAX_STREAMSIZE];
- va_start(va, s);
- vsnprintf(buf, sizeof(buf), s, va);
+ va_start(va, format);
+ vsnprintf(buf, sizeof(buf), format, va);
va_end(va);
IConsolePrint(colour_code, buf);
diff --git a/src/console_cmds.cpp b/src/console_cmds.cpp
index e15ec5ef6a..058aa77df9 100644
--- a/src/console_cmds.cpp
+++ b/src/console_cmds.cpp
@@ -1199,7 +1199,7 @@ DEF_CONSOLE_CMD(ConInfoVar)
IConsolePrintF(CC_DEFAULT, "variable name: %s", var->name);
IConsolePrintF(CC_DEFAULT, "variable type: %s", _icon_vartypes[var->type]);
- IConsolePrintF(CC_DEFAULT, "variable addr: 0x%X", var->addr);
+ IConsolePrintF(CC_DEFAULT, "variable addr: %p", var->addr);
if (var->hook.access) IConsoleWarning("variable is access hooked");
if (var->hook.pre) IConsoleWarning("variable is pre hooked");
@@ -1226,7 +1226,7 @@ DEF_CONSOLE_CMD(ConInfoCmd)
}
IConsolePrintF(CC_DEFAULT, "command name: %s", cmd->name);
- IConsolePrintF(CC_DEFAULT, "command proc: 0x%X", cmd->proc);
+ IConsolePrintF(CC_DEFAULT, "command proc: %p", cmd->proc);
if (cmd->hook.access) IConsoleWarning("command is access hooked");
if (cmd->hook.pre) IConsoleWarning("command is pre hooked");
@@ -1431,7 +1431,7 @@ DEF_CONSOLE_CMD(ConCompanies)
const NetworkCompanyStats *stats = &company_stats[c->index];
GetString(buffer, STR_00D1_DARK_BLUE + _company_colours[c->index], lastof(buffer));
- IConsolePrintF(CC_INFO, "#:%d(%s) Company Name: '%s' Year Founded: %d Money: %" OTTD_PRINTF64 "d Loan: %" OTTD_PRINTF64 "d Value: %" OTTD_PRINTF64 "d (T:%d, R:%d, P:%d, S:%d) %sprotected",
+ IConsolePrintF(CC_INFO, "#:%d(%s) Company Name: '%s' Year Founded: %d Money: " OTTD_PRINTF64 " Loan: " OTTD_PRINTF64 " Value: " OTTD_PRINTF64 " (T:%d, R:%d, P:%d, S:%d) %sprotected",
c->index + 1, buffer, company_name, c->inaugurated_year, (int64)c->money, (int64)c->current_loan, (int64)CalculateCompanyValue(c),
/* trains */ stats->num_vehicle[0],
/* lorry + bus */ stats->num_vehicle[1] + stats->num_vehicle[2],
diff --git a/src/console_func.h b/src/console_func.h
index 60fc7010c3..5487e3819d 100644
--- a/src/console_func.h
+++ b/src/console_func.h
@@ -17,7 +17,7 @@ void IConsoleClose();
/* console output */
void IConsolePrint(ConsoleColour colour_code, const char *string);
-void CDECL IConsolePrintF(ConsoleColour colour_code, const char *s, ...);
+void CDECL IConsolePrintF(ConsoleColour colour_code, const char *format, ...) WARN_FORMAT(2, 3);
void IConsoleDebug(const char *dbg, const char *string);
void IConsoleWarning(const char *string);
void IConsoleError(const char *string);
diff --git a/src/core/alloc_func.cpp b/src/core/alloc_func.cpp
index 028335d761..236a9c9d59 100644
--- a/src/core/alloc_func.cpp
+++ b/src/core/alloc_func.cpp
@@ -11,7 +11,7 @@
*/
void NORETURN MallocError(size_t size)
{
- error("Out of memory. Cannot allocate %i bytes", size);
+ error("Out of memory. Cannot allocate " PRINTF_SIZE " bytes", size);
}
/**
@@ -20,5 +20,5 @@ void NORETURN MallocError(size_t size)
*/
void NORETURN ReallocError(size_t size)
{
- error("Out of memory. Cannot reallocate %i bytes", size);
+ error("Out of memory. Cannot reallocate " PRINTF_SIZE " bytes", size);
}
diff --git a/src/debug.cpp b/src/debug.cpp
index 7717749f0c..7b369603e5 100644
--- a/src/debug.cpp
+++ b/src/debug.cpp
@@ -92,15 +92,13 @@ static void debug_print(const char *dbg, const char *buf)
}
}
-void CDECL debug(const char *dbg, ...)
+void CDECL debug(const char *dbg, const char *format, ...)
{
- va_list va;
- va_start(va, dbg);
- const char *s;
char buf[1024];
- s = va_arg(va, const char*);
- vsnprintf(buf, lengthof(buf), s, va);
+ va_list va;
+ va_start(va, format);
+ vsnprintf(buf, lengthof(buf), format, va);
va_end(va);
debug_print(dbg, buf);
@@ -149,7 +147,7 @@ void SetDebugString(const char *s)
if (p != NULL) {
*p = v;
} else {
- ShowInfoF("Unknown debug level '%.*s'", s - t, t);
+ ShowInfoF("Unknown debug level '%.*s'", (int)(s - t), t);
return;
}
}
diff --git a/src/debug.h b/src/debug.h
index c7a71c67a1..b21cd6434d 100644
--- a/src/debug.h
+++ b/src/debug.h
@@ -50,19 +50,12 @@
extern int _debug_gamelog_level;
extern int _debug_desync_level;
- void CDECL debug(const char *dbg, ...);
+ void CDECL debug(const char *dbg, const char *format, ...) WARN_FORMAT(2, 3);
#endif /* NO_DEBUG_MESSAGES */
void SetDebugString(const char *s);
const char *GetDebugString();
-/* MSVCRT of course has to have a different syntax for long long *sigh* */
-#if defined(_MSC_VER) || defined(__MINGW32__)
- #define OTTD_PRINTF64 "I64"
-#else
- #define OTTD_PRINTF64 "ll"
-#endif
-
/* Used for profiling
*
* Usage:
@@ -100,6 +93,6 @@ const char *GetDebugString();
}
void ShowInfo(const char *str);
-void CDECL ShowInfoF(const char *str, ...);
+void CDECL ShowInfoF(const char *str, ...) WARN_FORMAT(1, 2);
#endif /* DEBUG_H */
diff --git a/src/fileio.cpp b/src/fileio.cpp
index 8252f5b905..ff165d6f61 100644
--- a/src/fileio.cpp
+++ b/src/fileio.cpp
@@ -595,7 +595,7 @@ bool TarListAddFile(const char *filename)
/* Calculate the size of the file.. for some strange reason this is stored as a string */
memcpy(buf, th.size, sizeof(th.size));
buf[sizeof(th.size)] = '\0';
- int skip = strtol(buf, &end, 8);
+ size_t skip = strtoul(buf, &end, 8);
switch (th.typeflag) {
case '\0':
@@ -614,7 +614,7 @@ bool TarListAddFile(const char *filename)
/* Convert to lowercase and our PATHSEPCHAR */
SimplifyFileName(name);
- DEBUG(misc, 6, "Found file in tar: %s (%d bytes, %d offset)", name, skip, pos);
+ DEBUG(misc, 6, "Found file in tar: %s (" PRINTF_SIZE " bytes, " PRINTF_SIZE " offset)", name, skip, pos);
if (_tar_filelist.insert(TarFileList::value_type(name, entry)).second) num++;
break;
@@ -702,7 +702,7 @@ bool TarListAddFile(const char *filename)
pos += skip;
}
- DEBUG(misc, 1, "Found tar '%s' with %d new files", filename, num);
+ DEBUG(misc, 1, "Found tar '%s' with " PRINTF_SIZE " new files", filename, num);
fclose(f);
/* Resolve file links and store directory links.
diff --git a/src/gamelog.cpp b/src/gamelog.cpp
index e47a19f0a2..55b6a7468e 100644
--- a/src/gamelog.cpp
+++ b/src/gamelog.cpp
@@ -85,6 +85,8 @@ enum {
static int _dbgofs = 0; ///< offset in current output buffer
+static void AddDebugText(char *buf, const char *s, ...) WARN_FORMAT(2, 3);
+
static void AddDebugText(char *buf, const char *s, ...)
{
if (GAMELOG_BUF_LEN <= _dbgofs) return;
@@ -277,7 +279,7 @@ static int _gamelog_print_level = 0; ///< gamelog debug level we need to print s
static void GamelogPrintDebugProc(const char *s)
{
- DEBUG(gamelog, _gamelog_print_level, s);
+ DEBUG(gamelog, _gamelog_print_level, "%s", s);
}
diff --git a/src/gfxinit.cpp b/src/gfxinit.cpp
index 9dad75aa3e..d63d2429f4 100644
--- a/src/gfxinit.cpp
+++ b/src/gfxinit.cpp
@@ -250,7 +250,7 @@ void CheckExternalFiles()
add_pos += seprintf(add_pos, last, "Your 'sample.cat' file is corrupted or missing! You can find 'sample.cat' on your Transport Tycoon Deluxe CD-ROM.\n");
}
- if (add_pos != error_msg) ShowInfoF(error_msg);
+ if (add_pos != error_msg) ShowInfoF("%s", error_msg);
}
diff --git a/src/network/network_command.cpp b/src/network/network_command.cpp
index 36a3a11363..9dc483a8f2 100644
--- a/src/network/network_command.cpp
+++ b/src/network/network_command.cpp
@@ -179,7 +179,7 @@ void NetworkClientSocket::Send_Command(Packet *p, const CommandPacket *cp)
}
if (callback == _callback_table_count) {
- DEBUG(net, 0, "Unknown callback. (Pointer: %p) No callback sent", callback);
+ DEBUG(net, 0, "Unknown callback. (Pointer: %p) No callback sent", cp->callback);
callback = 0; // _callback_table[0] == NULL
}
p->Send_uint8 (callback);
diff --git a/src/network/network_func.h b/src/network/network_func.h
index af4a7d5770..e121d6744b 100644
--- a/src/network/network_func.h
+++ b/src/network/network_func.h
@@ -72,7 +72,7 @@ void NetworkServerKickClient(ClientID client_id);
void NetworkServerBanIP(const char *banip);
void NetworkInitChatMessage();
-void CDECL NetworkAddChatMessage(TextColour colour, uint8 duration, const char *message, ...);
+void CDECL NetworkAddChatMessage(TextColour colour, uint8 duration, const char *message, ...) WARN_FORMAT(3, 4);
void NetworkUndrawChatMessage();
void NetworkChatMessageDailyLoop();
diff --git a/src/newgrf.cpp b/src/newgrf.cpp
index 40c247e6cc..427c044fd8 100644
--- a/src/newgrf.cpp
+++ b/src/newgrf.cpp
@@ -150,7 +150,7 @@ void CDECL grfmsg(int severity, const char *str, ...)
static inline bool check_length(size_t real, size_t wanted, const char *str)
{
if (real >= wanted) return true;
- grfmsg(0, "%s: Invalid pseudo sprite length %d (expected %d)!", str, real, wanted);
+ grfmsg(0, "%s: Invalid pseudo sprite length " PRINTF_SIZE " (expected " PRINTF_SIZE ")!", str, real, wanted);
return false;
}
@@ -4226,7 +4226,7 @@ static void GRFInfo(byte *buf, size_t len)
_cur_grfconfig->status = _cur_stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED;
/* Do swap the GRFID for displaying purposes since people expect that */
- DEBUG(grf, 1, "GRFInfo: Loaded GRFv%d set %08lX - %s (palette: %s)", version, BSWAP32(grfid), name, _cur_grfconfig->windows_paletted ? "Windows" : "DOS");
+ DEBUG(grf, 1, "GRFInfo: Loaded GRFv%d set %08X - %s (palette: %s)", version, BSWAP32(grfid), name, _cur_grfconfig->windows_paletted ? "Windows" : "DOS");
}
/* Action 0x0A */
@@ -4403,7 +4403,7 @@ static void GRFComment(byte *buf, size_t len)
size_t text_len = len - 1;
const char *text = (const char*)(buf + 1);
- grfmsg(2, "GRFComment: %.*s", text_len, text);
+ grfmsg(2, "GRFComment: %.*s", (int)text_len, text);
}
/* Action 0x0D (GLS_SAFETYSCAN) */
@@ -4945,7 +4945,7 @@ static void FeatureTownName(byte *buf, size_t len)
if (!check_length(len, 1, "FeatureTownName: number of parts")) return;
byte nb = grf_load_byte(&buf);
len--;
- grfmsg(6, "FeatureTownName: %d parts", nb, nb);
+ grfmsg(6, "FeatureTownName: %u parts", nb);
townname->nbparts[id] = nb;
townname->partlist[id] = CallocT(nb);
diff --git a/src/newgrf.h b/src/newgrf.h
index dc9e1e67d8..e05ef89fe1 100644
--- a/src/newgrf.h
+++ b/src/newgrf.h
@@ -129,7 +129,7 @@ void LoadNewGRFFile(GRFConfig *config, uint file_index, GrfLoadingStage stage);
void LoadNewGRF(uint load_index, uint file_index);
void ReloadNewGRFData(); // in saveload/afterload.cpp
-void CDECL grfmsg(int severity, const char *str, ...);
+void CDECL grfmsg(int severity, const char *str, ...) WARN_FORMAT(2, 3);
bool HasGrfMiscBit(GrfMiscBit bit);
bool GetGlobalVariable(byte param, uint32 *value);
diff --git a/src/newgrf_engine.cpp b/src/newgrf_engine.cpp
index 1f19b2f014..43855a4350 100644
--- a/src/newgrf_engine.cpp
+++ b/src/newgrf_engine.cpp
@@ -803,7 +803,7 @@ static uint32 VehicleGetVariable(const ResolverObject *object, byte variable, by
default: break;
}
- DEBUG(grf, 1, "Unhandled vehicle property 0x%X, type 0x%X", variable, v->type);
+ DEBUG(grf, 1, "Unhandled vehicle property 0x%X, type 0x%X", variable, (uint)v->type);
*available = false;
return UINT_MAX;
diff --git a/src/saveload/saveload.cpp b/src/saveload/saveload.cpp
index e8030896e8..9616ae54ee 100644
--- a/src/saveload/saveload.cpp
+++ b/src/saveload/saveload.cpp
@@ -1627,7 +1627,7 @@ static SaveOrLoadResult SaveFileToDisk(bool threaded)
if (_sl.excpt_uninit != NULL) _sl.excpt_uninit();
/* Skip the "colour" character */
- DEBUG(sl, 0, GetSaveLoadErrorString() + 3);
+ DEBUG(sl, 0, "%s", GetSaveLoadErrorString() + 3);
if (threaded) {
SetAsyncSaveFinish(SaveFileError);
@@ -1827,7 +1827,7 @@ SaveOrLoadResult SaveOrLoad(const char *filename, int mode, Subdirectory sb)
if (_sl.excpt_uninit != NULL) _sl.excpt_uninit();
/* Skip the "colour" character */
- DEBUG(sl, 0, GetSaveLoadErrorString() + 3);
+ DEBUG(sl, 0, "%s", GetSaveLoadErrorString() + 3);
/* A saver/loader exception!! reinitialize all variables to prevent crash! */
return (mode == SL_LOAD) ? SL_REINIT : SL_ERROR;
diff --git a/src/spritecache.cpp b/src/spritecache.cpp
index 20c52104af..990f407262 100644
--- a/src/spritecache.cpp
+++ b/src/spritecache.cpp
@@ -52,7 +52,7 @@ static SpriteCache *AllocateSpriteCache(uint index)
/* Add another 1024 items to the 'pool' */
uint items = Align(index + 1, 1024);
- DEBUG(sprite, 4, "Increasing sprite cache to %d items (%d bytes)", items, items * sizeof(*_spritecache));
+ DEBUG(sprite, 4, "Increasing sprite cache to %u items (" PRINTF_SIZE " bytes)", items, items * sizeof(*_spritecache));
_spritecache = ReallocT(_spritecache, items);
@@ -333,7 +333,7 @@ void IncreaseSpriteLRU()
if (_sprite_lru_counter > 16384) {
SpriteID i;
- DEBUG(sprite, 3, "Fixing lru %d, inuse=%d", _sprite_lru_counter, GetSpriteCacheUsage());
+ DEBUG(sprite, 3, "Fixing lru %u, inuse=" PRINTF_SIZE, _sprite_lru_counter, GetSpriteCacheUsage());
for (i = 0; i != _spritecache_items; i++) {
SpriteCache *sc = GetSpriteCache(i);
@@ -361,7 +361,7 @@ static void CompactSpriteCache()
{
MemBlock *s;
- DEBUG(sprite, 3, "Compacting sprite cache, inuse=%d", GetSpriteCacheUsage());
+ DEBUG(sprite, 3, "Compacting sprite cache, inuse=" PRINTF_SIZE, GetSpriteCacheUsage());
for (s = _spritecache_ptr; s->size != 0;) {
if (s->size & S_FREE_MASK) {
@@ -404,7 +404,7 @@ static void DeleteEntryFromSpriteCache()
MemBlock *s;
int cur_lru;
- DEBUG(sprite, 3, "DeleteEntryFromSpriteCache, inuse=%d", GetSpriteCacheUsage());
+ DEBUG(sprite, 3, "DeleteEntryFromSpriteCache, inuse=" PRINTF_SIZE, GetSpriteCacheUsage());
cur_lru = 0xffff;
for (i = 0; i != _spritecache_items; i++) {
diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp
index e6313a7b34..6a48081af1 100644
--- a/src/station_cmd.cpp
+++ b/src/station_cmd.cpp
@@ -2963,6 +2963,9 @@ void FindStationsAroundTiles(TileIndex tile, int w_prod, int h_prod, StationList
uint MoveGoodsToStation(TileIndex tile, int w, int h, CargoID type, uint amount)
{
+ /* Return if nothing to do. Also the rounding below fails for 0. */
+ if (amount == 0) return 0;
+
Station *st1 = NULL; // Station with best rating
Station *st2 = NULL; // Second best station
uint best_rating1 = 0; // rating of st1
diff --git a/src/stdafx.h b/src/stdafx.h
index 619fa81e71..a0ce63bdd2 100644
--- a/src/stdafx.h
+++ b/src/stdafx.h
@@ -126,6 +126,9 @@
#define CDECL
#define __int64 long long
#define GCC_PACK __attribute__((packed))
+ /* Warn about functions using 'printf' format syntax. First argument determines which parameter
+ * is the format string, second argument is start of values passed to printf. */
+ #define WARN_FORMAT(string, args) __attribute__ ((format (printf, string, args)))
#if (__GNUC__ == 2)
#undef VARARRAY_SIZE
@@ -138,6 +141,7 @@
#define FORCEINLINE inline
#define CDECL
#define GCC_PACK
+ #define WARN_FORMAT(string, args)
#include
#endif /* __WATCOMC__ */
@@ -177,6 +181,7 @@
#pragma warning(disable: 6031) // code analyzer: Return value ignored: 'ReadFile'
#pragma warning(disable: 6255) // code analyzer: _alloca indicates failure by raising a stack overflow exception. Consider using _malloca instead
#pragma warning(disable: 6246) // code analyzer: Local declaration of 'statspec' hides declaration of the same name in outer scope. For additional information, see previous declaration at ...
+ #define WARN_FORMAT(string, args)
#include // alloca()
#define NORETURN __declspec(noreturn)
@@ -187,7 +192,7 @@
#define CDECL _cdecl
#endif
- int CDECL snprintf(char *str, size_t size, const char *format, ...);
+ int CDECL snprintf(char *str, size_t size, const char *format, ...) WARN_FORMAT(3, 4);
#if defined(WINCE)
int CDECL vsnprintf(char *str, size_t size, const char *format, va_list ap);
#endif
@@ -224,7 +229,7 @@
#define strncasecmp strnicmp
#endif
- void SetExceptionString(const char *s, ...);
+ void SetExceptionString(const char *s, ...) WARN_FORMAT(1, 2);
#if defined(NDEBUG) && defined(WITH_ASSERT)
#undef assert
@@ -272,6 +277,15 @@
#define PATHSEPCHAR '/'
#endif
+/* MSVCRT of course has to have a different syntax for long long *sigh* */
+#if defined(_MSC_VER) || defined(__MINGW32__)
+ #define OTTD_PRINTF64 "%I64d"
+ #define PRINTF_SIZE "%Iu"
+#else
+ #define OTTD_PRINTF64 "%lld"
+ #define PRINTF_SIZE "%zu"
+#endif
+
typedef unsigned char byte;
/* This is already defined in unix, but not in QNX Neutrino (6.x)*/
@@ -346,8 +360,8 @@ assert_compile(sizeof(uint8) == 1);
#define CloseConnection OTTD_CloseConnection
#endif /* __APPLE__ */
-void NORETURN CDECL usererror(const char *str, ...);
-void NORETURN CDECL error(const char *str, ...);
+void NORETURN CDECL usererror(const char *str, ...) WARN_FORMAT(1, 2);
+void NORETURN CDECL error(const char *str, ...) WARN_FORMAT(1, 2);
#define NOT_REACHED() error("NOT_REACHED triggered at line %i of %s", __LINE__, __FILE__)
#if defined(MORPHOS) || defined(__NDS__) || defined(__DJGPP__)
diff --git a/src/strgen/strgen.cpp b/src/strgen/strgen.cpp
index b769d55fef..11373edd80 100644
--- a/src/strgen/strgen.cpp
+++ b/src/strgen/strgen.cpp
@@ -151,6 +151,8 @@ static LangString *HashFind(const char *s)
# define LINE_NUM_FMT ":%d"
#endif
+static void CDECL strgen_warning(const char *s, ...) WARN_FORMAT(1, 2);
+
static void CDECL strgen_warning(const char *s, ...)
{
char buf[1024];
@@ -162,6 +164,8 @@ static void CDECL strgen_warning(const char *s, ...)
_warnings++;
}
+static void CDECL strgen_error(const char *s, ...) WARN_FORMAT(1, 2);
+
static void CDECL strgen_error(const char *s, ...)
{
char buf[1024];
@@ -598,7 +602,7 @@ static const CmdStruct *ParseCommandString(const char **str, char *param, int *a
cmd = FindCmd(start, s - start - 1);
if (cmd == NULL) {
- strgen_error("Undefined command '%.*s'", s - start - 1, start);
+ strgen_error("Undefined command '%.*s'", (int)(s - start - 1), start);
return NULL;
}
@@ -729,7 +733,7 @@ static void ExtractCommandString(ParsedCommandStruct *p, const char *s, bool war
p->cmd[argidx++] = ar;
} else if (!(ar->flags & C_DONTCOUNT)) { // Ignore some of them
- if (p->np >= lengthof(p->pairs)) error("too many commands in string, max %d", lengthof(p->pairs));
+ if (p->np >= lengthof(p->pairs)) error("too many commands in string, max " PRINTF_SIZE, lengthof(p->pairs));
p->pairs[p->np].a = ar;
p->pairs[p->np].v = param[0] != '\0' ? strdup(param) : "";
p->np++;
@@ -863,7 +867,7 @@ static void HandleString(char *str, bool master)
if (ent == NULL) {
if (_strings[_next_string_id]) {
- strgen_error("String ID 0x%X for '%s' already in use by '%s'", ent, str, _strings[_next_string_id]->name);
+ strgen_error("String ID 0x%X for '%s' already in use by '%s'", _next_string_id, str, _strings[_next_string_id]->name);
return;
}
diff --git a/src/string_func.h b/src/string_func.h
index ae5903bf10..10203047b4 100644
--- a/src/string_func.h
+++ b/src/string_func.h
@@ -89,9 +89,9 @@ char *strecat(char *dst, const char *src, const char *last);
*/
char *strecpy(char *dst, const char *src, const char *last);
-int CDECL seprintf(char *str, const char *last, const char *format, ...);
+int CDECL seprintf(char *str, const char *last, const char *format, ...) WARN_FORMAT(3, 4);
-char *CDECL str_fmt(const char *str, ...);
+char *CDECL str_fmt(const char *str, ...) WARN_FORMAT(1, 2);
/**
* Scans the string for valid characters and if it finds invalid ones,
diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp
index 30ddd67f08..d44b86a07c 100644
--- a/src/town_cmd.cpp
+++ b/src/town_cmd.cpp
@@ -455,6 +455,8 @@ static void TileLoop_Town(TileIndex tile)
if (cargo == CT_INVALID) continue;
uint amt = GB(callback, 0, 8);
+ if (amt == 0) continue;
+
uint moved = MoveGoodsToStation(tile, 1, 1, cargo, amt);
const CargoSpec *cs = GetCargo(cargo);
diff --git a/src/win32.cpp b/src/win32.cpp
index 066ea628bc..471801e93a 100644
--- a/src/win32.cpp
+++ b/src/win32.cpp
@@ -1082,13 +1082,13 @@ void DetermineBasePaths(const char *exe)
_searchpaths[SP_WORKING_DIR] = strdup(tmp);
if (!GetModuleFileName(NULL, path, lengthof(path))) {
- DEBUG(misc, 0, "GetModuleFileName failed (%d)\n", GetLastError());
+ DEBUG(misc, 0, "GetModuleFileName failed (%lu)\n", GetLastError());
_searchpaths[SP_BINARY_DIR] = NULL;
} else {
TCHAR exec_dir[MAX_PATH];
_tcsncpy(path, MB_TO_WIDE_BUFFER(exe, path, lengthof(path)), lengthof(path));
if (!GetFullPathName(path, lengthof(exec_dir), exec_dir, NULL)) {
- DEBUG(misc, 0, "GetFullPathName failed (%d)\n", GetLastError());
+ DEBUG(misc, 0, "GetFullPathName failed (%lu)\n", GetLastError());
_searchpaths[SP_BINARY_DIR] = NULL;
} else {
strecpy(tmp, WIDE_TO_MB_BUFFER(exec_dir, tmp, lengthof(tmp)), lastof(tmp));
@@ -1281,7 +1281,7 @@ char *convert_from_fs(const wchar_t *name, char *utf8_buf, size_t buflen)
{
int len = WideCharToMultiByte(CP_UTF8, 0, name, -1, utf8_buf, (int)buflen, NULL, NULL);
if (len == 0) {
- DEBUG(misc, 0, "[utf8] W2M error converting wide-string. Errno %d", GetLastError());
+ DEBUG(misc, 0, "[utf8] W2M error converting wide-string. Errno %lu", GetLastError());
utf8_buf[0] = '\0';
}
@@ -1300,7 +1300,7 @@ wchar_t *convert_to_fs(const char *name, wchar_t *utf16_buf, size_t buflen)
{
int len = MultiByteToWideChar(CP_UTF8, 0, name, -1, utf16_buf, (int)buflen);
if (len == 0) {
- DEBUG(misc, 0, "[utf8] M2W error converting '%s'. Errno %d", name, GetLastError());
+ DEBUG(misc, 0, "[utf8] M2W error converting '%s'. Errno %lu", name, GetLastError());
utf16_buf[0] = '\0';
}
diff --git a/src/yapf/yapf_base.hpp b/src/yapf/yapf_base.hpp
index bad51adc08..b29e886e4d 100644
--- a/src/yapf/yapf_base.hpp
+++ b/src/yapf/yapf_base.hpp
@@ -155,10 +155,10 @@ public:
int cost = bDestFound ? m_pBestDestNode->m_cost : -1;
int dist = bDestFound ? m_pBestDestNode->m_estimate - m_pBestDestNode->m_cost : -1;
- DEBUG(yapf, 3, "[YAPF%c]%c%4d- %d us - %d rounds - %d open - %d closed - CHR %4.1f%% - c%d(sc%d, ts%d, o%d) -- ",
- ttc, bDestFound ? '-' : '!', veh_idx, t, m_num_steps, m_nodes.OpenCount(), m_nodes.ClosedCount(),
- cache_hit_ratio, cost, dist, m_perf_cost.Get(1000000), m_perf_slope_cost.Get(1000000),
- m_perf_ts_cost.Get(1000000), m_perf_other_cost.Get(1000000)
+ DEBUG(yapf, 3, "[YAPF%c]%c%4d- %d us - %d rounds - %d open - %d closed - CHR %4.1f%% - C %d D %d - c%d(sc%d, ts%d, o%d) -- ",
+ ttc, bDestFound ? '-' : '!', veh_idx, t, m_num_steps, m_nodes.OpenCount(), m_nodes.ClosedCount(),
+ cache_hit_ratio, cost, dist, m_perf_cost.Get(1000000), m_perf_slope_cost.Get(1000000),
+ m_perf_ts_cost.Get(1000000), m_perf_other_cost.Get(1000000)
);
}
}