Press enter to see results or esc to cancel.

Dealing With Source Files

For each source file Turbo Pascal keeps a record with essential data like file handle, file name, current line number, current position, conditional compilation If level, etc.This way it can always reurn to the right position in previous source file (when include files are used). After the source file has changed Turbo Pascal displays compilation progress showing current module name and source line number.

Type PFileStructure = ^TFileStructure;
     TFileStructure = Record
                       CurrentPosition: Word;      { 00 }
                       CurrentLineNumber: Word;    { 02 }
                       FilePosition: Longint;      { 04 }
                       Handle: Word;               { 08 }
                       CurrentLineLength: Word;    { 0A }
                       FileRecordOffset: Word;     { 0C }
                       LineCounter: Word;          { 0E }
                       IF_Level: Word;             { 10 }
                       Name: Str64Rec;             { 12 13..XX, Len + NameChars + #0, Len = Length (+ NameChars + #0) }
                     end;

Procedure OpenSourceFile (UsedFilesRecord: PUsedFilesBlockRecord; FileName: PChar);
Var NewFileStructure: PFileStructure;
    NameLength: Byte;
begin
  If ProgramBlockCompilation then Error (IncludeFilesAreNotAllowedHere);
  NameLength := StrLen (FileName) + 1;
  NewFileStructure := Ptr (Seg (CurrentSourceFile^), Ofs (CurrentSourceFile^) - NameLength - 19);
  If Ofs (NewFileStructure^) < Ofs (StartOfSourceFileStructures^) then Error (TooManyFiles);
  NewFileStructure^.FileRecordOffset := Ofs (UsedFilesRecord^);
  NewFileStructure^.Name.Len := NameLength;
  StrCopy (@NewFileStructure^.Name.Chr, FileName);

  If FileRec (SourceFile).Handle <> 0 then Close (SourceFile);

  OpenFile (SourceFile, FileName);
  NewFileStructure^.Handle := FileRec (SourceFile).Handle;
  NewFileStructure^.CurrentPosition := Ofs (CurrentLine^);
  ErrorSourcePosition := CurrentLine;
  NewFileStructure^.CurrentLineNumber := 1;
  NewFileStructure^.FilePosition := 0;
  NewFileStructure^.CurrentLineLength := 0;
  NewFileStructure^.IF_Level := 0;

  CurrentLine^ := #0;
  FileBufferPtr := nil;
  FileBufferEnd := nil;
  CurrentSourceFile := NewFileStructure;
  WriteCompilationProgress (CurrentSourceFile);
end;

Procedure ReturnToPreviousSourceFile;
Var SavedLastLinePosition: Word;
begin
  If ProgramBlockCompilation or (CurrentSourceFile = FirstSourceFile) then Error (UnexpectedEndOfFile);
  If CurrentSourceFile^.IF_Level <> 0 then Error (ENDIF_directiveMissing);
  WritelnModuleNameWithCurrentLineNumber (CurrentSourceFile);
  Close (SourceFile);
  Inc (PChar (CurrentSourceFile), CurrentSourceFile^.Name.Len + 19);
  If CurrentSourceFile <> @EndOfFileStructure then
    With CurrentSourceFile^ do
      begin
        SavedLastLinePosition := CurrentPosition;
        CurrentPosition := Ofs (CurrentLine^);
        ErrorSourcePosition := CurrentLine;
        CurrentLine^ := #0;
        FileBufferPtr := nil;
        FileBufferEnd := nil;
        OpenFile (SourceFile, @Name.Chr);
        Handle := FileRec (SourceFile).Handle;
        Seek (SourceFile, FilePosition);
        If ReadNextLine <> CurrentLineLength then Error (UnexpectedEndOfFile);
        CurrentPosition := SavedLastLinePosition;
        ErrorSourcePosition := PChar (Ptr (Seg (ErrorSourcePosition^), SavedLastLinePosition));
      end;
  WriteCompilationProgress (CurrentSourceFile);
end;