DataMuseum.dk

Presents historical artifacts from the history of:

CP/M

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about CP/M

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download

⟦79fb32a59⟧ TextFile

    Length: 30464 (0x7700)
    Types: TextFile
    Names: »DATABASE.SRC«

Derivation

└─⟦57f0389e8⟧ Bits:30005761 SW1611 Access Manager v. 1.0
    └─ ⟦this⟧ »DATABASE.SRC« 

TextFile

PROGRAM DATABASE;

(* ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  
  	DATABASE EXAMPLE VERSION 1.0 9/14/82  0935
  
   ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  
 *)

(*$E-*)

CONST
	MAX_KEY = 2;
	MAX_FIELD = 7;
	MAX_KEY_LEN = 20;
	MAX_FLD_LEN = 20;
	NAME_LEN = 14;
	FLD_NAME_LEN = 18;
	ACTION_LEN = 4;
	NEW_MODE = 1;
	OLD_MODE = 2;
	YES = 1;
	NO = 0;
	SAVE = 1;
	DELT = 2;
	BACK = 3;
	CONT = 4;
	STOP = 5;

TYPE
	BYTEPTR = ^BYTE;
	KEYSTR = STRINGÆMAX_KEY_LENÅ;
	FLDSTR = STRINGÆMAX_FLD_LENÅ;

	FLD_REC = RECORD;
		LENBYTE : BYTE;
		FLDCHR  : ARRAYÆ1..MAX_FLD_LENÅ OF CHAR;
	END;

	CUST_REC = RECORD;
		CDF : CHAR;
		FLD : ARRAYÆ1..99Å OF CHAR;
	END;

(*
	WORKING VARIABLES
 *)

VAR
	KEY,TERMINAL,TRAP_ERRORS,TIME_OUT_TEST_DELAY,NO_BUFFERS : INTEGER;
	NO_NODE_SECTORS,NO_DATA_FILES,NO_KEYZ,FILE_NO : INTEGER;
	RECORD_LENGTH : INTEGER;
	SET_LENGTH,IDX_KEY,SPACE : KEYSTR;
	OLD_ACTION : INTEGER;
	FILNAME : STRINGÆNAME_LENÅ;
	NULL_BYT : BYTE;
	NULL_CHR : CHAR;

(*
   ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  
  	 DATABASE FIELD & KEY DESCRIPTORS
  
   ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *)

	DATBUF : CUST_REC;
	DATBUF_PTR : ^CUST_REC;
	FLD_NAME,KEY_NAME : ARRAYÆ0..MAX_FIELDÅ OF STRINGÆFLD_NAME_LENÅ;
	FLD_LEN : ARRAYÆ0..MAX_FIELDÅ OF BYTE;
	OLD_FLD,NEW_FLD : ARRAYÆ0..MAX_FIELDÅ OF FLDSTR;
	NO_FIELDS : INTEGER;

	IDX_NAME : ARRAYÆ0..MAX_KEYÅ OF STRINGÆNAME_LENÅ;
	KEY_LEN,KEY_MAP,KEY_TYPE,KEY_NUM,KEY_DUP : ARRAYÆ0..MAX_KEYÅ OF
		INTEGER;
	FOR_EVER : BOOLEAN;
	UNIQ_KEY,NLOCK,SLOCK,XLOCK,SFILE,XFILE,RLOCK : INTEGER;
  
(*
   	INTERFACE TO ACCESS MANAGER(tm)
  
   	AM86EXTR.PSC CONTAINS THE EXTERNAL DEFINITIONS OF THE ACCESS MANAGER
	ROUTINES
 *)

æ$I AM86EXTR.PSCå

EXTERNAL FUNCTION @BDOS86(FUNC:INTEGER; PARM:BYTEPTR) : INTEGER;

PROCEDURE GO_OP_SYS;

VAR
	DUMMY : INTEGER;
	DPARM : BYTEPTR;

	BEGIN
	DUMMY := @BDOS86(0,DPARM);
	END;æGO_OP_SYSå


PROCEDURE DATA_BASE;

	BEGIN
	CLRSCR;

	CASE MAIN_MENU OF

1: DBNEW;
2: DBSCAN;
3: DBLIST;
4: DBSTAT;
5: DBSAVE;
6: DBTERM;
	END;æOF CASEå
	END;æDATA_BASEå



(*
   ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  
   		ENTER NEW CUSTOMERS
   
   ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *)

PROCEDURE DBNEW;
VAR
	KEY,LOCK_CODE,NDRN,DRN,CHOICE : INTEGER;
	SAVE_KEY,LDRN,NO_LISTED : INTEGER;
	ROUTE : CHAR;
	CONTINUE,STAYPUT : BOOLEAN;
	L_VALUE,U_VALUE,CONV_TARGET,TARGET : KEYSTR;
	ACTION : INTEGER;


  BEGIN
     ACTION := SAVE;
     WHILE (ACTION = SAVE) DO
	BEGIN
	ACTION := NEWDAT;
	LOCK_CODE := 0;
	IF ACTION = SAVE THEN
		BEGIN
		NDRN := UPDATE(0);
		LOCK_CODE := FRELOK(FILE_NO,XLOCK,NDRN);
		END;

	IF LOCK_CODE <> 0 THEN
		LOCK_TYPE(8);
	END;
   END;æDBNEWå

(*
   ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  
   		SCAN/UPDATE/DELETE CUSTOMERS
  
   ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *)

