LCOV - code coverage report
Current view: top level - port - cpl_port.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 12 12 100.0 %
Date: 2025-02-20 10:14:44 Functions: 107 113 94.7 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  CPL - Common Portability Library
       4             :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       5             :  * Purpose:  Include file providing low level portability services for CPL.
       6             :  *           This should be the first include file for any CPL based code.
       7             :  *
       8             :  ******************************************************************************
       9             :  * Copyright (c) 1998, 2005, Frank Warmerdam <warmerdam@pobox.com>
      10             :  * Copyright (c) 2008-2013, Even Rouault <even dot rouault at spatialys.com>
      11             :  *
      12             :  * SPDX-License-Identifier: MIT
      13             :  ****************************************************************************/
      14             : 
      15             : #ifndef CPL_BASE_H_INCLUDED
      16             : #define CPL_BASE_H_INCLUDED
      17             : 
      18             : /**
      19             :  * \file cpl_port.h
      20             :  *
      21             :  * Core portability definitions for CPL.
      22             :  *
      23             :  */
      24             : 
      25             : /* -------------------------------------------------------------------- */
      26             : /*      The following apparently allow you to use strcpy() and other    */
      27             : /*      functions judged "unsafe" by microsoft in VS 8 (2005).          */
      28             : /* -------------------------------------------------------------------- */
      29             : #ifdef _MSC_VER
      30             : #ifndef _CRT_SECURE_NO_DEPRECATE
      31             : #define _CRT_SECURE_NO_DEPRECATE
      32             : #endif
      33             : #ifndef _CRT_NONSTDC_NO_DEPRECATE
      34             : #define _CRT_NONSTDC_NO_DEPRECATE
      35             : #endif
      36             : #endif
      37             : 
      38             : #include "cpl_config.h"
      39             : 
      40             : /* ==================================================================== */
      41             : /*      A few sanity checks, mainly to detect problems that sometimes   */
      42             : /*      arise with bad configured cross-compilation.                    */
      43             : /* ==================================================================== */
      44             : 
      45             : #if !defined(SIZEOF_INT) || SIZEOF_INT != 4
      46             : #error "Unexpected value for SIZEOF_INT"
      47             : #endif
      48             : 
      49             : #if !defined(SIZEOF_UNSIGNED_LONG) ||                                          \
      50             :     (SIZEOF_UNSIGNED_LONG != 4 && SIZEOF_UNSIGNED_LONG != 8)
      51             : #error "Unexpected value for SIZEOF_UNSIGNED_LONG"
      52             : #endif
      53             : 
      54             : #if !defined(SIZEOF_VOIDP)
      55             : #error "Unexpected value for SIZEOF_VOIDP"
      56             : #endif
      57             : 
      58             : /* ==================================================================== */
      59             : /*      This will disable most WIN32 stuff in a Cygnus build which      */
      60             : /*      defines unix to 1.                                              */
      61             : /* ==================================================================== */
      62             : 
      63             : #ifdef unix
      64             : #undef WIN32
      65             : #endif
      66             : 
      67             : /*! @cond Doxygen_Suppress */
      68             : #if defined(VSI_NEED_LARGEFILE64_SOURCE) && !defined(_LARGEFILE64_SOURCE)
      69             : #define _LARGEFILE64_SOURCE 1
      70             : #endif
      71             : 
      72             : /* ==================================================================== */
      73             : /*      If iconv() is available use extended recoding module.           */
      74             : /*      Stub implementation is always compiled in, because it works     */
      75             : /*      faster than iconv() for encodings it supports.                  */
      76             : /* ==================================================================== */
      77             : 
      78             : #if defined(HAVE_ICONV)
      79             : #define CPL_RECODE_ICONV
      80             : #endif
      81             : 
      82             : #define CPL_RECODE_STUB
      83             : /*! @endcond */
      84             : 
      85             : /* ==================================================================== */
      86             : /*      MinGW stuff                                                     */
      87             : /* ==================================================================== */
      88             : 
      89             : /* Needed for std=c11 on Solaris to have strcasecmp() */
      90             : #if defined(GDAL_COMPILATION) && defined(__sun__) &&                           \
      91             :     (__STDC_VERSION__ + 0) >= 201112L && (_XOPEN_SOURCE + 0) < 600
      92             : #ifdef _XOPEN_SOURCE
      93             : #undef _XOPEN_SOURCE
      94             : #endif
      95             : #define _XOPEN_SOURCE 600
      96             : #endif
      97             : 
      98             : /* ==================================================================== */
      99             : /*      Standard include files.                                         */
     100             : /* ==================================================================== */
     101             : 
     102             : #include <stdio.h>
     103             : #include <stdlib.h>
     104             : #include <math.h>
     105             : #include <stdarg.h>
     106             : #include <string.h>
     107             : #include <ctype.h>
     108             : #include <limits.h>
     109             : 
     110             : #include <time.h>
     111             : 
     112             : #include <errno.h>
     113             : 
     114             : #ifdef HAVE_LOCALE_H
     115             : #include <locale.h>
     116             : #endif
     117             : 
     118             : #ifdef HAVE_DIRECT_H
     119             : #include <direct.h>
     120             : #endif
     121             : 
     122             : #if !defined(_WIN32)
     123             : #include <strings.h>
     124             : #endif
     125             : 
     126             : #ifdef __cplusplus
     127             : extern "C++"
     128             : {
     129             : #include <cmath>
     130             : }
     131             : #endif
     132             : 
     133             : /* ==================================================================== */
     134             : /*      Base portability stuff ... this stuff may need to be            */
     135             : /*      modified for new platforms.                                     */
     136             : /* ==================================================================== */
     137             : 
     138             : /* -------------------------------------------------------------------- */
     139             : /*      Which versions of C++ are available.                            */
     140             : /* -------------------------------------------------------------------- */
     141             : 
     142             : /* MSVC fails to define a decent value of __cplusplus. Try to target VS2015*/
     143             : /* as a minimum */
     144             : 
     145             : #if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS)
     146             : #if !(__cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900))
     147             : #error Must have C++11 or newer.
     148             : #endif
     149             : #if __cplusplus >= 201402L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
     150             : #define HAVE_CXX14 1
     151             : #endif
     152             : #if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
     153             : #define HAVE_CXX17 1
     154             : #endif
     155             : #endif /* __cplusplus */
     156             : 
     157             : /*---------------------------------------------------------------------
     158             :  *        types for 16 and 32 bits integers, etc...
     159             :  *--------------------------------------------------------------------*/
     160             : #if UINT_MAX == 65535
     161             : typedef long GInt32;
     162             : typedef unsigned long GUInt32;
     163             : #else
     164             : /** Int32 type */
     165             : typedef int GInt32;
     166             : /** Unsigned int32 type */
     167             : typedef unsigned int GUInt32;
     168             : #endif
     169             : 
     170             : /** Int16 type */
     171             : typedef short GInt16;
     172             : /** Unsigned int16 type */
     173             : typedef unsigned short GUInt16;
     174             : /** Unsigned byte type */
     175             : typedef unsigned char GByte;
     176             : /** Signed int8 type */
     177             : typedef signed char GInt8;
     178             : /* hack for PDF driver and poppler >= 0.15.0 that defines incompatible "typedef
     179             :  * bool GBool" */
     180             : /* in include/poppler/goo/gtypes.h */
     181             : #ifndef CPL_GBOOL_DEFINED
     182             : /*! @cond Doxygen_Suppress */
     183             : #define CPL_GBOOL_DEFINED
     184             : /*! @endcond */
     185             : /** Type for boolean values (alias to int) */
     186             : typedef int GBool;
     187             : #endif
     188             : 
     189             : /*! @cond Doxygen_Suppress */
     190             : #ifdef __cplusplus
     191             : #define CPL_STATIC_CAST(type, expr) static_cast<type>(expr)
     192             : #define CPL_REINTERPRET_CAST(type, expr) reinterpret_cast<type>(expr)
     193             : #else
     194             : #define CPL_STATIC_CAST(type, expr) ((type)(expr))
     195             : #define CPL_REINTERPRET_CAST(type, expr) ((type)(expr))
     196             : #endif
     197             : /*! @endcond */
     198             : 
     199             : /* -------------------------------------------------------------------- */
     200             : /*      64bit support                                                   */
     201             : /* -------------------------------------------------------------------- */
     202             : 
     203             : /** Large signed integer type (generally 64-bit integer type).
     204             :  *  Use GInt64 when exactly 64 bit is needed */
     205             : typedef long long GIntBig;
     206             : /** Large unsigned integer type (generally 64-bit unsigned integer type).
     207             :  *  Use GUInt64 when exactly 64 bit is needed */
     208             : typedef unsigned long long GUIntBig;
     209             : 
     210             : /** Minimum GIntBig value */
     211             : #define GINTBIG_MIN (CPL_STATIC_CAST(GIntBig, 0x80000000) << 32)
     212             : /** Maximum GIntBig value */
     213             : #define GINTBIG_MAX ((CPL_STATIC_CAST(GIntBig, 0x7FFFFFFF) << 32) | 0xFFFFFFFFU)
     214             : /** Maximum GUIntBig value */
     215             : #define GUINTBIG_MAX                                                           \
     216             :     ((CPL_STATIC_CAST(GUIntBig, 0xFFFFFFFFU) << 32) | 0xFFFFFFFFU)
     217             : 
     218             : /*! @cond Doxygen_Suppress */
     219             : #define CPL_HAS_GINT64 1
     220             : /*! @endcond */
     221             : 
     222             : /* Note: we might want to use instead int64_t / uint64_t if they are available
     223             :  */
     224             : 
     225             : /** Signed 64 bit integer type */
     226             : typedef GIntBig GInt64;
     227             : /** Unsigned 64 bit integer type */
     228             : typedef GUIntBig GUInt64;
     229             : 
     230             : /** Minimum GInt64 value */
     231             : #define GINT64_MIN GINTBIG_MIN
     232             : /** Maximum GInt64 value */
     233             : #define GINT64_MAX GINTBIG_MAX
     234             : /** Minimum GUInt64 value */
     235             : #define GUINT64_MAX GUINTBIG_MAX
     236             : 
     237             : #if SIZEOF_VOIDP > 8
     238             : #include <stddef.h>  // ptrdiff_t
     239             : /** Integer type large enough to hold the difference between 2 addresses */
     240             : typedef ptrdiff_t GPtrDiff_t;
     241             : #elif SIZEOF_VOIDP == 8
     242             : /** Integer type large enough to hold the difference between 2 addresses */
     243             : typedef GIntBig GPtrDiff_t;
     244             : #else
     245             : /** Integer type large enough to hold the difference between 2 addresses */
     246             : typedef int GPtrDiff_t;
     247             : #endif
     248             : 
     249             : #ifdef GDAL_COMPILATION
     250             : #include <stdint.h>
     251             : typedef uintptr_t GUIntptr_t;
     252             : #define CPL_IS_ALIGNED(ptr, quant)                                             \
     253             :     ((CPL_REINTERPRET_CAST(GUIntptr_t, CPL_STATIC_CAST(const void *, ptr)) %   \
     254             :       (quant)) == 0)
     255             : 
     256             : #endif
     257             : 
     258             : #if (defined(__MSVCRT__) && !(defined(__MINGW64__) && __GNUC__ >= 10)) ||      \
     259             :     (defined(_WIN32) && defined(_MSC_VER))
     260             : #define CPL_FRMT_GB_WITHOUT_PREFIX "I64"
     261             : #else
     262             : /** Printf formatting suffix for GIntBig */
     263             : #define CPL_FRMT_GB_WITHOUT_PREFIX "ll"
     264             : #endif
     265             : 
     266             : /** Printf formatting for GIntBig */
     267             : #define CPL_FRMT_GIB "%" CPL_FRMT_GB_WITHOUT_PREFIX "d"
     268             : /** Printf formatting for GUIntBig */
     269             : #define CPL_FRMT_GUIB "%" CPL_FRMT_GB_WITHOUT_PREFIX "u"
     270             : 
     271             : /*! @cond Doxygen_Suppress */
     272             : #ifdef COMPAT_WITH_ICC_CONVERSION_CHECK
     273             : #define CPL_INT64_FITS_ON_INT32(x) ((x) >= INT_MIN && (x) <= INT_MAX)
     274             : #else
     275             : #define CPL_INT64_FITS_ON_INT32(x)                                             \
     276             :     (CPL_STATIC_CAST(GIntBig, CPL_STATIC_CAST(int, x)) == (x))
     277             : #endif
     278             : /*! @endcond */
     279             : 
     280             : /* ==================================================================== */
     281             : /*      Other standard services.                                        */
     282             : /* ==================================================================== */
     283             : #ifdef __cplusplus
     284             : /** Macro to start a block of C symbols */
     285             : #define CPL_C_START                                                            \
     286             :     extern "C"                                                                 \
     287             :     {
     288             : /** Macro to end a block of C symbols */
     289             : #define CPL_C_END }
     290             : #else
     291             : #define CPL_C_START
     292             : #define CPL_C_END
     293             : #endif
     294             : 
     295             : #ifndef CPL_DLL
     296             : #if defined(_MSC_VER) && !defined(CPL_DISABLE_DLL)
     297             : #ifdef GDAL_COMPILATION
     298             : #define CPL_DLL __declspec(dllexport)
     299             : #else
     300             : #define CPL_DLL
     301             : #endif
     302             : #define CPL_INTERNAL
     303             : #else
     304             : #if defined(USE_GCC_VISIBILITY_FLAG)
     305             : #define CPL_DLL __attribute__((visibility("default")))
     306             : #if !defined(__MINGW32__)
     307             : #define CPL_INTERNAL __attribute__((visibility("hidden")))
     308             : #else
     309             : #define CPL_INTERNAL
     310             : #endif
     311             : #else
     312             : #define CPL_DLL
     313             : #define CPL_INTERNAL
     314             : #endif
     315             : #endif
     316             : 
     317             : // Marker for unstable API
     318             : #define CPL_UNSTABLE_API CPL_DLL
     319             : 
     320             : #endif
     321             : 
     322             : /*! @cond Doxygen_Suppress */
     323             : /* Should optional (normally private) interfaces be exported? */
     324             : #ifdef CPL_OPTIONAL_APIS
     325             : #define CPL_ODLL CPL_DLL
     326             : #else
     327             : #define CPL_ODLL
     328             : #endif
     329             : /*! @endcond */
     330             : 
     331             : #ifndef CPL_STDCALL
     332             : #if defined(_MSC_VER) && !defined(CPL_DISABLE_STDCALL)
     333             : #define CPL_STDCALL __stdcall
     334             : #else
     335             : #define CPL_STDCALL
     336             : #endif
     337             : #endif
     338             : 
     339             : /*! @cond Doxygen_Suppress */
     340             : #ifdef _MSC_VER
     341             : #define FORCE_CDECL __cdecl
     342             : #else
     343             : #define FORCE_CDECL
     344             : #endif
     345             : /*! @endcond */
     346             : 
     347             : /*! @cond Doxygen_Suppress */
     348             : /* TODO : support for other compilers needed */
     349             : #if (defined(__GNUC__) && !defined(__NO_INLINE__)) || defined(_MSC_VER)
     350             : #define HAS_CPL_INLINE 1
     351             : #define CPL_INLINE __inline
     352             : #elif defined(__SUNPRO_CC)
     353             : #define HAS_CPL_INLINE 1
     354             : #define CPL_INLINE inline
     355             : #else
     356             : #define CPL_INLINE
     357             : #endif
     358             : /*! @endcond*/
     359             : 
     360             : #ifndef MAX
     361             : /** Macro to compute the minimum of 2 values */
     362             : #define MIN(a, b) (((a) < (b)) ? (a) : (b))
     363             : /** Macro to compute the maximum of 2 values */
     364             : #define MAX(a, b) (((a) > (b)) ? (a) : (b))
     365             : #endif
     366             : 
     367             : #ifndef ABS
     368             : /** Macro to compute the absolute value */
     369             : #define ABS(x) (((x) < 0) ? (-1 * (x)) : (x))
     370             : #endif
     371             : 
     372             : #ifndef M_PI
     373             : /** PI definition */
     374             : #define M_PI 3.14159265358979323846
     375             : /* 3.1415926535897932384626433832795 */
     376             : #endif
     377             : 
     378             : /* -------------------------------------------------------------------- */
     379             : /*      Macro to test equality of two floating point values.            */
     380             : /*      We use fabs() function instead of ABS() macro to avoid side     */
     381             : /*      effects.                                                        */
     382             : /* -------------------------------------------------------------------- */
     383             : /*! @cond Doxygen_Suppress */
     384             : #ifndef CPLIsEqual
     385             : #define CPLIsEqual(x, y) (fabs((x) - (y)) < 0.0000000000001)
     386             : #endif
     387             : /*! @endcond */
     388             : 
     389             : /* -------------------------------------------------------------------- */
     390             : /*      Provide macros for case insensitive string comparisons.         */
     391             : /* -------------------------------------------------------------------- */
     392             : #ifndef EQUAL
     393             : 
     394             : #if defined(AFL_FRIENDLY) && defined(__GNUC__)
     395             : 
     396             : static inline int CPL_afl_friendly_memcmp(const void *ptr1, const void *ptr2,
     397             :                                           size_t len)
     398             :     __attribute__((always_inline));
     399             : 
     400             : static inline int CPL_afl_friendly_memcmp(const void *ptr1, const void *ptr2,
     401             :                                           size_t len)
     402             : {
     403             :     const unsigned char *bptr1 = (const unsigned char *)ptr1;
     404             :     const unsigned char *bptr2 = (const unsigned char *)ptr2;
     405             :     while (len--)
     406             :     {
     407             :         unsigned char b1 = *(bptr1++);
     408             :         unsigned char b2 = *(bptr2++);
     409             :         if (b1 != b2)
     410             :             return b1 - b2;
     411             :     }
     412             :     return 0;
     413             : }
     414             : 
     415             : static inline int CPL_afl_friendly_strcmp(const char *ptr1, const char *ptr2)
     416             :     __attribute__((always_inline));
     417             : 
     418             : static inline int CPL_afl_friendly_strcmp(const char *ptr1, const char *ptr2)
     419             : {
     420             :     const unsigned char *usptr1 = (const unsigned char *)ptr1;
     421             :     const unsigned char *usptr2 = (const unsigned char *)ptr2;
     422             :     while (1)
     423             :     {
     424             :         unsigned char ch1 = *(usptr1++);
     425             :         unsigned char ch2 = *(usptr2++);
     426             :         if (ch1 == 0 || ch1 != ch2)
     427             :             return ch1 - ch2;
     428             :     }
     429             : }
     430             : 
     431             : static inline int CPL_afl_friendly_strncmp(const char *ptr1, const char *ptr2,
     432             :                                            size_t len)
     433             :     __attribute__((always_inline));
     434             : 
     435             : static inline int CPL_afl_friendly_strncmp(const char *ptr1, const char *ptr2,
     436             :                                            size_t len)
     437             : {
     438             :     const unsigned char *usptr1 = (const unsigned char *)ptr1;
     439             :     const unsigned char *usptr2 = (const unsigned char *)ptr2;
     440             :     while (len--)
     441             :     {
     442             :         unsigned char ch1 = *(usptr1++);
     443             :         unsigned char ch2 = *(usptr2++);
     444             :         if (ch1 == 0 || ch1 != ch2)
     445             :             return ch1 - ch2;
     446             :     }
     447             :     return 0;
     448             : }
     449             : 
     450             : static inline int CPL_afl_friendly_strcasecmp(const char *ptr1,
     451             :                                               const char *ptr2)
     452             :     __attribute__((always_inline));
     453             : 
     454             : static inline int CPL_afl_friendly_strcasecmp(const char *ptr1,
     455             :                                               const char *ptr2)
     456             : {
     457             :     const unsigned char *usptr1 = (const unsigned char *)ptr1;
     458             :     const unsigned char *usptr2 = (const unsigned char *)ptr2;
     459             :     while (1)
     460             :     {
     461             :         unsigned char ch1 = *(usptr1++);
     462             :         unsigned char ch2 = *(usptr2++);
     463             :         ch1 = (unsigned char)toupper(ch1);
     464             :         ch2 = (unsigned char)toupper(ch2);
     465             :         if (ch1 == 0 || ch1 != ch2)
     466             :             return ch1 - ch2;
     467             :     }
     468             : }
     469             : 
     470             : static inline int CPL_afl_friendly_strncasecmp(const char *ptr1,
     471             :                                                const char *ptr2, size_t len)
     472             :     __attribute__((always_inline));
     473             : 
     474             : static inline int CPL_afl_friendly_strncasecmp(const char *ptr1,
     475             :                                                const char *ptr2, size_t len)
     476             : {
     477             :     const unsigned char *usptr1 = (const unsigned char *)ptr1;
     478             :     const unsigned char *usptr2 = (const unsigned char *)ptr2;
     479             :     while (len--)
     480             :     {
     481             :         unsigned char ch1 = *(usptr1++);
     482             :         unsigned char ch2 = *(usptr2++);
     483             :         ch1 = (unsigned char)toupper(ch1);
     484             :         ch2 = (unsigned char)toupper(ch2);
     485             :         if (ch1 == 0 || ch1 != ch2)
     486             :             return ch1 - ch2;
     487             :     }
     488             :     return 0;
     489             : }
     490             : 
     491             : static inline char *CPL_afl_friendly_strstr(const char *haystack,
     492             :                                             const char *needle)
     493             :     __attribute__((always_inline));
     494             : 
     495             : static inline char *CPL_afl_friendly_strstr(const char *haystack,
     496             :                                             const char *needle)
     497             : {
     498             :     const char *ptr_haystack = haystack;
     499             :     while (1)
     500             :     {
     501             :         const char *ptr_haystack2 = ptr_haystack;
     502             :         const char *ptr_needle = needle;
     503             :         while (1)
     504             :         {
     505             :             char ch1 = *(ptr_haystack2++);
     506             :             char ch2 = *(ptr_needle++);
     507             :             if (ch2 == 0)
     508             :                 return (char *)ptr_haystack;
     509             :             if (ch1 != ch2)
     510             :                 break;
     511             :         }
     512             :         if (*ptr_haystack == 0)
     513             :             return NULL;
     514             :         ptr_haystack++;
     515             :     }
     516             : }
     517             : 
     518             : #undef strcmp
     519             : #undef strncmp
     520             : #define memcmp CPL_afl_friendly_memcmp
     521             : #define strcmp CPL_afl_friendly_strcmp
     522             : #define strncmp CPL_afl_friendly_strncmp
     523             : #define strcasecmp CPL_afl_friendly_strcasecmp
     524             : #define strncasecmp CPL_afl_friendly_strncasecmp
     525             : #define strstr CPL_afl_friendly_strstr
     526             : 
     527             : #endif /* defined(AFL_FRIENDLY) && defined(__GNUC__) */
     528             : 
     529             : #if defined(_WIN32)
     530             : #define STRCASECMP(a, b) (_stricmp(a, b))
     531             : #define STRNCASECMP(a, b, n) (_strnicmp(a, b, n))
     532             : #else
     533             : /** Alias for strcasecmp() */
     534             : #define STRCASECMP(a, b) (strcasecmp(a, b))
     535             : /** Alias for strncasecmp() */
     536             : #define STRNCASECMP(a, b, n) (strncasecmp(a, b, n))
     537             : #endif
     538             : /** Alias for strncasecmp() == 0 */
     539             : #define EQUALN(a, b, n) (STRNCASECMP(a, b, n) == 0)
     540             : /** Alias for strcasecmp() == 0 */
     541             : #define EQUAL(a, b) (STRCASECMP(a, b) == 0)
     542             : #endif
     543             : 
     544             : /*---------------------------------------------------------------------
     545             :  * Does a string "a" start with string "b".  Search is case-sensitive or,
     546             :  * with CI, it is a case-insensitive comparison.
     547             :  *--------------------------------------------------------------------- */
     548             : #ifndef STARTS_WITH_CI
     549             : /** Returns whether a starts with b */
     550             : #define STARTS_WITH(a, b) (strncmp(a, b, strlen(b)) == 0)
     551             : /** Returns whether a starts with b (case insensitive comparison) */
     552             : #define STARTS_WITH_CI(a, b) EQUALN(a, b, strlen(b))
     553             : #endif
     554             : 
     555             : /*! @cond Doxygen_Suppress */
     556             : #ifndef CPL_THREADLOCAL
     557             : #define CPL_THREADLOCAL
     558             : #endif
     559             : /*! @endcond */
     560             : 
     561             : /*! @cond Doxygen_Suppress */
     562             : #ifndef __cplusplus
     563             : /* -------------------------------------------------------------------- */
     564             : /*      Handle isnan() and isinf().  Note that isinf() and isnan()      */
     565             : /*      are supposed to be macros according to C99, defined in math.h   */
     566             : /*      Some systems (i.e. Tru64) don't have isinf() at all, so if      */
     567             : /*      the macro is not defined we just assume nothing is infinite.    */
     568             : /*      This may mean we have no real CPLIsInf() on systems with isinf()*/
     569             : /*      function but no corresponding macro, but I can live with        */
     570             : /*      that since it isn't that important a test.                      */
     571             : /* -------------------------------------------------------------------- */
     572             : #ifdef _MSC_VER
     573             : #include <float.h>
     574             : #define CPLIsNan(x) _isnan(x)
     575             : #define CPLIsInf(x) (!_isnan(x) && !_finite(x))
     576             : #define CPLIsFinite(x) _finite(x)
     577             : #elif defined(__GNUC__) &&                                                     \
     578             :     (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))
     579             : /* When including <cmath> in C++11 the isnan() macro is undefined, so that */
     580             : /* std::isnan() can work (#6489). This is a GCC specific workaround for now. */
     581             : #define CPLIsNan(x) __builtin_isnan(x)
     582             : #define CPLIsInf(x) __builtin_isinf(x)
     583             : #define CPLIsFinite(x) __builtin_isfinite(x)
     584             : #elif defined(isinf) || defined(__FreeBSD__)
     585             : /** Return whether a floating-pointer number is nan */
     586             : #define CPLIsNan(x) isnan(x)
     587             : /** Return whether a floating-pointer number is +/- infinity */
     588             : #define CPLIsInf(x) isinf(x)
     589             : /** Return whether a floating-pointer number is finite */
     590             : #define CPLIsFinite(x) (!isnan(x) && !isinf(x))
     591             : #elif defined(__sun__)
     592             : #include <ieeefp.h>
     593             : #define CPLIsNan(x) isnan(x)
     594             : #define CPLIsInf(x) (!finite(x) && !isnan(x))
     595             : #define CPLIsFinite(x) finite(x)
     596             : #else
     597             : #define CPLIsNan(x) ((x) != (x))
     598             : #define CPLIsInf(x) (0)
     599             : #define CPLIsFinite(x) (!isnan(x))
     600             : #endif
     601             : #endif
     602             : /*! @endcond */
     603             : 
     604             : /*! @cond Doxygen_Suppress */
     605             : /*---------------------------------------------------------------------
     606             :  *                         CPL_LSB and CPL_MSB
     607             :  * Only one of these 2 macros should be defined and specifies the byte
     608             :  * ordering for the current platform.
     609             :  * This should be defined in the Makefile, but if it is not then
     610             :  * the default is CPL_LSB (Intel ordering, LSB first).
     611             :  *--------------------------------------------------------------------*/
     612             : #if defined(WORDS_BIGENDIAN) && !defined(CPL_MSB) && !defined(CPL_LSB)
     613             : #define CPL_MSB
     614             : #endif
     615             : 
     616             : #if !(defined(CPL_LSB) || defined(CPL_MSB))
     617             : #define CPL_LSB
     618             : #endif
     619             : 
     620             : #if defined(CPL_LSB)
     621             : #define CPL_IS_LSB 1
     622             : #else
     623             : #define CPL_IS_LSB 0
     624             : #endif
     625             : /*! @endcond */
     626             : 
     627             : #if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS)
     628             : 
     629             : /*! @cond Doxygen_Suppress */
     630             : extern "C++"
     631             : {
     632             : 
     633             :     template <bool b> struct CPLStaticAssert
     634             :     {
     635             :     };
     636             : 
     637             :     template <> struct CPLStaticAssert<true>
     638             :     {
     639   292034199 :         static void my_function()
     640             :         {
     641   292034199 :         }
     642             :     };
     643             : 
     644             : } /* extern "C++" */
     645             : 
     646             : #define CPL_STATIC_ASSERT(x) CPLStaticAssert<x>::my_function()
     647             : #define CPL_STATIC_ASSERT_IF_AVAILABLE(x) CPL_STATIC_ASSERT(x)
     648             : 
     649             : #else /* __cplusplus */
     650             : 
     651             : #define CPL_STATIC_ASSERT_IF_AVAILABLE(x)
     652             : 
     653             : #endif /* __cplusplus */
     654             : /*! @endcond */
     655             : 
     656             : /*---------------------------------------------------------------------
     657             :  *        Little endian <==> big endian byte swap macros.
     658             :  *--------------------------------------------------------------------*/
     659             : 
     660             : /** Byte-swap a 16bit unsigned integer */
     661             : #define CPL_SWAP16(x)                                                          \
     662             :     CPL_STATIC_CAST(GUInt16, (CPL_STATIC_CAST(GUInt16, x) << 8) |              \
     663             :                                  (CPL_STATIC_CAST(GUInt16, x) >> 8))
     664             : 
     665             : #if defined(HAVE_GCC_BSWAP)
     666             : /** Byte-swap a 32bit unsigned integer */
     667             : #define CPL_SWAP32(x)                                                          \
     668             :     CPL_STATIC_CAST(GUInt32, __builtin_bswap32(CPL_STATIC_CAST(GUInt32, x)))
     669             : /** Byte-swap a 64bit unsigned integer */
     670             : #define CPL_SWAP64(x)                                                          \
     671             :     CPL_STATIC_CAST(GUInt64, __builtin_bswap64(CPL_STATIC_CAST(GUInt64, x)))
     672             : #elif defined(_MSC_VER)
     673             : #define CPL_SWAP32(x)                                                          \
     674             :     CPL_STATIC_CAST(GUInt32, _byteswap_ulong(CPL_STATIC_CAST(GUInt32, x)))
     675             : #define CPL_SWAP64(x)                                                          \
     676             :     CPL_STATIC_CAST(GUInt64, _byteswap_uint64(CPL_STATIC_CAST(GUInt64, x)))
     677             : #else
     678             : /** Byte-swap a 32bit unsigned integer */
     679             : #define CPL_SWAP32(x)                                                          \
     680             :     CPL_STATIC_CAST(GUInt32,                                                   \
     681             :                     ((CPL_STATIC_CAST(GUInt32, x) & 0x000000ffU) << 24) |      \
     682             :                         ((CPL_STATIC_CAST(GUInt32, x) & 0x0000ff00U) << 8) |   \
     683             :                         ((CPL_STATIC_CAST(GUInt32, x) & 0x00ff0000U) >> 8) |   \
     684             :                         ((CPL_STATIC_CAST(GUInt32, x) & 0xff000000U) >> 24))
     685             : 
     686             : /** Byte-swap a 64bit unsigned integer */
     687             : #define CPL_SWAP64(x)                                                          \
     688             :     ((CPL_STATIC_CAST(GUInt64, CPL_SWAP32(CPL_STATIC_CAST(GUInt32, x)))        \
     689             :       << 32) |                                                                 \
     690             :      (CPL_STATIC_CAST(GUInt64,                                                 \
     691             :                       CPL_SWAP32(CPL_STATIC_CAST(                              \
     692             :                           GUInt32, CPL_STATIC_CAST(GUInt64, x) >> 32)))))
     693             : 
     694             : #endif
     695             : 
     696             : /** Byte-swap a 16 bit pointer */
     697             : #define CPL_SWAP16PTR(x)                                                       \
     698             :     do                                                                         \
     699             :     {                                                                          \
     700             :         GUInt16 _n16;                                                          \
     701             :         void *_lx = x;                                                         \
     702             :         memcpy(&_n16, _lx, 2);                                                 \
     703             :         CPL_STATIC_ASSERT_IF_AVAILABLE(sizeof(*(x)) == 1 ||                    \
     704             :                                        sizeof(*(x)) == 2);                     \
     705             :         _n16 = CPL_SWAP16(_n16);                                               \
     706             :         memcpy(_lx, &_n16, 2);                                                 \
     707             :     } while (0)
     708             : 
     709             : /** Byte-swap a 32 bit pointer */
     710             : #define CPL_SWAP32PTR(x)                                                       \
     711             :     do                                                                         \
     712             :     {                                                                          \
     713             :         GUInt32 _n32;                                                          \
     714             :         void *_lx = x;                                                         \
     715             :         memcpy(&_n32, _lx, 4);                                                 \
     716             :         CPL_STATIC_ASSERT_IF_AVAILABLE(sizeof(*(x)) == 1 ||                    \
     717             :                                        sizeof(*(x)) == 4);                     \
     718             :         _n32 = CPL_SWAP32(_n32);                                               \
     719             :         memcpy(_lx, &_n32, 4);                                                 \
     720             :     } while (0)
     721             : 
     722             : /** Byte-swap a 64 bit pointer */
     723             : #define CPL_SWAP64PTR(x)                                                       \
     724             :     do                                                                         \
     725             :     {                                                                          \
     726             :         GUInt64 _n64;                                                          \
     727             :         void *_lx = x;                                                         \
     728             :         memcpy(&_n64, _lx, 8);                                                 \
     729             :         CPL_STATIC_ASSERT_IF_AVAILABLE(sizeof(*(x)) == 1 ||                    \
     730             :                                        sizeof(*(x)) == 8);                     \
     731             :         _n64 = CPL_SWAP64(_n64);                                               \
     732             :         memcpy(_lx, &_n64, 8);                                                 \
     733             :     } while (0)
     734             : 
     735             : /** Byte-swap a 64 bit pointer */
     736             : #define CPL_SWAPDOUBLE(p) CPL_SWAP64PTR(p)
     737             : 
     738             : #ifdef CPL_MSB
     739             : #define CPL_MSBWORD16(x) (x)
     740             : #define CPL_LSBWORD16(x) CPL_SWAP16(x)
     741             : #define CPL_MSBWORD32(x) (x)
     742             : #define CPL_LSBWORD32(x) CPL_SWAP32(x)
     743             : #define CPL_MSBPTR16(x)                                                        \
     744             :     CPL_STATIC_ASSERT_IF_AVAILABLE(sizeof(*(x)) == 1 || sizeof(*(x)) == 2)
     745             : #define CPL_LSBPTR16(x) CPL_SWAP16PTR(x)
     746             : #define CPL_MSBPTR32(x)                                                        \
     747             :     CPL_STATIC_ASSERT_IF_AVAILABLE(sizeof(*(x)) == 1 || sizeof(*(x)) == 4)
     748             : #define CPL_LSBPTR32(x) CPL_SWAP32PTR(x)
     749             : #define CPL_MSBPTR64(x)                                                        \
     750             :     CPL_STATIC_ASSERT_IF_AVAILABLE(sizeof(*(x)) == 1 || sizeof(*(x)) == 8)
     751             : #define CPL_LSBPTR64(x) CPL_SWAP64PTR(x)
     752             : #else
     753             : /** Return a 16bit word from a originally LSB ordered word */
     754             : #define CPL_LSBWORD16(x) (x)
     755             : /** Return a 16bit word from a originally MSB ordered word */
     756             : #define CPL_MSBWORD16(x) CPL_SWAP16(x)
     757             : /** Return a 32bit word from a originally LSB ordered word */
     758             : #define CPL_LSBWORD32(x) (x)
     759             : /** Return a 32bit word from a originally MSB ordered word */
     760             : #define CPL_MSBWORD32(x) CPL_SWAP32(x)
     761             : /** Byte-swap if necessary a 16bit word at the location pointed from a
     762             :  * originally LSB ordered pointer */
     763             : #define CPL_LSBPTR16(x)                                                        \
     764             :     CPL_STATIC_ASSERT_IF_AVAILABLE(sizeof(*(x)) == 1 || sizeof(*(x)) == 2)
     765             : /** Byte-swap if necessary a 16bit word at the location pointed from a
     766             :  * originally MSB ordered pointer */
     767             : #define CPL_MSBPTR16(x) CPL_SWAP16PTR(x)
     768             : /** Byte-swap if necessary a 32bit word at the location pointed from a
     769             :  * originally LSB ordered pointer */
     770             : #define CPL_LSBPTR32(x)                                                        \
     771             :     CPL_STATIC_ASSERT_IF_AVAILABLE(sizeof(*(x)) == 1 || sizeof(*(x)) == 4)
     772             : /** Byte-swap if necessary a 32bit word at the location pointed from a
     773             :  * originally MSB ordered pointer */
     774             : #define CPL_MSBPTR32(x) CPL_SWAP32PTR(x)
     775             : /** Byte-swap if necessary a 64bit word at the location pointed from a
     776             :  * originally LSB ordered pointer */
     777             : #define CPL_LSBPTR64(x)                                                        \
     778             :     CPL_STATIC_ASSERT_IF_AVAILABLE(sizeof(*(x)) == 1 || sizeof(*(x)) == 8)
     779             : /** Byte-swap if necessary a 64bit word at the location pointed from a
     780             :  * originally MSB ordered pointer */
     781             : #define CPL_MSBPTR64(x) CPL_SWAP64PTR(x)
     782             : #endif
     783             : 
     784             : /** Return a Int16 from the 2 bytes ordered in LSB order at address x.
     785             :  * @deprecated Use rather CPL_LSBSINT16PTR or CPL_LSBUINT16PTR for explicit
     786             :  * signedness. */
     787             : #define CPL_LSBINT16PTR(x)                                                     \
     788             :     ((*CPL_REINTERPRET_CAST(const GByte *, x)) |                               \
     789             :      (*((CPL_REINTERPRET_CAST(const GByte *, x)) + 1) << 8))
     790             : 
     791             : /** Return a Int32 from the 4 bytes ordered in LSB order at address x.
     792             :  * @deprecated Use rather CPL_LSBSINT32PTR or CPL_LSBUINT32PTR for explicit
     793             :  * signedness. */
     794             : #define CPL_LSBINT32PTR(x)                                                     \
     795             :     ((*CPL_REINTERPRET_CAST(const GByte *, x)) |                               \
     796             :      (*((CPL_REINTERPRET_CAST(const GByte *, x)) + 1) << 8) |                  \
     797             :      (*((CPL_REINTERPRET_CAST(const GByte *, x)) + 2) << 16) |                 \
     798             :      (*((CPL_REINTERPRET_CAST(const GByte *, x)) + 3) << 24))
     799             : 
     800             : /** Return a signed Int16 from the 2 bytes ordered in LSB order at address x */
     801             : #define CPL_LSBSINT16PTR(x) CPL_STATIC_CAST(GInt16, CPL_LSBINT16PTR(x))
     802             : 
     803             : /** Return a unsigned Int16 from the 2 bytes ordered in LSB order at address x
     804             :  */
     805             : #define CPL_LSBUINT16PTR(x) CPL_STATIC_CAST(GUInt16, CPL_LSBINT16PTR(x))
     806             : 
     807             : /** Return a signed Int32 from the 4 bytes ordered in LSB order at address x */
     808             : #define CPL_LSBSINT32PTR(x) CPL_STATIC_CAST(GInt32, CPL_LSBINT32PTR(x))
     809             : 
     810             : /** Return a unsigned Int32 from the 4 bytes ordered in LSB order at address x
     811             :  */
     812             : #define CPL_LSBUINT32PTR(x) CPL_STATIC_CAST(GUInt32, CPL_LSBINT32PTR(x))
     813             : 
     814             : /*! @cond Doxygen_Suppress */
     815             : /* Utility macro to explicitly mark intentionally unreferenced parameters. */
     816             : #ifndef UNREFERENCED_PARAM
     817             : #ifdef UNREFERENCED_PARAMETER /* May be defined by Windows API */
     818             : #define UNREFERENCED_PARAM(param) UNREFERENCED_PARAMETER(param)
     819             : #else
     820             : #define UNREFERENCED_PARAM(param) ((void)param)
     821             : #endif /* UNREFERENCED_PARAMETER */
     822             : #endif /* UNREFERENCED_PARAM */
     823             : /*! @endcond */
     824             : 
     825             : /***********************************************************************
     826             :  * Define CPL_CVSID() macro.  It can be disabled during a build by
     827             :  * defining DISABLE_CVSID in the compiler options.
     828             :  *
     829             :  * The cvsid_aw() function is just there to prevent reports of cpl_cvsid()
     830             :  * being unused.
     831             :  */
     832             : 
     833             : /*! @cond Doxygen_Suppress */
     834             : #ifndef DISABLE_CVSID
     835             : #if defined(__GNUC__) && __GNUC__ >= 4
     836             : #define CPL_CVSID(string)                                                      \
     837             :     static const char cpl_cvsid[] __attribute__((used)) = string;
     838             : #else
     839             : #define CPL_CVSID(string)                                                      \
     840             :     static const char cpl_cvsid[] = string;                                    \
     841             :     static const char *cvsid_aw()                                              \
     842             :     {                                                                          \
     843             :         return (cvsid_aw() ? NULL : cpl_cvsid);                                \
     844             :     }
     845             : #endif
     846             : #else
     847             : #define CPL_CVSID(string)
     848             : #endif
     849             : /*! @endcond */
     850             : 
     851             : /* We exclude mingw64 4.6 which seems to be broken regarding this */
     852             : #if defined(__GNUC__) && __GNUC__ >= 4 && !defined(DOXYGEN_SKIP) &&            \
     853             :     !(defined(__MINGW64__) && __GNUC__ == 4 && __GNUC_MINOR__ == 6)
     854             : /** Null terminated variadic */
     855             : #define CPL_NULL_TERMINATED __attribute__((__sentinel__))
     856             : #else
     857             : /** Null terminated variadic */
     858             : #define CPL_NULL_TERMINATED
     859             : #endif
     860             : 
     861             : #if defined(__GNUC__) && __GNUC__ >= 3 && !defined(DOXYGEN_SKIP)
     862             : /** Tag a function to have printf() formatting */
     863             : #define CPL_PRINT_FUNC_FORMAT(format_idx, arg_idx)                             \
     864             :     __attribute__((__format__(__printf__, format_idx, arg_idx)))
     865             : /** Tag a function to have scanf() formatting */
     866             : #define CPL_SCAN_FUNC_FORMAT(format_idx, arg_idx)                              \
     867             :     __attribute__((__format__(__scanf__, format_idx, arg_idx)))
     868             : #else
     869             : /** Tag a function to have printf() formatting */
     870             : #define CPL_PRINT_FUNC_FORMAT(format_idx, arg_idx)
     871             : /** Tag a function to have scanf() formatting */
     872             : #define CPL_SCAN_FUNC_FORMAT(format_idx, arg_idx)
     873             : #endif
     874             : 
     875             : #if defined(_MSC_VER) &&                                                       \
     876             :     (defined(GDAL_COMPILATION) || defined(CPL_ENABLE_MSVC_ANNOTATIONS))
     877             : #include <sal.h>
     878             : /** Macro into which to wrap the format argument of a printf-like function.
     879             :  * Only used if ANALYZE=1 is specified to nmake */
     880             : #define CPL_FORMAT_STRING(arg) _Printf_format_string_ arg
     881             : /** Macro into which to wrap the format argument of a sscanf-like function.
     882             :  * Only used if ANALYZE=1 is specified to nmake */
     883             : #define CPL_SCANF_FORMAT_STRING(arg) _Scanf_format_string_ arg
     884             : #else
     885             : /** Macro into which to wrap the format argument of a printf-like function */
     886             : #define CPL_FORMAT_STRING(arg) arg
     887             : /** Macro into which to wrap the format argument of a sscanf-like function. */
     888             : #define CPL_SCANF_FORMAT_STRING(arg) arg
     889             : #endif /* defined(_MSC_VER) && defined(GDAL_COMPILATION) */
     890             : 
     891             : #if defined(__GNUC__) && __GNUC__ >= 4 && !defined(DOXYGEN_SKIP)
     892             : /** Qualifier to warn when the return value of a function is not used */
     893             : #define CPL_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
     894             : #else
     895             : /** Qualifier to warn when the return value of a function is not used */
     896             : #define CPL_WARN_UNUSED_RESULT
     897             : #endif
     898             : 
     899             : #if defined(__GNUC__) && __GNUC__ >= 4
     900             : /** Qualifier for an argument that is unused */
     901             : #define CPL_UNUSED __attribute((__unused__))
     902             : #else
     903             : /* TODO: add cases for other compilers */
     904             : /** Qualifier for an argument that is unused */
     905             : #define CPL_UNUSED
     906             : #endif
     907             : 
     908             : #if defined(__GNUC__) && __GNUC__ >= 3 && !defined(DOXYGEN_SKIP)
     909             : /** Qualifier for a function that does not return at all (terminates the
     910             :  * process) */
     911             : #define CPL_NO_RETURN __attribute__((noreturn))
     912             : #else
     913             : /** Qualifier for a function that does not return at all (terminates the
     914             :  * process) */
     915             : #define CPL_NO_RETURN
     916             : #endif
     917             : 
     918             : /*! @cond Doxygen_Suppress */
     919             : /* Clang __has_attribute */
     920             : #ifndef __has_attribute
     921             : #define __has_attribute(x) 0  // Compatibility with non-clang compilers.
     922             : #endif
     923             : 
     924             : /*! @endcond */
     925             : 
     926             : #if ((defined(__GNUC__) &&                                                     \
     927             :       (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9))) ||            \
     928             :      __has_attribute(returns_nonnull)) &&                                      \
     929             :     !defined(DOXYGEN_SKIP) && !defined(__INTEL_COMPILER)
     930             : /** Qualifier for a function that does not return NULL */
     931             : #define CPL_RETURNS_NONNULL __attribute__((returns_nonnull))
     932             : #else
     933             : /** Qualifier for a function that does not return NULL */
     934             : #define CPL_RETURNS_NONNULL
     935             : #endif
     936             : 
     937             : #if defined(__GNUC__) && __GNUC__ >= 4 && !defined(DOXYGEN_SKIP)
     938             : /** restrict keyword to declare that pointers do not alias */
     939             : #define CPL_RESTRICT __restrict__
     940             : #else
     941             : /** restrict keyword to declare that pointers do not alias */
     942             : #define CPL_RESTRICT
     943             : #endif
     944             : 
     945             : #if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS)
     946             : 
     947             : /** To be used in public headers only. For non-public headers or .cpp files,
     948             :  * use override directly. */
     949             : #define CPL_OVERRIDE override
     950             : 
     951             : /** C++11 final qualifier */
     952             : #define CPL_FINAL final
     953             : 
     954             : /** Mark that a class is explicitly recognized as non-final */
     955             : #define CPL_NON_FINAL
     956             : 
     957             : /** Helper to remove the copy and assignment constructors so that the compiler
     958             :    will not generate the default versions.
     959             : 
     960             :    Must be placed in the private section of a class and should be at the end.
     961             : */
     962             : #define CPL_DISALLOW_COPY_ASSIGN(ClassName)                                    \
     963             :     ClassName(const ClassName &) = delete;                                     \
     964             :     ClassName &operator=(const ClassName &) = delete;
     965             : 
     966             : #endif /* __cplusplus */
     967             : 
     968             : #if !defined(DOXYGEN_SKIP) && !defined(CPL_WARN_DEPRECATED)
     969             : #if defined(__has_extension)
     970             : #if __has_extension(attribute_deprecated_with_message)
     971             : /* Clang extension */
     972             : #define CPL_WARN_DEPRECATED(x) __attribute__((deprecated(x)))
     973             : #else
     974             : #define CPL_WARN_DEPRECATED(x)
     975             : #endif
     976             : #elif defined(__GNUC__)
     977             : #define CPL_WARN_DEPRECATED(x) __attribute__((deprecated))
     978             : #else
     979             : #define CPL_WARN_DEPRECATED(x)
     980             : #endif
     981             : #endif
     982             : 
     983             : #if !defined(_MSC_VER) && !defined(__APPLE__) && !defined(_FORTIFY_SOURCE)
     984             : CPL_C_START
     985             : #if defined(GDAL_COMPILATION) && defined(WARN_STANDARD_PRINTF)
     986             : int vsnprintf(char *str, size_t size, const char *fmt, va_list args)
     987             :     CPL_WARN_DEPRECATED("Use CPLvsnprintf() instead");
     988             : int snprintf(char *str, size_t size, const char *fmt, ...)
     989             :     CPL_PRINT_FUNC_FORMAT(3, 4)
     990             :         CPL_WARN_DEPRECATED("Use CPLsnprintf() instead");
     991             : int sprintf(char *str, const char *fmt, ...) CPL_PRINT_FUNC_FORMAT(2, 3)
     992             :     CPL_WARN_DEPRECATED("Use CPLsnprintf() instead");
     993             : #elif defined(GDAL_COMPILATION) && !defined(DONT_DEPRECATE_SPRINTF)
     994             : int sprintf(char *str, const char *fmt, ...) CPL_PRINT_FUNC_FORMAT(2, 3)
     995             :     CPL_WARN_DEPRECATED("Use snprintf() or CPLsnprintf() instead");
     996             : #endif /* defined(GDAL_COMPILATION) && defined(WARN_STANDARD_PRINTF) */
     997             : CPL_C_END
     998             : #endif /* !defined(_MSC_VER) && !defined(__APPLE__) */
     999             : 
    1000             : #if defined(__cplusplus)
    1001             : #ifndef CPPCHECK
    1002             : /** Returns the size of C style arrays. */
    1003             : #define CPL_ARRAYSIZE(array)                                                   \
    1004             :     ((sizeof(array) / sizeof(*(array))) /                                      \
    1005             :      static_cast<size_t>(!(sizeof(array) % sizeof(*(array)))))
    1006             : #else
    1007             : /* simplified version for cppcheck */
    1008             : #define CPL_ARRAYSIZE(array) (sizeof(array) / sizeof(array[0]))
    1009             : #endif
    1010             : 
    1011             : extern "C++"
    1012             : {
    1013    11574392 :     template <class T> static void CPL_IGNORE_RET_VAL(const T &)
    1014             :     {
    1015    11548989 :     }
    1016             : 
    1017    78925312 :     inline static bool CPL_TO_BOOL(int x)
    1018             :     {
    1019    78925312 :         return x != 0;
    1020             :     }
    1021             : } /* extern "C++" */
    1022             : 
    1023             : #endif /* __cplusplus */
    1024             : 
    1025             : #if (((__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) ||              \
    1026             :       (defined(__clang__) && __clang_major__ >= 3)) &&                         \
    1027             :      !defined(_MSC_VER))
    1028             : #define HAVE_GCC_DIAGNOSTIC_PUSH
    1029             : #endif
    1030             : 
    1031             : #if ((__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2)) &&               \
    1032             :      !defined(_MSC_VER))
    1033             : #define HAVE_GCC_SYSTEM_HEADER
    1034             : #endif
    1035             : 
    1036             : /*! @cond Doxygen_Suppress */
    1037             : 
    1038             : #ifndef FALSE
    1039             : #define FALSE 0
    1040             : #endif
    1041             : 
    1042             : #ifndef TRUE
    1043             : #define TRUE 1
    1044             : #endif
    1045             : 
    1046             : #if __clang_major__ >= 4 || (__clang_major__ == 3 && __clang_minor__ >= 8)
    1047             : #define CPL_NOSANITIZE_UNSIGNED_INT_OVERFLOW                                   \
    1048             :     __attribute__((no_sanitize("unsigned-integer-overflow")))
    1049             : #else
    1050             : #define CPL_NOSANITIZE_UNSIGNED_INT_OVERFLOW
    1051             : #endif
    1052             : 
    1053             : #if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS) &&                 \
    1054             :     defined(GDAL_COMPILATION)
    1055             : extern "C++"
    1056             : {
    1057             :     template <class C, class A, class B>
    1058    21537655 :     CPL_NOSANITIZE_UNSIGNED_INT_OVERFLOW inline C CPLUnsanitizedAdd(A a, B b)
    1059             :     {
    1060    21537655 :         return a + b;
    1061             :     }
    1062             : }
    1063             : #endif
    1064             : 
    1065             : #if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS)
    1066             : #define CPL_NULLPTR nullptr
    1067             : #else
    1068             : #define CPL_NULLPTR NULL
    1069             : #endif
    1070             : 
    1071             : #if defined(__cplusplus) && defined(GDAL_COMPILATION)
    1072             : extern "C++"
    1073             : {
    1074             :     namespace cpl
    1075             :     {
    1076             :     /** Function to indicate that the result of an arithmetic operation
    1077             :          * does fit on the specified type. Typically used to avoid warnings
    1078             :          * about potentially overflowing multiplications by static analyzers.
    1079             :          */
    1080      162974 :     template <typename T> inline T fits_on(T t)
    1081             :     {
    1082      162974 :         return t;
    1083             :     }
    1084             : 
    1085             :     /** Emulates the C++20 .contains() method */
    1086             :     template <typename C, typename V>
    1087     3046231 :     inline bool contains(const C &container, const V &value)
    1088             :     {
    1089     3046231 :         return container.find(value) != container.end();
    1090             :     }
    1091             : 
    1092             :     }  // namespace cpl
    1093             : }
    1094             : #endif
    1095             : 
    1096             : /*! @endcond */
    1097             : 
    1098             : /* This typedef is for C functions that take char** as argument, but */
    1099             : /* with the semantics of a const list. In C, char** is not implicitly cast to */
    1100             : /* const char* const*, contrary to C++. So when seen for C++, it is OK */
    1101             : /* to expose the prototypes as const char* const*, but for C we keep the */
    1102             : /* historical definition to avoid warnings. */
    1103             : #if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS) &&                 \
    1104             :     !defined(DOXYGEN_SKIP)
    1105             : /** Type of a constant null-terminated list of nul terminated strings.
    1106             :  * Seen as char** from C and const char* const* from C++ */
    1107             : typedef const char *const *CSLConstList;
    1108             : #else
    1109             : /** Type of a constant null-terminated list of nul terminated strings.
    1110             :  * Seen as char** from C and const char* const* from C++ */
    1111             : typedef char **CSLConstList;
    1112             : #endif
    1113             : 
    1114             : #if defined(__cplusplus) && defined(GDAL_COMPILATION)
    1115             : #if defined(__GNUC__) && !defined(DOXYGEN_SKIP)
    1116             : /** Macro that evaluates to (cond), and possibly gives a hint to the compiler
    1117             :  * than (cond) is unlikely to be true.
    1118             :  */
    1119             : #define CPL_UNLIKELY(cond) __builtin_expect(static_cast<bool>(cond), 0)
    1120             : #else
    1121             : #define CPL_UNLIKELY(cond) (cond)
    1122             : #endif
    1123             : #endif
    1124             : 
    1125             : #endif /* ndef CPL_BASE_H_INCLUDED */

Generated by: LCOV version 1.14