
/*
 *  TEST.C
 *
 *  Test Library Functions.
 */

#include <typedefs.h>
#include <stdio.h>

typedef struct Library LIB;

LIST ListA;
LIST ListB;
NODE Node1;
NODE Node2;
NODE Node3;
short Glob;

extern int Enable_Abort;

LIB *DMiscSupportBase;

extern LIB *OpenLibrary();
extern char *AllocMem();
extern char *GetHead();
extern char *GetTail();
extern char *GetSucc();
extern char *GetPred();
extern char *GetHeadOff();
extern char *GetTailOff();
extern char *GetSuccOff();
extern char *GetPredOff();
extern long srch();

main()
{
    Enable_Abort = 0;
    DMiscSupportBase = OpenLibrary("dmiscsup.library", 0);
    if (!DMiscSupportBase) {
	puts("Unable to open library");
	exit(1);
    }
    printf("library at: %08lx\n", DMiscSupportBase);
    printf("library flags: %02lx  Rev: %ld  OpenCnt: %ld\n",
	DMiscSupportBase->lib_Flags,
	DMiscSupportBase->lib_Revision,
	DMiscSupportBase->lib_OpenCnt
    );
    NewList(&ListA);
    NewList(&ListB);
    AddTail(&ListA, &Node1);
    AddTail(&ListA, &Node2);
    AddTail(&ListA, &Node3);
    printf("\nGetHead()         "); fflush(stdout);
    results((NODE *)GetHead(&ListA) == &Node1);
    results(GetHead(&ListB) == NULL);
    printf("\nGetTail()         "); fflush(stdout);
    results((NODE *)GetTail(&ListA) == &Node3);
    results(GetTail(&ListB) == NULL);
    printf("\nGetSucc()         "); fflush(stdout);
    results((NODE *)GetSucc(&Node1) == &Node2);
    results((NODE *)GetSucc(&Node3) == NULL);
    printf("\nGetPred()         "); fflush(stdout);
    results((NODE *)GetPred(&Node3) == &Node2);
    results((NODE *)GetPred(&Node1) == NULL);
    printf("\nGetHeadOff()      "); fflush(stdout);
    results(GetHeadOff(&ListA, 3) == (char *)&Node1 - 3);
    results(GetHeadOff(&ListB, 3) == NULL);
    printf("\nGetTailOff()      "); fflush(stdout);
    results(GetTailOff(&ListA, 3) == (char *)&Node3 - 3);
    results(GetTailOff(&ListB, 3) == NULL);
    printf("\nGetSuccOff()      "); fflush(stdout);
    results(GetSuccOff((char *)&Node1 - 3, 3) == (char *)&Node2 - 3);
    results(GetSuccOff((char *)&Node3 - 3, 3) == NULL);
    printf("\nGetPredOff()      "); fflush(stdout);
    results(GetPredOff((char *)&Node2 - 3, 3) == (char *)&Node1 - 3);
    results(GetPredOff((char *)&Node1 - 3, 3) == NULL);
    printf("\nSearchFwdNode()   "); fflush(stdout);
    Glob = 0; SearchFwdNodeOff(NULL, srch, 3, 27); results(Glob == 0);
    Glob = 0; SearchFwdNodeOff(GetHeadOff(&ListA, 3), srch, 3, 27); results(Glob == 3);
    printf("\nSearchRvsNode()   "); fflush(stdout);
    Glob = 0; SearchRvsNodeOff(NULL, srch, 3, 27); results(Glob == 0);
    Glob = 0; SearchRvsNodeOff(GetTailOff(&ListA, 3), srch, 3, 27); results(Glob == 3);
    puts("");
    wildtest();
    memory_test();
    RemLibrary(DMiscSupportBase);
    CloseLibrary(DMiscSupportBase);
}

results(bool)
{
    if (bool)
	printf("   ok");
    else
	printf(" fail");
    fflush(stdout);
}

