#ifndef COMPILERSPECIFIC_H
#define COMPILERSPECIFIC_H

/*
**      $Id: CompilerSpecific.h,v 1.2 2000/01/12 20:00:57 bernie Exp $
**
**      Copyright (C) 1997 Bernardo Innocenti <bernie@cosmos.it>
**      All rights reserved.
**
**      Defines wrappers for several compiler dependent constructs,
**      including function attributes and register specification for
**      function arguments. Supports SAS/C, gcc, EGCS, Storm C, VBCC,
**      Maxon C, DICE and Aztec C.
**
**      You can easily add support for other compilers as well. Please
**      return any changes you make to me, so I can add them to my
**      personal copy of this file.
**
**      Here is a short description of the macros defined below:
**
**      LIBCALL
**              Shared library entry point, with register args
**
**      HOOKCALL
**              Hook or boopsi dispatcher entry point with arguments
**              passed in registers
**
**      GLOBALCALL
**              Attribute for functions to be exported to other modules for
**              global access within the same executable file.
**              Usually defined to "extern", but can be overridden for special
**              needs, such as compiling all modules together in a single
**              object module to optimize code better.
**
**      XDEF
**              Attribute for symbols to be exported to other modules for
**              global access within the same executable file.
**              Usually defined to an empty value.
**
**      XREF
**              Attribute for symbols to be imported from other modules
**              within the same executable file.
**              Usually defined to "extern".
**
**      INLINE
**              Please put function body inline to the calling code
**
**      STDARGS
**              Function uses standard C conventions for arguments
**
**      ASMCALL
**              Function takes arguments in the specified 68K registers
**
**      REGCALL
**              Function takes arguments in registers choosen by the compiler
**
**      FARCALL
**              Storage to absolute-long
**
**      CONSTCALL
**              Function does not modify any global variable
**
**      FORMATCALL(archetype,string_index,first_to_check)
**              Function uses printf or scanf-like formatting
**
**      SAVEDS
**              Function needs to reload context for small data model
**
**      INTERRUPT
**              Function will be called from within an interrupt
**
**      NORETURN
**              Function does never return
**
**      ALIGNED
**              Variable must be aligned to longword boundaries
**
**      UNUSED(var)
**              Eclicitly specify a function parameter as being
**              unused to prevent a compiler warning.
**
**      CHIP
**              Variable must be stored in CHIP RAM
**
**      REG(reg,arg)
**              Put argument <arg> in 68K register <reg>
**
**      min(a,b)
**              Return the minimum between <a> and <b>
**
**      max(a,b)
**              Return the maximum between <a> and <b>
**
**      abs(a)
**              Return the absolute value of <a>
**
**      _COMPILED_WITH
**              A string containing the name of the compiler
*/


//one of the following 3 defines are neccessary for proper compiling
/* #define GERMAN
#define FRENCH */

#define ENGLISH


#ifndef __SASC
#define __SASC
#endif

#ifdef __SASC
        /* SAS/C 6.58 or better */

        #define INLINE          static __inline
        #define STDARGS         __stdargs
        #define ASMCALL         __asm
        #define REGCALL         __regcall
        #define CONSTCALL       /* unsupported */
        #define FORMATCALL      /* unsupported */
        #define FARCALL         __far
        #define SAVEDS          __saveds
        #define INTERRUPT       __interrupt
        #define NORETURN        /* unsupported */
        #define ALIGNED         __aligned
        #define UNUSED(var)     var /* unsupported */
        #define CHIP            __chip
        #define REG(reg,arg) register __##reg arg
        #define _COMPILED_WITH  "SAS/C"

        /* For min(), max() and abs() */
        #define USE_BUILTIN_MATH
        #include <string.h>
#else
#ifdef __GNUC__
        /* GeekGadgets GCC 2.7.2.1 or better */

        #define INLINE          static inline
        #define STDARGS         __attribute__((stkparm))
        #define ASMCALL         /* nothing */
        #define REGCALL         /* nothing */
        #define CONSTCALL       __attribute__((const))
        #define FORMATCALL(a,s,f)       __attribute__((format(a,s,f)))
        #define SAVEDS          __attribute__((saveds))
        #define INTERRUPT       __attribute__((interrupt))
        #define NORETURN        __attribute__((noreturn))
        #define ALIGNED         __attribute__((aligned(4)))
        #define UNUSED(var)     var __attribute__((unused))
        #define REG(reg,arg) arg __asm(#reg)
        #define _COMPILED_WITH  "GCC"

        #define min(a,b)        (((a)<(b))?(a):(b))
        #define max(a,b)        (((a)>(b))?(a):(b))

#if 0
        #define abs(a)          (((a)>0)?(a):-(a))

        /* Inline versions of some str*() and mem*() functions
         */
        #define _ANSI_SOURCE
        #include <string.h>
        #undef _ANSI_SOURCE

        INLINE STDARGS size_t strlen (const char *src)
                { const char *tmp = src; while (*tmp) tmp++; return tmp - src; }

        INLINE STDARGS int memcmp (const void *src, const void *dest, size_t n)
        {
                while (n--)
                {
                        if (*((char *)src) != *((char *)dest))
                                return (*((char *)src) - *((char *)dest));
                        ((char *)src)++;
                        ((char *)dest)++;
                }
                return 0;
        }

        INLINE STDARGS void * memset (void *m, int c, size_t n)
        {
                void *r = m;
                n++;
                while (--n > 0)
                        *(((unsigned char *) m)++) = (unsigned char) c;
                return r;
        }
