Tcl エラーの処理 - 2023.2 日本語

Vivado Design Suite ユーザー ガイド: Tcl スクリプト機能の使用 (UG894)

Document ID
UG894
Release Date
2023-11-17
Version
2023.2 日本語

一部のビルトイン Tcl コマンド (およびユーザー プロシージャ) は、エラーがプログラムにより検出されない場合、Tcl エラー (TCL_ERROR) を生成してスクリプトを停止することがあります。たとえば file コマンドは、ファイルを開くことができないと、TCL_ERROR を生成します。

Tcl には、プログラムを正しく実行し TCL_ERROR 状態を検出できるようにビルトインの catch コマンドがあります。このコマンドは、エラーが検出された場合は 1 を返し、検出されなかった場合は 0 を返します。catch コマンドは、1 つのコマンドまたはコマンドのグループに対して使用できます。

catch コマンドの基本的な構文は、次のとおりです。

catch script [varname]

ここで、script は 1 つの Tcl コマンドまたは Tcl コマンドのグループ、varname は TCL_ERROR を説明するメッセージを保存する変数の名前です。

注記: 引数 varname は省略できます。

通常、catch コマンドは次のように使用されます。

If {[catch script errorstring]} {
  # A low-level TCL_ERROR happened
  puts " Error - $errorstring "
} else {
  # No TCL_ERROR was generated
  puts " The code completed successfully "
}

例 1 は、catch コマンドを使用してファイルを開くことができない場合を考慮することにより、より適切なスクリプトとなります。

例 3: ファイルを読み出し/書き込みで開いたときのチェック (正しいスクリプト例)。

if {[file exists $filename]} {
  if {[catch { set FH [open $filename r] } errorstring]} {
    puts " File $filename could not be opened : $errorstring"
  } else {
    # The file is opened, do something
    # …
    close $FH
  }
} else {
  puts " File $filename does not exist"
}

Tcl エラーは、error コマンドを使用しても生成できます。たとえば、catch コマンドで検出した TCL_ERROR を上位に伝搬する場合に使用できます。error コマンドは、スクリプトでコーナー ケースがサポートされていない場合や、コードで予期されない状況が発生した場合に、TCL_ERROR を生成するために使用できます。

たとえば次のプロシージャは、ファイルの内容を返すか、ファイルを開くことができない場合は TCL_ERROR を生成します。

proc get_file_content { filename } {
  if {[catch {
    set FH [open $filename r]
    set content [read $FH]
    close $FH
  } errorstring]} {
    error " File $filename could not be opened : $errorstring "
  }
  return $content
} 

プロシージャ get_file_contentcatch コマンドで呼び出すと、発生する可能性のあるエラーを検出できます。

if {[catch { set content [get_file_content ./myreport.rpt] } errorstring]} {
  puts " The following error was generated: $errorstring "
} else {
  puts " The content of the file is: $content "
}

例 2 も、例 4 に示すように、間違った条件が発生した場合に TCL_ERROR を生成するよう改善できます。

例 4: Vivado オブジェクトが有効であるかをチェックし、有効でない場合は TCL_ERROR を生成 (改善後)。

proc get_pin_dir { pinName } {
  if {$pinName == {}} {
    error " Error - no pin name provided"
  }
  set pin [get_pins $pinName]
  if {$pin == {}} {
    error " Error - pin $pinName does not exist"
  }
  set direction [get_property DIRECTION $pin]
  return $direction
}