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

    MODUL
	rxadd.c

    DESCRIPTION
	Daten an AREXX übergeben

    NOTES

    BUGS

    TODO

    EXAMPLES

    SEE ALSO

    INDEX

    HISTORY

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

/**************************************
		Includes
**************************************/
#include "defs.h"
#include "rexx/rxslib.h"

#define PATCH_RXVARS

/**************************************
	    Globale Variable
**************************************/
Prototype char * GetRexxClip  (char *);
Prototype void	 SetRexxClip  (char *, char *);


Prototype void * currentmsg;


/**************************************
      Fremde Defines & Strukturen
**************************************/
extern struct RxsLib * RexxSysBase;


/**************************************
	    Interne Variable
**************************************/
void * currentmsg = NULL;	/* the currently active foreign rexxmsg */



/**************************************
	   Interne Prototypes
**************************************/






#ifdef PATCH_RXCLIPS

/*************************************************
**
**  REXX CLIPS INTERFACE
**
**  SetRexxClip()   - set an ARexx Cliplist entry
**  UnsetRexxClip() - remove an ARexx Cliplist entry
**  GetRexxClip()   - get the Value of an ARexx Cliplist entry
**
**  do_setclip()   - COM: set an ARexx Cliplist entry
**  do_unsetclip() - COM: remove an ARexx Cliplist entry
**
**************************************************
**
**  The ARexx Cliplist is searched on every Variable
**  reference
**
**  WARNING - YOU NEED AN EXTENDES HEADERLIST
**  TO COMPILE THESE FUNCTIONS
**  as the std OS20-RX_protos do not reference
**  the following functions:
*/
struct Node* FindRsrcNode (struct List*, const char*, long);
void	     RemClipNode  (struct Node*);
struct Node* AddClipNode  (struct List*, const char*, long, long);
#pragma libcall RexxSysBase FindRsrcNode b4 9803
#pragma libcall RexxSysBase AddClipNode 1b6 19804
#pragma libcall RexxSysBase RemClipNode 1bc 801
/*
extern Node* FindRsrcNode (__A0 List*, __A1 const char*, __D0 long);
extern void  RemClipNode  (__A0 Node*);
extern Node* AddClipNode  (__A0 List*, __A1 const char*, __D0 long, __D1 long);
**
*************************************************/

/*
 *  GetRexxClip
 *
 *  Get a variable from the AREXX - cliplist
 */

char*
GetRexxClip ( char * Name )
{
    char	    * str;
    struct RexxRsrc * Node;

    if ((Name != NULL) && (RexxSysBase != NULL) && (Name[0]!='\0')) { /* correct call */

	Node = (struct RexxRsrc *)FindRsrcNode(&RexxSysBase -> rl_ClipList,Name,RRT_CLIP); /* find node */
	if (Node != NULL) {
	    str = (char*)malloc(strlen((char*)(Node -> rr_Arg1))+1);  /* alloc string to copy contents of node to */
	    if (str != NULL) {
		str=strcpy(str,(char*)(Node -> rr_Arg1));             /* copy contents to str */
		return(str);
	    } else {		    /* allocation failed */
		nomemory();
		abort (NULL);
	    } /* if */
	} /* if */
    } /* if */
    return(NULL);
} /* GetRexxClip */


/*
*! >SETCIP    name value
*! >UNSETCLIP name
*!
*!  nearly the same as SETENV/UNSETENV but for the REXX-cliplist
*!
*/

void
UnsetRexxClip (char * name)
{
    struct RexxRsrc *Node;

    if (RexxSysBase != NULL) {
	LockBase(RRT_CLIP);
	Node = (struct RexxRsrc *)FindRsrcNode(&RexxSysBase -> rl_ClipList,name,RRT_CLIP);
	if (Node != NULL) {
	    RemClipNode(Node);
	} /* if */
	UnlockBase(RRT_CLIP);
    } /* if */
} /* UnsetRexxClip */