PROCEDURE DBSCAN;
VAR
	KEY,LOCK_CODE,NDRN,DRN,CHOICE : INTEGER;
	SAVE_KEY,LDRN,NO_LISTED : INTEGER;
	ROUTE : CHAR;
	CONTINUE,STAYPUT : BOOLEAN;
	L_VALUE,U_VALUE,CONV_TARGET,TARGET : KEYSTR;
	ACTION : INTEGER;


   BEGIN
     KEY := SEARCH_KEY;
     WRITELN;
     WRITELN ('Enter target value for ',KEY_NAMEÆKEYÅ,',');
     WRITE('     or enter a period (.) to see main menu>>');
     READLN(TARGET);
     IF TARGET <> '.' THEN
	BEGIN
	CONV_TARGET := TARGET;
	KEY_FORMAT(KEY,CONV_TARGET);
	STAYPUT := TRUE;
	WHILE (STAYPUT) DO
		BEGIN
		DRN := SERKEY(KEY_NUMÆKEYÅ,FILE_NO,SLOCK,
			CONV_TARGET,IDX_KEY);
		IF ERRCOD <> 0 THEN
			ERROR_TYPE(KEY,2);
		IF LOKCOD <> 0 THEN
			STAYPUT := CHECK_LOCK(KEY,DRN)
		ELSE
			STAYPUT :=FALSE;
		END;
	
	OLD_ACTION := CONT;
	CONTINUE := TRUE;
	WHILE (CONTINUE) AND (DRN <> 0) DO
		BEGIN
		LDRN := DRN;
		READ_CUST(DRN);
		ACTION := OLDDAT(DRN);
		SAVE_KEY := KEY;
		IF ACTION = SAVE THEN
			DRN := UPDATE(DRN);
		IF ACTION = DELT THEN
			DELETE(DRN);
		IF (ACTION <> DELT) AND (FRELOK(FILE_NO,RLOCK,LDRN) <> 0)
			THEN LOCK_TYPE(2);
		IF (ACTION = SAVE) OR (ACTION = DELT) THEN
			BEGIN 
			KEY := SAVE_KEY;
			ACTION := OLD_ACTION;
			END;
		OLD_ACTION := ACTION;
		CONV_TARGET := COPY(IDX_KEY,1,KEY_LENÆKEYÅ);
		IDX_KEY := SET_LENGTH;
		LOCK_CODE := 0;

		STAYPUT := TRUE;
		WHILE (STAYPUT) DO
		    BEGIN
		    IF ACTION = CONT THEN
			BEGIN
			DRN := AFTKEY(KEY_NUMÆKEYÅ,FILE_NO,
				SLOCK, CONV_TARGET,IDX_KEY);
			LOCK_CODE := LOKCOD;
			END;
		    IF ACTION = BACK THEN
			BEGIN
			DRN := BEFKEY(KEY_NUMÆKEYÅ,FILE_NO,
				SLOCK, CONV_TARGET,IDX_KEY);
			LOCK_CODE := LOKCOD;
			END;

		    IF LOCK_CODE <> 0 THEN
			STAYPUT := CHECK_LOCK(KEY,DRN)
		    ELSE
			STAYPUT := FALSE;
		    END;

		IF ACTION = STOP THEN
			CONTINUE := FALSE;
		END;

	WRITELN;
	WRITELN('SCAN ENDED');
	PAUSE;
	END;
   END;æDBSCANå

(*
   ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  
   			LIST CUSTOMERS
  
   ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *)

PROCEDURE DBLIST;
VAR
	KEY,LOCK_CODE,NDRN,DRN,CHOICE : INTEGER;
	SAVE_KEY,LDRN,NO_LISTED : INTEGER;
	ROUTE : CHAR;
	CONTINUE,STAYPUT : BOOLEAN;
	L_VALUE,U_VALUE,CONV_TARGET,TARGET : KEYSTR;
	ACTION : INTEGER;


   BEGIN
	KEY := SEARCH_KEY;
	WRITELN;
	WRITE('Do you want listing routed to printer (Y/N) >>');
	READLN(ROUTE);
	IF ROUTE = 'y' THEN ROUTE := 'Y';
	
	WRITELN;
	WRITELN;
	WRITELN(
'Enter lower and upper limits for ',KEY_NAMEÆKEYÅ,' listing;');
	WRITE('     place values on separate lines >>') ;
	READLN(L_VALUE);
	READLN(U_VALUE);
	KEY_FORMAT(KEY,L_VALUE);
	KEY_FORMAT(KEY,U_VALUE);
	DRN := SERKEY(KEY_NUMÆKEYÅ,FILE_NO,SLOCK,
		L_VALUE,IDX_KEY);
	IF LOKCOD <> 0 THEN
		SKIP_LOCK(KEY,DRN);

	NO_LISTED := 0;
	WHILE (DRN <> 0) AND (COMPARE(KEY,IDX_KEY,U_VALUE) <= 0) DO
		BEGIN
		READ_CUST(DRN);
		PRINT_CUST(ROUTE);
		NO_LISTED := NO_LISTED + 1;
		IF FRELOK(FILE_NO,SLOCK,DRN) <> 0 THEN
			LOCK_TYPE(4);
		L_VALUE := COPY(IDX_KEY,1,KEY_LENÆKEYÅ);
		IDX_KEY := SET_LENGTH;
		DRN := AFTKEY(KEY_NUMÆKEYÅ,FILE_NO,SLOCK,
			L_VALUE,IDX_KEY);
		IF LOKCOD <> 0 THEN
			SKIP_LOCK(KEY,DRN);
		END;

	IF DRN <> 0 THEN
		LOCK_CODE := FRELOK(FILE_NO,SLOCK,DRN)
	ELSE
		LOCK_CODE := 0;
	IF LOCK_CODE <> 0 THEN
		LOCK_TYPE(5);

	WRITELN;
	WRITELN(NO_LISTED,' records listed.');
	PAUSE;
   END;æDBLISTå

(*
   ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  
   		DATABASE STATISTICS
  
   ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *)

