Hatena::Grouperlang

檜山正幸のErlang未確認情報 RSSフィード

 | 

2009-03-17 (火)

コマンドライン引数 (2)

| 14:33

実際的な対処としては、プレーン引数という概念を一切使わなければそれで済む。これ以上詮索するのは虚しい話なんだが、気になるのでまた少し調べた。推測が多いのでアテにならないけど。

どうも、マニュアル(または仕様)の著者と、CパートのプログラマErlangパートのプログラマで意識がだいぶズレてるようだ。

http://www.erlang.org/doc/man/erl.html :

Plain arguments are not interpreted in any way. They are also stored by the init process and can be retrieved by calling init:get_plain_arguments/0. Plain arguments can occur before the first flag, or after a -- flag. Additionally, the flag -extra causes everything that follows to become plain arguments.

これによれば、プレーン引数

  1. 最初のフラグの前
  2. --フラグの直後
  3. -extraフラグに後続する全ての引数

のハズ。僕は、"after a -- flag"を誤読していて、-extraと同じく、--が出現したらそこから先はフラグの認識をしなくなるかと思っていた。Cパートの引数処理を見ると、どうも僕と同じ解釈(誤解)をしているっぽい。

    while (i < argc) {
        if (argv[i][0] != '-') {
            erts_usage(); // 終了してしまう
        }
        if (strcmp(argv[i], "--") == 0) { /* end of emulator options */
            i++;
            break;
        }
        switch (argv[i][1]) {
        // 
        // 省略
        //
        default:
            erts_fprintf(stderr, "%s unknown flag %s\n", argv[0], argv[i]);
            erts_usage();
        }
        i++;
    }

"--"はオプションフラグ)解析ループをbreakで終了させる。

'+'で始まるオプションエミュレータフラグ)の解析部分と、CパートからErlangパートへのコマンドライン受け渡しがイマイチ分からないのだが、init.erlを見てみた。Erlangで書かれているから解読しやすい。

[追記]erts/etc/common/erlexec.c がホントの起動コマンドのようだ。これのmain()から execv(emu, Eargsp) からエミュレータのmain()を呼んでいる。このとき、引数の配列を編成し直してからエミュレータに渡している。よって、erlexec内での引数処理も見ないとダメだね。[/追記]

Erlangパートinit.erlの作者は、明らかに"--"を違った意味で解釈している。"--"をend_argsというシンボルで表しているが、argsはなんと「フラグ引数」を意味している。つまり、-foo bar baz -zot ... というコマンドラインがあると、bar baz はフラグ-fooの引数パラメータとか呼んで区別すべき!!)と呼んでいる。そのフラグパラメータの終了を"--"でマークするという解釈(これは間違いない)。

したがって、-foo bar -- baz -zot なら、-fooのパラメータはbarだけとなり、bazはプレーン引数となる。-foo -- bar baz -zot なら、-fooのパラメータはナシ、bar bazはプレーン引数となる。また、--がどのフラグよりも前に出現してしまうとプレーン引数扱いとなる。フラグのスコープ内に出現したときだけ、"--"がend_of_flag_paramsとなるわけ。

「最初のフラグの前はプレーン引数」という記述もErlnagパートだけなら正しい。が、Cパートはそうなってないようだ。

事実として:

  1. "--"は、直後の引数を強制的にプレーン引数とみなすエスケープのようには働かない。
  2. 原則的に、"--"はフラグパラメータ列を終了させるマーカー(データではない)。
  3. だが、出現位置により "--"自体がプレーン引数データとみなされる。
  4. また、出現位置により "--"がCパートのオプション解析を終了させるマーカー。
  5. -extraは、後続の全ての引数を強制的にプレーン引数にする効果を持つ。

なんか悲惨。

 |