/* === rexx/storage.h ==================================================
 *
 * Copyright (c) 1986, 1987 by William S. Hawes (All Rights Reserved)
 *
 * =====================================================================
 * Header file to define ARexx data structures.
 */

#ifndef REXX_STORAGE_H
#define REXX_STORAGE_H

#ifndef EXEC_TYPES_H
#include "exec/types.h"
#endif

#ifndef EXEC_NODES_H
#include "exec/nodes.h"
#endif

#ifndef EXEC_LISTS_H
#include "exec/lists.h"
#endif

#ifndef EXEC_PORTS_H
#include "exec/ports.h"
#endif

#ifndef EXEC_LIBRARIES_H
#include "exec/libraries.h"
#endif

#ifndef LIBRARIES_DOS_H
#include <libraries/dos.h>
#endif

/* The NexxStr structure is used to maintain the internal strings in REXX.
 * It includes the buffer area for the string and associated attributes.
 * This is actually a variable-length structure; it is allocated for a
 * specific length string, and the length is never modified thereafter
 * (since it's used for recycling).
 */

struct NexxStr {
   LONG     ns_Ivalue;                 /* integer value                 */
   UWORD    ns_Length;                 /* length in bytes (excl null)   */
   UBYTE    ns_Flags;                  /* attribute flags               */
   UBYTE    ns_Hash;                   /* hash code                     */
   BYTE     ns_Buff[8];                /* buffer area for strings       */
   };                                  /* size: 16 bytes (minimum)      */

#define NXADDLEN 9                     /* offset plus null byte         */
#define IVALUE(nsPtr) (nsPtr->ns_Ivalue)

/* String attribute flag bit definitions                                */
#define NSB_KEEP     0                 /* permanent string?             */
#define NSB_STRING   1                 /* string form valid?            */
#define NSB_NOTNUM   2                 /* non-numeric?                  */
#define NSB_NUMBER   3                 /* a valid number?               */
#define NSB_BINARY   4                 /* integer value saved?          */
#define NSB_FLOAT    5                 /* floating point format?        */
#define NSB_EXT      6                 /* an external string?           */
#define NSB_SOURCE   7                 /* part of the program source?   */

/* The flag form of the string attributes                               */
#define NSF_KEEP     (1 << NSB_KEEP  )
#define NSF_STRING   (1 << NSB_STRING)
#define NSF_NOTNUM   (1 << NSB_NOTNUM)
#define NSF_NUMBER   (1 << NSB_NUMBER)
#define NSF_BINARY   (1 << NSB_BINARY)
#define NSF_FLOAT    (1 << NSB_FLOAT )
#define NSF_EXT      (1 << NSB_EXT   )
#define NSF_SOURCE   (1 << NSB_SOURCE)

/* Combinations of flags                                                */
#define NSF_INTNUM   (NSF_NUMBER | NSF_BINARY | NSF_STRING)
#define NSF_DPNUM    (NSF_NUMBER | NSF_FLOAT)
#define NSF_ALPHA    (NSF_NOTNUM | NSF_STRING)
#define NSF_OWNED    (NSF_SOURCE | NSF_EXT    | NSF_KEEP)
#define KEEPSTR      (NSF_STRING | NSF_SOURCE | NSF_NOTNUM)
#define KEEPNUM      (NSF_STRING | NSF_SOURCE | NSF_NUMBER | NSF_BINARY)

/* The RexxArg structure is identical to the NexxStr structure, but
 * is allocated from system memory rather than from internal storage.
 * This structure is used for passing arguments to external programs.
 * It is usually passed as an "argstring", a pointer to the string buffer.
 */

struct RexxArg {
   LONG     ra_Size;                   /* total allocated length        */
   UWORD    ra_Length;                 /* length of string              */
   UBYTE    ra_Flags;                  /* attribute flags               */
   UBYTE    ra_Hash;                   /* hash code                     */
   BYTE     ra_Buff[8];                /* buffer area                   */
   };                                  /* size: 16 bytes (minimum)      */

/* The RexxMsg structure is used for all communications with REXX
 * programs.  It is an EXEC message with a parameter block appended.
 */

struct RexxMsg {
   struct Message rm_Node;             /* EXEC message structure        */
   APTR     rm_TaskBlock;              /* global structure (private)    */
   APTR     rm_LibBase;                /* library base (private)        */
   LONG     rm_Action;                 /* command (action) code         */
   LONG     rm_Result1;                /* primary result (return code)  */
   LONG     rm_Result2;                /* secondary result              */
   STRPTR   rm_Args[16];               /* argument block (ARG0-ARG15)   */

