模組 Arg

module Arg: sig .. end

剖析命令列引數。

此模組提供從命令列提取選項和引數到程式的一般機制。例如

     let usage_msg = "append [-verbose] <file1> [<file2>] ... -o <output>"
     let verbose = ref false
     let input_files = ref []
     let output_file = ref ""

     let anon_fun filename =
       input_files := filename::!input_files

     let speclist =
       [("-verbose", Arg.Set verbose, "Output debug information");
        ("-o", Arg.Set_string output_file, "Set output file name")]

     let () =
       Arg.parse speclist anon_fun usage_msg;
       (* Main functionality here *)

命令列的語法:關鍵字是以 - 開頭的字串。選項是單獨的關鍵字,或後面跟著引數。關鍵字的類型有:UnitBoolSetClearStringSet_stringIntSet_intFloatSet_floatTupleSymbolRestRest_allExpand

UnitSetClear 關鍵字不接受引數。

RestRest_all 關鍵字將命令列的剩餘部分作為引數。(更多說明如下。)

其他每個關鍵字都將命令列上的下一個單字作為引數。為了與 GNU getopt_long 相容,也允許使用 keyword=arg。沒有關鍵字前綴的引數稱為匿名引數。

範例(假設 cmd 是命令名稱)

  • cmd -flag           (一個 unit 選項)
  • cmd -int 1          (一個 int 選項,引數為 1
  • cmd -string foobar  (一個 string 選項,引數為 "foobar"
  • cmd -float 12.34    (一個 float 選項,引數為 12.34
  • cmd a b c           (三個匿名引數:"a""b""c"
  • cmd a b -- c d      (兩個匿名引數和一個 rest 選項,帶有兩個引數)

Rest 接受一個函式,該函式會針對每個剩餘的命令列引數重複呼叫。Rest_all 接受一個函式,該函式會呼叫一次,並將所有剩餘的引數列表作為引數。

請注意,如果 Rest 關鍵字後面沒有引數,則不會呼叫該函式,而 Rest_all 關鍵字的函式會以空列表呼叫。


type spec = 
| Unit of (unit -> unit) (*

以 unit 引數呼叫函式

*)
| Bool of (bool -> unit) (*

以 bool 引數呼叫函式

*)
| Set of bool ref (*

將參考設定為 true

*)
| Clear of bool ref (*

將參考設定為 false

*)
| String of (string -> unit) (*

以 string 引數呼叫函式

*)
| Set_string of string ref (*

將參考設定為 string 引數

*)
| Int of (int -> unit) (*

以 int 引數呼叫函式

*)
| Set_int of int ref (*

將參考設定為 int 引數

*)
| Float of (float -> unit) (*

以 float 引數呼叫函式

*)
| Set_float of float ref (*

將參考設定為 float 引數

*)
| Tuple of spec list (*

根據 spec 列表取多個引數

*)
| Symbol of string list * (string -> unit) (*

取其中一個符號作為引數,並使用該符號呼叫函式

*)
| Rest of (string -> unit) (*

停止解釋關鍵字,並使用每個剩餘的引數呼叫函式

*)
| Rest_all of (string list -> unit) (*

停止解釋關鍵字,並使用所有剩餘的引數呼叫函式

*)
| Expand of (string -> string array) (*

如果要處理的剩餘引數形式為 ["-foo""arg"] @ rest,其中 "foo" 註冊為 Expand f,則會處理引數 "arg" @ rest。僅允許在 parse_and_expand_argv_dynamic 中使用。

*)

描述與關鍵字關聯的行為的具體類型。

type key = string 
type doc = string 
type usage_msg = string 
type anon_fun = string -> unit 
val parse : (key * spec * doc) list -> anon_fun -> usage_msg -> unit

Arg.parse speclist anon_fun usage_msg 會剖析命令列。speclist 是三元組 (key, spec, doc) 的列表。key 是選項關鍵字,必須以 '-' 字元開頭。spec 提供選項類型以及在命令列上找到此選項時要呼叫的函式。doc 是此選項的單行描述。anon_fun 在匿名引數上呼叫。specanon_fun 中的函式會按照引數在命令列上的顯示順序呼叫。

如果發生錯誤,Arg.parse 會在將錯誤訊息列印到標準錯誤後結束程式,如下所示

  • 錯誤原因:未知的選項、無效或遺失的引數等。
  • usage_msg
  • 選項列表,每個選項後面跟著對應的 doc 字串。請注意:具有空 doc 字串的選項將不會包含在列表中。

為了讓使用者能夠指定以 - 開頭的匿名引數,請在 speclist 中包含例如 ("-"String anon_fun, doc)

預設情況下,parse 會辨識兩個 unit 選項 -help--help,這會將 usage_msg 和選項列表列印到標準輸出,並結束程式。您可以透過在 speclist 中指定您自己的 -help--help 選項來覆寫此行為。

val parse_dynamic : (key * spec * doc) list ref ->
anon_fun -> usage_msg -> unit

Arg.parse 相同,不同之處在於 speclist 引數是參考,並且可以在剖析期間更新。此功能的一個典型用途是剖析以下形式的命令列

  • 命令 子命令 options,其中選項列表取決於子命令引數的值。
val parse_argv : ?current:int ref ->
string array ->
(key * spec * doc) list -> anon_fun -> usage_msg -> unit

Arg.parse_argv ~current args speclist anon_fun usage_msg 會剖析陣列 args,如同它是命令列一樣。它會使用並更新 ~current 的值(如果提供),或 Arg.current。您必須在呼叫 parse_argv 之前設定它。current 的初始值是陣列中程式名稱(引數 0)的索引。如果發生錯誤,Arg.parse_argv 會引發 Arg.Bad,並將錯誤訊息作為引數。如果提供選項 -help--helpArg.parse_argv 會引發 Arg.Help,並將說明訊息作為引數。

val parse_argv_dynamic : ?current:int ref ->
string array ->
(key * spec * doc) list ref ->
anon_fun -> string -> unit

Arg.parse_argv 相同,不同之處在於 speclist 引數是參考,並且可以在剖析期間更新。請參閱 Arg.parse_dynamic

val parse_and_expand_argv_dynamic : int ref ->
string array ref ->
(key * spec * doc) list ref ->
anon_fun -> string -> unit

Arg.parse_argv_dynamic 相同,不同之處在於 argv 引數是參考,並且可以在剖析 Expand 引數期間更新。請參閱 Arg.parse_argv_dynamic

val parse_expand : (key * spec * doc) list -> anon_fun -> usage_msg -> unit

Arg.parse 相同,不同之處在於允許使用 Expand 引數,並且不會更新 Arg.current 參考。

exception Help of string

當使用者要求說明時,由 Arg.parse_argv 引發。

exception Bad of string

specanon_fun 中的函式可以引發 Arg.Bad 並帶有錯誤訊息,以拒絕無效的引數。在發生錯誤的情況下,Arg.parse_argv 也會引發 Arg.Bad

val usage : (key * spec * doc) list -> usage_msg -> unit

Arg.usage speclist usage_msg 會將包含有效選項列表的錯誤訊息列印到標準錯誤。這與 Arg.parse 在發生錯誤時列印的訊息相同。speclistusage_msgArg.parse 的相同。

val usage_string : (key * spec * doc) list -> usage_msg -> string

傳回如果提供相同參數,Arg.usage 會列印的訊息。

val align : ?limit:int ->
(key * spec * doc) list -> (key * spec * doc) list

根據關鍵字的長度,在第一個對齊分隔符(Tab 或,如果找不到 Tab,則為空格)插入空格來對齊文件字串。如果想要對齊整個字串,請使用對齊分隔符作為 doc 字串中的第一個字元。對應於 Symbol 引數的 doc 字串會對齊到下一行。

limit:關鍵字和訊息長度超過 limit 的選項將不會用於計算對齊。
val current : int ref

正在處理的參數在 Sys.argv 中的位置(索引)。您可以更改此值,例如,強制 Arg.parse 跳過某些參數。Arg.parse 使用 Arg.current 的初始值作為參數 0(程式名稱)的索引,並從下一個元素開始解析參數。

val read_arg : string -> string array

Arg.read_arg file 從檔案 file 讀取以換行符號結尾的命令列參數。

val read_arg0 : string -> string array

Arg.read_arg 相同,但假設命令列參數是以空字元結尾。

val write_arg : string -> string array -> unit

Arg.write_arg file args 將參數 args 以換行符號結尾的形式寫入檔案 file。如果 args 中的任何參數包含換行符號,請改用 Arg.write_arg0

val write_arg0 : string -> string array -> unit

Arg.write_arg 相同,但使用空字元而不是換行符號作為終止符。