Merge pull request #79 from abergmeier/add_format_analysis

Properly handle format analysis
This commit is contained in:
Robert Beckebans 2014-02-23 15:06:01 +01:00
commit 6a2633fb20
7 changed files with 24 additions and 21 deletions

View file

@ -261,11 +261,11 @@ public:
// Issues a C++ throw. Normal errors just abort to the game loop, // Issues a C++ throw. Normal errors just abort to the game loop,
// which is appropriate for media or dynamic logic errors. // which is appropriate for media or dynamic logic errors.
virtual void Error( VERIFY_FORMAT_STRING const char* fmt, ... ) = 0; virtual void Error( VERIFY_FORMAT_STRING const char* fmt, ... ) ID_INSTANCE_ATTRIBUTE_PRINTF( 1, 2 ) = 0;
// Fatal errors quit all the way to a system dialog box, which is appropriate for // Fatal errors quit all the way to a system dialog box, which is appropriate for
// static internal errors or cases where the system may be corrupted. // static internal errors or cases where the system may be corrupted.
virtual void FatalError( VERIFY_FORMAT_STRING const char* fmt, ... ) = 0; virtual void FatalError( VERIFY_FORMAT_STRING const char* fmt, ... ) ID_INSTANCE_ATTRIBUTE_PRINTF( 1, 2 ) = 0;
// Returns key bound to the command // Returns key bound to the command
virtual const char* KeysFromBinding( const char* bind ) = 0; virtual const char* KeysFromBinding( const char* bind ) = 0;

View file

