diff options
| -rw-r--r-- | libraries/std/textio-body.vhdl | 8 | ||||
| -rw-r--r-- | src/grt/grt-files.adb | 35 | ||||
| -rw-r--r-- | src/grt/grt-files_operations.adb | 45 | 
3 files changed, 65 insertions, 23 deletions
| diff --git a/libraries/std/textio-body.vhdl b/libraries/std/textio-body.vhdl index 235da706a..8ea3dc789 100644 --- a/libraries/std/textio-body.vhdl +++ b/libraries/std/textio-body.vhdl @@ -428,16 +428,14 @@ package body textio is      loop        untruncated_text_read (f, str, len);        exit when len = 0; -      if str (len) = LF or str (len) = CR then +      if str (len) = LF then          --  LRM 14.3          --  The representation of the line does not contain the representation          --  of the end of the line.          is_eol := true;          len := len - 1; -        --  End of line is any of LF/CR/CR+LF/LF+CR. -        if len > 0 and (str (len) = LF or str (len) = CR) then -          len := len - 1; -        end if; +        --  End of line is any of LF/CR/CR+LF.  This is now handled +        --  by untruncated_text_read because we need to do a look-ahead.        elsif endfile (f) then          is_eol := true;        else diff --git a/src/grt/grt-files.adb b/src/grt/grt-files.adb index 826e9b05f..5d214052e 100644 --- a/src/grt/grt-files.adb +++ b/src/grt/grt-files.adb @@ -34,6 +34,10 @@ pragma Elaborate_All (Grt.Table);  package body Grt.Files is     subtype C_Files is Grt.Stdio.FILEs; +   --  The end of lines +   C_LF : constant int := 10;   --  \n +   C_CR : constant int := 13;   --  \r +     Auto_Flush : constant Boolean := False;     type File_Entry_Type is record @@ -470,22 +474,37 @@ package body Grt.Files is     is        Stream : C_Files;        Max_Len : int; +      C : int; +      L : Ghdl_Index_Type;     begin        Stream := Get_File (File);        Check_Read (File, True);        Max_Len := int (Str.Bounds.Dim_1.Length); -      if fgets (Str.Base (0)'Address, Max_Len, Stream) = Null_Address then -         Internal_Error ("ghdl_untruncated_text_read: end of file"); -      end if; -      --  Compute the length. -      for I in Ghdl_Index_Type loop -         if Str.Base (I) = NUL then -            Len.all := Std_Integer (I); -            exit; +      --  Read at most LEN characters, stop at EOL. +      L := 0; +      for I in 1 .. Max_Len loop +         C := fgetc (Stream); +         exit when C < 0; +         --  Be nice with DOS files: handle CR/CR+LF/LF. +         --  Note: LF+CR is not handled, so that on unix we don't need +         --  to read the next line. +         --  Always return LF as end of line. +         if C = C_CR then +            C := fgetc (Stream); +            if C > 0 and C /= C_LF then +               C := ungetc (C, Stream); +               pragma Assert (C >= 0); +            end if; +            C := C_LF;           end if; +         Str.Base (L) := Character'Val (C); +         L := L + 1; +         exit when C = C_LF;        end loop; + +      Len.all := Std_Integer (L);     end Ghdl_Untruncated_Text_Read;     procedure File_Close (File : Ghdl_File_Index; Is_Text : Boolean) diff --git a/src/grt/grt-files_operations.adb b/src/grt/grt-files_operations.adb index c7770b5f3..b1f504dc9 100644 --- a/src/grt/grt-files_operations.adb +++ b/src/grt/grt-files_operations.adb @@ -31,6 +31,10 @@ pragma Elaborate_All (Grt.Table);  package body Grt.Files_Operations is     subtype C_Files is Grt.Stdio.FILEs; +   --  The end of lines +   C_LF : constant int := 10;   --  \n +   C_CR : constant int := 13;   --  \r +     Auto_Flush : constant Boolean := False;     type File_Entry_Type is record @@ -518,7 +522,7 @@ package body Grt.Files_Operations is              Str.Base (I) := Character'Val (C);           end if;           --  End of line is '\n' or LF or character # 10. -         if C = 10 then +         if C = C_LF then              Length := Std_Integer (I + 1);              Status := Op_Ok;              return; @@ -534,7 +538,8 @@ package body Grt.Files_Operations is                                           Status : out Op_Status)     is        Stream : C_Files; -      Max_Len : int; +      L : Natural; +      C : int;     begin        Get_File (File, Stream, Status);        if Status /= Op_Ok then @@ -545,15 +550,35 @@ package body Grt.Files_Operations is           return;        end if; -      Max_Len := int (Len); -      if fgets (To_Address (Buf), Max_Len, Stream) = Null_Address then -         Status := Op_End_Of_File; -         return; -      end if; - -      --  Compute the length. -      Len := Std_Integer (strlen (Buf)); +      --  Default status.        Status := Op_Ok; + +      --  Read at most LEN characters, stop at EOL. +      L := 0; +      for I in 1 .. Len loop +         C := fgetc (Stream); +         if C < 0 then +            Status := Op_End_Of_File; +            exit; +         end if; +         --  Be nice with DOS files: handle CR/CR+LF/LF. +         --  Note: LF+CR is not handled, so that on unix we don't need +         --  to read the next line. +         --  Always return LF as end of line. +         if C = C_CR then +            C := fgetc (Stream); +            if C > 0 and C /= C_LF then +               C := ungetc (C, Stream); +               pragma Assert (C >= 0); +            end if; +            C := C_LF; +         end if; +         L := L + 1; +         Buf (L) := Character'Val (C); +         exit when C = C_LF; +      end loop; + +      Len := Std_Integer (L);     end Ghdl_Untruncated_Text_Read;     procedure File_Close | 
