Ada 编程/库/Ada.Command_Line
此语言功能从 Ada 95 开始提供。
Ada.Command_Line 是自 Ada 95 以来 预定义语言环境 的一个单元。
Ada.Command_Line 包允许 Ada 程序访问调用该程序的命令设置的命令行参数。它是 C argv 和 argc[n] 系统的 Ada 版本。
如果环境支持,还可以使用 Ada.Command_Line 设置 Ada 程序的退出状态。
重要的是要注意,本文中的所有代码都是在 Slackware Linux 系统上编译和执行的。使用的编译器是 GNATMAKE GPL 2008 (20080521),外壳是 BASH。这很重要,因为参考手册明确指出
如果外部执行环境支持向程序传递参数,则 Argument_Count 返回传递给调用该函数的程序的参数数量。否则,它返回 0。 “参数数量” 的含义由实现定义。
注意结尾句:“参数数量” 的含义由实现定义。这意味着您不能相信给定的参数字符串在所有环境中都能产生相同的结果。Argument_Count 高度依赖于操作系统、外壳和编译器等因素。
我们将在本文中使用的程序实际上什么也不做,只是报告我们在调用该程序时使用的各种参数。基本程序如下所示
withAda.Text_IO;withAda.Command_Line;procedureArgsispackageIOrenamesAda.Text_IO;packageCLIrenamesAda.Command_Line;beginIO.Put_Line (Item => "Argument Count:" & CLI.Argument_Count'Img);endArgs;
在没有给出任何参数的情况下执行上述程序时,您应该得到以下输出
Argument Count: 0
让我们快速回顾一下程序:在第 1 行和第 2 行,我们将 Text_IO 和 Command_Line 包添加到程序中。在第 5 行和第 6 行,我们将这些包重命名为较短的 IO 和 CLI,最后在第 8 行,我们输出当前的参数计数。这实际上是访问传递给程序的命令行参数所需的全部内容。
Command_Line 包的完整规范与这种 规范 可以说的一样简单。
我们已经在 Args 程序中遇到了 Argument_Count 函数,但是让我们看看当我们用一些参数调用 Args 程序时会发生什么。
Argument_Count 的规范如下所示
functionArgument_CountreturnNatural;
基本 Args 程序已经使用 Argument_Count 函数,所以要查看它的工作原理,我们只需为该程序提供各种参数即可
$ ./args --option=value Argument Count: 1 $ ./args --option=value --foo=bar Argument Count: 2 $ ./args --name=Thomas Løcke Argument Count: 2 $ ./args --option="Thomas Løcke" Argument Count: 1 $ ./args /path/to/file with spaces in name Argument Count: 5 $ ./args /path/to/file with spaces in name Argument Count: 1
到目前为止应该出现了一种模式。最后一个例子尤其引人注目:由于空格被转义,整个字符串被视为一个参数。可以很容易地想象,另一个环境可能会对这样的参数进行不同的处理,并且可能会忽略反斜杠。对于双引号示例(“Thomas Løcke”)也是如此。其他外壳/环境可能会将“Thomas Løcke” 视为两个单独的参数,因为空格。关键是要在使用 Ada.Command_Line 时注意这些细节。
Argument 的规范如下所示
functionArgument (Number : Positive)returnString;
Argument 返回与相对位置 Number 对应的 String 参数。请注意,Number 的类型为 Positive。这意味着 Number 的有效范围为 1 .. Argument_Count。如果 Number 超出此范围,则会引发 Constraint_Error。
要查看它的工作原理,我们将在小型 Args 程序中添加 3 行
foriin1 .. CLI.Argument_CountloopIO.Put_Line (Item => CLI.Argument (Number => i));endloop;
如果我们使用与 Argument_Count 示例中相同的参数运行 Args,我们将获得以下结果
$ ./args --option=value Argument Count: 1 1: --option=value $ ./args --option=value --foo=bar Argument Count: 2 1: --option=value 2: --foo=bar $ ./args --name=Thomas Løcke Argument Count: 2 1: --name=Thomas 2: Løcke $ ./args --option="Thomas Løcke" Argument Count: 1 1: --option=Thomas Løcke $ ./args /path/to/file with spaces in name Argument Count: 5 1: /path/to/file 2: with 3: spaces 4: in 5: name $ ./args /path/to/file with spaces in name Argument Count: 1 1: /path/to/file with spaces in name
这里没有什么大惊喜。
如果在运行程序时没有给出任何参数,您将得到一个 null range 循环:(1 .. 0)。这完全有效,结果与预期一致:循环立即终止。
withAda.Text_IO;withAda.Command_Line;procedureArgsispackageIOrenamesAda.Text_IO;packageCLIrenamesAda.Command_Line;beginIO.Put_Line (Item => "Argument Count:" & CLI.Argument_Count'Img);foriin1 .. CLI.Argument_CountloopIO.Put (Item => i'Img & ": "); IO.Put_Line (Item => CLI.Argument (Number => i));endloop;endArgs;
Command_Name 的规范如下所示
functionCommand_NamereturnString;
Command_Name 返回用于调用该程序的字符串命令。与 Argument_Count 一样,这是由实现定义的,因此 Command_Name 可能会在系统 A 上返回 X,在系统 B 上返回 Y,在系统 C 上返回 null。您不能依赖此值在所有编译器、外壳和操作系统的组合中都相同。
要查看它的工作原理,请将此行添加到 Args 程序中
IO.Put_Line (CLI.Command_Name);
如果我们在没有参数的情况下从 GNAT Studio(使用 Shift+F2)中执行程序,结果将是
Argument Count: 0 /home/thomas/wiki_examples/Args/args
请注意 GNAT Studio 如何使用 Args 程序的完整路径来调用它。
如果我将目录更改为 /home/thomas/wiki_examples/Args/,并从命令行执行 Args 程序,我得到的是
$ args Argument Count: 0 args
如果我使用常见的 ./ 语法来执行程序,我得到的是
$ ./args Argument Count: 0 ./args
如您所见,在支持参数传递的环境中,Command_Name 函数返回用于调用该程序的确切字符串。
Set_Exit_Status 的规范如下所示
procedure Set_Exit_Status (Code : Exit_Status);
如果环境支持返回任务完成代码,则 Set_Exit_Status 允许您设置程序的退出状态。如果您查看 Ada.Command_Line 的规范,您会注意到 Exit_Status 类型以及 Success 和 Failure 两个变量。这两个变量分别定义为 0 和 1,但完全可以定义自己的退出状态代码。
要查看它的工作原理,请将以下内容添加到 Args 程序的规范中
More_Than_One_Arg : constant CLI.Exit_Status := 3;
以及以下内容添加到程序的主体中
ifCLI.Argument_Count = 0thenCLI.Set_Exit_Status (Code => CLI.Failure);elsifCLI.Argument_Count = 1thenCLI.Set_Exit_Status (Code => CLI.Success);elseCLI.Set_Exit_Status (Code => More_Than_One_Arg);endif;
我们在这里做的是根据传递给程序的参数数量来设置退出状态。以下是在我们使用各种参数执行程序时发生的情况
$ ./args Argument Count: 0 $ echo $? 1 $ ./args one Argument Count: 1 $ echo $? 0 $ ./args one two Argument Count: 2 $ echo $? 3
echo $? 输出最近执行程序的退出代码。第一次执行时,由于没有给出任何参数,因此会失败。第二次执行时,由于只给了一个参数,因此会成功。第三次执行时,由于给出了多个参数,因此会得到特殊的退出代码 3。
withAda.Text_IO;withAda.Command_Line;procedureArgsispackageIOrenamesAda.Text_IO;packageCLIrenamesAda.Command_Line; More_Than_One_Arg :constantCLI.Exit_Status := 3;beginIO.Put_Line (Item => "Argument Count:" & CLI.Argument_Count'Img);ifCLI.Argument_Count = 0thenCLI.Set_Exit_Status (Code => CLI.Failure);elsifCLI.Argument_Count = 1thenCLI.Set_Exit_Status (Code => CLI.Success);elseCLI.Set_Exit_Status (Code => More_Than_One_Arg);endif;endArgs;
-- Standard Ada library specification -- Copyright (c) 2003-2018 Maxim Reznik <reznikmm@gmail.com> -- Copyright (c) 2004-2016 AXE Consultants -- Copyright (c) 2004, 2005, 2006 Ada-Europe -- Copyright (c) 2000 The MITRE Corporation, Inc. -- Copyright (c) 1992, 1993, 1994, 1995 Intermetrics, Inc. -- SPDX-License-Identifier: BSD-3-Clause and LicenseRef-AdaReferenceManual -- -------------------------------------------------------------------------packageAda.Command_LineispragmaPreelaborate (Command_Line);functionArgument_CountreturnNatural;functionArgument (Number :inPositive)returnString;functionCommand_NamereturnString;typeExit_Statusisrangeimplementation_defined .. implementation_defined; Success :constantExit_Status; Failure :constantExit_Status;procedureSet_Exit_Status (Code :inExit_Status);privatepragmaImport (Ada, Success);pragmaImport (Ada, Failure);endAda.Command_Line;
外部示例
[编辑源代码]- 在以下位置搜索
Ada.Command_Line的示例:Rosetta 代码、GitHub (gists)、任何 Alire 包 或 本。 - 在以下位置搜索与
Ada.Command_Line相关的帖子:堆栈溢出、comp.lang.ada 或 任何与 Ada 相关的页面。
FSF GNAT
- 规范:a-comlin.ads
- 主体:a-comlin.adb
drake
