C ユーザーズガイド ホーム目次前ページへ次ページへ索引


第 9 章

cscope: 対話的な C プログラムの検査

cscope は、C、lex、または yacc のソースファイル内のコードの特定の要素を探し出す対話型プログラムです。cscope ブラウザを使用すると、従来のエディタよりも効率的にソースファイルを検索、編集できます。これは、cscope が関数呼び出し (関数がいつ呼び出され、いつその関数を実行するか) についてと、C 言語の識別子と予約語を理解しているためです。本章は cscope ブラウザについて説明します。

この章は、このリリースに付属している cscope ブラウザの使い方を学ぶための資料として利用できます。説明項目は次のとおりです。

cscope プロセス

cscope は、C、lexyacc のソースファイルを読み取り、ファイル内の関数、関数呼び出し、マクロ、変数、前処理シンボルのシンボル相互参照表を作成します。次に作成した表を検索して、ユーザーが指定したシンボルの位置を探し出します。cscope は、最初にメニューを表示し、実行したい検索のタイプを聞いてきます。たとえば、特定の関数を呼び出しているすべての関数を検索することができます。

検索が終了すると、cscope は結果を表示します。リストの各エントリ行には、指定したコードが存在するファイル名、行番号、その行のテキストが含まれます。この例では、指定された関数を呼び出している関数名も表示されます。リストを表示した後は、新しく検索するか、あるいはリストに表示された行をエディタで調べるかを選択することができます。後者の場合、cscope はその行があるファイルをエディタで読み込んで、その行にカーソルを移動します。ここで、その行の前後関係を調べることができます。さらに他のファイルと同じように編集することもできます。エディタを終了したら、メニューに戻って新しい検索を始めます。

作業内容によって手順も変わってくるので、cscope の使用方法は 1 通りではありません。cscope の詳しい使用方法や、コード全体を調べることなくプログラム内のバグを探し出す方法については、次の「基本的な使用方法」で説明します。

基本的な使用方法

たとえば、プログラム prog の開始直後に out of storage というエラーメッセージが表示されることがあると想定します。これを解決するには、まず cscope を使用してコード内のメッセージを発行している場所を探し出さなければなりません。この場合、次の手順で実行します。

ステップ 1:環境設定

cscope は、画面指向ツールです。使用できる端末は、端末情報ユーティリティ (terminfo) データベースに書かれているものに限られます。TERM 環境変数を自分の端末タイプ<端末名> に設定してあることを確認してください。cscopeTERM 環境変数の値を見て、それが terminfo データベースに存在するか確認します。まだ設定していない場合は、次のようにして TERM に値を設定し、それをシェルに伝えます。

B シェル:

$ TERM=<端末名>; export TERM

C シェル:

% setenv TERM <端末名>

次に、EDITOR 環境変数に値を設定します。デフォルトでは、cscopevi エディタを起動します (本章の例も vi を使用して説明しています)。vi を使用したくない場合は、EDITOR 環境変数を任意のエディタ名に変更して、EDITOR をエクスポートします。

B シェルの場合は以下のように入力します。

$ EDITOR=emacs; export EDITOR

C シェルの場合は以下のように入力します。

% setenv EDITOR emacs

cscope とエディタ間のインタフェースを設定しなければなりません。詳細は、
「エディタのコマンド行構文」を参照してください。

cscope を表示するためだけに使用したい (編集は使用しない) 場合は、VIEWER 環境変数を pg に設定して VIEWER をエクスポートします。cscopevi の代わりに pg を起動します。

環境変数 VPATH には、ソースファイルの検索対象ディレクトリを指定します。
「ビューパス (Viewpath)」を参照してください。

ステップ 2:cscope プログラムの起動

デフォルトでは、cscope は現ディレクトリ内にあるすべての C、lex、および yacc のソースファイルのシンボル相互参照表、および現ディレクトリまたは標準位置内にあるすべてのインクルードヘッダーファイルのシンボル相互参照表を作成します。したがって、表示するプログラムのすべてのソースファイルが現ディレクトリにあり、かつそのヘッダーファイルが現ディレクトリまたは標準位置にある場合は、cscope を引数なしで起動します。

% cscope

特定のソースファイルを表示する場合は、そのファイルの名前を引数にして cscope を起動します。

% cscope <ファイル 1>.c <ファイル 2>.c <ファイル 3>.h

