comp.lang.ada
 help / color / mirror / Atom feed
* Creating an empty file with Ada.Text_IO
@ 2015-08-24 14:16 Maciej Sobczak
  2015-08-24 16:15 ` Dmitry A. Kazakov
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Maciej Sobczak @ 2015-08-24 14:16 UTC (permalink / raw)


Consider:

with Ada.Text_IO;
use Ada.Text_IO;

procedure Test is
   F : File_Type;
begin
   Create (F, Out_File, "file.txt");
   Close (F);
end Test;

The program creates a file, but before the file is closed, a newline character(s) is written to it. It is, physically, not empty.
Similarly, if a non-terminated line is written (by means of Ada.Text_IO.Put), it is automatically terminated by a newline.

I understand that the intent of the Ada.Text_IO package was to provide a line-oriented file I/O, but it is sometimes getting in the way.
What are the recommended ways of:
a) creating empty files
b) writing a non-terminated line to (or generally at the end of) the file

?

-- 
Maciej Sobczak * http://www.inspirel.com

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Creating an empty file with Ada.Text_IO
  2015-08-24 14:16 Creating an empty file with Ada.Text_IO Maciej Sobczak
@ 2015-08-24 16:15 ` Dmitry A. Kazakov
  2015-08-25  8:20   ` Maciej Sobczak
  2015-08-24 18:51 ` AdaMagica
  2015-08-25  0:06 ` Dennis Lee Bieber
  2 siblings, 1 reply; 9+ messages in thread
From: Dmitry A. Kazakov @ 2015-08-24 16:15 UTC (permalink / raw)


On Mon, 24 Aug 2015 07:16:45 -0700 (PDT), Maciej Sobczak wrote:

> I understand that the intent of the Ada.Text_IO package was to provide a line-oriented file I/O, but it is sometimes getting in the way.
> What are the recommended ways of:
> a) creating empty files
> b) writing a non-terminated line to (or generally at the end of) the file
>
> ?

Stream I/O.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Creating an empty file with Ada.Text_IO
  2015-08-24 14:16 Creating an empty file with Ada.Text_IO Maciej Sobczak
  2015-08-24 16:15 ` Dmitry A. Kazakov
@ 2015-08-24 18:51 ` AdaMagica
  2015-08-24 22:22   ` Randy Brukardt
  2015-08-25  0:06 ` Dennis Lee Bieber
  2 siblings, 1 reply; 9+ messages in thread
From: AdaMagica @ 2015-08-24 18:51 UTC (permalink / raw)


Sequential_ and Direct_IO might also work.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Creating an empty file with Ada.Text_IO
  2015-08-24 18:51 ` AdaMagica
@ 2015-08-24 22:22   ` Randy Brukardt
  0 siblings, 0 replies; 9+ messages in thread
From: Randy Brukardt @ 2015-08-24 22:22 UTC (permalink / raw)


"AdaMagica" <christ-usch.grein@t-online.de> wrote in message 
news:9ea096fc-26f0-48c4-9be9-4a6466506ef4@googlegroups.com...
> Sequential_ and Direct_IO might also work.

For question 1, surely. For question 2, probably too much mess.

More generally, Text_IO is for processing files in an 
implementation-determined format. (And that's true to some extent for 
Sequential_IO and Direct_IO as well.) If you actually care about the bits in 
the file (as you might when writing a file for some other program), only 
Stream_IO gives the needed control.

For example, the Janus/Ada compiler only uses our in-house Basic_IO package 
for file I/O (we invented Basic_IO for Ada 83; if we were starting today 
we'd use Stream_IO which has essentially the same capabilities). The 
standard I/O packages just didn't work for our needs, even though we 
implemented them ourselves. They had too much overhead and too little 
control.

                                 Randy.



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Creating an empty file with Ada.Text_IO
  2015-08-24 14:16 Creating an empty file with Ada.Text_IO Maciej Sobczak
  2015-08-24 16:15 ` Dmitry A. Kazakov
  2015-08-24 18:51 ` AdaMagica
@ 2015-08-25  0:06 ` Dennis Lee Bieber
  2 siblings, 0 replies; 9+ messages in thread
From: Dennis Lee Bieber @ 2015-08-25  0:06 UTC (permalink / raw)


On Mon, 24 Aug 2015 07:16:45 -0700 (PDT), Maciej Sobczak
<see.my.homepage@gmail.com> declaimed the following:

>
>The program creates a file, but before the file is closed, a newline character(s) is written to it. It is, physically, not empty.
>Similarly, if a non-terminated line is written (by means of Ada.Text_IO.Put), it is automatically terminated by a newline.
>
	And that IS the documented standard... Actually, you are lucky that the
new-line is all you see, as the standard would have the Close operation
ensure the file ends with: new-line, new-page, end-of-file (but does not
mandate how those states are represented in the file -- suspect EOF is
mostly handled as meta-data in the directory entry rather than an explicit
character)

