跳轉至內容

Ada 程式設計/庫/Ada.Command_Line

來自 Wikibooks,開放的書籍,開放的世界

Ada. Time-tested, safe and secure.
Ada.經久耐用,安全可靠。

此語言功能從 Ada 95 開始提供。

Ada.Command_Line 是自 Ada 95 以來 預定義語言環境 的一個單元。

Ada.Command_Line 包允許 Ada 程式訪問呼叫該程式的命令設定的命令列引數。它是 C argvargc[n] 系統的 Ada 版本。

如果環境支援,還可以使用 Ada.Command_Line 設定 Ada 程式的退出狀態。

重要的是要注意,本文中的所有程式碼都是在 Slackware Linux 系統上編譯和執行的。使用的編譯器是 GNATMAKE GPL 2008 (20080521),外殼是 BASH。這很重要,因為參考手冊明確指出

如果外部執行環境支援向程式傳遞引數,則 Argument_Count 返回傳遞給呼叫該函式的程式的引數數量。否則,它返回 0。 “引數數量” 的含義由實現定義。

注意結尾句:“引數數量” 的含義由實現定義。這意味著您不能相信給定的引數字串在所有環境中都能產生相同的結果。Argument_Count 高度依賴於作業系統、外殼和編譯器等因素。

使用 Ada.Command_Line

[編輯 | 編輯原始碼]

我們將在本文中使用的程式實際上什麼也不做,只是報告我們在呼叫該程式時使用的各種引數。基本程式如下所示

with Ada.Text_IO;
with Ada.Command_Line;
 
procedure Args is
   package IO renames Ada.Text_IO;
   package CLI renames Ada.Command_Line;
begin
   IO.Put_Line (Item => "Argument Count:" & CLI.Argument_Count'Img);
end Args;

在沒有給出任何引數的情況下執行上述程式時,您應該得到以下輸出

 Argument Count: 0

讓我們快速回顧一下程式:在第 1 行和第 2 行,我們將 Text_IOCommand_Line 包新增到程式中。在第 5 行和第 6 行,我們將這些包重新命名為較短的 IOCLI,最後在第 8 行,我們輸出當前的引數計數。這實際上是訪問傳遞給程式的命令列引數所需的全部內容。

Command_Line 包的完整規範與這種 規範 可以說的一樣簡單。

我們已經在 Args 程式中遇到了 Argument_Count 函式,但是讓我們看看當我們用一些引數呼叫 Args 程式時會發生什麼。

Ada.Command_Line.Argument_Count

[編輯 | 編輯原始碼]

Argument_Count 的規範如下所示

function Argument_Count return Natural;

基本 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 時注意這些細節。

Ada.Command_Line.Argument

[編輯 | 編輯原始碼]

Argument 的規範如下所示

function Argument (Number : Positive) return String;

Argument 返回與相對位置 Number 對應的 String 引數。請注意,Number 的型別為 Positive。這意味著 Number 的有效範圍為 1 .. Argument_Count。如果 Number 超出此範圍,則會引發 Constraint_Error

要檢視它的工作原理,我們將在小型 Args 程式中新增 3 行

for i in 1 .. CLI.Argument_Count loop
   IO.Put_Line (Item => CLI.Argument (Number => i));
end loop;

如果我們使用與 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)。這完全有效,結果與預期一致:迴圈立即終止。

with Ada.Text_IO;
with Ada.Command_Line;
 
procedure Args is
   package IO renames Ada.Text_IO;
   package CLI renames Ada.Command_Line;
begin
   IO.Put_Line (Item => "Argument Count:" & CLI.Argument_Count'Img);
   for i in 1 .. CLI.Argument_Count loop
      IO.Put (Item => i'Img & ": ");
      IO.Put_Line (Item => CLI.Argument (Number => i));
   end loop;
end Args;

Ada.Command_Line.Command_Name

[編輯 | 編輯原始碼]

Command_Name 的規範如下所示

function Command_Name return String;

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 函式返回用於呼叫該程式的確切字串。

Ada.Command_Line.Set_Exit_Status

[編輯 | 編輯原始碼]

Set_Exit_Status 的規範如下所示

procedure Set_Exit_Status (Code : Exit_Status);

如果環境支援返回任務完成程式碼,則 Set_Exit_Status 允許您設定程式的退出狀態。如果您檢視 Ada.Command_Line 的規範,您會注意到 Exit_Status 型別以及 SuccessFailure 兩個變數。這兩個變數分別定義為 0 和 1,但完全可以定義自己的退出狀態程式碼。

要檢視它的工作原理,請將以下內容新增到 Args 程式的規範中

More_Than_One_Arg : constant CLI.Exit_Status := 3;

以及以下內容新增到程式的主體中

if CLI.Argument_Count = 0 then
   CLI.Set_Exit_Status (Code => CLI.Failure);
elsif CLI.Argument_Count = 1 then
   CLI.Set_Exit_Status (Code => CLI.Success);
else
   CLI.Set_Exit_Status (Code => More_Than_One_Arg);
end if; 

我們在這裡做的是根據傳遞給程式的引數數量來設定退出狀態。以下是在我們使用各種引數執行程式時發生的情況

 $ ./args
 Argument Count: 0
 $ echo $?
 1
 
 $ ./args one
 Argument Count: 1
 $ echo $?
 0
 
 $ ./args one two
 Argument Count: 2
 $ echo $?
 3

echo $? 輸出最近執行程式的退出程式碼。第一次執行時,由於沒有給出任何引數,因此會失敗。第二次執行時,由於只給了一個引數,因此會成功。第三次執行時,由於給出了多個引數,因此會得到特殊的退出程式碼 3。

with Ada.Text_IO;
with Ada.Command_Line;

procedure Args is
   package IO renames Ada.Text_IO;
   package CLI renames Ada.Command_Line;
   More_Than_One_Arg : constant CLI.Exit_Status := 3;
begin
   IO.Put_Line (Item => "Argument Count:" & CLI.Argument_Count'Img);
   if CLI.Argument_Count = 0 then
      CLI.Set_Exit_Status (Code => CLI.Failure);
   elsif CLI.Argument_Count = 1 then
      CLI.Set_Exit_Status (Code => CLI.Success);
   else
      CLI.Set_Exit_Status (Code => More_Than_One_Arg);
   end if; 
end Args;
--                     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
-- -------------------------------------------------------------------------

package Ada.Command_Line is
   pragma Preelaborate (Command_Line);

   function Argument_Count return Natural;

   function Argument (Number : in Positive) return String;

   function Command_Name return String;

   type Exit_Status is range implementation_defined .. implementation_defined;

   Success : constant Exit_Status;
   Failure : constant Exit_Status;

   procedure Set_Exit_Status (Code : in Exit_Status);

private

   pragma Import (Ada, Success);
   pragma Import (Ada, Failure);

end Ada.Command_Line;

另請參閱

[編輯 | 編輯原始碼]

華夏公益教科書

[編輯 | 編輯原始碼]

外部示例

[編輯原始碼]

Ada 參考手冊

[編輯 | 編輯原始碼]

開源實現

[編輯 | 編輯原始碼]

FSF GNAT

drake

華夏公益教科書