PROCEDURE DBSTAT;
VAR
	KEY,LOCK_CODE,NDRN,DRN,CHOICE : INTEGER;
	SAVE_KEY,LDRN,NO_LISTED : INTEGER;
	ROUTE : CHAR;
	CONTINUE,STAYPUT : BOOLEAN;
	L_VALUE,U_VALUE,CONV_TARGET,TARGET : KEYSTR;
	ACTION : INTEGER;


   BEGIN
	CLRSCR;
	WRITELN(FILNAME,' has ',GETDFS(FILE_NO),
		' records; currently, ',GETDFU(FILE_NO),
		' of them are in use.');
	WRITELN;
	WRITELN;
	WRITELN('    INDEX','ENTRIES':30);
	WRITELN ('-----------------','-------':22);
	FOR KEY := 0 TO MAX_KEY DO
		WRITELN(KEY_NAMEÆKEYÅ:16,' ':16,NOKEYS(KEY):7);

	WRITELN;
	WRITELN;
	PAUSE;
   END;æDBSTATå

(*
   ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  
   		SAVE DATABASE UPDATES & RESTART
  
   ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *)

PROCEDURE DBSAVE;
VAR
	KEY,LOCK_CODE,NDRN,DRN,CHOICE : INTEGER;
	SAVE_KEY,LDRN,NO_LISTED : INTEGER;
	ROUTE : CHAR;
	CONTINUE,STAYPUT : BOOLEAN;
	L_VALUE,U_VALUE,CONV_TARGET,TARGET : KEYSTR;
	ACTION : INTEGER;


   BEGIN
	IF SAVDAT(FILE_NO) <> 0 THEN
		ERROR_TYPE(0,7);
	FOR KEY := 0 TO MAX_KEY DO
		IF SAVIDX(KEY_NUMÆKEYÅ) <> 0 THEN
			ERROR_TYPE(KEY,3);
   END;æDBSAVEå

(*
   ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  
   		SAVE DATABASE UPDATES & TERMINATE
  
   ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *)

PROCEDURE DBTERM;
VAR
	KEY,LOCK_CODE,NDRN,DRN,CHOICE : INTEGER;
	SAVE_KEY,LDRN,NO_LISTED : INTEGER;
	ROUTE : CHAR;
	CONTINUE,STAYPUT : BOOLEAN;
	L_VALUE,U_VALUE,CONV_TARGET,TARGET : KEYSTR;
	ACTION : INTEGER;


   BEGIN
	IF FRELOK(FILE_NO,SFILE,0) <> 0 THEN
		ERROR_TYPE(0,13);
	IF CLSDAT(FILE_NO) <> 0 THEN
		ERROR_TYPE(0,15);
	FOR KEY := 0 TO MAX_KEY DO
		IF CLSIDX(KEY_NUMÆKEYÅ) <> 0 THEN
			ERROR_TYPE(KEY,16);


	WRITELN;
	WRITELN(' ***  SUCCESSFUL TERMINATION ***');
	FOR_EVER := FALSE;
   END;æDBTERMå


(*
   +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  
  		BEGINNING OF UTILITY FUNCTIONS
  
  
   :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  
   		CLEAR SCREEN ROUTINE
  
   :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *)

PROCEDURE CLRSCR;
VAR
	DUMMY : INTEGER;

	BEGIN
	FOR DUMMY := 1 TO 24 DO
		WRITELN;
	END;æCLRSCRå

(*
   :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  
   		MAIN MENU ROUTINE
  
   :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *)

FUNCTION MAIN_MENU : INTEGER;
VAR
	OP : INTEGER;

	BEGIN
	WRITELN(' ':19,' ACCESS MANAGER(tm) DEMONSTRATION');
	WRITELN;
	WRITELN(' ':19,'   Customer Database Operations') ;
	WRITELN(' ':19,'          Terminal ',TERMINAL);
	WRITELN(' ':19,'   ****************************');
	WRITELN;
	WRITELN;
	WRITELN('    1. Enter New Customers');
	WRITELN('    2. Scan/Update/Delete Customer Records');
	WRITELN('    3. List Customer Records');
	WRITELN('    4. Database Statistics');
	WRITELN('    5. Save All Files & Restart Operations');
	WRITELN('    6. Terminate Operations');

	OP := 0;
	WHILE (OP < 1) OR (OP > 6) DO
		BEGIN
		WRITELN;
		WRITE('Enter desired operation number>>');
		READLN(OP);
		END;
	MAIN_MENU := OP;
	END;æMAIN_MENUå

(*
   :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  
   		SELECT SEARCH KEY ROUTINE
  
   :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *)

FUNCTION SEARCH_KEY : INTEGER;
VAR
	KEY,KEY_NO : INTEGER;

	BEGIN
	CLRSCR;
	WRITELN(' ':24,'Customer Database Search Keys');
	WRITELN;
	WRITELN;
	WRITELN;

	FOR KEY := 0 TO MAX_KEY DO
		BEGIN
		KEY_NO := KEY + 1;
		WRITELN(KEY_NO,' - ',KEY_NAMEÆKEYÅ) 
		END;

	KEY := 0;
	WHILE (KEY < 1) OR (KEY > NO_KEYZ) DO
		BEGIN
		WRITELN;
		WRITELN;
		WRITE('Enter desired key number>>');
		READLN(KEY);
		END;
	SEARCH_KEY := KEY-1;
	END;æSEARCH_KEYå

(*
   ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  
   		ERROR HANDLING
  
   ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *)

PROCEDURE ERROR_TYPE(INFO,LOCALE : INTEGER);
VAR
	DUMMY : INTEGER;

PROCEDURE ET_CLOSE;
VAR
	T_KEY : INTEGER;

	BEGIN
	DUMMY := CLSDAT(FILE_NO);
	FOR T_KEY := 0 TO MAX_KEY DO
		IF T_KEY <> INFO THEN DUMMY := CLSIDX(KEY_NUMÆT_KEYÅ);
	ET_STOP;
	END;

PROCEDURE ET_PCLOSE;
VAR
	L_KEY,T_KEY : INTEGER;
	
	BEGIN
	L_KEY := INFO + 1;
	IF L_KEY > MAX_KEY THEN GO_OP_SYS;
	FOR T_KEY := L_KEY TO MAX_KEY DO
		DUMMY := CLSIDX(KEY_NUMÆT_KEYÅ);
	END;

