gencomp 確認 (14)
やっぱ手を動かさないと駄目だな、と言いつつ以下なソレをでっち上げ。
(use gauche.parseopt) (define (main args) (let-args (cdr args) ((keep-private-macro "keep-private-macro=s" #f) (ext-module "ext-module=s" #f) (output-base "o|output=s" #f) . args) (when keep-private-macro (format #t "keep-private-macro = ~s\n" keep-private-macro)) (when ext-module (format #t "ext-module = ~s\n" ext-module)) (when output-base (format #t "output-base = ~s\n" output-base)) (format #t "args = ~s\n" args)) )
上記はスクリプトにしてナニ。確認事項は以下。
- オプション引数の正常な取り扱い
- 一つ指定
- 二つ指定
- 定義順
- 定義順をあえて外す
- オプション引数と普通の引数
- 通常の指定
- 普通の引数の後に指定されたオプション引数は無視
- オプション文字列間違い
- 例外発生
- オプション引数指定なし
ヤッてみます。
$ gosh test2.scm -keep-private-macro=xx keep-private-macro = "xx" args = () $ gosh test2.scm -keep-private-macro xx keep-private-macro = "xx" args = () $ gosh test2.scm --keep-private-macro=xx keep-private-macro = "xx" args = () $ gosh test2.scm --keep-private-macro xx keep-private-macro = "xx" args = () $
二つ指定で色々。
$ gosh test2.scm -keep-private-macro x -ext-module=y z keep-private-macro = "x" ext-module = "y" args = ("z") $ gosh test2.scm -ext-module=y -keep-private-macro x z keep-private-macro = "x" ext-module = "y" args = ("z") $
順不同。ただし
$ gosh test2.scm -keep-private-macro x z -ext-module=y keep-private-macro = "x" args = ("z" "-ext-module=y") $
は仕様上、許容されてない。あと、オプション文字列間違いは
$ gosh test2.scm -keep-private-macr=xx *** ERROR: unrecognized option: "keep-private-macr" Stack Trace: _______________________________________ 0 (build-option-parser (list (list "keep-private-macro=s" (lambda x ... [unknown location] $
叱られる。オプション無しだと以下なカンジ。
$ gosh test2.scm x yy zzz args = ("x" "yy" "zzz") $
let-args 掘ってくのは別途で。
(match args ((scmfile) ...)) の動作について
- ext/util/util-match-lib.c がソースな模様
- libsrc/util/match.scm がその元な模様
gencomp では以下な記述 (main 手続きの一部のみ
(match args ((scmfile) (when ext-module (ext-module-file (ensure-ext-module-file ext-module))) (do-it scmfile (or output-base (sys-basename (path-sans-extension scmfile)))) (when ext-module (close-output-port (ext-module-file)))) (else (print "Usage: gosh gencomp [--keep-macro] <file.scm>") (exit 0)))
最初は scmfile ってパターンは何か特別な記述? とか手続き? とか色々カン違いしながら色々調べてたんですが、どうやら残りが一つじゃないとダメ、という意味しかない模様。
ええと (match args ((scmfile) ...)) の意図は (scmfile . '()) かどうか、という意味らしい。成程。
てーコトはオプション引数以外は引数一つだかんね、という意味ですな。先のナニを以下に修正して試験。
(use util.match) (use gauche.parseopt) (define (main args) (let-args (cdr args) ((keep-private-macro "keep-private-macro=s" #f) (ext-module "ext-module=s" #f) (output-base "o|output=s" #f) . args) (when keep-private-macro (format #t "keep-private-macro = ~s\n" keep-private-macro)) (when ext-module (format #t "ext-module = ~s\n" ext-module)) (when output-base (format #t "output-base = ~s\n" output-base)) (match args ((scmfile) (format #t "scmfile = ~s\n" scmfile)) (else (print "Usage: gosh gencomp [--keep-macro] <file.scm>") ))) )
で、試験。
$ gosh test3.scm x scmfile = "x" $ gosh test3.scm Usage: gosh gencomp [--keep-macro] <file.scm> $ gosh test3.scm -o xxx.out yyy output-base = "xxx.out" scmfile = "yyy" $
なんと言えば良いかわかりませんが便利だなぁ。(感想が微妙杉
sys-dirname について
マニュアルによれば (use file.utils) しないとダメな模様
gosh> (use file.util) #<undef> gosh> (sys-dirname "/home/hoge") "/home" gosh>
上記は ensure-ext-module-file 手続きのナニ
(define (ensure-ext-module-file filename) (let1 dir (sys-dirname filename) (unless (file-exists? dir) (make-directory* dir)) (open-output-file filename)))
ええと、ディレクトリが無ければ作って出力ファイルとして open して open-output-file の戻りを戻す、のでしょうか。
ちなみに呼び出し元な記述は以下 (main 手続きの一部のみ
(match args ((scmfile) (when ext-module (ext-module-file (ensure-ext-module-file ext-module)))
ちなみに ext-module-file はグローバルなスコープで定義されてた
(define ext-module-file (make-parameter #f))
これも動作確認。
gosh> (use gauche.parameter) #<undef> gosh> (define test (make-parameter #f)) test gosh> (test "a") #f gosh> (test) "a" gosh> (test) "a" gosh> (test "b") "a" gosh> (test) "b" gosh>
これは gauche 本の 22.7 節に解説あり。let-args 色々試してみるのは面白そげ。