/**************************************************************************
 *{@C
 *      Copyright:      1988-2024 Paul Obermeier (obermeier@poSoft.de)
 *
 *      Module:         Utilities
 *      Filename:       UT_Compat.h
 *
 *      Author:         Paul Obermeier
 *
 *      Description:    Machine independent type definitions.
 *
 *      Additional documentation:
 *                      None.
 *
 **************************************************************************/

#ifndef __UT_COMPAT_H__
#define __UT_COMPAT_H__

#include "UT_Export.h"

/*
    - Some data types which should be the same precision on all machines:

        Int8            Signed 8 bit integer
        UInt8           Unsigned 8 bit integer
        Int16           Signed 16 bit integer
        UInt16          Unsigned 16 bit integer
        Int32           Signed 32 bit integer
        UInt32          Unsigned 32 bit integer
        Int64           Signed 64 bit integer
        UInt64          Unsigned 64 bit integer
        Float32         32 bit floating point
        Float64         64 bit floating point
        UT_Bool         Boolean data type

    - Memory alignment factor: Set MEM_ALIGN to n if every n'th address
      in the program's address space is suitable for storing all data
      types.  This will be used by the memory management library.

    - The operating system.  Currently the following types are supported:

        OS_IS_SYS5_UNIX         AT&T Unix System 5
        OS_IS_WIN32             Microsoft WIndows 9x, NT

    - The maximum length of a complete file name with access path and the
      maximum length of each component of a file access path:

        MAXPATH         somewhere around 1024 on Unix systems

    - The character used to separate the access path components in a file
      name (the equivalent of the '/' in path names on Unix systems):

        C_Sep           for usage in character constants

    Define the following preprocessor symbols if necessary:

    - If the operating system supports multiple program execution threads
      within a single shared address space, so that the UT_ThreadExec
      function can be implemented as defined in our parallelism library,
      then define

        HAVE_THREADS

<*/

/* Check for Microsoft compiler */
#ifdef _MSC_VER
    #define CC_IS_MSC
#endif
/* Check for GNU compiler */
#ifdef __GNUC__
    #define CC_IS_GCC
#endif

typedef unsigned char  UInt8;
typedef unsigned short UInt16;
typedef unsigned int   UInt32;

typedef char  Int8;
typedef short Int16;
typedef int   Int32;

typedef float  Float32;
typedef double Float64;

#define MAXPATH 1024
#define MEM_ALIGN 8               /* Memory alignment factor */

typedef enum {
    UT_False = 0,
    UT_True  = 1
} UT_Bool;

#if defined (Linux)

    #if OS_BITS == 64
        typedef long Int64;
        typedef unsigned long UInt64;
    #else
        typedef long long Int64;
        typedef unsigned long long UInt64;
    #endif

    #define OS_IS_SYS5_UNIX       /* Operating system is System 5 Unix */
    #define HAVE_THREADS          /* Multithreading is supported */
    #define HAVE_PTHREADS         /* Multithreading with pthreads is supported */

    #define C_Sep       '/'

#elif defined (Darwin)

    typedef long long Int64;
    typedef unsigned long long UInt64;

    #define OS_IS_SYS5_UNIX     /* Operating System is System 5 Unix */
    #define HAVE_THREADS        /* Multithreading is supported */
    #define HAVE_PTHREADS       /* Multithreading with pthreads is supported */

    #define C_Sep       '/'

#elif defined (CC_IS_MSC)

    typedef __int64 Int64;
    typedef unsigned __int64 UInt64;

    #define OS_IS_WIN32         /* Operating system is Windows9x, NT */

    #if defined (CC_IS_MSC)
        #define HAVE_THREADS    /* Multithreading is supported */
        #define HAVE_PTHREADS   /* Multithreading with pthreads is supported */

        #if(_MSC_VER > 1800)
            #error "Unsupported Visual Studio version"
        #elif(_MSC_VER >= 1800)
            /* VC 12.0 (VS 2013) */
            #define CC_IS_VC12
        #elif(_MSC_VER >= 1700)
            /* VC 11.0 (VS 2012) */
            #define CC_IS_VC11
        #elif(_MSC_VER >= 1600)
            /* VC 10.0 (VS 2010) */
            #define CC_IS_VC10
        #elif(_MSC_VER >= 1500)
            /* VC 9.0 (VS 2008) */
            #define CC_IS_VC9
        #elif(_MSC_VER >= 1400)
            /* VC 8.0 (aka 2005) */
            #define CC_IS_VC8
        #elif(_MSC_VER >= 1310)
            /* VC 7.1 (aka .NET 2003) */
            #define CC_IS_VC7
        #elif(_MSC_VER >= 1300)
            /* VC 7.0 (aka .NET 2002) */
            #define CC_IS_VC7
        #else
            /* VC 6.0 */
            #define CC_IS_VC6
        #endif
    #endif

    #define C_Sep       '\\'

#elif defined (mingw)

    #if OS_BITS == 64
        typedef long long Int64;
        typedef unsigned long long UInt64;
    #else
        typedef long long Int64;
        typedef unsigned long long UInt64;
    #endif

    #define OS_IS_WIN32 /* Operating system is Windows9x, NT */

    #define C_Sep       '/'

#else
        #error "Basic definitions for your operating system missing here"
#endif

#ifdef _MSC_VER
    #if _MSC_VER <= 1800 /* VS 2013 and older do not have snprintf */
        #define UT_SNPRINTF _snprintf
    #else
        #define UT_SNPRINTF snprintf
    #endif
#else
    #define UT_SNPRINTF snprintf
#endif

/* Marker for exported symbols. Normal operating systems don't need a 
   special handling for that. Only Windows needs some trick here.
*/
#if defined (OS_IS_WIN32)
    #define snprintf _snprintf
    #define UT_DSO_EXPORT  __declspec( dllexport ) 
    #define UT_DSO_IMPORT  __declspec( dllimport ) 
#else
    #define UT_DSO_EXPORT
    #define UT_DSO_IMPORT
#endif

#endif /* __UT_COMPAT_H__ */