PROCEDURE ET_STOP;

	BEGIN
	WRITELN;
	WRITELN('DATABASE TERMINATING WITH ERROR CODE #',ERRCOD);
	GO_OP_SYS;
	END;


	BEGIN
	WRITELN;
	WRITELN;
	WRITE('User Error #',ERRCOD,' occurred while trying to ');

	CASE LOCALE OF
		
1:	WRITELN('open ',IDX_NAMEÆINFOÅ);
2:	WRITELN('search ',KEY_NAMEÆINFOÅ,' Index File');
3:	WRITELN('save ',IDX_NAMEÆINFOÅ);
4:	WRITELN('remove old key from ',IDX_NAMEÆINFOÅ);
5:	WRITELN('enter key into ',IDX_NAMEÆINFOÅ);
6:	WRITELN('delete key from ',IDX_NAMEÆINFOÅ);
7: BEGIN
	WRITELN('save ',FILNAME);
	INFO := -1;
   END;
8:	WRITELN('get a new data record',' (',FILE_NO,')');
9:	WRITELN('delete data record #',INFO);
10:	WRITELN('open ',FILNAME,' (',FILE_NO,')');
11:	WRITELN('read data record #',INFO);
12:	WRITELN('write data record #',INFO);
13:	WRITELN('release shared file lock on ',FILNAME);
14: BEGIN
	WRITELN('initialize user.');
	GO_OP_SYS;
    END;
15: BEGIN
	WRITELN('close ',FILNAME);
	INFO := -1;
    END;
16:	WRITELN('close ',IDX_NAMEÆINFOÅ);

	END;æOF CASEå

	IF (LOCALE = 1) OR ((LOCALE > 7) AND (LOCALE < 13)) THEN
		ET_STOP
	ELSE IF (LOCALE = 2) OR ((LOCALE > 3) AND (LOCALE < 7)) OR
	    (LOCALE = 13) THEN
		ET_CLOSE
	ELSE
		ET_PCLOSE;


	END;æERROR_TYPEå

PROCEDURE LOCK_TYPE(LOCALE : INTEGER);
VAR
	T_KEY,DUMMY : INTEGER;

	BEGIN
	WRITELN('Lock Type: ',LOCALE,'  Lock Code:',LOKCOD);
	DUMMY := CLSDAT(FILE_NO);
	FOR T_KEY := 0 TO MAX_KEY DO
		DUMMY := CLSIDX(KEY_NUMÆT_KEYÅ);
	GO_OP_SYS;
	END;æLOCK_TYPEå


(*
   :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  
   		READ DATA RECORD ROUTINE
  
   :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *)

PROCEDURE READ_CUST(DRN : INTEGER);
VAR
	FLD,CHR,POS_PTR : INTEGER;
	TMP_FLD : FLDSTR;
	FLDPTR : ^FLD_REC;

	BEGIN
	IF READAT(FILE_NO,DRN,DATBUF_PTR) <> 0 THEN
		ERROR_TYPE(DRN,11);

	FLDPTR := ADDR(TMP_FLD); (* PTR TO STRING *)

	POS_PTR := 0;
	FOR FLD := 0 TO MAX_FIELD DO
		BEGIN
		FLDPTR^.LENBYTE := FLD_LENÆFLDÅ;
		FOR CHR := 1 TO FLDPTR^.LENBYTE DO
			FLDPTR^.FLDCHRÆCHRÅ := DATBUF.FLDÆPOS_PTR + CHRÅ;
		
		WHILE (FLDPTR^.FLDCHRÆFLDPTR^.LENBYTEÅ = ' ') AND 
		    (FLDPTR^.LENBYTE > 0) DO
			FLDPTR^.LENBYTE := FLDPTR^.LENBYTE - 1;
		OLD_FLDÆFLDÅ := TMP_FLD;
		POS_PTR := POS_PTR + FLD_LENÆFLDÅ;
		END;
		
	END;æREAD_CUSTå

(*
   :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  
   		LIST CUSTOMER RECORD ROUTINE
  
   :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *)

PROCEDURE PRINT_CUST(ROUTE : CHAR);
VAR
	DUMMY : INTEGER;
	LIST_FILE : TEXT;

	BEGIN
	IF ROUTE = 'Y' THEN
		ASSIGN(LIST_FILE,'LST:')
	ELSE
		ASSIGN(LIST_FILE,'CON:');
	RESET(LIST_FILE);

	WRITELN(LIST_FILE);
	WRITELN(LIST_FILE,' ':4,OLD_FLDÆ0Å:10,'  ',OLD_FLDÆ7Å);            
	WRITELN(LIST_FILE,' ':24,OLD_FLDÆ1Å,' ',OLD_FLDÆ2Å);
	WRITELN(LIST_FILE,' ':24,OLD_FLDÆ3Å);
	WRITELN(LIST_FILE,' ':24,OLD_FLDÆ4Å,', ',OLD_FLDÆ5Å,'    ',OLD_FLDÆ6Å);
	WRITELN(LIST_FILE);
	CLOSE(LIST_FILE,DUMMY);
	END;æPRINT_CUSTå

(*
   :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  
   		PAUSE ROUTINE
  
   :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *)

PROCEDURE PAUSE;
VAR
	NULL : CHAR;

	BEGIN
	WRITE('Press "RETURN" to continue ---');
	READLN(NULL);
	END;æPAUSEå

(*
   :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  
   	CONVERT TARGET VALUE TO KEY FORMAT ROUTINE
  
   :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *)

PROCEDURE KEY_FORMAT(KEY : INTEGER;VAR TARGET : KEYSTR);
VAR
	TEMP : STRINGÆ40Å;

	BEGIN
	IF UNIQ_KEY = KEY THEN
		EXIT
	ELSE
		BEGIN
		TEMP := CONCAT(TARGET,SPACE);
		TEMP :=COPY(TEMP,1,KEY_LENÆKEYÅ-2);
		TARGET :=  CONCAT(TEMP,NULL_CHR,NULL_CHR);
		END;
	END;æKEY_FORMATå

