Emacs + GLOBALでソース読みを快適に

ネットワークサーバー実装のためにuIPのソースを読もう。
NICドライバの移植のためにFreeBSDのソースを読もう。


ということで以前使っていた etags を使おうと思ったがキーバインド忘れた。
そして etags はなんだかいろいろ不満点があった気がするので GLOBALを使ってみることに。
以前GLOBALは出力をHTMLにして使ったことがあるのだが、最近EmacsにどっぷりなのでEmacsから使ってみることに。

0.GLOBALって何?

GNU GLOBAL は、ソースコードに索引付けを行うことで、大規模システムのハックやレビューを効率化するソフトウエアです。

ソースファイル中の指定したシンボルを高速に見つけ出し、素早くその場所に移動することができます。多くのサブディレクトリからなり、#ifdef や main() 関数を沢山含んでいるような、いわゆる巨大なプロジェクトをハックするのに役立ちます。ctags やetags に似た働きをしますが、エディタには依存せず様々な環境でご利用になれます

以下の言語に対応しているとのこと。

1.GLOBALインストール

Linux, cygwinともに同じ手順です

wget http://tamacom.com/global/global-4.8.7.tar.gz
tar zvxf global-4.8.7.tar.gz
cd global-4.8.7
./configure
make
make install
global --help

2.tag生成

ソースファイルがあるディレクトリで

cd MonaNew
gtags -v

とします。

すると直下に

rw-r--r--   1 higepon なし   81920 Jan  7 18:12 GPATH
rw-r--r--   1 higepon なし 4292608 Jan  7 18:12 GRTAGS
rw-r--r--   1 higepon なし 1540096 Jan  7 18:12 GSYMS
rw-r--r--   1 higepon なし  679936 Jan  7 18:12 GTAGS

こんな感じで関連ファイルができます。

3.HTML生成

ちょっと寄り道してHTMLを出力してみましょう。
GTAGSがあるディレクトリで

htags

と実行するとHTMLディレクトリにHTML出力されます。

出力サンプルはこちら
http://www.monaos.org/htags/

ソースコードをリンクをたどって読み進められてとても便利ですね。
でもこれで満足してはいけません。

4.Emacsの設定

global-4.8.7にある gtags.el をロードパスの通ったところに置きます。
そして .emacs にこれを追加します。(ここを参考にしました。)

(autoload 'gtags-mode "gtags" "" t)
(setq gtags-mode-hook
      '(lambda ()
         (local-set-key "\M-t" 'gtags-find-tag)
         (local-set-key "\M-r" 'gtags-find-rtag)
         (local-set-key "\M-s" 'gtags-find-symbol)
         (local-set-key "\C-t" 'gtags-pop-stack)
         ))

ついでに自動で gtags-mode になるように&補完リスト作成

(add-hook 'c-mode-common-hook
          '(lambda()
             (gtags-mode 1)
             (gtags-make-complete-list)
             ))


Meadowの場合は更に追加設定が必要です。
http://www.emacswiki.org/cgi-bin/wiki/download/cygwin-mount.elをダウンロードしてロードパスの通ったところに置きます。

.emacsに追加

(when (and (featurep 'meadow) (locate-library "cygwin-mount"))
  (require 'cygwin-mount)
  (cygwin-mount-activate))

5.Emacsから使ってみよう

Emacsで たとえば MonaNew/core/kernel/kernel.cppを開いてみましょう。
好きな関数のところにカーソルを当てて M-t とやると関数が定義されているところにジャンプできます。
更に C-t で元のバッファに戻ります。
また関数の上で、M-r をすると、この関数が呼び出されている場所がリストされ好きな場所にジャンプできます。

そのほかには M-sでシンボルの参照先にジャンプできます。

整理すると

キーバインド アクション
M-t 関数定義にジャンプ
M-r 関数呼び出し場所にジャンプ
M-s シンボル参照先にジャンプ


というわけで Emacs + GLOBAL で快適にソースを読んでいきましょう。
仕上げにid:yaneurao:20040730で紹介されている

Code Reading―オープンソースから学ぶソフトウェア開発技法

Code Reading―オープンソースから学ぶソフトウェア開発技法

を読めばいいのかな。

ドラえもんコミック

正月に実家に帰ったら子供のときに集めていたドラえもんのコミックを発見。
てんとう虫も持っていたけどこちらのほうが多かったな。
巻末のおまけマンガが楽しいんだようなぁ。

[Mona][network] uIPのhttpdのソースを読んでフローとやるべきことをつかむ

ネットワークサーバの実装にはuIPを利用したアプリケーションの作り方を学ぶ必要がある。
Emacs + GLOBALでフローを追ってみた。

処理フロー

httpd_init();
  fs_init();
  uip_listen(HTONS(80));
uip_input() (== uip_process(UIP_DATA))
  uip_tcpchksum()
  UIP_APPCALL(==httpd_appcall)

httpd_appcall内で使われている関数たち

  • uip_conn->lport // ポートが分かる
  • uip_connected() // 接続されているか
  • uip_poll() // poolしているか?
  • uip_abort() // abort
  • uip_newdata() // 新しいデータがあったらtrue
  • uip_appdataにデータがある


ちなみにこの作業が終わってからドキュメントの存在に気づいた。
これは次回読みます。
http://www.sics.se/~adam/uip/uip-0.9-refman/main.html