/**********************************************************************
 * Copyright (c) 2005, 2006 Scapa Technologies Limited and others
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * $Id: system.h,v 1.2 2006/10/26 22:40:21 kcallaghan Exp $
 * 
 * Contributors: 
 * Scapa Technologies Limited - Initial API and implementation
 **********************************************************************/

/***********************************************************************
 *      
 * File: system.h
 * Overview:  system abstraction header file
 *
 ***********************************************************************/

#ifndef __XSYSTEM_H__
#define __XSYSTEM_H__

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <memory.h>
#include <string.h>
#include <limits.h>
#include <float.h>

#ifdef WIN32
	#define XSNPrintf _snprintf
#else
	#define XSNPrintf snprintf
#endif

#ifdef _DEBUG

   #define _CRTDBG_MAP_ALLOC // include Microsoft memory leak detection procedures
   #define _INC_MALLOC	     // exclude standard memory alloc procedures
	
   #include <crtdbg.h>
#endif

#ifdef _DEBUG
#ifndef DEBUG
#define DEBUG
#endif
#endif

#ifdef WIN32
#include <windows.h>
#include <winbase.h>
#include <process.h>
#include <winsock.h>
#include <signal.h>
#endif

#if defined(SOLARIS) || defined(LINUX) || defined(AIX) || defined(USS) || defined(HPUX) || defined(LINUX_S390) || defined(SOLARIS_I386)
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <sys/timeb.h>
#include <pthread.h>
#include <netdb.h>
#include <netinet/in.h>
#include <pwd.h>
#include <signal.h>
#include <time.h>
#include <sys/time.h>
#include <dlfcn.h>
#include <errno.h>
#include <fcntl.h>
#include <syslog.h>

#ifdef AIX
#include <sys/ldr.h>
#endif

#endif

#ifdef _DEBUG

   #define _CRTDBG_MAP_ALLOC // include Microsoft memory leak detection procedures
   #define _INC_MALLOC	     // exclude standard memory alloc procedures
	
   #include <crtdbg.h>
#endif
/**
static FILE* ALOG = NULL;
#define   malloc(s)         malloc(s);if(ALOG==NULL){ALOG=fopen("C:\\ALLOC_LOG.txt","w");}fprintf(ALOG,"ALLOC %s,%d %d bytes\n",__FILE__, __LINE__,s)
#define   realloc(o,s)         realloc(o,s);if(ALOG==NULL){ALOG=fopen("C:\\ALLOC_LOG.txt","w");}fprintf(ALOG,"REALLOC %s,%d %d bytes\n",__FILE__, __LINE__,s)
**/

/*----------------------------------------
 * Usefuls section
 *----------------------------------------*/

#ifndef TRUE
#define TRUE (1)
#endif
#ifndef FALSE
#define FALSE (0)
#endif
#ifndef NONE
#define NONE (-1)
#endif
#ifndef BOOL
#define BOOL int
#endif

#define SUCCESS (FALSE)
#define FAILURE (NONE)

/*----------------------------------------
 * Limits section
 *----------------------------------------*/

#define XFILE_NAME_LIMIT (1023)
#define XFILE_NAME_ALLOC ((XFILE_NAME_LIMIT) + 1)

#define XARGUMENT_LIMIT (511)
#define XARGUMENT_ALLOC ((XARGUMENT_LIMIT) + 1)

#define XCOMMAND_LIMIT (1023)
#define XCOMMAND_ALLOC ((XCOMMAND_LIMIT) + 1)

#define XHOST_NAME_LIMIT (255)
#define XHOST_NAME_ALLOC ((XHOST_NAME_LIMIT) + 1)

#define XPORT_NAME_LIMIT (7)
#define XPORT_NAME_ALLOC ((XPORT_NAME_LIMIT) + 1)

#define XKIND_NAME_LIMIT (7)
#define XKIND_NAME_ALLOC ((XKIND_NAME_LIMIT) + 1)

#define XUSER_NAME_LIMIT (31)
#define XUSER_NAME_ALLOC ((XUSER_NAME_LIMIT) + 1)

#define XPASS_WORD_LIMIT (31)
#define XPASS_WORD_ALLOC ((XPASS_WORD_LIMIT) + 1)

#define XSTRING_LIMIT (2047)
#define XSTRING_ALLOC ((XSTRING_LIMIT) + 1)

/*----------------------------------------
 * Datatypes section
 *----------------------------------------*/

