2009年11月15日

プログラム名でプログラムの挙動を変える

最近も言及したconv と deconv
このプログラムのように、プラグラムの中身がほとんど同じの場合、別々にプログラムを書いて、別々にコンパイルするのが、なんだかバカらしいと感じることがある。
それで、オプションを増やして
convert -i input_encoding -o output_encoding
のように合体させることも可能だが、 実際に使う場面で、いちいちオプションを指定しないといけない(デフォルト&デフォルトでは意味が無いので、必ずどちらかのオプション指定が必要になる)しオプションも覚えておかないといけないし、長くなるのがイヤだ・
そう言う場合、プログラム名で挙動を変えるようにするといいかもしれない。
.NET の場合、
System.Environment.GetCommandLineArgs()
で、文字列の配列としてコマンドラインを取り出すことができるので、
この第一番目の内容(プログラム起動名)で、プログラムの挙動を変化させることができる。
(例のソースは「続きを読む」から)
それで、ソース名として、conv.fs として保存し、コンパイルして、conv.exe と deconv.exe を別々に作る・・・
それぐらいなら、元の2つのファイルをそれぞれコンパイルした方が良い。
Windows の場合、ショートカットを作成してdeconv のような名前を付けることで、起動できるが、
ツール起動用のパスの通ったフォルダ(例えばc:\user\bin)等に置いた場合には、Windows は、拡張子でプログラムを起動するので、実行できなくなる。
そう言う場合、
ファイル(conv.exe)を置いたフォルダで、
C:\user\bin>fsutil hardlink create deconv.exe conv.exe
のようにすると、(NTFSの場合)
deconv.exe というファイル名に、conv.exe がリンクされる(UNIX でいうln に相当の動作)。
これで、conv.exe をdeconv.exe として使えるようになる。

//conv.fs とdeconv.fs を一体化

open System
open System.IO
open System.Text

let Default_name = "conv"
let prog_name = Environment.GetCommandLineArgs().[0];
let mutable encode = Encoding.UTF8
let SetEncoding (enc:string) = 
    try
      encode <-
      match enc.ToLower() with
      | "jis" -> Encoding.GetEncoding("iso-2022-jp")
      | enc when enc = "euc" or enc = "euc-jp" -> Encoding.GetEncoding(20932)
      | _  -> Encoding.GetEncoding(enc)
    with _ ->
      stderr.WriteLine("サポートされたエンコード名ではありません"); exit -1

[<STAThread()>]
[<EntryPoint>]
let main(args) =
    match args with
    | [|"-encoding"; enc |] ->
        SetEncoding enc // enc:{utf-8, sjis, iso-2022-jp, euc, euc-jp, ... }
    | [| option |] when option = "--help" or option = "/?" ->
        Console.WriteLine("{0} [-encoding encode] //default UTF-8", prog_name); exit 0
    | _ -> ()
    //実際は、拡張子の有る無し、大文字小文字が無視できるようにする
    let enc_bk = if prog_name = Default_name then Console.InputEncoding else Console.OutputEncoding
    if prog_name = Default_name then Console.InputEncoding <- encode else Console.OutputEncoding <- encode
    let mutable line:string = null
    while (line <- Console.ReadLine();line) <> null do
        Console.WriteLine(line)
    done
    if prog_name = Default_name then Console.InputEncoding <- enc_bk else  Console.OutputEncoding <- enc_bk 

    0 //exit 0 でもOK

Posted by BLUEPIXY at 01:21│Comments(0)TrackBack(0)F# |

クリップコメント

トラックバックURL


pre表示(Firefox)

コメントする

名前
URL
 
  絵文字