Version 1.2 of ais/ai-00085.txt

Unformatted version of ais/ai-00085.txt version 1.2
Other versions for file ais/ai-00085.txt

!standard A.8.2 (16)          98-04-04 AI95-00085/05
!standard A.12.1(33)
!class confirmation 95-08-19
!status ARG approved (subject to editorial review) 12-0-0 98-04-03
!status work item 95-11-01
!status received 95-08-19
!priority High
!difficulty Hard
!subject Append_File, Reset and positioning
!summary 98-04-04
A call to Reset without the Mode parameter is equivalent to a call to Reset with the current mode of the file.
The beginning and end of the file mentioned in the description of the semantics of Reset designate the beginning and end of the external file.
It is legitimate for an implementation to raise Use_Error on the positioning operations of Stream_IO in the circumstances where the underlying operating system does not support positioning.
The procedure Stream_IO.Set_Mode sets the mode of the file, it doesn't necessarily change it.
!question 98-04-04
1. Are the following two calls equivalent, even if F is opened in
Append_File mode? (yes)
Reset (F, Mode => Mode (F)); Reset (F);
2. A call to Reset with mode In_File allows reading to be restarted
"from the beginning of the file". RM95 A.7(2) indicates that the term "file" refers to a file object, not to an external file. Does the phrase "beginning of the file" refer to the beginning of the external file? (the external file)
3. For a Unix implementation that uses the Unix append mode to implement
files opened in Append_File mode, what are the possible effects of Set_Index? (do the right thing or raise Use_Error.)
4. RM95 A.12.1(35) says that "the Set_Mode procedure changes the mode of
file." Does that mean that Set_Mode can only be used to "change" the mode of the file? (no)
!response 98-04-04
1. RM95 A.8.2(16) states that: "if a Mode parameter is supplied, the current mode of the given file is set to the given mode." This paragraph doesn't mention any other effect for the Mode parameter; therefore, setting the Mode parameter Mode (F) has essentially no effect, and the two calls Reset (File, Mode (File)) and Reset (File) are equivalent.
For a file which is opened in Append_File mode, Reset (F) positions the file so that writing can be restarted after the last element of the external file. This is explicitly stated in RM95 A.8.2(16), although this section uses the word "file" when it should say "external file".
Note that for a Unix implementation, it makes it possible to use the Unix append mode, and to implement any of these two calls without closing and reopening the file.
2. When RM95 A.8.2(16) talks about the "beginning of the file" or "the last element of the file" it is talking about the beginning and end of the external file (despite RM95 A.7(2)).
For a file that is Reset to mode In_File, reading restarts at the beginning of the external file. This is supported by the annotation in AARM A.10.2(4.a), which indicates that Reset should be similar to closing and then reopening. The internal file essentially disappears between closing and reopening, so clearly Reset is resetting based on properties of the external file, not of the internal file.
Note that for a Unix implementation which uses the Unix append mode to implement files opened in Append_File mode, this means that resetting to In_File or Out_File must be implemented by closing and reopening.
3. It is the intent that a Unix implementation can use the Unix append mode to implement files opended in Append_File mode. For a stream designating such a file, positioning is effectively impossible because, if the O_APPEND bit was set at open time, "the file pointer is set to the end of the file prior to each write" (excerpt from the Unix man page for open). RM95 A.12.1(32) makes it clear that such an implementation is legitimate, provided that it raises Use_Error on the positioning operations: "if positioning is not supported for the given file, then a call to Index or Set_Index propagates Use_Error."
Although this compromises portability (different compilers may use different implementations, and certainly different OSes may have different restrictions), the stress here is on performance: the intent is that the file and stream operations should be implemented as a thin layer on top of the OS calls, and should not have to simulate services that are not provided by the underlying OS.
4. RM95 A.12.1(35) should say that "the procedure Set Mode sets the mode of the file." If the Mode parameter is the current mode of the file, then surely the mode of the file is not changed.
!appendix