cscope の他の起動方法については、「コマンド行オプション」を参照してください。

プログラムを表示するため、最初に cscope が使用されるときにシンボル相互参照表が作成されます。デフォルトでは、作成されたシンボル相互参照表は現ディレクトリ内の cscope.out ファイルに格納されます。その後 cscope を再び起動すると、前回と比較してソースファイルが修正されていたとき、またはソースファイルのリストが異なるときだけ相互参照表が作成し直されます。相互参照表を再び作成する時には、変更されていないファイルのデータは前回の相互参照表からコピーされます。これによって、最初の作成時より作成速度が速くなり、起動時のスタートアップ時間も短くなります。

ステップ 3:コード位置の確定

本節の最初で述べた本来の作業に戻り、out of storage のエラーメッセージの原因となっている場所を確定します。cscope が起動され、相互参照表が作成されました。画面には、cscope の作業メニューが表示されます。

cscope の作業メニュー

% cscope

 
cscope     Press the ? key for help

 

 
Find this C symbol:
Find this global definition:
Find functions called by this function:
Find functions calling this function:
Find this text string:
Change this text string:
Find this egrep pattern:
Find this file:
Find files #including this file:

Return キーを押すと、カーソルは下に移動し (画面の一番下まで移動すると、先頭に戻ります)、^p (Ctrl キーと p キー) を押すと上に移動します。また、上矢印と下矢印キーも使用できます。以下の単一キーコマンドを使用すれば、メニュー操作とその他の作業が行えます。

表 9-1   cscope メニュー操作コマンド 
TAB 次の入力フィールドへ移動する
Return 次の入力フィールドへ移動する
^n 次の入力フィールドへ移動する
^p 前の入力フィールドへ移動する
^y 最後に入力したテキストを検索する
^b 逆方向にパターンを検索する
^f 順方向にパターンを検索する
^c 検索時に大文字と小文字を区別するか否かのトグルスイッチ (大文字と小文字を区別しない場合、たとえば FILE 文字列は fileFile の両方と一致)
^r 相互参照表を再作成する
! 対話型シェルを起動する (^dcscope に復帰)
^l 画面を描き直す
? コマンドのリストを表示する
^d cscope を終了する


検索文字列の最初の文字が上記のいずれかのコマンドと一致する場合は、検索文字列の前にバックスラッシュ (\) を加えてコマンドと区別します。

たとえば、カーソルを 5 番目のメニュー項目「Find this text string」に移動して文字列「out of storage」を入力し、Return キーを押します。

cscope 関数: 文字列検索の要求

$ cscope

 
cscope      Press the ? key for help

 

 
Find this C symbol
Find this global definition
Find functions called by this function
Find functions calling this function
Find this text string:  out of storage
Change this text string
Find this egrep pattern
Find this file
Find files #including this file


注 - 6 番目の「Change this text string」項目以外のメニュー項目についても同じ手順に従ってください。6 番目の項目は他の項目よりも多少複雑なので手順が異なります。文字列の変更方法については 「cscope の使用例」を参照してください。

cscope は指定された文字列を検索し、それを含む行を見つけ出して次のように検索結果を表示します。

cscope 関数: 文字列を含む cscope 行のリスト表示

Text string:  out of storage

 
  File Line
1 alloc.c 63 (void) fprintf(stderr, "\n%s:  out of storage\n", argv0);

 

 
Find this C symbol:
Find this global definition:
Find functions called by this function:
Find functions calling this function:
Find this text string:
Change this text string:
Find this egrep pattern:
Find this file:
Find files #including this file:

検索結果が正常に表示されたら、次の操作を選択します。行を変更したり、またはその行の前後をエディタで調べることができます。あるいは、cscope の検索結果のリストが一画面に収まらない場合は、リストの次の部分を見ることもできます。cscope が指定した文字列を検索した後に使用可能なコマンドを以下に示します。

表 9-2   最初の検索後に使用するコマンド 
1 - 9 この行を含むファイルを編集する (入力した番号は cscope が表示したリストの行番号に対応する)
スペース 次画面のリストを表示する
+ 次画面のリストを表示する
^v 次画面のリストを表示する
- 前画面のリストを表示する
^e 表示されたファイル順に編集する
> 表示されているリストをファイルへ追加する
| 全行をパイプでシェルコマンドに渡す


