• 検索結果がありません。

32  Sapidによるソフトウエア解析技法

関数getFuncCall 関数呼び出しのカウント

アルゴリズム

関数main

1.宣言declarationオブジェクト配列中で、関数宣言であるものを選ぶ 2.1.でもとめたdecralationオブジェクトからoptionaldeclを得る 関数

g

etFuncCall

a

各定義関数中のクラスidentierのオブジヱクト出現 (ωαlITence)の取得 4取得されたオブジェク卜の中で属性

: ω

此が関数(ID̲FUNCTIO問であるものを選ぶ 5関数名を絡納する配列func̲idを調べ、新規の名前かどうかを判断する

ら新規の関数であった場合は配列白nc̲idに格納し、情報を出力する

#fineMAX FUNC SIZE 100  :?o idge ncωCall(S凶OIdftmB

SpdO白 白nc00c; SpdCursorncー田町

SpdObjld  func̲id[MAX̲FUNC̲SIZE]func̲id 1;  int  i=Oj=O; 

/ / 3 .

名前の出現を求める

func":‑cS

  ' r

spdGctIItciudedOccInit(funcDecUd, "identifier" funcDecUd); 

while ((func'::'occ = spdGetInc1udedO(func一 回r)).relationld!= SAPID̲NON̲ID) 

/ / 4 .

関数の名前の出現だけ抜き出す

if (5pdGetAttrValInt(func̲oobjectld"50此")== ID]UNCI10N){ 

/ / 5 .

重複する関数名の出現があった場合は取り除く whi1e(j<=i) 

if(runc̲id[j++ ]==func̲occ.objectld)  goto EXIT2; 

//6.新規の場合配列funcidに格納、情報を出力する func̲id[i]=func̲occ.objectId; 

printf(" ealling Function Name %d:%5¥n'i++5pdGetName(funcid[i])); EXlT2 

J=α 

SpdFreeCuor(func̲r);

4 ‑ 1 ‑ 1  

関数getFunc

1 1

の改良

上記の関数getFuncCallは、処理対象の関数の数を最大

100

個として配列を 宣言しているが、対象とする関数の数が

100

個を超えると処理できなくなる。

そのため、構造体を用いてサイズに対応するよう関数を改良する。

関数getFuncCall(改良版)

void getFuncCll(SpdObjldfuncDecUd){ 

Spdゆ田 funcc' Spdursormcr' int  j;  /↓構造体の定義

Struct FUNC{ 

int func̲size;  }

spdohdIdfunc̲id; struct FUNC func;  /↓構造体の初期化 func.funcsize = 0;  func.func̲id = NULL; 

2章 ドキュメントの作成 33 

func̲csr = spdGetIncludedOccInit(funcDecUd, "identifier",funcDecUd); 

whiIe ((func':"occ = spdGetIncludedOcc(funcr)).relationld!= SAPID̲NON̲ID)  if(spdGeIAttrValInt(funcoec.objectI Ic"sort") == ID̲FUN

Cn

ON){ 

//↓関数の名前の出現だけ抜き出す for(j= 0; jfunc.funcsize;j++) 

if(func.funcid[j]==funcocc.objectld)  goto EXIT2; 

/↓構造体を配列のように使う方法(注参照)

func.func̲id=spdRealloc(func.funcid, sizeof(SpdOId)(func.funcsize+ 1));  func.funcid[func.nc̲size]= funcocc.objectId; 

/↓結果の面力

prin

r

Calling Function Name %s¥!l" 

spdGetName(func.func̲id[func.func̲size]));  func.func̲size ++; 

EXIT2: 

func.func̲id=(SpdObjld)malloc(sizeof(SpdObjld)(func.func̲si配 +1});でも可

4 . 2   関数の呼び出し位置(行数)

呼 び 出 し 位 置 を 行 数 で 求 め る 関 数 を 用 意 す る 。 オ ブ ジ ェ ク ト の 出 現 位 置 は オ フ セ ッ ト よ り 行 数 で 表 現 し た 方 が 便 利 で あ る 。 オ ブ ジ ェ ク ト I d をパラメータ として、該当オブジェクトの出現する先頭の行数を求める関数 spd̲geClineO を作成する。 i d e n t i f i e r な ど は 複 数 の 出 現 を 持 つ の で 、 参 照 関 連 で 対 応 す る ク ラス ( e x p r e s s i o n ) のオブジェクトを関数 spd̲get̲IineO のパラメータとする。

同関数を利用するためには、モデ)レ P‑model が 必 要 で あ り 、 モ デ ル 呼 び 出 し 関 数を用意する。

関数 spd̲geCline 行数を求める

static int spdJ;ecline(SpdObjld id){ 

SpdOcc  occ;  SpdRegion  i̲region;  SpdRegion  c̲region;  int  line = MAJCUNE̲SIZE; 

int  column = MAX̲COLUMN̲SIZE; 

occ = spdGetAnOffsetOfObj(id);  if(occ.objectld!= SAPID̲NON̲IDl { 

34  Sapid

によるソフトウェア解析技法

仁元gion=云両面面てー玩Ton‑(c); c̲gionipdConvRegionItoCbyPIDB(i̲region);  if(cregion.fileld != SAPID̲NON̲ID) {  } 

spdCnvOffsetToLineColumn(c̲region.fileld. c̲region.offset. 

&line. &column);  return Oine); 

関数

openModel

ーモデル呼び出し

void openModel(SpdDBld dbld){ 

SpdModeUd  ImodelId. PmodelId;  ImodelIspdUseModel(&Cmode; PmodelIipdUseMod1(&P

model); spdIt回dDB(TmodelId.dbld);  spdIt回dDB(PmodelId.dbld); 

4 . 3   関数被呼び出しを求める

ある関数が他の関数中で呼び出される情報を求める。プログラム中のすべて の関数定義文における当該関数の出現を求める。

optionaldecl

オブジエクト配 列 で 関 数 宣 言 オ ブ ジ ェ ク ト を 順 番 に 求 め 、 そ の 関 数 本 体 中 の

expression

オブ ジ エ ク ト の 出 現 を 求 め る 。 そ れ ら の オ ブ ジ ェ ク ト 中 で

sort

が 関 数 呼 び 出 し 式

(EXPR̲SORT̲FUNCCALL)

で 、 関 数 名 を 表 す

identifier

オブジェクトの

Id

が呼び出される関数と同じものを選び、そのオブジェクトに関連する情報を求 める。

関数

getFuncCalled

一関数被呼び出しの情報を求める アルゴリズム

関数

getFuncCalled

1.クラス

optionalde

cJの配列オブジェクトを取得

2. 

1.で取得されたオブジェクト中で

SORT

が関数宣言であるものを選ぶ

3.

式の出現で、

SORT

が関数呼び出しであるものを選ぶ

4.3.で得られた式から関数名(i

dentifier)

を取り出し、パラメータの

Idと比較 5.

該当関数を呼び出す関数の情報(行数など)を出力

void geCfuncCalled(SpdObjld ident.ーid)

S凶Cuor・ 白r SpdObjldArray func̲a'ay; SpdOcc  0田;

SpdObjld  decr̲id. fname̲id;  int  i; 

2章

ドキュメントの作成

35 

ドキュメント内 Sapidによるソフトウェア解析技法 (ページ 37-41)