<前の日記(2006-01-26) 次の日記(2006-02-26)> 最新

おおいわのこめんと (2006-01-27)


2006-01-27

[Work] [Comp] Embedded-C 公開

Fail-Safe C では各種データのサイズ (int とか long とか) や、 OS の各種定数 (SOCK_STREAM とか) は基底にある標準Cコンパイラ及び OS標準ABIに合わせることになっていて、 ある種の configure 処理が必要になっている。 *1

これまでは割と場当たり的に OCaml の native method 書いたり、その場しのぎの検出プログラムを書いたり、 これまたその場しのぎで cpp + sed で処理したりしていたのだが、どうせなら汎用のツールを作って きちんと処理してやろう、ということで、すこし開発時間を確保してツールを作ってみた。

というわけでできたのが、Embedded-C。 端的にいえば、ERB や EPerl の C 言語版。 1/6日に触れた 奥君の Large-C との関係は、 perl -e と eperl の関係とか、irb と erb の関係……ってこれじゃさっぱりわからないか(苦笑)。

例えば、

<%# #include <errno.h> #%>
#define EINVAL <%=d EINVAL %>
#define EFAULT <%=d EFAULT %>

というソースを処理すると、

#define EINVAL 22
#define EFAULT 14

という感じになる。"<%=d x %>" というのが、x を printf の %d フォーマットで出力する、 という意味になっている。もちろん文の埋め込みもサポートしているので、

<%# int fib(int i) { return i <= 1 ? 1 : fib(i - 1) + fib(i - 2); } #%>
int array[1000] = { <% { int i; for (i = 0; i < 1000; i++) printf("%d, ", fib(i)); } %> };

とかやれば、フィボナッチ数列で初期化された配列とか作れるし *2、 もちろん出力言語は C ヘッダじゃなくても、OCaml でも Perl でも text file でもなんでもいい。 この手の値の検知が必要な状況で、configure.in の M4 がメンドクサイ向きにはちょうどいいかも(笑)。

変数置換に特化した autoconf の *.in → * の出力部分と違って、 埋め込む出力自体をループや関数呼出を含む複雑な処理で生成できるので、 実はちょっと複雑なC言語プログラムとマクロ定義を書いてやれば、IDL モドキまで作れてしまう。 GCC の typeof 拡張演算子と sizeof 演算子をうまく使うと、 型のサイズと種類を見て、生成する処理を分岐して……… とかできてしまうので、 結構怪しげな物が書けることは、自分で作ってから気がついた :-)。

作ってみたら結構便利そうで、自分一人で使ってるのは勿体ないので、 公開してしまうことにした。 何か面白い使い方があったらぜひ教えて欲しい。

ちなみに、お仕事の本題の Fail-Safe C の方ですが、ここ数カ月極めて順調に開発が進んでいるんで、 単なる性能評価ベンチマークじゃない、実用的に意味のあるデモが作れそうな気がしてきている。 乞御期待(笑)。

*1 特に Linux とか、昔なら #define で定義していたような各種定数がことごとく enum になってて、cpp では値取れないんだよね……

*2 当然こんないい加減な fib だと fib(999) は終了しないけど(ぉぃ

[TrackBack URL: http://www.oiwa.jp/~yutaka/tdiary/trackback.rb/20060127 (note: TrackBacks are moderated: spams will not be shown.) ]

大岩 寛 (おおいわ ゆたか) <yutaka@oiwa.jp.nospam ... remove .nospam> .

Copyright © 2005-2014 Yutaka OIWA. All rights reserved.
Posted comments and trackbacks are copyrighted by their respective posters.

記事の内容について (Disclaimer / Terms and Conditions)