前回紹介したWiki、Gollum。すでにレポジトリに入っているものに対しては問題なく日本語ファイル名も使えるのだが、Createするときに問題がある。それは...
このように日本語ページへのリンクを作り、
リンクをたどってCreateさせると...
"nituite"はいいにしても"ri ben yu"は日本語じゃありませんから!
これはあまりにもひどいので調べたところ、"to_url"というメソッドがこの変換をやっている模様。あまりはっきりとは調べてないのだが、どうやらstringexというモジュールに"Unidecode"という機能があり、これをしているようだ。
仕方ないので、この機能を外した。to_urlはどうもこのページ名の調整に使っているっぽいので、すべてのto_urlを機能しなくした。それに伴いURLエンコードが必要になる部分があるので、対応した。
その変更がこちら。
2012-11-18
GitバックエンドなWiki「Gollum」をインストールする
Gitit使ってたんじゃなかったのかよ、という話なのだが、Gititは単体でディレクトリ以下にホストできない((Virtual)Host必須)とか、いろいろ遭遇したので、別のものを使ってみた。
使ってみたのは、Githubの(?)Wiki engine「Gollum」
http://github.com/github/gollum
Ruby, Sinatraのお馴染みの構成。今のところRuby 1.8でも動く優しい仕様。
画面はこんな感じ。
bundleコマンドが使える状態になったら、bundleコマンドを叩く前に、libxsltの開発パッケージをインストールする(自分のところでこれが足りなかっただけで、他にも必要かも)
あとは、cloneしてbundle installすればOK。
あとはhttp://server:5080/wiki/にアクセスすればOK.
--host 127.0.0.1をつけたいんだけど、--helpに書いてあるのにまさかの無視される罠があるのでそのままでは使えない。(これも対応させた。)
マージされたので--host使えます。
これで概ね使うことができる。
使ってみたのは、Githubの(?)Wiki engine「Gollum」
http://github.com/github/gollum
Ruby, Sinatraのお馴染みの構成。今のところRuby 1.8でも動く優しい仕様。
画面はこんな感じ。
インストール
gemで入れる方法もあるが、細かい事情によりちょいちょいいじる必要があるため、git cloneしてbundlerで拾ってくる方法を取る(bundlerは例えばUbuntu 12.04ならapt-get install ruby-bundlerで入る。)bundleコマンドが使える状態になったら、bundleコマンドを叩く前に、libxsltの開発パッケージをインストールする(自分のところでこれが足りなかっただけで、他にも必要かも)
# apt-get install libxslt-dev
あとは、cloneしてbundle installすればOK。
$ cd ~/opt $ git clone https://github.com/github/gollum.git $ cd gollum $ bundle install --path vendor/bundler
設定
保存するためのgitレポジトリを作る。$ mkdir ~/wikidata $ cd wikidata $ git init--bareで作ったものは2012/11/17時点のmasterでは怒られる(手元のは対応させちゃった)
実行方法
bundlerで入れたので、bundle execを使う。$ bundle exec bin/gollum --port 5080 --base-path wiki ~/wikidata--base-path wikiを指定すると、/wiki/がトップになる(=ProxyPassするときに便利)
あとはhttp://server:5080/wiki/にアクセスすればOK.
デーモン化
例によってrunitを使った。以下のような感じ。$ mkdir -p ~/var/log/gollum $ mkdir -p ~/service/.gollum/log $ vi ~/service/.gollum/run ~~~ #!/bin/sh echo "Start." cd ~/opt/gollum exec bundle exec bin/gollum --host 127.0.0.1 --port 5080 --base-path wiki ~/wikidata 2>&1 ~~~ $ chmod +x ~/service/.gollum/run $ vi ~/service/.gollum/log/run ~~~ #!/bin/sh exec svlogd -tt ~/var/log/gollum ~~~ chmod +x ~/service/.gollum/log/run $ mv ~/service/.gollum ~/service/gollum
マージされたので--host使えます。
認証
Apacheでかける。<Location /wiki>
AuthUserFile /dokka/www/htpasswd-wiki
AuthGroupFile /dev/null
AuthName "Input password"
AuthType basic
require valid-user
</Location>
ProxyPass /wiki/ http://127.0.0.1:5080/wiki/
ProxyPassReverse /wiki/ http://127.0.0.1:5080/wiki/
これで概ね使うことができる。
2012-11-17
blockdiag-mediawiki-extensionをseqdiag,actdiag,nwdiagに対応させた
blockdiagのMediaWiki対応が素晴らしかったので、他のseqdiag, actdiag, nwdiagにも対応させた。PHPなんてひさしぶりで、arrayの書き方覚えてなかったよ。pull requestしたので、うまくいけば取り込んでもらえるかも。
対応してて気付いたのだけど、nwdiagにはrackdiag, packetdiagなんてのもあるのね。ラック図はまぁそうだよねって感じだけど、パケットのアレを描くという発想はなかった... バイナリアン達には便利かも。
(追記)
早速取り込んでいただけました。
対応してて気付いたのだけど、nwdiagにはrackdiag, packetdiagなんてのもあるのね。ラック図はまぁそうだよねって感じだけど、パケットのアレを描くという発想はなかった... バイナリアン達には便利かも。
(追記)
早速取り込んでいただけました。
2012-11-10
MSBuild Launcher 0.0.2リリース
MSBuild Launcher 0.0.2をリリースした。
https://github.com/sunnyone/MsbuildLauncher/downloads
キャンセル機能がついた。といっても、ビルド処理を別プロセスで立ち上げてキャンセルしたいときはKillするというアグレッシブな仕様だけど。
https://github.com/sunnyone/MsbuildLauncher/downloads
キャンセル機能がついた。といっても、ビルド処理を別プロセスで立ち上げてキャンセルしたいときはKillするというアグレッシブな仕様だけど。
bkimgprocに傾き補正機能を追加
bkimgprocに傾き補正機能を追加した。
(といっても、-deskew 40%を引数に追加しただけだけど)
ちなみに、"t"を指定された場合のみ機能するようになっている。テキストでないと誤爆しそうだったので。これでようやくmとtを分けた意味がでてきた。
(といっても、-deskew 40%を引数に追加しただけだけど)
ちなみに、"t"を指定された場合のみ機能するようになっている。テキストでないと誤爆しそうだったので。これでようやくmとtを分けた意味がでてきた。
2012-10-27
2012-10-25
C#の"ref"引数のMSIL的取り扱い(.NETと参照渡し)
C#でrefを使ったメソッドのMSIL的作り方/呼び出し方(参照渡しの方法)についてメモしておく。
これをコンパイルしたものを逆アセンブルしたものが以下。
(評価スタックのイメージを忘れてしまった場合は、この絵を思い出してほしい。)
まずメソッドの定義。
そしてtmp = x;の部分。
x = y;はいったん飛ばして、y = tmp;部分を見るとこう。
x = yは上記の組み合わせ。
ここでは、int32なので、ldind.i4/stind.i4だが、型によって使うべき命令は違う。ただし、
ldobj/stobjの例としては、ref int?を使うと、以下の感じで生成される。
&のついたref型で入っている。この元の型を得たいときは、こんな感じになる。
サマリ
- メソッドに渡す際は、アドレスを渡す。Cのポインタで言う&valのイメージ。
- 引数のpushには ldloca命令を使う。
- メソッド内では、アドレスの解決を行う。Cのポインタで言う*aのイメージ。
- 取得にはldind命令シリーズ(ldobj)、設定にはstind命令シリーズ(stobj)を使う。
- 型は、実際の型に&がついた「ref型」を利用する(例: System.Int32&)
- Type.MakeByRefTypeでref型化、Type.GetElementTypeで非ref型化できる。
- ref型かどうかは、Type.IsByRefで判断できる。
例
具体例として、参照を使うコードにありがちなSwapメソッドを作ってみる。C#コード
void Swap(ref int x, ref int y) {
int tmp;
tmp = x;
x = y;
y = tmp;
}
void SampleFunc()
{
int x = 10; int y = 20;
Swap(ref x, ref y);
System.Console.WriteLine("x, y: {0},{1}", x, y);
}
これをコンパイルしたものを逆アセンブルしたものが以下。
.method private hidebysig instance void Swap(int32& x,
int32& y) cil managed
{
.maxstack 2
.locals init ([0] int32 tmp)
IL_0000: nop
IL_0001: ldarg.1
IL_0002: ldind.i4
IL_0003: stloc.0
IL_0004: ldarg.1
IL_0005: ldarg.2
IL_0006: ldind.i4
IL_0007: stind.i4
IL_0008: ldarg.2
IL_0009: ldloc.0
IL_000a: stind.i4
IL_000b: ret
}
.method private hidebysig instance void SampleFunc() cil managed
{
.maxstack 3
.locals init ([0] int32 x,
[1] int32 y)
IL_0000: nop
IL_0001: ldc.i4.s 10
IL_0003: stloc.0
IL_0004: ldc.i4.s 20
IL_0006: stloc.1
IL_0007: ldarg.0
IL_0008: ldloca.s x
IL_000a: ldloca.s y
IL_000c: call instance void ConsoleApplication1.Program::Swap(int32&,
int32&)
IL_0011: nop
IL_0012: ldstr "x, y: {0},{1}"
IL_0017: ldloc.0
IL_0018: box [mscorlib]System.Int32
IL_001d: ldloc.1
IL_001e: box [mscorlib]System.Int32
IL_0023: call void [mscorlib]System.Console::WriteLine(string,
object,
object)
IL_0028: nop
IL_0029: ret
} // end of method Program::SampleFunc
呼ばれるSwapメソッド
適当に端折りながら、上から見ていく。(評価スタックのイメージを忘れてしまった場合は、この絵を思い出してほしい。)
まずメソッドの定義。
.method private hidebysig instance void Swap(int32& x,
int32& y) cil managed
int32ではなく、int32&型が使われている。これは、Type t = typeof(Int32).MakeByRefType();てな感じで得られる。
そしてtmp = x;の部分。
IL_0001: ldarg.1 IL_0002: ldind.i4 IL_0003: stloc.0これは、
- 1番目の引数(ref x)を持ってくる
- 持ってきたアドレスからint32の値を持ってくる
- 0番目のローカル変数に格納する
x = y;はいったん飛ばして、y = tmp;部分を見るとこう。
IL_0008: ldarg.2 IL_0009: ldloc.0 IL_000a: stind.i4これは、
- 2番目の引数(ref y)を持ってくる
- 0番目のローカル変数からint32の値を持ってくる
- 持ってきたアドレスに持ってきた値を入れる
x = yは上記の組み合わせ。
IL_0004: ldarg.1 IL_0005: ldarg.2 IL_0006: ldind.i4 IL_0007: stind.i4
ここでは、int32なので、ldind.i4/stind.i4だが、型によって使うべき命令は違う。ただし、
すべての ldind 命令は、対応している組み込み値クラスを指定する Ldobj 命令のショートカットです。(OpCodes.Ldind_I4 フィールド)なので、ldobj [type]でもよい。
ldobj/stobjの例としては、ref int?を使うと、以下の感じで生成される。
IL_0008: stobj valuetype [mscorlib]System.Nullable`1
Swap()を呼ぶメソッド
こちらは実際に呼び出しているところだけ。IL_0001: ldc.i4.s 10
IL_0003: stloc.0
IL_0004: ldc.i4.s 20
IL_0006: stloc.1
IL_0007: ldarg.0
IL_0008: ldloca.s x
IL_000a: ldloca.s y
IL_000c: call instance void ConsoleApplication1.Program::Swap(int32&,
int32&)
10、20をそれぞれx、yに入れたあと、this、xのアドレス、yのアドレスの順に持ってきて、関数をコールしている。リフレクションでの扱い
すでにあるメソッドのMethodInfoをGetMethod()で持ってきて、ParameterTypeを見ると、&のついたref型で入っている。この元の型を得たいときは、こんな感じになる。
if (parameterType.IsByRef) {
Type valueType = parameterType.GetElementType();
}
(Type.MakeByRefType メソッド)
登録:
投稿 (Atom)




