/*
The following declarations are used in most every program written by Paul
Kienitz.  Generally, I use a symbol table file which includes exec/exec.h,
libraries/dosextens.h, stdio.h, and this, which pulls in functions.h.  I have
a separate symbol file for intuition/intuitionbase.h with INTUITIONPRIVATE
defined.  Intuitionbase.h pulls in all the other intuition/ files.
*/

#ifndef PAUL_DOT_AITCH
#define PAUL_DOT_AITCH

/* This won't work unless you pull in stdio.h */
#define put(S) fputs(S, stdout)


#define null   0L
#define maxint 0x7fffffffL
#define minint 0x80000000L
/* uppercase is a pain in the wazoo */

#define bip(T, B) ((T *) (B << 2))
#define gbip(B)   bip(void, B)
/* B is expected to be of type BPTR or BSTR. */

typedef short bool;
#define false 0
#define true  1

typedef unsigned short ushort;
typedef unsigned long  ulong;
typedef unsigned char  ubyte;

typedef void *adr;
typedef char *str;
typedef str  *stray;

#define bit(B) (1L << (B))

#define private static
#define import  extern
#define PUBLIC


#ifdef AZTEC_C

/******
HERE'S THE PART where we monkey with functions.h.  The problem is that many
of the functions in there are incorrectly declared, according to me.  First,
CreateProc and DeviceProc are declared as returning struct Process pointers
when they in fact return struct MsgPort pointers.  Secondly, all of the DOS
functions that return BPTRs are declared as returning pointers.  Some of
these functions can be fixed by #defining Blah as _Blah, when the glue
routine provides both names, and declaring _Blah properly.  For the others,
we use a #define before functions.h to prevent it from defining them at all. 
*/

#define CreateProc ___n_O_ne_XI__st_EN_t____1
#define DeviceProc ___n_O_ne_XI__st_EN_t____2
#define CreateDir  ___n_O_ne_XI__st_EN_t____3
#define ParentDir  ___n_O_ne_XI__st_EN_t____4
#define DupLock    ___n_O_ne_XI__st_EN_t____5
#define LoadSeg    ___n_O_ne_XI__st_EN_t____6

#include <functions.h>

#undef CreateProc
#undef DeviceProc
#undef CreateDir
#undef ParentDir
#undef DupLock
#undef LoadSeg

/* these won't work unless exec/ports.h and libraries/dos.h are pulled in: */
import BPTR CreateDir(), ParentDir(), DupLock(), LoadSeg();
import struct MsgPort *CreateProc(), *DeviceProc();

import BPTR _Lock(), _Open(), _Input(), _Output(), _CurrentDir();

#define Lock       _Lock
#define Open       _Open
#define Input      _Input
#define Output     _Output
#define CurrentDir _CurrentDir

/*
What we really need is different BPTR types that are incompatible for
assignment without casts, yet refuse to be dereferenced as pointers.  Like
FileLockBPTR, SegListBPTR, etc.  But what would these be defined as?
*/


/* AND NOW, convenience stuff:::::::::::::::::::: */

#ifdef SAVE_ONE_MEASLY_INSTRUCTION_PER_CALL
import struct Message *_GetMsg();
import void            _ReplyMsg();
import struct Message *_WaitPort();
import struct Task    *_FindTask();

#define GetMsg   _GetMsg
#define ReplyMsg _ReplyMsg
#define WaitPort _WaitPort
#define FindTask _FindTask
#endif
/*
There are probably a few other glue routines with two names and wasted
instructions.  (It's like, GetMsg is a jump to _GetMsg.  Why didn't they just
put the two symbols at the same address??  Bozos...)
*/

import adr  _AllocMem();
import void _FreeMem();

#else  /* lattice */
#define _AllocMem AllocMem
#define _FreeMem  FreeMem
#define _Lock     Lock
#define _Open     Open
#endif AZTEC_C

/* remember, these won't expand lessen you pulls in exec/memory.h: */

#define Alloc(S)    _AllocMem((long) (S), 0L)
#define AllocC(S)   _AllocMem((long) (S), MEMF_CHIP)
#define AllocP(S)   _AllocMem((long) (S), MEMF_PUBLIC)
#define AllocZ(S)   _AllocMem((long) (S), MEMF_CLEAR)
#define AllocCP(S)  _AllocMem((long) (S), MEMF_CHIP | MEMF_PUBLIC)
#define AllocCZ(S)  _AllocMem((long) (S), MEMF_CHIP | MEMF_CLEAR)
#define AllocPZ(S)  _AllocMem((long) (S), MEMF_PUBLIC | MEMF_CLEAR)
#define AllocCPZ(S) _AllocMem((long) (S), MEMF_CHIP | MEMF_PUBLIC | MEMF_CLEAR)
#define NewR(T, R)  ((T *) _AllocMem((long) sizeof(T), R))
#define New(T)      NewR(T, 0L)
#define MewC(T)     NewR(T, MEMF_CHIP)
#define NewP(T)     NewR(T, MEMF_PUBLIC)
#define NewZ(T)     NewR(T, MEMF_CLEAR)
#define NewCP(T)    NewR(T, MEMF_CHIP | MEMF_PUBLIC)
#define NewCZ(T)    NewR(T, MEMF_CHIP | MEMF_CLEAR)
#define NewPZ(T)    NewR(T, MEMF_PUBLIC | MEMF_CLEAR)
#define NewCPZ(T)   NewR(T, MEMF_CHIP | MEMF_PUBLIC | MEMF_CLEAR)

#define Free(T, A)    _FreeMem(A, (long) sizeof(T))
#define FreeMem(A, S) _FreeMem(A, (long) (S))


#define RLock(F) _Lock(F, ACCESS_READ)
#define WLock(F) _Lock(F, ACCESS_WRITE)
#define OOpen(F) _Open(F, MODE_OLDFILE)
#define NOpen(F) _Open(F, MODE_NEWFILE)


#define Forbid() ((*((ubyte **) 4))[295]++)
/* as efficient as assembly; Aztec turns that into two instructions. */

/***
#define ThisProcess() ((*((struct Process ***) 4))[69])
***/
/* equivalent to (struct Process *) SysBase->ThisTask, two instructions. */

/* Aw heck, I better play it safe for future versions of Exec: */
#define ThisProcess() ((struct Process *) _FindTask(0L))
import struct Task *_FindTask();

#ifdef AZTEC_C	 /* remove this for old v3.4 aztec */
#define strcpy _BUILTIN_strcpy
#define strcmp _BUILTIN_strcmp
#define strlen _BUILTIN_strlen
#endif

#endif PAUL_DOT_AITCH
