/* misc.c */

/*		Copyright © 1989 by Donald T. Meyer, Stormgate Software
 *		All Rights Reserved
 */



#include "rxil.h"



/* NAME
 *		RxilGetReturn
 *
 * SYNOPSIS
 *		rxi = RxilGetReturn();
 *
 *		struct RxilInvocation *rxi;
 *
 * FUNCTION
 *		This will return a pointer to any RxilInvocation message
 *		that has been replyed (but not yet cleaned up and available).
 *		NULL will be returned if all RxilInvocation structures which have
 *		been allocated are available or pending.
 *
 * INPUTS
 *		None
 *
 * RESULT
 *		A pointer to a RxilInvocation structure.  If none have been
 *		replied and are available to be handled, this will return a NULL.
 *
 * SIDES
 *
 * HISTORY
 *		01-Aug-89	Creation.
 *
 * BUGS
 *
 * SEE ALSO
 *
 */

struct RxilInvocation *RxilGetReturn( void )
{
	struct RxilInvocation *rxi;


	/* Make call "safe" even if RxilInit() failed */
	if( global_rdef == NULL )
	{
		return( NULL );
	}


	for( rxi=global_rdef->Invocations; rxi; rxi=rxi->Next )
	{
		if( rxi->State == RXIL_STATE_RETURNED )
		{
			return( rxi );
		}
	}

	return( NULL );
}



/* NAME
 *		RxilCleanupReturn
 *
 * SYNOPSIS
 *		RxilCleanupReturn( rxi );
 *
 *		struct RxilInvovcation *rxi;
 *
 * FUNCTION
 * 		This will take a pointer to a RxilInvocation structure and
 *		free what needs to be freed.
 *		The RexxMsg pointer is then NULL'ed and the structure's state
 *		set to AVAILABLE.
 *
 *		This should be called by the main program to cleanup after
 *		a function or command has returned and after the main program
 *		has done whatever it wanted to with the result.
 *		This will close the extension filehandles for Stdin and Stdout.
 *
 * INPUTS
 *		rxi = pointer to the RxilInvocation structure to be cleaned up.
 *
 * RESULT
 *		None
 *
 * SIDES
 *
 * HISTORY
 *		01-Aug-89	Creation.
 *
 * BUGS
 *
 * SEE ALSO
 *		RxilCreateRxi(), RxilDeleteRxi(), RxilGetReturn()
 */

void RxilCleanupReturn( struct RxilInvocation *rxi )
{
	struct RexxMsg *rexxmsg = rxi->RexxMsg;
	int i;


	RxilCloseConsole( rexxmsg );

	if(  ( rexxmsg->rm_Result1 == 0 ) && ( rexxmsg->rm_Result2 != 0 )  )
	{
	 	/* Free up the result string */
		DeleteArgstring( (struct RexxArg *)rexxmsg->rm_Result2 );
	}


	/* We always delete the name string argument */
	DeleteArgstring( (struct RexxArg *)(ARG0(rexxmsg)) );

	/* If a function invocation, free up any and all arguments */
	if(  ( rexxmsg->rm_Action & RXCODEMASK ) == RXFUNC  )
	{
		for( i=1; i<=(rexxmsg->rm_Action & RXARGMASK); i++ )
		{
			if( rexxmsg->rm_Args[i] != NULL )
			{
				DeleteArgstring( (struct RexxArg *)
					(rexxmsg->rm_Args[i]) );
			}
		}
	}

	DeleteRexxMsg( rexxmsg );
	rxi->RexxMsg = NULL;

	rxi->State = RXIL_STATE_AVAILABLE;
}



/* NAME
 *		RxilPending
 *
 * SYNOPSIS
 *		flag = RxilPending();
 *
 * FUNCTION
 *		If any ARexx functions or commands have been launched via
 *		a call to RxilLaunch(), and have not yet terminated, this will
 *		return TRUE.
 *
 * INPUTS
 *		None
 *
 * RESULT
 *		A boolean flag which indicates if any launches are in progress.
 *
 * SIDES
 *
 * HISTORY
 *		01-Aug-89	Creation.
 *
 * BUGS
 *
 * SEE ALSO
 *		RxilLaunch(), RxilCmdPending(), RxilFuncPending()
 */

BOOL RxilPending( void )
{
	struct RxilInvocation *rxi;


	/* Make call "safe" even if RxilInit() failed */
	if( global_rdef == NULL )
	{
		return( FALSE );
	}


	for( rxi=global_rdef->Invocations; rxi; rxi=rxi->Next )
	{
		if( rxi->State == RXIL_STATE_PENDING )
		{
			return( TRUE );
		}
	}

	return( FALSE );
}



/* NAME
 *		RxilCmdPending
 *
 * SYNOPSIS
 *		flag = RxilCmdPending();
 *
 * FUNCTION
 *		If any ARexx commands have been launched via
 *		a call to RxilLaunch(), and have not yet terminated, this will
 *		return TRUE.
 *
 * INPUTS
 *		None
 *
 * RESULT
 *		A boolean flag which indicates if any launches are in progress.
 *
 * SIDES
 *
 * HISTORY
 *		01-Aug-89	Creation.
 *
 * BUGS
 *
 * SEE ALSO
 *		RxilLaunch(), RxilPending(), RxilFuncPending()
 */

BOOL RxilCmdPending( void )
{
	struct RxilInvocation *rxi;


	/* Make call "safe" even if RxilInit() failed */
	if( global_rdef == NULL )
	{
		return( FALSE );
	}


	for( rxi=global_rdef->Invocations; rxi; rxi=rxi->Next )
	{
		if(  ( rxi->State == RXIL_STATE_PENDING ) &&
			( rxi->Type == RXCOMM  )  )
		{
			return( TRUE );
		}
	}

	return( FALSE );
}



/* NAME
 *		RxilFuncPending
 *
 * SYNOPSIS
 *		flag = RxilFuncPending();
 *
 * FUNCTION
 *		If any ARexx functions have been launched via
 *		a call to RxilLaunch(), and have not yet terminated, this will
 *		return TRUE.
 *
 * INPUTS
 *		None
 *
 * RESULT
 *		A boolean flag which indicates if any launches are in progress.
 *
 * SIDES
 *
 * HISTORY
 *		01-Aug-89	Creation.
 *
 * BUGS
 *
 * SEE ALSO
 *		RxilLaunch(), RxilPending(), RxilCmdPending()
 */

BOOL RxilFuncPending( void )
{
	struct RxilInvocation *rxi;


	/* Make call "safe" even if RxilInit() failed */
	if( global_rdef == NULL )
	{
		return( FALSE );
	}


	for( rxi=global_rdef->Invocations; rxi; rxi=rxi->Next )
	{
		if(  ( rxi->State == RXIL_STATE_PENDING ) &&
			( rxi->Type == RXFUNC  )  )
		{
			return( TRUE );
		}
	}

	return( FALSE );
}