(*
   :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  
   		COMPARE IDX_KEY & U_VALUE ROUTINE
  
   :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *)

FUNCTION COMPARE(KEY : INTEGER; IDXVAL,UPVAL : KEYSTR) : INTEGER;
VAR
	KL : INTEGER;
	C1,C2 :  STRINGÆ40Å;

	BEGIN
	IF KEY = UNIQ_KEY THEN
		KL := KEY_LENÆKEYÅ
	ELSE
		KL := KEY_LENÆKEYÅ-2;

	C1 := CONCAT(IDXVAL,SPACE);
	C1 := COPY(C1,1,KL);
	C2 := CONCAT(UPVAL,SPACE);
	C2 := COPY(C2,1,KL);

	IF C1<C2 THEN
		COMPARE := -1
      	ELSE IF C1>C2 THEN
		COMPARE := 1
      	ELSE
		COMPARE := 0;
	END;æCOMPAREå

(*
   :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  
  		CHECK LOCK ROUTINES
  
   :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *)

PROCEDURE SKIP_LOCK(KEY,DRN : INTEGER);
VAR
	L_VALUE : KEYSTR;

	BEGIN
	WHILE (DRN <> 0) AND (LOKCOD <> 0) DO
		BEGIN
		L_VALUE := COPY(IDX_KEY,1,KEY_LENÆKEYÅ);
		IDX_KEY := SET_LENGTH;
		DRN := AFTKEY(KEY_NUMÆKEYÅ,FILE_NO,SLOCK,
			L_VALUE,IDX_KEY);
		END;
	END;æSKIP_LOCKå

FUNCTION CHECK_LOCK(KEY,DRN : INTEGER) : BOOLEAN;
VAR
	CONV_TARGET : KEYSTR;
	DUMMY : CHAR;

	BEGIN
	WRITELN;
	WRITE(
'Enter a "W" if you wish to wait for locked record(s)>>');
	READLN(DUMMY);

	IF (DUMMY = 'W') OR (DUMMY = 'w') THEN
		BEGIN
		CHECK_LOCK := TRUE;
		EXIT;
		END;

	WHILE (DRN <> 0) AND (LOKCOD <> 0) DO
		BEGIN
		CONV_TARGET := COPY(IDX_KEY,1,KEY_LENÆKEYÅ);
		IDX_KEY := SET_LENGTH;
		IF OLD_ACTION = CONT THEN
			DRN := AFTKEY(KEY_NUMÆKEYÅ,FILE_NO,
				SLOCK, CONV_TARGET,IDX_KEY)
		ELSE
			DRN := BEFKEY(KEY_NUMÆKEYÅ,FILE_NO,
				SLOCK, CONV_TARGET,IDX_KEY);
		END;
	CHECK_LOCK := FALSE;
	END;æCHECK_LOCKå

(*
   ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  
  		WARNING MESSAGES
  
   ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *)

PROCEDURE WARNING_TYPE(KEY,LOCALE,RET_CODE : INTEGER);

	BEGIN
	WRITELN;
	WRITE('WARNING...Return Code #',RET_CODE,
		' occurred while trying to ');
	
	CASE LOCALE OF

1:	WRITELN('remove old key from ',IDX_NAMEÆKEYÅ);

2:	WRITELN('enter key into ',IDX_NAMEÆKEYÅ);

3:	WRITELN('delete key from ',IDX_NAMEÆKEYÅ);

	END; æOF CASEå
	PAUSE;
	END;æWARNING_TYPEå

(*
   :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  
   		ADD NEW KEY VALUE ROUTINE
  
   :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *)

PROCEDURE ADD_A_KEY(KEY,DRN : INTEGER);
VAR
	RET_CODE,K_FLD : INTEGER;

	BEGIN
	K_FLD := KEY_MAPÆKEYÅ;

(*
	REMOVE OLD KEY VALUE
 *)

	RET_CODE := DELKEY(KEY_NUMÆKEYÅ,FILE_NO,
		XLOCK,OLD_FLDÆK_FLDÅ,DRN);

	IF ERRCOD <> 0 THEN
		ERROR_TYPE(KEY,4);
	IF LOKCOD <> 0 THEN
		LOCK_TYPE(6);
	IF RET_CODE <> 1 THEN
		WARNING_TYPE(KEY,1,RET_CODE);

(*
	ADD NEW KEY VALUE
*)

	RET_CODE := ADDKEY(KEY_NUMÆKEYÅ,FILE_NO,
		XLOCK,NEW_FLDÆK_FLDÅ,DRN);

	IF ERRCOD <> 0 THEN
		ERROR_TYPE(KEY,5);
	IF LOKCOD <> 0 THEN
		LOCK_TYPE(7);
	IF RET_CODE <> 1 THEN
		WARNING_TYPE(KEY,2,RET_CODE);

	END;æADD_A_KEYå

(*
   :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  
   		WRITE NEW DATA RECORD ROUTINE
  
   :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *)

PROCEDURE WRITE_CUST(DRN : INTEGER);
VAR
	FLD,CHR,POS_PTR : INTEGER;
	TMP_FLD : FLDSTR;
	FLDPTR : ^FLD_REC;

	BEGIN
	DATBUF.CDF := NULL_CHR;

	FLDPTR := ADDR(TMP_FLD); (* PTR TO STRING *)

	POS_PTR := 0;
	FOR FLD := 0 TO MAX_FIELD DO
		BEGIN
		TMP_FLD := NEW_FLDÆFLDÅ;
		FOR CHR := 1 TO FLDPTR^.LENBYTE DO
			DATBUF.FLDÆPOS_PTR + CHRÅ := 
				FLDPTR^.FLDCHRÆCHRÅ;
		
		WHILE (FLDPTR^.LENBYTE < FLD_LENÆFLDÅ) DO
			BEGIN
			FLDPTR^.LENBYTE := FLDPTR^.LENBYTE + 1;
			DATBUF.FLDÆPOS_PTR + FLDPTR^.LENBYTEÅ := ' ';
			END;
		POS_PTR := POS_PTR + FLD_LENÆFLDÅ;
		END;
		
	IF WRTDAT(FILE_NO,DRN,DATBUF_PTR) <> 0 THEN
		ERROR_TYPE(DRN,12);
	END;æWRITE_CUSTå
 
