/******************************************************************************

    MODULE
	Definitions.h

    DESCRIPTION
	The most important definitions to make a module work
	in the XDME complex

    HISTORY
	20-11-94 b_noll created

******************************************************************************/

#ifndef DEFINITIONS_H
#define DEFINITIONS_H 1

/**************************************
	    Macros
**************************************/


/* ---- std way to declare prototypes, introduced by DICE */
#undef	Prototype
#define Prototype extern

#undef	Local
#define Local	  static

/* ---- Some protos might be interesting only to a certain module */
/*	while others might be usable for all other modules; so we */
/*	should introduce something to distinguish these cases	  */


/* ---- alternative entry for an external visible function */
#undef	DEFPROTO
#define DEFPROTO(ret,func,param)                        ret func param


/* ---- entry for XDME v1.xx macro language commands */
#undef	DEFUSERCMD
#define DEFUSERCMD(str,nargs,flags,ret,func,param,ext)  ret func param ext


/* ---- entries for generic flags - first create gen_flags.h 2 compile */
#undef	DEFFLAG
#include "gen_flags.h"
#undef	DEFFLAG
#define DEFFLAG(date,name,initval)  /* expand to nothing */


/* ---- entries for localizable strings - create gen_messages.h 2 compile */
#undef	DEFMESSAGE
#define DEFMESSAGE(name,txt) extern const char *name;
#include "gen_messages.h"
#undef	DEFMESSAGE
#define DEFMESSAGE(name,txt)        /* expand to nothing */


/* ---- entry for a XDME v1.xx group of variables  */
#undef	DEFVARTREE
#define DEFVARTREE(prio,prefix,id,prelen,precut,flags,replace,ud,set,get) \
				    /* expand to nothing */


/* ---- entry for a XDME signal bit handler in main loop */
#undef	DEFSIGHANDLER
#define DEFSIGHANDLER(sig,func)     /* expand to nothing */


/* ---- entry for a define, that is only active, if a certain module is used */
#include "gen_definitions.h"
#undef	DEFDEFINITION
#define DEFDEFINITION(x)            /* expand to nothing */


/* ---- entries for autoinit and autoexit functions (compiler dependent) */

#if   defined(__SASC)

#   undef  DEFAUTOINIT
#   define DEFAUTOINIT(name)                \
    void _STI__ ## name (void)

    /* ---- the somehow funny defexit is caused by the fact, that some */
    /*	    other functions are trying to call the exitfunc by name    */
#   undef  DEFAUTOEXIT
#   define DEFAUTOEXIT(name)                \
    void name (void);                       \
    void _STD__ ## name (void) { name(); }  \
    void name (void)

#elif defined(_DCC)

#   undef  DEFAUTOINIT
#   define DEFAUTOINIT(name) __autoinit void name (void)

#   undef  DEFAUTOEXIT
#   define DEFAUTOEXIT(name) __autoexit void name (void)

#else

#   error "Unknown compiler! Please add proper defines in Definitions.h"

#endif


/* ---- some other compiler specific stuff used for special OS	   */
/*	related functionality like e.g. Libs, callbacks, BOOPSI    */
/*								   */
/*	**** this stuff is currently not used inside XDME ****	   */
/*								   */
/*	PRE_A4 qualifier for a function to restore the A4 register */
/*	POST_A4 function to restore the A4 register		   */
/*	    either PRE_A4 or POST_A4 is normally empty		   */
/*	PRE_REG qualifier to indicate, a function uses explicitely */
/*	    defined registerized arguments			   */
/*	REG() definition for a registerized parameter              */
/*	__A[012]/__D[01] the mostly used registerized parameters   */

#if   defined(__SASC)

#   define  PRE_A4  __saveds
#   define  PRE_REG __asm
#   define POST_A4

#   define REG(r,x) register __ ## r x

#   define __A0(x)  register __a0 x
#   define __A1(x)  register __a1 x
#   define __A2(x)  register __a2 x
#   define __D0(x)  register __d0 x
#   define __D1(x)  register __d1 x

#elif defined(_DCC)

#   define  PRE_A4  __geta4
#   define  PRE_REG
#   define POST_A4

#   define REG(r,x) __ ## r x

#   define __A0(x)  __A0 x
#   define __A1(x)  __A1 x
#   define __A2(x)  __A2 x
#   define __D0(x)  __D0 x
#   define __D1(x)  __D1 x

