Browse Source

* simplified version of SeekEof for improved TP/BP/Delphi compatibility by Andrey 'Croco' Stolyarov as fix for #37716, plus a new test for testing the compatibility

git-svn-id: trunk@46946 -
Tomas Hajny 4 years ago
parent
commit
a71f87357d
3 changed files with 73 additions and 49 deletions
  1. 1 0
      .gitattributes
  2. 0 49
      rtl/inc/text.inc
  3. 72 0
      tests/test/units/system/tseekeof.pp

+ 1 - 0
.gitattributes

@@ -16101,6 +16101,7 @@ tests/test/units/system/tresb.res -text
 tests/test/units/system/tresext.pp svneol=native#text/plain
 tests/test/units/system/trnd1.pp svneol=native#text/pascal
 tests/test/units/system/tround.pp svneol=native#text/plain
+tests/test/units/system/tseekeof.pp svneol=native#text/plain
 tests/test/units/system/tseg.pp svneol=native#text/plain
 tests/test/units/system/tsetstr.pp svneol=native#text/plain
 tests/test/units/system/tsetstr2.pp svneol=native#text/plain

+ 0 - 49
rtl/inc/text.inc

@@ -440,11 +440,6 @@ End;
 
 
 Function SeekEof (Var t : Text) : Boolean;
-var
-  oldfilepos : Int64;
-  oldbufpos, oldbufend : SizeInt;
-  reads: longint;
-  isdevice: boolean;
 Begin
   If (InOutRes<>0) then
    exit(true);
@@ -456,33 +451,12 @@ Begin
       InOutRes:=103;
      exit(true);
    end;
-  { try to save the current position in the file, seekeof() should not move }
-  { the current file position (JM)                                          }
-  oldbufpos := TextRec(t).BufPos;
-  oldbufend := TextRec(t).BufEnd;
-  reads := 0;
-  oldfilepos := -1;
-  isdevice := Do_IsDevice(TextRec(t).handle);
   repeat
     If TextRec(t).BufPos>=TextRec(t).BufEnd Then
      begin
-       { signal that the we will have to do a seek }
-       inc(reads);
-       if not isdevice and
-          (reads = 1) then
-         begin
-           oldfilepos := Do_FilePos(TextRec(t).handle) - TextRec(t).BufEnd;
-           if InOutRes <> 0 then
-             isdevice := true;
-           InOutRes:=0;
-         end;
        FileFunc(TextRec(t).InOutFunc)(TextRec(t));
        If TextRec(t).BufPos>=TextRec(t).BufEnd Then
         begin
-          { if we only did a read in which we didn't read anything, the }
-          { old buffer is still valid and we can simply restore the     }
-          { pointers (JM)                                               }
-          dec(reads);
           SeekEof := true;
           break;
         end;
@@ -504,29 +478,6 @@ Begin
     end;
    inc(TextRec(t).BufPos);
   until false;
-  { restore file position if not working with a device }
-  if not isdevice then
-    { if we didn't modify the buffer, simply restore the BufPos and BufEnd  }
-    { (the latter because it's now probably set to zero because nothing was }
-    {  was read anymore)                                                    }
-    if (reads = 0) then
-      begin
-        TextRec(t).BufPos:=oldbufpos;
-        TextRec(t).BufEnd:=oldbufend;
-      end
-    { otherwise return to the old filepos and reset the buffer }
-    else
-      begin
-        InOutRes := 0;
-        do_seek(TextRec(t).handle,oldfilepos);
-        if InOutRes = 0 then
-          begin
-            FileFunc(TextRec(t).InOutFunc)(TextRec(t));
-            TextRec(t).BufPos:=oldbufpos;
-          end
-        else
-          InOutRes:=0;
-      end;
 End;
 
 

+ 72 - 0
tests/test/units/system/tseekeof.pp

@@ -0,0 +1,72 @@
+program TSeekEof;
+{$DEFINE DEBUG}
+{$I+}
+
+{$IFNDEF FPC}
+uses
+ Dos;
+{$ENDIF FPC}
+
+const
+ Line1 = '  123 23 45   ';
+ Line2 = '                                            '#9#9#9'              ';
+
+var
+ T: text;
+ F: file;
+ B: byte;
+ SeekEofReached: boolean;
+
+begin
+ Assign (T, 'tseekeof.txt');
+ Assign (F, 'tseekeof.txt');
+ Rewrite (T);
+ WriteLn (T, Line1);
+ WriteLn (T, Line2);
+ WriteLn (T, Line2);
+ WriteLn (T, Line2);
+ WriteLn (T, Line2);
+ Close (T);
+ TextRec (T).BufSize := 5;
+(* Buffer size decreased to make sure that the buffer needs to be read more often *)
+ Reset (T);
+{$IFDEF DEBUG}
+ WriteLn ('Before: BufPos = ', TextRec (T).BufPos, ', BufEnd = ', TextRec (T).BufEnd);
+{$ENDIF DEBUG}
+ SeekEofReached := SeekEof (T);
+{$IFDEF DEBUG}
+ WriteLn ('After: BufPos = ', TextRec (T).BufPos, ', BufEnd = ', TextRec (T).BufEnd);
+{$ENDIF DEBUG}
+ while not (SeekEofReached) do
+  begin
+   Read (T, B);
+{$IFDEF DEBUG}
+   WriteLn ('Read: ', B);
+{$ENDIF DEBUG}
+{$IFDEF DEBUG}
+ WriteLn ('Before: BufPos = ', TextRec (T).BufPos, ', BufEnd = ', TextRec (T).BufEnd);
+{$ENDIF DEBUG}
+   SeekEofReached := SeekEof (T);
+{$IFDEF DEBUG}
+ WriteLn ('After: BufPos = ', TextRec (T).BufPos, ', BufEnd = ', TextRec (T).BufEnd);
+{$ENDIF DEBUG}
+  end;
+{$IFDEF DEBUG}
+ WriteLn ('SeekEof reached');
+{$ENDIF DEBUG}
+ if not (Eof (T)) then
+  begin
+{$IFDEF DEBUG}
+   WriteLn ('File not at EOF after SeekEof!');
+{$ENDIF DEBUG}
+   Close (T);
+   Erase (F);
+   Halt (1);
+  end
+ else
+{$IFDEF DEBUG}
+  WriteLn ('File at EOF after SeekEof');
+{$ENDIF DEBUG}
+ Close (T);
+ Erase (F);
+end.