/*
 * etmtest.c - check out Exception and Termination Manager.  Also
 * 	serves as modest example of ETM use.
 *
 * etmtest 1	normal init/shutdown
 * etmtest 2	test panic recursion detection
 * etmtest 3	test print routine recursion detection
 * etmtest 4	use alternate print procedure
 * etmtest 5	deregistration
 * etmtest 6	dump core
 */

# ifdef THINK_C
# include	<console.h>
# endif

# include	<stdio.h>

# include	"etm.h"


static ETMProcRetType	Shutdown1 ();
static ETMProcRetType	Shutdown2 ();
static ETMProcRetType	Shutdown5 ();
static ETMProcRetType	PrintProc3 ();
static ETMProcRetType	PrintProc4 ();


char	*usage = "\
Usage:\tetmtest 1\ttest normal initialization and shutdown\n\
\tetmtest 2\ttest panic loop detection\n\
\tetmtest 3\ttest print recursion detection\n\
\tetmtest 4\ttest alternate print procedure\n\
\tetmtest 5\ttest shutdown proc deregistration\n\
\tetmtest 6\ttest core dump generation\n\
";


int
main (argc, argv)
int	argc;
char	*argv[];
{

# ifdef	THINK_C
	argc = ccommand (&argv);
# else	/* !THINK_C */
	if (argc < 2)
		ETMPanic (usage);
# endif /* THINK_C */

	switch (atoi (argv[1]))
	{
	case 1:
		printf ("Initializing test 1 (normal initialization/shutdown)\n");
		ETMInit (Shutdown1);
		break;
	case 2:
		printf ("Initializing test 2 (panic loop detection)\n");
		printf ("(this should be followed by a panic loop message)\n");
		ETMInit (Shutdown2);
		break;
	case 3:
		printf ("Initializing test 3 (print recursion detection)\n");
		ETMInit ((ETMProcPtr) NULL);
		ETMSetPrintProc (PrintProc3);
		ETMMsg ("testing recursion loop detection...");
		break;
	case 4:
		printf ("Initializing test 4 (alternate print procedure)\n");
		ETMInit ((ETMProcPtr) NULL);
		ETMSetPrintProc (PrintProc4);
		ETMMsg ("message to alternate print procedure...");
		ETMPanic ("panic to alternate print procedure...");
		break;
	case 5:
		printf ("Initializing test 5 (shutdown proc deregistration)\n");
		ETMInit ((ETMProcPtr) NULL);
		ETMAddShutdownProc (Shutdown5);
		ETMRemoveShutdownProc (Shutdown5);
		break;
	case 6:
		printf ("Initializing test 6 (core dump generation)\n");
		ETMInit ((ETMProcPtr) NULL);
		ETMSetAbort (1);
		ETMPanic ("This should be followed by a core dump.");
	default:
		ETMPanic (usage);
	}

	ETMEnd ();
	printf ("Exiting...\n");
	exit (0);
}


static ETMProcRetType Shutdown1 ()
{
	printf ("Shutting down...\n");
}


static ETMProcRetType Shutdown2 ()
{
	/* shutdown routines shouldn't call ETMPanic(), so... */
	ETMPanic ("This should cause a panic loop");
}


static ETMProcRetType Shutdown5 ()
{
	printf ("Shutdown5: You should not see this message.\n");
	printf ("(if you do, ETM has a bug)\n");
}


/*
	This should result in ETM aborting, since this is the print
	procedure called by ETM, and itself (erroneously) calls ETM.
*/

static ETMProcRetType PrintProc3 (s)
char	*s;
{
	ETMMsg ("%s", s);
}


/*
	Alternate print procedure which routes output to multiple 
	destintations.
*/

static ETMProcRetType PrintProc4 (s)
char	*s;
{
	printf ("stdout: %s", s);
	fprintf (stderr, "stderr: %s", s);
}
