c のソース中で文字列のエスケープ
2007/10/10
discypusさんに id:smeghead:20071009:trac のコメントで教えていただいた、CVStrac(http://www.cvstrac.org/) のソースを見ていたら、@ の見たことのない使い方があった。
if( i==0 ){ @ <thread><tr><th>Date</th><th width=80>Version</th> @ <th>Description</th></tr> @ <tbody> }
今自分で作ってるアプリも、テンプレートエンジン書くのが面倒で、とりあえず、Cのソースでベタ書きでhtmlを出力してるんですが、エスケープとかが、かなり面倒だし、可読性も落ちている。
是非この @ の使い方、取り入れたいんですが、#define @ でなんかやってるのかと思ったけど違うようです。(見付けられなかった。)
続きは、夜。多分追記します。
追記 tarnslate.c
やはり、上で疑問に思っていた書き方は、Cで許されているものではなかったです。コンパイルしてみてわかりました。
からくりは、まず、tarnslate.c をコンパイルすることで変換ツール(tarnslate)を作成して、各ソースを、tarnslateでフィルタした結果を別のファイルに保存して、保存したファイルをコンパイルした結果で、バイナリを生成していました。
tarnslateは、
if( g.okAdmin ){ @ <tr> @ <td valign="top"> @ <a href="setup"><b>Setup</b></a> @ </td> @ <td valign="top"> @ Setup global system parameters. @ </td> @ </tr> @ cnt++; }
を
if( g.okAdmin ){ cgi_printf("<tr>\n" "<td valign=\"top\">\n" "<a href=\"setup\"><b>Setup</b></a>\n" "</td>\n" "<td valign=\"top\">\n" "Setup global system parameters.\n" "</td>\n" "</tr>\n" "\n"); cnt++; }
に変換していました。すごい。あと、お手製ヒアドキュメントもできるようになってました。(直前の行の最後が ‘=’だったら、cgi_printfではなく、文字列にするだけにしてました。)
static char zSchemaChange_1_7[] = @ BEGIN; @ CREATE TABLE markup( @ markup text primary key, -- Style name for this markup @ type int, -- 0: markup, 1: program markup
こうゆうアクロバチックなことは、Cでは一般的なのかな。lispでcのソースを生成する話もどこかで聞いたことがあるなぁ。この程度の変換処理なら、awkで書いた方が楽かもしれない。
でも、自分が作ってるアプリに取り入れるかどうかは、もうちょっと考えてみます。