--  psh1.adb
--    Prompting shell (version 1).
--      Prompts for the command and its arguments.
--      Builds the argument vector for the call to execvp.
--      Uses execvp and never returns.

with
  Ada.Strings.Unbounded,
  Ada.Strings.Unbounded.Text_IO,
  Ada.Text_IO,
  Interfaces.C.Strings,
  System,
  Unchecked_Conversion;

procedure Prompting_Shell_1 is
   package size_t_Text_IO is new Ada.Text_IO.Modular_IO (Interfaces.C.size_t);

   type chars_ptr_ptr is access constant Interfaces.C.Strings.chars_ptr;
   pragma Convention (C, chars_ptr_ptr);
   function To_Ptr is new Unchecked_Conversion (System.Address, chars_ptr_ptr);

   procedure execvp
     (path : Interfaces.C.Strings.chars_ptr;
      argv : chars_ptr_ptr);
   pragma Import (C, execvp, "execvp");

   use type Interfaces.C.size_t;

   Arguments      : Interfaces.C.Strings.chars_ptr_array (0 .. 20);
   Argument_Count : Interfaces.C.size_t := Arguments'First;
   Argument       : Ada.Strings.Unbounded.Unbounded_String;
begin
   while Argument_Count < Arguments'Last loop
      Ada.Text_IO.Put ("Arg[");
      size_t_Text_IO.Put (Argument_Count, Width => 0);
      Ada.Text_IO.Put ("]? ");
      Argument := Ada.Strings.Unbounded.Text_IO.Get_Line;
      if Ada.Strings.Unbounded.Length (Argument) = 0 then
         if Argument_Count > Arguments'First then
            Arguments (Argument_Count) := Interfaces.C.Strings.Null_Ptr;
            execvp (path => Arguments (0),
                    argv => To_Ptr (Arguments'Address));
            Argument_Count := 0;
         end if;
      else
         Arguments (Argument_Count) := Interfaces.C.Strings.New_String
           (Ada.Strings.Unbounded.To_String (Argument));
         Argument_Count := Argument_Count + 1;
      end if;
   end loop;
end Prompting_Shell_1;

