#ifndef AO_H
#define AO_H

/* These are potential duplicates. */
#ifndef EXTERN
#   ifdef __cplusplus
#	define EXTERN extern "C"
#   else
#	define EXTERN extern
#   endif
#endif
#ifndef ARGS
#   if defined(__STDC__) || defined(__cplusplus)
#	define ARGS(protos)    protos          /* ANSI C */
#   else /* !(__STDC__ || __cplusplus) */
#	define ARGS(protos)    ()              /* K&R C */
#   endif /* !(__STDC__ || __cplusplus) */
#endif
#ifndef NULLARGS
#   if defined(__STDC__) || defined(__cplusplus)
#       define NULLARGS    (void)
#   else
#       define NULLARGS    ()
#   endif
#endif
#ifndef const
#   if !defined(__STDC__) && !defined(__cplusplus)
#       define const
#   endif
#endif


#if defined(__GNUC__)
#   define UTIL_INLINE __inline__
#   if __GNUC__ > 2 || __GNUC_MINOR__ >= 7
#       define UTIL_UNUSED __attribute__ ((unused))
#   else
#       define UTIL_UNUSED
#   endif
#else
#   define UTIL_INLINE
#   define UTIL_UNUSED
#endif

#ifndef SIZEOF_VOID_P
#define SIZEOF_VOID_P 4
#endif
#ifndef SIZEOF_INT
#define SIZEOF_INT 4
#endif
#ifndef SIZEOF_LONG
#define SIZEOF_LONG 4
#endif

#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4
typedef long util_ptrint;
#else
typedef int util_ptrint;
#endif

#if defined(__STDC__) || defined(__cplusplus)
EXTERN void exit ARGS((int));
#endif

#define NIL(type)		((type *) 0)

/* No machines seem to have much of a problem with these */
#include <stdio.h>
#include <ctype.h>

/* some call it strings.h, some call it string.h; others, also have memory.h */
#if defined(__STDC__) || defined(__cplusplus) || defined(_IBMR2) || defined(ultrix)
#include <string.h>
#else
/* ANSI C string.h -- 1/11/88 Draft Standard */
extern char *strcpy(), *strncpy(), *strcat(), *strncat(), *strerror();
extern char *strpbrk(), *strtok(), *strchr(), *strrchr(), *strstr();
extern int strcoll(), strxfrm(), strncmp(), strlen(), strspn(), strcspn();
extern char *memmove(), *memccpy(), *memchr(), *memcpy(), *memset();
extern int memcmp(), strcmp();
#endif


#ifdef __STDC__
#include <assert.h>
#else
#ifndef NDEBUG
#define assert(ex) {\
    if (! (ex)) {\
	(void) fprintf(stderr,\
	    "Assertion failed: file %s, line %d\n\"%s\"\n",\
	    __FILE__, __LINE__, "ex");\
	(void) fflush(stdout);\
	abort();\
    }\
}
#else
#define assert(ex) ;
#endif
#endif


#define fail(why) {\
    (void) fprintf(stderr, "Fatal error: file %s, line %d\n%s\n",\
	__FILE__, __LINE__, why);\
    (void) fflush(stdout);\
    abort();\
}

#define ABS(a)			((a) < 0 ? -(a) : (a))
#define MAX(a,b)		((a) > (b) ? (a) : (b))
#define MIN(a,b)		((a) < (b) ? (a) : (b))
#define ALLOC(type, num)        \
    ((type *) malloc(sizeof(type) * (num)))
#define FREE(obj) free((void *) (obj))

EXTERN long cpuTime ARGS((void));
EXTERN char *printTime ARGS((unsigned long));
EXTERN void printCpuStats ARGS((FILE *));
EXTERN float ran3 ARGS((long *seed));
EXTERN void setTimeOutAlarm ARGS((int seconds));

#ifndef MSPY
#define malloc(s) \
  (mallocSpy(1, (s), __FILE__, __LINE__, 0, NULL))
#define free(p) (freeSpy(p, __FILE__, __LINE__, 1))
#define realloc(p, s) (reallocSpy((p), (s), __FILE__, __LINE__))
#define calloc(n, s) \
  (mallocSpy((n), (s), __FILE__, __LINE__, 1, NULL))

int mspyLeakCount ARGS(());
int mspyStrayFreeCount ARGS(());
size_t mspyUsedMemory ARGS(());
size_t mspyPeakMemory ARGS(());
void mspyReport ARGS(());
void mspySetInternalTrace ARGS((int t));
void *mallocSpy ARGS((size_t nmemb, size_t size, char *file, int line, int clear, void *givenPtr));
void freeSpy ARGS((void *ptr, char *file, int line, int perform));
void *reallocSpy ARGS((void *ptr, size_t size, char *file, int line));

#endif

#endif /* AO_H */

