/***************************************************************
 * Copyright (C) 1984, 1985, 1986   -   All Rights Reserved    *
 *                                                             *
 * Lattice, Inc.                                               *
 * Glen Ellyn, Illinois                                        *
 * U. S. A.                                                    *
 *                                                             *
 * Author: Billy Shakespeare & Company                         *
 ***************************************************************/
/****************************
 *        STDYDBC2.C        *
 ************************************************************************
 * This file contains study-functions that call the dBC functions that  *
 * access an index file(.NDX).                                          *
 * It also includes study-functions for the field/key manipulation      *
 * functions.
 ************************************************************************/


#include <stdio.h>
#include "dbc.h"

/* extern statements for refering global data */
extern char dbfname[], ndxname[];
extern char *dbfid, *ndxid;
extern char recbuf[];
static char string1[200], string2[200];

/* extern function statements */
extern void readin(), gendump(); /* written in STUDYDBC.C */


/******* tBicreat *********/
int tBicreat()
{
BYTE keyexpr[256], ibuf[80];
KEYLEN keylen;
BYTE keytype;
int rc;
extern int dBicreat();
extern long inputnum();

printf("\nSYNOPSIS:   int dBicreat(ndxname, keyexpr, keylen, keytype)");
printf("\n\n            If 'keytype' parameter value is N(numeric) or D(date)");
printf("\n            type, 'keylen' value can be any integer value.");
printf("\n\nndxname == %s", ndxname);
if (!ndxname[0])
{
	printf("\nYou have not specify an index file name.");
	printf("\nSpecify the file name by entering selection 91");
	printf("\nbefore you create the file");
	return(-1);
}

printf("\nEnter key expression >>>");
readin(keyexpr);
printf("\nEnter key length > ");
keylen = (KEYLEN) inputnum();
printf("\nEnter key type: C {character}, N {numeric} or D {date} > ");
readin(ibuf);
keytype = ibuf[0];

rc = dBicreat(ndxname, keyexpr, (BYTE) keylen, keytype);

return(rc);

} /* end of tBicreat() */

/********* tBiopen ********/
int tBiopen()
{
int rc;
extern int dBiopen();

printf("\nSYNOPSIS:   int dBiopen(ndxname, ndxfd)");

if (ndxid != (char *) 0)
{
	printf("\n\007Index file already open!");
	printf("\nIf you want to open another index file, ");
	printf("close the current one first.");
	return(-1);
}
if (!ndxname[0])
{
	printf("\nYou have not specify an index file name.");
	printf("\nSpecify the file name by entering selection 91");
	printf("\nbefore you open the file.");
	return(-1);
}

printf("\nOpening the index file: %s ...............", ndxname);

rc = dBiopen(ndxname, &ndxid);

if (rc == SUCCESS) printf("File successfully opened!");

return(rc);

} /* end of tBiopen() */

