From f91af305845aa1e99d830a7a6addaee058b518d1 Mon Sep 17 00:00:00 2001 From: David Steele Date: Mon, 30 Jan 2023 10:51:48 +0700 Subject: [PATCH] Add FN_PRINTF() macro. Bring the format(printf) attribute in line with the FN_NO_RETURN and FN_INLINE_ALWAYS macros. This is simpler to read and can be customized for different compilers. --- meson.build | 6 ++++++ src/build.auto.h.in | 3 +++ src/common/error.h | 14 ++++++-------- src/common/log.h | 4 ++-- src/common/stackTrace.c | 2 +- src/common/type/json.h | 2 +- src/common/type/string.h | 4 ++-- src/common/type/stringList.h | 2 +- src/common/type/stringStatic.h | 2 +- src/common/type/stringZ.h | 2 +- test/src/common/harnessConfig.h | 6 ++---- 11 files changed, 26 insertions(+), 21 deletions(-) diff --git a/meson.build b/meson.build index c1fd7e605..494f69843 100644 --- a/meson.build +++ b/meson.build @@ -194,6 +194,12 @@ configuration.set( description: 'Indicate that a function should always be inlined' ) +# Set FN_PRINTF macro +configuration.set( + 'FN_PRINTF(fmt, args)', '__attribute__((format(printf, fmt, args)))', + description: 'Indicate that a function is formatted like printf (and provide format and args position)' +) + #################################################################################################################################### # Include subdirs #################################################################################################################################### diff --git a/src/build.auto.h.in b/src/build.auto.h.in index e348a6adc..14bc69d64 100644 --- a/src/build.auto.h.in +++ b/src/build.auto.h.in @@ -32,6 +32,9 @@ Build Flags Generated by Configure // Indicate that a function should always be inlined #define FN_INLINE_ALWAYS __attribute__((always_inline)) static inline +// Indicate that a function is formatted like printf (and provide format and args position) +#define FN_PRINTF(fmt, args) __attribute__((format(printf, fmt, args))) + // Extern function/variable required by other compilation units. Changing these to static is a meson-only feature. #define FN_EXTERN extern #define VR_EXTERN_DECLARE extern diff --git a/src/common/error.h b/src/common/error.h index a32ce2810..3a9907e1f 100644 --- a/src/common/error.h +++ b/src/common/error.h @@ -325,18 +325,16 @@ FN_EXTERN void errorInternalTryEnd(void); FN_EXTERN FN_NO_RETURN void errorInternalThrow( const ErrorType *errorType, const char *fileName, const char *functionName, int fileLine, const char *message, const char *stackTrace); -FN_EXTERN FN_NO_RETURN void errorInternalThrowFmt( - const ErrorType *errorType, const char *fileName, const char *functionName, int fileLine, const char *format, ...) - __attribute__((format(printf, 5, 6))); +FN_EXTERN FN_NO_RETURN FN_PRINTF(5, 6) void errorInternalThrowFmt( + const ErrorType *errorType, const char *fileName, const char *functionName, int fileLine, const char *format, ...); // Throw a system error FN_EXTERN FN_NO_RETURN void errorInternalThrowSys( int errNo, const ErrorType *errorType, const char *fileName, const char *functionName, int fileLine, const char *message); // Throw a formatted system error -FN_EXTERN FN_NO_RETURN void errorInternalThrowSysFmt( - int errNo, const ErrorType *errorType, const char *fileName, const char *functionName, int fileLine, const char *format, ...) - __attribute__((format(printf, 6, 7))); +FN_EXTERN FN_NO_RETURN FN_PRINTF(6, 7) void errorInternalThrowSysFmt( + int errNo, const ErrorType *errorType, const char *fileName, const char *functionName, int fileLine, const char *format, ...); // Versions of the above for coverage testing which checks the error condition inside the function #ifdef DEBUG_COVERAGE @@ -344,9 +342,9 @@ FN_EXTERN FN_NO_RETURN void errorInternalThrowSysFmt( bool error, int errNo, const ErrorType *errorType, const char *fileName, const char *functionName, int fileLine, const char *message); - FN_EXTERN void errorInternalThrowOnSysFmt( + FN_EXTERN FN_PRINTF(7, 8) void errorInternalThrowOnSysFmt( bool error, int errNo, const ErrorType *errorType, const char *fileName, const char *functionName, int fileLine, - const char *format, ...) __attribute__((format(printf, 7, 8))); + const char *format, ...); #endif /*********************************************************************************************************************************** diff --git a/src/common/log.h b/src/common/log.h index 812aafafc..dd949d144 100644 --- a/src/common/log.h +++ b/src/common/log.h @@ -157,8 +157,8 @@ FN_EXTERN void logInternal( const char *functionName, int code, const char *message); // Log function with formatting -FN_EXTERN void logInternalFmt( +FN_EXTERN FN_PRINTF(8, 9) void logInternalFmt( LogLevel logLevel, LogLevel logRangeMin, LogLevel logRangeMax, unsigned int processId, const char *fileName, - const char *functionName, int code, const char *format, ...) __attribute__((format(printf, 8, 9))); + const char *functionName, int code, const char *format, ...); #endif diff --git a/src/common/stackTrace.c b/src/common/stackTrace.c index df8d48f6a..b686379e5 100644 --- a/src/common/stackTrace.c +++ b/src/common/stackTrace.c @@ -251,7 +251,7 @@ stackTracePop(void) /*********************************************************************************************************************************** Stack trace format ***********************************************************************************************************************************/ -__attribute__((format(printf, 4, 5))) static size_t +static FN_PRINTF(4, 5) size_t stackTraceFmt(char *buffer, size_t bufferSize, size_t bufferUsed, const char *format, ...) { va_list argumentList; diff --git a/src/common/type/json.h b/src/common/type/json.h index e585ec5e7..330368b9b 100644 --- a/src/common/type/json.h +++ b/src/common/type/json.h @@ -150,7 +150,7 @@ FN_EXTERN JsonWrite *jsonWriteObjectEnd(JsonWrite *this); // Write string FN_EXTERN JsonWrite *jsonWriteStr(JsonWrite *this, const String *value); -FN_EXTERN JsonWrite *jsonWriteStrFmt(JsonWrite *this, const char *format, ...) __attribute__((format(printf, 2, 3))); +FN_EXTERN FN_PRINTF(2, 3) JsonWrite *jsonWriteStrFmt(JsonWrite *this, const char *format, ...); FN_EXTERN JsonWrite *jsonWriteStrId(JsonWrite *this, StringId value); FN_EXTERN JsonWrite *jsonWriteStrLst(JsonWrite *this, const StringList *value); FN_EXTERN JsonWrite *jsonWriteZ(JsonWrite *this, const char *value); diff --git a/src/common/type/string.h b/src/common/type/string.h index a17a341d0..d0fcd2d5d 100644 --- a/src/common/type/string.h +++ b/src/common/type/string.h @@ -73,7 +73,7 @@ FN_EXTERN String *strNewDbl(double value); FN_EXTERN String *strNewEncode(EncodingType type, const Buffer *buffer); // Create a new fixed length string from a format string with parameters (i.e. sprintf) -FN_EXTERN String *strNewFmt(const char *format, ...) __attribute__((format(printf, 1, 2))); +FN_EXTERN FN_PRINTF(1, 2) String *strNewFmt(const char *format, ...); // Create a new fixed length string from a string FN_EXTERN String *strDup(const String *this); @@ -130,7 +130,7 @@ FN_EXTERN String *strCatChr(String *this, char cat); FN_EXTERN String *strCatEncode(String *this, EncodingType type, const Buffer *buffer); // Append a formatted string -FN_EXTERN String *strCatFmt(String *this, const char *format, ...) __attribute__((format(printf, 2, 3))); +FN_EXTERN FN_PRINTF(2, 3) String *strCatFmt(String *this, const char *format, ...); // Append N characters from a zero-terminated string. Note that the string does not actually need to be zero-terminated as long as // N is <= the end of the string being concatenated. diff --git a/src/common/type/stringList.h b/src/common/type/stringList.h index c097c3d24..209c7eb18 100644 --- a/src/common/type/stringList.h +++ b/src/common/type/stringList.h @@ -76,7 +76,7 @@ strLstAddSub(StringList *const this, const String *const string, const size_t si return strLstAddSubN(this, string, 0, size); } -FN_EXTERN String *strLstAddFmt(StringList *this, const char *format, ...) __attribute__((format(printf, 2, 3))); +FN_EXTERN FN_PRINTF(2, 3) String *strLstAddFmt(StringList *this, const char *format, ...); FN_EXTERN String *strLstAddZ(StringList *this, const char *string); FN_EXTERN String *strLstAddZSubN(StringList *this, const char *string, size_t offset, size_t size); diff --git a/src/common/type/stringStatic.h b/src/common/type/stringStatic.h index b7009f76e..8306cef3b 100644 --- a/src/common/type/stringStatic.h +++ b/src/common/type/stringStatic.h @@ -33,7 +33,7 @@ strStcInit(char *const buffer, const size_t bufferSize) Functions ***********************************************************************************************************************************/ // Cat formatted string to static string -FN_EXTERN StringStatic *strStcFmt(StringStatic *debugLog, const char *format, ...) __attribute__((format(printf, 2, 3))); +FN_EXTERN FN_PRINTF(2, 3) StringStatic *strStcFmt(StringStatic *debugLog, const char *format, ...); // Cat zero-terminated string to static string FN_EXTERN void strStcCat(StringStatic *debugLog, const char *cat); diff --git a/src/common/type/stringZ.h b/src/common/type/stringZ.h index 2643c719d..3989db0a9 100644 --- a/src/common/type/stringZ.h +++ b/src/common/type/stringZ.h @@ -18,6 +18,6 @@ Zero-terminated strings that are generally useful Functions ***********************************************************************************************************************************/ // Format a zero-terminated string -FN_EXTERN char *zNewFmt(const char *format, ...) __attribute__((format(printf, 1, 2))); +FN_EXTERN FN_PRINTF(1, 2) char *zNewFmt(const char *format, ...); #endif diff --git a/test/src/common/harnessConfig.h b/test/src/common/harnessConfig.h index 408848795..44eaca67f 100644 --- a/test/src/common/harnessConfig.h +++ b/test/src/common/harnessConfig.h @@ -60,10 +60,8 @@ variant that works with indexed options and allows the key to be specified, e.g. void hrnCfgArgRaw(StringList *argList, ConfigOption optionId, const String *value); void hrnCfgArgKeyRaw(StringList *argList, ConfigOption optionId, unsigned optionKey, const String *value); -void hrnCfgArgRawFmt(StringList *argList, ConfigOption optionId, const char *format, ...) - __attribute__((format(printf, 3, 4))); -void hrnCfgArgKeyRawFmt(StringList *argList, ConfigOption optionId, unsigned optionKey, const char *format, ...) - __attribute__((format(printf, 4, 5))); +FN_PRINTF(3, 4) void hrnCfgArgRawFmt(StringList *argList, ConfigOption optionId, const char *format, ...); +FN_PRINTF(4, 5) void hrnCfgArgKeyRawFmt(StringList *argList, ConfigOption optionId, unsigned optionKey, const char *format, ...); void hrnCfgArgRawZ(StringList *argList, ConfigOption optionId, const char *value); void hrnCfgArgKeyRawZ(StringList *argList, ConfigOption optionId, unsigned optionKey, const char *value);