void
SetRexxClip ( char * name, char * value )
{
    struct RexxRsrc *Node;

    if (RexxSysBase != NULL) {
	UnsetRexxClip(name);         /* for sure first delete a perhaps existing node - not very fast, but clean(?) */
	LockBase(RRT_CLIP);
	Node = (struct RexxRsrc *)AddClipNode (&RexxSysBase -> rl_ClipList, name, strlen(value), value);
	if (Node == NULL) {

	    nomemory();
	} /* if */
	UnlockBase(RRT_CLIP);
    } /* if */
} /* SetRexxClip */


void
do_unsetclip ()
{
    UnsetRexxClip(av[1]);
} /* do_unsetclip */


void
do_setclip ()
{
    SetRexxClip(av[1], av[2]);
} /* do_setclip */



#endif /* PATCH_RXCLIPS */
#ifdef PATCH_RXVARS

#if 0
/*************************************************
**
**  REXX VARIABLE INTERFACE (RVI)
**
**  setrexxvar() - set an ARexx variable
**  getrexxvar() - get the Value of an ARexx variable
**
**  do_setrexx() - COM: set an ARexx variable
**
**************************************************
**
**  The ARexx Variables are checked on every Variable
**  reference
**
**************************************************
**
**  ATTENTION!!!!
**
**	YOU NEED  REXXVARS.O  TO LINK, IF
**	YOU'VE COMPILED WITH "PATCH_RXVARS" DEFINED
**
**	I'll try to recompile rexxVars.o so that
**	No longer on each call to getrexxvar the
**	rexxsyslib.library is opened a 2nd time
**
*************************************************/
/*
**  REXXVARS
**
**  Headers for use with rexxvars.o
*/


extern	__stdargs long CheckRexxMsg(struct Message* msg);
/* Usage: boolean = CheckRexxMsg(message); */

extern	__stdargs long GetRexxVar(struct RexxMsg* msg, char* name, char** value);
/* Usage: error = GetRexxVar(message,variable,&value); */

extern	__stdargs long SetRexxVar(struct RexxMsg* msg, char* name, char* value, int length);
/* Usage: error = SetRexxVar(message,variable,value,length); */
#endif

DEFVARTREE( 88, "RX_", VAR_RX, 3, 3, 0, NULL, NULL, setrexxvar, getrexxvar )

/*
 *  setrexxvar / getrexxvar
 *	Rexx Vars functions for Variable support
 */

Prototype char * getrexxvar   (char * name);
char *getrexxvar (char *name)
{
    char* val0 = NULL;
    char* val1 = NULL;
    long err;

    if (currentmsg == NULL) {
	/* error ("Cannot get RxVars\nwithout a pending RxMsg"); */ /* can not be called if we check tha routine at every var-expansion */
	return (NULL);
    } /* if */

    err = GetRexxVar((void*)currentmsg, name, &val0);
    if (val0 && !err) {
	val1 = malloc(strlen(val0)+1);
	if (val1) {
	    strcpy(val1, val0);
	} else {
	    nomemory();
	    return (NULL);
	} /* if */
    } /* if */

    return(val1);
} /* getrexxvar */


Prototype void	 setrexxvar   (char * name, char * value);
void setrexxvar (char * name, char * value)
{
    long err;

    if (currentmsg == NULL) {
	error ("%s:\nCannot set RxVars\nwithout a pending RxMsg", av[0]);
	return;
    } /* if */

    err = SetRexxVar((void*)currentmsg, name, value, strlen(value));
/* printf ("setting rxvar %s to %s - %ld\n", name, value, err); */
    if (err) {
	SET_ABORTION( 1 );
    } /* if */
} /* setrexxvar */

/*
*! >SETREXX
*!	Interface to use Variables from Arexx Programs
*!
*!  NOTE: UNSETREXX does NOT exist
*!
*/

DEFUSERCMD("SetRexx", 2, CF_COK|CF_VWM|CF_ICO|0, void, do_setrexx, (void), )
{
    setrexxvar(av[1], av[2]);
} /* do_setrexx */


#endif /* PATCH_RXVARS */
/******************************************************************************
*****  ENDE rxadd.c
******************************************************************************/

