*if_cscop.txt* For Vim バージョン 8.1. Last change: 2019 May 05
VIMリファレンスマニュアル by Andy Kahn
この文章は Vim における cscope インターフェイスの使ひ方について述べてゐる。
cscope は ctags のやうなツールであるが、ctags よりも多くの機能が提供されるので ctags の代はりとみなせる。Vim ではタグにジャンプするやうに、cscope クエリの結果へジャンプすることができる; ジャンプの履歷はタグスタックに保存されいつものキーマッピングにより、普段 |tags| でやるやうに函數の閒を行つたり來たりできる。
| 1. Cscope の紹介 | |cscope-intro| |
| 2. Cscope に關係するコマンド | |cscope-commands| |
| 3. Cscope オプション | |cscope-options| |
| 4. Vim での cscope の使ひ方 | |cscope-howtouse| |
| 5. 制限事項 | |cscope-limitations| |
| 6. 使ひ方の提案 | |cscope-suggestions| |
| 7. 入手法と情報 | |cscope-info| |
現在のところ UNIX と Win32 で使へる。
以下の文章はあるバージョンの cscope のマニュアルから引用した:
cscope は貴方を助けるインタラクティブなスクリーン指向のツールです:
- いつ終はるかわからない厚いソースリストのページをめくることなく、C プログラムがどのやうに働くかを知る。
- プログラム全體を知らなくても、バグを修正するために變更すべきコードの位置を見つける。
- 列擧變數 (enum) に値を追加するといつた提案された變更の影響を檢證する。
- 既存の函數に引數を追加したといふやうな全部のソースファイルに施された變更を檢證する。
- 全部のソースファイルのグローバル變數の名前を變へる。
- ファイルの指定された行にある定數をプリプロセッサーのシンボルに變更する。
- これは次のやうな質問に答へるやうに意圖されてゐる:
- どこでこのシンボルが使はれたのか?
- それがどこで定義されたのか?
- この變數がどこでその値を得たのか?
- このグローバルシンボルの定義は何か?
- この函數はどのソースファイルのどこにあるのか?
- どの函數がこの函數を呼んでゐるのか?
- どの函數がこの函數から呼ばれてゐるか?
- "メモリが足りない" といふメッセージはどこから來たのか?
- このソースファイルはディレクトリのどこにあるのか?
- どんなファイルがこのヘッダーファイルをインクルードしてゐるのか?
cscope は起動すると最初に 1 度だけソースファイルからシンボルデータベースを作成し、このデータベースを用ゐてこれらの質問に答へる。2 度目以降の起動では、ソースファイルが變更されたかソースファイルのリストが異なる時にだけデータベースが再構築される。データベースが再構築される時でも變更されてゐないファイルについては過去のデータベースよりコピーされるので、初めから構築し直すよりも高速に構築できる。
通常 cscope を起動すると、上のやうな問ひ合はせ (クエリ) を入力できるフルスクリーンの選擇畫面が表示される。しかしながら、一度クエリが見つかりマッチを含むソースファイルを編輯するためのエディタを指定してあると、普段 vi で Ctrl-] や :tag コマンドでやつてゐるやうなタグからタグへの單純なジャンプはできなくなる。
Vim の cscope インターフェイスは cscope の行指向インターフェイスを利用することでこれを行ひ、實クエリに對する出力を解釋する。cscope のクエリの結果は最終的に通常の tags のやうになるので、普通のタグのやうなジャンプ操作 (Ctrl-] や :tag) を行ふことができ、タグスタックを Ctrl-T で逆に辿ることも可能になる。(しかしキーマップの再定義やコマンドやオプションの設定をしないで、まつたく單純に Ctrl-] や :tag と同じやうにジャンプできるわけではないことに注意して欲しい。cscope インターフェイスがどのやうに働くのか、どういふ使ひ方が提案されてゐるのかは殘りのセクションを參照。)
すべての cscope コマンドは、cscope コマンドへのサブオプションを通して利用される。
:cscope‘ もしくは ‘:cs‘ はメインコマンド。
:scscope‘ もしくは ‘:scs‘ は同じでウィンドウを分割する。
:lcscope‘ もしくは ‘:lcs‘ はロケーションリストを使ふ。|:lcscope| を參照。
利用可能なサブコマンドは:
新しい cscope データベース/接續を追加する。
使用法 :cs add {file|dir} [pre-path] [flags]
[pre-path] cscope に -P コマンドで渡されるパス名
[flags] cscope に引き渡す追加フラグ
例
:cscope add /usr/local/cdb/cscope.out :cscope add /projects/vim/cscope.out /usr/local/vim :cscope add cscope.out /usr/local/vim -C
cscope に問ひ合はせる。#5 オプション (grep パターンを變更する) 以外の全 cscope クエリオプションが使用可能。
使用法 :cs find {querytype} {name}
{querytype} は實際の cscope のラインインターフェイスの番號 (デフォルトの nvi コマンド) に對應する:
| 0 or s: | C のシンボルを檢索 |
| 1 or g: | 定義を檢索 |
| 2 or d: | この函數から呼ばれる函數を檢索 |
| 3 or c: | この函數を呼んでゐる函數を檢索 |
| 4 or t: | 文字列を檢索 |
| 6 or e: | egrep パターンを檢索 |
| 7 or f: | このファイルを檢索 |
| 8 or i: | このファイルを參照 (#include) してゐるファイルを檢索 |
| 9 or a: | このシンボルが變數に割り當てられた場所を檢索 |
4 と 6 以外のタイプでは、{name} における先頭のスペースは取り除かれる。4 と 6 では {querytype} と {name} の閒にちやうど 1 個のスペースが插入される。
例
:cscope find c vim_free :cscope find 3 vim_free
この 2 つの例は、同じクエリ ("vim_free" を呼び出してゐる函數を檢索) を實行する。
:cscope find t initOnce :cscope find t initOnce
この例の上の方は、"initOnce" といふテキストを檢索し、下の方は "initOnce" を檢索する。
:cscope find 0 DEFAULT_TERM
この例を Vim 5.1 のソースコードに對して行ふと、以下の出力を生成する。
Cscope tag: DEFAULT_TERM
# line filename / context / line
1 1009 vim-5.1-gtk/src/term.c <<GLOBAL>>
#define DEFAULT_TERM (char_u *)"amiga"
2 1013 vim-5.1-gtk/src/term.c <<GLOBAL>>
#define DEFAULT_TERM (char_u *)"win32"
3 1017 vim-5.1-gtk/src/term.c <<GLOBAL>>
#define DEFAULT_TERM (char_u *)"pcterm"
4 1021 vim-5.1-gtk/src/term.c <<GLOBAL>>
#define DEFAULT_TERM (char_u *)"ansi"
5 1025 vim-5.1-gtk/src/term.c <<GLOBAL>>
#define DEFAULT_TERM (char_u *)"vt52"
6 1029 vim-5.1-gtk/src/term.c <<GLOBAL>>
#define DEFAULT_TERM (char_u *)"os2ansi"
7 1033 vim-5.1-gtk/src/term.c <<GLOBAL>>
#define DEFAULT_TERM (char_u *)"ansi"
8 1037 vim-5.1-gtk/src/term.c <<GLOBAL>>
# undef DEFAULT_TERM
9 1038 vim-5.1-gtk/src/term.c <<GLOBAL>>
#define DEFAULT_TERM (char_u *)"beos-ansi"
10 1042 vim-5.1-gtk/src/term.c <<GLOBAL>>
#define DEFAULT_TERM (char_u *)"mac-ansi"
11 1335 vim-5.1-gtk/src/term.c <<set_termname>>
term = DEFAULT_TERM;
12 1459 vim-5.1-gtk/src/term.c <<set_termname>>
if (STRCMP(term, DEFAULT_TERM))
13 1826 vim-5.1-gtk/src/term.c <<termcapinit>>
term = DEFAULT_TERM;
14 1833 vim-5.1-gtk/src/term.c <<termcapinit>>
term = DEFAULT_TERM;
15 3635 vim-5.1-gtk/src/term.c <<update_tcap>>
p = find_builtin_term(DEFAULT_TERM);
Enter nr of choice (<CR> to abort):
出力には幾つかの情報を示してゐる:
短い解說を表示する。
使用法 :cs help
cscope との接續を切斷する (もしくは全ての接續を切斷する)。
使用法 :cs kill {num|partial_name}
cscope との接續を切斷するには、接續番號か部分的な名前を指定しなければならない。「部分的名前」とは單純に cscope データベースのパス名の一部である。部分的名前を使用して cscope 接續を切斷する時には注意すること!
接續番號 -1 を指定すると、全ての cscope 接續が切斷される。
全ての cscope 接續を再初期化する。
使用法 :cs reset
cscope 接續を表示する。
使用法 :cs show
このコマンドは ":cscope" とほぼ同じだが、オプション ’cscopequickfix’ がオンになつてゐる場合、QuickFix リストでなくカレントウィンドウのロケーションリストで cscope の結果を表示する。
ctags と cscope を同じやうに使ふのならば、兩方を順に檢索してジャンプを行ふのに |:cstag| が利用できる。例へば、最初に cscope データベースを檢索し、見つからなかつた時には、tags ファイルを檢索することができる。どちらを先に檢索するかは |csto| の値で決まる。詳細は |cscope-options| を參照。
|:cstag| が cscope データベースを檢索する時には、識別子に對して ":cs find g" と同じやうに働く。
|:cstag| が tags ファイルを檢索する時には、識別子に對して |:tjump| と同じやうに働く。
全ての cscope のオプションは |:set| コマンドによつて設定できる。理想的には起動ファイルのどれか 1 つ (例: .vimrc) で行ふであらう。cscope に關係する幾つかの變數は |.vimrc| の中だけで有效である。Vim が起動した後にそれらの變數を變更しても效果が無い!
’cscopeprg’ には cscope を實行するコマンドを指定する。省略値は "cscope"。例:
:set csprg=/usr/local/bin/cscope
{|+quickfix| 付きでコンパイルしないと利用できない} ’cscopequickfix’ は cscope の結果を表示するために quickfix ウィンドウを使ふかどうかを決める。これはコンマ區切りのリストである。要素は |cscope-find| コマンド (s または g, d, c, t, e, f, i, a) とフラグ (+ または -, 0) から成つてゐる。
探索は始まりから最初のコマンドを見つけるまで實行される。デフォルトの値は "" (quickfix を使はない)。次の値が便利だらう:
:set cscopequickfix=s-,c-,d-,i-,t-,e-,a-
’cscopetag’ が設定されてゐると、コマンド ":tags", CTRL-] そして "vim -t" はデフォルトの :tag の代はりに、常に |:cstag| を使ふやうになる。事實上、tag ファイルと同じやうに cscope データベースを檢索することができるやうになるだらう。省略した場合はオフ。例:
:set cst :set nocst
’cscoperelative’ が設定されてゐて、cscope にプリフィックスが與へられてゐない場合 (プリフィックスは cscope の -P オプションの引數である)、絕對パスを得るために、cscope.out が保存されてゐるディレクトリ (通常はプロジェクトのルート) が使はれる。初期設定はオフである。
Note:
このオプションは cscope (cscopeprg) がプリフィックスパス (-P) なしで初期化されてゐる場合のみ效果がある。
例:
:set csre :set nocsre
’csto’ の値は |:cstag| が檢索を實行する順序を決定する。’csto’ が 0 に設定されてゐるならば、先に cscope データベースが檢索され、cscope では見つからなかつた時にだけ tag ファイルが檢索される。’csto’ が1ならば、cscope データベースの前に tags ファイルが檢索される。省略値は 0。例:
:set csto=0 :set csto=1
’cscopeverbose’ が設定されてゐないと (デフォルト)、cscope データベースを追加した際の成否結果のメッセージが表示されない。理想的には、|.vimrc| の中で cscope データベースを追加する前にリセットし、追加し終はつた後で設定すべきである。設定しておけば、Vim 使用中にデータベースの追加に失敗した時、(望むらくは原因を特定するのに) 役立つメッセージが表示されるだらう。例:
:set csverb :set nocsverb
’cspc’ の値はファイルパスのうち幾つの構成要素を表示するか決定する。省略値である 0 を設定した時には完全なパスが表示される。値として 1 を設定すればファイル名だけが表示される。その他の値であれば、その數だけ構成要素を表示する。例:
:set cspc=3
ファイルパスのうち最後の 3 つ (ファイル名と 2 段上までのディレクトリ名) を表示する。
最初にやらなければならないことは、ソースコードに對して cscope データベースを構築することである。最も基本的なケースでは、單純に "cscope -b" とする。詳細については cscope のマニュアル (man ページ) を參照して欲しい。
cscope データベースがあるならば、次にそのデータベースを Vim へ "add" しなければならない。これは cscope との "接續" を確立し、それを Vim が使へるやうな狀態にする。これは .vimrc や、vim 起動後に手動で行ふことができる。例へば、cscope データベース "cscope.out" を追加するには、次のやうにする:
:cs add cscope.out
この結果は ":cs show" を實行することでもう一度チェックすることができる。これは次のやうな出力を生成する:
# pid database name prepend path 0 28806 cscope.out <none>
Note:
Microsoft のランタイムライブラリの制限により、Win32 バージョンでは本當のプロセス ID ではなく 0 が表示される。
一旦 cscope 接續が確立されれば、cscope へクエリを送信でき、その結果を表示することができる。クエリは ":cs find" コマンドにより生成される。例:
:cs find g ALIGN_SIZE
これは最終的に結構な量のタイプを必要とするのでやつかいである。しかしながら、ショートカットキーをマッピングしてこれを避ける方法がある。その方法については |cscope-suggestions| を參照のこと。
一致する項目が 1 つしかなければ、自動的にその場所へ移動する。複數の結果が得られた場合には、行きたい項目を選擇できる畫面が表示される。新しい場所へ移動した後は、單に CTRL-T をタイプすることで以前の位置へ戾ることができる。
Vim の cscope 機能は 4 つのシステムコール: fork(), pipe(), execl(), waitpid() をサポートしてゐるシステムでのみ利用可能である。これはほとんど UNIX システムだけに限られることを意味してゐる。
加へて、Cscope は Win32 でも動く。Win32 で動く cscope について詳しくは次のサイトを見ること。
http://iamphet.nm.ru/cscope/index.html
http://cscope.sourceforge.net でダウンロードできる、DJGPP でビルドしたバージョンは、Vim では動かないことがわかつてゐる。
ハードコードされた限界: |:cstag| がタグファイルを檢索するときの |:tjump| の動作はカスタマイズできない (例: tjump でなく tselect を使ふことができない)。
次のエントリを .vimrc に記述する (パス名は環境にあはせて然るべく變更すること):
if has("cscope")
set csprg=/usr/local/bin/cscope
set csto=0
set cst
set nocsverb
" add any database in current directory
if filereadable("cscope.out")
cs add cscope.out
" else add database pointed to by environment
elseif $CSCOPE_DB != ""
cs add $CSCOPE_DB
endif
set csverb
endif
’cscopetag’ を設定することで、:tag コマンドの實體を :cstag で效率的に置き換へてゐる。これには :tags, CTRL-], そして "vim -t" も含まれる。かうすることで、通常の tag コマンドは ctags が生成した tag ファイルだけでなく、cscope データベースも檢索するやうになる。
あるユーザーは通常の tag の振る舞ひはそのままに、:cstag へアクセスする異なつたショートカットを望むかもしれない。例へば次のコマンドで CTRL-_ (アンダースコア) に :cstag をマップできる:
map <C-_> :cstag <C-R>=expand("<cword>")<CR><CR>
良く使はれる 2 つの cscope のクエリ (":cs find" を使ふ) は、ある函數を讀んでゐる全ての函數を探すのと、ある C のシンボルを使用してゐる箇所全てを探すものである。これを行ふには、例としてこのやうなマップを使ふことができる:
map g<C-]> :cs find 3 <C-R>=expand("<cword>")<CR><CR>
map g<C-\> :cs find 0 <C-R>=expand("<cword>")<CR><CR>
このマッピングにより CTRL-] (右角カッコ) と CTRL-\ (バックスラッシュ) を、カーソルの下にある函數名や C シンボルを素早く cscope に問ひ合はせ結果を得るのに利用できるやうになる。
もしくは次の仕組みを使ふこともできる。これは Vim/Cscope のチュートリアルに影響を受けた (http://cscope.sourceforge.net/)。
nmap <C-_>s :cs find s <C-R>=expand("<cword>")<CR><CR>
nmap <C-_>g :cs find g <C-R>=expand("<cword>")<CR><CR>
nmap <C-_>c :cs find c <C-R>=expand("<cword>")<CR><CR>
nmap <C-_>t :cs find t <C-R>=expand("<cword>")<CR><CR>
nmap <C-_>e :cs find e <C-R>=expand("<cword>")<CR><CR>
nmap <C-_>f :cs find f <C-R>=expand("<cfile>")<CR><CR>
nmap <C-_>i :cs find i ^<C-R>=expand("<cfile>")<CR>$<CR>
nmap <C-_>d :cs find d <C-R>=expand("<cword>")<CR><CR>
nmap <C-_>a :cs find a <C-R>=expand("<cword>")<CR><CR>
" 'CTRL-spacebar' を使ふと Vim のウィンドウを水平分割して、
" 結果を新しいウィンドウで表示する。
nmap <C-Space>s :scs find s <C-R>=expand("<cword>")<CR><CR>
nmap <C-Space>g :scs find g <C-R>=expand("<cword>")<CR><CR>
nmap <C-Space>c :scs find c <C-R>=expand("<cword>")<CR><CR>
nmap <C-Space>t :scs find t <C-R>=expand("<cword>")<CR><CR>
nmap <C-Space>e :scs find e <C-R>=expand("<cword>")<CR><CR>
nmap <C-Space>f :scs find f <C-R>=expand("<cfile>")<CR><CR>
nmap <C-Space>i :scs find i ^<C-R>=expand("<cfile>")<CR>$<CR>
nmap <C-Space>d :scs find d <C-R>=expand("<cword>")<CR><CR>
nmap <C-Space>a :scs find a <C-R>=expand("<cword>")<CR><CR>
" 檢索をする前に CTRL-space を 2 回連續して押すと、
" 新しいウィンドウを縱に開く
nmap <C-Space><C-Space>s
\:vert scs find s <C-R>=expand("<cword>")<CR><CR>
nmap <C-Space><C-Space>g
\:vert scs find g <C-R>=expand("<cword>")<CR><CR>
nmap <C-Space><C-Space>c
\:vert scs find c <C-R>=expand("<cword>")<CR><CR>
nmap <C-Space><C-Space>t
\:vert scs find t <C-R>=expand("<cword>")<CR><CR>
nmap <C-Space><C-Space>e
\:vert scs find e <C-R>=expand("<cword>")<CR><CR>
nmap <C-Space><C-Space>i
\:vert scs find i ^<C-R>=expand("<cfile>")<CR>$<CR>
nmap <C-Space><C-Space>d
\:vert scs find d <C-R>=expand("<cword>")<CR><CR>
nmap <C-Space><C-Space>a
\:vert scs find a <C-R>=expand("<cword>")<CR><CR>
まだ cscope を持つてゐない (あなたのコンパイラのライセンスや OS のディストリビューションに含まれてない) のならば、次の場所から無料で入手できる:
http://cscope.sourceforge.net/
cscope は SCO により BSD ライセンスに基づいて配布されてゐる。
Solaris 2.x では、C コンパイラのライセンスを入手してゐれば、cscope も入手してゐるだらう。どちらも通常は /opt/SUNWspro/bin に格納される。
古い cscope のクローン ("cs" といふ名) のソースコードがネットで入手可能である。ただし樣々な理由で、これは Vim ではサポートされない。
オリジナルの cscope インターフェイス/サポートは Andy Kahn <ackahn@netapp.com> によつて書かれた。元となつた構造 (かなり小さいコードだつた) は nvi の cscope インターフェイスから改作された。 Win32 バージョンの cscope についてはこのサイトを參照すること (もうダメぽ):
https://code.google.com/archive/p/cscope-win32/
Win32 への對應は Sergey Khorev <khorev@softlab.ru> がしてくれた。Win32 に固有の問題については彼に問ひ合はせていただきたい。