ゼットログ

よしなしごとを記す

bashのaliasを読む(3)

aliasのソースコードを読み進めていく最中、GNU globalというツールに出会った。このツールはソースコードを読み進めていくのに大変便利。勉強会のときもこのツールについても軽く触れてみよう。詳しい使い方はこちらのブログにある。
ソースコードを快適に読むための GNU GLOBAL 入門 (前編)
いままで、find&grepをしまくってソースコードを読んでいたが、このツールを使えば大幅にソースコード解析の労力を削減できることを実感。使い方も簡単で、apt-getしたらまずは読む対象が入っているフォルダ内で次のコマンドを実行すれば準備完了。

$apt-get install global
$cd bash-4.1
$global -v (GPATH,GRTAGS,GSYMS,GTAGS)

"alias.c"ファイルの中で定義している関数がどれだけあるかを知りたい場合は以下のように実行。今まではソースを開いてちまちま関数を整理していたのがあっという間に終わってしまう。

$glbashobal -f alias.c
 ALIAS_HASH_BUCKETS   45 alias.c        #define ALIAS_HASH_BUCKETS	16	/* must be power of two */
 sh_alias_map_func_t   47 alias.c        typedef int sh_alias_map_func_t __P((alias_t *));
 initialize_aliases   68 alias.c        initialize_aliases ()
 find_alias         77 alias.c        find_alias (name)
 get_alias_value    91 alias.c        get_alias_value (name)

ある関数がどのファイルで定義されているか、ある関数がソースで使用されているかもすぐにわかる。これはやっていて気持ちがいい。-xオプションをつけて実行すると、関数が定義or呼び出されている部分の行番号とその行の内容も一緒に出てくる。

$global -x find_alias
find_alias         77 alias.c          find_alias (name)
$global -rx find_alias
find_alias         99 alias.c            alias = find_alias (name);
find_alias        119 alias.c              temp = find_alias (name);
find_alias        275 alias.c            r = find_alias (s);
find_alias        540 alias.c          	  (alias = find_alias (token)))
find_alias         45 alias.h          extern alias_t *find_alias __P((char *));
find_alias       2613 parse.y                ap = find_alias (tokstr);

さらにソースコードからhtmlファイルを生成することも可能。次のようにコマンドを実行すると、htmlというフォルダが出来るので、その中にあるindex.htmlをクリックすればいい。

htags -ansx

出来上がったhtmlファイルは関数や変数の記述部分にリンクが貼ってあって、クリックすると定義元や呼び出し先へすぐに飛べるようになっている。WEBブラウザが使える環境であればhtmlファイルを生成するやり方が一番快適だと思った。ただし、デフォルトだと.defの拡張子がついたファイルは解析の対象になっていないので、以下のようにして.defの拡張子を登録しておこう。globalやhtagsのmanページを見ると、/etc/gtags.confがあると書いてあるけれど、Ubuntu 10.04では/usr/share/doc/global/examlpes/gtags.confにありました。

$cp /usr/share/doc/global/examlpes/gtags.conf ~/.globalrc
#.globalrcのlangmapに".def"を追記。
  :langmap=c\:.c.h.def,yacc\:.y,asm\:.s.S,java\:.java,cpp\:.c++.cc.cpp.cxx.hxx.hpp.C.H,php\:.php.php3.phtml:||
#再度、globalコマンドとhtagsコマンドを実行し、解析結果を更新
$global
$htags -ansx

他にも、globalにはvimemacsにプラグインとして組み込んで使うやり方もあるようです。僕はhtmlで読んでいます。

aliasコマンドが実行されるまで

alias.cで定義されている関数がどのファイルから呼び出されているか、整理しておく。

  • find_alias
    • alias.c
    • builtins/alias.def
    • builtins/type.def
    • parse.y
  • get_alias_value
    • bashline.c
  • add_alias
    • alias.c
    • valiables.c
  • all_aliases
    • builtins/alias.def
    • pcomplete.c
    • bashline.c
  • alias_expand
    • bashline.c
  • delete_all_aliaes
    • builtins/alias.def
    • execute_cmd.c

alias関連の関数は結構、いろんなところから呼ばれている。ファイル間の関連性を調べるのもglobalを使うとかなり楽ですね。alias.cで定義されている関数の意味、内容は理解できるのだけど、それがbashの中でどのように使われているかが自分の中でまだ理解が足りない。芯を捉えていない気がしている。