(*
   :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  
   		DELETE KEY VALUE FROM INDEX ROUTINE
  
   :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *)
PROCEDURE DEL_A_KEY(KEY,DRN : INTEGER);
VAR
	RET_CODE,K_FLD : INTEGER;

	BEGIN
	K_FLD := KEY_MAPÆKEYÅ;
	
	RET_CODE := DELKEY(KEY_NUMÆKEYÅ,FILE_NO,
		XLOCK,OLD_FLDÆK_FLDÅ,DRN);

	IF ERRCOD <> 0 THEN
		ERROR_TYPE(KEY,6);
	IF LOKCOD <> 0 THEN
		LOCK_TYPE(10);
	IF RET_CODE <> 1 THEN
		WARNING_TYPE(KEY,3,RET_CODE);
	
	END;æDEL_A_KEYå

(*
   :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  
   		UPDATE INDICES & DATA FILE ROUTINE
  
   :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *)

FUNCTION UPDATE(DATA_RECORD : INTEGER) : INTEGER;
VAR
	FLD,KEY : INTEGER;

	BEGIN
	IF DATA_RECORD = 0 THEN
		BEGIN
		DATA_RECORD := NEWREC(FILE_NO,XLOCK);
		IF ERRCOD <> 0 THEN
			ERROR_TYPE(0,8);
		IF LOKCOD <> 0 THEN
			LOCK_TYPE(3) ;
		END;

	UPDATE := DATA_RECORD;
	FOR KEY := 0 TO MAX_KEY DO
		BEGIN
		FLD := KEY_MAPÆKEYÅ;
		IF OLD_FLDÆFLDÅ <> NEW_FLDÆFLDÅ THEN
			ADD_A_KEY(KEY,DATA_RECORD);
		END;

	FOR FLD := 0 TO MAX_FIELD DO
		IF OLD_FLDÆFLDÅ <> NEW_FLDÆFLDÅ THEN
			BEGIN 
			WRITE_CUST(DATA_RECORD);
			EXIT;
			END;
	END;æUPDATEå

(*
   :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  
   		DELETE INDEX & DATA FILE ENTRY ROUTINE
  
   :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *)

PROCEDURE DELETE(DATA_RECORD : INTEGER);
VAR
	FLD,KEY : INTEGER;

	BEGIN
	FOR KEY := 0 TO MAX_KEY DO
		BEGIN
		FLD := KEY_MAPÆKEYÅ;
		IF OLD_FLDÆFLDÅ <> '' THEN
			DEL_A_KEY(KEY,DATA_RECORD);
		END;
	
	IF RETREC(FILE_NO,XLOCK,DATA_RECORD) <> 0 THEN
		ERROR_TYPE(DATA_RECORD,9);
	IF LOKCOD <> 0 THEN
		LOCK_TYPE(9);
	END;æDELETEå

(*
   :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  
   		NEW DATA ENTRY ROUTINE
  
   :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *)

FUNCTION NEWDAT : INTEGER;


VAR
	TMPFLD : STRINGÆ40Å;
	UNIQUE : BOOLEAN;
	TMPDAT : INTEGER;
	FLD,OP_VAL,FLD_NO : INTEGER;
	OP1 : CHAR;
	OP1_BYT : BYTE;

LABEL
	111;

	BEGIN
		FOR FLD := 0 TO MAX_FIELD DO
			OLD_FLDÆFLDÅ := '';

		CLRSCR;

		WRITELN(' ':19,'Enter New Customer Information');
		WRITELN(' ':19,'******************************');
		WRITELN;
		WRITELN;
		WRITELN(
		    '    ÆPress "RETURN" for customer # to see main menu.Å');
		WRITELN;

		FOR FLD := 0 TO MAX_FIELD DO
			BEGIN
			FLD_NO := FLD + 1;
111:
			WRITE(FLD_NO:6,' - ',FLD_NAMEÆFLDÅ:20,
				'(',FLD_LENÆFLDÅ:2,') >>');
			READLN(NEW_FLDÆFLDÅ);
			IF (FLD = KEY_MAPÆUNIQ_KEYÅ) AND (NEW_FLDÆFLDÅ = '')
			    	THEN BEGIN
				NEWDAT := STOP;
				EXIT;
				END;

			IF FLD = KEY_MAPÆUNIQ_KEYÅ THEN
				BEGIN
				NEW_FLDÆFLDÅ := CONCAT('0000',NEW_FLDÆFLDÅ);
				RIGHT(NEW_FLDÆFLDÅ,FLD_LENÆFLDÅ);
				UNIQUE := TEST_UNIQUENESS;
				END
			ELSE
				BEGIN
				TMPFLD := CONCAT(NEW_FLDÆFLDÅ,
					'                    ');
				NEW_FLDÆFLDÅ := COPY(TMPFLD,1,FLD_LENÆFLDÅ);
				UNIQUE := TRUE;
				END;

			IF üUNIQUE THEN GOTO 111;
			END;
 
	WHILE (FOR_EVER) DO
		BEGIN
		WRITELN;
		WRITELN;
		WRITELN;
		WRITELN(' ':19,'Current customer information');
		WRITELN;

		FOR FLD := 0 TO MAX_FIELD DO
			BEGIN
			FLD_NO := FLD + 1;
			WRITELN(FLD_NO:6,' - ',FLD_NAMEÆFLDÅ:20,'   ',
				NEW_FLDÆFLDÅ);
			END;


		
			OP_VAL := 0;
			WHILE (OP_VAL < 1) OR (OP_VAL > NO_FIELDS) DO
				BEGIN
				WRITELN;
				WRITELN;
				WRITELN(
'Enter S to save data, Field # to change data,');
				WRITE(
'D to delete data, or E to end input >>') ;
				READLN(OP1);
				TMPDAT := 0;
				IF (OP1 = 'S') OR (OP1 = 's') THEN
					TMPDAT := SAVE;
				IF (OP1 = 'D') OR (OP1 = 'd') THEN
					TMPDAT := DELT;
				IF (OP1 = 'E') OR (OP1 = 'e') THEN
					TMPDAT := STOP;
				IF TMPDAT <> 0 THEN
					BEGIN
					NEWDAT := TMPDAT;
					EXIT;
					END;
				OP1_BYT := OP1;
				OP_VAL := OP1_BYT - 48;
				END;
			UPDATE_FIELD(OP_VAL);
			END;
		
	END;æNEWDATå

