#ifndef PORT_H
#define PORT_H
#include "machine.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <stddef.h>
/* p_int : an integer that has the same size as a pointer */
#if SIZEOF_LONG == SIZEOF_P_INT
typedef long p_int;
typedef unsigned long p_uint;
#else
#if SIZEOF_INT == SIZEOF_P_INT
typedef int p_int;
typedef unsigned int p_uint;
#endif
#if SIZEOF_LONG < SIZEOF_P_INT
typedef long long p_int;
typedef unsigned long long p_uint;
#endif
#endif
#define P_INT_MIN ((p_int)1 << 8 * SIZEOF_P_INT - 1)
#define P_INT_MAX (-1 - P_INT_MIN)
/* ph_int : an integer that has half the size of a pointer */
#if SIZEOF_P_INT == SIZEOF_INT * 2
typedef int ph_int;
typedef unsigned int ph_uint;
#else
#if SIZEOF_P_INT == 4
/* short is assumed to be always 2 bytes. */
typedef short ph_int;
typedef unsigned short ph_uint;
#endif
#endif
/* mp_int : an integer that has at least the size of a pointer */
typedef p_int mp_int;
typedef p_uint mp_uint;
/* int32 : an integer with 32 bits */
#if SIZEOF_INT == 4
typedef int int32;
typedef unsigned int uint32;
#else
#if SIZEOF_LONG == 4
typedef long int32;
typedef unsigned long uint32;
#endif
#endif
typedef unsigned char uint8;
typedef signed char int8;
typedef short int16;
typedef unsigned short uint16;
#define UINT16_MAX 65535
/* How large a buffer do we need to print a p_int in decimal? We assume 8
bit bytes; these have a decimal logarithm of 2.40824. Rounded up, this
makes 2.5 or 5/2. Add 1/2 to round up, and one (2/2) each for the sign
and a terminating '\0'. Actually, I hardly expect anything but 32bit or
64 bit p_int being used; we get exactly the right sizes for theses, 12
and 22 bytes, respectively. */
#define P_INT_PRINT_SIZE ((sizeof (p_int) * 5 + 5) / 2)
/* How large a buffer do we need to print a double with %g? */
#define DOUBLE_PRINT_SIZE 13
#ifdef FREE_RETURNS_VOID
#define FREE_RETURN_TYPE void
#define FREE_RETURN return;
#else
#define FREE_RETURN_TYPE int
#define FREE_RETURN return 1;
#endif
#if defined(atarist) || defined(AMIGA) || defined(MSDOS)
#ifndef NO_IP_DEMON
#define NO_IP_DEMON
#endif
#endif
#if defined(M_UNIX) || defined(__linux__) || defined(solaris) || \
defined(_POSIX_VERSION)
#ifndef POSIX
#define POSIX
#endif
#endif
#if defined(POSIX) && (HAVE_SYSCONF)
/* there is actually a system that pretends to be POSIX, prototypes sysconf,
* but does not have it.
*/
#define TIMES_FREQ sysconf(_SC_CLK_TCK)
#else /* !POSIX */
#include <sys/time.h>
#include <sys/times.h>
#include <time.h>
#define TIMES_FREQ CLK_TCK
#ifndef CLK_TCK
#define CLK_TCK CLOCKS_PER_SEC
#ifndef CLOCKS_PER_SEC
#define CLOCKS_PER_SEC 60
#endif /* !CLOCKS_PER_SEC */
#endif /* !CLK_TCK */
#endif /* !POSIX */
#ifndef HAVE_MEMCPY
/* The following 'implementation' is suitable for throwing away a value,
but not to using it; the cast to return int is likely to show a warning
if the value is used by accident.
*/
#define memcpy(b, a, s) (*((int (*)())(&bcopy)))(a, b, s)
#endif
#ifndef HAVE_BZERO
#define bzero(str, i) memset(str, '\0', i)
#endif
#if !defined(HAVE_CRYPT) && defined(HAVE__CRYPT)
#define crypt(pass, salt) _crypt(pass, salt)
#endif
#ifndef HAVE_STRCHR
#define strchr index
#endif
#ifndef HAVE_STRRCHR
#define strchr rindex
#endif
#ifndef MSDOS
#define O_BINARY 0
#define O_TEXT 0
#endif
#ifdef HAVE_MEMMOVE
#define move_memory(dest, source, size) memmove(dest, source, size)
#endif
#if !defined(HAVE_MEMMOVE) && defined(OVERLAPPING_BCOPY)
#define move_memory(dest, source, size) bcopy(source, dest, size)
#endif
#ifndef offsetof
#define offsetof(type, mem) ((size_t) \
((char *)&((type *) 0)->mem - (char *)((type *) 0)))
#endif
#ifdef __GNUC__
#define STDCALL __attribute__ ((stdcall))
#define REGPARM(n) __attribute__ ((regparm(n)))
#define ALIGN8 __attribute__ ((aligned(8)))
#define TRANSPARENT_UNION __attribute__ ((transparent_union))
#else
#define STDCALL
#define REGPARM(n)
#define ALIGN8
#define TRANSPARENT_UNION
#endif
#if defined(sparc) && !defined(WORDS_BIGENDIAN)
#define WORDS_BIGENDIAN
#endif
#ifdef i386
#define CHEAP_UNALIGNED
/*
* making functions equal by name, not only by address, allows the optimizer
* more tricks :-)
*/
#define uhash(str, len) ahash(str, len)
#else
#define ahash(str, len) aphash(str, len)
#endif
#ifdef CHEAP_UNALIGNED
/* use if unaligned memory access is fine */
#define STORE16(dest, source) ((void)(*(int16 *)(dest) = (source)))
#define UEXTRACT16(source) (*(uint16 *)(source))
#define EXTRACT16(source) (*(int16 *)(source))
#define STORE24(dest, source) \
(void)(((uint8 *)(dest))[2] = (source), *(uint16 *)(dest) = (source) >> 8)
#define EXTRACT24(source) ((*(int16 *)(source) << 8) + ((uint8 *)(source))[2])
#define STORE32(dest, source) ((void)(*(int32 *)(dest) = (source)))
#define EXTRACT32(source) (*(int32 *)(source))
#else
#define STORE16(dest, source) \
((void)(*(uint8 *)(dest) = (source) >> 8, ((uint8 *)(dest))[1] = (source)))
#define UEXTRACT16(source) ( \
(((uint8 *)(source))[0] << 8) + ((uint8 *)(source))[1] )
#define EXTRACT16(source) ( \
(((int8 *)(source))[0] << 8) + ((uint8 *)(source))[1] )
#define STORE24(dest, source) ((void)( \
((uint8 *)(dest))[0] = (source) >> 16, \
((uint8 *)(dest))[1] = (source) >> 8, \
((uint8 *)(dest))[2] = (source) ))
#define EXTRACT24(source) ( \
(((int8 *)(source))[0] << 16) + (((uint8 *)(source))[1] << 8) + \
((uint8 *)(source))[2] )
#define STORE32(dest, source) ((void)( \
((uint8 *)(dest))[0] = (source) >> 24, \
((uint8 *)(dest))[1] = (source) >> 16, \
((uint8 *)(dest))[2] = (source) >> 8, \
((uint8 *)(dest))[3] = (source) ))
#define EXTRACT32(source) ( \
(((int8 *)(source))[0] << 24) + (((uint8 *)(source))[1] << 16) + \
(((uint8 *)(source))[2] << 8) + ((uint8 *)(source))[3] )
#endif
#ifdef WORDS_BIGENDIAN
#define C2I16(a,b) (((a) << 8) | (b))
#define C2I32(a,b,c,d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
#define C2PI(a,b,c,d) (C2I32(a,b,c,d) << (sizeof(char *)*8 - 32))
#define HI24(l) ((l) & 0xffffff)
#define COMBINE8_24(c,size) (((c) << 24) | (size))
#define COMBINE8_8_16(c1,c2,s) (((c1) << 24) | ((c2) << 16) | (s))
#define S2I32(s1,s2) (((s1) << 16) | (s2))
#define EXTRACT_T_WORD(i) (i) &= COMBINE8_8_16(T_MASK,0,0xffff)
#else
#define C2I16(a,b) (((b) << 8) | (a))
#define C2I32(a,b,c,d) (((d) << 24) | ((c) << 16) | ((b) << 8) | (a))
#define C2PI(a,b,c,d) C2I32(a,b,c,d)
#define HI24(l) ((l) >> 8)
#define COMBINE8_24(c,size) ((c) | ((size) << 8))
#define COMBINE8_8_16(c1,c2,s) ((c1) | ((c2) << 8) | ((s) << 16))
#define S2I32(s1,s2) (((s2) << 16) | (s1))
#define EXTRACT_T_WORD(i) (\
(i) &= COMBINE8_8_16(T_MASK,0,0xffff), \
(i) = ((p_uint)(i) >> 8) | ((p_uint)(i) << 24))
#endif
#endif /* PORT_H */