(57)【要約】【課題】既に使用されているソースコード構成管理システムで管理しているソースコードでは、ソースファイル内のどの関数が変更されたのかを確認する手段がない。静的解析情報の複雑度は関数ごとの情報であり、プログラム開発者が改善すべきソースコードを把握する際に変更の情報と複雑度の情報を合わせて見られず、優先して改善すべきソースコードを把握できない。【解決手段】各リビジョンのソースファイルをソースコード構成管理システムから取得し、ソースファイル内を関数に分割する。そのリビジョンの差分情報の変更・削除・追加された行の内容および行番号の情報をソースコード構成管理システムから取得し、どの関数が変更されたか把握する。関数ごとの変更情報を作成し、関数ごとの静的解析情報の複雑度と結合して表示する。【選択図】図１
2012230512.tif 000002
【特許請求の範囲】
【請求項１】
構成管理システムで管理されているソースファイル単位の更新履歴から関数の変更回数を解析し、複雑度と結合して表示する機能を特徴とする関数の変更回数と複雑度を表示するシステム。
【請求項２】
請求項１における関数の変更回数の解析に加えて、関数の変更行数も解析し、関数の変更回数と変更行数と複雑度を結合して表示する機能を特徴とする関数の変更回数と変更行数と複雑度を表示するシステム。
【請求項３】
請求項１における関数の変更回数と複雑度の表示する際に、関数の変更回数と複雑度から改善優先度を評価して表示順序を並び替えて表示する機能を特徴とする関数の変更回数と複雑度を表示するシステム。
【請求項４】
請求項３における改善優先度を評価する際に、ユーザから指定された値により改善優先度の評価計算を変更する機能を特徴とする関数の変更回数と複雑度を表示するシステム。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、Ｃ言語のソースコードにおける関数ごとの複雑度と変更情報を表示するシステムに関するものである。
【背景技術】
【０００２】
ソースコード構成管理システムは、ソースコードをファイルごとに管理し、ファイルごとの変更履歴を確認することができる。例えば、１ソースファイルについて２つのリビジョン間における変更・削除・追加された行を取得できる。過去に変更回数が多いソースファイルは、今後も変更が多い可能性が高い。
【０００３】
関数の複雑度は、ソースコード内の各関数についてのプログラム構造の複雑度である。複雑度が高いソースコードは、そのソースコードを継続管理していく上で変更が発生した場合に、作業時間がかかる可能性が高い。
【０００４】
複雑度は改善すべき関数を決定する指針の１つであり、プログラム開発者は、複雑度が高い関数に対してプログラム構造を見直すが、変更を行う可能性が高いソースコード部分を優先して見直していく必要がある。
【０００５】
特開２００８−０２１２４４２号公報（特許文献１）に開示された、ソースコード修正優先度付けシステムおよびその優先度付け方法では、ソースコード修正の優先度付けがされるが、ソースコード構成管理システムに独自の構成管理データベースを持つ方式のため、既に使用されているソースコード構成管理システムで管理しているソースコードに対して適用できないという問題がある。
【先行技術文献】
【特許文献】
【０００６】
【特許文献１】特開２００８−０２１２４４２号公報
【発明の概要】
【発明が解決しようとする課題】
【０００７】
既に使用されているソースコード構成管理システムで管理しているソースコードでは、ソースコード構成管理システムから取得できる変更履歴はソースファイル単位のため、ソースファイル内のどの関数が変更されたのかを確認する手段がない。
【０００８】
本発明が解決する課題は、既存のソースコード構成管理システムのソースファイルの変更履歴情報と、関数ごとの情報である静的解析情報の複雑度とから、関数ごとの変更情報と複雑度を結合して表示することにより、プログラム開発者が見直すべきソースコードを把握することができることである。
【課題を解決するための手段】
【０００９】
本発明のシステムは、ソースコード構成管理システムを持つ。ソースコード構成管理システムに作成・変更したソースファイルを登録すると、登録時にリビジョンが付加される。ソースコード構成管理システムは、各リビジョンのソースファイルを出力することができる。また、１ソースファイルの２つのリビジョン間の差分情報を出力することができる。差分情報には、リビジョン間で変更・削除・追加された行の内容および行番号を含む。
【００１０】
各リビジョンのソースファイルをソースコード構成管理システムから取得し、ソースファイル内を関数に分割する。次にそのリビジョンの差分情報の変更・削除・追加された行の内容および行番号の情報をソースコード構成管理システムから取得し、どの関数が変更されたかを把握する。
【００１１】
関数ごとの変更情報を作成することにより、関数ごとの静的解析情報の複雑度と結合して表示することが出来る。
【発明の効果】
【００１２】
本発明のシステムにより、関数ごとの変更情報と複雑度を結合して表示することで、プログラム開発者は見直すべきソースコードを把握することができる。
【図面の簡単な説明】
【００１３】
【図１】表示システムの構成図。
【図２】差分情報の例。
【図３】テーブル１の例。
【図４】テーブル２の例。
【図５】テーブル３の例。
【図６】テーブル４の例。
【図７】テーブル５の例。
【図８】テーブル６の例。
【図９】テーブル７の例。
【図１０】テーブル８の例。
【図１１】テーブル９の例。
【図１２】関数の変更回数と複雑度の一覧を表示する処理の処理フロー図。
【図１３】差分情報から変更前後のリビジョンについて変更範囲を解析する処理の処理フロー図。
【図１４】リビジョン間の変更範囲の情報をテーブル３に格納する処理の処理フロー図。
【図１５】ソースコードを字句解析してテーブル４に格納する処理の処理フロー図。
【図１６】字句解析して得られたトークンから関数の開始行番号を解析する処理の処理フロー図。
【図１７】字句解析して得られたトークンから関数の終了行番号を解析する処理の処理フロー図。
【図１８】テーブル３の各行について変更開始行番号列と変更終了行番号列の値を取り出す処理の処理フロー図。
【図１９】リビジョン間で変更のあった関数を解析する処理の処理フロー図。
【図２０】変更のあった関数の変更回数をテーブル７に格納する処理の処理フロー図。
【図２１】ソースコードを字句解析してテーブル４に格納する処理の処理フロー図。
【図２２】関数の変更回数と複雑度を結合する処理の処理フロー図。
【図２３】関数の変更回数と複雑度を表示する処理の処理フロー図。
【図２４】関数の変更回数と複雑度の表示例。
【図２５】テーブル１０の例。
【図２６】テーブル１１の例。
【図２７】テーブル１２の例。
【図２８】リビジョン間で変更のあった関数の変更行数をテーブル１０に格納する処理の処理フロー図。
【図２９】変更のあった関数の変更回数と変更行数をテーブル１１に格納する処理の処理フロー図。
【図３０】関数の変更回数と変更行数と、複雑度を結合する処理の処理フロー図。
【図３１】関数の変更回数と変更行数と、複雑度の表示例。
【図３２】テーブル１３の例。
【図３３】変更回数と複雑度から優先度評価を求めてテーブル１３に格納する処理の処理フロー図。
【図３４】関数の変更回数と複雑度を優先度評価列で降順に並び替えてから表示する処理の処理フロー図。
【図３５】関数の変更回数と複雑度を優先度評価列で降順に並び替えた表示例。
【図３６】ユーザから指定された複雑度の閾値により優先度評価を行う処理の処理フロー図。
【発明を実施するための形態】
【００１４】
以下、実施例を図面を用いて説明する。
【実施例１】
【００１５】
図１は本発明を実施するシステムの構成図である。本システムは、関数の変更回数と複雑度対応付け機能（１０１）、関数の変更回数測定機能（１０２）、複雑度測定機能（１０３）、ソースコード構成管理システム（１０４）を持つサーバ装置（１０５）と、入力装置（１０６）、出力装置（１０７）から構成される。ソースコード構成管理システムは構成管理情報の格納された構成情報管理ＤＢ（１０８）を持ち、検出機能からの問い合わせに対して構成管理情報を返す。例えば、ソースコード構成管理システムとしてはＳｕｂｖｅｒｉｏｎというＯＳＳ（Ｏｐｅｎ Ｓｏｕｒｃｅ Ｓｏｆｔｗａｒｅ）がある。本システムが持つソースコード構成管理システムはソースファイル名と２つのリビジョン番号を指定することにより、リビジョン間の差分情報を出力する機能を持つ。
【００１６】
図２は差分情報の一例を示した図である。差分情報（２０１）は、ユニファイド形式である。ユニファイド形式の差分情報の構造は、先頭にファイル名を示す行、その後にファイルについて２つのリビジョン間で何行目に変更があるかを示す行番号の行が続き、さらにその後に削除行を示す行、挿入行を示す行、非変更行を示す行が続く。ファイル名を示す行は、３つの−記号で始まる行と、３つの＋記号で始まる行である。変更のあった行番号を示す行は２つの＠記号で始まり２つの＠記号で終わる行である。削除行を示す行は−記号で始まる行である。挿入行を示す行は＋記号で始まる行である。非変更行を示す行は半角スペース記号で始まる行である。行番号の行の−記号から始まる「−５，１０」の部分が変更前のソースコードについて表示されている差分情報の表示開始行と表示範囲行を示し、＋記号から始まる「＋５，１０」が変更後のソースコードについて表示されている差分情報の表示開始行と表示範囲行を示す。
【００１７】
図３は２つのリビジョン間で変更のあったファイルのファイル名をソースコード構成管理システムから取得して格納するテーブル１を示した図である。テーブル１はファイル名列（３０１）を持ち、ファイル名列の各行にはファイル名が１つずつ格納される。
【００１８】
図４はテーブル１に格納されたファイル名のファイルについて、その差分情報をソースコード構成管理システムから取得して格納するテーブル２を示した図である。テーブル２は差分情報列（４０１）を持ち、差分情報列の各行には差分情報が１行ずつ格納される。
【００１９】
図５はテーブル２に格納された差分情報をもとに、変更前後のリビジョンの変更開始行と変更終了行を格納するテーブル３を示した図である。テーブル３はリビジョン列（５０１）、変更開始行番号列（５０２）、変更終了行番号列（５０３）を持つ。リビジョン列の各行には、変更範囲が変更前後のリビジョンのどちらであるかを識別するためにリビジョン番号が格納される。変更開始行番号列の各行には、変更範囲の開始行番号が格納される。変更終了行番号列の各行には、変更範囲の終了行番号が格納される。
【００２０】
図６はテーブル１に格納されたファイル名のファイルについて、字句解析して得られたトークンを格納するテーブル４を示した図である。字句解析は、ソースコードを構成する文字の並びを、意味を持つ最小単位ごとに分割する。意味を持つ最小単位をトークンという。Ｃ言語のトークンは、ＩＳＯ／ＩＥＣ  ９８９９で定められている。テーブル４はＩＤ列（６０１）、値列（６０２）、種別列（６０３）、行番号列（６０４）を持つ。ＩＤ列の各行には、トークンを識別するためにトークンの出現する順に数値が１ずつ加算して格納される。値列の各行にはトークンが格納される。種別列の各行にはトークンの種別が格納される。行番号列の各行にはトークンの出現する行の行番号が格納される。トークンの種別は「ｉｄｅｎｔｉｆｉｅｒ」を「識別子」、「（」記号を「開き丸括弧」、「）」記号を「閉じ丸括弧」、「｛」記号を「開き波括弧」、「｝」記号を「閉じ波括弧」、「；」記号を「セミコロン」、「，」記号を「コンマ」、その他のトークンを「その他」とする。
【００２１】
図７はテーブル４に格納されたトークン情報をもとに、関数定義の開始行と終了行を格納するテーブル５を示した図である。テーブル５はＩＤ列（７０１）、関数名列（７０２）、開始行番号列（７０３）、終了行番号列（７０４）を持つ。ＩＤ列の各行には、関数名を表すトークンのＩＤが格納される。関数名列の各行には、関数名を表すトークンの値が格納される。開始行番号列の各行には、関数名を表すトークンの出現する行の行番号が格納される。終了行番号列には、関数の終了を表すトークンの出現する行の行番号が格納される。
【００２２】
図８はテーブル３に格納された変更開始行番号（５０２）と変更終了行番号（５０３）と、テーブル５に格納された関数定義範囲の情報をもとに、変更のあった関数の関数名を格納するテーブル６を示した図である。テーブル６はファイル名列（８０１）、関数名列（８０２）を持つ。ファイル名列の各行には、関数定義が記述されているファイルのファイル名が格納される。関数名列の各行には、関数名が格納される。
【００２３】
図９はテーブル６に格納されたファイル名と関数名をもとに、関数の変更回数を格納するテーブル７を示した図である。テーブル７はファイル名列（９０１）、関数名列（９０２）、変更回数列（９０３）を持つ。ファイル名列の各行には、関数定義が記述されているファイルのファイル名が格納される。関数名列の各行には、関数名が格納される。変更回数列の各行には、関数の変更回数が格納される。
【００２４】
図１０は複雑度測定機能により得られた関数の複雑度を格納するテーブル８を示した図である。テーブル８はファイル名列（１００１）、関数名列（１００２）、複雑度列（１００３）を持つ。ファイル名列の各行には、関数定義が記述されているファイルのファイル名が格納される。関数名列の各行には、関数名が格納される。複雑度列の各行には、関数の複雑度が格納される。
【００２５】
図１１はテーブル７に格納された変更回数とテーブル８に格納された複雑度を結合して格納するテーブル９を示した図である。テーブル９はファイル名列（１１０１）、関数名列（１１０２）、変更回数列（１１０３）、複雑度列（１１０４）を持つ。ファイル名列の各行には、関数定義が記述されているファイルのファイル名が格納される。関数名列の各行には、関数名が格納される。変更回数列の各行には、関数の変更回数が格納される。複雑度列の各行には、関数の複雑度が格納される。
【００２６】
図１２は関数の変更回数と複雑度の一覧を表示するまでの一実施例を示した処理フロー図である。まず、構成情報管理ＤＢから最新のリビジョン番号を取得し、変数ｒｅｖ１に格納する（１２０１）。ｒｅｖ１の値が２以上であるか、１以下であるかを確認する（１２０２）。ｒｅｖ１の値が２以上の場合（１２０３）、ｒｅｖ１から１引いた値を変数ｒｅｖ２に格納する（１２０４）。ｒｅｖ２とｒｅｖ１の間で変更された全ファイルのファイル名を構成情報管理ＤＢから取得し、テーブル１に格納する（１２０５）。テーブル１の先頭の行に移動する（１２０６）。行が存在するか確認する（１２０７）。行が存在する場合（１２０８）、ファイル名列の値を変数ｆｉｌｅに格納する（１２０９）。構成情報管理ＤＢからファイル名がｆｉｌｅであるファイルについて、ｒｅｖ２とｒｅｖ１の間の差分情報を取得する（１２１０）。取得した差分情報を行単位に分割し、テーブル２に格納する（１２１１）。その後に図１３のコネクタＡへ処理を進める（１２１２）。テーブル１の先頭の行に移動したときに行が存在するか確認し、行が存在しない場合（１２１３）、ｒｅｖ２の値をｒｅｖ１に格納し（１２１４）、ｒｅｖ１の値を確認し、値が１以下の場合（１２１５）、図２２のコネクタＰに処理を進める（１２１６）。
【００２７】
図１３はテーブル２に格納した差分情報から変更前後のリビジョンについて変更範囲を解析する処理を示した処理フロー図である。処理はコネクタＡから開始される（１３０１）。テーブル２の先頭の行に移動する（１３０２）。行の先頭の文字が＠記号かその他かを確認する（１３０３）。その他の場合（１３０４）、テーブル２の１つ後の行に移動する（１３０５）。行が存在するか確認し、存在する場合（１３０６）、行の先頭の文字が＠記号かその他かを確認する。＠記号の場合（１３０７）、この行の、＋記号の直後に出現する数値を変数ｓｔａｒｔ１に格納し（１３０８）、−記号の直後に出現する数値を変数ｓｔａｒｔ２に格納する（１３０９）。変数ｃｎｔ１に０を、変数ｃｎｔ２に０を格納する（１３１０）。変数ｒｎｇ１に−１を、変数ｒｎｇ２に−１を格納する（１３１１）。テーブル２の１つ後の行に移動する（１３１２）。行が存在するか確認し、行が存在する場合（１３１３）、行の先頭の文字が＠記号かその他かを確認する（１３１４）。＠記号の場合（１３１５）、処理１３０８に進む。その他の場合（１３１６）、行の先頭の文字が＋記号か−記号かその他かを確認する（１３１７）。＋記号の場合（１３１８）、ｒｎｇ１の値に１加算する（１３１９）。−記号の場合（１３２０）、ｒｎｇ２の値に１加算する（１３２１）。その後、コネクタＢ（１３２２）を経由して（１３２３）、テーブル２の１つ後ろの行の処理に進む。その他の場合（１３２４）、図１４のコネクタＣに処理を進める（１３２５）。図１４の処理からの復帰を示すコネクタＤ（１３２６）からは、ｃｎｔ１にｒｎｇ１に２を加算した値を、ｃｎｔ２にｒｎｇ２に２を加算した値を格納し（１３２７）、処理１３１１に進む。テーブル２の１つ後の行に移動して行が存在するか確認し、存在しない場合（１３２８）（１３２９）、図１５のコネクタＥへ処理を進める（１３３０）（１３３１）。
【００２８】
図１４は図１３で解析した変更範囲の情報をテーブル３に格納する処理を示した処理フロー図である。処理はコネクタＣ（１４０１）から開始される。ｒｎｇ１の値が−１か確認する（１４０２）。−１以外の場合（１４０３）、変数ｓｌ１にｓｔａｒｔ１とｃｎｔ１の和を格納し（１４０４）、変数ｅｌ１にｓｌ１とｒｎｇ１の和を格納する（１４０５）。テーブル３に行を追加し、追加した行のリビジョン列にｒｅｖ１の値、開始行番号列にｓｌ１の値、終了行番号列にｅｌ１の値を格納する（１４０６）。ｒｎｇ１の値が−１か確認し、−１の場合（１４０７）、ｒｎｇ２の値が−１か確認する（１４０８）。−１以外の場合（１４０９）、変数ｓｌ２にｓｔａｒｔ２とｃｎｔ２の和を格納し（１４１０）、変数ｅｌ２にｓｌ２とｒｎｇ２の和を格納する（１４１１）。テーブル３に行を追加し、追加行のリビジョン列にｒｅｖ２の値、開始行番号列にｓｌ２の値、終了行番号列にｅｌ２の値を格納する（１４１２）。格納後、図１３のコネクタＤへ処理を進める（１４１３）。ｒｎｇ２の値が−１か確認し、−１の場合（１４１４）、図１３のコネクタＤへ処理を進める（１４１５）。
【００２９】
図１５はファイル名がｆｉｌｅのファイルについて、リビジョンがｒｅｖ１のときのソースコードを字句解析してテーブル４に格納する処理を示した処理フロー図である。処理はコネクタＥ（１５０１）から開始される。変数ｒｅｖにｒｅｖ１の値を格納する（１５０２）。構成情報管理ＤＢからファイル名がｆｉｌｅのファイルについて、リビジョンがｒｅｖのときのソースコードを取得する（１５０３）。ソースコードを字句解析してトークンに分割し、出現する順に１ずつ加算したＩＤ、トークン、種別、出現する行の行番号を、テーブル４に格納する（１５０４）。その後、図１６のコネクタＦへ処理を進める（１５０５）。
【００３０】
図１６はテーブル４に格納されたトークンから関数の開始行番号を解析する処理を示した処理フロー図である。処理はコネクタＦ（１６０１）から開始される。テーブル４の先頭の行に移動する（１６０２）。行が存在するか確認する（１６０３）。行が存在する場合（１６０４）、種別列の値を確認する（１６０５）。種別列の値が「識別子」以外の場合（１６０６）、テーブル４の１つ後の行に移動する（１６０７）。種別列の値が「識別子」の場合（１６０８）、変数ｉｄにＩＤ列の値を、変数ｖａｌｕｅに値列の値を、変数ｌｉｎｅに行番号列の値を格納する（１６０９）。テーブル４の１つ後の行に移動する（１６１０）。行が存在するか確認する（１６１１）。行が存在する場合（１６１２）、種別列の値を確認する（１６１３）。種別列の値が「開き丸括弧」以外の場合（１６１４）、コネクタＧへ処理を進める（１６１５）。種別列の値が「開き丸括弧」の場合（１６１６）、テーブル４の１つ後の行に移動する（１６１７）。行が存在するか確認する（１６１８）。行が存在する場合（１６１９）、種別列の値を確認する（１６２０）。種別列の値が「閉じ丸括弧」以外の場合（１６２１）、処理１６１７へ処理を進める。種別列の値が「閉じ丸括弧」の場合（１６２２）、テーブル４の１つ後の行に移動する（１６２３）。行が存在するか確認する（１６２４）。行が存在する場合（１６２５）、種別列の値を確認する（１６２６）。種別列の値が「開き波括弧」以外の場合（１６２７）、コネクタＧへ処理を進める（１６２８）。種別列の値が「開き波括弧」の場合（１６２９）、テーブル５に行を追加し、追加した行のＩＤ列にｉｄの値を、関数名列にｖａｌｕｅの値を、開始行番号列にｌｉｎｅの値を格納する（１６３０）。格納後、コネクタＧへ処理を進める（１６２８）。コネクタＧ（１６３１）からは、テーブル４の１つ後の行に移動し、処理を進める。行が存在するか確認したときに、行が存在しない場合（１６３２）（１６３３）（１６３４）（１６３５）、図１７のコネクタＨへ処理を進める（１６３６）（１６３７）（１６３８）（１６３９）。
【００３１】
図１７はテーブル４に格納されたトークンから関数の終了行番号を解析する処理を示した処理フロー図である。処理はコネクタＨ（１７０１）から開始される。テーブル４の末尾の行に移動する（１７０２）。行が存在するか確認する（１７０３）。行が存在しない場合（１７０４）、図１８のコネクタＪへ処理を進める（１７０５）。行が存在する場合（１７０６）、種別列の値が「閉じ波括弧」か確認する（１７０７）。種別列の値が「閉じ波括弧」以外の場合（１７０８）、テーブル４の１つ前の行に移動し（１７０９）、処理を進める。種別列の値が「閉じ波括弧」の場合（１７１０）、変数ｉｄ１にＩＤ列の値を、変数ｖａｌｕｅに値列の値を、変数ｌｉｎｅに行番号列の値を格納する（１７１１）。テーブル４の１つ後の行を確認する（１７１２）。行が存在する場合（１７１３）、種別列の値が「識別子」か確認する（１７１４）。種別列の値が「識別子」の場合（１７１５）、テーブル４の１つ後の行を確認する（１７１６）。行が存在する場合（１７１７）か、処理１７１４で種別列の値が「識別子」以外の場合（１７１８）、種別列の値が「コンマ」か「セミコロン」か確認する（１７１９）。種別列の値が「コンマ」か「セミコロン」の場合（１７２０）か、処理１７１６で行が存在しない場合（１７２１）、コネクタＩへ処理を進める（１７２２）。コネクタＩ（１７２３）からは、テーブル４の１つ前の行に移動し、処理を進める。種別列の値が「コンマ」でも「セミコロン」でもない場合（１７２４）か、処理１７１２で行が存在しない場合（１７２５）、テーブル５からＩＤ列の値がｉｄ１の次に小さい行を探す（１７２６）。行が存在しない場合（１７２７）、図１８のコネクタＪへ処理を進める（１７２８）。行が存在する場合（１７２９）、この行の終了行番号の列にｌｉｎｅの値を格納する（１７３０）。この行のＩＤ列の値を変数ｉｄ２に格納する（１７３１）。テーブル４のＩＤ列の値がｉｄ２の行へ移動し（１７３２）、処理を進める。
【００３２】
図１８はテーブル３の各行について変更開始行番号列と変更終了行番号列の値を取り出す処理を示した処理フロー図である。処理はコネクタＪ（１８０１）から開始される。テーブル３の先頭の行に移動する（１８０２）。行が存在するか確認する（１８０３）。行が存在しない場合（１８０４）、図２０のコネクタＭへ処理を進める（１８０５）。行が存在する場合（１８０６）、リビジョン列の値を確認する（１８０７）。リビジョン列の値がｒｅｖと等しくない場合（１８０８）、テーブル３の１つ後の１行を確認する（１８０９）。リビジョン列の値がｒｅｖと等しい場合（１８１０）、変数ｍｓに変更開始行番号列の値を、変数ｍｅに変更終了行番号列の値を格納する（１８１１）。格納後、図１９のコネクタＫへ処理を進める（１８１２）。図１９の処理からの復帰を示すコネクタＬ（１８１３）からは、テーブル３の１つ後の１行を確認する（１８０９）。
【００３３】
図１９はｍｓ、ｍｅとテーブル５の関数の開始行番号と終了行番号から、変更のあった関数を解析する処理を示した処理フロー図である。処理はコネクタＫ（１９０１）から開始される。テーブル５の先頭の１行を確認する（１９０２）。行が存在するか確認する（１９０３）。行が存在しない場合（１９０４）、図１８のコネクタＬへ処理を進める（１９０５）。行が存在する場合（１９０６）、開始行番号列の値がｍｅ以下であり、かつ、終了行番号列の値がｍｓ以上であることを満たすか確認する（１９０７）。満たさない場合（１９０８）、テーブル５の１つ後の１行を確認し（１９０９）、次の処理を進める。満たす場合（１９１０）、変数ｆｕｎｃに関数名列の値を格納する（１９１１）。テーブル６から、ファイル名列の値がｆｉｌｅと等しく、関数名列の値がｆｕｎｃと等しい行を探す（１９１２）。行が存在する場合（１９１３）、テーブル５の１つ後の１行を確認し（１９０９）、次の処理を進める。行が存在しない場合（１９１４）、テーブル６に行を追加し、追加した行のファイル名列にｆｉｌｅを、関数名列にｆｕｎｃを格納する（１９１５）。テーブル５の１つ後の１行を確認し（１９０９）、次の処理を進める。
【００３４】
図２０はテーブル６に格納されたファイル名と関数名から、変更のあった関数の変更回数をテーブル７に格納する処理を示した処理フロー図である。処理はコネクタＭ（２００１）から開始される。テーブル６の先頭の行に移動する（２００２）。行が存在するか確認する（２００３）。行が存在しない場合（２００４）、ｒｅｖの値を確認する（２００５）。ｒｅｖの値がｒｅｖ１と等しい場合（２００６）、図２１のコネクタＮへ処理を進める（２００７）。ｒｅｖの値がｒｅｖ２と等しい場合（２００８）、図１２のコネクタＯへ処理を進める（２００９）。行が存在する場合（２０１０）、変数ｍｆｉｌｅにファイル名を、変数ｍｆｕｎｃに関数名を格納する（２０１１）。テーブル７から、ファイル名列の値がｍｆｉｌｅと等しく、関数名列の値がｍｆｕｎｃと等しい行を探す（２０１２）。行が存在する場合（２０１３）、この行の変更回数列の値に１加算する（２０１４）。行が存在しない場合（２０１５）、テーブル７に行を追加し、追加した行のファイル名列にｍｆｉｌｅを、関数名列にｍｆｕｎｃを、変更回数列に１を格納する（２０１６）。テーブル５の１つ後の１行を確認し（２０１７）、次の処理を進める。
【００３５】
図２１はファイル名がｆｉｌｅのファイルについて、リビジョンがｒｅｖ２のときのソースコードを字句解析してテーブル４に格納する処理を示した処理フロー図である。処理はコネクタＮ（２１０１）から開始される。変数ｒｅｖにｒｅｖ２の値を格納する（２１０２）。構成情報管理ＤＢからファイル名がｆｉｌｅのファイルについて、リビジョンがｒｅｖのときのソースコードを取得する（２１０３）。ソースコードを字句解析してトークンに分割し、出現する順に１ずつ加算したＩＤ、トークン、種別、出現する行の行番号を、テーブル４に格納する（２１０４）。その後、図１６のコネクタＦへ処理を進める（２１０５）。
【００３６】
図２２は複雑度測定機能により取得された複雑度とテーブル６の関数の変更回数を結合する処理を示した処理フロー図である。処理はコネクタＰ（２２０１）から開始される。構成情報管理ＤＢから最新のリビジョンの全ソースコードを取得する（２２０２）。全ソースコードについて複雑度測定機能により取得された複雑度をテーブル８に格納する（２２０３）。テーブル７の先頭の行に移動する（２２０４）。行が存在するか確認する（２２０５）。行が存在しない場合（２２０６）、図２３のコネクタＱへ処理を進める（２２０７）。行が存在する場合（２２０８）、変数ｆｉｌｅにファイル名列の値を、変数ｆｕｎｃに関数名列の値を、変数ｍｃに変更回数列の値を格納する（２２０９）。テーブル８からファイル名列の値がｆｉｌｅと等しく、関数名列の値がｆｕｎｃと等しい行を探す（２２１０）。行が存在しない場合（２２１１）、テーブル７の１つ後の行に移動し（２２１２）、次の処理を進める。行が存在する場合（２２１３）、変数ｃｃに複雑度列の値を格納する（２２１４）。テーブル９に行を追加し、追加した行のファイル名列にｆｉｌｅを、関数名列にｆｕｎｃを、変更回数列にｍｃを、複雑度列にｃｃを格納する（２２１５）。その後、テーブル７の１つ後の行に移動し（２２１２）、次の処理を進める。
【００３７】
図２３はテーブル９に格納された関数の変更回数と複雑度を表示する処理を示した処理フロー図である。処理はコネクタＱ（２３０１）から開始される。テーブル９に格納された関数の変更回数と複雑度を表示し（２３０２）、処理を終了する。
【００３８】
図２４はテーブル９に格納された関数の変更回数と複雑度の表示例である。テーブル９の各行に行番号を付与してＮｏ．列（２４０１）として表示する。
【実施例２】
【００３９】
本実施例では、関数の変更回数に加えて変更行数を表示することができる例を説明する。
【００４０】
図２５はテーブル３に格納された変更開始行番号（５０２）と変更終了行番号（５０３）と、テーブル５に格納された関数定義範囲の情報をもとに、変更のあった関数の関数名と変更行数を格納するテーブル１０を示した図である。テーブル１０はファイル名列（２５０１）、関数名列（２５０２）、変更行数列（２５０３）を持つ。ファイル名列の各行には、関数定義が記述されているファイルのファイル名が格納される。関数名列の各行には、関数名が格納される。変更行数列の各行には、関数の変更行数が格納される。
【００４１】
図２６はテーブル１０に格納されたファイル名と関数名、変更行数から、変更のあった関数の変更回数と変更行数を格納するテーブル１１を示した図である。テーブル１１はファイル名列（２６０１）、関数名列（２６０２）、変更回数列（２６０３）、変更行数列（２６０４）を持つ。ファイル名列の各行には、関数定義が記述されているファイルのファイル名が格納される。関数名列の各行には、関数名が格納される。変更回数列の各行には、関数の変更回数が格納される。変更行数列の各行には、関数の変更行数が格納される。
【００４２】
図２７はテーブル１１に格納された変更回数と変更行数と、テーブル８に格納された複雑度を結合して格納するテーブル１２を示した図である。テーブル１２はファイル名列（２７０１）、関数名列（２７０２）、変更回数列（２７０３）、変更行数列（２７０４）、複雑度列（２７０５）を持つ。ファイル名列の各行には、関数定義が記述されているファイルのファイル名が格納される。関数名列の各行には、関数名が格納される。変更回数列の各行には、関数の変更回数が格納される。変更行数列の各行には、関数の変更行数が格納される。複雑度列の各行には、関数の複雑度が格納される。
【００４３】
図２８は実施例１の図１９の処理について、変更行数を取得できるように拡張した処理フロー図である。処理はコネクタＫ（２８０１）から開始される。テーブル５の先頭の１行を確認する（２８０２）。行が存在するか確認する（２８０３）。行が存在しない場合（２８０４）、図１８のコネクタＬへ処理を進める（２８０５）。行が存在する場合（２８０６）、変数ｆｓに開始行番号列の値を、変数ｆｅに終了行番号列の値を格納する（２８０７）。ｆｓがｍｅ以下であり、かつ、ｆｅがｍｓ以上であることを満たすか確認する（２８０８）。満たさない場合（２８０９）、テーブル５の１つ後の１行を確認し（２８１０）、次の処理を進める。満たす場合（２８１１）、ｆｅの値を確認する（２８１２）。ｆｅの値がｍｅ未満の場合（２８１３）、変数ｒｅにｆｅの値を格納する（２８１４）。ｆｅの値がｍｅ以上の場合（２８１５）、変数ｒｅにｍｅの値を格納する（２８１６）。続けてｆｓの値を確認する（２８１７）。ｆｓの値がｍｓ未満の場合（２８１８）、変数ｒｓにｍｓの値を格納する（２８１９）。ｆｓの値がｍｓ以上の場合（２８２０）、変数ｒｓにｆｓの値を格納する（２８２１）。変数ｍｒにｒｅからｒｓを引いて１を加算した値を格納する（２８２２）。変数ｆｕｎｃに関数名列の値を格納する（２８２３）。テーブル１０から、ファイル名列の値がｆｉｌｅと等しく、関数名列の値がｆｕｎｃと等しい行を探す（２８２４）。行が存在する場合（２８２５）、この行の変更行数列の値にｍｒを加算する（２８２６）。行が存在しない場合（２８２７）、テーブル１０に行を追加し、追加した行のファイル名列にｆｉｌｅを、関数名列にｆｕｎｃを、変更行数列にｍｒを格納する（２８２８）。テーブル５の１つ後の１行を確認し（２８１０）、次の処理を進める。
【００４４】
図２９は実施例１の図２０について、テーブル１０に格納されたファイル名と関数名、変更行数から、変更のあった関数の変更回数と変更行数をテーブル１１に格納するように拡張した処理フロー図である。処理はコネクタＭ（２９０１）から開始される。テーブル１０の先頭の行に移動する（２９０２）。行が存在するか確認する（２９０３）。行が存在しない場合（２９０４）、ｒｅｖの値を確認する（２９０５）。ｒｅｖの値がｒｅｖ１と等しい場合（２９０６）、図２１のコネクタＮへ処理を進める（２９０７）。ｒｅｖの値がｒｅｖ２と等しい場合（２９０８）、図１２のコネクタＯへ処理を進める（２９０９）。行が存在する場合（２９１０）、変数ｍｆｉｌｅにファイル名を、変数ｍｆｕｎｃに関数名を、変数ｍｌｉｎｅに変更行数を格納する（２９１１）。テーブル１１から、ファイル名列の値がｍｆｉｌｅと等しく、関数名列の値がｍｆｕｎｃと等しい行を探す（２９１２）。行が存在する場合（２９１３）、この行の変更回数列の値に１を加算し、変更行数列にｍｌｉｎｅを加算する（２９１４）。行が存在しない場合（２９１５）、テーブル１１に行を追加し、追加した行のファイル名列にｍｆｉｌｅを、関数名列にｍｆｕｎｃを、変更回数列に１を、変更行数列にｍｌｉｎｅを格納する（２９１６）。テーブル５の１つ後の１行を確認し（２９１７）、次の処理を進める。
【００４５】
図３０は実施例１の図２２の処理について、テーブル１１に格納された関数の変更回数と変更行数と、複雑度を結合するように拡張した処理フロー図である。処理はコネクタＰ（３００１）から開始される。構成情報管理ＤＢから最新のリビジョンの全ソースコードを取得する（３００２）。全ソースコードについて複雑度測定機能により取得された複雑度をテーブル８に格納する（３００３）。テーブル１１の先頭の行に移動する（３００４）。行が存在するか確認する（３００５）。行が存在しない場合（３００６）、図２３のコネクタＱへ処理を進める（３００７）。行が存在する場合（３００８）、変数ｆｉｌｅにファイル名列の値を、変数ｆｕｎｃに関数名列の値を、変数ｍｃに変更回数列の値を、変数ｍｒに変更行数列の値を格納する（３００９）。テーブル７からファイル名列の値がｆｉｌｅと等しく、関数名列の値がｆｕｎｃと等しい行を探す（３０１０）。行が存在しない場合（３０１１）、テーブル１１の１つ後の行に移動し（３０１２）、次の処理を進める。行が存在する場合（３０１３）、変数ｃｃに複雑度列の値を格納する（３０１４）。テーブル１２に行を追加し、追加した行のファイル名列にｆｉｌｅを、関数名列にｆｕｎｃを、複雑度列にｃｃを、変更回数列にｍｃを、変更行数列にｍｒを格納する（３０１５）。その後、テーブル１１の１つ後の行に移動し（３０１２）、次の処理を進める。
【００４６】
図３１はテーブル１２に格納された関数の変更回数と変更行数と、複雑度の表示例である。テーブル１２の各行に行番号を付与してＮｏ．列（３１０１）として表示する。
【実施例３】
【００４７】
本実施例では、優先して改善すべき関数を変更回数と複雑度により並び替えて表示することができる例を説明する。
【００４８】
図３２はテーブル７に格納された変更回数、テーブル８に格納された複雑度、さらに変更回数と複雑度から求めた優先度評価を格納するテーブル１３を示した図である。テーブル１３はファイル名列（３２０１）、関数名列（３２０２）、変更回数列（３２０３）、複雑度列（３２０４）、優先度評価列（３２０５）を持つ。ファイル名列の各行には、関数定義が記述されているファイルのファイル名が格納される。関数名列の各行には、関数名が格納される。変更回数列の各行には、関数の変更回数が格納される。複雑度列の各行には、関数の複雑度が格納される。優先度評価列の各行には、変更回数と複雑度から求めた値が格納される。
【００４９】
図３３は実施例１の図２２の処理について、テーブル７に格納された変更回数とテーブル８に格納された複雑度から、優先度評価を求めるように拡張した処理を示した処理フロー図である。処理はコネクタＰ（３３０１）から開始される。構成情報管理ＤＢから最新のリビジョンの全ソースコードを取得する（３３０２）。全ソースコードについて複雑度測定機能により取得された複雑度をテーブル８に格納する（３３０３）。テーブル７の先頭の行に移動する（３３０４）。行が存在するか確認する（３３０５）。行が存在しない場合（３３０６）、図３４のコネクタＲへ処理を進める（３３０７）。行が存在する場合（３３０８）、変数ｆｉｌｅにファイル名列の値を、変数ｆｕｎｃに関数名列の値を、変数ｍｃに変更回数列の値を格納する（３３０９）。テーブル８からファイル名列の値がｆｉｌｅと等しく、関数名列の値がｆｕｎｃと等しい行を探す（３３１０）。行が存在しない場合（３３１１）、テーブル７の１つ後の行に移動し（３３１２）、次の処理を進める。行が存在する場合（３３１３）、変数ｃｃに複雑度列の値を格納する（３３１４）。ｃｃの値を確認する（３３１５）。ｃｃの値が２０以下の場合（３３１６）、変数ｅｓｔにｍｃを格納する（３３１７）。ｃｃの値が２０より大きい場合（３３１８）、変数ｅｓｔにｃｃから２０を引いた値にｍｃをかけた値を格納する（３３１９）。テーブル１３に行を追加し、追加した行のファイル名列にｆｉｌｅを、関数名列にｆｕｎｃを、変更回数列にｍｃを、複雑度列にｃｃを、優先度評価列にｅｓｔを格納する（３３２０）。その後、テーブル７の１つ後の行に移動し（３３１２）、次の処理を進める。
【００５０】
図３４は、テーブル１３の行を優先度評価列で降順に並び替えてから表示する処理を示した処理フロー図である。処理はコネクタＲ（３４０１）から開始される。テーブル１３の行を優先度評価列で降順に並び替える（３４０２）。テーブル１３に格納された関数の変更回数と複雑度を表示し（３４０３）、処理を終了する。
【００５１】
図３５はテーブル１３に格納された関数の変更回数と変更行数と、複雑度の表示例である。テーブル１３の各行に行番号を付与してＮｏ．列（３５０１）として表示する。
【実施例４】
【００５２】
本実施例では、優先して改善すべき関数を変更回数と複雑度により並び替えて表示することができる例を説明する。
【００５３】
図３６は実施例３の図３３について、ユーザから指定された複雑度の閾値により優先度評価を行うように拡張した処理を示した処理フロー図である。処理はコネクタＰ（３６０１）から開始される。構成情報管理ＤＢから最新のリビジョンの全ソースコードを取得する（３６０２）。全ソースコードについて複雑度測定機能により取得された複雑度をテーブル８に格納する（３６０３）。入力装置１０６によりユーザから指定された複雑度の閾値を受け取り変数ｔｈに格納する（３６０４）。テーブル７の先頭の行に移動する（３６０５）。行が存在するか確認する（３６０７）。行が存在しない場合（３６０８）、図３４のコネクタＲへ処理を進める（３６０９）。行が存在する場合（３６１０）、変数ｆｉｌｅにファイル名列の値を、変数ｆｕｎｃに関数名列の値を、変数ｍｃに変更回数列の値を格納する（３６１１）。テーブル８からファイル名列の値がｆｉｌｅと等しく、関数名列の値がｆｕｎｃと等しい行を探す（３６１２）。行が存在しない場合（３６１３）、テーブル７の１つ後の行に移動し（３６１４）、次の処理を進める。行が存在する場合（３６１５）、変数ｃｃに複雑度列の値を格納する（３６１６）。ｃｃの値を確認する（３６１７）。ｃｃの値がｔｈ以下の場合（３６１８）、変数ｅｓｔにｍｃを格納する（３６１９）。ｃｃの値がｔｈより大きい場合（３６２０）、変数ｅｓｔにｃｃからｔｈを引いた値にｍｃをかけた値を格納する（３６２１）。テーブル１３に行を追加し、追加した行のファイル名列にｆｉｌｅを、関数名列にｆｕｎｃを、変更回数列にｍｃを、複雑度列にｃｃを、優先度評価列にｅｓｔを格納する（３６２２）。その後、テーブル７の１つ後の行に移動し（３６１４）、次の処理を進める。
【符号の説明】
【００５４】
１０１…雑度対応付け機能、１０２…関数の変更回数測定機能、１０３…複雑度測定機能、１０４…ソースコード構成管理システム、１０５…サーバ装置、１０６…入力装置、１０７…出力装置、１０８…構成情報管理ＤＢ、２０１…差分情報、９０３…関数の変更回数、１００３…関数の複雑度。
【図１】
2012230512.tif 000003
【図２】
2012230512.tif 000004
【図３】
2012230512.tif 000005
【図４】
2012230512.tif 000006
【図５】
2012230512.tif 000007
【図６】
2012230512.tif 000008
【図７】
2012230512.tif 000009
【図８】
2012230512.tif 000010
【図９】
2012230512.tif 000011
【図１０】
2012230512.tif 000012
【図１１】
2012230512.tif 000013
【図１２】
2012230512.tif 000014
【図１３】
2012230512.tif 000015
【図１４】
2012230512.tif 000016
【図１５】
2012230512.tif 000017
【図１６】
2012230512.tif 000018
【図１７】
2012230512.tif 000019
【図１８】
2012230512.tif 000020
【図１９】
2012230512.tif 000021
【図２０】
2012230512.tif 000022
【図２１】
2012230512.tif 000023
【図２２】
2012230512.tif 000024
【図２３】
2012230512.tif 000025
【図２４】
2012230512.tif 000026
【図２５】
2012230512.tif 000027
【図２６】
2012230512.tif 000028
【図２７】
2012230512.tif 000029
【図２８】
2012230512.tif 000030
【図２９】
2012230512.tif 000031
【図３０】
2012230512.tif 000032
【図３１】
2012230512.tif 000033
【図３２】
2012230512.tif 000034
【図３３】
2012230512.tif 000035
【図３４】
2012230512.tif 000036
【図３５】
2012230512.tif 000037
【図３６】
2012230512.tif 000038