   struct MsgPort *rm_PassPort;        /* forwarding port               */
   STRPTR   rm_CommAddr;               /* host address (port name)      */
   STRPTR   rm_FileExt;                /* file extension                */
   LONG     rm_Stdin;                  /* input stream (filehandle)     */
   LONG     rm_Stdout;                 /* output stream (filehandle)    */
   LONG     rm_avail;                  /* future expansion              */
   };                                  /* size: 128 bytes               */

/* Field definitions                                                    */
#define ARG0(rmp) (rmp->rm_Args[0])    /* start of argblock             */
#define ARG1(rmp) (rmp->rm_Args[1])    /* first argument                */
#define ARG2(rmp) (rmp->rm_Args[2])    /* second argument               */

#define MAXRMARG  15                   /* maximum arguments             */

/* Command (action) codes for message packets                           */
#define RXCOMM    0x01000000           /* a command-level invocation    */
#define RXFUNC    0x02000000           /* a function call               */
#define RXCLOSE   0x03000000           /* close the REXX server         */
#define RXQUERY   0x04000000           /* query for information         */
#define RXADDFH   0x07000000           /* add a function host           */
#define RXADDLIB  0x08000000           /* add a function library        */
#define RXREMLIB  0x09000000           /* remove a function library     */
#define RXADDCON  0x0A000000           /* add/update a ClipList string  */
#define RXREMCON  0x0B000000           /* remove a ClipList string      */
#define RXTCOPN   0x0C000000           /* open the trace console        */
#define RXTCCLS   0x0D000000           /* close the trace console       */

/* Command modifier flag bits                                           */
#define RXFB_NOIO    16                /* suppress I/O inheritance?     */
#define RXFB_RESULT  17                /* result string expected?       */
#define RXFB_STRING  18                /* program is a "string file"?   */
#define RXFB_TOKEN   19                /* tokenize the command line?    */
#define RXFB_NONRET  20                /* a "no-return" message?        */

/* The flag form of the command modifiers                               */
#define RXFF_NOIO    (1L << RXFB_NOIO  )
#define RXFF_RESULT  (1L << RXFB_RESULT)
#define RXFF_STRING  (1L << RXFB_STRING)
#define RXFF_TOKEN   (1L << RXFB_TOKEN )
#define RXFF_NONRET  (1L << RXFB_NONRET)

#define RXCODEMASK   0xFF000000
#define RXARGMASK    0x0000000F

/* The RexxRsrc structure is used to manage global resources.  Each node 
 * has a name string created as a RexxArg structure, and the total size
 * of the node is saved in the "rr_Size" field.  The REXX systems library
 * provides functions to allocate and release resource nodes.  If special
 * deletion operations are required, an offset and base can be provided in
 * "rr_Func" and "rr_Base", respectively.  This "autodelete" function will
 * be called with the base in register A6 and the node in A0.
 */

struct RexxRsrc {
   struct Node rr_Node;
   WORD     rr_Func;                   /* "auto-delete" offset          */
   APTR     rr_Base;                   /* "auto-delete" base            */
   LONG     rr_Size;                   /* total size of node            */
   LONG     rr_Arg1;                   /* available ...                 */
   LONG     rr_Arg2;                   /* available ...                 */
   };                                  /* size: 32 bytes                */

/* Resource node types                                                  */
#define RRT_ANY      0                 /* any node type ...             */
#define RRT_LIB      1                 /* a function library            */
#define RRT_PORT     2                 /* a public port                 */
#define RRT_FILE     3                 /* a file IoBuff                 */
#define RRT_HOST     4                 /* a function host               */
#define RRT_CLIP     5                 /* a Clip List node              */

/* The RexxTask structure holds the fields used by REXX to communicate with
 * external processes, including the client task.  It includes the global
 * data structure (and the base environment).  The structure is passed to
 * the newly-created task in its "wake-up" message.
 */

#define GLOBALSZ  200                  /* total size of GlobalData      */

struct RexxTask {
   BYTE     rt_Global[GLOBALSZ];       /* global data structure         */
   struct MsgPort rt_MsgPort;          /* global message port           */
   UBYTE    rt_Flags;                  /* task flag bits                */
   BYTE     rt_SigBit;                 /* signal bit                    */

   APTR     rt_ClientID;               /* the client's task ID          */
   APTR     rt_MsgPkt;                 /* the packet being processed    */
   APTR     rt_TaskID;                 /* our task ID                   */
   APTR     rt_RexxPort;               /* the REXX public port          */

   APTR     rt_ErrTrap;                /* Error trap address            */
   APTR     rt_StackPtr;               /* stack pointer for traps       */

   struct List rt_Header1;             /* Environment list              */
   struct List rt_Header2;             /* Memory freelist               */
   struct List rt_Header3;             /* Memory allocation list        */
   struct List rt_Header4;             /* Files list                    */
   struct List rt_Header5;             /* Message Ports List            */
   };