>I understand that the intent of the Ada.Text_IO package was to provide a line-oriented file I/O, but it is sometimes getting in the way.
>What are the recommended ways of:
>a) creating empty files
>b) writing a non-terminated line to (or generally at the end of) the file
>
>?

	As has been mentioned, Stream_IO was sort of created for this role.
-- 
	Wulfraed                 Dennis Lee Bieber         AF6VN
    wlfraed@ix.netcom.com    HTTP://wlfraed.home.netcom.com/

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Creating an empty file with Ada.Text_IO
  2015-08-24 16:15 ` Dmitry A. Kazakov
@ 2015-08-25  8:20   ` Maciej Sobczak
  2015-08-25 15:26     ` Maciej Sobczak
  0 siblings, 1 reply; 9+ messages in thread
From: Maciej Sobczak @ 2015-08-25  8:20 UTC (permalink / raw)


> > What are the recommended ways of:
> > a) creating empty files
> > b) writing a non-terminated line to (or generally at the end of) the file
> 
> Stream I/O.

Right. For those who might be looking for the same in the future:


with Ada.Characters.Latin_1;
with Ada.Streams.Stream_IO;

procedure Test is

   procedure Write_String_To_File (File_Name : in String; S : in String) is
      A : Ada.Streams.Stream_Element_Array (1 .. S'Length);
      F : Ada.Streams.Stream_IO.File_Type;
   begin
      -- convert S to stream elements
      for I in S'Range loop
         A (Ada.Streams.Stream_Element_Offset (I)) :=
            Ada.Streams.Stream_Element (Character'Pos (S (I)));
      end loop;
      
      -- create a stream file and write the content (which might be empty)
      Ada.Streams.Stream_IO.Create (F, Ada.Streams.Stream_IO.Out_File, File_Name);
      Ada.Streams.Stream_IO.Write (F, A);
      Ada.Streams.Stream_IO.Close (F);
   end Write_String_To_File;

begin
   -- empty file:
   Write_String_To_File ("file1.txt", "");
   
   -- file with one, non-terminated line:
   Write_String_To_File ("file2.txt", "abc");
   
   -- file with "one line and a half":
   Write_String_To_File ("file3.txt",
      "abc" & Ada.Characters.Latin_1.LF & "xyz");
end Test;


The above is, of course, platform-specific in the sense that some compatibility between characters and stream elements is assumed. This works everywhere.

Having fun with platform-specific newline variants is left as an exercise to the reader. ;-)

-- 
Maciej Sobczak * http://www.inspirel.com


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Creating an empty file with Ada.Text_IO
  2015-08-25  8:20   ` Maciej Sobczak
@ 2015-08-25 15:26     ` Maciej Sobczak
  2015-08-25 16:18       ` J-P. Rosen
  2015-08-25 16:45       ` G.B.
  0 siblings, 2 replies; 9+ messages in thread
From: Maciej Sobczak @ 2015-08-25 15:26 UTC (permalink / raw)



>    procedure Write_String_To_File (File_Name : in String; S : in String) is
>       A : Ada.Streams.Stream_Element_Array (1 .. S'Length);
>       F : Ada.Streams.Stream_IO.File_Type;
>    begin
>       -- convert S to stream elements
>       for I in S'Range loop
>          A (Ada.Streams.Stream_Element_Offset (I)) :=
>             Ada.Streams.Stream_Element (Character'Pos (S (I)));
>       end loop;

Before anybody uses it in a rocket - there is no provision above that S'First will be 1 and the indices might not be compatible in the above assignment.

Correct version is:

      for I in S'Range loop
         A (Ada.Streams.Stream_Element_Offset (I - S'First + 1)) :=
            Ada.Streams.Stream_Element (Character'Pos (S (I)));
      end loop;

And there are actually several ways to write it.
Now this procedure can write String slices that do not begin at index 1.

(Frankly, this part of Ada is inherently error-prone. I stumble on it repeatedly.)

-- 
Maciej Sobczak * http://www.inspirel.com

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Creating an empty file with Ada.Text_IO
  2015-08-25 15:26     ` Maciej Sobczak
@ 2015-08-25 16:18       ` J-P. Rosen
  2015-08-25 16:45       ` G.B.
  1 sibling, 0 replies; 9+ messages in thread
From: J-P. Rosen @ 2015-08-25 16:18 UTC (permalink / raw)


