TCL proc 子函數調用

 

TCL裏的過程,等效於C語言裏的函數(function)
一個標準的proc一般具有如下的特點

proc proc_name {argument} {
    ......
    return return_value
}
1
2
3
4
在使用的時候,直接輸入過程名即可執行。
先來看一個下面的例子,

這是一個標準的過程,get_area就是這個過程名,直接執行它就可以了,這個過程名的作用就是得到整個設計裏邊的cell 的面積,源碼示例如下

proc get_area {} {
  set area 0
  foreach_in_collection c [get_flat_cell *] {
    set area [expr [get_attribute $c area] + $area]
  }
  puts "cell area is: $area"
  return $area
}
define_proc_attributes get_area  \
  -info "get_area"
1
2
3
4
5
6
7
8
9
10
可以看到,除過計算面積意外,這裏還有一個return和define_proc_attributes ,通過下面的操作來感受一下它們的意義

這個操作,就是使用 [] 來獲取命令的返回值,這個是和shell裏邊的 `` 功能是一樣的。

再來看看以下define_proc_attributes,這個命令可以定義你的proc的釋義等。使用help proc_name來喚出來proc的解釋

這個get_area僅僅就是計算所有cell面積的一個過程,如果只想計算某種特殊名稱的cell 面積呢?沒問題,使用argument輕鬆完成。
先看一下命令使用上的變化


可以看到,這裏使用了pattern 這個參數,但是帶來的便利性是巨大的,用戶可以自行篩選結果,而不用去修改下邊的proc本身。代碼示例如下:

proc get_area {args} {
  parse_proc_arguments -args $args opt
  set pattern ""
  if {[info exists opt(-pattern) ]} {
    set pattern $opt(-pattern)
  } 
  set area 0
  foreach_in_collection c [get_flat_cell *${pattern}*] {
    set area [expr [get_attribute $c area] + $area]
  }
  puts "Pattarn \"${pattern}\" cell area is: $area"
  return $area
}
define_proc_attributes get_area  \
  -info "get_area for specified pattern" \
  -define_args {
    {-pattern   "instance name pattern"  AString string required } \
  }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
可以看到,在proc get_area 裏邊,加入瞭如下的擴充

  parse_proc_arguments -args $args opt
1
這個即使參數解析的命令,通過這個命令,可以很方便的將外界的參數,轉化爲proc內部的數組(array)opt 用戶通過調用這個數組,來實現參數的傳遞

此外,在定義過程屬性的命令裏邊,也多了一些信息

  -define_args {
    {-pattern   "instance name pattern"  AString string required } \
  }
1
2
3
這個命令就是在定義argument的具體需求,具體格式釋義如下面表格

arg_name option_help value_help data_type attributes

縮略語    描述    示例
arg_name    選項的名稱    -pattern
option_help    選項的描述    “instance name pattern”
value_help    選項值的描述    AString
string    選項值的類別    string
attribute    選項的屬性    required
這裏的選項值的類別和選項的屬性 都是需要符合工具的定義,必須要按照工具定義的來,類別一般分爲:string/int/ boolean等,屬性一般有:required/required等等。如果用戶的輸入和定義的不匹配,工具會報錯。
更進一步,再來一個使用ref_name進行二次過濾,運行結果如下

proc的代碼如下

proc get_area {args} {
  parse_proc_arguments -args $args opt
  set pattern ""
  if {[info exists opt(-pattern) ]} {
    set pattern $opt(-pattern)
  } 
  set area 0
  if {[info exists opt(-ref) ]} {
    foreach_in_collection c [get_flat_cell *${pattern}* -f "ref_name=~*$opt(-ref)*"] {
      set area [expr [get_attribute $c area] + $area]
    }
    puts "Pattarn \"${pattern}\" with ref \"$opt(-ref)\" cell area is: $area"
  } else {
    foreach_in_collection c [get_flat_cell *${pattern}*] {
      set area [expr [get_attribute $c area] + $area]
    }
    puts "Pattarn \"${pattern}\" cell area is: $area"
  }
  return $area
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
細心的同學們可能已經注意到了,這裏使用了-ref這個新的argument,但是依然支持不帶-ref的命令行操作
這是因爲下面的代碼的操作:

define_proc_attributes get_area  \
  -info "get_area for specified pattern" \
  -define_args {
    {-pattern   "instance name pattern"  AString string required } \
    {-ref       "ref name pattern"       AString string optional } \
  }
1
2
3
4
5
6
這裏的**-ref …optional**就是這個作用,可以使用,也可以不使用,非必須的argument。
在文章的最開始提到proc還有一個不留“殘渣”的作用,說的是proc裏邊的變量都是局部變量,每次執行的時候纔會用到,但是不會影響當前的會話,利用這個特點可以放心的執行,又不用擔心環境被破壞。用戶只需要使用當前proc的返回值就可以了。

foreach t { place CTS route_opt } { 
  puts "area for $t is [get_area -pattern $t]"

1
2
3
執行結果如下,可以看到,每次的返回值都回基於輸入而產生不同,相互之間不影響

從上邊的例子中,同學們已經能感知到proc的強大威力了吧!在真正的工作中,可以使用這些特點,構建自己的強大proc,從而可以更爲方便的運行命令。
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章