For Development HEAD DRAFTSearch (procedure/syntax/module):

11.10 srfi.37 - args-fold プログラム引数処理

Module: srfi.37

このモジュールは、args-fold を実装しています。 これは、SRFI-37で定義されている コマンドライン引数の処理をするもうひとつの手続きです。

gauche.parseopt (gauche.parseopt - コマンドライン引数の解析 参照) とは違って、args-fold は関数的なインタフェースです。すなわち、 利用者側の状態は、パーザの引数を通じて明示的に渡され、値が返ります。 また、ロングオプションを含む、POSIX および GNU の getopt のガイドラインに 準拠しています。

Function: args-fold args options unrecognized-proc operand-proc :rest seeds

[SRFI-37]{srfi.37} 与えられたオプション仕様 options および、ふたつの手続き unrecognized-procoperand-proc とにしたがって、プログラム 引数 args を左から右へ処理します。

options はオプションオブジェクトのリストで以下のようなものです。 各オプションオブジェクトはオプションの名前、そのオプションが引数を とるかどうかを指定するフラグ、そのオプションを処理する手続き (今後これを オプション手続きとよびます)を保持しています。

args-fold は単一文字のオプション(ショートオプション)と ロングオプションの両方を認識します。ショートオプションは単一の ハイフンで始まって(たとえば、-a)いなければなりません。一方、 ロングオプションは二つのハイフンで始まって(たとえば、--help) いなければなりません。ショートオプションは連結することが可能で、 たとえば、-abc あるいは -a -b -c と書くことができます。 ショートオプション、ロングオプションはともに、必須引数あるいはオプショナル 引数を取ることができます。ショートオプションの必須引数は当該オプション あとに空白なしあるいは空白をいれて指定することができます。たとえば、 -afoo あるいは -a foo が可能です。ロングオプションの 引数は’=’文字あるいは空白をはさみます。たとえば、 --long=foo または --long foo です。

args-fold はオプションの引数ではなく、ハイフンで始まっていない コマンドライン引数をオペランドとしてとりあつかいます。 args-fold はオペランドとオプションが交互に出現するのを許します。 しかし、’--’ に出逢うと、のこりは、ハイフンで始まっていようと なかろうと、オペランドとして扱われます。

与えられたオプションが options 内のオプションオブジェクトのひとつ にマッチすれば、オプション手続きが以下のように呼出されます。

(option-proc option name arg seed ...)

ここで、option はマッチしたオプションオブジェクトで、name は実際にオプションを指定するのに使われた文字列、arg はそのオプション の引数(あるいは存在しなければ、#f)、そして seed … は 利用者側の状態情報です。option-procseed と同じ数だけ 値を返さなければなりません。

args-fold がオペランドを見つけたら、operand-proc が 以下のように呼出されます。

(operand-proc operand seed ...)

operand-procseed と同じ数だけ 値を返さなければなりません。

呼出し側の状態は明示的にシード引数で渡され、戻されます。初期のシード値は args-fold に与えた seed です。この値は、オプション手続き unrecognized-procoperand-proc によって戻され、 次にこれらのオプション手続きの呼出し時にシード引数として使われます。 これらの手続きの最後の呼出しから返されたこの値は args-fold によって 返されます。

Function: option names require-arg? optional-arg? processor

[SRFI-37]{srfi.37} 渡されたプロパティでオプションオブジェクトを作成します。

names は文字と(あるいは)文字列のリストです。文字はショートオプションに 使い、文字列はロングオプションに使います。

ふたつのフラグ require-arg?optional-arg? はオプションが 必須引数をとるか、あるいは、オプショナル引数をとるかを示します。

processor はそのオプションの処理をする手続きです。

オプションの引数が ’=’ つきで渡された場合には、 たとえ require-arg?optional-arg? がともに #f であっても、そのオプションの引数はオプション処理手続きに渡されることに 注意してください。オプション手続きにその引数を処理させようとします。

ショートオプションに対するオプショナルなオプションの引数は、オプションに つづいてスペースなしで指定されたときにだけ認識されることにも 注意してください。たとえば、ショートオプション d がオプショナル 引数をもつことになっているとき、’-dfoo’ は ’-d’ が引数 ’foo’ をもつと解釈されますが、’-d foo’ は引数なしの ’-d’ とオペランド ’foo’ と解釈されてしまいます。もし、 ’-d’ が必須引数をもつと設定されているなら、両方ともに ’-dfoo’ は ’-d’ が引数 ’foo’ をもつと解釈されます。

Function: option? obj

[SRFI-37]{srfi.37} obj がオプションオブジェクトなら #t を返し、 そうでなければ、#f を返します。

Function: option-names option
Function: option-required-arg? option
Function: option-optional-arg? option
Function: option-processor

[SRFI-37]{srfi.37} オプションオブジェクト option のプロパティを返します。

簡単な例:

(use srfi.37)

(define options
 (list (option '(#\d "debug") #f #t
               (lambda (option name arg debug batch paths files)
                 (values (or arg "2") batch paths files)))
       (option '(#\b "batch") #f #f
               (lambda (option name arg debug batch paths files)
                 (values debug #t paths files)))
       (option '(#\I "include") #t #f
               (lambda (option name arg debug batch paths files)
                 (values debug batch (cons arg paths) files)))))

(define (main args)
  (receive (debug-level batch-mode include-paths files)
    (args-fold (cdr args)
               options
               (lambda (option name arg . seeds)         ; unrecognized
                 (error "Unrecognized option:" name))
               (lambda (operand debug batch paths files) ; operand
                 (values debug batch paths (cons operand files)))
               0      ; default value of debug level
               #f     ; default value of batch mode
               '()    ; initial value of include paths
               '()    ; initial value of files
               )
     (print "debug level = " debug-level)
     (print "batch mode = " batch-mode)
     (print "include paths = " (reverse include-paths))
     (print "files = " (reverse files))
     0))


For Development HEAD DRAFTSearch (procedure/syntax/module):
DRAFT