/* Definitions for RexxTask flag bits                                   */
#define RTFB_TRACE   0                 /* external trace flag           */
#define RTFB_HALT    1                 /* external halt flag            */
#define RTFB_SUSP    2                 /* suspend task?                 */
#define RTFB_TCUSE   3                 /* trace console in use?         */
#define RTFB_WAIT    6                 /* waiting for reply?            */
#define RTFB_CLOSE   7                 /* task completed?               */

/* Definitions for memory allocation constants                          */
#define MEMQUANT  16L                  /* quantum of memory space       */
#define MEMMASK   0xFFFFFFF0           /* mask for rounding the size    */

#define MEMQUICK  (1L << 0 )           /* EXEC flags: MEMF_PUBLIC       */
#define MEMCLEAR  (1L << 16)           /* EXEC flags: MEMF_CLEAR        */

/* The SrcNode is a temporary structure used to hold values destined for
 * a segment array.  It is also used to maintain the memory freelist.
 */

struct SrcNode {
   struct SrcNode *sn_Succ;            /* next node                     */
   struct SrcNode *sn_Pred;            /* previous node                 */
   APTR     sn_Ptr;                    /* pointer value                 */
   LONG     sn_Size;                   /* size of object                */
   };                                  /* size: 16 bytes                */

#ifdef	LATTICE
struct NexxStr*ErrorMsg(long) ;
long IsSymbol(char *) ;
struct List *CurrentEnv(struct RexxTask *) ;
void FreeSpace(struct List *, void *, long) ;
struct RexxArg *CreateArgstring(char *, long) ;
void DeleteArgstring(struct RexxArg *) ;
long LengthArgstring(struct RexxArg *) ;
struct RexxMsg *CreateRexxMsg(struct MsgPort *, char *, char *) ;
void DeleteRexxMsg(struct RexxMsg *) ;
void ClearRexxMsg(struct RexxMsg *, long) ;
long FillRexxMsg(struct RexxMsg *, long, long) ;
long IsRexxMsg(struct RexxMsg *) ;
struct RexxRsrc *AddRsrcNode(struct List *, char *, long) ;
struct RexxRsrc *FindRsrcNode(struct List *, char *, long) ;
void RemRsrcList(struct List *) ;
void RemRsrcNode(struct RexxRsrc *) ;
struct RexxRsrc *OpenPublicPort(struct List *, char *) ;
void ClosePublicPort(struct RexxRsrc *) ;
char *ListNames(struct List *, char) ;
void ClearMem(APTR, long) ;
void InitList(struct List *) ;
struct MsgPort *InitPort(struct MsgPort *, char *) ;
void FreePort(struct MsgPort *) ;
long CmpString(char *, char *) ;
char *StcToken(char *) ;
long StrcmpN(char *, char *, long) ;
long StrcmpU(char *, char *, long) ;
long StrcpyA(char *, char *, long) ;
long StrcpyN(char *, char *, long) ;
long StrcpyU(char *, char *, long) ;
void StrflipN(char *, long) ;
long Strlen(char *) ;
char ToUpper(char) ;
long CVa2i(char *) ;
char *CVi2a(char *, long, long) ;
char *CVi2arg(long) ;
char *CVi2az(char *, long, long) ;
long CVc2x(char *, char *, long, long) ;
long CVx2c(char *, char *, long, long) ;
struct IoBuff *OpenF(struct List *, char *, long, long) ;
void CloseF(struct IoBuff *) ;
char *ReadStr(struct IoBuff *, char *, long) ;
long ReadF(struct IoBuff *, char *, long) ;
long WriteF(struct IoBuff *, char *, long) ;
long SeekF(struct IoBuff *, long, long) ;
long QueueF(struct IoBuff *, char *, long) ;
long StackF(struct IoBuff *, char *, long) ;
long ExistF(char *) ;
long DOSRead(BPTR, char *, long) ;
long DOSWrite(BPTR, char *, long) ;
struct StandardPacket *CreateDOSPkt(void) ;
void DeleteDOSPkt(struct StandardPacket *) ;
struct Node *FindDevice(char *, long) ;
struct RexxRsrc *AddClipNode(struct List *, char *, long, long) ;
void RemClipNode(struct RexxRsrc *) ;
void LockRexxBase(long) ;
void UnlockRexxBase(long) ;

long __stdargs SetRexxVar(struct RexxMsg *, char *, char *, long) ;

