/***********************************************************
* odintest.c                                               *
* Created 12-jul-90 by Peter Oerbaek                       *
* This is supposed to be a complete test-suite of the      *
* functions in odin.library                                *
* Modified 13-jul-90 for ANSI compatibility                *
* Compiles and runs under both Aztec C 3.40a and PDC 3.33  *
************************************************************/

#include	"exec/types.h"
#include	"exec/tasks.h"
#include	"exec/semaphores.h"
#include	"exec/execbase.h"
#include	"odin.h"
#include	"stdio.h"

void *OpenLibrary();
struct Task *FindTask();

struct OdinBase *OdinBase;
struct SignalSemaphore ss;
#define CR(s) ObtainSemaphore(&ss); { s } ReleaseSemaphore(&ss);
#define debug(str) CR(printf(str);)

Envelope e1,e2;

Envelope *my_copyfunc(src,tar)
Envelope *src,*tar;
{
	int i;
	register char *a,*b;

	a = (char *)src; b = (char *)tar;
	for(i = 0; i < e_sizeof; i++) {
		*a++ = *b++;
	}

	return tar;
}

Envelope *process1(e)
Envelope *e;
{
	struct Task *tsk;
	Envelope *env;

	debug("process1 started\n");
	CR(printf("lenght = %ld\n",e->e_len);)

	tsk = FindTask(NULL);
	
	CR(printf("stacksize = %d\n",(int)(tsk->tc_SPUpper - tsk->tc_SPLower));)
	CR(printf("pri = %d\n",(int)tsk->tc_Node.ln_Pri);)
	CR(printf("taskname=%s\n",tsk->tc_Node.ln_Name);)

	debug("creating envelope\n");
	env = CreateEnvelope("Env2",e_sizeof);
	if(env == NULL) { debug("create returned NULL\n"); return e; }

	debug("envelope created\n");

	Delay(100L);
	debug("copyouting\n");
	CopyOut(env);

	Delay(199L);
	debug("copy outing with copyfunc\n");
	env->e_copyfunc = my_copyfunc;
	CopyOut(env);

	debug("normal out\n");
	Out(env);

	debug("wait for V3\n");
	while(!(env = PollNamedEnvelope("V3"))) { 
		debug("waiting with poll.\n");
	}

	debug("got V3 dispose\n");
	DisposeEnvelope(env);

	debug("wait for V4 and dispose\n");
	DisposeEnvelope(AwaitNamedEnvelope("V4"));

	debug("wait for task1\n");
	DisposeEnvelope(AwaitNamedEnvelope("V5"));
	debug("shake hands\n");
	OutEmptyEnvelope("R1");

	Delay(100L);
	return e;
}

void task1()
{
	OutEmptyEnvelope("V5");	/* shake hands with process */
	DisposeEnvelope(AwaitNamedEnvelope("R1"));
}

main()
{
	Envelope *ptr;
	struct Task *tsk;

	if(!(OdinBase = (struct OdinBase *)OpenLibrary("RAM:odin.library",0L)))
	{
		printf("couldn't find odin.library.\n");
		exit(20);
	}

	InitSemaphore(&ss);

	debug("begin\n");

	debug("test InitEnvelope():\n");
	ptr = InitEnvelope(&e1,"Test",e_sizeof,NoCopyFunc);
	debug("init envelope finished\n");
	if(ptr == &e1) {
		debug("returnvalue ok.\n");
		if(strcmp(ptr->e_name,"Test") == 0) {
			debug("name inited ok\n");
		} else {
			debug("name wrong\n");
		}
		if(ptr->e_len == e_sizeof && ptr->e_copyfunc == NULL) {
			debug("inited ok\n");
		} else {
			debug("wrong init\n");
		}
	} else {
		debug("returned wrong value.\n");
	}


	debug("test Eval():\n");
	e1.e_proc = process1;
	(void)Eval(&e1,(long)0,(ULONG)4000,EVAL_PROCESS);
	debug("eval finished\n");

	debug("test rdp\n");
	(void)InitEnvelope(&e2,"Env2",e_sizeof,NoCopyFunc);
	while(!(ptr = Rdp(&e2))) { debug("waiting in rdp\n"); }
	if(ptr == &e2) {
		debug("rdp returned ok\n");
	} else {
		debug("rdp returned wrong\n");
	}
	CR(printf("name returned by rdp: %s\n",e2.e_name);)

	debug("test rd\n");
	(void)InitEnvelope(&e2,"Env2",e_sizeof,NoCopyFunc);
	ptr = Rd(&e2);
	if(ptr == &e2) {
		debug("rd returned ok\n");
	} else {
		debug("rd returned wrong\n");
	}
	CR(printf("name returned by rd: %s\n",ptr->e_name);)

	debug("test In()\n");
	(void)InitEnvelope(&e2,"Env2",e_sizeof,NoCopyFunc);
	ptr = In(&e2);
	if(ptr != &e2) {
		debug("in returned ok\n");
	} else {
		debug("in returned wrong\n");
	}
	CR(printf("name returned by in: %s\n",ptr->e_name);)
	DisposeEnvelope(ptr);

	debug("test AwaitNamedEnvelope()\n");
	ptr = AwaitNamedEnvelope("Env2");
	CR(printf("name returned by Await..: %s\n",ptr->e_name);)
	DisposeEnvelope(ptr);

	debug("test rdp with copyfunc\n");
	(void)InitEnvelope(&e2,"Env2",e_sizeof,NoCopyFunc);
	while(!(ptr = Rdp(&e2))) { debug("waiting in rdp2\n"); }
	if(ptr == &e2) {
		debug("rdp2 returned ok\n");
	} else {
		debug("rdp2 returned wrong\n");
	}
	CR(printf("name returned by rdp2: %s\n",e2.e_name);)

	debug("rd with copyfunc\n");
	(void)InitEnvelope(&e2,"Env2",e_sizeof,NoCopyFunc);
	ptr = Rd(&e2);
	if(ptr == &e2) {
		debug("rd2 returned ok\n");
	} else {
		debug("rd2 returned wrong\n");
	}
	CR(printf("name returned by rd2: %s\n",e2.e_name);)

	DisposeEnvelope(AwaitNamedEnvelope("Env2"));

	Delay(100L);
	Out(CreateEnvelope("V3",e_sizeof));

	OutEmptyEnvelope("V4");

	tsk = StartTask(task1,"TAsk1",0L,4000L);
	if(tsk == NULL) { debug("couldn't start task\n"); }
	debug("task started\n");

	debug("wait for process to die\n");
	(void)AwaitNamedEnvelope("Test");	

	CloseLibrary(OdinBase);
}

