【发布时间】:2020-11-06 10:36:52
【问题描述】:
按照AdaCore Gem #138 : Master the Commandline,我正在尝试创建一个只接受两个选项的命令行程序。
我将一个字符串传递给 getopt,它说明哪些选项是有效的:
Getopt ("-project= -help")
这意味着可以给出“--project foo”,也可以不带参数给出“--help”。我想非常严格 - 项目需要一个参数,而帮助不应该带一个参数。但是,上面似乎很乐意接受(并忽略)命令行上给出的其他参数,只要它们不以减号开头:
$ ./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'
如何禁止上面的前两个示例?
我的情况有点复杂,因为我有一个部分,在此之后应该允许一切。通过阅读GNAT.Command_Line 的规范,我认为这可以通过在转到相应的部分之后调用Getopt("*") 来实现,但无论有没有一个部分,我都无法捕获无效开关(除非它们以'- ')。
在下面的代码中,我对与该部分相关的部分进行了注释;但关键是完整的解决方案也需要与该部分一起使用。
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;
我尝试将第一个 Getopt 更改为:
case Getopt ("-project= -help *") is
这根本不会改变行为!也试过了:
case Getopt ("*") is
这一切都不允许,很奇怪。
【问题讨论】:
-
Getopt 移动到下一个开关,非开关需要 Get_Argument