ここでも、検索文字列の最初の文字が上記のいずれかのコマンドと一致する場合は、検索文字列の前にバックスラッシュ (\) を加えてコマンドと区別します。

次に、新しく検索した行の前後を調べます。「1」(リスト内の行番号) を入力してください。エディタが起動され、alloc.c ファイルが読み込まれます。カーソルは、
alloc.c の 63 行目の先頭に移動します。

cscope 関数: コード行の検査

{
    return(alloctest(realloc(p, (unsigned) size)));
}

 
/* メモリーの割り当て失敗を検査する */

 
static char *
alloctest(p)
char *p;
{
    if (p == NULL) {
    (void) fprintf(stderr, "\n%s:  out of storage\n", argv0);
    exit(1);
    }
    return(p);
} 
~ 
~ 
~ 
~ 
~ 
~ 
~ 
"alloc.c" 67 lines, 1283 characters 

変数 pNULL のときに、エラーメッセージが出力されることがわかります。alloctest() に渡される引数がなぜ NULL になったのかを調べるには、まず alloctest() を呼び出している関数を確定する必要があります。

通常の終了方法でエディタを終了し、作業メニューに戻ります。ここで、4 番目の項目「Find functions calling this function」の後に alloctest と入力します。

cscope 関数: alloctest() を呼び出す関数のリストの要求

Text string:  out of storage

 
  File Line
1 alloc.c 63(void)fprintf(stderr,"\n%s:  out of storage\n",argv0);

 

 
Find this C symbol:
Find this global definition:
Find functions called by this function:
Find functions calling this function:  alloctest
Find this text string:
Change this text string:
Find this egrep pattern:
Find this file:
Find files #including this file:


cscope は検索を実行し、次の 3 つの関数のリストを表示します。

cscope 関数: alloctest() を呼び出す Listing 関数

Functions calling this function:  alloctest
File Function Line
1 alloc.c mymalloc 33 return(alloctest(malloc((unsigned) size)));
2 alloc.c mycalloc 43 return(alloctest(calloc((unsigned) nelem, 
(unsigned) size)));
3 alloc.c myrealloc 53 return(alloctest(realloc(p, (unsigned) 
size)));

 

 
Find this C symbol:
Find this global definition:
Find functions called by this function:
Find functions calling this function:
Find this text string:
Change this text string:
Find this egrep pattern:
Find this file:
Find files #including this file:


今度は、mymalloc() を呼び出す関数を調べます。cscope は、次のような 10 個の関数を見つけ出します。そのうち 9 個を画面に表示し、残りの 1 個を見るにはスペースバーを押すように指示しています。

cscope 関数: mymalloc() を呼び出す関数の Listing 関数

{
    return(alloctest(realloc(p, (unsigned) size)));
}

 
/* check for memory allocation failure */

 
static char *
alloctest(p)
char *p;
{
    if (p == NULL) {
    (void) fprintf(stderr, "\n%s:  out of storage\n", argv0);
    exit(1);
    }
    return(p);
} 
~ 
~ 
~ 
~ 
~ 
~ 
~ 
"alloc.c" 67 lines, 1283 characters 


out of storage のエラーメッセージはプログラムの開始直後に出力されるので、関数 dispinit() (表示の初期化) 内で問題が発生していることが推測できます。

dispinit() はリストの 7 番目の関数なので、これを参照するには 7と入力します。

cscope 関数: dispinit() をエディタで参照