#else

#   error "Unknown compiler! Please add proper defines in Definitions.h"

#endif



#if 0

/* ---- support for (not yet supported) ARexx commands  */
/*	Other than ARexxBox we do not calloc/free	*/
/*	the arg structs in additional calls to the	*/
/*	according function but immediately in the main	*/
/*	command dispatcher				*/
/*							*/
/* *** this stuff is currently not used inside XDME *** */

//////////////////////////////////////////////////
//	Read the C-fied Definitions
//////////////////////////////////////////////////
#include "gen_rx_commands.h"

//////////////////////////////////////////////////
//	    Make Arg Structs
//////////////////////////////////////////////////
#undef	ARG_SEP
#define ARG_SEP ";"
#undef	DEFRXCMD
#define DEFRXCMD(name,param,results)            \
    struct name ## _ARG {			\
	A_ARGS_ ## name 			\
    };
#include "rx_commands.h"

//////////////////////////////////////////////////
//	    Make Prototypes
//////////////////////////////////////////////////
#undef	ARG_SEP
#define ARG_SEP ","
#undef	DEFRXCMD
#define DEFRXCMD(name,param,results)            \
    RX_TYPE name ( APTR, A_ARGS_ ## name APTR); \
    RX_TYPE name ## A ( APTR, struct name ## _ARG *arg, APTR);
#include "rx_commands.h"

//////////////////////////////////////////////////
//	    Header for each RX Command
//	we create a stackargs function
//	and a varargs function
//////////////////////////////////////////////////
#undef	ARG_SEP
#define ARG_SEP ","
#undef	DEFRXCMD
#define DEFRXCMD(name,param,results)                    \
    RX_TYPE name ( APTR lock, A_ARGS_ ## name APTR ud) {\
	va_list arg;					\
	va_start (va, lock);                            \
	return VCALL (name);                            \
	va_end (arg);                                   \
    }							\
    RX_TYPE name ## A ( APTR lock, struct name ## _ARG *arg, APTR ud )

//////////////////////////////////////////////////
//  Call another command with the same Arguments
//////////////////////////////////////////////////
#define VCALL(name) name ## A (lock, (struct name ## _ARG *) arg, ud)

//////////////////////////////////////////////////
// Make sure only One of the Args is used
//////////////////////////////////////////////////
#define ONLY_ONE() do{                                      \
	int    num = 0; 				    \
	ULONG *ptr = (ULONG *)((ULONG)arg) + sizeof (arg*); \
	do {						    \
	    if (*(--ptr)) ++ num;                           \
	} while (ptr != (ULONG *)arg);                      \
	if (num != 1)                                       \
	    return RX_ERROR;				    \
    }while(0)

#endif


#if 0

/* ---- support for (not yet supported) ARexx commands          */
/*	this time we use the same mechanism like ARexxBox	*/
/*	ahhhh that's imho a waste of code                       */
/*	the main differences to our code are that here a **parg */
/*	is used and we are using a 3-parted function		*/
/*								*/
/*	please note, that the same overhead is neccessary is in */
/*	the previous way; i have omitted it here, since its not */
/*	much more than codecopying				*/
/*								*/
/*	**** this stuff is currently not used inside XDME ****	*/


#undef	DEFARBCMD
#define DEFARBCMD(name,param,results)       \
    void name ## A ( APTR lock, struct name ## _ARG **parg, ULONG action )

#define ARBINIT(name,block)                 \
    {					    \
	struct name ## _ARG *arg = *parg;   \
	switch (action) {                   \
	case INIT:			    \
	    *parg = calloc(sizeof (*arg));  \
	    if (*parg) {                    \
		arg = *parg;		    \
		block			    \
	    }				    \
	    break;			    \
	case ACTION:

#define ARBEXIT(name,block)                 \
	    break;			    \
	case FREE:			    \
	    block;			    \
	    free (arg);                     \
	    break;			    \
	}				    \
    }

#endif


/* ---- we use SPC_VAR to shade out parts of the file that are only of */
/*	interest to the VariableParser, and which would confuse the C  */
/*	compiler ...						       */
#undef SPC_VAR

#endif /* !DEFINITIONS_H */

/******************************************************************************
*****  END Definitions.h
******************************************************************************/
