LLVM r42498 on OpenBSD 4.6

折角iPod Touchをいじり始めたのだから、iPhoneアプリケーションの開発環境を整備しようと思った。
しかし、手元にあるマシンはと言うと、Windows XPのオンボロ据え置きと、Windows XP/Ubuntu(ネットブック仕様)のネットブック君と、あと一つ、OpenBSDのサーバ機君だけだ。iPhoneアプリケーションの開発環境はMac OS Xの物しか提供されていないわけで、これではどう開発した物か。
調べてみると、Cygwin on Windows XPや、*NIX上で環境を構築する方法が幾つか載っている。方法はあるにはあるようだ。iPhoneの中身を吸ったりだとか、割りとダークネスだが……

早速、ツールチェインの一つ、iphone-devを、OpenBSD君に突っ込むことに決めた。CygwinMinGW?しらない。

まずは、LLVMの準備から始める。標準ではパッケージの入手、およびコンパイルに必要な
bison, gmake, subversion がないので、pkg_addしておく。
パッケージを揃えたら、SVNリポジトリから拾って野良ビルド用のディレクトリに展開する。

$ sudo -s
# cd /usr/local/src
# svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm-svn -r 42498

ビルド用のディレクトリを掘って、そこでconfigure。ここまではマニュアル通りに進めていけば良いだけだった。

# cd llvm-svn
# ./configure --enable-optimized

さて、ここからが地獄の始まりだ……OpenBSDの呪いは恐ろしい。

gmakeするに当たって必要な小細工をあげていく。

intptr_tの定義切れ

エラー元は何処かのシステムヘッダでインクルードされていることを期待しているようだ。configure機構を採用しているのに、こういうシステム依存べったりなのは疑問だが、これは単にヘッダを追加するだけで終わる。

ADT/DenseMap.h

uintptr_t(T) が通らない。OpenBSDのuintptr_tはこういう使い方が出来ないようだ。諦めてC style castにしておく。

Bitcode/Writer/BitWriter.cpp

__gnu_cxx::stdio_bufが旧仕様。stdc++が古い、古すぎる。
コンストラクタのパラメータを旧仕様に合わせる。盛るパラメータは、新仕様のコードを見る限りdel=false, size=BUFSIZでいい様だ。

あとは、幾つか些末な不具合を取り除けばビルドが通るはずだ。
〆に

# make install

で、インストール完了。デフォルトでは、/usr/local/上にインストールされる。

LimeChatにprototype.jsの潤いを

LimeChatではwindowとかdocumentが設定されていないので、うまくごまかさないと、prototype.jsが動かない。
以下のコードを評価してから、prototype.jsを評価すれば、prototype.jsが使えるようになる。

var document = {
	getElementsByTagName : function() { return [ { src : '' } ]; }, 
	createElement : function() { return { appendChild : function() {} }; },
	createTextNode : function() {},
	createEvent : function() { return { __proto__ : {} }; },
	getElementById : function() { return {}; },
	write : function() {},
	domain : "localhost"
};
var window = {
	document : document,
	attachEvent: function() {},
	setTimeout : function(a, b) { setTimeout(a, b); }
};
var navigator = { userAgent : 'LimeChat' };
var location = { protocol : "http:", port : "" };
function Element() {}

ブラウザに依存するコードは使えない、と言うか使うシーンがない、はず。

分割メール結合アドオンJoinをThunderbird 3.0で

Outlookや、一部のメールユーザクライアントは、メールが一定以上のサイズになると、そのメールを分割して送信する機能を持っている。メールサーバのサイズ制限で大きなメールが送れないときも、この機能を使うことで、送信できるようになるわけだ。しかも、時々我々を困らせる某社独自拡張ではなく、RFC 2046(www.ietf.org)の5.2.2.で定義されており、れっきとした標準仕様である。
だが、困ったことに、Thunderbird君はこの仕様に則ったメールを受け取っても結合する術を持たない。しかも、真っ白な本文に、「attachment」なる一つの添付ファイルだけの内容を示してくるからタチが悪い。そんなに不審なメールに見せたいの?どうしてBug 71189(bugzilla.mozilla.org)を塩漬けにするの?
さて、そこで活躍するのがThunderbirdアドオンJoin(www.c-a-m.co.jp)だ。
このアドオンは、RFC 2046の5.2.2.で定義されているmessage/partial形式の分割メールを結合する機能をThunderbirdに付加してくれる。
使い方は簡単で、届いた同じ分割メールを全て選択し、右クリックから結合するメニュー項目を選ぶだけ。結合が成功すると、同じフォルダに結合後の元のメールが追加される。
しかし、このプラグインMozilla Foundationが満を持して発表したThunderbird 3.0に対応していない。もちろん、Thunderbird 3.0も分割メールに対応していない。なんてこったい……
とは言うものの、今更Thunderbird 2.*には戻りたくない。だって、Glodaが便利すぎるんだもの。
それならば、自分で動くようにするまでだ……と、意気込んでパッチ作ってしまった。

chrome/join.jar/content/join.js:116
		// 選択されているメッセージの、メッセージ URI のリストを取得する
-		var sMsgUriLst = GetSelectedMessages();
+		var sMsgUriLst = gFolderDisplay.selectedMessageUris;

		// メッセージが複数選択されていない場合、中断する

chrome/join.jar/content/join.js:323
		// よく分からない
-		var oResource = GetSelectedFolderResource();
-		var oMsgFolder = oResource.QueryInterface( Components.interfaces.nsIMsgFolder );
+		var oMsgFolder = gFolderDisplay.displayedFolder;
		var oMsgLocalFolder = oMsgFolder.QueryInterface( Components.interfaces.nsIMsgLocalMailFolder );

chrome/join.jar/content/join.js:439
		// そのフォルダのメッセージ数を取得する
