From fb37e019b4ff60dc8be48b34c0c945ddbaf4c24c Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Thu, 9 Jan 2025 16:14:46 +0100 Subject: [PATCH] CPLErrorOnce()/CPLDebugOnce(): append a 'Further messages of this type will be suppressed' suffix text --- port/cpl_error.h | 42 +++++++++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/port/cpl_error.h b/port/cpl_error.h index 748d61555c5c..a4d8fcd0a862 100644 --- a/port/cpl_error.h +++ b/port/cpl_error.h @@ -126,21 +126,36 @@ void CPL_DLL CPLError(CPLErr eErrClass, CPLErrorNum err_no, CPL_FORMAT_STRING(const char *fmt), ...) CPL_PRINT_FUNC_FORMAT(3, 4); +#ifdef GDAL_COMPILATION + +const char CPL_DLL *CPLSPrintf(CPL_FORMAT_STRING(const char *fmt), ...) + CPL_PRINT_FUNC_FORMAT(1, 2) CPL_WARN_UNUSED_RESULT; + /** Similar to CPLError(), but only execute it once during the life-time * of a process. * * @since 3.11 */ -#define CPLErrorOnce(...) \ +#define CPLErrorOnce(eErrClass, err_no, ...) \ do \ { \ static bool lbCPLErrorOnce = false; \ if (!lbCPLErrorOnce) \ { \ lbCPLErrorOnce = true; \ - CPLError(__VA_ARGS__); \ + const char *lCPLErrorMsg = CPLSPrintf(__VA_ARGS__); \ + const size_t lCPLErrorMsgLen = strlen(lCPLErrorMsg); \ + const char *lCPLErrorMsgSuffix = \ + " Further messages of this type will be suppressed."; \ + if (lCPLErrorMsgLen && lCPLErrorMsg[lCPLErrorMsgLen - 1] == '.') \ + CPLError((eErrClass), (err_no), "%s%s", lCPLErrorMsg, \ + lCPLErrorMsgSuffix); \ + else \ + CPLError((eErrClass), (err_no), "%s.%s", lCPLErrorMsg, \ + lCPLErrorMsgSuffix); \ } \ } while (0) +#endif void CPL_DLL CPLErrorV(CPLErr, CPLErrorNum, const char *, va_list); void CPL_DLL CPLEmergencyError(const char *) CPL_NO_RETURN; @@ -189,6 +204,7 @@ void CPL_DLL CPL_STDCALL CPLPopErrorHandler(void); { \ } while (0) /* Eat all CPLDebugProgress calls. */ +#ifdef GDAL_COMPILATION /** Similar to CPLDebug(), but only execute it once during the life-time * of a process. * @@ -198,6 +214,7 @@ void CPL_DLL CPL_STDCALL CPLPopErrorHandler(void); do \ { \ } while (0) +#endif #else void CPL_DLL CPLDebug(const char *, CPL_FORMAT_STRING(const char *), ...) @@ -205,21 +222,32 @@ void CPL_DLL CPLDebug(const char *, CPL_FORMAT_STRING(const char *), ...) void CPL_DLL CPLDebugProgress(const char *, CPL_FORMAT_STRING(const char *), ...) CPL_PRINT_FUNC_FORMAT(2, 3); +#ifdef GDAL_COMPILATION /** Similar to CPLDebug(), but only execute it once during the life-time * of a process. * * @since 3.11 */ -#define CPLDebugOnce(...) \ +#define CPLDebugOnce(category, ...) \ do \ { \ - static bool lbCPLErrorOnce = false; \ - if (!lbCPLErrorOnce) \ + static bool lbCPLDebugOnce = false; \ + if (!lbCPLDebugOnce) \ { \ - lbCPLErrorOnce = true; \ - CPLDebug(__VA_ARGS__); \ + lbCPLDebugOnce = true; \ + const char *lCPLDebugMsg = CPLSPrintf(__VA_ARGS__); \ + const size_t lCPLErrorMsgLen = strlen(lCPLDebugMsg); \ + const char *lCPLDebugMsgSuffix = \ + " Further messages of this type will be suppressed."; \ + if (lCPLErrorMsgLen && lCPLDebugMsg[lCPLErrorMsgLen - 1] == '.') \ + CPLDebug((category), "%s%s", lCPLDebugMsg, \ + lCPLDebugMsgSuffix); \ + else \ + CPLDebug((category), "%s.%s", lCPLDebugMsg, \ + lCPLDebugMsgSuffix); \ } \ } while (0) +#endif #endif