diff mbox

[Ada] Spurious End_Error with Get_Line on strings without line terminators

Message ID 20160427123107.GA27989@adacore.com
State New
Headers show

Commit Message

Arnaud Charlet April 27, 2016, 12:31 p.m. UTC
This patch fixes a spurious End_Error raised by Text_IO.Get_Line, when the
input line has 499 or 500 characters and does not contain a line terminator.

No short example available.

Tested on x86_64-pc-linux-gnu, committed on trunk

2016-04-27  Ed Schonberg  <schonberg@adacore.com>

	* a-textio.adb (Get_Line function): Handle properly the case of
	a line that has the same length as the buffer (or a multiple
	thereof) and there is no line terminator.
	* a-tigeli.adb (Get_Line procedure): Do not store an end_of_file
	in the string when there is no previous line terminator and we
	need at most one additional character.
diff mbox

Patch

Index: a-textio.adb
===================================================================
--- a-textio.adb	(revision 235481)
+++ a-textio.adb	(working copy)
@@ -6,7 +6,7 @@ 
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---          Copyright (C) 1992-2015, Free Software Foundation, Inc.         --
+--          Copyright (C) 1992-2016, Free Software Foundation, Inc.         --
 --                                                                          --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
@@ -704,9 +704,6 @@ 
    end Get_Line;
 
    function Get_Line (File : File_Type) return String is
-      Buffer : String (1 .. 500);
-      Last   : Natural;
-
       function Get_Rest (S : String) return String;
       --  This is a recursive function that reads the rest of the line and
       --  returns it. S is the part read so far.
@@ -732,12 +729,19 @@ 
          begin
             if Last < Buffer'Last then
                return R;
+
             else
                return Get_Rest (R);
             end if;
          end;
       end Get_Rest;
 
+      --  Local variables
+
+      Buffer : String (1 .. 500);
+      ch     : int;
+      Last   : Natural;
+
    --  Start of processing for Get_Line
 
    begin
@@ -745,6 +749,22 @@ 
 
       if Last < Buffer'Last then
          return Buffer (1 .. Last);
+
+      --  If the String has the same length as the buffer, and there is no end
+      --  of line, check whether we are at the end of file, in which case we
+      --  have the full String in the buffer.
+
+      elsif Last = Buffer'Last then
+         ch := Getc (File);
+
+         if ch = EOF then
+            return Buffer;
+
+         else
+            Ungetc (ch, File);
+            return Get_Rest (Buffer (1 .. Last));
+         end if;
+
       else
          return Get_Rest (Buffer (1 .. Last));
       end if;
Index: a-tigeli.adb
===================================================================
--- a-tigeli.adb	(revision 235481)
+++ a-tigeli.adb	(working copy)
@@ -6,7 +6,7 @@ 
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---          Copyright (C) 1992-2015, Free Software Foundation, Inc.         --
+--          Copyright (C) 1992-2016, Free Software Foundation, Inc.         --
 --                                                                          --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
@@ -187,9 +187,14 @@ 
          --  If we get EOF after already reading data, this is an incomplete
          --  last line, in which case no End_Error should be raised.
 
-         if ch = EOF and then Last < Item'First then
-            raise End_Error;
+         if ch = EOF then
+            if  Last < Item'First then
+               raise End_Error;
 
+            else  --  All done
+               return;
+            end if;
+
          elsif ch /= LM then
 
             --  Buffer really is full without having seen LM, update col