-		var oView = window.GetDBView();
+		var oView = gDBView;
		var oFolder = oView.msgFolder;

chrome/join.jar/content/joinOverlay.xul:10
	<script language="JavaScript" src="chrome://messenger/content/addressbook/abMailListDialog.js"/>

-	<popup id="threadPaneContext">
-		<menuseparator />
+	<popup id="mailContext">
		<menuitem id="join" label="&join.label;" accesskey="J" oncommand="Join.Main();" />

install.rdf:7
                   em:id="{3550f703-e582-4d05-9a08-453d09bdfdc6}"
-                   em:minVersion="1.5"
-                   em:maxVersion="2.0.0.*" />
+                   em:minVersion="3.0"
+                   em:maxVersion="3.0.*" />
  <RDF:Description RDF:about="urn:mozilla:install-manifest"

似非diffぽい感じに。
使ってみると、動作は完璧(?)。ちゃんと結合が機能するし、エラーコンソールを見てもエラーらしき項目は一つも見えなかった。
これで、暫く安心してThunderbird 3を使えたらいいなぁ……?

細かいこと

このパッチを作っていて分かったこと。

* GetSelectedMessages()
廃止されました。
gFolderDisplay.selectedMessageUrisを使いましょう。

* GetSelectedFolderResource()
廃止されました。
gFolderDisplay.displayedFolderを使いましょう。

* GetDBView()
廃止されました。
gDBViewを使いましょう。

* threadPaneContext
mailContextに変更されました。

追記

2010/01/18 バージョン縛りの表記が不味かったらしいので修正した。

更に追記

公式で対応されたようだ。やったね!

KompoZerに72文字で強制改行させない

Webページデザインソフトと言えば、DreamWeaverや、Homepage Builderが有名だが、それらが買えるほど裕福ではないので、KompoZer(0.8b1)を常用している。
しかし、このKompoZerがなかなかの曲者。保存時、72文字を越える行に対して72文字毎に改行を入れてしまう。
直す方法をググってみると、Java Consoleで、

top.opener.GetCurrentEditor().wrapWidth = 9999;

と叩けばいいことが分かった。
しかし、使うたびにいちいち入力しに行くのも面倒なものだ。どうにかして自動化できないのか、と粘ってみると、方法を見付けた。
一つは、HandCoderと呼ばれるアドオンを利用する方法だ。しかし、このHandCoder、現行開発版の0.8b1には対応してないらしく、今回はこの方法が使えない。仕方ないね。
もう一つは、KompoZerのクロームのコードを書き換える方法だ。
まず、以下のようにファイルを書き換える。

// chrome/comm.jar/content/editor/editor.js:2473
function UpdateWindowTitle()
{
  try {
    var editor = GetCurrentEditor();
    if (editor) {
      editor.wrapWidth = gPrefs.getIntPref('editor.htmlWrapColumn');
    }

    var windowTitle = GetDocumentTitle();
    if (!windowTitle)

次に、AboutConfigアドオンをインストールし、editor.htmlWrapColumnパラメータに適当な数値(9999)を入力する。
そして、再起動すれば、素敵なKompoZerライフの到来だ。いくら伸ばしても改行されない。すばらしいじゃない……

プログラミング初心者は何が分からなくて詰まるのか

プログラマーは誰しも、右も左も分からないような初心者の時代を過ごして来ている。そんな頃、課題を解決している途中で詰まってしまった経験が一度はあるだろう。それは何が分からなくて詰まってしまったのだろうか。
思い返してみると、何時も入力と出力は分かっていて、分からないのは「課題を解決する具体的な手段」だった。ここで言う手段とは、アルゴリズムや、APIを指す。
それと、もう一つ考えられるのは、「具体的な手段は分かるけど、どういうコードとして書けばいいか分からない」だろう。
この中間だとか、前者よりの中間という物もあるかも知れないけど、まあどちらかと同じようなものだ。
前者は、その課題に関係する先人達の記録を訪ねてみれば、使うべき物が見えてくるだろう。最悪、Numerical Recipeと言った、手段のレシピ本を漁って、ローラー作戦的に探すという選択もある。
後者は単なる技量不足だ。技量を持てば、手段に対応するコードが目の前に浮かんでくるようになる。
どちらにせよ、言えることは一つ、「経験の差」だ。とにかく大量にコードを生産しろ、と言うことに尽きる。
(このネタを取ってきたときは、何か面白いモノが綴れそうだと思ったけど、結局、一般的な初心者と変わらない話になってしまった。物書きは全くの初心者なので、話を上手くふくらませる手段を知らないのだろう。プログラマーより、物書きからの見方で綴った方が、現在進行形で体験しているという意味で、もう少しましな物が出来たかも知れないな……)

薄氷のようなSDL

こないだ導入したruby/sdlだけど、サンプルをくるくる回しながら、ちょいとSDLのマニュアル見てみると、描画オペレーションがBitBlt系とドット打ち位しかないことに今更気付いた。ドット打ちさえあれば、直線はプレゼンハム、円はミッチェナーのアルゴリズムで再現できるけど、ねぇ。
今更図形描画なんぞ流行らなくて、スプライト転送出来ればゲーム開発にゃことたりるんですよね、ってことですか。うむむ……

Go to give up

自分「GoのCygwinポーティング計画が面倒くさく」
相手「Cygwinステステ
Cygwinポートなんて100害あって一利なし。」

(中略)

自分「うおー、cygwinにptraceがねぇ/(^o^)\」
相手「あ き ら め ろ」

Windows APIでptraceシミュレーション等やり始めたら取り返しが付かなくなるのは明らかなので、ひっそりとGoのCygwin移植計画は幕を閉じた……

……だが、しかし、Windowsへの移植は絶対諦めない……!