Command Line Subcommands in Ada
Here’s the translation of the Go code to Ada, with explanations in Markdown format suitable for Hugo:
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:
We use the
GNAT.Command_Line
package to parse command-line arguments.We define two procedures,
Handle_Foo
andHandle_Bar
, to handle the “foo” and “bar” subcommands respectively.In the main procedure, we check if a subcommand is provided and call the appropriate handler.
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.