typedef signed   char  XINT8;
typedef unsigned char  XUINT8;
typedef unsigned short XUINT16;
typedef signed   short XINT16;
typedef unsigned int   XUINT32;
typedef signed   int   XINT32;
#ifdef WIN32
typedef ULONGLONG      XUINT64;
typedef  LONGLONG      XINT64;
#else
typedef unsigned long long  XUINT64;
typedef signed   long long  XINT64;
#endif
typedef float   XFLOAT;
typedef double  XDOUBLE;

typedef XINT8   XBYTE;  /* alias for INT8   */
typedef XINT16  XSHORT; /* alias for INT16  */ 
typedef XINT32  XINT;   /* alias for INT16  */ 
typedef XINT64  XLONG;  /* alias for INT64  */
typedef XUINT32 XBOOL;  /* alias for UINT32 */

#define XBYTE_MIN ((XBYTE)(SCHAR_MIN))
#define XBYTE_MAX ((XBYTE)(SCHAR_MAX))

#define XSHORT_MIN ((XSHORT)(SHRT_MIN))
#define XSHORT_MAX ((XSHORT)(SHRT_MAX))

#define XINT_MIN ((XINT)(INT_MIN))
#define XINT_MAX ((XINT)(INT_MAX))

#ifdef WIN32
#define XLONG_MIN ((XLONG)(0X8000000000000000I64))
#define XLONG_MAX ((XLONG)(0X7FFFFFFFFFFFFFFFI64))
#else
#define XLONG_MIN ((XLONG)(LLONG_MIN))
#define XLONG_MAX ((XLONG)(LLONG_MAX))
#endif

#define XFLOAT_MIN (FLT_MIN)
#define XFLOAT_MAX (FLT_MAX)

#define XDOUBLE_MIN (DBL_MIN)
#define XDOUBLE_MAX (DBL_MAX)

#define XDT_ENDIAN_LITTLE (0)
#define XDT_ENDIAN_BIG    (1)

#define XDT_FLOATING_IEEE    (0)
#define XDT_FLOATING_VAX     (1)
#define XDT_FLOATING_CRAY    (2)
#define XDT_FLOATING_IBM     (3)

#define XDT_CHARACTER_ASCII  (0)
#define XDT_CHARACTER_EBCDIC (1)

#define XDT_NO_MEMORY_ALIGNMENT        (0)
#define XDT_SPECIAL_MEMORY_ALIGNMENT   (1)

#ifdef WIN32
#define XDT_ENDIAN_LOCAL    (XDT_ENDIAN_LITTLE)
#define XDT_MEMORY_ALIGNMENT (XDT_NO_MEMORY_ALIGNMENT)
#endif
#ifdef LINUX
#define XDT_ENDIAN_LOCAL    (XDT_ENDIAN_LITTLE)
#define XDT_MEMORY_ALIGNMENT (XDT_NO_MEMORY_ALIGNMENT)
#endif
#ifdef LINUX_S390
#define XDT_ENDIAN_LOCAL    (XDT_ENDIAN_BIG)
#define XDT_MEMORY_ALIGNMENT (XDT_NO_MEMORY_ALIGNMENT)
#endif
#ifdef SOLARIS_I386
#define XDT_ENDIAN_LOCAL    (XDT_ENDIAN_LITTLE)
#define XDT_MEMORY_ALIGNMENT (XDT_SPECIAL_MEMORY_ALIGNMENT)
#define XDT_ALIGNMENT_16   (2)
#define XDT_ALIGNMENT_32   (4)
#define XDT_ALIGNMENT_64   (8)
#endif
#ifdef SOLARIS
#define XDT_ENDIAN_LOCAL    (XDT_ENDIAN_BIG)
#define XDT_MEMORY_ALIGNMENT (XDT_SPECIAL_MEMORY_ALIGNMENT)
#define XDT_ALIGNMENT_16   (2)
#define XDT_ALIGNMENT_32   (4)
#define XDT_ALIGNMENT_64   (8)
#endif
#ifdef AIX
#define XDT_ENDIAN_LOCAL    (XDT_ENDIAN_BIG)
#define XDT_MEMORY_ALIGNMENT (XDT_NO_MEMORY_ALIGNMENT)
#define PTHREAD_INIT_NEEDED
#define XDT_THREAD_SAFE_MALLOC
#endif
#if defined(USS) || defined(HPUX)
#error Byte endianness not defined for this platform, please define in system.h
#endif

