{THIS PROGRAM FIRST ALPHABETIZES THE NAME AND ADDRESS FILE
  THEN CREATES A FILE CONTAINING THE FIRST AND LAST
  RECORD NUMBER OF THE NAME AND ADDRESS FILE, FOR EACH
  LETTER OF THE ALPHABET.  THIS LATTER FILE (WHICH HAS
  AN EXTENSION OF .ALP  IS THEN USED BY THE  NAD
  PROGRAM TO QUICKLY FIND A DESIRED NAME WITHIN THE FILE.

                       WRITTEN BY:  CRAIG RUDLIN
                                    202 OVERLOOK ROAD
                                    RICHMOND, VA. 23229


       THE SORT ROUTINE IS ADAPTED FROM THE LISTING IN
       'PROGRAMMING IN PASCAL' BY PETER GROGONO.


  VERSION 1.5}





PROGRAM SORT_AND_ALPHABETIZE; {$P}
TYPE
                       NAME=ARRAY[1..128] OF CHAR;

       ALPHABETT =     RECORD
                       START:INTEGER;
                       FINISH:INTEGER;
                       END;

FI=FILE OF NAME;
FO=FILE OF ALPHABETT;
$STRING14 = STRING 14;


VAR
FIN,FOUT:FI;
FALP:FO;
INFORMATION:NAME;
POINTERS:ALPHABETT;
COUNTER,LETTER,RECORD_NUMBER,NUMBER_OF_RECORDS,LAST_RECORD_NUMBER:INTEGER;
ALPFILE,FILENAM:$STRING14;

PROCEDURE CLEAR_SCREEN;
BEGIN
WRITE(CHR(27),'*',CHR(0),CHR(0),CHR(0),CHR(0));
END;


PROCEDURE ENTER_FILE_NAME;
VAR
ERROR:BOOLEAN;
BEGIN
REPEAT
ERROR:=FALSE;
CLEAR_SCREEN;
WRITELN;
WRITE('ENTER THE FILE NAME AS:  DRIVE: NAME. EXTENSION  ');
READ(FILENAM);
RESET(FILENAM,FIN);

IF EOF(FIN) THEN
BEGIN;
WRITELN;
WRITELN ('FILE NOT FOUND. PLEASE RE-ENTER.');
ERROR:=TRUE;
END;

UNTIL ERROR = FALSE;
END; {OF PROCEDURE ENTER FILE NAME}


PROCEDURE NUMBER_RECORDS(FILENAM:$STRING14);
TYPE
       MAILING = RECORD
               NAME_ADDRESS:ARRAY[1..124] OF CHAR;
               ACCT_NUMBER:ARRAY[1..4] OF CHAR;
               END;
XFI = FILE OF MAILING;

VAR
INFORMATION:MAILING;
FIN:XFI;
BEGIN

RESET(FILENAM,FIN);
WITH INFORMATION DO
BEGIN

READ(FIN:1,INFORMATION);
NUMBER_OF_RECORDS:=(((ORD(ACCT_NUMBER[1])-48)*1000)+
               ((ORD(ACCT_NUMBER[2])-48)*100)+
               ((ORD(ACCT_NUMBER[3])-48)*10)+
               ((ORD(ACCT_NUMBER[4])-48)*1));
END; {OF WITH}
END; {OF PROCEDURE}


PROCEDURE XPOINTERS (FILENAM:$STRING14);
VAR
I:INTEGER;


BEGIN
LAST_RECORD_NUMBER:=2;
RECORD_NUMBER:=2;
LETTER:=65;
I:=1;

WHILE FILENAM[I] <> '.' DO
BEGIN
ALPFILE[I]:=FILENAM[I];
I:=I+1;
END;
ALPFILE[I]:='.';
ALPFILE[I+1]:='A';
ALPFILE[I+2]:='L';
ALPFILE[I+3]:='P';
IF (I+4) < 14 THEN
BEGIN
I:=I+4;
WHILE I < 15 DO
BEGIN
ALPFILE[I]:=' ';
I:=I+1;
END;
END;

REWRITE(ALPFILE,FALP);

       RESET(FILENAM,FIN);

       REPEAT
       READ(FIN:RECORD_NUMBER,INFORMATION);
       WHILE (ORD(INFORMATION[1]) = LETTER) AND
             (RECORD_NUMBER < NUMBER_OF_RECORDS + 1)  DO
               BEGIN
               RECORD_NUMBER:=RECORD_NUMBER+1;
               READ(FIN:RECORD_NUMBER,INFORMATION);
               END;

       WITH POINTERS DO
       BEGIN
       START:=LAST_RECORD_NUMBER;
       FINISH:=RECORD_NUMBER;
       COUNTER:=LETTER-64;
       WRITE(FALP:COUNTER,POINTERS);
       LAST_RECORD_NUMBER:=RECORD_NUMBER;
       WRITELN('LETTER= ',CHR(COUNTER+64):2,'   START= ',START:3,
                  '   FINISH= ',FINISH:3,
       '   # RECS WITH THIS LETTER= ',(FINISH-START):3);
       END;

LETTER:=LETTER+1;

       UNTIL LETTER > 90;

END; {END OF PROCEDURE POINTERS}


PROCEDURE SORT_FILE (FILENAM:$STRING14);
CONST
MAXLENGTH = 250;

TYPE
INDEX = 1..MAXLENGTH;
ROWTYPE = ARRAY[INDEX] OF NAME;

VAR
INROW: ROWTYPE;
COUNT:0..MAXLENGTH;
IX:INDEX;
XX:INTEGER;


PROCEDURE SORT (VAR ROW:ROWTYPE; LENGTH:INDEX);
VAR
JUMP,M,N:INTEGER;
TEMP:NAME;
ALLDONE:BOOLEAN;

BEGIN
JUMP:=LENGTH;
WHILE JUMP > 1 DO
BEGIN
JUMP:=JUMP  DIV 2;
REPEAT
ALLDONE:=TRUE;
FOR M:= 1 TO LENGTH-JUMP DO
BEGIN
N:=M + JUMP;
IF ROW[M] > ROW[N] THEN
BEGIN
TEMP:=ROW[M];
ROW[M]:=ROW[N];
ROW[N]:=TEMP;
ALLDONE:=FALSE;
END;
END; {FOR}
UNTIL ALLDONE = TRUE;
END; {WHILE}
END; {SORT}

BEGIN {OF PROCEDURE SORT_FILE}
RESET(FILENAM,FIN);
COUNT:=1;
FOR XX:= 1 TO NUMBER_OF_RECORDS DO
BEGIN
READ(FIN:XX,INROW[COUNT]);
IF COUNT < NUMBER_OF_RECORDS THEN COUNT:=COUNT +1;
END;

IF COUNT > 0 THEN
BEGIN
SORT(INROW,COUNT);
FOR IX:= 1 TO COUNT DO
WRITE(FIN:IX,INROW[IX]);
END;


END; {END OF PROCEDURE SORT}


BEGIN  {MAIN}
ENTER_FILE_NAME;
NUMBER_RECORDS(FILENAM);
WRITELN('NUMBER OF RECORDS IN FILE ',FILENAM, ' = ',NUMBER_OF_RECORDS);
SORT_FILE(FILENAM);
XPOINTERS(FILENAM);
END.