2011年2月
02/01
FreeBSDでのOpenOffice.org(3.2.1)のコマンド名
Linux版だとsoffice -writerとかsoffice -calcのようにして各機能を指定する(オプションなしで全体メニュー)が、自宅のマシンでOOoをビルドしたところsofficeコマンドが見つからない。良く見たらこれは/usr/local/openoffice.org-3.2.1/openoffice.org3/program/sofficeとして存在し、openoffice.org-3.2.1-swriterとかopenoffice.org-3.2.1-scalcみたいなコマンド(シェルスクリプト)を通して呼び出す形となっていた。
02/05
Wikiでのドキュメンテーション時の等幅文字の使用
- FPの辞書とかdwmの解説を書いていて、ファイル名、パス、環境変数、コマンド名やコマンドラインオプションなどに等幅文字を使うことにした。
例えばソフトウェア名としてのgccはgccだが、コマンドとしてのgccはgccと表記することにした
- うまく使うとかなり見やすくなるが、濫用すると鬱陶しいし、何より書くのが面倒。さじ加減が難しいところ
02/06
CapsLock不用論に関する実験
- 目的: 自宅の家族共用マシン(WinXP)で残念な思いをしないようにする。
原理: CapsLockをCtrlにこっそり変更しておく。もししばらく経っても誰からも文句がでなければ、それはすなわち誰もCapsLockを使っていないということである。
- 方法: レジストリを編集した。
結果: 1日目に「CapsLockが効かない」という発言が確認され、実験を終了した。設定は元に戻した。
考察: CapsLockの需要はあると考えられる。
ImageMagickで画像の切り出しを行う
convertコマンドを使う。
convert -crop <width>x<height>+<x>+<y> inputfile outputfile
で、inputfileから座標(x, y)を始点として幅width、高さheightの矩形を切り出し、outputfileとして保存する
02/07
X11フォワーディングしてきたアプリケーションで日本語を入力する
リモートホスト上で環境変数XMODIFIERSを設定する。例えばibusを使っているなら
export XMODIFIERS="@im=ibus"
02/09
ArchWikiの翻訳をやってみようかと思ったり思わなかったり。
02/11
勉強したことを記録していくと、何もやらなかった期間はぽっかり記録が空くので良いかもしれない。とりあえず、積みっぱなしの「初めてのPython」をちゃんと読んで勉強しようと思う。それからOCamlももっと書く。買った本に練習問題が付いているので、解いてみるのも良いか。
オレンジジュースに求めるもの
今日、もとい昨日飲んだものが期待に反してあまりにも残念だったので、個人的にオレンジジュースに対して求めるものを書いておく。
- 果汁100%
- 程よい酸味
- オレンジジュースは若干ツンツンしているくらいが丁度いいと思う。デレデレのオレンジジュースに用はない。
- 強く残りすぎない程度の風味
三日くらい経ってから読み返したら、何でこんなものを書いたのかと自分でも思うかもしれないが、こういうのはそのときの感情が大事なのだろう、ということで残しておく。
なんだこれ
作ったものをgitの管理下に入れようと思いたち、nestでcommitした際のエラーメッセージ(commit自体はできた)。
".git/COMMIT_EDITMSG" [変換済] 21L, 514C /usr/local/share/vim/vim73/syntax/diff.vim の処理中にエラーが検出されました: 行 62: E401: パターン区切りがみつかりません: "^Δεν υπάρχει χαρακτήρας νέας γραμμής στ > ο τέλος του αρχείου" E475: 無効な引数です: diffNoEOL^I"^Δεν υπάρχει χαρακτήρας νέας γραμμής στο τ > έλος του αρχείου"
gitではなくvimがエラーメッセージを吐いている。件のファイル/usr/local/share/vim/vim73/syntax/diff.vimはUTF-8だが、これが原因なのだろうか。エラーが出ているのはギリシャ語(el)のセクションである。試しに、適当なdiffファイルを作ってvimで開いたところ全く同じ出力が得られた。もう少し調べてみようと思う。
もちろんsyntax offであればエラーは出ない
02/12
個人ページ以下の構造に手を加えた。ある程度文書としての形が出来上がったものはdocに置く所存
家のマシン(FreeBSD 8.1-RELEASE amd64)でOpenOffice.org 3.3.0をビルドした
- 10から11時くらいに始めて、終わったのは16:40くらい。ハードウェアは調布祭のときのあれ
- バイナリパッケージも作った
[clear@mirage /usr/ports/packages/All] $ ls -lh total 394283 -rw-r--r-- 1 root wheel 192M 2月 12 16:34 ja-openoffice.org-3.3.0.tbz
02/13
- 今更ながら、毎回2011/02と年月まで書いているのは無駄なことに気づく
- 04/16 直した
02/14
よくわからない
C++において、C標準ライブラリの中身はstd名前空間に入る。これを用いるには、例えばstdio.hではなくcstdioをインクルードする。ただし、互換性のためC++でもstdio.hを使うことができる。この場合グローバル名前空間に入る。
nestで/usr/include/c++/4.2/cstdioを読むと、だいたい以下のようなことをやっていた。
// cstdio
#include <stdio.h>
// ...
namespace std {
using ::printf;
// ...
}
よって、こういうコードが通る。
ここまでが前提。
snprintf()を使うコードを書いていた。これはC99で標準となった。C++においてC99の機能は、一部がTR1や0xで取り込まれている(完全ではないが今回は問題ないはず)。そこでtr1/cstdioをインクルードしたのだが、std::tr1::snprintf()のように呼び出すと「snprintfはtr1の中に無い」とコンパイルエラーが出る。std::snprintf()としてもやはりstdの中には無いと言われる。前提に立ち返ると、これはすなわちstd::tr1とかstdの中でusing宣言がされていないということだ。一体どうなっているのだろう。tr1/cstdioを読むと上に書いたような形でusing宣言されている。#ifdefに囲まれているのでその辺の問題なのか。
色々考えていて、もう一つ気になった。そもそも先に上げた前提は(事実ではあるが)正しいのかということだ。std::と修飾することを「必要」としている文章も見つかった(こことか)。この場合、標準Cライブラリの中身がグローバル名前空間で見えてはいけないことになる。
これに関してWikipediaの記事に興味深い記述があった。
... また、標準Cライブラリとの互換性を持たせるため、<xxx.h> 形式のヘッダも使用することができ、std 名前空間内で宣言された識別子はusing指令によってグローバル名前空間に引き出される。
「引き出される」ということはつまり初めからグローバル名前空間にある訳ではないということだ。英語版を見ると
... The only difference between these headers and the traditional C Standard Library headers is that where possible the functions should be placed into the std:: namespace (although few compilers actually do this).
std名前空間内に配置されるべき(グローバル名前空間から見えるべきではない)だが、実際にそのように実装しているコンパイラはほとんど無い、ということだろうか。
- google先生に聞いたりしたところ、"where possible"は「可能なら」という意味らしい。つまりグローバルに見えても良いということか
結論: 試験勉強をすべきときに色々気にし出すとよくない。
OpenOffice.org 3.3.0
家でコンパイルしてきたのが端末に入った。libsigsegvが無いと言われて残念な思いをしたが、別途入れたらOKだった。動作も少し試した限りでは問題無し。
02/15
これが画面を分割しすぎた者の末路だ
- もうよくわからない
02/21
設定リーダの実装
02/23
STLのアルゴリズムを駆使したら開発効率が上がった気がする。
STLアルゴリズムと述語の話
文字列からトークンを切り出すために「ある位置から空白(ここではスペースとタブ)か、デリミタまで」の部分を得たかったので、ちょうど使えそうなstd::find_if()を試すことにした。find_if()はイテレータfirst、lastと述語(真偽値を返す関数あるいは関数オブジェクト)predを受け取り、[first, last)の範囲で最初にpredが真となるような要素のイテレータを返す。
まず、述語として次の関数オブジェクト(ファンクタ)is_token_endを用意した。std::binary_function(二引数の関数オブジェクトのための基底クラスとして用意されている)を継承して作る。
// トークンの終わりかどうか
struct is_token_end : public std::binary_function<char, char, bool>
{
bool operator()(char c, char delim) const
{
return is_ws(c) || (c == delim); // is_ws()は単純に(c == ' ' || c == '\t')の値を返すだけの関数
}
};
ここで問題になるのがpredは一引数の関数へのポインタか、または一引数のoperator()を持つ関数オブジェクトでなければならないことだ。しかしデリミタが定まっていない以上引数として与えるしかないので、二引数となる。これではfind_if()に渡すことが出来ない。これは、「is_token_endとdelimを受け取って、『文字cを受け取りis_token_end(c, delim)の値を返すような(operator()を持つ)一引数の関数オブジェクト』を返す関数」があれば解決する。これに相当するのがstd::bind1st()あるいはstd::bind2nd()だ。以下のようにして使う。
// ...
string::iterator key_end = find_if(i, end, bind2nd(is_token_end(), delim));
// ...
いくつかのミスによるコンパイルエラーを経たものの期待通りに動作し、めでたしめでたし…と思いつつ、色々googleで調べていたところ、わざわざbindしないでいい(binary_functionである必要が無い)という方法を見つけた。具体的にはここ。すなわち、関数オブジェクトにメンバ変数として比較対象を持たせることでunary_function(一引数の関数オブジェクト…略。ちなみにbinaryまでしかない)にできる。
// トークンの終わりかどうか
struct is_token_end : public std::unary_function<char, bool>
{
explicit is_token_end(char delim) : delim_(delim) {}
bool operator()(char c) const
{
return is_ws(c) || (c == delim_);
}
private:
const char delim_;
};
bindする必要がなくなるので、呼出側はすっきりする。
// ...
string::iterator key_end = find_if(i, end, is_token_end(delim));
// ...
これも期待通りに動き、こちらの方が綺麗なのでなるほどと思っていたのだが、一つだけ気になることがある。つまり「述語がメンバ変数を持っていて良いのか」ということだ。値を書き換える訳でもないから大丈夫だとは思うけれど(そもそもconstな時点で書き換えられないが)。ともあれ、なんだかfunctionalな感じでSTLのアルゴリズムをいじるのは楽しい。考えた人の頭の良さを感じて止まない。
02/28
ftdi.hpp
kagisysに使われているlibftdiにはC++のラッパーがあった。pimplイディオムを使うために<boost/shared_ptr>を使っているので、使うとしたら依存関係にboostが加わることに。一応shared_ptrはTR1に入っている(多分互換性はある)ので、ライブラリを書き換える手もある。
- 使わないでも良い気がする