FUNCTION OLDDAT(DRN: INTEGER) : INTEGER;

VAR
	UNIQUE : BOOLEAN;
	TMPDAT : INTEGER;
	FLD,OP_VAL,FLD_NO : INTEGER;
	OP1 : CHAR;
	OP1_BYT : BYTE;


	BEGIN

		FOR FLD := 0 TO MAX_FIELD DO
			NEW_FLDÆFLDÅ := OLD_FLDÆFLDÅ;

		CLRSCR;
 
	WHILE (FOR_EVER) DO
		BEGIN
		WRITELN;
		WRITELN;
		WRITELN;
		WRITELN(' ':19,'Current customer information');
		WRITELN;

		FOR FLD := 0 TO MAX_FIELD DO
			BEGIN
			FLD_NO := FLD + 1;
			WRITELN(FLD_NO:6,' - ',FLD_NAMEÆFLDÅ:20,'   ',
				NEW_FLDÆFLDÅ);
			END;

			OP_VAL := 0;
			WHILE (OP_VAL < 1) OR (OP_VAL > NO_FIELDS) DO
				BEGIN
				WRITELN;
				WRITELN;
				WRITELN(
'Enter C to continue scan, Field # to change data, S to save changes,');
				WRITE(
'D to delete data, B for back scan, or E to end scan >>');
				READLN(OP1);
				TMPDAT := 0;
				IF (OP1 = 'C') OR (OP1 = 'c') THEN
					TMPDAT := CONT;
				IF (OP1 = 'S') OR (OP1 = 's') THEN
					TMPDAT := SAVE;
				IF (OP1 = 'D') OR (OP1 = 'd') THEN
					TMPDAT := SET_XLOCK(OP1,DRN);
				IF (OP1 = 'B') OR (OP1 = 'b') THEN
					TMPDAT := BACK;
				IF (OP1 = 'E') OR (OP1 = 'e') THEN
					TMPDAT := STOP;
				IF TMPDAT <> 0 THEN
					BEGIN
					OLDDAT := TMPDAT;
					EXIT;
					END;
				OP1_BYT := OP1;
				OP_VAL := OP1_BYT - 48;
				END;
			UPDATE_FIELD(OP_VAL);
			
		END;
	END;æOLDDATå


FUNCTION SET_XLOCK(OP : CHAR; DRN : INTEGER) : INTEGER;
VAR
	DUMMY : CHAR;

	BEGIN
	DUMMY := 'W';
	WHILE (DUMMY = 'W') AND (SETLOK(FILE_NO,XLOCK,DRN) <>  0) DO
		BEGIN
		WRITELN;
		WRITELN('Customer update on hold due to record lock');
		WRITE(
'Enter W if you wish to wait or any other key to cancel update>>');
		READLN(DUMMY);
		IF DUMMY = 'w' THEN DUMMY := 'W';
		END;
	
	IF DUMMY = 'W' THEN
                BEGIN
		IF OP = 'S' THEN
			SET_XLOCK := SAVE
		ELSE
			SET_XLOCK := DELT;
		END
	ELSE
		SET_XLOCK := OLD_ACTION;
	END;æSET_XLOCKå


(*
   :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  
   		UPDATE DATA FIELD ROUTINE
  
   :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *)

PROCEDURE UPDATE_FIELD(FLD_NO : INTEGER);
VAR
	TMPFLD : STRINGÆ40Å;
	TEST : BOOLEAN;
	FIELD_NO : INTEGER;

	BEGIN
	FIELD_NO := FLD_NO-1;
	TEST := FALSE;

	WHILE (üTEST) DO
		BEGIN
		WRITELN;
		WRITE('Input new ',FLD_NAMEÆFIELD_NOÅ,'>>');
		READLN(NEW_FLDÆFIELD_NOÅ);
	
		IF FIELD_NO = KEY_MAPÆUNIQ_KEYÅ THEN
			BEGIN
			NEW_FLDÆFIELD_NOÅ := CONCAT('0000',NEW_FLDÆFIELD_NOÅ);
			RIGHT(NEW_FLDÆFIELD_NOÅ,FLD_LENÆFIELD_NOÅ);
			END
		ELSE
			BEGIN
			TMPFLD := CONCAT(NEW_FLDÆFIELD_NOÅ,
				'                    ');
			NEW_FLDÆFIELD_NOÅ := COPY(TMPFLD,1,FLD_LENÆFIELD_NOÅ);
			END;

		IF (FIELD_NO = KEY_MAPÆUNIQ_KEYÅ) AND (NEW_FLDÆFIELD_NOÅ <>
		    OLD_FLDÆFIELD_NOÅ) THEN
			TEST := TEST_UNIQUENESS
		ELSE
			TEST := TRUE;
		END;
	END;æUPDATE_FIELDå


(*
   :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  
   		CUST # UNIQUENESS TEST ROUTINE
  
   :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *)

