Tclのトークン分割機能をC/C++から直接呼び出してみるテスト

Tcl を C/C++ で活用する・・・というと、Tcl_Eval で Tcl の各種コマンドを呼び出す方法をまず思いつきますが、
Tcl_Eval を使う以外にも、文字列処理や、ファイル処理、参照カウンタ式のオブジェクト管理等、
色々便利そうな API が結構揃っていて、純粋に C/C++ 用のライブラリとしても使えそうな感じです。

さらに欲張って、Tcl がスクリプトを内部形式に変換する際に使用している
トークン分割処理を使えないか調べてみたのでその結果をちょっと書いてみます。

Tcl のトークン分割処理は、 Tcl_ParseCommand という C API から呼び出せるようです。
Tcl の文法に沿った文字列を試しに入れて、結果を表示してみます。

<実験コード>
void tokenize_test(){
  const char *some_tcl_script[] = {
    "hello {ABC DEF GHI} [hoge AA BB $CC] $def OKOK # comment start",
    "hello {ABC DEF \nGHI} [hoge AA BB $CC] $def OKOK #comment start"
  };
  for (int j = 0; j < 2; ++j){
    std::printf("[%d]\n", j+1);
    Tcl_Parse parse;
    ::Tcl_ParseCommand(0, some_tcl_script[j], -1, 0, &parse);
    std::printf("command:");
    std::fwrite(parse.commandStart, parse.commandSize, 1, stdout);
    std::printf("\n");
    for (int i = 0; i < parse.numTokens; ++i){
      Tcl_Token &tok = parse.tokenPtr[i];
      std::printf("token[%d] (%d):", i + 1, tok.type);
      std::fwrite(tok.start, tok.size, 1, stdout);
      std::printf("\n");
    }
    std::printf("comment:%s\n", parse.commentStart);
    ::Tcl_FreeParse(&parse);
  }
}

<結果>
[1]
command:hello {ABC DEF GHI} [hoge AA BB $CC] $def OKOK # comment start
token[1] (2):hello
token[2] (4):hello
token[3] (2):{ABC DEF GHI}
token[4] (4):ABC DEF GHI
token[5] (1):[hoge AA BB $CC]
token[6] (16):[hoge AA BB $CC]
token[7] (1):$def
token[8] (32):$def
token[9] (4):def
token[10] (2):OKOK
token[11] (4):OKOK
token[12] (2):#
token[13] (4):#
token[14] (2):comment
token[15] (4):comment
token[16] (2):start
token[17] (4):start
comment:(null)
[2]
command:hello {ABC DEF
GHI} [hoge AA BB $CC] $def OKOK #comment start
token[1] (2):hello
token[2] (4):hello
token[3] (2):{ABC DEF
GHI}
token[4] (4):ABC DEF
GHI
token[5] (1):[hoge AA BB $CC]
token[6] (16):[hoge AA BB $CC]
token[7] (1):$def
token[8] (32):$def
token[9] (4):def
token[10] (2):OKOK
token[11] (4):OKOK
token[12] (2):#comment
token[13] (4):#comment
token[14] (2):start
token[15] (4):start
comment:(null)
()内の数字は トークンの type を表していて、tcl.h に次のように定義されています。
#define TCL_TOKEN_WORD 1
#define TCL_TOKEN_SIMPLE_WORD 2
#define TCL_TOKEN_TEXT 4
#define TCL_TOKEN_BS 8
#define TCL_TOKEN_COMMAND 16
#define TCL_TOKEN_VARIABLE 32
#define TCL_TOKEN_SUB_EXPR 64
#define TCL_TOKEN_OPERATOR 128
#define TCL_TOKEN_EXPAND_WORD 256

スペースやタブをトークン区切りにして、各トークンを純粋に取り出したい、といった場合は、
TCL_TOKEN_WORD、または TCL_TOKEN_SIMPLE_WORD のトークンだけを処理して、それ以外の
トークンは無視すれば使えそうな感じでしょうか。

parse.commentStart がコメント開始箇所を見つけ出せてない理由が謎ですが・・・