LCOV - code coverage report
Current view: top level - port - cpl_port.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 10 10 100.0 %
Date: 2024-04-28 23:18:46 Functions: 72 76 94.7 %

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

Generated by: LCOV version 1.14