@ -157,15 +157,15 @@ public:
virtual void BeginRedirect( char* buffer, int buffersize, void ( *flush )( const char* ) ); virtual void BeginRedirect( char* buffer, int buffersize, void ( *flush )( const char* ) );
virtual void EndRedirect(); virtual void EndRedirect();
virtual void SetRefreshOnPrint( bool set ); virtual void SetRefreshOnPrint( bool set );
virtual void Printf( VERIFY_FORMAT_STRING const char* fmt, ... ); virtual void Printf( VERIFY_FORMAT_STRING const char* fmt, ... ) ID_INSTANCE_ATTRIBUTE_PRINTF( 1, 2 );
virtual void VPrintf( const char* fmt, va_list arg ); virtual void VPrintf( const char* fmt, va_list arg );
virtual void DPrintf( VERIFY_FORMAT_STRING const char* fmt, ... ); virtual void DPrintf( VERIFY_FORMAT_STRING const char* fmt, ... ) ID_INSTANCE_ATTRIBUTE_PRINTF( 1, 2 );
virtual void Warning( VERIFY_FORMAT_STRING const char* fmt, ... ); virtual void Warning( VERIFY_FORMAT_STRING const char* fmt, ... ) ID_INSTANCE_ATTRIBUTE_PRINTF( 1, 2 );
virtual void DWarning( VERIFY_FORMAT_STRING const char* fmt, ... ); virtual void DWarning( VERIFY_FORMAT_STRING const char* fmt, ... ) ID_INSTANCE_ATTRIBUTE_PRINTF( 1, 2 );
virtual void PrintWarnings(); virtual void PrintWarnings();
virtual void ClearWarnings( const char* reason ); virtual void ClearWarnings( const char* reason );
virtual void Error( VERIFY_FORMAT_STRING const char* fmt, ... ); virtual void Error( VERIFY_FORMAT_STRING const char* fmt, ... ) ID_INSTANCE_ATTRIBUTE_PRINTF( 1, 2 );
virtual void FatalError( VERIFY_FORMAT_STRING const char* fmt, ... ); virtual void FatalError( VERIFY_FORMAT_STRING const char* fmt, ... ) ID_INSTANCE_ATTRIBUTE_PRINTF( 1, 2 );
virtual bool IsShuttingDown() const virtual bool IsShuttingDown() const
{ {
return com_shuttingDown; return com_shuttingDown;

View file

@ -209,7 +209,7 @@ public:
//BSM Added for the material editors rename capabilities //BSM Added for the material editors rename capabilities
virtual bool RenameDecl( declType_t type, const char* oldName, const char* newName ); virtual bool RenameDecl( declType_t type, const char* oldName, const char* newName );
virtual void MediaPrint( VERIFY_FORMAT_STRING const char* fmt, ... ); virtual void MediaPrint( VERIFY_FORMAT_STRING const char* fmt, ... ) ID_INSTANCE_ATTRIBUTE_PRINTF(1, 2);
virtual void WritePrecacheCommands( idFile* f ); virtual void WritePrecacheCommands( idFile* f );
virtual const idMaterial* FindMaterial( const char* name, bool makeDefault = true ); virtual const idMaterial* FindMaterial( const char* name, bool makeDefault = true );

View file

@ -156,8 +156,8 @@ public:
int ExpectAnyToken( idToken* token ); int ExpectAnyToken( idToken* token );
void SetMarker() {} void SetMarker() {}
void UnreadToken( const idToken* token ); void UnreadToken( const idToken* token );
void Error( VERIFY_FORMAT_STRING const char* str, ... ); void Error( VERIFY_FORMAT_STRING const char* str, ... ) ID_INSTANCE_ATTRIBUTE_PRINTF(1, 2);
void Warning( VERIFY_FORMAT_STRING const char* str, ... ); void Warning( VERIFY_FORMAT_STRING const char* str, ... ) ID_INSTANCE_ATTRIBUTE_PRINTF(1, 2);
int ParseInt(); int ParseInt();
bool ParseBool(); bool ParseBool();
float ParseFloat( bool* errorFlag = NULL ); float ParseFloat( bool* errorFlag = NULL );

View file

@ -62,12 +62,12 @@ public:
static void ShutDown(); static void ShutDown();
// wrapper to idCommon functions // wrapper to idCommon functions
static void Printf( const char* fmt, ... ); static void Printf ( VERIFY_FORMAT_STRING const char* fmt, ... ) ID_STATIC_ATTRIBUTE_PRINTF( 1, 2 );
static void PrintfIf( const bool test, const char* fmt, ... ); static void PrintfIf ( const bool test, VERIFY_FORMAT_STRING const char* fmt, ... ) ID_STATIC_ATTRIBUTE_PRINTF( 2, 3 );
NO_RETURN static void Error( const char* fmt, ... ); NO_RETURN static void Error ( VERIFY_FORMAT_STRING const char* fmt, ... ) ID_STATIC_ATTRIBUTE_PRINTF( 1, 2 );
NO_RETURN static void FatalError( const char* fmt, ... ); NO_RETURN static void FatalError( VERIFY_FORMAT_STRING const char* fmt, ... ) ID_STATIC_ATTRIBUTE_PRINTF( 1, 2 );
static void Warning( const char* fmt, ... ); static void Warning ( VERIFY_FORMAT_STRING const char* fmt, ... ) ID_STATIC_ATTRIBUTE_PRINTF( 1, 2 );
static void WarningIf( const bool test, const char* fmt, ... ); static void WarningIf ( const bool test, VERIFY_FORMAT_STRING const char* fmt, ... ) ID_STATIC_ATTRIBUTE_PRINTF( 2, 3 );
// the extra check for mainThreadInitialized is necessary for this to be accurate // the extra check for mainThreadInitialized is necessary for this to be accurate
// when called by startup code that happens before idLib::Init // when called by startup code that happens before idLib::Init

View file

@ -402,7 +402,7 @@ public:
static const int INVALID_POSITION = -1; static const int INVALID_POSITION = -1;
}; };
char* va( VERIFY_FORMAT_STRING const char* fmt, ... ) ATTRIBUTE_PRINTF( 1, 2 ); char* va( VERIFY_FORMAT_STRING const char* fmt, ... ) ID_STATIC_ATTRIBUTE_PRINTF( 1, 2 );
/* /*
================================================================================================ ================================================================================================

View file

@ -213,16 +213,19 @@ bulk of the codebase, so it is the best place for analyze pragmas.
#include <CodeAnalysis\SourceAnnotations.h> #include <CodeAnalysis\SourceAnnotations.h>
#define VERIFY_FORMAT_STRING [SA_FormatString(Style="printf")] #define VERIFY_FORMAT_STRING [SA_FormatString(Style="printf")]
// DG: alternative for GCC with attribute (NOOP for MSVC) // DG: alternative for GCC with attribute (NOOP for MSVC)
#define ATTRIBUTE_PRINTF(STRIDX, FIRSTARGIDX) #define ID_STATIC_ATTRIBUTE_PRINTF(STRIDX, FIRSTARGIDX)
#elif defined(__GNUC__) // FIXME: what about clang? #else
#define VERIFY_FORMAT_STRING #define VERIFY_FORMAT_STRING
// STRIDX: index of format string in function arguments (first arg == 1) // STRIDX: index of format string in function arguments (first arg == 1)
// FIRSTARGIDX: index of first argument for the format string // FIRSTARGIDX: index of first argument for the format string
#define ATTRIBUTE_PRINTF(STRIDX, FIRSTARGIDX) __attribute__ ((format (printf, STRIDX, FIRSTARGIDX))) #define ID_STATIC_ATTRIBUTE_PRINTF(STRIDX, FIRSTARGIDX) __attribute__ ((format (printf, STRIDX, FIRSTARGIDX)))
// DG end // DG end
#endif // _MSC_VER #endif // _MSC_VER
// This needs to be handled so shift by 1
#define ID_INSTANCE_ATTRIBUTE_PRINTF(STRIDX, FIRSTARGIDX) ID_STATIC_ATTRIBUTE_PRINTF((STRIDX+1),(FIRSTARGIDX+1))
// We need to inform the compiler that Error() and FatalError() will // We need to inform the compiler that Error() and FatalError() will
// never return, so any conditions that leeds to them being called are // never return, so any conditions that leeds to them being called are
// guaranteed to be false in the following code // guaranteed to be false in the following code