//! @file a68g-platform.h
//! @author J. Marcel van der Veer

//! @section Copyright
//!
//! This file is part of Algol68G - an Algol 68 compiler-interpreter.
//! Copyright 2001-2026 J. Marcel van der Veer [algol68g@algol68genie.nl].

//! @section License
//!
//! This program is free software; you can redistribute it and/or modify it 
//! under the terms of the GNU General Public License as published by the 
//! Free Software Foundation; either version 3 of the License, or 
//! (at your option) any later version.
//!
//! This program is distributed in the hope that it will be useful, but 
//! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
//! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 
//! more details. You should have received a copy of the GNU General Public 
//! License along with this program. If not, see [http://www.gnu.org/licenses/].

//! @section Synopsis
//!
//! Platform dependent definitions.

#if !defined (__A68G_PLATFORM_H__)
#define __A68G_PLATFORM_H__

#if defined (BUILD_WIN32)
  #include "a68g-config.win32.h"
  #if !defined (HAVE_GCC)
    #define HAVE_GCC
  #endif
  #undef C_COMPILER
  #undef HAVE_CLANG
#elif defined (BUILD_WIN64)
  #include "a68g-config.win64.h"
  #if !defined (HAVE_GCC)
    #define HAVE_GCC
  #endif
  #undef C_COMPILER
  #undef HAVE_CLANG
#elif defined (__clang__)
  #include "a68g-config.h"
  #if !defined (HAVE_CLANG)
    #define HAVE_CLANG
  #endif
  #if !defined (C_COMPILER)
    #define C_COMPILER "clang"
  #endif
  #undef HAVE_GCC
  #undef HAVE_GNU_MPFR
#elif defined (__GNUC__)
  #include "a68g-config.h"
  #if !defined (HAVE_GCC)
    #define HAVE_GCC
  #endif
  #if !defined (C_COMPILER)
    #define C_COMPILER "gcc"
  #endif
  #undef HAVE_CLANG
#else
  #error "a68g: abend: a68g requires either gcc or clang"
#endif

#if defined (BUILD_LINUX)
  #define BUILD_UNIX
#elif defined (BUILD_BSD)
  #define BUILD_UNIX
#elif defined (BUILD_CYGWIN)
  #define BUILD_UNIX
#elif defined (BUILD_HAIKU)
  #define BUILD_UNIX
#endif

#if defined (BUILD_WIN32)
  #define BUILD_WINDOWS
#elif defined (BUILD_WIN64)
  #define BUILD_WINDOWS
#endif

#if (defined (BUILD_LINUX) || defined (BUILD_BSD))

// Autoconf macros may impose outdated feature test macros.
// For instance AX_WITH CURSES may define _DEFAULT_SOURCE and _XOPEN_SOURCE 600.
// Here we correct, post hoc.

// _GNU_SOURCE includes ISO C89, ISO C99, POSIX.1, POSIX.2, BSD, SVID, X/Open, LFS, and GNU extensions.

  #if defined (_GNU_SOURCE)
    #undef _GNU_SOURCE
  #endif

// _BSD_SOURCE is deprecated, and caused header files to expose BSD-derived definitions.

  #if defined (_BSD_SOURCE)
    #undef _BSD_SOURCE
  #endif

// _DEFAULT_SOURCE includes most features, apart from X/Open, LFS and GNU extensions.

  #if defined (_DEFAULT_SOURCE)
    #undef _DEFAULT_SOURCE
  #endif

// _XOPEN_SOURCE includes functionality described in the X/Open Portability Guide.
// A68G defines _XOPEN_SOURCE 700 which is a superset of _POSIX_C_SOURCE 200809L. 

  #if defined (_XOPEN_SOURCE)
    #undef _XOPEN_SOURCE
  #endif

  #define _XOPEN_SOURCE 700

#endif

// Decide on A68G "LEVEL".
// LEVEL 3 uses INT*8 and REAL*16 data types, when available in hardware.
// LEVEL 2 builds generic A68G with INT*4 and REAL*8 data types.
// LEVEL 1 is reserved for (possible) restrictive builds.

#if defined (BUILD_WINDOWS)
  #define A68G_LEVEL 3
#elif defined (HAVE_LONG_TYPES)
  #define A68G_LEVEL 3
#else
  #define A68G_LEVEL 2
#endif

#undef HAVE_LARGE_STORAGE // Default.
#if (A68G_LEVEL >= 3)
  #if defined (SIZEOF_SIZE_T)
    #if (SIZEOF_SIZE_T >= 8)
      #define HAVE_LARGE_STORAGE
    #endif
  #elif defined (BUILD_WIN64)
    #define HAVE_LARGE_STORAGE
  #endif
#endif

// GNU MPFR
#if (A68G_LEVEL < 3)
  #undef HAVE_GNU_MPFR
#endif

// R mathlib

#if defined (HAVE_R_MATHLIB)
  #if !defined (MATHLIB_STANDALONE)
    #define MATHLIB_STANDALONE
  #endif
#endif

// Imported libraries

#if defined (__cplusplus)
  #undef __cplusplus
#endif

#endif