/********* tBiclose ********/
int tBiclose()
{
int rc;
extern int dBiclose();

printf("\nSYNOPSIS:   int dBiclose(ndxfd)");
printf("\n\nClosing the index file: %s ...............", ndxname);

rc = dBiclose(ndxid);

ndxid = (char *) 0;

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


/****** tBakey ********/
int tBakey()
{
BYTE key[128];
RECNUM recno;
int rc;
extern int dBakey();
extern int scankey();
extern long inputnum();

printf("\nSYNOPSIS:     int dBakey(ndxfd, key, recno)");

if ((rc = scankey(ndxid, 128, key)) != SUCCESS) return(rc);

printf("\nEnter recno > ");
recno = (RECNUM) inputnum();

rc = dBakey(ndxid, key, recno);

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

/******** tBrmvkey **********/
int tBrmvkey()
{
BYTE key[128];
RECNUM recno;
int rc;
extern int dBrmvkey();
extern int scankey();
extern long inputnum();


printf("\nSYNOPSIS:     int dBrmvkey(ndxfd, key, recno)");

if ((rc = scankey(ndxid, 128, key)) != SUCCESS) return(rc);

printf("\nEnter recno > ");
recno = (RECNUM) inputnum();

rc = dBrmvkey(ndxid, key, recno);
return(rc);

} /* end of tBrmvkey() */

/******** tBtkey **********/
int tBtkey()
{
int rc;
BYTE key[128];
RECNUM recno;
extern int dBtkey();
extern int scankey();

printf("\nSYNOPSIS:     int dBtkey(ndxfd, key, recno)");

if ((rc = scankey(ndxid, 128, key)) != SUCCESS) return(rc);

rc = dBtkey(ndxid, key, &recno);

if (rc != SUCCESS) return(rc);

printf("\nrecno = %ld", recno);

return(rc);

} /* end of tBtkey() */

/******** tBckey **********/
int tBckey()
{
BYTE key[128];
RECNUM recno;
int rc;
extern int dBckey();

printf("\nSYNOPSIS:     int dBckey(ndxfd, key, recno)");

rc = dBckey(ndxid, key, &recno);

if (rc != SUCCESS) return(rc);

printf("\nrecno = %ld", recno);
printkey(ndxid, key); 

return(rc);

} /* end of tBckey() */

/******** tBnkey **********/
int tBnkey()
{
BYTE key[128];
RECNUM recno;
int rc;
extern int dBnkey();

printf("\nSYNOPSIS:     int dBnkey(ndxfd, key, recno)");

rc = dBnkey(ndxid, key, &recno);

if (rc != SUCCESS) return(rc);

printf("\n\nrecno = %ld", recno);
printkey(ndxid, key);

return(rc);

} /* end of tBnkey() */

/******** tBpkey **********/
int tBpkey()
{
BYTE key[128];
RECNUM recno;
int rc;
extern int dBpkey();

printf("\nSYNOPSIS:     int dBpkey(ndxfd, key, recno)");

rc = dBpkey(ndxid, key, &recno);

if (rc != SUCCESS) return(rc);

printf("\n\nrecno = %ld", recno);
printkey(ndxid, key);

return(rc);

} /* end of tBpkey() */

/****** tBrewind ******/
int tBrewind()
{
int rc;
extern int dBrewind();

printf("\nSYNOPSIS:     int dBrewind(ndxfd)");

rc = dBrewind(ndxid);

return(rc);

} /* end of tBrewind() */

/****** tBfwd ******/
int tBfwd() 
{
int rc;
extern int dBfwd();

printf("\nSYNOPSIS:     int dBfwd(ndxfd)");

rc = dBfwd(ndxid);

return(rc);

} /* end of tBfwd() */

/******* tBgetrk *********/
int tBgetrk()
{
BYTE key[128];
int rc;
RECLEN reclen;
BYTE month, day, year;
FLDNUM nofields;
dBFIELD *fields;
BYTE status;
extern int dBgetf(), dBgetrk();
extern char *malloc();
extern int free();
extern int scankey();

printf("\nSYNOPSIS:     int dBgetrk(dbffd, ndxfd, key, record, status)");

if (!(fields = (dBFIELD *) malloc( (U2BYTES) sizeof(dBFIELD) * 128)))
{
	printf("\nSTUDYDBC: not enough memory space available");
	return(-1);
}

rc = dBgetf(dbfid, &reclen, &month, &day, &year, &nofields, fields);
if (rc != SUCCESS)
{
	printf("\nerror code returned by 'dBgetf'");
	free( (char *) fields);
	return(rc);
}

if ((rc = scankey(ndxid, 128, key)) != SUCCESS)
{
	free( (char *) fields);
	return(rc);
}
rc = dBgetrk(dbfid, ndxid, key, recbuf, &status);
if (rc != SUCCESS)
{
	free( (char *) fields);
	return(rc);
}
printf("\nrecord status = ");
if (status == ACTIVE) printf("ACTIVE");
else		      printf("INACTIVE");

printf("\nrecord retrieve =>");
gendump(recbuf, reclen);

free( (char *) fields);

return(SUCCESS);

} /* end of tBgetrk() */

/******* tBgetnr ********/
int tBgetnr()
{
int rc;
RECLEN reclen;
BYTE month, day, year;
FLDNUM nofields;
dBFIELD *fields;
BYTE status;
extern int dBgetf(), dBgetnr(), free();
extern char *malloc();

printf("\nSYNOPSIS:     int dBgetnr(dbffd, ndxfd, record, status)");

if (!(fields = (dBFIELD *) malloc( (U2BYTES) sizeof(dBFIELD) * 128)))
{
	printf("\nSTUDYDBC: not enough memory space available");
	return(-1);
}

rc = dBgetf(dbfid, &reclen, &month, &day, &year, &nofields, fields);
if (rc != SUCCESS)
{
	printf("\nerror code returned by 'dBgetf'");
	free( (char *) fields);
	return(rc);
}

rc = dBgetnr(dbfid, ndxid, recbuf, &status);

if (rc != SUCCESS)
{
	free( (char *) fields);
	return(rc);
}

printf("\nrecord status = ");
if (status == ACTIVE) printf("ACTIVE");
else		      printf("INACTIVE");

gendump(recbuf, reclen);

free( (char *) fields);

return(rc);

} /* end of tBgetnr() */

/******* tBgetpr ********/
int tBgetpr()
{
int rc;
RECLEN reclen;
BYTE month, day, year;
FLDNUM nofields;
dBFIELD *fields;
BYTE status;
extern int dBgetf(), dBgetpr();
extern char *malloc();
extern int  free();

printf("\nSYNOPSIS:     int dBgetpr(dbffd, ndxfd, record, status)");

if (!(fields = (dBFIELD *) malloc( (U2BYTES) sizeof(dBFIELD) * 128)))
{
	printf("\nSTUDYDBC: not enough memory space available");
	return(-1);
}

rc = dBgetf(dbfid, &reclen, &month, &day, &year, &nofields, fields);
if (rc != SUCCESS)
{
	printf("\nerror code returned by 'dBgetf'");
	free( (char *) fields);
	return(rc);
}

rc = dBgetpr(dbfid, ndxid, recbuf, &status);

if (rc != SUCCESS)
{
	free( (char *) fields);
	return(rc);
}

printf("\nrecord status = ");
if (status == ACTIVE) printf("ACTIVE");
else		      printf("INACTIVE");

gendump(recbuf, reclen);

free( (char *) fields);

return(rc);

} /* end of tBgetpr() */

/******* tBputrk *********/
int tBputrk()
{
BYTE key[128], *kptr;
int i, rc;
extern int dBputrk();
extern int scankey(), scanrec();

for (i=1, kptr=key; i<=128; i++) *kptr++ = ' ';

printf("\nSYNOPSIS:     int dBputrk(dbffd, ndxfd, key, record)");

if ((rc = scankey(ndxid, 128, key)) != SUCCESS) return(rc);
if ((rc = scanrec(recbuf)) != SUCCESS) return(-1);
		/* scanrec(): implemented in stdydbc1.c */

rc = dBputrk(dbfid, ndxid, key, recbuf);
return(rc);

} /* end of tBputrk() */


/******* tBkexpr *********/
int tBkexpr()
{
BYTE keyexpr[128];
BYTE keytype;
int kexprlen;
KEYLEN keylen;
int rc;
extern int dBkexpr();

printf("\nSYNOPSIS:   int dBkexpr(ndxfd, keytype, keyexpr, kexprlen, keylen)");

rc = dBkexpr(ndxid, &keytype, keyexpr, &kexprlen, &keylen);

if (rc != SUCCESS) return(rc);
printf("\n\nkeytype = ");
if (keytype == CHARKEY) printf("CHARACTER type");
else                    printf("NUMERIC or DATE type");
printf("\nkey expression =>%s", keyexpr);
printf("\nkexprlen = %d", kexprlen);
printf("\nkeylen = %d", keylen);

return(rc);

} /* end of tBkexpr() */


/******* tBiflsh *******/
int tBiflsh()
{
int rc;
extern int dBiflsh();

printf("\nSYNOPSIS:     int dBiflsh(ndxfd)\n");
rc = dBiflsh(ndxid);

return(rc);

} /* end of tBiflsh() */

/******* tBatofld *********/
int tBatofld()
{
int width, decimal;
int rc;

printf("\nSYNOPSIS:     int dBatofld(ascii, width, decimal, field)");
printf("\n                     char    *ascii;");
printf("\n                     int     width;");
printf("\n                     int     decimal;");
printf("\n                     char    *field;");

printf("\nEnter \"ascii\" > ");
readin(string1);
printf("\nEnter \"width\" value > ");
width = (int) inputnum();
printf("\nEnter \"decimal\" value > ");
decimal = (int) inputnum();

/* dBatofld() does not put a NULL character at the end of "field".
   Clear string2[] just for this demo. */
for (rc=0; rc < 200; rc++) string2[rc] = (char) 0;

rc = dBatofld(string1, width, decimal, string2);
if (rc != SUCCESS) return(rc);

printf("\nConverted field => [%s]", string2);

return(SUCCESS);
} /* end of tBatofld() */


/******* tBfldtoa *********/
int tBfldtoa()
{
int width;
int rc;

printf("\nSYNOPSIS:     int dBfldtoa(field, width, ascii)");
printf("\n                     char    *field;");
printf("\n                     int     width;");
printf("\n                     char    *ascii;");

printf("\nEnter \"field\" > ");
readin(string1);
printf("\nEnter \"width\" value > ");
width = (int) inputnum();

rc = dBfldtoa(string1, width, string2);
if (rc != SUCCESS) return(rc);

printf("\nConverted ascii => [%s]", string2);

return(SUCCESS);

} /* end of tBfldtoa() */

/******* tBatokey *********/
int tBatokey()
{
int rc;
union
{
    double dval;
    char   key[8];
} ieee;

printf("\nSYNOPSIS:     int dBatokey(ascii, key)");
printf("\n                     char    *ascii;");
printf("\n                     char    *key;");
printf("\n    (Read the tBatokey() function written in STDYDBC2.C");
printf("\n     to find out exactly what is going on.)");

printf("\n\nEnter \"ascii\" > ");
readin(string1); /* get ASCII in string1[]
		    ( Readin() is written in STUDYDBC.C. ) */
printf("\nEnter 'd' or 'D' if the \"ascii\" represents a DATE key, or");
printf("\n      any other key if it is a NUMERIC key\n > ");
readin(ieee.key); /* get ASCII in ieee.key[0]
		    ( Readin() is written in STUDYDBC.C. ) */
printf("\nkey[0] set to %c", ieee.key[0]);

rc = dBatokey(string1, ieee.key); /* finally call dBatokey() */

if (rc != SUCCESS) return(rc);

printf("\n\nConverted key in IEEE format (\"double\") => %f", ieee.dval);    
    /* This printf() demonstrates that ieee.key is actually in IEEE floating-
       point number format. */
return(SUCCESS);

} /* end of tBatokey() */

/******* tBkeytoa *********/
int tBkeytoa()
{
int rc;
union
{
    double dval;
    char   key[8];
} ieee;

printf("\nSYNOPSIS:     int dBkeytoa(key, ascii)");
printf("\n                     char    *key;");
printf("\n                     char    *ascii;");
printf("\n    (Read the tBkeytoa() function written in STDYDBC2.C");
printf("\n     to find out exactly what is going on.)");

printf("\n\nEnter \"key\" in double floating number > ");
scanf("%lf", &(ieee.dval)); /* This sets ieee.key. */
getchar();

printf("\nEnter 'd' or 'D' if the \"ascii\" represents a DATE key, or");
printf("\n      any other key if it is a NUMERIC key\n > ");
readin(recbuf); /* get ASCII in recbuf[]
		    ( Readin() is written in STUDYDBC.C. ) */
string2[1] = recbuf[0];
printf("\nascii[1] set to %c", string2[1]);
if (string2[1] != 'd' && string2[1] != 'D')
{
    printf("\nEnter number of decimal places > ");
    string2[0] = (char) inputnum(); /* get number in string2[0]
		    		( Inputnum() is written in STUDYDBC.C. ) */
    printf("\nascii[0] set to %d", string2[0]);
}

/* finally call dBkeytoa()
   Notice that "ieee.key" was set as "ieee.dval" by scanf(). */
rc = dBkeytoa(ieee.key, string2);
if (rc != SUCCESS) return(rc);

printf("\n\nConverted ASCII string => %s", string2);

return(SUCCESS);

} /* end of tBkeytoa() */

/******* tBstrcpy *********/
int tBstrcpy()
{
int length;
char *cptr;
printf("\nSYNOPSIS:     void dBstrcpy(string, adjmode, length, origstr)");
printf("\n		       char    *string;");
printf("\n                     char    adjmode;");
printf("\n                     int     length;");
printf("\n                     char    *origstr;");

printf("\nEnter L or R for \"adjmode\" > ");
readin(recbuf);
printf("\nEnter \"length\" value > ");
length = (int) inputnum();
printf("\nEnter a character string to be formatted (i.e., \"origstr\")");
printf("\n>");
readin(string1);

dBstrcpy(string2, recbuf[0], length, string1);

printf("\nFormatted String:\n[");
cptr = &string2[0];
while (length--) printf("%c", *cptr++);
printf("]");
return(0);
} /* end of tBstrcpy() */


/***** function to read a key from user input *****/
scankey(ndxfd, buflen, key)
	char *ndxfd; /* input:  index file descriptor */
	int  buflen; /* input:  length of key buffer */
	BYTE *key;   /* output: pointer to key array */
{
BYTE keyexpr[128];
BYTE akey[128];
BYTE keytype;
int kexprlen;
KEYLEN keylen;
int i, rc, inputlen;
BYTE *cptr;
extern char numordat();


rc = dBkexpr(ndxid, &keytype, keyexpr, &kexprlen, &keylen);

if (rc != SUCCESS)
{
	printf("\nFailure in reading key expression");
	return(rc);
}

printf("\n\nEnter key in ASCII character string > ");

for (i=1, cptr=akey; i<=buflen; i++) *cptr++ = ' ';
readin(akey);
inputlen = strlen(akey);
*(akey + inputlen) = ' ';

if (keytype != CHARKEY)
{
	printf("\nKey Type Is NUMERIC or DATE");
	*(akey + inputlen) = 0; /* NULL */
	*key = numordat();
	printf("\n   Calling 'dBatokey' for ASCII to NUMERIC/DATE key ");
	printf("conversion.......");
	rc = dBatokey(akey, key);
	if (rc != SUCCESS)
	{
		printf("\nFailure in converting ASCII to NUMERIC/DATE KEY");
		return(rc);
	}
	printf("\nConversion Complete!");
}
else
{
	for (i=1, cptr=akey; i<=buflen; i++) *key++ = *cptr++;
}

return(SUCCESS);

} /* end of scankey() */


/***** function to print a key *****/
printkey(ndxfd, key)
	char *ndxfd; /* input:  index file descriptor */
	BYTE *key;   /* output: pointer to key array */
{
BYTE keyexpr[128];
BYTE keytype;
int kexprlen;
KEYLEN keylen;
int rc;
BYTE numdatky[64];
extern int dBkexpr(), dBkeytoa();
extern long inputnum();
extern char numordat();


rc = dBkexpr(ndxid, &keytype, keyexpr, &kexprlen, &keylen);

if (rc != SUCCESS)
{
	printf("\nFailure in reading key expression");
	return(rc);
}

if (keytype == CHARKEY)
{
	printf("\n[Key Type is CHARACTER]");
	gendump(key, keylen);
}
else
{
	printf("\n[Key Type Is NUMERIC or DATE]");
	numdatky[1] = numordat();
	if (numdatky[1] != 'D' && numdatky[1] != 'd') { 
		/* Let's assume any character other than 'D' is for NUMERIC. */
		printf("\n\nSPECIFY:\nthe number of DECIMAL PLACES ");
		printf("included in the converted ASCII string > ");
		numdatky[0] = (char) inputnum();
	}
	printf("\n   Calling 'dBkeytoa' for NUMERIC or DATE KEY to ASCII");
	printf(" conversion........");
	rc = dBkeytoa(key, numdatky);
	if (rc != SUCCESS)
	{
		printf("\nFailure in converting NUMERIC/DATE key");
		printf(" to ASCII string");
		return(rc);
	}
	printf("\nThe conversion was successful!");
	printf("\nKEY=%s", numdatky);
}
return(SUCCESS);

} /* end of printkey() */

char numordat()
{
char smallbuf[10];

printf("\nIndex file itself simply knows that it contains NUMERIC or");
printf(" DATE keys.");
printf("\nIt does not exactly know which type the keys are.");
printf("\nSPECIFY key type (N for numeric key; D for date key) > ");

readin(smallbuf);
return(smallbuf[0]);
} /* end of numordat() */