#endif
#else
#ifdef __STORM__
        /* StormC 2.00.23 or better */
        #define INLINE          __inline
        #define STDARGS         /* nothing */
        #define ASMCALL         /* nothing */
        #define REGCALL         register
        #define CONSTCALL       /* unsupported */
        #define FORMATCALL      /* unsupported */
        #define SAVEDS          __saveds
        #define INTERRUPT       __interrupt
        #define NORETURN        /* unsupported */
        #define ALIGNED         /* unsupported */
        #define UNUSED(var)     var /* unsupported */
        #define CHIP            __chip
        #define REG(reg,arg) register __##reg arg
        #define _COMPILED_WITH  "StormC"

        #define min(a,b)        (((a)<(b))?(a):(b))
        #define max(a,b)        (((a)>(b))?(a):(b))
        #define abs(a)          (((a)>0)?(a):-(a))

        #define _INLINE_INCLUDES
        #include <string.h>
#else
#ifdef __VBCC__
        /* VBCC 0.7 (m68k) or better */

        #define INLINE          static __inline
        #define STDARGS         /* unsupported */
        #define ASMCALL         /* nothing */
        #define REGCALL         /* nothing */
        #define CONSTCALL       /* unsupported */
        #define FORMATCALL      /* unsupported */
        #define SAVEDS          __saveds
        #define INTERRUPT       /* unsupported */
        #define NORETURN        /* unsupported */
        #define ALIGNED         /* unsupported */
        #define UNUSED(var)     var /* unsupported */
        #define CHIP            __chip
        #define REG(reg,arg) __reg(##reg) arg
        #define _COMPILED_WITH  "VBCC"

        /* #error VBCC compiler support is untested. Please check all the above definitions */
#else
#ifdef __MAXON__
        /* Maxon C/C++ 3.0 */

        #define INLINE          static inline
        #define STDARGS         /* ? */
        #define ASMCALL         /* ? */
        #define REGCALL         /* ? */
        #define CONSTCALL       /* unsupported */
        #define FORMATCALL      /* unsupported */
        #define SAVEDS          /* unsupported */
        #define INTERRUPT       /* unsupported */
        #define NORETURN        /* unsupported */
        #define ALIGNED         /* unsupported */
        #define UNUSED(var)     var /* unsupported */
        #define REG(reg,arg)    register __##reg arg
        #define _COMPILED_WITH  "Maxon C"

        /* For min(), max() and abs() */
        #define USE_BUILTIN_MATH
        #include <string.h>

        /* #error Maxon C compiler support is untested. Please check all the above definitions */
#else
#ifdef _DCC
        /* DICE C 3.15 */

        #define INLINE          static __inline
        #define STDARGS         __stdargs
        #define ASMCALL         /* nothing */
        #define REGCALL         __regargs
        #define CONSTCALL       const
        #define FORMATCALL      /* unsupported */
        #define FARCALL         __far
        #define SAVEDS          __geta4
        #define INTERRUPT       /* unsupported */
        #define NORETURN        /* unsupported */
        #define ALIGNED         __aligned
        #define UNUSED(var)     var /* unsupported */
        #define CHIP            __chip
        #define REG(reg,arg)    __##reg arg
        #define _COMPILED_WITH  "DICE"

        #define min(a,b)        (((a)<(b))?(a):(b))
        #define max(a,b)        (((a)>(b))?(a):(b))
        #define abs(a)          (((a)>0)?(a):-(a))

        /* #error DICE compiler support is untested. Please check all the above definitions */
#else
#ifdef AZTEC_C
        /* Aztec/Manx C */

        #define INLINE          static
        #define STDARGS         /* ? */
        #define ASMCALL         /* ? */
        #define REGCALL         /* ? */
        #define CONSTCALL       /* unsupported */
        #define FORMATCALL      /* unsupported */
        #define SAVEDS          __geta4
        #define INTERRUPT       /* unsupported */
        #define NORETURN        /* unsupported */
        #define ALIGNED         __aligned
        #define UNUSED(var)     var /* unsupported */
        #define REG(reg,arg)    __##reg arg
        #define _COMPILED_WITH  "Manx C"

        #define min(a,b)        (((a)<(b))?(a):(b))
        #define max(a,b)        (((a)>(b))?(a):(b))
        #define abs(a)          (((a)>0)?(a):-(a))

        #error Aztec/Manx C compiler support is untested. Please check all the above definitions
#else
        #error Please add compiler specific definitions for your compiler
#endif
#endif
#endif
#endif
#endif
#endif
#endif


/* CONST_STRPTR is a new typedef provided since the V44 version of
 * <exec/types.h>. Passing "const char *" parameters will only work
 * if the OS protos are using CONST_STRPTR accordingly, otherwise you
 * will get a lot of compiler warnings for const to volatile conversions.
 *
 * Using "const" where it is appropriate helps the compiler optimizing
 * code better, so this mess is probably worth it.
 */
#if INCLUDE_VERSION < 44
typedef char *CONST_STRPTR;
#endif


/* Special function attributes */

#define LIBCALL         ASMCALL SAVEDS
#define HOOKCALL        ASMCALL SAVEDS
#ifdef __cplusplus
        #define GLOBALCALL extern "C"
#else
        #define GLOBALCALL
#endif

/* special variable attributes */
#define XDEF
#define XREF extern


/* AROS Compatibility: IPTR is a type which can store a pointer
 * as well as a long integer.
 */
#ifndef IPTR
#define IPTR LONG
#endif /* IPTR */


#endif /* !COMPILERSPECIFIC_H */