void
dispinit()
{
    /* 表示される参照行数の最大を計算する */
    lastdispline = FLDLINE - 4;
    mdisprefs = lastdispline - REFLINE + 1;
    if (mdisprefs > 9) {
    mdisprefs = 9;
    }
    /* 表示される行の配列を割り当てる */
    displine = (int *) mymalloc(mdisprefs * sizeof(int));
}
^L  /* 参照ページを表示する */

 
void
display()
{
    char file[PATHLEN + 1];   /* ファイル名 */
    char function[PATLEN + 1];/* 関数名 */
    char linenum[NUMLEN + 1]; /* 行番号 */
    int screenline; /* 画面行番号 */
    int width;      /* ソース行表示幅 */
    register int i, j;
"display.c" 622 lines, 14326 characters

mymalloc() が失敗したのは、非常に大きな数または負数を引数にして呼び出されたためです。FLDLINEREFLINE が取り得る値を調べてみると、mdisprefs の値が負になる場合があることがわかります。この場合、mymalloc() は負数を引数にして呼び出されます。

ステップ 4:コードの編集

ウィンドウ端末上では、任意のサイズで複数のウィンドウを開くことができます。
out of storage のエラーメッセージが出力されたのは、prog を実行するウィンドウ内の行数が少なすぎたためと考えられます。つまり、mymalloc() が負数を引数にして呼び出された場合にこのような状況が発生する可能性があるということです。
今後このような状況が発生した場合に、もっと分かりやすいエラーメッセージ、たとえば Screen too small を出力してプログラムを中止するように設定しておくとよいでしょう。それには、dispinit() 関数を以下のように編集します。

cscope 関数: 問題箇所の修正

void
dispinit()
{
        /* 表示される参照行数の最大を計算する */ 
    lastdispline = FLDLINE - 4;
    mdisprefs = lastdispline - REFLINE + 1;
    if (mdisprefs > 9) {
    mdisprefs = 9;
    }
        /* 表示される行の配列を割り当てる */
    displine = (int *) mymalloc(mdisprefs * sizeof(int));
} 
^L/* 参照ページを表示する */

 
void
display()
{
    char file[PATHLEN + 1];   /* ファイル名 */
    char function[PATLEN + 1];/* 関数名 */
    char linenum[NUMLEN + 1]; /* 行番号 */
    int screenline; /* 画面行番号 */
    int width;      /* ソース行表示幅 */
    register int i, j;
"display.c" 622 lines, 14326 characters

以上で、本節の最初で調査を開始した問題箇所は修正されました。これで、行数が少なすぎるウィンドウ内で prog を実行したときに、単に意味不明のエラーメッセージ
out of storage を出力して中止するのではなく、ウィンドウサイズを検査して分かりやすいエラーメッセージを出力した後に終了するようになります。

コマンド行オプション

すでに述べたとおり、cscope はデフォルトでは現ディレクトリ内にある C、lex、およびソースファイルのシンボル相互参照表を作成します。すなわち、次の 2 つのコマンドは等価です。

% cscope

% cscope *.[chly]

指定したソースファイルを表示するには、ソースファイル名を引数に指定して cscope を起動します。

% cscope <ファイル 1>.c <ファイル 2>.c <ファイル 3>.h

cscope のコマンド行オプションを使用して、相互参照表に含まれるソースファイルをさらに自由に指定することもできます。それには、次のように -s オプションの後にコンマで区切られた任意の数のディレクトリ名を指定して cscope を起動します。

% cscope -s <ディレクトリ 1>,<ディレクトリ 2>,<ディレクトリ 3>

cscope は現ディレクトリ内だけでなく、指定されたディレクトリ内にあるすべてのソースファイルを対象に相互参照表を作成します。<ファイル> 中にリストされているソースファイル (ファイル名をスペースやタブまたは復帰改行で区切ったもの) のすべてを表示するには、-i オプションとリストを持つファイル名を指定して cscope を起動します。

% cscope -i <ファイル>

ソースファイルがディレクトリツリーの中にある場合は、以下のコマンドでディレクトリツリー内のすべてのソースファイルを簡単に表示できます。

% find .  -name '*.[chly] ' -print | sort > <ファイル>
% cscope -i <ファイル>

このオプションを使用しても、コマンド行でファイルが指定されている場合は、指定されたファイル以外については無視されるので注意してください。

-I オプションは、cc に対する -I オプションと同じような形式で cscope にも指定できます。「インクルードファイル」を参照してください。

-f オプションを使用すると、デフォルトの cscope.out 以外のファイルを相互参照ファイルとして指定できます。このオプションは、同じディレクトリ内に異なるシンボル相互参照ファイルを保管するのに役立ちます。たとえば、2 つのプログラムが同じディレクトリ内にあるが、すべてのファイルを共有しているとは限らない場合に使用します。

$ cscope -f admin.ref admin.c common.c aux.c libs.c
$ cscope -f delta.ref delta.c common.c aux.c libs.c

この例では、2 つのプログラム admindelta のソースファイルは同じディレクトリ内にありますが、プログラムを構成するファイルは異なっています。cscope 起動時に、別のシンボル相互参照ファイルを指定しておくことによって、2 つのプログラムの相互参照情報を別々に保管できます。

-pn オプションを使用すると、検索結果でリストされたファイルのあるパス名やそのパス名の一部を表示することができます。-p の後の n には、パス名の中で最後から何番目までの要素を表示させたいかを指定します。デフォルト値は 1 で、これはファイル名そのものを意味します。したがって現ディレクトリが home/common の場合、以下のコマンドによって検索結果のリストに表示されるパス名は、common/<ファイル 1>.ccommon/<ファイル 2>.c のようになります。

% cscope -p2

表示したいプログラムが大量のソースファイルを含む場合、-b オプションを使用して、相互参照表を作成した後で cscope を終了することができます。このとき、作業メニューは表示されません。パイプを使用して、cscope -b の出力を batch(1) コマンドの入力につなげると、cscope は相互参照表をバックグラウンドで作成します。

% echo 'cscope -b' | batch

相互参照表がいったん作成されると、その後、ソースファイルまたはソースファイルのリストを変更しない限り、次のように指定するだけで相互参照表がコピーされ、通常どおり作業メニューが表示されます。

% cscope

このコマンドシーケンスを使用すると cscope の初期処理の終了を待たずに作業を続けることができます。

-d オプションは、cscope にシンボル相互参照表を更新させません。このオプションを指定すると、ソースファイルの変更が検査されないため時間の節約になります。変更されていないと確信できる場合にのみ使用してください。


注 - -d オプションの使用には注意が必要です。ソースファイルが変更されていることに気付かずに -d オプションを使用すると、cscope は古いシンボル相互参照表を使用して照会に応じてしまいます。

他のコマンド行オプションについては、cscope(1) のマニュアルページを参照してください。

ビューパス (Viewpath)

前述のように cscope は、デフォルトでは現ディレクトリ内のソースファイルを検索します。環境変数 VPATH が設定されているときは、cscopeVPATH に指定されたディレクトリ内のソースファイルを検索します。ビューパスとは、順序付けされたディレクトリのリストで、リスト内の各ディレクトリの下は同じディレクトリ構造になっています。

たとえば、ユーザーがあるソフトウェアプロジェクトのメンバーであるとします。
/fs1/ofc 下のディレクトリには、正式バージョンのソースファイルがあります。各メンバーはホームディレクトリ (/usr/you) を持っており、ソフトウェアシステムを変更する場合は、変更するファイルだけを /usr/you/src/cmd/prog1 にコピーします。全プログラムの正式バージョンは、/fs1/ofc/src/cmd/prog1 にあります。

cscope を使用して、prog1 を構成する 3 つのファイル ( f1.c、f2.c、f3.c) を表示します。まず VPATH/usr/you/fs1/ofc に設定してエクスポートします。

B シェルの場合は、以下のように入力します。

$ VPATH=/usr/you:/fs1/ofc; export VPATH

C シェルの場合は、以下のように入力します。

% setenv VPATH /usr/you:/fs1/ofc

次に、現ディレクトリを /usr/you/src/cmd/prog1 に移動して cscope を起動します。

$ cscope

cscope はビューパスにあるすべてのファイルの位置を調べます。同じファイルが複数のディレクトリにある場合は、VPATH 内で先に現れたディレクトリの下にあるファイルを使用します。したがって、f2.c がユーザーのディレクトリにあり (3 つのファイルはすべて正式バージョン用ディレクトリの下にもある場合)、cscopef2.c はユーザーのディレクトリのものを、f1.c および f3.c は正式バージョン用のディレクトリのものを検査します。

VPATH 内の最初のディレクトリは、作業用ディレクトリの接頭辞 (通常は $HOME) でなければなりません。VPATH 内のコロンで区切られたそれぞれのディレクトリは、/ から始まる絶対パス名でなければなりません。

cscope とエディタ呼び出しのスタック

cscope とエディタの呼び出しはスタックできます。たとえば、cscope がエディタを起動してシンボルへの参照を調べているときに、他にも参照関係を調べたいシンボルがある場合、エディタ内部から再び cscope を起動して 2 番目の参照関係を調べることができます。現在起動中の cscope やエディタを終了する必要はありません。一番最後に起動した cscope またはエディタコマンドを正常に終了すれば、1 つ前の状態に戻ることができます。

cscope の使用例

cscope が次の 3 つの作業を行うのにどのように使用されるかを見ていきます。対象とする作業は、定数をプリプロセッサシンボルに変更する、関数に引数を追加する、変数の値を変更するの 3 つです。最初の例では、文字列の変更手順を示します。この作業は、cscope メニューの他の作業項目とは少し異なっています。変更したい文字列を入力すると、cscope はそれを置き換える新しい文字列を聞いてきます。画面には古い文字列を含む行が表示されます。ここで、どの行に含まれる文字列を変更するかを指定します。

例 1:定数をプリプロセッサシンボルに変更する

たとえば、定数 100 をプリプロセッサシンボル MAXSIZE に変更するとします。6 番目のメニュー項目「Change this text string」を選択して、\100 と入力します。
1 の前にはバックスラッシュを加えて、cscope のメニュー項目番号を意味する 1 と区別します。Return キーを押すと cscope は新しい文字列を聞いてくるので、MAXSIZE と入力します。

cscope 関数: 文字列の変更

cscope  Press the ? key for help

 

 
Find this C symbol:
Find this global definition:
Find functions called by this function:
Find functions calling this function:
Find this text string:
Change this text string: \100
Find this egrep pattern:
Find this file:
Find files #including this file:
To:  MAXSIZE 


cscope は、指定された文字列を含む行を表示します。どの行の文字列を変更するかが選択されるまで入力待ちになります。

cscope 関数: 変更行に対するプロンプト

Change "100" to "MAXSIZE"

 
  File Line
1>init.c 4 char s[100];
2>init.c 26 for (i = 0; i < 100; i++)
3>find.c 8 if (c < 100) {
4 read.c 12 f = (bb & 0100);
5 err.c 19 p = total/100.0; /* get percentage */

 
Find this C symbol:
Find this global definition:
Find functions called by this function:
Find functions calling this function:
Find this text string:
Change this text string:
Find this egrep pattern:
Find this file:
Find files #including this file:
Select lines to change (press the ? key for help):

リストの 1、2、3 行目 (ソースファイル内の行番号はそれぞれ 4、26、8 行目) に含まれる定数 100 は、MAXSIZE に変更すべきだとわかります。また、read.c 内の 0100
err.c 内の 100.0 (リストの 4、 5 行目) は、変更すべきでないこともわかります。変更する行を指定するには、以下の単一キーコマンドを使用します。

表 9-3   変更行選択コマンド 
1-9 変更行をマークまたはマーク解除する
* 表示されている行をすべて変更対象としてマークまたはマーク解除する
スペース 次画面のリストを表示する
+ 次画面のリストを表示する
- 前画面のリストを表示する
a すべての行を変更対象としてマークする
^d マークされた行を変更して終了する
Esc マークされた行を変更しないで終了する


この場合、1、2、および 3 を入力します。入力した番号は画面上には表示されません。代わりに各行の行番号の後に > (右不等号) を表示することによって、変更箇所を示します。

cscope 関数: 変更行のマーキング

Change "100" to "MAXSIZE"

 
  File Line
1>init.c 4 char s[100];
2>init.c 26 for (i = 0; i < 100; i++)
3>find.c 8 if (c < 100) {
4 read.c 12 f = (bb & 0100);
5 err.c 19 p = total/100.0; /* 百分率にする */

 
Find this C symbol:
Find this global definition:
Find functions called by this function:
Find functions calling this function:
Find this text string:
Change this text string:
Find this egrep pattern:
Find this file:
Find files #including this file:
Select lines to change (press the ? key for help):

ここで、^d を入力して選択行を変更します。cscope は変更後の各行を表示し、作業の継続を促します。

cscope 関数: 変更後のテキスト行表示

Changed lines:

 
    char s[MAXSIZE];
    for (i = 0; i < MAXSIZE; i++)
    if (c < MAXSIZE) {

 
Press the RETURN key to continue:


このプロンプトに対して Return キーを押すと、cscope は画面を書き換えて変更行を指定する前の画面に戻ります。

次に新しいシンボル MAXSIZE#define 文を追加します。#define 文を追加するヘッダーファイルは、現在表示されている行の参照元ファイルの中にはありません。したがって、! と入力してシェルに入る必要があります。シェルプロンプトが画面の一番下に現れます。あとは、エディタを起動して #define 文を追加します。

cscope 関数: シェルへの一時移行

Text string:  100

 
  File Line
1 init.c 4 char s[100];
2 init.c 26 for (i = 0; i < 100; i++)
3 find.c 8 if (c < 100) {
4 read.c 12 f = (bb & 0100);
5 err.c 19 p = total/100.0; /* 百分率にする */

 
Find this C symbol:
Find this global definition:
Find functions called by this function:
Find functions calling this function:
Find this text string:
Change this text string:
Find this egrep pattern:
Find this file:
Find files #including this file:
$ vi defs.h


cscope セッションへ戻るには、エディタを終了し、^d を入力してシェルを終了させます。

例 2:関数に引数を追加する

関数に引数を追加するには、関数そのものを編集することとその関数が呼び出されているすべての箇所に新しい引数を追加することの 2 つのステップがあります。cscope を使用すると簡単にこのステップを実行できます。

まず、2 番目のメニュー項目「Find this global definition」を使用して、関数を編集します。次に、その関数がどこで呼び出されているかを探します。4 番目のメニュー項目「Find function calling this function」を使用すると、ある関数を呼び出しているすべての関数のリストを表示することができます。このリストを使用して、リストの各行番号を個々に入力してエディタを起動するかまたは ^e を入力して、各行のすべての参照元ファイルを対象にエディタを自動的に起動することができます。このような修正処理に cscope を使用すると、修正を必要とする関数はすべて修正され、見落とすことがありません。

例 3:変数の値を変更する

変更内容がコードにどのように影響するかを見たいときに、表示手段として cscope が力を発揮します。変数の値またはプリプロセッサシンボルを変更する場合を考えてみます。実際に変更する前に、最初のメニュー項目「Find this C symbol」を使用して、変更によって影響を受ける参照箇所のリストを表示します。それから、エディタを起動して各参照箇所を調べます。これによって、変更によるすべての影響を予測できます。同様に cscope を使用して、間違いなく変更されたことも確認できます。

エディタのコマンド行構文

cscope はデフォルトで vi エディタを使用しています。EDITOR 環境変数に任意のエディタ名を設定して EDITOR をエクスポートすると、デフォルトを変更することができます。この手順については、「ステップ 1:環境設定」で述べた通りです。ただし cscope は、使用するエディタのコマンド行構文が vi と同様に次のような形式であるとみなします。

% editor +<行番号> <ファイル>

使用したいエディタがこのようなコマンド行構文を持っていない場合は、cscope とエディタ間のインタフェースを定義する必要があります。

ed を使用する場合を考えてみます。ed では、コマンド行内に行番号を指定することができないので、そのままでは cscope のエディタとして使用できません。そこで、次のような行を含むシェルスクリプトを作成します。

/usr/bin/ed $2

ここでは、シェルスクリプトを myedit とします。環境変数 EDITOR の値をこのシェルスクリプトに設定して EDITOR をエクスポートします。

Bourne シェルの場合は以下のように入力します。

$ EDITOR=myedit; export EDITOR

C シェルの場合は以下のように入力します。

% setenv EDITOR myedit

cscope は、指定されたリスト項目 (たとえば、main.c の 17 行目) を読み込んでエディタを起動するとき、次のようなコマンド行を使用してシェルスクリプトを起動します。

% myedit +17 main.c

myedit は第一引数の行番号 ($1) を無視して、第二引数のファイル名 ($2) だけを使用して ed を正しく呼び出します。希望する行を表示および編集するには、適切な ed コマンドを実行する必要があります。すなわち、17 行目に自動的に移動することはありません。

不明な端末タイプのエラー

次のエラーメッセージが出力されることがあります。

Sorry, I don't know how to deal with your "term" terminal

このメッセージは、現在ロードされている端末情報ユーティリティ (terminfo) データベース内に使用端末が含まれていないことを意味します。TERM に正しい値が設定されていることを確認してください。それでもメッセージが出力される場合は、端末情報ユーティリティを再ロードしてください。次のようなメッセージも表示されることがあります。

Sorry, I need to know a more specific terminal type than "unknown"

このメッセージが表示されたら、「ステップ 1:環境設定」で述べた手順に従って、TERM 環境変数を設定しエクスポートしてください。


サン・マイクロシステムズ株式会社
Copyright information. All rights reserved.
ホーム   |   目次   |   前ページへ   |   次ページへ   |   索引