Program dbTest;
{컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴�
  This program creates a Phonebook file from an ASCII fixed length
  format text file.  The Text file must be in the same format as the
  records: Name (20 char);
           Phone(27 char);
           FAX  (27 char);
           Polling Password ( 8 char);

  Both phone numbers may have the following characters ONLY:
    0..9    ,;  ()    -
  Spaces may fill after the number but should not be included in the
  number itself.  In particular the folling are illegal!
  408 434-9701      ; illegal space after 408
  (408) 434-9701    ; illegal space after (408)
  408/434-9701      ; illegal /
  [408]434-9701     : illegal []
읕컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴�}

Uses Ascii, CFAX;

{ TpString is used procedure ParseRecord to modify string after it is
parsed.  It only uses two functions from the Unit, but I like them and
they are fast.  Re-Write them if you must or buy Turbo Power's Turbo
Professional 5.0.  }


TYPE

{ This describes a name record for working storage.  It will be
implemented as a linked list. }
  InRecPtr = ^InRec;
  InRec = RECORD
    Name     : NameStr;
    CAMPhone : PhoneStr;
    FAXPhone : PhoneStr;
    PollPWD  : PollStr;
    Next     : InRecPtr
  END;

CONST
{컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴커
This section defines head and tail sentinals for linked list usage.
Although this technique uses a little more memory, it sure makes coding
linked lists a LOT easier.
읕컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴}

  ListHead  : InRec = ( Name   : '^A';
                      CAMPhone : '';
                      FAXPhone : '^A';
                      PollPWD  : '';
                      Next     : Nil  );

  ListTail  : InRec = ( Name   : '~~~~~~~~~~~~~~~~~~~';
                      CAMPhone : '~~~~~~~~~~~~~~~~~~~~~~~~~~';
                      FAXPhone : '~~~~~~~~~~~~~~~~~~~~~~~~~~';
                      PollPWD  : '~~~~~~~~';
                      Next     : Nil  );

  LASTNAME  =  '~~~~~~~~~~~~~~~~~~~';

VAR
  InputFile  : SDFile;
  OutputFile : PhoneBook;
  ListIR     : InRecPtr;
  IRHead     : InRecPtr;
  IRTail     : InRecPtr;
  InFileName : FNType;
  p          : Pointer;



PROCEDURE AddRecord(NewPtr : InRecPtr;
                    VAR ListIR : InRecPtr );
VAR
  CurPtr,
  NxtPtr   : InRecPtr;

BEGIN
  CurPtr := ListIR;
  NxtPtr := ListIR^.Next;
  While NewPtr^.Name > NxtPtr^.Name DO
    Begin
      CurPtr := NxtPtr;
      NxtPtr := NxtPtr^.Next;
    End;
  NewPtr^.Next := NxtPtr;
  CurPtr^.Next := NewPtr;
END;


PROCEDURE ReadInput(Var RecCount : Word);

VAR
  TextRec  : SDFRec;
  InRecord : InRecPtr;
  p        : Pointer;

BEGIN
  New(IRHead);
  IRHead^ := ListHead;
  ListIR  := IRHead;
  New(IRHead^.Next);
  IRHead^.Next^ := ListTail;
  SDFCount := 0;
  While Not EOF(InputFile) Do Begin
    TextRec := GetSDF(InputFile);
    New(InRecord);
    ParseSDF(InRecord^.Name,
             InRecord^.CamPhone,
             InRecord^.FaxPhone,
             InRecord^.PollPwd,
             TextRec);
    AddRecord(InRecord, ListIR);
    Inc(SDFCount);
    Write(SDFCount:3, ' lines read.', ^M);
  End;
  WriteLn;
END;


PROCEDURE MakePBook;

CONST
  ok = True;

VAR
  CurPtr,
  NxtPtr   : InRecPtr;
  CntByte  : Byte;
  Error    : Integer;
  PBRecord : PBRec;     { PBRec defined in CFAX unit interface }

BEGIN
  CurPtr := ListIR;
  NxtPtr := ListIR^.Next;
  RecCount := SDFCount;
  If not WritePBHdr(OutputFile, RecCount) then begin
    WriteLn;
    WriteLn( 'Error writing the phonebook header' );
    Halt;
  End;
  While NxtPtr^.Name < LASTNAME DO
    Begin
      CurPtr := NxtPtr;
      NxtPtr := NxtPtr^.Next;
      Write(CurPtr^.Name);
      WriteLn(CurPtr^.FAXPhone);
      PBRecord.Name     := CurPtr^.Name;
      PBRecord.CAMPhone := CurPtr^.CamPhone;
      PBRecord.FAXPhone := CurPtr^.FaxPhone;
      PBRecord.PollPWD  := CurPtr^.PollPwd;
      PutPBRec(OutputFile, PBRecord);
    End;
END;


PROCEDURE OpenFiles;

VAR
  IRError, PBError : Integer;

BEGIN
  If ParamCount < 1 Then
     Begin
       WriteLn( 'You must supply the name of the data file!');
       Halt
     End
    Else InFileName := ParamStr(1);
  RecCount := 0;
  SDFCount := 0;
  IRError := OpenSDF(InputFile, InFileName);
  IF ( IRError > 0 )
    then begin
      WriteLn;
      WriteLn('Error', IRError, ' opening ', InFileName, ';  Program Halted');
      WriteLn('Please write down the above line!');
      exit;
    end;
  PBError := OpenPB(OutputFile, 'DIALBOOK.DIR');
  IF PBError > 0 then
    begin
      WriteLn('Error ', PBError, ' opening DIALBOOK.DIR;  Program Halted');
      halt;
    end;
END;


PROCEDURE CloseFiles;

BEGIN
  CloseSDF( InputFile );
  ClosePB( OutputFile );
END;


BEGIN
  OpenFiles;
  Mark(p);
  ReadInput(RecCount);
  MakePBook;
  Release(p);
  CloseFiles;
END.
