tolower

#include <locale>
#include <iostream>
#include <string>

int main()
{
	std::locale loc("ja_JP.UTF-8");
	const std::ctype<char>& cty = std::use_facet<std::ctype<char> >(loc);

	std::string str = "HELLO WORLD.";
	std::cout << str << std::endl;
	
	for (std::string::iterator itor = str.begin();
		 itor != str.end(); ++itor)
		*itor = cty.tolower(*itor);
	std::cout << str << std::endl;

	const std::ctype<wchar_t>& wcty = std::use_facet<std::ctype<wchar_t> >(loc);
	
	std::wstring wstr = L"HELLO WORLD.";
	std::wcout << wstr << std::endl;
	
	for (std::wstring::iterator itor = wstr.begin();
		 itor != wstr.end(); ++itor)
		*itor = wcty.tolower(*itor);
	std::wcout << wstr << std::endl;

	return 0;
}

C++的にはlocaleオブジェクトからctypeファセットを取り出してそれを使ってtolower、と言うのが正しいやり方じゃないかと。
メドいですが。

あとUnicode文字コードだと結局Unicodeの等価性 - WikipediaとかもあるのでUTF-16とかUTF-32とかに揃えた上でICU - International Components for Unicodeとかに丸投げしちゃうんだろうしなぁ・・・

gnomeのショートカットキー変更

ubuntuでpidgin使ってるんですが、これのアクセラレータにCtrl+Fってのが設定してあるのがありまして、emacs使いの自分にとっては誠にイラつきの元になってました。

~/.gnome2 以下だかにそれっぽいファイルがあったんで昔はおっかなびっくりそれを直接いじってたんですが、9.04に移行したときに設定飛んだかでまたイラつく日々をすごしてたわけです。

まぁ、設定ファイルぽいのがあったからアクセラレータキーのエディタはあるんだろうなぁ、とか思ってたわけですが今日また切れたのを機にちょいとググって見たところ見つかりました。

メニューの[システム] - [設定] - [外観の設定] から [外観] タブを選択して、[メニューのショートカット・キーを編集可能にする]のチェックボックスをonにします。

んでおもむろにpidginのチャットウィンドウのメニューの[会話] - [検索] にマウスカーソルを合わせてCtrl+Sとか押すと・・・

変わりました・・・
これで文字編集中にクソなダイアログ出されて「きぃいいぃぃぃぃいいぃ!!!!!!1111!!!!!!」とか切れなくてすみそうです。


そういや、なんかでCtrl+Pでプリントのダイアログでて切れてたなぁ、と思って探してたらantlr studioでした。
こっちは変わりませんでした。まー、仕方ないか・・・

ソースパッケージのビルドオプション

debian系ディストリでは

$ apt-get -b source package-name

でソースとパッチ落っことしてきてパッチ当ててビルドしてパッケージ作成までやってくれますが、デフォルトだとCFLAGSが-g -O2です。

デバッガで追いかけるのにoptimize outされてると嫌なのでCFLAGSを-g -O0にしたい、と。

で調べたところ、結局dpkg-buildpackageとかに流れてるようなのでそっちから調べて見たところ・・・

環境変数 DEB_BUILD_OPTIONSにnooptが指定されてるとCFLAGSに-g -O0が代入される、とのことです。

それで、

$ DEB_BUILD_OPTIONS=noopt apt-get -b source postgresql

として、postgresqlのパッケージをビルドしてます・・・
いや、比較的読みやすいソースなんですけどね・・・コメント多いし>PostgreSQL

gtagsで追いかけるのに疲れたんで・・・

eq, eql, equal, equalp でハマる。

lispの比較関数でハマりました。
どういうのかって言うとstreamから文字読み出していって文字列にしてハッシュに叩き込む、というやつです。

ちょうどそれ書いてる数時間前にclsqlでテストデータ投入するコード組んでて最初、すごく遅かった(18件/秒くらい)んですが declare やらメモリの再利用やらしてやるととたんに数百倍に速度アップしてくれた後でした。

まぁ、最近始めたばっかりのlisper一年生の身としてはガベコレ遅いのねー、くらいに思って次のコードを書き始めたわけですが・・・

で、何が起こったかというとハッシュがおかしい。
文字列をキーにしてたんですが、違う文字列でgethashしてもなんかキーがマッチしてしまう・・・

で、試しに以下のサンプルコードで実験してみると・・・

(let ((a (make-array 2 :element-type 'character))
      (h (make-hash-table :test 'equal)))
  (progn
    (setf (aref a 0) #\a
	  (aref a 1) #\a)
    (setf (gethash a h) 'a)
    (setf (aref a 0) #\b)
    (gethash a h)))

結果、帰ってきた戻り値は・・・
=> A, T

・・・字面がちがうのにマッチする・・・
微かにeqとかはシンボルマッチ都下に使われる用でメモリアドレスしか見ないから文字列マッチには使ったらダメだよー、都頭にこびりついてたのでequalでつくってたんですが・・・Hyperspecちゃんと読めってことなんでしょうねぇ。

http://www.lispworks.com/documentation/HyperSpec/Body/f_equal.htmによると・・・

equal is true of two objects if they are symbols that are eq, if they are numbers that are eql, or if they are characters that are eql. 

とのことで先にeqで比較してからeqlするよー、とのこと。
つまり読み込んだ文字列をバッファに溜め込むようなやり方をすると同じアドレス上に文字列が作られるのでハッシュでは比較に使えない、ということらしいです。

で、まぁどういう風に回避したかっつーと・・・
字面ちがうと違う、同じなら同じっていう判定してほしかったので文字列をinternしてシンボルにしてeqで比較することでにげましたとさ。