GDAL
cpl_port.h
Go to the documentation of this file.
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
42/* ==================================================================== */
43/* We will use WIN32 as a standard windows define. */
44/* ==================================================================== */
45#if defined(_WIN32) && !defined(WIN32)
46# define WIN32
47#endif
48
49#if defined(_WINDOWS) && !defined(WIN32)
50# define WIN32
51#endif
52
53/* -------------------------------------------------------------------- */
54/* The following apparently allow you to use strcpy() and other */
55/* functions judged "unsafe" by microsoft in VS 8 (2005). */
56/* -------------------------------------------------------------------- */
57#ifdef _MSC_VER
58# ifndef _CRT_SECURE_NO_DEPRECATE
59# define _CRT_SECURE_NO_DEPRECATE
60# endif
61# ifndef _CRT_NONSTDC_NO_DEPRECATE
62# define _CRT_NONSTDC_NO_DEPRECATE
63# endif
64#endif
65
66#include "cpl_config.h"
67
68/* ==================================================================== */
69/* A few sanity checks, mainly to detect problems that sometimes */
70/* arise with bad configured cross-compilation. */
71/* ==================================================================== */
72
73#if !defined(SIZEOF_INT) || SIZEOF_INT != 4
74#error "Unexpected value for SIZEOF_INT"
75#endif
76
77#if !defined(SIZEOF_UNSIGNED_LONG) || (SIZEOF_UNSIGNED_LONG != 4 && SIZEOF_UNSIGNED_LONG != 8)
78#error "Unexpected value for SIZEOF_UNSIGNED_LONG"
79#endif
80
81#if !defined(SIZEOF_VOIDP)
82#error "Unexpected value for SIZEOF_VOIDP"
83#endif
84
85/* ==================================================================== */
86/* This will disable most WIN32 stuff in a Cygnus build which */
87/* defines unix to 1. */
88/* ==================================================================== */
89
90#ifdef unix
91# undef WIN32
92#endif
93
95#if defined(VSI_NEED_LARGEFILE64_SOURCE) && !defined(_LARGEFILE64_SOURCE)
96# define _LARGEFILE64_SOURCE 1
97#endif
98
99/* ==================================================================== */
100/* If iconv() is available use extended recoding module. */
101/* Stub implementation is always compiled in, because it works */
102/* faster than iconv() for encodings it supports. */
103/* ==================================================================== */
104
105#if defined(HAVE_ICONV)
106# define CPL_RECODE_ICONV
107#endif
108
109#define CPL_RECODE_STUB
112/* ==================================================================== */
113/* MinGW stuff */
114/* ==================================================================== */
115
116/* We need __MSVCRT_VERSION__ >= 0x0700 to have "_aligned_malloc" */
117/* Latest versions of mingw32 define it, but with older ones, */
118/* we need to define it manually */
119#if defined(__MINGW32__)
120#ifndef __MSVCRT_VERSION__
121#define __MSVCRT_VERSION__ 0x0700
122#endif
123#endif
124
125/* Needed for std=c11 on Solaris to have strcasecmp() */
126#if defined(GDAL_COMPILATION) && defined(__sun__) && (__STDC_VERSION__ + 0) >= 201112L && (_XOPEN_SOURCE + 0) < 600
127#ifdef _XOPEN_SOURCE
128#undef _XOPEN_SOURCE
129#endif
130#define _XOPEN_SOURCE 600
131#endif
132
133/* ==================================================================== */
134/* Standard include files. */
135/* ==================================================================== */
136
137#include <stdio.h>
138#include <stdlib.h>
139#include <math.h>
140#include <stdarg.h>
141#include <string.h>
142#include <ctype.h>
143#include <limits.h>
144
145#include <time.h>
146
147#include <errno.h>
148
149#ifdef HAVE_LOCALE_H
150# include <locale.h>
151#endif
152
153#ifdef HAVE_DIRECT_H
154# include <direct.h>
155#endif
156
157#if !defined(WIN32)
158# include <strings.h>
159#endif
160
161/* ==================================================================== */
162/* Base portability stuff ... this stuff may need to be */
163/* modified for new platforms. */
164/* ==================================================================== */
165
166/* -------------------------------------------------------------------- */
167/* Which versions of C++ are available. */
168/* -------------------------------------------------------------------- */
169
170/* MSVC fails to define a decent value of __cplusplus. Try to target VS2015*/
171/* as a minimum */
172
173#if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS)
174# if !(__cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900))
175# error Must have C++11 or newer.
176# endif
177# if __cplusplus >= 201402L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
178# define HAVE_CXX14 1
179# endif
180# if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
181# define HAVE_CXX17 1
182# endif
183#endif /* __cplusplus */
184
185/*---------------------------------------------------------------------
186 * types for 16 and 32 bits integers, etc...
187 *--------------------------------------------------------------------*/
188#if UINT_MAX == 65535
189typedef long GInt32;
190typedef unsigned long GUInt32;
191#else
193typedef int GInt32;
195typedef unsigned int GUInt32;
196#endif
197
199typedef short GInt16;
201typedef unsigned short GUInt16;
203typedef unsigned char GByte;
204/* hack for PDF driver and poppler >= 0.15.0 that defines incompatible "typedef bool GBool" */
205/* in include/poppler/goo/gtypes.h */
206#ifndef CPL_GBOOL_DEFINED
208#define CPL_GBOOL_DEFINED
211typedef int GBool;
212#endif
213
215#ifdef __cplusplus
216#define CPL_STATIC_CAST(type, expr) static_cast<type>(expr)
217#define CPL_REINTERPRET_CAST(type, expr) reinterpret_cast<type>(expr)
218#else
219#define CPL_STATIC_CAST(type, expr) ((type)(expr))
220#define CPL_REINTERPRET_CAST(type, expr) ((type)(expr))
221#endif
224/* -------------------------------------------------------------------- */
225/* 64bit support */
226/* -------------------------------------------------------------------- */
227
230typedef long long GIntBig;
233typedef unsigned long long GUIntBig;
234
236#define GINTBIG_MIN (CPL_STATIC_CAST(GIntBig, 0x80000000) << 32)
238#define GINTBIG_MAX ((CPL_STATIC_CAST(GIntBig, 0x7FFFFFFF) << 32) | 0xFFFFFFFFU)
240#define GUINTBIG_MAX ((CPL_STATIC_CAST(GUIntBig, 0xFFFFFFFFU) << 32) | 0xFFFFFFFFU)
241
243#define CPL_HAS_GINT64 1
246/* Note: we might want to use instead int64_t / uint64_t if they are available */
247
252
254#define GINT64_MIN GINTBIG_MIN
256#define GINT64_MAX GINTBIG_MAX
258#define GUINT64_MAX GUINTBIG_MAX
259
260#if SIZEOF_VOIDP > 8
261#include <stddef.h> // ptrdiff_t
263typedef ptrdiff_t GPtrDiff_t;
264#elif SIZEOF_VOIDP == 8
266typedef GIntBig GPtrDiff_t;
267#else
269typedef int GPtrDiff_t;
270#endif
271
272#ifdef GDAL_COMPILATION
273#include <stdint.h>
274typedef uintptr_t GUIntptr_t;
275#define CPL_IS_ALIGNED(ptr, quant) ((CPL_REINTERPRET_CAST(GUIntptr_t, CPL_STATIC_CAST(const void*, ptr)) % (quant)) == 0)
276
277#endif
278
279#if (defined(__MSVCRT__) && !(defined(__MINGW64__) && __GNUC__ >= 10)) || (defined(WIN32) && defined(_MSC_VER))
280 #define CPL_FRMT_GB_WITHOUT_PREFIX "I64"
281#else
283 #define CPL_FRMT_GB_WITHOUT_PREFIX "ll"
284#endif
285
287#define CPL_FRMT_GIB "%" CPL_FRMT_GB_WITHOUT_PREFIX "d"
289#define CPL_FRMT_GUIB "%" CPL_FRMT_GB_WITHOUT_PREFIX "u"
290
292#ifdef COMPAT_WITH_ICC_CONVERSION_CHECK
293#define CPL_INT64_FITS_ON_INT32(x) ((x) >= INT_MIN && (x) <= INT_MAX)
294#else
295#define CPL_INT64_FITS_ON_INT32(x) (CPL_STATIC_CAST(GIntBig, CPL_STATIC_CAST(int, x)) == (x))
296#endif
299/* ==================================================================== */
300/* Other standard services. */
301/* ==================================================================== */
302#ifdef __cplusplus
304# define CPL_C_START extern "C" {
306# define CPL_C_END }
307#else
308# define CPL_C_START
309# define CPL_C_END
310#endif
311
312#ifndef CPL_DLL
313#if defined(_MSC_VER) && !defined(CPL_DISABLE_DLL)
314# ifdef GDAL_COMPILATION
315# define CPL_DLL __declspec(dllexport)
316# else
317# define CPL_DLL
318# endif
319# define CPL_INTERNAL
320#else
321# if defined(USE_GCC_VISIBILITY_FLAG)
322# define CPL_DLL __attribute__ ((visibility("default")))
323# if !defined(__MINGW32__)
324# define CPL_INTERNAL __attribute__((visibility("hidden")))
325# else
326# define CPL_INTERNAL
327# endif
328# else
329# define CPL_DLL
330# define CPL_INTERNAL
331# endif
332#endif
333
334// Marker for unstable API
335#define CPL_UNSTABLE_API CPL_DLL
336
337#endif
338
340/* Should optional (normally private) interfaces be exported? */
341#ifdef CPL_OPTIONAL_APIS
342# define CPL_ODLL CPL_DLL
343#else
344# define CPL_ODLL
345#endif
348#ifndef CPL_STDCALL
349#if defined(_MSC_VER) && !defined(CPL_DISABLE_STDCALL)
350# define CPL_STDCALL __stdcall
351#else
352# define CPL_STDCALL
353#endif
354#endif
355
357#ifdef _MSC_VER
358# define FORCE_CDECL __cdecl
359#else
360# define FORCE_CDECL
361#endif
365/* TODO : support for other compilers needed */
366#if (defined(__GNUC__) && !defined(__NO_INLINE__)) || defined(_MSC_VER)
367#define HAS_CPL_INLINE 1
368#define CPL_INLINE __inline
369#elif defined(__SUNPRO_CC)
370#define HAS_CPL_INLINE 1
371#define CPL_INLINE inline
372#else
373#define CPL_INLINE
374#endif
377#ifndef MAX
379# define MIN(a,b) (((a)<(b)) ? (a) : (b))
381# define MAX(a,b) (((a)>(b)) ? (a) : (b))
382#endif
383
384#ifndef ABS
386# define ABS(x) (((x)<0) ? (-1*(x)) : (x))
387#endif
388
389#ifndef M_PI
391# define M_PI 3.14159265358979323846
392/* 3.1415926535897932384626433832795 */
393#endif
394
395/* -------------------------------------------------------------------- */
396/* Macro to test equality of two floating point values. */
397/* We use fabs() function instead of ABS() macro to avoid side */
398/* effects. */
399/* -------------------------------------------------------------------- */
401#ifndef CPLIsEqual
402# define CPLIsEqual(x,y) (fabs((x) - (y)) < 0.0000000000001)
403#endif
406/* -------------------------------------------------------------------- */
407/* Provide macros for case insensitive string comparisons. */
408/* -------------------------------------------------------------------- */
409#ifndef EQUAL
410
411#if defined(AFL_FRIENDLY) && defined(__GNUC__)
412
413static inline int CPL_afl_friendly_memcmp(const void* ptr1, const void* ptr2, size_t len)
414 __attribute__((always_inline));
415
416static inline int CPL_afl_friendly_memcmp(const void* ptr1, const void* ptr2, size_t len)
417{
418 const unsigned char* bptr1 = (const unsigned char*)ptr1;
419 const unsigned char* bptr2 = (const unsigned char*)ptr2;
420 while( len-- )
421 {
422 unsigned char b1 = *(bptr1++);
423 unsigned char b2 = *(bptr2++);
424 if( b1 != b2 ) return b1 - b2;
425 }
426 return 0;
427}
428
429static inline int CPL_afl_friendly_strcmp(const char* ptr1, const char* ptr2)
430 __attribute__((always_inline));
431
432static inline int CPL_afl_friendly_strcmp(const char* ptr1, const char* ptr2)
433{
434 const unsigned char* usptr1 = (const unsigned char*)ptr1;
435 const unsigned char* usptr2 = (const unsigned char*)ptr2;
436 while( 1 )
437 {
438 unsigned char ch1 = *(usptr1++);
439 unsigned char ch2 = *(usptr2++);
440 if( ch1 == 0 || ch1 != ch2 ) return ch1 - ch2;
441 }
442}
443
444static inline int CPL_afl_friendly_strncmp(const char* ptr1, const char* ptr2, size_t len)
445 __attribute__((always_inline));
446
447static inline int CPL_afl_friendly_strncmp(const char* ptr1, const char* ptr2, size_t len)
448{
449 const unsigned char* usptr1 = (const unsigned char*)ptr1;
450 const unsigned char* usptr2 = (const unsigned char*)ptr2;
451 while( len -- )
452 {
453 unsigned char ch1 = *(usptr1++);
454 unsigned char ch2 = *(usptr2++);
455 if( ch1 == 0 || ch1 != ch2 ) return ch1 - ch2;
456 }
457 return 0;
458}
459
460static inline int CPL_afl_friendly_strcasecmp(const char* ptr1, const char* ptr2)
461 __attribute__((always_inline));
462
463static inline int CPL_afl_friendly_strcasecmp(const char* ptr1, const char* ptr2)
464{
465 const unsigned char* usptr1 = (const unsigned char*)ptr1;
466 const unsigned char* usptr2 = (const unsigned char*)ptr2;
467 while( 1 )
468 {
469 unsigned char ch1 = *(usptr1++);
470 unsigned char ch2 = *(usptr2++);
471 ch1 = (unsigned char)toupper(ch1);
472 ch2 = (unsigned char)toupper(ch2);
473 if( ch1 == 0 || ch1 != ch2 ) return ch1 - ch2;
474 }
475}
476
477static inline int CPL_afl_friendly_strncasecmp(const char* ptr1, const char* ptr2, size_t len)
478 __attribute__((always_inline));
479
480static inline int CPL_afl_friendly_strncasecmp(const char* ptr1, const char* ptr2, size_t len)
481{
482 const unsigned char* usptr1 = (const unsigned char*)ptr1;
483 const unsigned char* usptr2 = (const unsigned char*)ptr2;
484 while( len-- )
485 {
486 unsigned char ch1 = *(usptr1++);
487 unsigned char ch2 = *(usptr2++);
488 ch1 = (unsigned char)toupper(ch1);
489 ch2 = (unsigned char)toupper(ch2);
490 if( ch1 == 0 || ch1 != ch2 ) return ch1 - ch2;
491 }
492 return 0;
493}
494
495static inline char* CPL_afl_friendly_strstr(const char* haystack, const char* needle)
496 __attribute__((always_inline));
497
498static inline char* CPL_afl_friendly_strstr(const char* haystack, const char* needle)
499{
500 const char* ptr_haystack = haystack;
501 while( 1 )
502 {
503 const char* ptr_haystack2 = ptr_haystack;
504 const char* ptr_needle = needle;
505 while( 1 )
506 {
507 char ch1 = *(ptr_haystack2++);
508 char ch2 = *(ptr_needle++);
509 if( ch2 == 0 )
510 return (char*)ptr_haystack;
511 if( ch1 != ch2 )
512 break;
513 }
514 if( *ptr_haystack == 0 )
515 return NULL;
516 ptr_haystack ++;
517 }
518}
519
520#undef strcmp
521#undef strncmp
522#define memcmp CPL_afl_friendly_memcmp
523#define strcmp CPL_afl_friendly_strcmp
524#define strncmp CPL_afl_friendly_strncmp
525#define strcasecmp CPL_afl_friendly_strcasecmp
526#define strncasecmp CPL_afl_friendly_strncasecmp
527#define strstr CPL_afl_friendly_strstr
528
529#endif /* defined(AFL_FRIENDLY) && defined(__GNUC__) */
530
531# if defined(WIN32)
532# define STRCASECMP(a,b) (_stricmp(a,b))
533# define STRNCASECMP(a,b,n) (_strnicmp(a,b,n))
534# else
536# define STRCASECMP(a,b) (strcasecmp(a,b))
538# define STRNCASECMP(a,b,n) (strncasecmp(a,b,n))
539# endif
541# define EQUALN(a,b,n) (STRNCASECMP(a,b,n)==0)
543# define EQUAL(a,b) (STRCASECMP(a,b)==0)
544#endif
545
546/*---------------------------------------------------------------------
547 * Does a string "a" start with string "b". Search is case-sensitive or,
548 * with CI, it is a case-insensitive comparison.
549 *--------------------------------------------------------------------- */
550#ifndef STARTS_WITH_CI
552#define STARTS_WITH(a,b) (strncmp(a,b,strlen(b)) == 0)
554#define STARTS_WITH_CI(a,b) EQUALN(a,b,strlen(b))
555#endif
556
558#ifndef CPL_THREADLOCAL
559# define CPL_THREADLOCAL
560#endif
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__) && ( __GNUC__ > 4 || ( __GNUC__ == 4 && __GNUC_MINOR__ >= 4 ) )
578/* When including <cmath> in C++11 the isnan() macro is undefined, so that */
579/* std::isnan() can work (#6489). This is a GCC specific workaround for now. */
580# define CPLIsNan(x) __builtin_isnan(x)
581# define CPLIsInf(x) __builtin_isinf(x)
582# define CPLIsFinite(x) __builtin_isfinite(x)
583#elif defined(__cplusplus) && defined(HAVE_STD_IS_NAN) && HAVE_STD_IS_NAN
584extern "C++" {
585#ifndef DOXYGEN_SKIP
586#include <cmath>
587#endif
588static inline int CPLIsNan(float f) { return std::isnan(f); }
589static inline int CPLIsNan(double f) { return std::isnan(f); }
590static inline int CPLIsInf(float f) { return std::isinf(f); }
591static inline int CPLIsInf(double f) { return std::isinf(f); }
592static inline int CPLIsFinite(float f) { return std::isfinite(f); }
593static inline int CPLIsFinite(double f) { return std::isfinite(f); }
594}
595#else
597#if defined(__cplusplus) && defined(__GNUC__) && defined(__linux) && !defined(__ANDROID__) && !defined(CPL_SUPRESS_CPLUSPLUS)
598/* so to not get warning about conversion from double to float with */
599/* gcc -Wfloat-conversion when using isnan()/isinf() macros */
600extern "C++" {
601static inline int CPLIsNan(float f) { return __isnanf(f); }
602static inline int CPLIsNan(double f) { return __isnan(f); }
603static inline int CPLIsInf(float f) { return __isinff(f); }
604static inline int CPLIsInf(double f) { return __isinf(f); }
605static inline int CPLIsFinite(float f) { return !__isnanf(f) && !__isinff(f); }
606static inline int CPLIsFinite(double f) { return !__isnan(f) && !__isinf(f); }
607}
608#else
609# define CPLIsNan(x) isnan(x)
610# if defined(isinf) || defined(__FreeBSD__)
612# define CPLIsInf(x) isinf(x)
614# define CPLIsFinite(x) (!isnan(x) && !isinf(x))
615# elif defined(__sun__)
616# include <ieeefp.h>
617# define CPLIsInf(x) (!finite(x) && !isnan(x))
618# define CPLIsFinite(x) finite(x)
619# else
620# define CPLIsInf(x) (0)
621# define CPLIsFinite(x) (!isnan(x))
622# endif
623#endif
624#endif
625
627/*---------------------------------------------------------------------
628 * CPL_LSB and CPL_MSB
629 * Only one of these 2 macros should be defined and specifies the byte
630 * ordering for the current platform.
631 * This should be defined in the Makefile, but if it is not then
632 * the default is CPL_LSB (Intel ordering, LSB first).
633 *--------------------------------------------------------------------*/
634#if defined(WORDS_BIGENDIAN) && !defined(CPL_MSB) && !defined(CPL_LSB)
635# define CPL_MSB
636#endif
637
638#if ! ( defined(CPL_LSB) || defined(CPL_MSB) )
639#define CPL_LSB
640#endif
641
642#if defined(CPL_LSB)
643# define CPL_IS_LSB 1
644#else
645# define CPL_IS_LSB 0
646#endif
649#if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS)
650
652extern "C++" {
653
654template <bool b> struct CPLStaticAssert {};
655template<> struct CPLStaticAssert<true>
656{
657 static void my_function() {}
658};
659
660} /* extern "C++" */
661
662#define CPL_STATIC_ASSERT(x) CPLStaticAssert<x>::my_function()
663#define CPL_STATIC_ASSERT_IF_AVAILABLE(x) CPL_STATIC_ASSERT(x)
664
665#else /* __cplusplus */
666
667#define CPL_STATIC_ASSERT_IF_AVAILABLE(x)
668
669#endif /* __cplusplus */
672/*---------------------------------------------------------------------
673 * Little endian <==> big endian byte swap macros.
674 *--------------------------------------------------------------------*/
675
677#define CPL_SWAP16(x) CPL_STATIC_CAST(GUInt16, (CPL_STATIC_CAST(GUInt16, x) << 8) | (CPL_STATIC_CAST(GUInt16, x) >> 8) )
678
679#if defined(HAVE_GCC_BSWAP)
681#define CPL_SWAP32(x) CPL_STATIC_CAST(GUInt32, __builtin_bswap32(CPL_STATIC_CAST(GUInt32, x)))
683#define CPL_SWAP64(x) CPL_STATIC_CAST(GUInt64, __builtin_bswap64(CPL_STATIC_CAST(GUInt64, x)))
684#elif defined(_MSC_VER)
685#define CPL_SWAP32(x) CPL_STATIC_CAST(GUInt32, _byteswap_ulong(CPL_STATIC_CAST(GUInt32, x)))
686#define CPL_SWAP64(x) CPL_STATIC_CAST(GUInt64, _byteswap_uint64(CPL_STATIC_CAST(GUInt64, x)))
687#else
689#define CPL_SWAP32(x) \
690 CPL_STATIC_CAST(GUInt32, \
691 ((CPL_STATIC_CAST(GUInt32, x) & 0x000000ffU) << 24) | \
692 ((CPL_STATIC_CAST(GUInt32, x) & 0x0000ff00U) << 8) | \
693 ((CPL_STATIC_CAST(GUInt32, x) & 0x00ff0000U) >> 8) | \
694 ((CPL_STATIC_CAST(GUInt32, x) & 0xff000000U) >> 24) )
695
697#define CPL_SWAP64(x) \
698 ((CPL_STATIC_CAST(GUInt64, CPL_SWAP32(CPL_STATIC_CAST(GUInt32, x))) << 32) | \
699 (CPL_STATIC_CAST(GUInt64, CPL_SWAP32(CPL_STATIC_CAST(GUInt32, CPL_STATIC_CAST(GUInt64, x) >> 32)))))
700
701#endif
702
704#define CPL_SWAP16PTR(x) \
705do { \
706 GUInt16 _n16; \
707 void* _lx = x; \
708 memcpy(&_n16, _lx, 2); \
709 CPL_STATIC_ASSERT_IF_AVAILABLE(sizeof(*(x)) == 1 || sizeof(*(x)) == 2); \
710 _n16 = CPL_SWAP16(_n16); \
711 memcpy(_lx, &_n16, 2); \
712} while(0)
713
715#define CPL_SWAP32PTR(x) \
716do { \
717 GUInt32 _n32; \
718 void* _lx = x; \
719 memcpy(&_n32, _lx, 4); \
720 CPL_STATIC_ASSERT_IF_AVAILABLE(sizeof(*(x)) == 1 || sizeof(*(x)) == 4); \
721 _n32 = CPL_SWAP32(_n32); \
722 memcpy(_lx, &_n32, 4); \
723} while(0)
724
726#define CPL_SWAP64PTR(x) \
727do { \
728 GUInt64 _n64; \
729 void* _lx = x; \
730 memcpy(&_n64, _lx, 8); \
731 CPL_STATIC_ASSERT_IF_AVAILABLE(sizeof(*(x)) == 1 || sizeof(*(x)) == 8); \
732 _n64 = CPL_SWAP64(_n64); \
733 memcpy(_lx, &_n64, 8); \
734} while(0)
735
737#define CPL_SWAPDOUBLE(p) CPL_SWAP64PTR(p)
738
739#ifdef CPL_MSB
740# define CPL_MSBWORD16(x) (x)
741# define CPL_LSBWORD16(x) CPL_SWAP16(x)
742# define CPL_MSBWORD32(x) (x)
743# define CPL_LSBWORD32(x) CPL_SWAP32(x)
744# define CPL_MSBPTR16(x) CPL_STATIC_ASSERT_IF_AVAILABLE(sizeof(*(x)) == 1 || sizeof(*(x)) == 2)
745# define CPL_LSBPTR16(x) CPL_SWAP16PTR(x)
746# define CPL_MSBPTR32(x) CPL_STATIC_ASSERT_IF_AVAILABLE(sizeof(*(x)) == 1 || sizeof(*(x)) == 4)
747# define CPL_LSBPTR32(x) CPL_SWAP32PTR(x)
748# define CPL_MSBPTR64(x) CPL_STATIC_ASSERT_IF_AVAILABLE(sizeof(*(x)) == 1 || sizeof(*(x)) == 8)
749# define CPL_LSBPTR64(x) CPL_SWAP64PTR(x)
750#else
752# define CPL_LSBWORD16(x) (x)
754# define CPL_MSBWORD16(x) CPL_SWAP16(x)
756# define CPL_LSBWORD32(x) (x)
758# define CPL_MSBWORD32(x) CPL_SWAP32(x)
760# define CPL_LSBPTR16(x) CPL_STATIC_ASSERT_IF_AVAILABLE(sizeof(*(x)) == 1 || sizeof(*(x)) == 2)
762# define CPL_MSBPTR16(x) CPL_SWAP16PTR(x)
764# define CPL_LSBPTR32(x) CPL_STATIC_ASSERT_IF_AVAILABLE(sizeof(*(x)) == 1 || sizeof(*(x)) == 4)
766# define CPL_MSBPTR32(x) CPL_SWAP32PTR(x)
768# define CPL_LSBPTR64(x) CPL_STATIC_ASSERT_IF_AVAILABLE(sizeof(*(x)) == 1 || sizeof(*(x)) == 8)
770# define CPL_MSBPTR64(x) CPL_SWAP64PTR(x)
771#endif
772
776#define CPL_LSBINT16PTR(x) ((*CPL_REINTERPRET_CAST(const GByte*, x)) | (*((CPL_REINTERPRET_CAST(const GByte*, x))+1) << 8))
777
781#define CPL_LSBINT32PTR(x) ((*CPL_REINTERPRET_CAST(const GByte*, x)) | (*((CPL_REINTERPRET_CAST(const GByte*, x))+1) << 8) | \
782 (*((CPL_REINTERPRET_CAST(const GByte*, x))+2) << 16) | (*((CPL_REINTERPRET_CAST(const GByte*, x))+3) << 24))
783
785#define CPL_LSBSINT16PTR(x) CPL_STATIC_CAST(GInt16,CPL_LSBINT16PTR(x))
786
788#define CPL_LSBUINT16PTR(x) CPL_STATIC_CAST(GUInt16, CPL_LSBINT16PTR(x))
789
791#define CPL_LSBSINT32PTR(x) CPL_STATIC_CAST(GInt32, CPL_LSBINT32PTR(x))
792
794#define CPL_LSBUINT32PTR(x) CPL_STATIC_CAST(GUInt32, CPL_LSBINT32PTR(x))
795
797/* Utility macro to explicitly mark intentionally unreferenced parameters. */
798#ifndef UNREFERENCED_PARAM
799# ifdef UNREFERENCED_PARAMETER /* May be defined by Windows API */
800# define UNREFERENCED_PARAM(param) UNREFERENCED_PARAMETER(param)
801# else
802# define UNREFERENCED_PARAM(param) ((void)param)
803# endif /* UNREFERENCED_PARAMETER */
804#endif /* UNREFERENCED_PARAM */
807/***********************************************************************
808 * Define CPL_CVSID() macro. It can be disabled during a build by
809 * defining DISABLE_CVSID in the compiler options.
810 *
811 * The cvsid_aw() function is just there to prevent reports of cpl_cvsid()
812 * being unused.
813 */
814
816#ifndef DISABLE_CVSID
817#if defined(__GNUC__) && __GNUC__ >= 4
818# define CPL_CVSID(string) static const char cpl_cvsid[] __attribute__((used)) = string;
819#else
820# define CPL_CVSID(string) static const char cpl_cvsid[] = string; \
821static const char *cvsid_aw() { return( cvsid_aw() ? NULL : cpl_cvsid ); }
822#endif
823#else
824# define CPL_CVSID(string)
825#endif
828/* We exclude mingw64 4.6 which seems to be broken regarding this */
829#if defined(__GNUC__) && __GNUC__ >= 4 && !defined(DOXYGEN_SKIP) && !(defined(__MINGW64__) && __GNUC__ == 4 && __GNUC_MINOR__ == 6)
831# define CPL_NULL_TERMINATED __attribute__((__sentinel__))
832#else
834# define CPL_NULL_TERMINATED
835#endif
836
837#if defined(__GNUC__) && __GNUC__ >= 3 && !defined(DOXYGEN_SKIP)
839#define CPL_PRINT_FUNC_FORMAT( format_idx, arg_idx ) __attribute__((__format__ (__printf__, format_idx, arg_idx)))
841#define CPL_SCAN_FUNC_FORMAT( format_idx, arg_idx ) __attribute__((__format__ (__scanf__, format_idx, arg_idx)))
842#else
844#define CPL_PRINT_FUNC_FORMAT( format_idx, arg_idx )
846#define CPL_SCAN_FUNC_FORMAT( format_idx, arg_idx )
847#endif
848
849#if defined(_MSC_VER) && (defined(GDAL_COMPILATION) || defined(CPL_ENABLE_MSVC_ANNOTATIONS))
850#include <sal.h>
853# define CPL_FORMAT_STRING(arg) _Printf_format_string_ arg
856# define CPL_SCANF_FORMAT_STRING(arg) _Scanf_format_string_ arg
857#else
859# define CPL_FORMAT_STRING(arg) arg
861# define CPL_SCANF_FORMAT_STRING(arg) arg
862#endif /* defined(_MSC_VER) && defined(GDAL_COMPILATION) */
863
864#if defined(__GNUC__) && __GNUC__ >= 4 && !defined(DOXYGEN_SKIP)
866#define CPL_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
867#else
869#define CPL_WARN_UNUSED_RESULT
870#endif
871
872#if defined(__GNUC__) && __GNUC__ >= 4
874# define CPL_UNUSED __attribute((__unused__))
875#else
876/* TODO: add cases for other compilers */
878# define CPL_UNUSED
879#endif
880
881#if defined(__GNUC__) && __GNUC__ >= 3 && !defined(DOXYGEN_SKIP)
883#define CPL_NO_RETURN __attribute__((noreturn))
884#else
886#define CPL_NO_RETURN
887#endif
888
890/* Clang __has_attribute */
891#ifndef __has_attribute
892 #define __has_attribute(x) 0 // Compatibility with non-clang compilers.
893#endif
894
897#if ((defined(__GNUC__) && (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9))) || __has_attribute(returns_nonnull)) && !defined(DOXYGEN_SKIP) && !defined(__INTEL_COMPILER)
899# define CPL_RETURNS_NONNULL __attribute__((returns_nonnull))
900#else
902# define CPL_RETURNS_NONNULL
903#endif
904
905#if defined(__GNUC__) && __GNUC__ >= 4 && !defined(DOXYGEN_SKIP)
907#define CPL_RESTRICT __restrict__
908#else
910#define CPL_RESTRICT
911#endif
912
913#if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS)
914
917# define CPL_OVERRIDE override
918
920# define CPL_FINAL final
921
923# define CPL_NON_FINAL
924
930# define CPL_DISALLOW_COPY_ASSIGN(ClassName) \
931 ClassName( const ClassName & ) = delete; \
932 ClassName &operator=( const ClassName & ) = delete;
933
934#endif /* __cplusplus */
935
936#if !defined(DOXYGEN_SKIP) && !defined(CPL_WARN_DEPRECATED)
937#if defined(__has_extension)
938 #if __has_extension(attribute_deprecated_with_message)
939 /* Clang extension */
940 #define CPL_WARN_DEPRECATED(x) __attribute__ ((deprecated(x)))
941 #else
942 #define CPL_WARN_DEPRECATED(x)
943 #endif
944#elif defined(__GNUC__)
945 #define CPL_WARN_DEPRECATED(x) __attribute__ ((deprecated))
946#else
947 #define CPL_WARN_DEPRECATED(x)
948#endif
949#endif
950
951#if !defined(_MSC_VER) && !defined(__APPLE__) && !defined(_FORTIFY_SOURCE)
953# if defined(GDAL_COMPILATION) && defined(WARN_STANDARD_PRINTF)
954int vsnprintf(char *str, size_t size, const char* fmt, va_list args)
955 CPL_WARN_DEPRECATED("Use CPLvsnprintf() instead");
956int snprintf(char *str, size_t size, const char* fmt, ...)
958 CPL_WARN_DEPRECATED("Use CPLsnprintf() instead");
959int sprintf(char *str, const char* fmt, ...)
961 CPL_WARN_DEPRECATED("Use CPLsnprintf() instead");
962# elif defined(GDAL_COMPILATION) && !defined(DONT_DEPRECATE_SPRINTF)
963int sprintf(char *str, const char* fmt, ...)
965 CPL_WARN_DEPRECATED("Use snprintf() or CPLsnprintf() instead");
966# endif /* defined(GDAL_COMPILATION) && defined(WARN_STANDARD_PRINTF) */
968#endif /* !defined(_MSC_VER) && !defined(__APPLE__) */
969
970#if defined(MAKE_SANITIZE_HAPPY) || !(defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_X64))
972#define CPL_CPU_REQUIRES_ALIGNED_ACCESS
974#endif
975
976#if defined(__cplusplus)
977#ifndef CPPCHECK
979#define CPL_ARRAYSIZE(array) \
980 ((sizeof(array) / sizeof(*(array))) / \
981 static_cast<size_t>(!(sizeof(array) % sizeof(*(array)))))
982#else
983/* simplified version for cppcheck */
984#define CPL_ARRAYSIZE(array) (sizeof(array) / sizeof(array[0]))
985#endif
986
987extern "C++" {
988template<class T> static void CPL_IGNORE_RET_VAL(const T&) {}
989inline static bool CPL_TO_BOOL(int x) { return x != 0; }
990} /* extern "C++" */
991
992#endif /* __cplusplus */
993
994#if (((__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) || (defined(__clang__) && __clang_major__ >= 3)) && !defined(_MSC_VER))
995#define HAVE_GCC_DIAGNOSTIC_PUSH
996#endif
997
998#if ((__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2)) && !defined(_MSC_VER))
999#define HAVE_GCC_SYSTEM_HEADER
1000#endif
1001
1002#if ((defined(__clang__) && (__clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >=7))) || __GNUC__ >= 7)
1004# define CPL_FALLTHROUGH [[clang::fallthrough]];
1005#else
1007# define CPL_FALLTHROUGH
1008#endif
1009
1012#ifndef FALSE
1013# define FALSE 0
1014#endif
1015
1016#ifndef TRUE
1017# define TRUE 1
1018#endif
1019
1020#if __clang_major__ >= 4 || (__clang_major__ == 3 && __clang_minor__ >= 8)
1021#define CPL_NOSANITIZE_UNSIGNED_INT_OVERFLOW __attribute__((no_sanitize("unsigned-integer-overflow")))
1022#else
1023#define CPL_NOSANITIZE_UNSIGNED_INT_OVERFLOW
1024#endif
1025
1026#if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS) && defined(GDAL_COMPILATION)
1027extern "C++" {
1028template<class C, class A, class B>
1029CPL_NOSANITIZE_UNSIGNED_INT_OVERFLOW
1030inline C CPLUnsanitizedAdd(A a, B b)
1031{
1032 return a + b;
1033}
1034}
1035#endif
1036
1037#if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS)
1038#define CPL_NULLPTR nullptr
1039#else
1040#define CPL_NULLPTR NULL
1041#endif
1044/* This typedef is for C functions that take char** as argument, but */
1045/* with the semantics of a const list. In C, char** is not implicitly cast to */
1046/* const char* const*, contrary to C++. So when seen for C++, it is OK */
1047/* to expose the prototypes as const char* const*, but for C we keep the */
1048/* historical definition to avoid warnings. */
1049#if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS) && !defined(DOXYGEN_SKIP)
1052typedef const char* const* CSLConstList;
1053#else
1056typedef char** CSLConstList;
1057#endif
1058
1059#endif /* ndef CPL_BASE_H_INCLUDED */
int GPtrDiff_t
Integer type large enough to hold the difference between 2 addresses.
Definition: cpl_port.h:269
#define CPLIsInf(x)
Return whether a floating-pointer number is +/- infinity.
Definition: cpl_port.h:612
unsigned long long GUIntBig
Large unsigned integer type (generally 64-bit unsigned integer type).
Definition: cpl_port.h:233
short GInt16
Int16 type.
Definition: cpl_port.h:199
#define CPL_C_END
Macro to end a block of C symbols.
Definition: cpl_port.h:306
#define CPL_C_START
Macro to start a block of C symbols.
Definition: cpl_port.h:304
GIntBig GInt64
Signed 64 bit integer type.
Definition: cpl_port.h:249
int GBool
Type for boolean values (alias to int)
Definition: cpl_port.h:211
unsigned int GUInt32
Unsigned int32 type.
Definition: cpl_port.h:195
#define CPL_PRINT_FUNC_FORMAT(format_idx, arg_idx)
Tag a function to have printf() formatting.
Definition: cpl_port.h:844
#define CPLIsNan(x)
Return whether a floating-pointer number is NaN.
Definition: cpl_port.h:609
char ** CSLConstList
Type of a constant null-terminated list of nul terminated strings.
Definition: cpl_port.h:1056
GUIntBig GUInt64
Unsigned 64 bit integer type.
Definition: cpl_port.h:251
unsigned short GUInt16
Unsigned int16 type.
Definition: cpl_port.h:201
unsigned char GByte
Unsigned byte type.
Definition: cpl_port.h:203
int GInt32
Int32 type.
Definition: cpl_port.h:193
long long GIntBig
Large signed integer type (generally 64-bit integer type).
Definition: cpl_port.h:230
#define CPLIsFinite(x)
Return whether a floating-pointer number is finite.
Definition: cpl_port.h:614
int CPLsnprintf(char *str, size_t size, const char *fmt,...)
snprintf() wrapper that is not sensitive to LC_NUMERIC settings.
Definition: cpl_string.cpp:1354