Update Arun.Launcher_Type.Execute to take a Slic_Set in order to support arguments

With this commit Arun now supports executing commands which can be found on
$PATH with arguments

🎆
This commit is contained in:
R. Tyler Croy 2017-01-14 00:05:35 -08:00
parent f3bb2ab92e
commit bfdce8bc38
No known key found for this signature in database
GPG Key ID: 1426C7DC3F51E16F
4 changed files with 66 additions and 34 deletions

View File

@ -29,6 +29,8 @@ with Gtk.Widget;
with Gtk.Search_Entry;
with Gtkada.Builder; use Gtkada.Builder;
with GNAT.String_Split;
with Arun;
with Arun.Launchers.Unix;
with Arun.View; use Arun.View;
@ -53,21 +55,37 @@ package body Arun.Handlers is
end Search_Changed;
function Slice_Command (Text : in String) return GNAT.String_Split.Slice_Set is
use GNAT.String_Split;
Separator : constant String := " ";
Slices : Slice_Set;
begin
Create (Slices, Text, Separator, Single);
return Slices;
end Slice_Command;
procedure Execute_Command (Object : access Gtkada_Builder_Record'Class) is
use Ada.Text_IO;
use Gtk.Search_Entry;
use Gtkada.Builder;
use GNAT.String_Split;
Widget : Gtk_Search_Entry := Gtk_Search_Entry (Get_Object (Object, "commandEntry"));
Command : constant String := Widget.Get_Text;
B : Arun.View.Arun_Builder_Record renames Arun.View.Arun_Builder_Record (Object.all);
L : Arun.Launchers.Unix.UnixLauncher renames Arun.Launchers.Unix.UnixLauncher (B.Launcher);
Widget : Gtk_Search_Entry := Gtk_Search_Entry (Get_Object (Object, "commandEntry"));
Builder : Arun.View.Arun_Builder_Record renames Arun.View.Arun_Builder_Record (Object.all);
L : Arun.Launchers.Unix.UnixLauncher renames Arun.Launchers.Unix.UnixLauncher (Builder.Launcher);
Slices : constant Slice_Set := Slice_Command (Widget.Get_Text);
Command : constant String := Slice (S => Slices, Index => 1);
Full_Path : aliased constant String := L.Find_Full_Path (Command);
begin
if Full_Path /= "" then
Put_Line ("Should Execute: " & Command);
L.Execute (Full_Path);
Put_Line ("Should Execute: " & Full_Path);
L.Execute (Full_Path, Slices);
end if;
Gtk.Main.Main_Quit;

View File

@ -74,41 +74,48 @@ package body Arun.Launchers.Unix is
end Find_Full_Path;
procedure Execute (L : in UnixLauncher;
Executable : in String) is
use GNAT.OS_Lib;
function Exec_And_Replace (Filename : in Interfaces.C.Char_Array;
Arguments : in Interfaces.C.Strings.Chars_Ptr_Array) return Integer
with Import,
Convention => C,
Link_Name => "execv";
procedure Print_Errno (Message : in String)
with Import,
Convention => C,
Link_Name => "perror";
procedure Execute (L : in UnixLauncher;
Executable_Path : in String;
Argv : in GNAT.String_Split.Slice_Set) is
use GNAT.String_Split;
use Interfaces.C;
use Interfaces.C.Strings;
use Ada.Command_Line.Environment;
function Exec_And_Replace (Filename : in Char_Array;
Arguments : in Chars_Ptr_Array) return Integer
with Import,
Convention => C,
Link_Name => "execv";
procedure Print_Errno (Message : in String)
with Import,
Convention => C,
Link_Name => "perror";
Default_Args : Chars_Ptr_Array (1 .. 2) := (1 => New_String (Executable), 2 => Null_Ptr);
Status : Integer;
Argc : constant Size_T := Size_T (Slice_Count (Argv));
Arguments : Chars_Ptr_Array (1 .. (Argc + 1)) := (others => Null_Ptr);
begin
Put_Line ("Spawning " & Executable);
-- For the first argument, we must replace the executable name with
-- the full path, e.g. "xeyes" => "/usr/bin/xeyes"
Arguments (1) := New_String (Executable_Path);
for Index in 1 .. Argc loop
Arguments (Index) := New_String (Slice (S => Argv,
Index => Slice_Number (Index)));
end loop;
Status := Exec_And_Replace (Filename => To_C (Item => Executable,
Put_Line ("Spawning " & Executable_Path);
Status := Exec_And_Replace (Filename => To_C (Item => Executable_Path,
Append_Nul => True),
Arguments => Default_Args);
Arguments => Arguments);
-- If the Exec_And_Replace function returns then something has gone wrong
Put_Line ("Spawned " & Executable & " with " & Status'Img);
if Status /= 0 then
Print_Errno ("Something went wrong");
end if;
end Execute;
end Arun.Launchers.Unix;

View File

@ -19,7 +19,7 @@
with Arun;
private with GNAT.String_Split;
with GNAT.String_Split;
package Arun.Launchers.Unix is
type UnixLauncher is new Arun.Launcher_Type with private;
@ -34,8 +34,12 @@ package Arun.Launchers.Unix is
-- Will return an empty string if a full path was not discoverable.
procedure Execute (L : in UnixLauncher;
Executable : in String);
procedure Execute (L : in UnixLauncher;
Executable_Path : in String;
Argv : in GNAT.String_Split.Slice_Set);
-- Execute a command using the given UnixLauncher with an "Argv"
-- Slice_Set assuming the first argument is the command and subsequent values
-- are arguments for that command.
private
type UnixLauncher is new Arun.Launcher_Type with record

View File

@ -17,6 +17,8 @@
-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
------------------------------------------------------------------------------
with GNAT.String_Split;
package Arun is
procedure Main;
@ -32,8 +34,9 @@ package Arun is
--
-- Will return an empty string if a full path was not discoverable.
procedure Execute (L : in Launcher_Type;
Executable : in String) is abstract;
procedure Execute (L : in Launcher_Type;
Executable_Path : in String;
Argv : in GNAT.String_Split.Slice_Set) is abstract;
-- Spawn the Executable in place of the current process
end Arun;