Command Line Subcommands in Ada

Our program demonstrates the use of subcommands in Ada, similar to how tools like git have different subcommands (e.g., git pull, git push). We’ll use the GNAT.Command_Line package to parse command-line arguments and implement subcommands.

with Ada.Text_IO;
with Ada.Command_Line;
with GNAT.Command_Line;

procedure Command_Line_Subcommands is
   use Ada.Text_IO;
   use Ada.Command_Line;
   use GNAT.Command_Line;

   procedure Handle_Foo is
      Enable : Boolean := False;
      Name   : String(1..100) := (others => ' ');
      Name_Last : Natural := 0;
   begin
      loop
         case Getopt ("e n:") is
            when 'e' =>
               Enable := True;
            when 'n' =>
               Name(1..Full_Switch'Length) := Full_Switch;
               Name_Last := Full_Switch'Length;
            when others =>
               exit;
         end case;
      end loop;

      Put_Line ("subcommand 'foo'");
      Put_Line ("  enable: " & Boolean'Image(Enable));
      Put_Line ("  name: " & Name(1..Name_Last));
      Put ("  tail:");
      for I in 1..Argument_Count loop
         Put (" " & Argument(I));
      end loop;
      New_Line;
   end Handle_Foo;

   procedure Handle_Bar is
      Level : Integer := 0;
   begin
      loop
         case Getopt ("l:") is
            when 'l' =>
               Level := Integer'Value(Parameter);
            when others =>
               exit;
         end case;
      end loop;

      Put_Line ("subcommand 'bar'");
      Put_Line ("  level: " & Integer'Image(Level));
      Put ("  tail:");
      for I in 1..Argument_Count loop
         Put (" " & Argument(I));
      end loop;
      New_Line;
   end Handle_Bar;

begin
   if Argument_Count < 1 then
      Put_Line ("expected 'foo' or 'bar' subcommands");
      Set_Exit_Status (Failure);
      return;
   end if;

   if Argument(1) = "foo" then
      Initialize_Option_Scan (1);
      Handle_Foo;
   elsif Argument(1) = "bar" then
      Initialize_Option_Scan (1);
      Handle_Bar;
   else
      Put_Line ("expected 'foo' or 'bar' subcommands");
      Set_Exit_Status (Failure);
   end if;
end Command_Line_Subcommands;

This Ada program implements subcommands similar to the original example. Here’s how it works:

  1. We use the GNAT.Command_Line package to parse command-line arguments.

  2. We define two procedures, Handle_Foo and Handle_Bar, to handle the “foo” and “bar” subcommands respectively.

  3. In the main procedure, we check if a subcommand is provided and call the appropriate handler.

  4. Each handler uses Getopt to parse its specific flags and then prints the results.

To compile and run the program:

$ gnatmake command_line_subcommands.adb
$ ./command_line_subcommands foo -e -n=joe a1 a2
subcommand 'foo'
  enable: TRUE
  name: joe
  tail: a1 a2

$ ./command_line_subcommands bar -l 8 a1
subcommand 'bar'
  level: 8
  tail: a1

Note that Ada’s command-line parsing is somewhat different from the Go example. We use short options (-e, -n, -l) instead of long options, and the syntax for specifying option values is slightly different.

If you try to use an undefined flag, Ada will raise an exception:

$ ./command_line_subcommands bar -e a1
raised PROGRAM_ERROR : command_line_subcommands.adb:61 bad option: e

This example demonstrates how to implement subcommands and parse command-line arguments in Ada, providing similar functionality to the original Go program.

查看推荐产品

Comments powered by Disqus