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,
// 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
// 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
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 EndRedirect();
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 DPrintf( VERIFY_FORMAT_STRING const char* fmt, ... );
virtual void Warning( VERIFY_FORMAT_STRING const char* fmt, ... );
virtual void DWarning( 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, ... ) ID_INSTANCE_ATTRIBUTE_PRINTF( 1, 2 );
virtual void DWarning( VERIFY_FORMAT_STRING const char* fmt, ... ) ID_INSTANCE_ATTRIBUTE_PRINTF( 1, 2 );
virtual void PrintWarnings();
virtual void ClearWarnings( const char* reason );
virtual void Error( VERIFY_FORMAT_STRING const char* fmt, ... );
virtual void FatalError( 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, ... ) ID_INSTANCE_ATTRIBUTE_PRINTF( 1, 2 );
virtual bool IsShuttingDown() const
{
return com_shuttingDown;

View file

@ -209,7 +209,7 @@ public:
//BSM Added for the material editors rename capabilities
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 const idMaterial* FindMaterial( const char* name, bool makeDefault = true );

View file

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

View file

@ -62,12 +62,12 @@ public:
static void ShutDown();
// wrapper to idCommon functions
static void Printf( const char* fmt, ... );
static void PrintfIf( const bool test, const char* fmt, ... );
NO_RETURN static void Error( const char* fmt, ... );
NO_RETURN static void FatalError( const char* fmt, ... );
static void Warning( const char* fmt, ... );
static void WarningIf( const bool test, const char* fmt, ... );
static void Printf ( VERIFY_FORMAT_STRING const char* fmt, ... ) ID_STATIC_ATTRIBUTE_PRINTF( 1, 2 );
static void PrintfIf ( const bool test, VERIFY_FORMAT_STRING const char* fmt, ... ) ID_STATIC_ATTRIBUTE_PRINTF( 2, 3 );
NO_RETURN static void Error ( VERIFY_FORMAT_STRING const char* fmt, ... ) ID_STATIC_ATTRIBUTE_PRINTF( 1, 2 );
NO_RETURN static void FatalError( VERIFY_FORMAT_STRING const char* fmt, ... ) ID_STATIC_ATTRIBUTE_PRINTF( 1, 2 );
static void Warning ( VERIFY_FORMAT_STRING const char* fmt, ... ) ID_STATIC_ATTRIBUTE_PRINTF( 1, 2 );
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
// when called by startup code that happens before idLib::Init

View file

@ -402,7 +402,7 @@ public:
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>
#define VERIFY_FORMAT_STRING [SA_FormatString(Style="printf")]
// 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
// STRIDX: index of format string in function arguments (first arg == 1)
// 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
#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
// never return, so any conditions that leeds to them being called are
// guaranteed to be false in the following code