/***************************************************************
 * Copyright 1984, 1985, 1986   -   All Rights Reserved        *
 *                                                             *
 * Lattice, Inc.                                               *
 * Glen Ellyn, Illinois                                        *
 * U. S. A.                                                    *
 *                                                             *
 * Author: Billy Shakespeare & Company                         *
 ***************************************************************/
#include <stdio.h>
#include "dbc.h"

/**
*
* name
*	studydbc - program to study the dBC III functions
*
* description
*	This is a program to study the dBC III functions.
*
**/

/**** GLOBAL DATA ******/
char dbfname[50], ndxname[50], dbtname[50];
char *dbfid, *ndxid, *dbtid;
#define LENGTH 4100
char recbuf[LENGTH]; /* record buffer */

/* extern function statements */
extern void bintoasc(), adrsasc(), readme(); /* written in this file */


void main(argc, argv)
	int argc;
	char *argv[];
{
int choice;
int rc;
char ans[16];
extern char _dbcver[];
extern int _dbcerr;
extern long inputnum();
extern void readin();


/* study function declarations */
extern int tBcreat(), tBclose(), tBgetr(), tBgetf(), tBputr();
extern int tBupdr(), tBdelete(), tBrecall(), tBsize(), tBrmvr(), tBflush();
extern int tBicreat(), tBiclose(), tBakey(), tBrmvkey(), tBtkey(), tBckey();
extern int tBnkey(), tBpkey(), tBrewind(), tBfwd(), tBgetrk(), tBgetnr();
extern int tBgetpr(), tBputrk(), tBkexpr(), tBiflsh();
extern int tBopen(), tBiopen();
extern int tBmcreat(), tBmopen(), tBmclose(), tBgetm(), tBputm();
extern int tBatofld(), tBfldtoa(), tBatokey(), tBkeytoa(), tBstrcpy();

static int (*testtbl[40]) () =
{
	0, tBcreat,  tBopen,   tBclose,  tBgetr,   tBgetf,   tBputr,
	   tBupdr,   tBdelete, tBrecall, tBsize,   tBrmvr,   tBflush,
	   tBicreat, tBiopen,  tBiclose, tBakey,   tBrmvkey, tBtkey,
	   tBckey,   tBnkey,   tBpkey,   tBrewind, tBfwd,    tBgetrk,
	   tBgetnr,  tBgetpr,  tBputrk,  tBkexpr,  tBiflsh,  tBmcreat,
	   tBmopen,  tBmclose, tBgetm,   tBputm,   tBatofld, tBfldtoa,
	   tBatokey, tBkeytoa, tBstrcpy
};


if (argc > 4)
{
	printf("\nUsage: studydbc [data file name] [index file name]");
	printf(" [memo file name]");
	exit(1);
}

dbfid = ndxid = dbtid = (char *) 0; /* initially,
				       no .DBF, .NDX & .DBT files are open */

switch(argc)
{
case 1:
	strcpy(dbfname, "DEFAULT.DBF"); /* set default data file name */
	strcpy(ndxname, "DEFAULT.NDX"); /* set default index file name */
        strcpy(dbtname, "DEFAULT.DBT"); /* set default memo file name */
	break; /* goto menu */
case 2:
	/* check data file given in the argument */
	if (tstfname(argv[1])) exit(1);
	strcpy(dbfname, argv[1]); /* set user supplied data file name */
	strcpy(ndxname, "DEFAULT.NDX"); /* set default index file name */
        strcpy(dbtname, "DEFAULT.DBT"); /* set default memo file name */
	break;

case 3:
	if (tstfname(argv[1])) exit(1); /* test data file name */
	if (tstfname(argv[2])) exit(1); /* test index file name */
	strcpy(dbfname, argv[1]); /* set user supplied file name */
	strcpy(ndxname, argv[2]); /* set user supplied file name */
        strcpy(dbtname, "DEFAULT.DBT"); /* set default memo file name */
	break;

case 4:
	if (tstfname(argv[1])) exit(1); /* test data file name */
	if (tstfname(argv[2])) exit(1); /* test index file name */
	if (tstfname(argv[3])) exit(1); /* test memo file name */
	strcpy(dbfname, argv[1]); /* set user supplied data file name */
	strcpy(ndxname, argv[2]); /* set user supplied index file name */
        strcpy(dbtname, argv[3]); /* set user supplied memo file name */
	break;
}

readme();

while(1)
{ /* dummy loop */

printf("\n\n       dBC III Functions Study Menu     V%s", _dbcver);
printf("\n           Copyright  1984, 1985, 1986   Lattice Inc.");

printf("\n  DATA FILE SELECTED : %s",   dbfname);
printf("\n INDEX FILE SELECTED : %s",   ndxname);
printf("\n  MEMO FILE SELECTED : %s\n", dbtname);

printf("\n 1. dBcreat   15. dBiclose   29. dBiflsh");
printf("\n 2. dBopen    16. dBakey     30. dBmcreat");
printf("\n 3. dBclose   17. dBrmvkey   31. dBmopen");
printf("\n 4. dBgetr    18. dBtkey     32. dBmclose");
printf("\n 5. dBgetf    19. dBckey     33. dBgetm");
printf("\n 6. dBputr    20. dBnkey     34. dBputm");
printf("\n 7. dBupdr    21. dBpkey     35. dBatofld");
printf("\n 8. dBdelete  22. dBrewind   36. dBfldtoa");
printf("\n 9. dBrecall  23. dBfwd      37. dBatokey");
printf("\n10. dBsize    24. dBgetrk    38. dBkeytoa");
printf("\n11. dBrmvr    25. dBgetnr    39. dBstrcpy");
printf("\n12. dBflush   26. dBgetpr    90. Reselect Data File");
printf("\n13. dBicreat  27. dBputrk    91. Reselect Index File");
printf("\n14. dBiopen   28. dBkexpr    92. Reselect Memo File");
printf("\n                             99. END");
printf("\n*   Enter your choice (one of above numbers) > ");

choice = (int) inputnum();
while (2)
{
	if (choice == 90)
	{
		getdbf();
		break;
	}
	else if (choice == 91)
	{
		getndx();
		break;
        }
        else if (choice == 92)
	{
                getdbt();
                break;
	}
	if (choice == 99)
	{
		if (!excheck())	exit(0); /* go back to operating system */
		break;
	}
	else if (choice < 1 || 39 < choice) break;
	else
	{
		printf("\n");
		rc = (*testtbl[choice]) ();
		if (rc != SUCCESS)
			printf("\n_dbcerr = %d", _dbcerr);
		prrc(rc);
	}

	switch(choice)
	{
	case 2:		/* dBopen */
	case 3:		/* dBclose */
	case 14:	/* dBiopen */
	case 15:	/* dBiclose */
	case 31:        /* dBmopen */
        case 32:        /* dBmclose */
		break;
	default:
	 	printf("\n\nTry Again? [your choice was: %d] (y/n) ", choice);
		readin(ans);
		if (*ans == 'y' || *ans == 'Y') continue;
	}
	printf("\nDo you want to see the menu? (y/n) ");
	readin(ans);
	if (*ans == 'y' || *ans == 'Y') break;
	printf("\n\n* Enter your choice > ");
	choice = (int) inputnum();
} /* end of while(2)-loop */

} /* end of dummy loop */
} /* end of main() */