FUNCTION TEST_UNIQUENESS : BOOLEAN;
VAR
	TEMP : INTEGER;
	TEST : FLDSTR;

	BEGIN
	TEST := NEW_FLDÆKEY_MAPÆUNIQ_KEYÅÅ;
	TEMP := GETKEY(UNIQ_KEY,0,NLOCK,TEST);

	IF LOKCOD <> 0 THEN
		LOCK_TYPE(12);
	IF TEMP = 0 THEN
		TEST_UNIQUENESS := TRUE
      	ELSE
		BEGIN
		WRITELN;
		WRITELN(' *** Already Assigned ***');
		WRITELN;
		TEST_UNIQUENESS := FALSE;
		END;
	END;æTEST_UNIQUENESSå


(*
   :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  
   		RIGHT STRING ROUTINE
  
   :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *)

PROCEDURE RIGHT(VAR FLDVAL : FLDSTR; FLDLEN : INTEGER);

	BEGIN
	FLDVAL := COPY(FLDVAL,LENGTH(FLDVAL)-FLDLEN+1,FLDLEN);
	END;æRIGHTå

(*
		END OF UTILITY FUNCTIONS
 
   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 *)



(*
   ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  
  	 SET-UP DATABASE FIELD & KEY DESCRIPTORS
  
   ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *)
BEGIN
NO_FIELDS := MAX_FIELD + 1;

FLD_NAMEÆ0Å := 'Customer Number';
FLD_LENÆ0Å := 4;
FLD_NAMEÆ1Å := 'First Name';
FLD_LENÆ1Å := 16;
FLD_NAMEÆ2Å := 'Last Name';
FLD_LENÆ2Å := 20;
FLD_NAMEÆ3Å := 'Street Address';
FLD_LENÆ3Å := 20;
FLD_NAMEÆ4Å := 'City';
FLD_LENÆ4Å := 20;
FLD_NAMEÆ5Å := 'State';
FLD_LENÆ5Å := 2;
FLD_NAMEÆ6Å := 'Zipcode';
FLD_LENÆ6Å := 9;
FLD_NAMEÆ7Å := 'Customer Status';
FLD_LENÆ7Å := 8;



KEY_LENÆ0Å:=10;
KEY_TYPEÆ0Å:=0;
KEY_MAPÆ0Å:=2 ;	(*   KEY 0 = LAST NAME		*)
KEY_LENÆ1Å:=11;
KEY_TYPEÆ1Å:=0;
KEY_MAPÆ1Å:=6 ;	(*   KEY 1 = ZIPCODE		*)
KEY_LENÆ2Å:=4 ;
KEY_TYPEÆ2Å:=0;
KEY_MAPÆ2Å:=0 ;	(*   KEY 2 = CUST NUMBER	*)

UNIQ_KEY := 2 ;	(*  USED IN TEST OF UNIQUENESS	*)

FOR KEY := 0 TO MAX_KEY DO
	BEGIN
	IF KEY = UNIQ_KEY THEN
		KEY_DUPÆKEYÅ := NO
	ELSE
		KEY_DUPÆKEYÅ := YES;

	KEY_NAMEÆKEYÅ := FLD_NAMEÆKEY_MAPÆKEYÅÅ;
	END;

IDX_NAMEÆ0Å := 'NAME.IDX';
IDX_NAMEÆ1Å := 'ZIPC.IDX';
IDX_NAMEÆ2Å := 'NUMB.IDX';

NLOCK := 0;	(* IGNORE LOCKS			*)
SLOCK := 1;	(* SHARED RECORD LOCK		*)
XLOCK := 2;	(* EXCLUSIVE RECORD LOCK	*)
SFILE := 3;	(* SHARED FILE LOCK		*)
XFILE := 4;	(* EXCLUSIVE FILE LOCK		*)
RLOCK := 5;	(* RELEASE SLOCK) OR (XLOCK	*)


(*  
   ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  
   		INITIALIZE INDEX FILES
  
   ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *)

	SET_LENGTH := '12345678901';
	IDX_KEY := SET_LENGTH;
	SPACE :=      '           ';

(*
	SET TERMINAL TO -1 FOR AUTOMATIC ASSIGNMENT BY ACCESS MANAGER
 *)

	TERMINAL := -1;
	TRAP_ERRORS := YES;
	TIME_OUT_TEST_DELAY := 2;  (* APPROXIMATELY 2 SECONDS *)
	TERMINAL := INTUSR(TERMINAL,TRAP_ERRORS,TIME_OUT_TEST_DELAY);
	IF ERRCOD <> 0 THEN
		ERROR_TYPE(0,14);

	NO_BUFFERS := 5;
	NO_NODE_SECTORS := 4;
	NO_DATA_FILES := 1;
	NO_KEYZ := MAX_KEY + 1;

	IF SETUP(NO_BUFFERS,NO_KEYZ,NO_NODE_SECTORS,NO_DATA_FILES) <> 0 THEN
		BEGIN
		WRITELN('Illegal SETUP Parameters');
		EXIT;
		END;

	FOR KEY := 0 TO MAX_KEY DO
		BEGIN
		KEY_NUMÆKEYÅ := OPNIDX(-1,IDX_NAMEÆKEYÅ,
			KEY_LENÆKEYÅ, KEY_TYPEÆKEYÅ,KEY_DUPÆKEYÅ);
		IF ERRCOD <> 0 THEN
			ERROR_TYPE(KEY,1);
		END;

(*
   ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  
   		INITIALIZE DATA FILE
  
   ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *)

	FILE_NO := -1;
	RECORD_LENGTH := 100;
	FILNAME := 'CUSTOMER.DAT';
	FILE_NO := OPNDAT(FILE_NO,SFILE,FILNAME,RECORD_LENGTH);
	IF ERRCOD <> 0 THEN
		ERROR_TYPE(0,10);
	IF LOKCOD <> 0 THEN
		LOCK_TYPE(1);

(*
	CUST_REC IS THE DATA FILE BUFFER AREA
 *)

	DATBUF_PTR := ADDR(DATBUF);

(*
   ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  
   		BEGIN DATABASE OPERATION
  
   ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *)

	NULL_BYT := 0;
	NULL_CHR := NULL_BYT;

	FOR_EVER := TRUE;

	WHILE (FOR_EVER) DO
		DATA_BASE;
	EXIT;
END.
«eof»