Following AdaCore Gem #138 : Master the Commandline I am trying to create a commandline program that only accepts two options.
I pass a string to getopt which says which options are valid:
Getopt ("-project= -help")
Which means '--project foo' can be given, and also '--help' without an argument. I want to be very strict - project requires a parameter, and help should not take an argument. However, it seems the above will happily accept (and ignore) futher parameters given on the commandline, as long as they don't begin with a minus symbol:
$ ./getopt_invalid_option.exe --project foo these options are all invalid
Project := foo
$ ./getopt_invalid_option.exe things
Project :=
$ ./getopt_invalid_option.exe --switch
raised GNAT.COMMAND_LINE.INVALID_SWITCH : Unrecognized option '--switch'
$ ./getopt_invalid_option.exe -sss
raised GNAT.COMMAND_LINE.INVALID_SWITCH : Unrecognized option '-s'
How do I disallow the first two examples above?
My situation is slightly complicated by the fact that I have a section, after which everything should be allowed. From reading the specification of GNAT.Command_Line I thought this would be achieved by calling Getopt("*") after going to the corresponding section, which works, but with and without a section, I am unable to catch invalid switches (unless they begin with '-').
In the code below, I've commented the parts pertaining to the section; but the point is that a complete solution would need to work with the section as well.
with Ada.Text_IO; use Ada.Text_IO;
with GNAT.Command_Line; use GNAT.Command_Line;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
procedure Main is
Project : Unbounded_String;
begin
-- Initialize_Option_Scan (Section_Delimiters => "anything");
-- Goto_Section ("");
loop
case Getopt ("-project= -help") is
when '-' =>
if Full_Switch = "-project" then
Project := To_Unbounded_String (Parameter);
elsif Full_Switch = "-help" then
Put_Line ("Usage: etc... ");
return;
end if;
when ASCII.Nul =>
exit;
when others =>
Put_Line ("Error: unrecognized switch " & Full_Switch);
return;
end case;
end loop;
-- Goto_Section ("anything");
-- loop
-- exit when Getopt ("*") = ASCII.Nul;
-- Put_Line ("Accepted: " & Full_Switch);
-- end loop;
Put_Line ("Project := " & To_String (Project));
end Main;
I have tried changing the first Getopt to:
case Getopt ("-project= -help *") is
Which does not change the behaviour at all! Also tried:
case Getopt ("*") is
Which disallows everything, oddly enough.