srch(sptr, arg)
{
    ++Glob;
    printf(".");
    fflush(stdout);
    if (arg != 27)      /*  failure */
	return(1);
    return(NULL);
}

/*
 *  TEST:   WildCmp()
 */

wildtest()
{
    printf("WildCmp()         "); fflush(stdout);
    results(WildCmp("a??b", "axeb") == 1);
    results(WildCmp("a??b", "axebx")== 0);
    results(WildCmp("*/x*y*b", "a/x/u/xcharliey/b") == 1);
    results(WildCmp("*/x*y*b", "a/x/u/xcharlieq/b") == 0);
    puts("");
}

/*
 *  TEST:   BZero(), BSet(), BMov(), and BCmp();
 */

memory_test()
{
    long Size = 80000;	    /*	MUST BE 80000	*/
    short result;
    short i;
    char *ary1 = AllocMem(Size, MEMF_PUBLIC);
    char *ary2 = AllocMem(Size, MEMF_PUBLIC);

    printf("\nTEST MEMORY SUBROUTINES:\n");
    if (!ary1 || !ary2) {
	puts("    UNABLE TO ALLOCATE TWO CONTIGUOUS 80K SEGMENTS");
	puts("    THUS, CANNOT PERFORM MEMORY ROUTINES TEST.");
	goto fail;
    }

    /*
     *	Test BZero/BSet (both are the same subroutine, essentially).
     *	Test:	>64K, odd start, odd length.
     */

    printf(" BZero():   "); fflush(stdout);

    xbset(ary1, Size, 43);
    xbset(ary2, Size, 43);
    printf("."); fflush(stdout);
    BZero(ary1 + 1000, 20);
    BZero(ary1 + 1200, 70000);
    BZero(ary2 + 512 + 3, 70000);
    printf("."); fflush(stdout);
    results(xbcheck(ary1, 1000, 43));
    results(xbcheck(ary1 + 1000, 20, 0));
    results(xbcheck(ary1 + 1020, 1200 - 1020, 43));
    results(xbcheck(ary1 + 1200, 70000, 0));
    results(xbcheck(ary1 + 1200 + 70000, Size - 1200 - 70000, 43));

    printf("\n BSet():   "); fflush(stdout);
    xbset(ary1, Size, 43);
    xbset(ary2, Size, 43);
    printf("."); fflush(stdout);
    BSet(ary1 + 999, 21, 5);
    BSet(ary1 + 1201, 70001, 6);
    BSet(ary2 + 512 + 1, 69999, 7);
    printf("."); fflush(stdout);
    results(xbcheck(ary1, 999, 43));
    results(xbcheck(ary1 + 999, 21, 5));
    results(xbcheck(ary1 + 999 + 21, 1201 - 999 - 21, 43));
    results(xbcheck(ary1 + 1201, 70001, 6));
    results(xbcheck(ary1 + 1201 + 70001, Size - 1201 - 70001, 43));
    results(xbcheck(ary2, 512 + 1, 43));
    results(xbcheck(ary2 + 512 + 1, 69999, 7));
    results(xbcheck(ary2 + 512 + 1 + 69999, Size - 69999 - 512 - 1, 43));

    /*
     *	TEST BMov().  Odd start, overlapping blocks in forward and
     *	reverse.
     */

    printf("\n BMov(): 1"); fflush(stdout);
    xbset(ary1, Size, 43);
    xbset(ary2, Size, 43);
    xbiset(ary1 + 1001, 69999, 1);
    xbiset(ary2 + 1003, 70001, 1);
    BMov(ary1 + 1001, ary1 + 997, 69999);
    BMov(ary2 + 1003, ary2 + 1008, 70001);
    results(xbicheck(ary1 + 997, 69999, 1));
    results(xbicheck(ary2 + 1008, 70001, 1));
    results(xbcheck(ary1, 997, 43));
    results(xbcheck(ary1 + 1001 + 69999, Size - 1001 - 69999, 43));
    results(xbcheck(ary2, 1003, 43));
    results(xbcheck(ary2 + 1008 + 70001, Size - 1008 - 70001, 43));
    printf("\n BMov(): 2"); fflush(stdout);
    xbset(ary1, Size, 43);
    xbset(ary2, Size, 43);
    xbiset(ary1 + 1024, 70000, 1);
    xbiset(ary2 + 1024, 70000, 1);
    BMov(ary1 + 1024, ary1 + 1004, 70000);
    BMov(ary2 + 1024, ary2 + 1044, 70000);
    results(xbicheck(ary1 + 1004, 70000, 1));
    results(xbicheck(ary2 + 1044, 70000, 1));
    results(xbcheck(ary1, 1004, 43));
    results(xbcheck(ary1 + 1024 + 70000, Size - 70000 - 1024, 43));
    results(xbcheck(ary2, 1024, 43));
    results(xbcheck(ary1 + 1044 + 70000, Size - 70000 - 1044, 43));
    puts("");
    printf(" SPEEDTEST (K/sec BMov lw bndry, fastmem): %ld K/sec\n", speedtest(MEMF_FAST, 0, 0));
    printf(" SPEEDTEST (K/sec BSet lw bndry, fastmem): %ld K/sec\n", speedtest(MEMF_FAST, 1, 0));
    printf(" SPEEDTEST (K/sec BMov lw bndry, chipmem): %ld K/sec\n", speedtest(MEMF_CHIP, 0, 0));
    printf(" SPEEDTEST (K/sec BSet lw bndry, chipmem): %ld K/sec\n", speedtest(MEMF_CHIP, 1, 0));
    puts("");
    printf(" SPEEDTEST (K/sec BMov by bndry, fastmem): %ld K/sec\n", speedtest(MEMF_FAST, 0, 1));
    printf(" SPEEDTEST (K/sec BMov by bndry, chipmem): %ld K/sec\n", speedtest(MEMF_CHIP, 0, 1));
fail:
    if (ary1)
	FreeMem(ary1, Size);
    if (ary2)
	FreeMem(ary2, Size);
}

speedtest(memtype, zero, off)
{
    char *buf = AllocMem(65536+256, memtype);
    short i;
    long s;

    if (!buf)
	return(0);
    s = ltm();
    for (i = 0; i < 128; ++i) {
	if (zero)
	    BSet(buf + off, 65536, 1);
	else
	    BMov(buf + off, buf + 128 + off, 65536);
    }
    s = ltm() - s;          /*  1/50ths second for 64K * 128 */
    FreeMem(buf, 65536+256);
    return(64 * 128 * 50 / s);
}

ltm()
{
    long st[3];

    DateStamp(st);
    return(st[2] + 50 * 60 * st[1] + 50 * 60 * 60 * 24 * st[0]);
}

xbset(s, n, v)
register char *s;
register long n;
register char v;
{
    while (n--)
	*s++ = v;
}

xbiset(s, n, v)
register char *s;
register long n;
register char v;
{
    while (n--) {
	++v;
	*s++ = v;
    }
}


xbcheck(s, n, v)
register char *s;
register long n;
register char v;
{
    char *orig = s;
    short errs = 255;
    while (n--) {
	if (*s++ != v) {
	    if (errs) {
		--errs;
		printf("(%ld)", s - orig - 1);
	    } else {
		printf("giveup");
		return(0);
	    }
	}
    }
    return(errs == 255);
}

xbicheck(s, n, v)
register char *s;
register long n;
register char v;
{
    char *orig = s;
    short errs = 255;
    while (n--) {
	++v;
	if (*s++ != v) {
	    if (errs) {
		--errs;
		printf("(%ld)", s - orig);
	    } else {
		printf("giveup");
		return(0);
	    }
	}
    }
    return(errs == 255);
}