Le 25/08/2015 17:26, Maciej Sobczak a écrit :
>> procedure Write_String_To_File (File_Name : in String; S : in String) is
>> >       A : Ada.Streams.Stream_Element_Array (1 .. S'Length);
>> >       F : Ada.Streams.Stream_IO.File_Type;
>> >    begin
>> >       -- convert S to stream elements
>> >       for I in S'Range loop
>> >          A (Ada.Streams.Stream_Element_Offset (I)) :=
>> >             Ada.Streams.Stream_Element (Character'Pos (S (I)));
>> >       end loop;
> Before anybody uses it in a rocket - there is no provision above that S'First will be 1 and the indices might not be compatible in the above assignment.
> 
> Correct version is:
> 
>       for I in S'Range loop
>          A (Ada.Streams.Stream_Element_Offset (I - S'First + 1)) :=
>             Ada.Streams.Stream_Element (Character'Pos (S (I)));
>       end loop;
Or simply:
      A : Ada.Streams.Stream_Element_Array
         (Stream_Element_Offset(S'First) ..
          Stream_Element_Offset(S'Last));

(saves some computation in the loop)
-- 
J-P. Rosen
Adalog
2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX
Tel: +33 1 45 29 21 52, Fax: +33 1 45 29 25 00
http://www.adalog.fr

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Creating an empty file with Ada.Text_IO
  2015-08-25 15:26     ` Maciej Sobczak
  2015-08-25 16:18       ` J-P. Rosen
@ 2015-08-25 16:45       ` G.B.
  1 sibling, 0 replies; 9+ messages in thread
From: G.B. @ 2015-08-25 16:45 UTC (permalink / raw)


On 25.08.15 17:26, Maciej Sobczak wrote:
>
>>     procedure Write_String_To_File (File_Name : in String; S : in String) is
>>        A : Ada.Streams.Stream_Element_Array (1 .. S'Length);
>>        F : Ada.Streams.Stream_IO.File_Type;
>>     begin
>>        -- convert S to stream elements
>>        for I in S'Range loop
>>           A (Ada.Streams.Stream_Element_Offset (I)) :=
>>              Ada.Streams.Stream_Element (Character'Pos (S (I)));
>>        end loop;
>
> Before anybody uses it in a rocket - there is no provision above that S'First will be 1 and the indices might not be compatible in the above assignment.
>
> Correct version is:
>
>        for I in S'Range loop
>           A (Ada.Streams.Stream_Element_Offset (I - S'First + 1)) :=
>              Ada.Streams.Stream_Element (Character'Pos (S (I)));
>        end loop;
>
> And there are actually several ways to write it.
> Now this procedure can write String slices that do not begin at index 1.
>
> (Frankly, this part of Ada is inherently error-prone. I stumble on it repeatedly.)
>

subtypes seem helpful. If S can be made of a constraint subtype,
too, then an unchecked conversion should work, too. (Does, using GNAT).


with Ada.Characters.Latin_1;
with Ada.Streams.Stream_IO;

procedure Test is

    subtype S_E_Offset is Ada.Streams.Stream_Element_Offset;
    use type S_E_Offset;
    -- static assert:
    Is_Positive_in_S_E_Offset : constant array (Boolean) of Integer :=
      (
       S_E_Offset'First > S_E_Offset (Positive'First) => 123,
       S_E_Offset'Last >= S_E_Offset (Positive'Last) => 123
      );

    procedure Write_String_To_File (File_Name : in String; S : in String) is
       subtype Index is S_E_Offset
         range S_E_Offset (S'First) .. S_E_Offset (S'Last);

       A : Ada.Streams.Stream_Element_Array (Index);
       F : Ada.Streams.Stream_IO.File_Type;
    begin
       -- convert S to stream elements
       for I in S'Range loop
          A (S_E_Offset (I)) :=
            Ada.Streams.Stream_Element (Character'Pos (S (I)));
       end loop;

       -- create a stream file and write the content (which might be empty)
       Ada.Streams.Stream_IO.Create (F, Ada.Streams.Stream_IO.Out_File, 
File_Name);
       Ada.Streams.Stream_IO.Write (F, A);
       Ada.Streams.Stream_IO.Close (F);
    end Write_String_To_File;

begin
    -- empty file:
    Write_String_To_File ("file1.txt", "");

    -- file with one, non-terminated line:
    Write_String_To_File ("file2.txt",
                          String'(22 => 'a',
                                  23 => 'b',
                                  24 => 'c'));

    -- file with "one line and a half":
    Write_String_To_File ("file3.txt",
       "abc" & Ada.Characters.Latin_1.LF & "xyz");
end Test;

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2015-08-25 16:45 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-08-24 14:16 Creating an empty file with Ada.Text_IO Maciej Sobczak
2015-08-24 16:15 ` Dmitry A. Kazakov
2015-08-25  8:20   ` Maciej Sobczak
2015-08-25 15:26     ` Maciej Sobczak
2015-08-25 16:18       ` J-P. Rosen
2015-08-25 16:45       ` G.B.
2015-08-24 18:51 ` AdaMagica
2015-08-24 22:22   ` Randy Brukardt
2015-08-25  0:06 ` Dennis Lee Bieber

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox