Marcello90
Marcello90

Reputation: 1343

Start executable from Ada program and read result

I found this question and the first answer contains some example code demonstrating how to start an executable with Ada code. The output of the executable is written to the standard output.

What options do I have to read the output of the executable for further parsing/processing in Ada (for example line by line)?

Upvotes: 3

Views: 1327

Answers (1)

DeeDee
DeeDee

Reputation: 5941

If you use GNAT, then you might want to take a look at Get_Command_Output in the GNAT.Expect package. Here's an example:

with Ada.Text_IO, GNAT.Expect;

procedure Main is

   Command    : constant String := "gnat";   
   Argument_1 : aliased String  := "--version";
   Input      : constant String := ""; 
   Status     : aliased Integer := 0;      

   --  Execute the command and retrieve the output.

   Output : String :=
              GNAT.Expect.Get_Command_Output
                (Command    => Command,
                 Arguments  => (1 => Argument_1'Unchecked_Access),
                 Input      => Input,
                 Status     => Status'Access,
                 Err_To_Out => False);

   --  NOTE: Cheating with Unchecked_Access, OK for demo. You may want
   --        to properly new and Free these strings (see Argument_List 
   --        type in package GNAT.OS_Lib).

begin  
   Ada.Text_IO.Put_Line (Output);
end Main;

The program returns after execution:

$ ./main
GNAT Community 2019 (20190517-83)
Copyright (C) 1996-2019, Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

As can be seen, the result is returned as a single string. You will have do the line splitting yourself.


Update

An update in response to some comments below.

You might also consider using the system function if you're targeting the Windows platform (see also this post on SO). Quoting from the function reference:

The system function passes command to the command interpreter, which executes the string as an operating-system command.

This is similar to what the program cmd.exe does. You can obtain the output of the command by redirecting its output to a file (i.e. using >) and then subsequently read it back. Here's an example:

with Ada.Text_IO;              
with Ada.Text_IO.Unbounded_IO;
with Ada.Strings.Unbounded;

with Interfaces.C;
with Interfaces.C.Strings;         

procedure Main is

   use Ada.Strings.Unbounded;
   Content : Unbounded_String := Null_Unbounded_String;   

begin

   --  Execute.
   declare   

      use Interfaces.C;
      use Interfaces.C.Strings; 

      function system (command : chars_ptr) return int
        with Import, Convention => C, External_Name => "system";      

      command : chars_ptr := New_String("gnat --version > gnat_version.out");
      result  : int       := system (command); 

   begin
      --  Check value of result (omitted in this example).
      Free(Command);
   end;

   --  Read.
   declare

      use Ada.Text_IO;
      use Ada.Text_IO.Unbounded_IO;  

      Fd : File_Type;

   begin  
      Open (Fd, In_File, "./gnat_version.out");
      while not End_Of_File (Fd) loop
         Content := Content 
           & Unbounded_String'(Get_Line (Fd))
           & ASCII.CR & ASCII.LF;   --  Restore the line break removed by Get_Line.
      end loop;
      Close (fd);
   end;

   --  Show.
   Ada.Text_IO.Unbounded_IO.Put (Content);   

end Main;

Upvotes: 3

Related Questions