TECSInfoの使い方

[TECS](https://www.toppers.jp/tecs.html)の提供機能TECSInfoの使い方です．

# 対象
TECSで開発ができる方（中級者から）、TECSプログラムのデバッグをしたい方

# TECSInfoとは
TECSにおける**情報を効率的に取得する**フレームワークです．
ここでいう情報とはセル、セルタイプ、シグニチャ、関数などの

- 名称
- 接続関係
- 変数やメモリ情報

等を指します．
取得した情報はデバッグに使うなり、自分の開発に組込むなどしてみてください．

## TECSInfoコンポーネント図

以下のコンポーネント図を見るとどの情報を取得できるかがわかりやすいです．（本来今回の図はコンポーネント図とは言えませんが．）
![TECSInfo.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207569/b7b78745-e13a-1c67-a127-1bff57f5ad8c.png)


それぞれのセルが階層的に対象の情報を保持しています．同一セルタイプのセルが対象ごとに存在します．
（例えばNameSpaceが２つあれば２つのNameSpaceeInfoセルがプラグインにより自動生成されています．
これらはさらに各NameSpace下のセルタイプやシグニチャに対応したInfoセルに接続しています．）

<!-- TECSInfoセルは図中の全てのセルへの動的呼び口を持っています．   -->
これらの内、**目的のセルに動的結合**することで情報にアクセスできます．  

（同一セルタイプのセルに接続を切り替える場合は動的結合が便利でした．
 まだ動的結合やディスクリプタについてよくわからないという方はこちらからご覧ください．）
 ⇒ [TECS：動的結合の使い方](https://qiita.com/seito-zoso/items/2d387c0c51b6dcb3217a)

## TECSInfoディスクリプタの取得手順

TECSInfoディスクリプタの取得手順は以下になります、

- STEP１. TECSInfoセルで実装されたfind関数で名称からディスクリプタを取得．（ネームスペース、リージョン、シグニチャ、セルタイプ、セル名が指定できる）
  
- STEP２. そのセルに接続しているセルもディスクリプタを所有しています．例えばFunctionInfoセルへのディスクリプタはSignatureInfoセルが保持しています．つまりStep１で接続したセルから順に目的のセルまでたどるイメージです．

注意してほしいのは、例えばfind_cell( "CellA", &desc )でディスクリプタを取得した場合、 
「CellAへのディスクリプタを取得した」
のではなく、
「**CellAの情報を保持しているCellInfoセルへのディスクリプタを取得した**」 
ということです．



<!-- 例えばネームスペースNSに属するシグニチャSigの関数Funcのもつ引数にアクセスしたければ、その順番でセルに動的結合したどっていきます． -->


# 使用例
実際にTECSInfoを使ってみます．
以下のCDLの情報を取得したいとします．

```:target.cdl
namespace nNS {
  signature sSigA {
      void funcA( void );
  };
  signature sSigB {
      int funcB( [in] int a, [in] int b);
  };
  celltype tMain {
    call sSigA cMainA;
    call sSigB cMainB;
  };
  celltype tCelltypeA {
      entry sSigA eA;
      var {
        int var1;
      };
  };
  celltype tCelltypeB {
      entry sSigB eB;
      attr {
        int attr1 = 1;
      };
  };
};
region rR {
  cell nS::tMain Main {
    cMainA = CellA.eA;
    cMainB = CellB.eB;
  };
  cell tCelltypeA CellA {};
  cell tCelltypeA CellA {};
};
```
分かりにくいかもなので下のコンポーネント図を参考にしてください．

![TECSInfo-CD.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207569/64617b94-1b18-b20f-7116-fdcdcaea014d.png)

では今回の目標を

- CellAの変数 var1 の型を取得する

とします．それぞれの実装をみていきます．
その前に準備です．

## 準備
以下のCDLコードを作成してください．

```:TECSInfo.cdl
import( <TECSInfo.cdl> );
import( "target.cdl" ); /* 先の情報を取得するためのCDL */
celltype tTaskMain {
    entry sTaskBody            eBody;
    /* 省略 */

    /* TECSInfo用呼び口 */
    call  nTECSInfo::sTECSInfo cTECSInfo;
    [dynamic,optional]
        call  nTECSInfo::sNamespaceInfo cNSInfo;
    [dynamic,optional]
        call  nTECSInfo::sRegionInfo    cRegionInfo;
    [dynamic,optional]
        call  nTECSInfo::sCellInfo      cCellInfo;
    [dynamic,optional]
        call  nTECSInfo::sSignatureInfo cSignatureInfo;
    [dynamic,optional]
        call  nTECSInfo::sCelltypeInfo  cCelltypeInfo;
    [dynamic,optional]
        call  nTECSInfo::sVarDeclInfo   cVarDeclInfo;
    [dynamic,optional]
        call  nTECSInfo::sTypeInfo      cTypeInfo;
};

cell tTask Task {
  /* 省略 */
};

[in_through()]
region rTEMP{
    cell tTaskMain TaskMain {
        cTECSInfo  = TECSInfo.eTECSInfo;
    };
/******* TECSInfo cell *******/
    cell nTECSInfo::tTECSInfo TECSInfo {
    };
};
```

要はいつものTaskで起動されるセルの実装に、TECSInfoセルへの呼び口と必要な情報を持つInfoセルへの動的呼び口を設けるだけです．  
組上げ記述でTECSInfoへの呼び口を定義してください．動的呼び口は定義する必要はありません．
TECSInfoセルの作成も忘れないでください．target.cdlのインポートもです．



では先の目標を達成します．
TaskMainのセルタイプコードで実装します．

## 実装：CellAの変数 var1 の型を取得する


```c:tTaskMain.c
eBody_main(){
  int i, n;
  Descriptor( nTECSInfo_sCellInfo ) cellDesc;
  Descriptor( nTECSInfo_sCelltypeInfo ) celltypeDesc;
  Descriptor( nTECSInfo_sVarDeclInfo ) varDesc;
  Descriptor( nTECSInfo_sTypeInfo ) typeDesc;

  cTECSInfo_findCell( "CellA", &cellDesc );
  cCellInfo_set_descriptor( cellDesc );
  cCellInfo_getCelltypeInfo( &celltypeDesc );
  cCelltypeInfo_set_descriptor( celltypeDesc );
  n = cCelltypeInfo_getNVar();
  for( i = 0; i < n; i++ ){
    cCelltypeInfo_getVarInfo( i, &varDesc );
    cVarDeclInfo_set_descriptor( varDesc );
    cVarDeclInfo_getName( VAR_name, ATTR_NAME_LEN );
    if( strcmp( VAR_name, "var1")){
      cVarDeclInfo_getTypeInfo( &typeDesc );
      cTypeInfo_set_descriptor( typeDesc );
      cTypeInfo_getName( VAR_name2, ATTR_NAME_LEN );
    }
  }
}
```

まずSTEP１です．find関数を用いてセル CellA の情報を保持しているCellInfoセルへのディスクリプタを取得します．

次にSTEP２です．set_descを用いて動的結合します．
動的結合したらget関数を用いてTECSInfoコンポーネント図の通りにTypeInfoまでたどります．

今回も **ディスクリプタをgetしてsetする．** この流れです．


# 練習
以下よりtecsgenの最新バージョンをインストールしてください．  
⇒ [TECS](https://www.toppers.jp/tecs.html)  

tecsgen/test/TECSInfo　にて今回より詳細な実装が行われいます．参考にして自分でセルタイプコードなどいじってみてください．  
tecsgen/test/TECSInfo/src にtTaskMain.cなどセルタイプコードが入っています．

    % cd tecsgen/test/TECSInfo
    % make

で実行ファイルができるので

    % ./info.exe

で実行してみてください．

「tecsgenコマンドが見つかりません」の場合は tecsgen/にて

    % source set_env.sh

でパスが通るはずです．



<!-- ## 参考 -->