diff --git a/source/lib/code_annotation.h b/source/lib/code_annotation.h index 9efea6eca2..73d7daf26d 100644 --- a/source/lib/code_annotation.h +++ b/source/lib/code_annotation.h @@ -194,4 +194,21 @@ private:\ # define ASSUME_ALIGNED(ptr, multiple) #endif +// annotate printf-style functions for compile-time type checking. +// fmtpos is the index of the format argument, counting from 1 or +// (if it's a non-static class function) 2; the '...' is assumed +// to come directly after it. +#if GCC_VERSION +# define PRINTF_ARGS(fmtpos) __attribute__ ((format (printf, fmtpos, fmtpos+1))) +# define VPRINTF_ARGS(fmtpos) __attribute__ ((format (printf, fmtpos, 0))) +# define WPRINTF_ARGS(fmtpos) /* not currently supported in GCC */ +# define VWPRINTF_ARGS(fmtpos) /* not currently supported in GCC */ +#else +# define PRINTF_ARGS(fmtpos) +# define VPRINTF_ARGS(fmtpos) +# define WPRINTF_ARGS(fmtpos) +# define VWPRINTF_ARGS(fmtpos) +// TODO: support _Printf_format_string_ for VC9+ +#endif + #endif // #ifndef INCLUDED_CODE_ANNOTATION diff --git a/source/lib/debug.h b/source/lib/debug.h index 0c25c5734c..3e21419f36 100644 --- a/source/lib/debug.h +++ b/source/lib/debug.h @@ -55,8 +55,8 @@ extern void debug_break(); * * @param format string and varargs; see printf. **/ -LIB_API void debug_printf(const char* fmt, ...); -LIB_API void debug_printf(const wchar_t* fmt, ...); +LIB_API void debug_printf(const char* fmt, ...) PRINTF_ARGS(1); +LIB_API void debug_printf(const wchar_t* fmt, ...) WPRINTF_ARGS(1); /** @@ -222,7 +222,7 @@ LIB_API bool debug_filter_allows(const char* text); * * @param format string and varags; see printf. **/ -LIB_API void debug_wprintf_mem(const wchar_t* fmt, ...); +LIB_API void debug_wprintf_mem(const wchar_t* fmt, ...) WPRINTF_ARGS(1); /** * write an error description and all logs into crashlog.txt diff --git a/source/lib/precompiled.h b/source/lib/precompiled.h index 807ab3f176..6f7fc32664 100644 --- a/source/lib/precompiled.h +++ b/source/lib/precompiled.h @@ -69,9 +69,9 @@ #include "lib/types.h" #include "lib/lib.h" #include "lib/lib_errors.h" +#include "lib/code_annotation.h" #include "lib/secure_crt.h" #include "lib/debug.h" -#include "lib/code_annotation.h" // Boost // .. if this package isn't going to be statically linked, we're better off diff --git a/source/lib/res/graphics/unifont.h b/source/lib/res/graphics/unifont.h index 994a84b3f2..d6ab510c79 100644 --- a/source/lib/res/graphics/unifont.h +++ b/source/lib/res/graphics/unifont.h @@ -60,14 +60,14 @@ extern LibError unifont_bind(Handle h); * glDisable(GL_ALPHA_TEST); * glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); **/ -extern void glwprintf(const wchar_t* fmt, ...); +extern void glwprintf(const wchar_t* fmt, ...) WPRINTF_ARGS(1); /** * varargs version of glwprintf. * * @param fmt, args - see vfprintf **/ -extern void glvwprintf(const wchar_t* fmt, va_list args); +extern void glvwprintf(const wchar_t* fmt, va_list args) VWPRINTF_ARGS(1); /** * Determine pixel extents of a string. diff --git a/source/lib/secure_crt.h b/source/lib/secure_crt.h index 4a22f647c6..3f3ab13a20 100644 --- a/source/lib/secure_crt.h +++ b/source/lib/secure_crt.h @@ -85,11 +85,11 @@ extern int wcsncat_s(wchar_t* dst, size_t max_dst_chars, const wchar_t* src, siz extern int strcat_s(char* dst, size_t max_dst_chars, const char* src); extern int wcscat_s(wchar_t* dst, size_t max_dst_chars, const wchar_t* src); -extern int vsprintf_s(char* dst, size_t max_dst_chars, const char* fmt, va_list ap); -extern int vswprintf_s(wchar_t* dst, size_t max_dst_chars, const wchar_t* fmt, va_list ap); +extern int vsprintf_s(char* dst, size_t max_dst_chars, const char* fmt, va_list ap) VPRINTF_ARGS(3); +extern int vswprintf_s(wchar_t* dst, size_t max_dst_chars, const wchar_t* fmt, va_list ap) VWPRINTF_ARGS(3); -extern int sprintf_s(char* buf, size_t max_chars, const char* fmt, ...); -extern int swprintf_s(wchar_t* buf, size_t max_chars, const wchar_t* fmt, ...); +extern int sprintf_s(char* buf, size_t max_chars, const char* fmt, ...) PRINTF_ARGS(3); +extern int swprintf_s(wchar_t* buf, size_t max_chars, const wchar_t* fmt, ...) WPRINTF_ARGS(3); typedef int errno_t; extern errno_t fopen_s(FILE** pfile, const char* filename, const char* mode); diff --git a/source/ps/CLogger.h b/source/ps/CLogger.h index 2f508e24e4..f0b6d73a16 100644 --- a/source/ps/CLogger.h +++ b/source/ps/CLogger.h @@ -64,15 +64,15 @@ public: // Function to log stuff to file // -- This function has not been removed because the build would break. - void Log(ELogMethod method, const char* category, const char *fmt, ...); + void Log(ELogMethod method, const char* category, const char *fmt, ...) PRINTF_ARGS(4); // Similar to Log, but only outputs each message once no matter how many times it's called // -- This function has not been removed because the build would break. - void LogOnce(ELogMethod method, const char* category, const char *fmt, ...); + void LogOnce(ELogMethod method, const char* category, const char *fmt, ...) PRINTF_ARGS(4); // Functions to write a message, warning or error to file. - void LogMessage(const char *fmt, ...); - void LogWarning(const char *fmt, ...); - void LogError(const char *fmt, ...); + void LogMessage(const char *fmt, ...) PRINTF_ARGS(2); + void LogWarning(const char *fmt, ...) PRINTF_ARGS(2); + void LogError(const char *fmt, ...) PRINTF_ARGS(2); private: void Init();