void readme()
{
int i, j;


printf("\n\nUsage:  studydbc [data file name] [index file name]");
printf(" [memo file name]\n\n");
printf("\nThis program helps you learn the dBC functions.");
printf("\n\nBring your dBC III manual and get ready.\n\n\n\n\n");
for (j=3; j--;) for (i=(U2BYTES) 0xffff; i--;); /* show message for a while */
printf("\n\n\n\n\n\n");
} /* end of readme() */


int excheck()
{
int rc;

rc = 0;
if (dbfid != (char *) 0)
{
	printf("\007\nData File Still Open!  Close it before exit.\007");
	rc = 1;
}
if (ndxid != (char *) 0)
{
	printf("\007\nIndex File Still Open!  Close it before exit.\007");
	rc = 1;
}
if (dbtid != (char *) 0)
{
	printf("\007\nMemo File Still Open!  Close it before exit.\007");
	rc = 1;
}
return(rc);
} /* end of excheck() */


int getdbf()
{
	char filename[80];

	printf("\n* Enter Data File Name > ");
	readin(filename);
	if (tstfname(filename)) return(-1);
	strcpy(dbfname, filename);
	return(0);
} /* end of getdbf() */

int getndx()
{
	char filename[80];

	printf("\n* Enter Index File Name > ");
	readin(filename);
	if (tstfname(filename)) return(-1);
	strcpy(ndxname, filename);
	return(0);
} /* end of getndx() */

int getdbt()
{
	char filename[80];

	printf("\n* Enter Memo File Name > ");
	readin(filename);
	if (tstfname(filename)) return(-1);
	strcpy(dbtname, filename);
	return(0);
} /* end of getdbt() */


int tstfname(filename)
	char *filename;
{
	if (strlen(filename) >= 30)
{
		printf("\n\007Too long file name: %s", filename);
		return(-1);
	}
	return(0);
} /* end of tstfname() */

/********* print return code function *********/
int prrc(rc)
	int rc;
{
printf("\nreturn code : ");
switch(rc)
{
case SUCCESS:
	printf("SUCCESS");
	break;
case d_ERROR:
	printf("d_ERROR");
	break;
case d_NODBF:
	printf("d_NODBF");
	break;
case d_BADREC:
	printf("d_BADREC");
	break;
case d_WTFAIL:
	printf("d_WTFAIL");
	break;
case d_NONDX:
	printf("d_NONDX");
	break;
case d_KYLONG:
	printf("d_KYLONG");
	break;
case d_NOKEY:
	printf("d_NOKEY");
	break;
case d_MAYBE:
	printf("d_MAYBE");
	break;
case d_ENDKEY:
	printf("d_ENDKEY");
	break;
case d_NOSYNC:
	printf("d_NOSYNC");
	break;
case d_TOPKEY:
	printf("d_TOPKEY");
	break;
default:
	printf("STUDYDBC DETECTED NON-dBC ERROR!");
	break;
}

return(rc);
} /* end of prrc() */


/******* gendump (general dump) *******/
void gendump(buffer, buflen)
	/* input parameters */
	char *buffer;
	int  buflen; /* buffer lenth */

	/* output parameter */
	/* none */
{
char linebuf[80];
BYTE byte;
BYTE *hexptr, *ascptr;
U2BYTES adrs;
int flag;
int i;
int linelen;
BYTE printable[0x80];

for (i=0x00; i<=0x1f; i++) printable[i] = 0;
for (i=0x20; i<=0x7e; i++) printable[i] = 1;
printable[(BYTE) 0x7f] = 0;

printf("\n       0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F");
printf("        0123456789ABCDEF\n");

flag = 1;
adrs = 0x0000;
for (;;)
{
	linelen = (buflen > 16) ? 16 : buflen;
	if (linelen == 0) break; /* end of file */

	for (ascptr=linebuf; ascptr <= (linebuf+77);) *ascptr++ = ' ';
	*ascptr = 0;
	adrsasc(linebuf, adrs);
	adrsasc(linebuf+55, adrs);
	*(linebuf + 4) = ':';
	*(linebuf + 59) = ':';

	hexptr = linebuf + 6;
	ascptr = linebuf + 61;

	for (i=1; i <= linelen; i++)
	{
		byte = *buffer++;
 		bintoasc(hexptr, (byte >> 4) & 0x0f);
		bintoasc(hexptr+1, (byte & 0x0f));
		byte &= 0x7f;
		*ascptr = printable[byte] ? byte : '.';

		hexptr += 3;
		ascptr++;
	}
	printf("%s\n", linebuf);

	buflen -= linelen;
	adrs += 0x0010;
} 

} /* end of gendump() */

void adrsasc(cptr, adrs)
	char *cptr;    /* destination */
	U2BYTES adrs; /* source */
{
	bintoasc(cptr++, (char) ((adrs >> 12) & 0x000f));
	bintoasc(cptr++, (char) ((adrs >> 8)  & 0x000f));
	bintoasc(cptr++, (char) ((adrs >> 4)  & 0x000f));
	bintoasc(cptr,   (char) ( adrs        & 0x000f));
} /* end of adrsasc() */

void bintoasc(cptr, digit)
	char *cptr; /* destination */
	char digit; /* source */
{
	*cptr = (digit <= 0x9) ? (digit + '0') : (digit + 0x37);
} /* end of bintoasc() */

long inputnum()
{
char numstr[40];
int i;
long num;

num = 0L;
while(1)
{
	readin(numstr);
	for (i=0; i<40 && '0'<=numstr[i] && numstr[i]<='9'; i++)
		num = num * 10 + (numstr[i] - '0');
	if (i > 0) break;
	printf("\n* Enter number in decimal digits > ");
}
return(num);
} /* end of inputnum() */

/**
 * Readin() reads the user input into the supplied buffer
 * until a newline character or carriage return is entered.
 * The newline character is replaced by a NULL(\000) character.
 * */
#define NEWLINE 0xa
#define CR      0xd
void readin(buffer)
	BYTE *buffer;
{
int c;

c = getchar();
while ( (c != EOF) && ((c & (BYTE) 0xff) != NEWLINE)
	&& ((c & (BYTE) 0xff) != CR) )
{
	*buffer++ = (char) c;
	c = getchar();
}
*buffer	= (char) 0;

} /* end of readin() */
