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) || \
78 (SIZEOF_UNSIGNED_LONG != 4 && SIZEOF_UNSIGNED_LONG != 8)
79#error "Unexpected value for SIZEOF_UNSIGNED_LONG"
80#endif
81
82#if !defined(SIZEOF_VOIDP)
83#error "Unexpected value for SIZEOF_VOIDP"
84#endif
85
86/* ==================================================================== */
87/* This will disable most WIN32 stuff in a Cygnus build which */
88/* defines unix to 1. */
89/* ==================================================================== */
90
91#ifdef unix
92#undef WIN32
93#endif
94
96#if defined(VSI_NEED_LARGEFILE64_SOURCE) && !defined(_LARGEFILE64_SOURCE)
97#define _LARGEFILE64_SOURCE 1
98#endif
99
100/* ==================================================================== */
101/* If iconv() is available use extended recoding module. */
102/* Stub implementation is always compiled in, because it works */
103/* faster than iconv() for encodings it supports. */
104/* ==================================================================== */
105
106#if defined(HAVE_ICONV)
107#define CPL_RECODE_ICONV
108#endif
109
110#define CPL_RECODE_STUB
113/* ==================================================================== */
114/* MinGW stuff */
115/* ==================================================================== */
116
117/* We need __MSVCRT_VERSION__ >= 0x0700 to have "_aligned_malloc" */
118/* Latest versions of mingw32 define it, but with older ones, */
119/* we need to define it manually */
120#if defined(__MINGW32__)
121#ifndef __MSVCRT_VERSION__
122#define __MSVCRT_VERSION__ 0x0700
123#endif
124#endif
125
126/* Needed for std=c11 on Solaris to have strcasecmp() */
127#if defined(GDAL_COMPILATION) && defined(__sun__) && \
128 (__STDC_VERSION__ + 0) >= 201112L && (_XOPEN_SOURCE + 0) < 600
129#ifdef _XOPEN_SOURCE
130#undef _XOPEN_SOURCE
131#endif
132#define _XOPEN_SOURCE 600
133#endif
134
135/* ==================================================================== */
136/* Standard include files. */
137/* ==================================================================== */
138
139#include <stdio.h>
140#include <stdlib.h>
141#include <math.h>
142#include <stdarg.h>
143#include <string.h>
144#include <ctype.h>
145#include <limits.h>
146
147#include <time.h>
148
149#include <errno.h>
150
151#ifdef HAVE_LOCALE_H
152#include <locale.h>
153#endif
154
155#ifdef HAVE_DIRECT_H
156#include <direct.h>
157#endif
158
159#if !defined(WIN32)
160#include <strings.h>
161#endif
162
163/* ==================================================================== */
164/* Base portability stuff ... this stuff may need to be */
165/* modified for new platforms. */
166/* ==================================================================== */
167
168/* -------------------------------------------------------------------- */
169/* Which versions of C++ are available. */
170/* -------------------------------------------------------------------- */
171
172/* MSVC fails to define a decent value of __cplusplus. Try to target VS2015*/
173/* as a minimum */
174
175#if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS)
176#if !(__cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900))
177#error Must have C++11 or newer.
178#endif
179#if __cplusplus >= 201402L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
180#define HAVE_CXX14 1
181#endif
182#if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
183#define HAVE_CXX17 1
184#endif
185#endif /* __cplusplus */
186
187/*---------------------------------------------------------------------
188 * types for 16 and 32 bits integers, etc...
189 *--------------------------------------------------------------------*/
190#if UINT_MAX == 65535
191typedef long GInt32;
192typedef unsigned long GUInt32;
193#else
195typedef int GInt32;
197typedef unsigned int GUInt32;
198#endif
199
201typedef short GInt16;
203typedef unsigned short GUInt16;
205typedef unsigned char GByte;
206/* hack for PDF driver and poppler >= 0.15.0 that defines incompatible "typedef
207 * bool GBool" */
208/* in include/poppler/goo/gtypes.h */
209#ifndef CPL_GBOOL_DEFINED
211#define CPL_GBOOL_DEFINED
214typedef int GBool;
215#endif
216
218#ifdef __cplusplus
219#define CPL_STATIC_CAST(type, expr) static_cast<type>(expr)
220#define CPL_REINTERPRET_CAST(type, expr) reinterpret_cast<type>(expr)
221#else
222#define CPL_STATIC_CAST(type, expr) ((type)(expr))
223#define CPL_REINTERPRET_CAST(type, expr) ((type)(expr))
224#endif
227/* -------------------------------------------------------------------- */
228/* 64bit support */
229/* -------------------------------------------------------------------- */
230
233typedef long long GIntBig;
236typedef unsigned long long GUIntBig;
237
239#define GINTBIG_MIN (CPL_STATIC_CAST(GIntBig, 0x80000000) << 32)
241#define GINTBIG_MAX ((CPL_STATIC_CAST(GIntBig, 0x7FFFFFFF) << 32) | 0xFFFFFFFFU)
243#define GUINTBIG_MAX \
244 ((CPL_STATIC_CAST(GUIntBig, 0xFFFFFFFFU) << 32) | 0xFFFFFFFFU)
245
247#define CPL_HAS_GINT64 1
250/* Note: we might want to use instead int64_t / uint64_t if they are available
251 */
252
257
259#define GINT64_MIN GINTBIG_MIN
261#define GINT64_MAX GINTBIG_MAX
263#define GUINT64_MAX GUINTBIG_MAX
264
265#if SIZEOF_VOIDP > 8
266#include <stddef.h> // ptrdiff_t
268typedef ptrdiff_t GPtrDiff_t;
269#elif SIZEOF_VOIDP == 8
271typedef GIntBig GPtrDiff_t;
272#else
274typedef int GPtrDiff_t;
275#endif
276
277#ifdef GDAL_COMPILATION
278#include <stdint.h>
279typedef uintptr_t GUIntptr_t;
280#define CPL_IS_ALIGNED(ptr, quant) \
281 ((CPL_REINTERPRET_CAST(GUIntptr_t, CPL_STATIC_CAST(const void *, ptr)) % \
282 (quant)) == 0)
283
284#endif
285
286#if (defined(__MSVCRT__) && !(defined(__MINGW64__) && __GNUC__ >= 10)) || \
287 (defined(WIN32) && defined(_MSC_VER))
288#define CPL_FRMT_GB_WITHOUT_PREFIX "I64"
289#else
291#define CPL_FRMT_GB_WITHOUT_PREFIX "ll"
292#endif
293
295#define CPL_FRMT_GIB "%" CPL_FRMT_GB_WITHOUT_PREFIX "d"
297#define CPL_FRMT_GUIB "%" CPL_FRMT_GB_WITHOUT_PREFIX "u"
298
300#ifdef COMPAT_WITH_ICC_CONVERSION_CHECK
301#define CPL_INT64_FITS_ON_INT32(x) ((x) >= INT_MIN && (x) <= INT_MAX)
302#else
303#define CPL_INT64_FITS_ON_INT32(x) \
304 (CPL_STATIC_CAST(GIntBig, CPL_STATIC_CAST(int, x)) == (x))
305#endif
308/* ==================================================================== */
309/* Other standard services. */
310/* ==================================================================== */
311#ifdef __cplusplus
313#define CPL_C_START \
314 extern "C" \
315 {
317#define CPL_C_END }
318#else
319#define CPL_C_START
320#define CPL_C_END
321#endif
322
323#ifndef CPL_DLL
324#if defined(_MSC_VER) && !defined(CPL_DISABLE_DLL)
325#ifdef GDAL_COMPILATION
326#define CPL_DLL __declspec(dllexport)
327#else
328#define CPL_DLL
329#endif
330#define CPL_INTERNAL
331#else
332#if defined(USE_GCC_VISIBILITY_FLAG)
333#define CPL_DLL __attribute__((visibility("default")))
334#if !defined(__MINGW32__)
335#define CPL_INTERNAL __attribute__((visibility("hidden")))
336#else
337#define CPL_INTERNAL
338#endif
339#else
340#define CPL_DLL
341#define CPL_INTERNAL
342#endif
343#endif
344
345// Marker for unstable API
346#define CPL_UNSTABLE_API CPL_DLL
347
348#endif
349
351/* Should optional (normally private) interfaces be exported? */
352#ifdef CPL_OPTIONAL_APIS
353#define CPL_ODLL CPL_DLL
354#else
355#define CPL_ODLL
356#endif
359#ifndef CPL_STDCALL
360#if defined(_MSC_VER) && !defined(CPL_DISABLE_STDCALL)
361#define CPL_STDCALL __stdcall
362#else
363#define CPL_STDCALL
364#endif
365#endif
366
368#ifdef _MSC_VER
369#define FORCE_CDECL __cdecl
370#else
371#define FORCE_CDECL
372#endif
376/* TODO : support for other compilers needed */
377#if (defined(__GNUC__) && !defined(__NO_INLINE__)) || defined(_MSC_VER)
378#define HAS_CPL_INLINE 1
379#define CPL_INLINE __inline
380#elif defined(__SUNPRO_CC)
381#define HAS_CPL_INLINE 1
382#define CPL_INLINE inline
383#else
384#define CPL_INLINE
385#endif
388#ifndef MAX
390#define MIN(a, b) (((a) < (b)) ? (a) : (b))
392#define MAX(a, b) (((a) > (b)) ? (a) : (b))
393#endif
394
395#ifndef ABS
397#define ABS(x) (((x) < 0) ? (-1 * (x)) : (x))
398#endif
399
400#ifndef M_PI
402#define M_PI 3.14159265358979323846
403/* 3.1415926535897932384626433832795 */
404#endif
405
406/* -------------------------------------------------------------------- */
407/* Macro to test equality of two floating point values. */
408/* We use fabs() function instead of ABS() macro to avoid side */
409/* effects. */
410/* -------------------------------------------------------------------- */
412#ifndef CPLIsEqual
413#define CPLIsEqual(x, y) (fabs((x) - (y)) < 0.0000000000001)
414#endif
417/* -------------------------------------------------------------------- */
418/* Provide macros for case insensitive string comparisons. */
419/* -------------------------------------------------------------------- */
420#ifndef EQUAL
421
422#if defined(AFL_FRIENDLY) && defined(__GNUC__)
423
424static inline int CPL_afl_friendly_memcmp(const void *ptr1, const void *ptr2,
425 size_t len)
426 __attribute__((always_inline));
427
428static inline int CPL_afl_friendly_memcmp(const void *ptr1, const void *ptr2,
429 size_t len)
430{
431 const unsigned char *bptr1 = (const unsigned char *)ptr1;
432 const unsigned char *bptr2 = (const unsigned char *)ptr2;
433 while (len--)
434 {
435 unsigned char b1 = *(bptr1++);
436 unsigned char b2 = *(bptr2++);
437 if (b1 != b2)
438 return b1 - b2;
439 }
440 return 0;
441}
442
443static inline int CPL_afl_friendly_strcmp(const char *ptr1, const char *ptr2)
444 __attribute__((always_inline));
445
446static inline int CPL_afl_friendly_strcmp(const char *ptr1, const char *ptr2)
447{
448 const unsigned char *usptr1 = (const unsigned char *)ptr1;
449 const unsigned char *usptr2 = (const unsigned char *)ptr2;
450 while (1)
451 {
452 unsigned char ch1 = *(usptr1++);
453 unsigned char ch2 = *(usptr2++);
454 if (ch1 == 0 || ch1 != ch2)
455 return ch1 - ch2;
456 }
457}
458
459static inline int CPL_afl_friendly_strncmp(const char *ptr1, const char *ptr2,
460 size_t len)
461 __attribute__((always_inline));
462
463static inline int CPL_afl_friendly_strncmp(const char *ptr1, const char *ptr2,
464 size_t len)
465{
466 const unsigned char *usptr1 = (const unsigned char *)ptr1;
467 const unsigned char *usptr2 = (const unsigned char *)ptr2;
468 while (len--)
469 {
470 unsigned char ch1 = *(usptr1++);
471 unsigned char ch2 = *(usptr2++);
472 if (ch1 == 0 || ch1 != ch2)
473 return ch1 - ch2;
474 }
475 return 0;
476}
477
478static inline int CPL_afl_friendly_strcasecmp(const char *ptr1,
479 const char *ptr2)
480 __attribute__((always_inline));
481
482static inline int CPL_afl_friendly_strcasecmp(const char *ptr1,
483 const char *ptr2)
484{
485 const unsigned char *usptr1 = (const unsigned char *)ptr1;
486 const unsigned char *usptr2 = (const unsigned char *)ptr2;
487 while (1)
488 {
489 unsigned char ch1 = *(usptr1++);
490 unsigned char ch2 = *(usptr2++);
491 ch1 = (unsigned char)toupper(ch1);
492 ch2 = (unsigned char)toupper(ch2);
493 if (ch1 == 0 || ch1 != ch2)
494 return ch1 - ch2;
495 }
496}
497
498static inline int CPL_afl_friendly_strncasecmp(const char *ptr1,
499 const char *ptr2, size_t len)
500 __attribute__((always_inline));
501
502static inline int CPL_afl_friendly_strncasecmp(const char *ptr1,
503 const char *ptr2, size_t len)
504{
505 const unsigned char *usptr1 = (const unsigned char *)ptr1;
506 const unsigned char *usptr2 = (const unsigned char *)ptr2;
507 while (len--)
508 {
509 unsigned char ch1 = *(usptr1++);
510 unsigned char ch2 = *(usptr2++);
511 ch1 = (unsigned char)toupper(ch1);
512 ch2 = (unsigned char)toupper(ch2);
513 if (ch1 == 0 || ch1 != ch2)
514 return ch1 - ch2;
515 }
516 return 0;
517}
518
519static inline char *CPL_afl_friendly_strstr(const char *haystack,
520 const char *needle)
521 __attribute__((always_inline));
522
523static inline char *CPL_afl_friendly_strstr(const char *haystack,
524 const char *needle)
525{
526 const char *ptr_haystack = haystack;
527 while (1)
528 {
529 const char *ptr_haystack2 = ptr_haystack;
530 const char *ptr_needle = needle;
531 while (1)
532 {
533 char ch1 = *(ptr_haystack2++);
534 char ch2 = *(ptr_needle++);
535 if (ch2 == 0)
536 return (char *)ptr_haystack;
537 if (ch1 != ch2)
538 break;
539 }
540 if (*ptr_haystack == 0)
541 return NULL;
542 ptr_haystack++;
543 }
544}
545
546#undef strcmp
547#undef strncmp
548#define memcmp CPL_afl_friendly_memcmp
549#define strcmp CPL_afl_friendly_strcmp
550#define strncmp CPL_afl_friendly_strncmp
551#define strcasecmp CPL_afl_friendly_strcasecmp
552#define strncasecmp CPL_afl_friendly_strncasecmp
553#define strstr CPL_afl_friendly_strstr
554
555#endif /* defined(AFL_FRIENDLY) && defined(__GNUC__) */
556
557#if defined(WIN32)
558#define STRCASECMP(a, b) (_stricmp(a, b))
559#define STRNCASECMP(a, b, n) (_strnicmp(a, b, n))
560#else
562#define STRCASECMP(a, b) (strcasecmp(a, b))
564#define STRNCASECMP(a, b, n) (strncasecmp(a, b, n))
565#endif
567#define EQUALN(a, b, n) (STRNCASECMP(a, b, n) == 0)
569#define EQUAL(a, b) (STRCASECMP(a, b) == 0)
570#endif
571
572/*---------------------------------------------------------------------
573 * Does a string "a" start with string "b". Search is case-sensitive or,
574 * with CI, it is a case-insensitive comparison.
575 *--------------------------------------------------------------------- */
576#ifndef STARTS_WITH_CI
578#define STARTS_WITH(a, b) (strncmp(a, b, strlen(b)) == 0)
580#define STARTS_WITH_CI(a, b) EQUALN(a, b, strlen(b))
581#endif
582
584#ifndef CPL_THREADLOCAL
585#define CPL_THREADLOCAL
586#endif
589/* -------------------------------------------------------------------- */
590/* Handle isnan() and isinf(). Note that isinf() and isnan() */
591/* are supposed to be macros according to C99, defined in math.h */
592/* Some systems (i.e. Tru64) don't have isinf() at all, so if */
593/* the macro is not defined we just assume nothing is infinite. */
594/* This may mean we have no real CPLIsInf() on systems with isinf()*/
595/* function but no corresponding macro, but I can live with */
596/* that since it isn't that important a test. */
597/* -------------------------------------------------------------------- */
598#ifdef _MSC_VER
599#include <float.h>
600#define CPLIsNan(x) _isnan(x)
601#define CPLIsInf(x) (!_isnan(x) && !_finite(x))
602#define CPLIsFinite(x) _finite(x)
603#elif defined(__GNUC__) && \
604 (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))
605/* When including <cmath> in C++11 the isnan() macro is undefined, so that */
606/* std::isnan() can work (#6489). This is a GCC specific workaround for now. */
607#define CPLIsNan(x) __builtin_isnan(x)
608#define CPLIsInf(x) __builtin_isinf(x)
609#define CPLIsFinite(x) __builtin_isfinite(x)
610#elif defined(__cplusplus) && defined(HAVE_STD_IS_NAN) && HAVE_STD_IS_NAN
611extern "C++"
612{
613#ifndef DOXYGEN_SKIP
614#include <cmath>
615#endif
616 static inline int CPLIsNan(float f)
617 {
618 return std::isnan(f);
619 }
620 static inline int CPLIsNan(double f)
621 {
622 return std::isnan(f);
623 }
624 static inline int CPLIsInf(float f)
625 {
626 return std::isinf(f);
627 }
628 static inline int CPLIsInf(double f)
629 {
630 return std::isinf(f);
631 }
632 static inline int CPLIsFinite(float f)
633 {
634 return std::isfinite(f);
635 }
636 static inline int CPLIsFinite(double f)
637 {
638 return std::isfinite(f);
639 }
640}
641#else
643#if defined(__cplusplus) && defined(__GNUC__) && defined(__linux) && \
644 !defined(__ANDROID__) && !defined(CPL_SUPRESS_CPLUSPLUS)
645/* so to not get warning about conversion from double to float with */
646/* gcc -Wfloat-conversion when using isnan()/isinf() macros */
647extern "C++"
648{
649 static inline int CPLIsNan(float f)
650 {
651 return __isnanf(f);
652 }
653 static inline int CPLIsNan(double f)
654 {
655 return __isnan(f);
656 }
657 static inline int CPLIsInf(float f)
658 {
659 return __isinff(f);
660 }
661 static inline int CPLIsInf(double f)
662 {
663 return __isinf(f);
664 }
665 static inline int CPLIsFinite(float f)
666 {
667 return !__isnanf(f) && !__isinff(f);
668 }
669 static inline int CPLIsFinite(double f)
670 {
671 return !__isnan(f) && !__isinf(f);
672 }
673}
674#else
675#define CPLIsNan(x) isnan(x)
676#if defined(isinf) || defined(__FreeBSD__)
678#define CPLIsInf(x) isinf(x)
680#define CPLIsFinite(x) (!isnan(x) && !isinf(x))
681#elif defined(__sun__)
682#include <ieeefp.h>
683#define CPLIsInf(x) (!finite(x) && !isnan(x))
684#define CPLIsFinite(x) finite(x)
685#else
686#define CPLIsInf(x) (0)
687#define CPLIsFinite(x) (!isnan(x))
688#endif
689#endif
690#endif
691
693/*---------------------------------------------------------------------
694 * CPL_LSB and CPL_MSB
695 * Only one of these 2 macros should be defined and specifies the byte
696 * ordering for the current platform.
697 * This should be defined in the Makefile, but if it is not then
698 * the default is CPL_LSB (Intel ordering, LSB first).
699 *--------------------------------------------------------------------*/
700#if defined(WORDS_BIGENDIAN) && !defined(CPL_MSB) && !defined(CPL_LSB)
701#define CPL_MSB
702#endif
703
704#if !(defined(CPL_LSB) || defined(CPL_MSB))
705#define CPL_LSB
706#endif
707
708#if defined(CPL_LSB)
709#define CPL_IS_LSB 1
710#else
711#define CPL_IS_LSB 0
712#endif
715#if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS)
716
718extern "C++"
719{
720
721 template <bool b> struct CPLStaticAssert
722 {
723 };
724 template <> struct CPLStaticAssert<true>
725 {
726 static void my_function()
727 {
728 }
729 };
730
731} /* extern "C++" */
732
733#define CPL_STATIC_ASSERT(x) CPLStaticAssert<x>::my_function()
734#define CPL_STATIC_ASSERT_IF_AVAILABLE(x) CPL_STATIC_ASSERT(x)
735
736#else /* __cplusplus */
737
738#define CPL_STATIC_ASSERT_IF_AVAILABLE(x)
739
740#endif /* __cplusplus */
743/*---------------------------------------------------------------------
744 * Little endian <==> big endian byte swap macros.
745 *--------------------------------------------------------------------*/
746
748#define CPL_SWAP16(x) \
749 CPL_STATIC_CAST(GUInt16, (CPL_STATIC_CAST(GUInt16, x) << 8) | \
750 (CPL_STATIC_CAST(GUInt16, x) >> 8))
751
752#if defined(HAVE_GCC_BSWAP)
754#define CPL_SWAP32(x) \
755 CPL_STATIC_CAST(GUInt32, __builtin_bswap32(CPL_STATIC_CAST(GUInt32, x)))
757#define CPL_SWAP64(x) \
758 CPL_STATIC_CAST(GUInt64, __builtin_bswap64(CPL_STATIC_CAST(GUInt64, x)))
759#elif defined(_MSC_VER)
760#define CPL_SWAP32(x) \
761 CPL_STATIC_CAST(GUInt32, _byteswap_ulong(CPL_STATIC_CAST(GUInt32, x)))
762#define CPL_SWAP64(x) \
763 CPL_STATIC_CAST(GUInt64, _byteswap_uint64(CPL_STATIC_CAST(GUInt64, x)))
764#else
766#define CPL_SWAP32(x) \
767 CPL_STATIC_CAST(GUInt32, \
768 ((CPL_STATIC_CAST(GUInt32, x) & 0x000000ffU) << 24) | \
769 ((CPL_STATIC_CAST(GUInt32, x) & 0x0000ff00U) << 8) | \
770 ((CPL_STATIC_CAST(GUInt32, x) & 0x00ff0000U) >> 8) | \
771 ((CPL_STATIC_CAST(GUInt32, x) & 0xff000000U) >> 24))
772
774#define CPL_SWAP64(x) \
775 ((CPL_STATIC_CAST(GUInt64, CPL_SWAP32(CPL_STATIC_CAST(GUInt32, x))) \
776 << 32) | \
777 (CPL_STATIC_CAST(GUInt64, \
778 CPL_SWAP32(CPL_STATIC_CAST( \
779 GUInt32, CPL_STATIC_CAST(GUInt64, x) >> 32)))))
780
781#endif
782
784#define CPL_SWAP16PTR(x) \
785 do \
786 { \
787 GUInt16 _n16; \
788 void *_lx = x; \
789 memcpy(&_n16, _lx, 2); \
790 CPL_STATIC_ASSERT_IF_AVAILABLE(sizeof(*(x)) == 1 || \
791 sizeof(*(x)) == 2); \
792 _n16 = CPL_SWAP16(_n16); \
793 memcpy(_lx, &_n16, 2); \
794 } while (0)
795
797#define CPL_SWAP32PTR(x) \
798 do \
799 { \
800 GUInt32 _n32; \
801 void *_lx = x; \
802 memcpy(&_n32, _lx, 4); \
803 CPL_STATIC_ASSERT_IF_AVAILABLE(sizeof(*(x)) == 1 || \
804 sizeof(*(x)) == 4); \
805 _n32 = CPL_SWAP32(_n32); \
806 memcpy(_lx, &_n32, 4); \
807 } while (0)
808
810#define CPL_SWAP64PTR(x) \
811 do \
812 { \
813 GUInt64 _n64; \
814 void *_lx = x; \
815 memcpy(&_n64, _lx, 8); \
816 CPL_STATIC_ASSERT_IF_AVAILABLE(sizeof(*(x)) == 1 || \
817 sizeof(*(x)) == 8); \
818 _n64 = CPL_SWAP64(_n64); \
819 memcpy(_lx, &_n64, 8); \
820 } while (0)
821
823#define CPL_SWAPDOUBLE(p) CPL_SWAP64PTR(p)
824
825#ifdef CPL_MSB
826#define CPL_MSBWORD16(x) (x)
827#define CPL_LSBWORD16(x) CPL_SWAP16(x)
828#define CPL_MSBWORD32(x) (x)
829#define CPL_LSBWORD32(x) CPL_SWAP32(x)
830#define CPL_MSBPTR16(x) \
831 CPL_STATIC_ASSERT_IF_AVAILABLE(sizeof(*(x)) == 1 || sizeof(*(x)) == 2)
832#define CPL_LSBPTR16(x) CPL_SWAP16PTR(x)
833#define CPL_MSBPTR32(x) \
834 CPL_STATIC_ASSERT_IF_AVAILABLE(sizeof(*(x)) == 1 || sizeof(*(x)) == 4)
835#define CPL_LSBPTR32(x) CPL_SWAP32PTR(x)
836#define CPL_MSBPTR64(x) \
837 CPL_STATIC_ASSERT_IF_AVAILABLE(sizeof(*(x)) == 1 || sizeof(*(x)) == 8)
838#define CPL_LSBPTR64(x) CPL_SWAP64PTR(x)
839#else
841#define CPL_LSBWORD16(x) (x)
843#define CPL_MSBWORD16(x) CPL_SWAP16(x)
845#define CPL_LSBWORD32(x) (x)
847#define CPL_MSBWORD32(x) CPL_SWAP32(x)
850#define CPL_LSBPTR16(x) \
851 CPL_STATIC_ASSERT_IF_AVAILABLE(sizeof(*(x)) == 1 || sizeof(*(x)) == 2)
854#define CPL_MSBPTR16(x) CPL_SWAP16PTR(x)
857#define CPL_LSBPTR32(x) \
858 CPL_STATIC_ASSERT_IF_AVAILABLE(sizeof(*(x)) == 1 || sizeof(*(x)) == 4)
861#define CPL_MSBPTR32(x) CPL_SWAP32PTR(x)
864#define CPL_LSBPTR64(x) \
865 CPL_STATIC_ASSERT_IF_AVAILABLE(sizeof(*(x)) == 1 || sizeof(*(x)) == 8)
868#define CPL_MSBPTR64(x) CPL_SWAP64PTR(x)
869#endif
870
874#define CPL_LSBINT16PTR(x) \
875 ((*CPL_REINTERPRET_CAST(const GByte *, x)) | \
876 (*((CPL_REINTERPRET_CAST(const GByte *, x)) + 1) << 8))
877
881#define CPL_LSBINT32PTR(x) \
882 ((*CPL_REINTERPRET_CAST(const GByte *, x)) | \
883 (*((CPL_REINTERPRET_CAST(const GByte *, x)) + 1) << 8) | \
884 (*((CPL_REINTERPRET_CAST(const GByte *, x)) + 2) << 16) | \
885 (*((CPL_REINTERPRET_CAST(const GByte *, x)) + 3) << 24))
886
888#define CPL_LSBSINT16PTR(x) CPL_STATIC_CAST(GInt16, CPL_LSBINT16PTR(x))
889
892#define CPL_LSBUINT16PTR(x) CPL_STATIC_CAST(GUInt16, CPL_LSBINT16PTR(x))
893
895#define CPL_LSBSINT32PTR(x) CPL_STATIC_CAST(GInt32, CPL_LSBINT32PTR(x))
896
899#define CPL_LSBUINT32PTR(x) CPL_STATIC_CAST(GUInt32, CPL_LSBINT32PTR(x))
900
902/* Utility macro to explicitly mark intentionally unreferenced parameters. */
903#ifndef UNREFERENCED_PARAM
904#ifdef UNREFERENCED_PARAMETER /* May be defined by Windows API */
905#define UNREFERENCED_PARAM(param) UNREFERENCED_PARAMETER(param)
906#else
907#define UNREFERENCED_PARAM(param) ((void)param)
908#endif /* UNREFERENCED_PARAMETER */
909#endif /* UNREFERENCED_PARAM */
912/***********************************************************************
913 * Define CPL_CVSID() macro. It can be disabled during a build by
914 * defining DISABLE_CVSID in the compiler options.
915 *
916 * The cvsid_aw() function is just there to prevent reports of cpl_cvsid()
917 * being unused.
918 */
919
921#ifndef DISABLE_CVSID
922#if defined(__GNUC__) && __GNUC__ >= 4
923#define CPL_CVSID(string) \
924 static const char cpl_cvsid[] __attribute__((used)) = string;
925#else
926#define CPL_CVSID(string) \
927 static const char cpl_cvsid[] = string; \
928 static const char *cvsid_aw() \
929 { \
930 return (cvsid_aw() ? NULL : cpl_cvsid); \
931 }
932#endif
933#else
934#define CPL_CVSID(string)
935#endif
938/* We exclude mingw64 4.6 which seems to be broken regarding this */
939#if defined(__GNUC__) && __GNUC__ >= 4 && !defined(DOXYGEN_SKIP) && \
940 !(defined(__MINGW64__) && __GNUC__ == 4 && __GNUC_MINOR__ == 6)
942#define CPL_NULL_TERMINATED __attribute__((__sentinel__))
943#else
945#define CPL_NULL_TERMINATED
946#endif
947
948#if defined(__GNUC__) && __GNUC__ >= 3 && !defined(DOXYGEN_SKIP)
950#define CPL_PRINT_FUNC_FORMAT(format_idx, arg_idx) \
951 __attribute__((__format__(__printf__, format_idx, arg_idx)))
953#define CPL_SCAN_FUNC_FORMAT(format_idx, arg_idx) \
954 __attribute__((__format__(__scanf__, format_idx, arg_idx)))
955#else
957#define CPL_PRINT_FUNC_FORMAT(format_idx, arg_idx)
959#define CPL_SCAN_FUNC_FORMAT(format_idx, arg_idx)
960#endif
961
962#if defined(_MSC_VER) && \
963 (defined(GDAL_COMPILATION) || defined(CPL_ENABLE_MSVC_ANNOTATIONS))
964#include <sal.h>
967#define CPL_FORMAT_STRING(arg) _Printf_format_string_ arg
970#define CPL_SCANF_FORMAT_STRING(arg) _Scanf_format_string_ arg
971#else
973#define CPL_FORMAT_STRING(arg) arg
975#define CPL_SCANF_FORMAT_STRING(arg) arg
976#endif /* defined(_MSC_VER) && defined(GDAL_COMPILATION) */
977
978#if defined(__GNUC__) && __GNUC__ >= 4 && !defined(DOXYGEN_SKIP)
980#define CPL_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
981#else
983#define CPL_WARN_UNUSED_RESULT
984#endif
985
986#if defined(__GNUC__) && __GNUC__ >= 4
988#define CPL_UNUSED __attribute((__unused__))
989#else
990/* TODO: add cases for other compilers */
992#define CPL_UNUSED
993#endif
994
995#if defined(__GNUC__) && __GNUC__ >= 3 && !defined(DOXYGEN_SKIP)
998#define CPL_NO_RETURN __attribute__((noreturn))
999#else
1002#define CPL_NO_RETURN
1003#endif
1004
1006/* Clang __has_attribute */
1007#ifndef __has_attribute
1008#define __has_attribute(x) 0 // Compatibility with non-clang compilers.
1009#endif
1010
1013#if ((defined(__GNUC__) && \
1014 (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9))) || \
1015 __has_attribute(returns_nonnull)) && \
1016 !defined(DOXYGEN_SKIP) && !defined(__INTEL_COMPILER)
1018#define CPL_RETURNS_NONNULL __attribute__((returns_nonnull))
1019#else
1021#define CPL_RETURNS_NONNULL
1022#endif
1023
1024#if defined(__GNUC__) && __GNUC__ >= 4 && !defined(DOXYGEN_SKIP)
1026#define CPL_RESTRICT __restrict__
1027#else
1029#define CPL_RESTRICT
1030#endif
1031
1032#if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS)
1033
1036#define CPL_OVERRIDE override
1037
1039#define CPL_FINAL final
1040
1042#define CPL_NON_FINAL
1043
1049#define CPL_DISALLOW_COPY_ASSIGN(ClassName) \
1050 ClassName(const ClassName &) = delete; \
1051 ClassName &operator=(const ClassName &) = delete;
1052
1053#endif /* __cplusplus */
1054
1055#if !defined(DOXYGEN_SKIP) && !defined(CPL_WARN_DEPRECATED)
1056#if defined(__has_extension)
1057#if __has_extension(attribute_deprecated_with_message)
1058/* Clang extension */
1059#define CPL_WARN_DEPRECATED(x) __attribute__((deprecated(x)))
1060#else
1061#define CPL_WARN_DEPRECATED(x)
1062#endif
1063#elif defined(__GNUC__)
1064#define CPL_WARN_DEPRECATED(x) __attribute__((deprecated))
1065#else
1066#define CPL_WARN_DEPRECATED(x)
1067#endif
1068#endif
1069
1070#if !defined(_MSC_VER) && !defined(__APPLE__) && !defined(_FORTIFY_SOURCE)
1072#if defined(GDAL_COMPILATION) && defined(WARN_STANDARD_PRINTF)
1073int vsnprintf(char *str, size_t size, const char *fmt, va_list args)
1074 CPL_WARN_DEPRECATED("Use CPLvsnprintf() instead");
1075int snprintf(char *str, size_t size, const char *fmt, ...)
1077 CPL_WARN_DEPRECATED("Use CPLsnprintf() instead");
1078int sprintf(char *str, const char *fmt, ...) CPL_PRINT_FUNC_FORMAT(2, 3)
1079 CPL_WARN_DEPRECATED("Use CPLsnprintf() instead");
1080#elif defined(GDAL_COMPILATION) && !defined(DONT_DEPRECATE_SPRINTF)
1081int sprintf(char *str, const char *fmt, ...) CPL_PRINT_FUNC_FORMAT(2, 3)
1082 CPL_WARN_DEPRECATED("Use snprintf() or CPLsnprintf() instead");
1083#endif /* defined(GDAL_COMPILATION) && defined(WARN_STANDARD_PRINTF) */
1085#endif /* !defined(_MSC_VER) && !defined(__APPLE__) */
1086
1087#if defined(MAKE_SANITIZE_HAPPY) || \
1088 !(defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || \
1089 defined(_M_X64))
1091#define CPL_CPU_REQUIRES_ALIGNED_ACCESS
1093#endif
1094
1095#if defined(__cplusplus)
1096#ifndef CPPCHECK
1098#define CPL_ARRAYSIZE(array) \
1099 ((sizeof(array) / sizeof(*(array))) / \
1100 static_cast<size_t>(!(sizeof(array) % sizeof(*(array)))))
1101#else
1102/* simplified version for cppcheck */
1103#define CPL_ARRAYSIZE(array) (sizeof(array) / sizeof(array[0]))
1104#endif
1105
1106extern "C++"
1107{
1108 template <class T> static void CPL_IGNORE_RET_VAL(const T &)
1109 {
1110 }
1111 inline static bool CPL_TO_BOOL(int x)
1112 {
1113 return x != 0;
1114 }
1115} /* extern "C++" */
1116
1117#endif /* __cplusplus */
1118
1119#if (((__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) || \
1120 (defined(__clang__) && __clang_major__ >= 3)) && \
1121 !defined(_MSC_VER))
1122#define HAVE_GCC_DIAGNOSTIC_PUSH
1123#endif
1124
1125#if ((__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2)) && \
1126 !defined(_MSC_VER))
1127#define HAVE_GCC_SYSTEM_HEADER
1128#endif
1129
1130#if ((defined(__clang__) && \
1131 (__clang_major__ > 3 || \
1132 (__clang_major__ == 3 && __clang_minor__ >= 7))) || \
1133 __GNUC__ >= 7)
1135#define CPL_FALLTHROUGH [[clang::fallthrough]];
1136#else
1138#define CPL_FALLTHROUGH
1139#endif
1140
1143#ifndef FALSE
1144#define FALSE 0
1145#endif
1146
1147#ifndef TRUE
1148#define TRUE 1
1149#endif
1150
1151#if __clang_major__ >= 4 || (__clang_major__ == 3 && __clang_minor__ >= 8)
1152#define CPL_NOSANITIZE_UNSIGNED_INT_OVERFLOW \
1153 __attribute__((no_sanitize("unsigned-integer-overflow")))
1154#else
1155#define CPL_NOSANITIZE_UNSIGNED_INT_OVERFLOW
1156#endif
1157
1158#if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS) && \
1159 defined(GDAL_COMPILATION)
1160extern "C++"
1161{
1162 template <class C, class A, class B>
1163 CPL_NOSANITIZE_UNSIGNED_INT_OVERFLOW inline C CPLUnsanitizedAdd(A a, B b)
1164 {
1165 return a + b;
1166 }
1167}
1168#endif
1169
1170#if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS)
1171#define CPL_NULLPTR nullptr
1172#else
1173#define CPL_NULLPTR NULL
1174#endif
1177/* This typedef is for C functions that take char** as argument, but */
1178/* with the semantics of a const list. In C, char** is not implicitly cast to */
1179/* const char* const*, contrary to C++. So when seen for C++, it is OK */
1180/* to expose the prototypes as const char* const*, but for C we keep the */
1181/* historical definition to avoid warnings. */
1182#if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS) && \
1183 !defined(DOXYGEN_SKIP)
1186typedef const char *const *CSLConstList;
1187#else
1190typedef char **CSLConstList;
1191#endif
1192
1193#endif /* ndef CPL_BASE_H_INCLUDED */
int GPtrDiff_t
Integer type large enough to hold the difference between 2 addresses.
Definition cpl_port.h:274
#define CPLIsInf(x)
Return whether a floating-pointer number is +/- infinity.
Definition cpl_port.h:678
unsigned long long GUIntBig
Large unsigned integer type (generally 64-bit unsigned integer type).
Definition cpl_port.h:236
short GInt16
Int16 type.
Definition cpl_port.h:201
#define CPL_C_END
Macro to end a block of C symbols.
Definition cpl_port.h:317
#define CPL_C_START
Macro to start a block of C symbols.
Definition cpl_port.h:313
GIntBig GInt64
Signed 64 bit integer type.
Definition cpl_port.h:254
int GBool
Type for boolean values (alias to int)
Definition cpl_port.h:214
unsigned int GUInt32
Unsigned int32 type.
Definition cpl_port.h:197
#define CPL_PRINT_FUNC_FORMAT(format_idx, arg_idx)
Tag a function to have printf() formatting.
Definition cpl_port.h:957
#define CPLIsNan(x)
Return whether a floating-pointer number is NaN.
Definition cpl_port.h:675
char ** CSLConstList
Type of a constant null-terminated list of nul terminated strings.
Definition cpl_port.h:1190
GUIntBig GUInt64
Unsigned 64 bit integer type.
Definition cpl_port.h:256
unsigned short GUInt16
Unsigned int16 type.
Definition cpl_port.h:203
unsigned char GByte
Unsigned byte type.
Definition cpl_port.h:205
int GInt32
Int32 type.
Definition cpl_port.h:195
long long GIntBig
Large signed integer type (generally 64-bit integer type).
Definition cpl_port.h:233
#define CPLIsFinite(x)
Return whether a floating-pointer number is finite.
Definition cpl_port.h:680