2012年1月25日水曜日

Racketでコマンドライン引数のパース

Racketにはコマンドライン引数をパースするための機能が備わっているようです.
ためしに簡易catコマンドを作ってみます.



#lang racket

(define line-number? #f)

(define files
(command-line
#:program "cat"
#:once-each
(("-n" "--number") "show line number"
(set! line-number? #t))
;; 残りの引数.command-lineの戻り値になる.
#:args args args))

(define output-lines
(if line-number?
(lambda (port)
(define n 1)
(for ((line (in-lines port)))
(printf "~a\t:~a~%" n line)
(set! n (+ 1 n))))
(lambda (port)
(for ((line (in-lines port)))
(displayln line)))))

(if (null? files)
(output-lines (current-input-port))
(for ((f files))
(call-with-input-file f output-lines)))


Racketに付属しているracoというツールを使って実行ファイルに変換します.



$ raco.exe exe cat.rkt

ソースファイルがcat.rktであるとすると、cat.exeという実行ファイルが作成されます(Windows)


cygwinでechoの出力をパイプすると以下のようになります.helpまで自動的に作ってくれるようです.



$ echo 'hoge
> fuga' | ./cat.exe
hoge
fuga

$ echo 'hoge
fuga' | ./cat.exe -n
1 :hoge
2 :fuga

$ ./cat.exe --help
cat [ <option> ... ] [<args>] ...
where <option> is one of
-n, --number : show line number
--help, -h : Show this help
-- : Do not treat any remaining argument as a switch (at this level)
Multiple single-letter switches can be combined after one `-'; for
example: `-h-' is the same as `-h --'

0 件のコメント:

コメントを投稿