From f815c849c20e912bc07a86ae707cfeac9472d51d Mon Sep 17 00:00:00 2001 From: harry Date: Sun, 29 Jan 2023 19:38:30 -0500 Subject: [PATCH] Added FCEU printf format specifier macros to enable compiler checking of format strings for custom printf style functions. --- src/driver.h | 4 ++-- src/drivers/Qt/LuaControl.cpp | 6 +----- src/drivers/Qt/LuaControl.h | 13 +------------ src/fceu.cpp | 4 ++-- src/fceu.h | 8 ++++---- src/types.h | 15 +++++++++++++++ src/video.cpp | 4 ++-- 7 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/driver.h b/src/driver.h index a1157355..9dde9c6d 100644 --- a/src/driver.h +++ b/src/driver.h @@ -23,7 +23,7 @@ ArchiveScanRecord FCEUD_ScanArchive(std::string fname); const char *FCEUD_GetCompilerString(); //This makes me feel dirty for some reason. -void FCEU_printf(const char *format, ...); +void FCEU_printf( __FCEU_PRINTF_FORMAT const char *format, ...) __FCEU_PRINTF_ATTRIBUTE( 1, 2 ); #define FCEUI_printf FCEU_printf //Video interface @@ -192,7 +192,7 @@ void TaseditorManualFunction(void); int32 FCEUI_GetDesiredFPS(void); void FCEUI_SaveSnapshot(void); void FCEUI_SaveSnapshotAs(void); -void FCEU_DispMessage(const char *format, int disppos, ...); +void FCEU_DispMessage( __FCEU_PRINTF_FORMAT const char *format, int disppos, ...) __FCEU_PRINTF_ATTRIBUTE( 1, 3 ); #define FCEUI_DispMessage FCEU_DispMessage int FCEUI_DecodePAR(const char *code, int *a, int *v, int *c, int *type); diff --git a/src/drivers/Qt/LuaControl.cpp b/src/drivers/Qt/LuaControl.cpp index 61c059b8..34fdac29 100644 --- a/src/drivers/Qt/LuaControl.cpp +++ b/src/drivers/Qt/LuaControl.cpp @@ -506,11 +506,7 @@ void PrintToWindowConsole(intptr_t hDlgAsInt, const char *str) updateLuaDisplay = true; } //---------------------------------------------------- -#ifdef WIN32 -int LuaPrintfToWindowConsole(_In_z_ _Printf_format_string_ const char *format, ...) -#else -int LuaPrintfToWindowConsole(const char *__restrict format, ...) throw() -#endif +int LuaPrintfToWindowConsole( __FCEU_PRINTF_FORMAT const char * format, ...) { int retval; va_list args; diff --git a/src/drivers/Qt/LuaControl.h b/src/drivers/Qt/LuaControl.h index 7427e9bd..2a2dea8e 100644 --- a/src/drivers/Qt/LuaControl.h +++ b/src/drivers/Qt/LuaControl.h @@ -54,18 +54,7 @@ private slots: }; // Formatted print -#ifdef WIN32 -int LuaPrintfToWindowConsole(_In_z_ _Printf_format_string_ const char *format, ...); -#elif __linux__ -#ifdef __THROWNL -int LuaPrintfToWindowConsole(const char *__restrict format, ...) - __THROWNL __attribute__((__format__(__printf__, 1, 2))); -#else -int LuaPrintfToWindowConsole(const char *__restrict format, ...) throw() __attribute__((__format__(__printf__, 1, 2))); -#endif -#else -int LuaPrintfToWindowConsole(const char *__restrict format, ...) throw(); -#endif +int LuaPrintfToWindowConsole( __FCEU_PRINTF_FORMAT const char *format, ...) __FCEU_PRINTF_ATTRIBUTE( 1, 2 ); void PrintToWindowConsole(intptr_t hDlgAsInt, const char *str); diff --git a/src/fceu.cpp b/src/fceu.cpp index edd5c389..13348e23 100644 --- a/src/fceu.cpp +++ b/src/fceu.cpp @@ -1066,7 +1066,7 @@ void FCEU_ResetVidSys(void) { FCEUS FSettings; -void FCEU_printf(const char *format, ...) +void FCEU_printf( __FCEU_PRINTF_FORMAT const char *format, ...) { char temp[2048]; @@ -1086,7 +1086,7 @@ void FCEU_printf(const char *format, ...) va_end(ap); } -void FCEU_PrintError(const char *format, ...) +void FCEU_PrintError( __FCEU_PRINTF_FORMAT const char *format, ...) { char temp[2048]; diff --git a/src/fceu.h b/src/fceu.h index 7fec58c4..9d75921b 100644 --- a/src/fceu.h +++ b/src/fceu.h @@ -139,10 +139,10 @@ extern FCEUS FSettings; bool CheckFileExists(const char* filename); //Receives a filename (fullpath) and checks to see if that file exists -void FCEU_PrintError(const char *format, ...); -void FCEU_printf(const char *format, ...); -void FCEU_DispMessage(const char *format, int disppos, ...); -void FCEU_DispMessageOnMovie(const char *format, ...); +void FCEU_PrintError( __FCEU_PRINTF_FORMAT const char *format, ...) __FCEU_PRINTF_ATTRIBUTE( 1, 2 ); +void FCEU_printf( __FCEU_PRINTF_FORMAT const char *format, ...) __FCEU_PRINTF_ATTRIBUTE( 1, 2 ); +void FCEU_DispMessage( __FCEU_PRINTF_FORMAT const char *format, int disppos, ...) __FCEU_PRINTF_ATTRIBUTE( 1, 3 ); +void FCEU_DispMessageOnMovie( __FCEU_PRINTF_FORMAT const char *format, ...) __FCEU_PRINTF_ATTRIBUTE( 1, 2 ); void FCEU_TogglePPU(); void SetNESDeemph_OldHacky(uint8 d, int force); diff --git a/src/types.h b/src/types.h index 64f6f6c5..67108d90 100644 --- a/src/types.h +++ b/src/types.h @@ -162,6 +162,21 @@ typedef uint8 (*readfunc)(uint32 A); #define FCEU_MAYBE_UNUSED #endif +#if defined(_MSC_VER) + // Microsoft compiler won't catch format issues, but VS IDE can catch on analysis mode + #define __FCEU_PRINTF_FORMAT _In_z_ _Printf_format_string_ + #define __FCEU_PRINTF_ATTRIBUTE( fmt, va ) + +#elif FCEU_HAS_CPP_ATTRIBUTE(format) + // GCC and Clang compilers will perform printf format type checks, useful for catching format errors. + #define __FCEU_PRINTF_FORMAT + #define __FCEU_PRINTF_ATTRIBUTE( fmt, va ) __attribute__((__format__(__printf__, fmt, va))) + +#else + #define __FCEU_PRINTF_FORMAT + #define __FCEU_PRINTF_ATTRIBUTE( fmt, va ) +#endif + #include "utils/endian.h" #endif diff --git a/src/video.cpp b/src/video.cpp index e3814460..c5c55134 100644 --- a/src/video.cpp +++ b/src/video.cpp @@ -390,7 +390,7 @@ void snapAVI() FCEUI_AviVideoUpdate(XBuf); } -void FCEU_DispMessageOnMovie(const char *format, ...) +void FCEU_DispMessageOnMovie( __FCEU_PRINTF_FORMAT const char *format, ...) { va_list ap; @@ -409,7 +409,7 @@ void FCEU_DispMessageOnMovie(const char *format, ...) guiMessage.howlong = 0; } -void FCEU_DispMessage(const char *format, int disppos=0, ...) +void FCEU_DispMessage( __FCEU_PRINTF_FORMAT const char *format, int disppos=0, ...) { va_list ap;