#ifndef	NO_PRAGMAS
/* #pragma libcall RexxSysBase Rexx 1e            ; Main entry point */
/* #pragma libcall RexxSysBase rxParse 24         ; (private) */
/* #pragma libcall RexxSysBase rxInstruct 2a      ; (private) */
/* #pragma libcall RexxSysBase rxSuspend 30       ; (private) */
/* #pragma libcall RexxSysBase EvalOp 36          ; (private) */
/* #pragma libcall RexxSysBase AssignValue 3c     ; (private) */
/* #pragma libcall RexxSysBase EnterSymbol 42     ; (private) */
/* #pragma libcall RexxSysBase FetchValue 48      ; (private) */
/* #pragma libcall RexxSysBase LookUpValue 4e     ; (private) */
/* #pragma libcall RexxSysBase SetValue 54        ; (private) */
/* #pragma libcall RexxSysBase SymExpand 5a       ; (private) */
#pragma libcall RexxSysBase ErrorMsg 60 081
#pragma libcall RexxSysBase IsSymbol 66 081
#pragma libcall RexxSysBase CurrentEnv 6c 081
#pragma libcall RexxSysBase GetSpace 72 0882
#pragma libcall RexxSysBase FreeSpace 78 09803
#pragma libcall RexxSysBase CreateArgstring 7e 0882
#pragma libcall RexxSysBase DeleteArgstring 84 801
#pragma libcall RexxSysBase LengthArgstring 8a 801	/* A guess... */
#pragma libcall RexxSysBase CreateRexxMsg 90 09883
#pragma libcall RexxSysBase DeleteRexxMsg 96 801
#pragma libcall RexxSysBase ClearRexxMsg 9c 0802
#pragma libcall RexxSysBase FillRexxMsg a2 10803
#pragma libcall RexxSysBase IsRexxMsg a8 801
#pragma libcall RexxSysBase AddRsrcNode ae 09883
#pragma libcall RexxSysBase FindRsrcNode b4 09883
#pragma libcall RexxSysBase RemRsrcList ba 801
#pragma libcall RexxSysBase RemRsrcNode c0 801
#pragma libcall RexxSysBase OpenPublicPort c6 9882
#pragma libcall RexxSysBase ClosePublicPort cc 801
#pragma libcall RexxSysBase ListNames d2 0882
#pragma libcall RexxSysBase ClearMem d8 0802
#pragma libcall RexxSysBase InitList de 801
#pragma libcall RexxSysBase InitPort e4 9892
#pragma libcall RexxSysBase FreePort ea 801
#pragma libcall RexxSysBase CmpString f0 9802
#pragma libcall RexxSysBase StcToken f6 891
#pragma libcall RexxSysBase StrcmpN fc 09803
#pragma libcall RexxSysBase StrcmpU 102 09803
#pragma libcall RexxSysBase StrcpyA 108 09803
#pragma libcall RexxSysBase StrcpyN 10e 09803
#pragma libcall RexxSysBase StrcpyU 114 09803
#pragma libcall RexxSysBase StrflipN 11a 0802
#pragma libcall RexxSysBase Strlen 120 801
#pragma libcall RexxSysBase ToUpper 126 001
#pragma libcall RexxSysBase CVa2i 12c 811
#pragma libcall RexxSysBase CVi2a 132 10883
#pragma libcall RexxSysBase CVi2arg 138 081
#pragma libcall RexxSysBase CVi2az 13e 10883
#pragma libcall RexxSysBase CVc2x 144 109804
#pragma libcall RexxSysBase CVx2c 14a 109804
#pragma libcall RexxSysBase OpenF 150  109884
#pragma libcall RexxSysBase CloseF 156 801
#pragma libcall RexxSysBase ReadStr 15c 09893
#pragma libcall RexxSysBase ReadF 162 09803
#pragma libcall RexxSysBase WriteF 168 09803
#pragma libcall RexxSysBase SeekF 16e 10803
#pragma libcall RexxSysBase QueueF 174 09803
#pragma libcall RexxSysBase StackF 17a 09803
#pragma libcall RexxSysBase ExistF 180 801
/* #pragma libcall RexxSysBase DOSCommand 186 */
#pragma libcall RexxSysBase DOSRead 18c 09803
#pragma libcall RexxSysBase DOSWrite 192 09803
#pragma libcall RexxSysBase CreateDOSPkt 198 80
#pragma libcall RexxSysBase DeleteDOSPkt 19e 801
/* #pragma libcall RexxSysBase SendDOSPkt 1a4 */
/* #pragma libcall RexxSysBase WaitDOSPkt 1aa */
#pragma libcall RexxSysBase FindDevice 1b0 0882
#pragma libcall RexxSysBase AddClipNode 1b6 109884
#pragma libcall RexxSysBase RemClipNode 1c2 801
#pragma libcall RexxSysBase LockRexxBase 1c8 001
#pragma libcall RexxSysBase UnlockRexxBase 1ce 001
#endif
#endif

#endif
