Skip to content

Commit

Permalink
Added annotations to help code analysis tools
Browse files Browse the repository at this point in the history
CR: Bruce Dawson
  • Loading branch information
slouken committed Jun 4, 2014
1 parent 529bcf6 commit da6d9a9
Show file tree
Hide file tree
Showing 16 changed files with 134 additions and 90 deletions.
2 changes: 1 addition & 1 deletion include/SDL_error.h
Expand Up @@ -38,7 +38,7 @@ extern "C" {

/* Public functions */
/* SDL_SetError() unconditionally returns -1. */
extern DECLSPEC int SDLCALL SDL_SetError(const char *fmt, ...);
extern DECLSPEC int SDLCALL SDL_SetError(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(1);
extern DECLSPEC const char *SDLCALL SDL_GetError(void);
extern DECLSPEC void SDLCALL SDL_ClearError(void);

Expand Down
16 changes: 8 additions & 8 deletions include/SDL_log.h
Expand Up @@ -137,44 +137,44 @@ extern DECLSPEC void SDLCALL SDL_LogResetPriorities(void);
/**
* \brief Log a message with SDL_LOG_CATEGORY_APPLICATION and SDL_LOG_PRIORITY_INFO
*/
extern DECLSPEC void SDLCALL SDL_Log(const char *fmt, ...);
extern DECLSPEC void SDLCALL SDL_Log(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(1);

/**
* \brief Log a message with SDL_LOG_PRIORITY_VERBOSE
*/
extern DECLSPEC void SDLCALL SDL_LogVerbose(int category, const char *fmt, ...);
extern DECLSPEC void SDLCALL SDL_LogVerbose(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2);

/**
* \brief Log a message with SDL_LOG_PRIORITY_DEBUG
*/
extern DECLSPEC void SDLCALL SDL_LogDebug(int category, const char *fmt, ...);
extern DECLSPEC void SDLCALL SDL_LogDebug(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2);

/**
* \brief Log a message with SDL_LOG_PRIORITY_INFO
*/
extern DECLSPEC void SDLCALL SDL_LogInfo(int category, const char *fmt, ...);
extern DECLSPEC void SDLCALL SDL_LogInfo(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2);

/**
* \brief Log a message with SDL_LOG_PRIORITY_WARN
*/
extern DECLSPEC void SDLCALL SDL_LogWarn(int category, const char *fmt, ...);
extern DECLSPEC void SDLCALL SDL_LogWarn(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2);

/**
* \brief Log a message with SDL_LOG_PRIORITY_ERROR
*/
extern DECLSPEC void SDLCALL SDL_LogError(int category, const char *fmt, ...);
extern DECLSPEC void SDLCALL SDL_LogError(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2);

/**
* \brief Log a message with SDL_LOG_PRIORITY_CRITICAL
*/
extern DECLSPEC void SDLCALL SDL_LogCritical(int category, const char *fmt, ...);
extern DECLSPEC void SDLCALL SDL_LogCritical(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2);

/**
* \brief Log a message with the specified category and priority.
*/
extern DECLSPEC void SDLCALL SDL_LogMessage(int category,
SDL_LogPriority priority,
const char *fmt, ...);
SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(3);

/**
* \brief Log a message with the specified category and priority.
Expand Down
68 changes: 56 additions & 12 deletions include/SDL_stdinc.h
Expand Up @@ -166,6 +166,50 @@ typedef uint64_t Uint64;
/* @} *//* Basic data types */


/* Annotations to help code analysis tools */
#ifdef SDL_DISABLE_ANALYZE_MACROS
#define SDL_IN_BYTECAP(x)
#define SDL_INOUT_Z_CAP(x)
#define SDL_OUT_Z_CAP(x)
#define SDL_OUT_CAP(x)
#define SDL_OUT_BYTECAP(x)
#define SDL_OUT_Z_BYTECAP(x)
#define SDL_PRINTF_FORMAT_STRING
#define SDL_SCANF_FORMAT_STRING
#define SDL_PRINTF_VARARG_FUNC( fmtargnumber )
#define SDL_SCANF_VARARG_FUNC( fmtargnumber )
#else
#if _MSC_VER >= 1600 /* VS 2010 and above */
#include <sal.h>

#define SDL_IN_BYTECAP(x) _In_bytecount_(x)
#define SDL_INOUT_Z_CAP(x) _Inout_z_cap_(x)
#define SDL_OUT_Z_CAP(x) _Out_z_cap_(x)
#define SDL_OUT_CAP(x) _Out_cap_(x)
#define SDL_OUT_BYTECAP(x) _Out_bytecap_(x)
#define SDL_OUT_Z_BYTECAP(x) _Out_z_bytecap_(x)

#define SDL_PRINTF_FORMAT_STRING _Printf_format_string_
#define SDL_SCANF_FORMAT_STRING _Scanf_format_string_impl_
#else
#define SDL_IN_BYTECAP(x)
#define SDL_INOUT_Z_CAP(x)
#define SDL_OUT_Z_CAP(x)
#define SDL_OUT_CAP(x)
#define SDL_OUT_BYTECAP(x)
#define SDL_OUT_Z_BYTECAP(x)
#define SDL_PRINTF_FORMAT_STRING
#define SDL_SCANF_FORMAT_STRING
#endif
#if defined(__GNUC__)
#define SDL_PRINTF_VARARG_FUNC( fmtargnumber ) __attribute__ (( format( __printf__, fmtargnumber, fmtargnumber+1 )))
#define SDL_SCANF_VARARG_FUNC( fmtargnumber ) __attribute__ (( format( __scanf__, fmtargnumber, fmtargnumber+1 )))
#else
#define SDL_PRINTF_VARARG_FUNC( fmtargnumber )
#define SDL_SCANF_VARARG_FUNC( fmtargnumber )
#endif
#endif /* SDL_DISABLE_ANALYSE_MACROS */

#define SDL_COMPILE_TIME_ASSERT(name, x) \
typedef int SDL_dummy_ ## name[(x) * 2 - 1]
/** \cond */
Expand Down Expand Up @@ -259,7 +303,7 @@ extern DECLSPEC int SDLCALL SDL_isspace(int x);
extern DECLSPEC int SDLCALL SDL_toupper(int x);
extern DECLSPEC int SDLCALL SDL_tolower(int x);

extern DECLSPEC void *SDLCALL SDL_memset(void *dst, int c, size_t len);
extern DECLSPEC void *SDLCALL SDL_memset(SDL_OUT_BYTECAP(len) void *dst, int c, size_t len);

#define SDL_zero(x) SDL_memset(&(x), 0, sizeof((x)))
#define SDL_zerop(x) SDL_memset((x), 0, sizeof(*(x)))
Expand Down Expand Up @@ -294,24 +338,24 @@ SDL_FORCE_INLINE void SDL_memset4(void *dst, Uint32 val, size_t dwords)
}


extern DECLSPEC void *SDLCALL SDL_memcpy(void *dst, const void *src, size_t len);
extern DECLSPEC void *SDLCALL SDL_memcpy(SDL_OUT_BYTECAP(len) void *dst, SDL_IN_BYTECAP(len) const void *src, size_t len);

SDL_FORCE_INLINE void *SDL_memcpy4(void *dst, const void *src, size_t dwords)
SDL_FORCE_INLINE void *SDL_memcpy4(SDL_OUT_BYTECAP(dwords*4) void *dst, SDL_IN_BYTECAP(dwords*4) const void *src, size_t dwords)
{
return SDL_memcpy(dst, src, dwords * 4);
}

extern DECLSPEC void *SDLCALL SDL_memmove(void *dst, const void *src, size_t len);
extern DECLSPEC void *SDLCALL SDL_memmove(SDL_OUT_BYTECAP(len) void *dst, SDL_IN_BYTECAP(len) const void *src, size_t len);
extern DECLSPEC int SDLCALL SDL_memcmp(const void *s1, const void *s2, size_t len);

extern DECLSPEC size_t SDLCALL SDL_wcslen(const wchar_t *wstr);
extern DECLSPEC size_t SDLCALL SDL_wcslcpy(wchar_t *dst, const wchar_t *src, size_t maxlen);
extern DECLSPEC size_t SDLCALL SDL_wcslcat(wchar_t *dst, const wchar_t *src, size_t maxlen);
extern DECLSPEC size_t SDLCALL SDL_wcslcpy(SDL_OUT_Z_CAP(maxlen) wchar_t *dst, const wchar_t *src, size_t maxlen);
extern DECLSPEC size_t SDLCALL SDL_wcslcat(SDL_INOUT_Z_CAP(maxlen) wchar_t *dst, const wchar_t *src, size_t maxlen);

extern DECLSPEC size_t SDLCALL SDL_strlen(const char *str);
extern DECLSPEC size_t SDLCALL SDL_strlcpy(char *dst, const char *src, size_t maxlen);
extern DECLSPEC size_t SDLCALL SDL_utf8strlcpy(char *dst, const char *src, size_t dst_bytes);
extern DECLSPEC size_t SDLCALL SDL_strlcat(char *dst, const char *src, size_t maxlen);
extern DECLSPEC size_t SDLCALL SDL_strlcpy(SDL_OUT_Z_CAP(maxlen) char *dst, const char *src, size_t maxlen);
extern DECLSPEC size_t SDLCALL SDL_utf8strlcpy(SDL_OUT_Z_CAP(dst_bytes) char *dst, const char *src, size_t dst_bytes);
extern DECLSPEC size_t SDLCALL SDL_strlcat(SDL_INOUT_Z_CAP(maxlen) char *dst, const char *src, size_t maxlen);
extern DECLSPEC char *SDLCALL SDL_strdup(const char *str);
extern DECLSPEC char *SDLCALL SDL_strrev(char *str);
extern DECLSPEC char *SDLCALL SDL_strupr(char *str);
Expand Down Expand Up @@ -340,10 +384,10 @@ extern DECLSPEC int SDLCALL SDL_strncmp(const char *str1, const char *str2, size
extern DECLSPEC int SDLCALL SDL_strcasecmp(const char *str1, const char *str2);
extern DECLSPEC int SDLCALL SDL_strncasecmp(const char *str1, const char *str2, size_t len);

extern DECLSPEC int SDLCALL SDL_sscanf(const char *text, const char *fmt, ...);
extern DECLSPEC int SDLCALL SDL_sscanf(const char *text, SDL_SCANF_FORMAT_STRING const char *fmt, ...) SDL_SCANF_VARARG_FUNC(2);
extern DECLSPEC int SDLCALL SDL_vsscanf(const char *text, const char *fmt, va_list ap);
extern DECLSPEC int SDLCALL SDL_snprintf(char *text, size_t maxlen, const char *fmt, ...);
extern DECLSPEC int SDLCALL SDL_vsnprintf(char *text, size_t maxlen, const char *fmt, va_list ap);
extern DECLSPEC int SDLCALL SDL_snprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, SDL_PRINTF_FORMAT_STRING const char *fmt, ... ) SDL_PRINTF_VARARG_FUNC(3);
extern DECLSPEC int SDLCALL SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *fmt, va_list ap);

#ifndef HAVE_M_PI
#ifndef M_PI
Expand Down
6 changes: 3 additions & 3 deletions include/SDL_test_assert.h
Expand Up @@ -58,7 +58,7 @@ extern "C" {
* \param assertCondition Evaluated condition or variable to assert; fail (==0) or pass (!=0).
* \param assertDescription Message to log with the assert describing it.
*/
void SDLTest_Assert(int assertCondition, const char *assertDescription, ...);
void SDLTest_Assert(int assertCondition, SDL_PRINTF_FORMAT_STRING const char *assertDescription, ...) SDL_PRINTF_VARARG_FUNC(2);

/**
* \brief Assert for test cases that logs but does not break execution flow on failures. Updates assertion counters.
Expand All @@ -68,14 +68,14 @@ void SDLTest_Assert(int assertCondition, const char *assertDescription, ...);
*
* \returns Returns the assertCondition so it can be used to externally to break execution flow if desired.
*/
int SDLTest_AssertCheck(int assertCondition, const char *assertDescription, ...);
int SDLTest_AssertCheck(int assertCondition, SDL_PRINTF_FORMAT_STRING const char *assertDescription, ...) SDL_PRINTF_VARARG_FUNC(2);

/**
* \brief Explicitely pass without checking an assertion condition. Updates assertion counter.
*
* \param assertDescription Message to log with the assert describing it.
*/
void SDLTest_AssertPass(const char *assertDescription, ...);
void SDLTest_AssertPass(SDL_PRINTF_FORMAT_STRING const char *assertDescription, ...) SDL_PRINTF_VARARG_FUNC(1);

/**
* \brief Resets the assert summary counters to zero.
Expand Down
4 changes: 2 additions & 2 deletions include/SDL_test_log.h
Expand Up @@ -47,14 +47,14 @@ extern "C" {
*
* \param fmt Message to be logged
*/
void SDLTest_Log(const char *fmt, ...);
void SDLTest_Log(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(1);

/**
* \brief Prints given message with a timestamp in the TEST category and the ERROR priority.
*
* \param fmt Message to be logged
*/
void SDLTest_LogError(const char *fmt, ...);
void SDLTest_LogError(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(1);

/* Ends C function definitions when using C++ */
#ifdef __cplusplus
Expand Down
2 changes: 1 addition & 1 deletion src/SDL_error.c
Expand Up @@ -50,7 +50,7 @@ SDL_LookupString(const char *key)
/* Public functions */

int
SDL_SetError(const char *fmt, ...)
SDL_SetError(SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
{
va_list ap;
SDL_error *error;
Expand Down
20 changes: 9 additions & 11 deletions src/SDL_log.c
Expand Up @@ -26,6 +26,7 @@

/* Simple log messages in SDL */

#include "SDL_error.h"
#include "SDL_log.h"

#if HAVE_STDIO_H
Expand All @@ -41,9 +42,6 @@
#define DEFAULT_APPLICATION_PRIORITY SDL_LOG_PRIORITY_INFO
#define DEFAULT_TEST_PRIORITY SDL_LOG_PRIORITY_VERBOSE

/* Forward definition of error function */
extern int SDL_SetError(const char *fmt, ...);

typedef struct SDL_LogLevel
{
int category;
Expand Down Expand Up @@ -172,7 +170,7 @@ SDL_LogResetPriorities(void)
}

void
SDL_Log(const char *fmt, ...)
SDL_Log(SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
{
va_list ap;

Expand All @@ -182,7 +180,7 @@ SDL_Log(const char *fmt, ...)
}

void
SDL_LogVerbose(int category, const char *fmt, ...)
SDL_LogVerbose(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
{
va_list ap;

Expand All @@ -192,7 +190,7 @@ SDL_LogVerbose(int category, const char *fmt, ...)
}

void
SDL_LogDebug(int category, const char *fmt, ...)
SDL_LogDebug(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
{
va_list ap;

Expand All @@ -202,7 +200,7 @@ SDL_LogDebug(int category, const char *fmt, ...)
}

void
SDL_LogInfo(int category, const char *fmt, ...)
SDL_LogInfo(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
{
va_list ap;

Expand All @@ -212,7 +210,7 @@ SDL_LogInfo(int category, const char *fmt, ...)
}

void
SDL_LogWarn(int category, const char *fmt, ...)
SDL_LogWarn(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
{
va_list ap;

Expand All @@ -222,7 +220,7 @@ SDL_LogWarn(int category, const char *fmt, ...)
}

void
SDL_LogError(int category, const char *fmt, ...)
SDL_LogError(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
{
va_list ap;

Expand All @@ -232,7 +230,7 @@ SDL_LogError(int category, const char *fmt, ...)
}

void
SDL_LogCritical(int category, const char *fmt, ...)
SDL_LogCritical(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
{
va_list ap;

Expand All @@ -242,7 +240,7 @@ SDL_LogCritical(int category, const char *fmt, ...)
}

void
SDL_LogMessage(int category, SDL_LogPriority priority, const char *fmt, ...)
SDL_LogMessage(int category, SDL_LogPriority priority, SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
{
va_list ap;

Expand Down
3 changes: 1 addition & 2 deletions src/audio/SDL_wave.c
Expand Up @@ -493,8 +493,7 @@ SDL_LoadWAV_RW(SDL_RWops * src, int freesrc,
IMA_ADPCM_encoded = 1;
break;
case MP3_CODE:
SDL_SetError("MPEG Layer 3 data not supported",
SDL_SwapLE16(format->encoding));
SDL_SetError("MPEG Layer 3 data not supported");
was_error = 1;
goto done;
default:
Expand Down
14 changes: 7 additions & 7 deletions src/dynapi/SDL_dynapi.c
Expand Up @@ -56,38 +56,38 @@ static void SDL_InitDynamicAPI(void);
#if DISABLE_JUMP_MAGIC
/* Can't use the macro for varargs nonsense. This is atrocious. */
#define SDL_DYNAPI_VARARGS_LOGFN(_static, name, initcall, logname, prio) \
_static void SDL_Log##logname##name(int category, const char *fmt, ...) { \
_static void SDL_Log##logname##name(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) { \
va_list ap; initcall; va_start(ap, fmt); \
jump_table.SDL_LogMessageV(category, SDL_LOG_PRIORITY_##prio, fmt, ap); \
va_end(ap); \
}

#define SDL_DYNAPI_VARARGS(_static, name, initcall) \
_static int SDL_SetError##name(const char *fmt, ...) { \
_static int SDL_SetError##name(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) { \
char buf[512]; /* !!! FIXME: dynamic allocation */ \
va_list ap; initcall; va_start(ap, fmt); \
jump_table.SDL_vsnprintf(buf, sizeof (buf), fmt, ap); \
va_end(ap); \
return jump_table.SDL_SetError("%s", buf); \
} \
_static int SDL_sscanf##name(const char *buf, const char *fmt, ...) { \
_static int SDL_sscanf##name(const char *buf, SDL_SCANF_FORMAT_STRING const char *fmt, ...) { \
int retval; va_list ap; initcall; va_start(ap, fmt); \
retval = jump_table.SDL_vsscanf(buf, fmt, ap); \
va_end(ap); \
return retval; \
} \
_static int SDL_snprintf##name(char *buf, size_t buflen, const char *fmt, ...) { \
_static int SDL_snprintf##name(SDL_OUT_Z_CAP(maxlen) char *buf, size_t maxlen, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) { \
int retval; va_list ap; initcall; va_start(ap, fmt); \
retval = jump_table.SDL_vsnprintf(buf, buflen, fmt, ap); \
retval = jump_table.SDL_vsnprintf(buf, maxlen, fmt, ap); \
va_end(ap); \
return retval; \
} \
_static void SDL_Log##name(const char *fmt, ...) { \
_static void SDL_Log##name(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) { \
va_list ap; initcall; va_start(ap, fmt); \
jump_table.SDL_LogMessageV(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, fmt, ap); \
va_end(ap); \
} \
_static void SDL_LogMessage##name(int category, SDL_LogPriority priority, const char *fmt, ...) { \
_static void SDL_LogMessage##name(int category, SDL_LogPriority priority, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) { \
va_list ap; initcall; va_start(ap, fmt); \
jump_table.SDL_LogMessageV(category, priority, fmt, ap); \
va_end(ap); \
Expand Down

0 comments on commit da6d9a9

Please sign in to comment.