一部のビルトイン 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_content
を catch
コマンドで呼び出すと、発生する可能性のあるエラーを検出できます。
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
}