!section A.7(02)
!subject Questions about Append_File mode
!reference RM95-A.7(2)
!reference RM95-A.8.2(15,16)
!reference AARM95-A.10.2(4.a)
!from Keith Thompson 95-08-09
!reference as: 95-5253.a Keith Thompson 95-8-9>>
!discussion

Some aspects of Append_File mode seem unclear.  For example:

1. Reset with an explicit Mode => Append_File (for a text or sequential
   file) causes writing to continue at the end of the file, yes?
   Assume F is a (text or sequential) file whose current mode is
   Append_File.  Are the following two calls equivalent?

      Reset(F, Mode => Append_File);
      Reset(F);

   More generally, are these always equivalent?

      Reset(F, Mode => Mode(F));
      Reset(F);

   I believe they should be, but I've been unable to prove it from the
   RM or AARM.

2. A call to Reset with mode In_File allows reading to be restarted
   "from the beginning of the file".  RM95-A.7(2) indicates that
   the term "file" refers to a file object, not to an external file.
   Does the phrase "beginning of the file" refer to the beginning
   of the external file?

   In particular, what is the effect of the following code fragment,
   assuming all operations are successful?

      declare
         package Int_IO is new Ada.Sequential_IO(Integer);
         F: Int_IO.File_Type;
         File_Name: constant String := "foo.dat";
      begin
         Int_IO.Create(F, File_Name);
         for I in 1 .. 3 loop
            Int_IO.Write(F, I);
         end loop;
         Int_IO.Close(F);
         --
         -- foo.dat now contains (1, 2, 3)
         --
         Int_IO.Open(F, Mode => Int_IO.Append_File, Name => File_Name);
         for I in 4 .. 6 loop
            Int_IO.Write(F, I);
         end loop;
         --
         -- foo.dat now contains (1, 2, 3, 4, 5, 6),
         -- but where is the "beginning of the file"?
         --
         Int_IO.Reset(F, Mode => Int_IO.Out_File);
         Int_IO.Write(F, 999);
         Int_IO.Close(F);
      end;

   If the "beginning of the file" is the beginning of the external
   file, the final contents of foo.dat should be the single integer 999.
   If it refers to the beginning of the file object, *and* the beginning
   of a file in Append_File mode is considered to be the point at which
   it was opened, foo.dat should contain 4 integers: 1, 2, 3, and 999.
   (The previously written values 4, 5, and 6 are lost in either case).

   It would be easier and more intuitive, IMHO, for Reset to go to the
   beginning of the external file, but I can't infer this behavior from
   the RM.  The note in AARM95-A.10.2(4.a):

      The behavior of Reset should be similar to closing a file and
      reopening it with the given mode.

   tends to support this, but it's not binding.

   On the other hand, if Reset goes back to the beginning of the external
   file, there's no easy way to go back to the position at which it was
   opened for appending.  (This is probably no great loss.)

****************************************************************

!section A.8.2(16)
!subject Questions about Append_File mode
!reference AI95-00085
!reference RM95-A.8.2(16)
!reference RM95-A.7(2)
!reference AARM-A.10.2(4.a)
!from Tucker Taft 95-10-30
!reference 95-5373.h Tucker Taft 95-10-30>>
!discussion

I certainly believe that Reset(File, Mode(File)) is equivalent 
to simply Reset(File).  I can't imagine any other meaningful
interpretation for A.8.2(16).

As far as external vs. internal file, I believe that 
the wording in A.8.2(16) is sloppy, and whenever it talks 
about the "beginning of the file" or "the last element
of the file" it is talking about the beginning and end of the 
external file (despite A.7(2)).  It makes no difference whether
the file was initially opened in append mode, or was reset to
that mode somewhere along the way.  

The annotation in A.10.2(4.a) seems to make this intent clear, 
by indicating that Reset should be similar to closing and then 
reopening.  The internal file essentially disappears between
closing and reopening, so clearly Reset is resetting based on
properties of the external file, not of the "internal" file.

****************************************************************

Questions? Ask the ACAA Technical Agent