/* diag.c */

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



#include "rxil.h"

#include <string.h>
#include <stdio.h>



static void dump_env( struct RxilDef *rdef );
static void dump_state( struct RxilDef *rdef );
static void dump_cmds( struct RxilDef *rdef );
static void dump_rxi( struct RxilInvocation *rxi );

static void leftword( char *buffer, char *source );
static int strpos( char *s, unsigned int c );



/* NAME
 *		RxilDumpRdef
 *
 * SYNOPSIS
 *		RxilDumpRdef( rdef, flags );
 *
 *		struct RxilDef *rdef;
 *		ULONG flags;
 *
 * FUNCTION
 *		This function is for debug and testing purposes.  It will
 *		dump information about the current ARexx environment to the
 *		CLI.
 *
 * INPUTS
 *		rdef = pointer to the global RxilDef structure.
 *		flags = an unsigned long whose bits control just what information
 *			about the RxilDef structure is displayed.
 *
 * RESULT
 *		None
 *
 * SIDES
 *
 * HISTORY
 *		01-Aug-89	Creation.
 *		25-Sep-89	Added display of library version string.
 *		01-Oct-89	Added "flags" argument to control just what is
 *					displayed, and ability to display the commands.
 *		10-Nov-89	Changed format of command info display slightly.
 *
 * BUGS
 *
 * SEE ALSO
 *
 */

void RxilDumpRdef( struct RxilDef *rdef, ULONG flags )
{
	printf( "\n%s\n\n", rdef->Version );

	if(  FlagIsSet( flags, RXIL_DUMP_CMDS )  )
	{
		dump_cmds( rdef );
		printf( "\n" );
	}

	if(  FlagIsSet( flags, RXIL_DUMP_ENV )  )
	{
		dump_env( rdef );
		printf( "\n" );
	}

	if(  FlagIsSet( flags, RXIL_DUMP_STATE )  )
	{
		dump_state( rdef );
		printf( "\n" );
	}
}



static void dump_env( struct RxilDef *rdef )
{
	printf( "Public Port name: %s\n", rdef->PortName );
	printf( "Secret Port name: %s\n", rdef->SecretPortName );

	if( rdef->Console )
	{
		printf( "Console: %s\n", rdef->Console );
	}
	else
	{
		printf( "No console will be used\n" );
	}

	printf( "Macro extension: %s\n", rdef->Extension );
	printf( "Invocation messages sent to port: %s\n", rdef->HostPort );
}



static void dump_cmds( struct RxilDef *rdef )
{
	unsigned int i;
	char *cf, *pl;


	printf( "  Command Name      Arguments    Case     Privilege\n\n" );

	for( i=0; rdef->CommandTable[i].Name != NULL; i++ )
	{
		if( rdef->CommandTable[i].CaseFlag == TRUE )
		{
			cf = "Matters";
		}
		else
		{
			cf = "Ignored";
		}

		pl = (rdef->CommandTable[i].Privilege > RXIL_PUBLIC) ?
			"*Private*" : "Public   ";


		if( rdef->CommandTable[i].MinArgs ==
			rdef->CommandTable[i].MaxArgs )
		{
			/* Argument count is fixed */

			printf( "%-18s     %2d      %s    %s\n",
				rdef->CommandTable[i].Name,
				(int)rdef->CommandTable[i].MinArgs,
				cf, pl );
		}
		else
		{
			/* Argument count is variable */

			printf( "%-18s   %2d -%2d    %s    %s\n",
				rdef->CommandTable[i].Name,
				(int)rdef->CommandTable[i].MinArgs,
				(int)rdef->CommandTable[i].MaxArgs,
				cf, pl );
		}
	}
}



static void dump_state( struct RxilDef *rdef )
{
	struct RxilInvocation *rxi;


	printf( "Lock count: %d\n", rdef->LockCount );

	if( rdef->Invocations )
	{
		rxi = rdef->Invocations;
		while( rxi )
		{
			dump_rxi( rxi );
			rxi = rxi->Next;
		}
	}
	else
	{
		printf( "No invocation structures allocated\n" );
	}
}



static void dump_rxi( struct RxilInvocation *rxi )
{
	char *s;
	char buf[128] = "(no name)";


	if( rxi->Name )
	{
		leftword( buf, rxi->Name );
	}

	printf( "\nInvocation: %s\n", buf );


	switch( rxi->State )
	{
		case RXIL_STATE_AVAILABLE:
			s = "Available";
			break;

		case RXIL_STATE_PENDING:
			s = "Pending";
			break;

		case RXIL_STATE_RETURNED:
			s = "Returned";
			break;
	}

	printf( "\tState: %s\n", s );

	if( rxi->Parent )
	{
		printf( "This is a child of a Macro\n" );
	}

	if( rxi->Console )
	{
		printf( "The console is: %s\n", rxi->Console );
	}
}



/* This will take the leftmost word (delimited by a space) from the
 * string pointed to by source and move it to the buffer pointed
 * to by buffer.  If there is no space in the source string, the
 * entire thing will be copied.
*/

static void leftword( char *buffer, char *source )
{
	unsigned int p;

	if( p = strpos( source, ' ' ) )
	{
		/* There is a space, so all we want is the leftmost word */
		strncpy( buffer, source, p-1 );
		buffer[p-1] = '\0';
	}
	else   strcpy( buffer, source );
}



/* This routine returns the leftmost position in which it finds
 * the desired character.  A null is returned if the character
 * is not found in the string.  The first character in the string
 * is considered to be position 1.
*/

static int strpos( char *s, unsigned int c )
{
	char *x;

	x = strchr( s, c );
	if( x==0 )   return( 0 );
	else   return( (int)(x-s+1) );
}

