読者です 読者をやめる 読者になる 読者になる

Meta/Multi Line Preprocessor 動作説明

はやく書かないと忘れてしまいますよ。いやすでにわすれている。

mlpp.yml に使用可能なプリプロセッサとその情報、使用可能なコンパイラとその情報が書いてあるみたいです。

まず、行情報を保持しなければなりません。ファイルなめて情報を記録するということを考えましたがファイルの比較は大変そうなので、プリプロセッサの影響を受けない行を挿入し、プリプロセスの後にその行を読んで行情報がどう変わったか、ということを調べてるみたいです。例えばプリプロセッサが m4 や eruby の場合は #pragma mlppline 38 "hoge.c" なんていう行を埋めてるみたいです。文字列はなんでもいいみたいですけど、なにぶんプリプロセッサやることだからなにやるかわからんということで、万一残っても大丈夫な可能性の高い #pragma で始める文字列を選んだのではないかと。プリプロセッサの情報は mlpp.yml の preprocessors セクションにあるようです。 #pragma... の一節を変換しないプリプロセッサであれば、 mlpp_line_info: pragma_line_info とコマンド名を記述する行を書けば簡単に対応プリプロセッサを増やすことができるんじゃないかと思います。

次にコンパイラに渡すのですけど、何故プリプロセッサと言いつつコンパイラを動かすかというと、結局行情報の表現の仕方はコンパイラ依存で、コンパイラの情報登録するならついでにコンパイルもしちゃえ、ということと、 Java なんかの場合は出力を横取りしなくちゃならんからだと思われます。そういう意味でメタプリプロセッサというのもどうかと。 mlpp.yml の compilers セクションにコンパイラ情報を保持します。 lang_line_info: cstyle_line_info と書けば C スタイルで行情報をファイルに埋め込みます。 cstyle_line_info の定義はまた別なセクションに登録されています。後 command と output でコンパイラを起動するコマンドと出力ファイルを指定するオプションを登録するみたいです。 suffix は出力が指定されなかった時に使うように(ソースを読む限り)見えます。 Java の場合は少し別な定義がされてます。 replaceFrom と replaceTo でコンパイラ出力の変換を行ないます。 replaceFrom は正規表現です。 runtimeReplaceFrom と runtimeReplaceTo で例外時の行情報の変換を行ないます。

それと suf_to_* のセクションはよくわかりません。最初拡張子プリプロセッサコンパイラを指定できるようにしてた気がしますが、ちゃんと動くことやら。だいたい拡張子からプリプロセッサを同定できる理由が無いでしょう。

-l を付けることによって . で始まるファイルに行情報が保持されますが、これも YAML ファイルです。 mlppfilt は起動時に問答無用で全ての .*.lines ファイルを読むようなので、二つのプロジェクトが同時に同じディレクトリで進行中だったりするとおかしなことになるかもしれませんが、やっぱり大丈夫な気がしました。ファイル名違いますし。

えー、ひどいせつめいでした。とにかく結論としては mlpp.yml をいじればプリプロセッサ増やすこともわけないに違いない、ということです。あれれなんかもっと説明すべきことがあった気がするのにさっぱり思い出せないよ。

Meta/Multi Line Preprocessor 更新

気が向いたので。

http://shinh.skr.jp/mlpp/mlpp.tar.bz2

テンポラリファイルは -s を付けない限りは消します。 -v を付けない限りメッセージを吐きません。

独自マクロをサポートしました。とりあえず __MLPP_LINE__, __MLPP_FILE__, __MLPP_FUNCTION__, __MLPP_CLASS__ を。

        __MLPP_CLASS__:
            match: '^(\s*(public|protected|private|final)\s+)class\s+(\w+)'
            to: '"$3"'

などと設定すると、 match の方の正規表現を毎行チェックして、前回マッチしたデータを使用して to に置換します。

もちろんこの正規表現に従ってないとダメなので __MLPP_FUNCTION__ と __MLPP_CLASS__ はかなりいいかげんなものだと言えます。でも D 言語で、

class Test {
    static void test() {
        printf("line=%d\n", __MLPP_LINE__);
        stdout.writeLine("file=" ~ __MLPP_FILE__);
        stdout.writeLine("func=" ~ __MLPP_FUNCTION__);
        stdout.writeLine("class=" ~  __MLPP_CLASS__);
    }
}

などと書いて func=test class=Test と出るのは嬉しいですね。

あと -c で設定ファイルを指定できるみたいです。前からあった機能らしい。

なにかあれば下記メールアドレスへ。
shinichiro.hamaji _at_ gmail.com
shinichiro.h