#define XDT_FLOATING_LOCAL  (XDT_FLOATING_IEEE)
#define XDT_CHARACTER_LOCAL (XDT_CHARACTER_ASCII)

#ifdef XDT_ENDIAN_LOCAL
#if (XDT_ENDIAN_LOCAL != XDT_ENDIAN_LITTLE)
#define XDT_REVERSE_BYTE_ORDER
#endif
#endif

#ifdef XDT_FLOATING_LOCAL
#if (XDT_FLOATING_LOCAL != XDT_FLOATING_IEEE)
#error "UNSUPPORTED FLOATING FORMAT (NOT IEEE)"
#endif
#endif

#if (XDT_CHARACTER_LOCAL != XDT_CHARACTER_ASCII)
#error "UNSUPPORTED CHARACTER FORMAT (NOT ASCII)"
#endif


/*----------------------------------------
 * BEGIN ALL FUNCTION CALL PROTOTYPES
 * WE DO EXTERN "C" ROUND ALL FUNCTIONS
 *----------------------------------------*/

#ifdef __cplusplus
extern "C" {
#endif

extern void XDTByteToNative(void *data);
extern void XDTShortToNative(void *data);
extern void XDTIntToNative(void *data);
extern void XDTLongToNative(void *data);
extern void XDTFloatToNative(void *data);
extern void XDTDoubleToNative(void *data);
extern void XDTStringToNative(void *data);

extern void XDTByteToNeutral(void *data);
extern void XDTShortToNeutral(void *data);
extern void XDTIntToNeutral(void *data);
extern void XDTLongToNeutral(void *data);
extern void XDTFloatToNeutral(void *data);
extern void XDTDoubleToNeutral(void *data);
extern void XDTStringToNeutral(void *data);

extern XSHORT  XDTShortToAligned(XSHORT*, void* data);
extern XINT    XDTIntToAligned(XINT*, void* data);
extern XFLOAT  XDTFloatToAligned(XFLOAT*, void* data);
extern XLONG   XDTLongToAligned(XLONG*, void* data);
extern XDOUBLE XDTDoubleToAligned(XDOUBLE*, void* data);

/*----------------------------------------
 * System section
 *----------------------------------------*/

#define XSYSTEM_ERROR ((0XFF000000) + (0XF00000))

#ifdef WIN32
#define XPATH_SEPARATOR "\\"
#define XPATH_SEPARATOR_CHAR '\\'
#define XDISK_SEPARATOR ":"
#define XLINE_SEPARATOR "\r\n"
#define XLIBRARY_PREFIX ""
#define XLIBRARY_EXTENSION "dll"
#define XLONG_FMT "I64"
#define XTHREADSPERPROCESS (128)

#define strcasecmp stricmp
#define atoll atoi64

#endif

#if defined(LINUX) || defined(SOLARIS) || defined(AIX) || defined(USS) || defined(HPUX) || defined(LINUX_S390) || defined(SOLARIS_I386)
#define XPATH_SEPARATOR "/"
#define XPATH_SEPARATOR_CHAR '/'
#define XDISK_SEPARATOR ""
#define XLINE_SEPARATOR "\n"
#define XLIBRARY_PREFIX "lib"
#define XLIBRARY_EXTENSION "so"
#define XLONG_FMT "ll"
#define XTHREADSPERPROCESS (128)

#endif


/*----------------------------------------
 * Clock section
 *----------------------------------------*/

#define XCLOCK_ERROR         ((XSYSTEM_ERROR) + (0X20000))
#define XCLOCK_ERROR_UNKNOWN ((XCLOCK_ERROR)  + (0X00000))

#define XCLOCK_PRECISION (10)

typedef struct 
{
  XINT64 initial;
} XClock;

extern int XClockMillis(XINT64 *d);
extern int XClockCreate(XClock *clock);
extern int XClockDelete(XClock *clock);
extern int XClockAdjust(XClock *clock, XINT64 adj);
extern int XClockRead(XClock *clock, XINT64 *ticks);
extern int XClockWait(XClock *clock, XINT64 until);

/*----------------------------------------
 * Mutex section
 *----------------------------------------*/

#define XMUTEX_ERROR         ((XSYSTEM_ERROR) + (0X40000))
#define XMUTEX_ERROR_CREATE  ((XMUTEX_ERROR)  + (0X00000))
#define XMUTEX_ERROR_CLAIM   ((XMUTEX_ERROR)  + (0X00001))
#define XMUTEX_ERROR_RELEASE ((XMUTEX_ERROR)  + (0X00002))
#define XMUTEX_ERROR_DELETE  ((XMUTEX_ERROR)  + (0X00003))
#define XMUTEX_ERROR_UNKNOWN ((XMUTEX_ERROR)  + (0X00004))

typedef struct
{
#ifdef WIN32
#undef MUTEX_HANDLE
#ifdef MUTEX_HANDLE
  HANDLE handle;
#else
  CRITICAL_SECTION cs;
#endif
#endif
#if defined(LINUX) || defined(SOLARIS) || defined(AIX) || defined(USS) || defined(HPUX) || defined(LINUX_S390) || defined(SOLARIS_I386)
  pthread_mutex_t mutex;
#endif
} XMutex;

extern int XMutexCreate(XMutex *mutex);
extern int XMutexClaim(XMutex *mutex);
extern int XMutexRelease(XMutex *mutex);
extern int XMutexDelete(XMutex *mutex);

/*----------------------------------------
 * Thread section
 *----------------------------------------*/

#define XTHREAD_ERROR         ((XSYSTEM_ERROR) + (0X50000))
#define XTHREAD_ERROR_CREATE  ((XTHREAD_ERROR) + (0X00000))
#define XTHREAD_ERROR_EXIT    ((XTHREAD_ERROR) + (0X00001))
#define XTHREAD_ERROR_WAIT    ((XTHREAD_ERROR) + (0X00002))
#define XTHREAD_ERROR_ABORT   ((XTHREAD_ERROR) + (0X00003))
#define XTHREAD_ERROR_UNKNOWN ((XTHREAD_ERROR) + (0X00004))

#define XTHREAD_STACKSZ (4 * 1024)

typedef void (XThreadFunction)(void *);

typedef struct
{
#ifdef WIN32
  HANDLE handle;
  DWORD id;
  XThreadFunction *function;
  void           *argument;
#endif
#if defined(LINUX) || defined(SOLARIS) || defined(AIX) || defined(USS) || defined(HPUX) || defined(LINUX_S390) || defined(SOLARIS_I386)
  XThreadFunction *function;
  void           *argument;
  pthread_t      pthread;
#endif
} XThread;

extern int XThreadStartup();
extern int XThreadMakeAbortable();
extern int XThreadCreate(XThreadFunction *function, void *argument, XThread *thread);
extern void XThreadExit(XUINT32 code);
extern int XThreadWait(XThread *thread, XUINT32 *code);
extern int XThreadAbort(XThread *thread);
extern int XThreadGetIdentifier(XINT32 *tid);

/*----------------------------------------
 * Library section
 *----------------------------------------*/

#define XLIBRARY_ERROR         ((XSYSTEM_ERROR)  + (0X60000))
#define XLIBRARY_ERROR_CREATE  ((XLIBRARY_ERROR) + (0X00000))
#define XLIBRARY_ERROR_SYMBOL  ((XLIBRARY_ERROR) + (0X00001))
#define XLIBRARY_ERROR_DELETE  ((XLIBRARY_ERROR) + (0X00002))
#define XLIBRARY_ERROR_UNKNOWN ((XLIBRARY_ERROR) + (0X00003))

typedef struct
{
#ifdef WIN32
  HINSTANCE instance;
#endif
#if defined(LINUX) || defined(SOLARIS) || defined(AIX) || defined(USS) || defined(HPUX) || defined(LINUX_S390) || defined(SOLARIS_I386)
  void *handle;
#endif
} XLibrary;

extern int XLibraryCreate(XLibrary *library, char *filename);
extern int XLibrarySymbol(XLibrary *library, char *symbol, void **address);
extern int XLibraryDelete(XLibrary *library);

/*----------------------------------------
 * Random section
 *----------------------------------------*/

#define XRANDOM_ERROR         ((XSYSTEM_ERROR)      + (0XA0000))
#define XRANDOM_ERROR_UNKNOWN ((XENVIRONMENT_ERROR) + (0X00001))

extern void XRandomSeed(XINT s);
extern XDOUBLE XRandomUniform(void);
extern XDOUBLE XRandomNormal(void);

extern int StrEq(char* a, char* b);

/*----------------------------------------
 * END ALL FUNCTION CALL PROTOTYPES
 * WE DO EXTERN "C" ROUND ALL FUNCTIONS
 *----------------------------------------*/

#ifdef __cplusplus
}
#endif


#endif
/***********************************************************************
 * EOF
 ***********************************************************************/

