aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/grt/grt-files.adb35
-rw-r--r--src/grt/grt-files_operations.adb45
2 files changed, 62 insertions, 18 deletions
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