tcl脚本编程知识点总结
软件设置文件
以下是sysnopsys工具的setup文件,一般会把一些常用的设置以及脚本放入其中。
command-line editer设置
如果习惯于vi或者emac编辑器,可以修改命令行的快捷键
icc2中已经不再使用set_cle_options命令。
可以使用sh_line_editing_mode或者
set_ app_options -as_ user_default -name shell. common. line_editing_ mode -value vi
log文件设置
set _pid [pid]
set filename_log_file “filename.log$pid”
压缩无用信息
suppress_message CMD-029
环境变量
可通过环境变量在文件间传递参数信息。
得到环境变量值
getenv name= set env(name)
设置环境变量
setenv name value=set env(name) value
执行系统命令
exec cmd
sh cmd
两者区别, exec不支持通配符,而sh支持
尽量使用tcl命令
以下是一些系统命令与tcl命令的对应关系
通过简单脚本来替代系统命令也是推荐的。
tcl中数据类型
string
关于string’相关的命令总结
list
创建list的三种方式
使用花括号将无法进行变量替换,避免这种情况,建议使用list命令
list操作相关命令总结
command | task |
---|---|
concat | Concatenates lists and returns a new list. |
join | Joins elements of a list into a string. |
lappend | Appends elements to a list. |
lindex | Returns a specific element from a list. |
linsert | Inserts elements into a list. |
list | Returns a list formed from its arguments. |
11ength | Returns the number of elements in a list. |
lminus | Removes one or more named elements from a list and returns a new list. |
lrange | Extracts elements from a list. |
lreplace | Replaces a specified range of elements in a list. |
lsearch | Searches a list for a regular expression. |
lsort | Sorts a list |
split | Splits a string into a list. |
array
创建
1 | set ArrayName(Index) value |
size of array
1 | array size variablename |
indices of Array
1 | array names variablename |
array iteration
1 | set languages(0) Tcl |
Indices of Array
1 | array names variablename |
Iteration of Associative Array
1 | set personA(Name) "Dave" |
array 转为 list
1 | % array set arr { a aaa b bbb } |
array不支持多维
1 | # 下面是非常象二维array的一维array |
1 | #比较常见的一种假二维array |
dict
1 | dict option arg1 ?arg2 ... argN? |
操作字典,具体操作由option决定,option支持以下选项:
create
1 | dict create ?key1 value1 key2 value2 ...keyN valueN? |
返回一个新字典,包含传入的key、value映射。
append
1 | dict append dictName key ?string ...? |
将给定的string追加到字典dictName中键key的值后面。如果key不存在,则相当于新增一个key的映射。如果未指定string,则视为空字符串。多个string会合并为一个字符串。此命令返回更新后的字典。
lapend
1 | dict lappend dictName key ?value ...? |
将给定的value追加到dictName中指定key对应的列表中,可以同时追加多个value,如果key对应的值不是列表,会创建一个列表,并将原有值和追加的值放到列表中。如果key存在,但没有指定value,则不做任何操作。如果dictName中不存在key,则视为空列表,若此时value也未指定则会添加一个键为key值为空列表的元素,若指定了value则会将value作为列表的元素。如果key对应的值不能表示为列表则会报错。
exists
1 | dict exists dictValue key ?key ...? |
判断给定的键key是否存在于给定的字典dictValue中,如果存在返回true,否则返回false。exists只能判断一个键是否存在,当传入多个key时,会将多个key作为嵌套字典的键路径进行查找。
get
1 | dict get dictValue ?key ...? |
获取dictValue中指定key的值,如果想获取嵌套字典中的值,则需要传入多个key作为键的路径。如果没有指定key则返回包含所有键值对的列表。如果字典中不存在指定的键则会报错。
incr
1 | dict incr dictName key ?increment? |
将字典dictName中指定key对应的值增加increment。如果未指定increment,则默认增加1。如果不存在指定的key,则视为0。如果key对应的值不是整数则会报错。
keys
1 | dict keys dictValue ?globPattern? |
返回包含dictValue所有键的列表。如果指定了globPattern,则只返回与之匹配的键的列表。列表中的键按其插入字典的顺序返回。
values
1 | dict values dictValue ?globPattern? |
返回包含字典dictValue的值的列表。如果指定了globPattern,则只返回根据string match规则与其匹配的值的列表。返回值按其插入字典dictValue的顺序排列。
set
1 | dict set dictName key ?key ...? value |
使用value替换字典dictName中key对应的值。如果dictName中不存在key,则值会新增key到value的映射。当存在多个键时表示更新嵌套字典,此时如果第一个key不存在,则会新增一个嵌套字典。如果第一个key存在但是后面的key不存在则会报错missing value to go with key。
update
1 | dict update dictName key varName ?key varName ...? body |
使用映射dictName中key对应的值的变量varName执行body中的脚本。如果dictName没有指定的key,则其对应的变量varname为未设置。当body终止时,对varName所做的更改都会被会写到字典内即使body的结果是一个错误或其他异常,除非字典不可读所有的更新都被静默的丢弃。除非发成异常,否则dict update的结果是body的执行结果。建议只在本地作用域内使用此命令,因为dict update命令中的变量varName在命令完成后,除非显示的执行unset,否则仍然存在。此外,只有当body终止时,才会更改dictName中的内容。
replace
1 | dict replace dictValue ?key value ...? |
返回一个新的字典,包括传入的dictValue以及一些额外的或不同的键值对。如果不传如键值对key、value,则返回的新字典与dictValue相同。键值对必须是成对出现,否则会报错。dictValue中存在的key会用心的value替换,不存在的key会新增到新的字典。
unset
1 | dict unset dictName key ?key ...? |
删除字典dictName中key对应的值。如果dictName中不存在key,则不进行任何操作。当存在多个键时表示删除嵌套字典中的元素,此时的键路径上除了最后一个key可以不存在外,前面的key必须存在,否则会报错key “xxx” not known in dictionary。
remove
1 | dict remove dictValue ?key ...? |
返回一个新的字典,字典包括键为key以外的所有dictValue中的键值对。如果不指定任何键则返回的字典与dictValue相同,如果key不在dictValue中,则不进行任何操作。
size
1 | dict size dictValue |
返回dictValue中键值对的数量,不包括值中嵌套的字典中的键值对。
merge
1 | dict merge ?dictValue ...? |
返回一个新的字典,包含dictValue中的所有元素,多个dictValue具有相同的key的元素的时,最后一次出现的key对应的值会出现在新的字典中。
info
1 | dict info dictValue |
返回字典信息,信息的具体格式取决于字典的实现方式。由于字典是散列表实现的,所以放回结果类似于array statistics命令。
with
1 | dict with dictName ?key ...? body |
与update类似,使用dictName中key对应的值执行body中的脚本。如果key为多个表示嵌套字典的键路径,此时会使用键路径对应的字典执行body中的脚本。字典中key对应的值会映射到与key同名的变量中。与dict update一样,如果dictName不可读或者字典调整导致键路径没有对应的值,则会静默丢弃字典的更新。除非发成异常,否则dict with的结果是body的执行结果。建议只在本地作用域内使用此命令,因为dict with命令中的变量在命令完成后,除非显示的执行unset,否则仍然存在。此外,只有当body终止时,才会更改dictName中的内容。当body终止时如果dictName不是字典则会产生错误。因此当字典中的键与字典变量dictName有冲突时不建议使用此命令。
for
1 | dict for {keyName valueName} dictValue body |
用于遍历字典dictValue,在执行body中脚本时,字典中每个键值对的键和值会分别分配给名为指定的keyName和valueName变量。dict for命令的结果为空字符串。当在body执行过程中遇到break时,会中止循环,结束dict for命令。当遇到continue命令时,会结束本轮循环。字典按键值对的插入顺序进行遍历。
filter
1 | dict filter dictValue filterType arg ?arg ...? |
返回一个新的与指定过滤类型匹配的键值对的字典。filterType支持三种类型:
key
1 | dict filter dictValue key ?globPattern ...? |
返回以stirng match的方式键与模式globPattern匹配的键值对。
value
1 | dict filter dictValue value ?globPattern ...? |
返回以stirng match的方式值与模式globPattern匹配的键值对。
script
1 | dict filter dictValue script {keyName valueName} script |
通过将键赋值给变量keyName,值赋值给变量valueName,根据srcipt脚本的布尔值结果来确定键值对是否匹配。当脚本结果为true时,表示键值对匹配。字典按键值对的插入顺序进行遍历。当在srcipt执行过程中遇到break时,会中止循环,结束dict filter命令。当遇到continue命令时,会结束本轮循环。
map
1 | dict map {keyName valueName} dictValue body |
Tcl8.6新增的命令。此命令通过执行body中的命令,对字典dictValue中的键值进行转换,然后返回一个新的包含转换后的键值对的字典。名为keyName、valueName对应于dictValue中键值对的键与值。每次body执行完后,变量keyName、valueName的值即为新字典的键值。当在body执行过程中遇到break时,会中止循环,结束dict map命令。当遇到continue命令时,会结束本轮循环。另外要注意的是,如果不想对值做改变,需要对其进行显示的set操作,否则值会被设置为body中最后一个命令的返回值。
简单示例
1 | set dic [dict create a 1 b 2 c 3] |
collection
synopsys 工具独有的数据类型,有序,可以理解为工具中objects(cell net blockage …)的集合
相关命令:
command | description |
---|---|
add_to_collection | Add object(s) to a collection. Result is new collection |
append_to_collection | Add object(s) to a collection. Modifies variable |
as_collection | Find a collection or iter_collection by name; result a collection |
collection_to_list | format collection contents as a Tcl list |
compare_collections | Return 0 if two collections contain the same objects |
copy_collection | Make a copy of a collection. Result is new collection |
filter collection | Filter a collection, resulting in new collection |
foreach_in_collection | Iterate over a collection |
index_collection | Extract object(s) from collection. Result is new collec tion |
remove_from collection | Remove object(s) from a collection. Result is new collection |
sizeof_collection | Get the number of objects in collection |
sort_collection | Create a sorted copy of the collection |
另外,所有的get_*都会返回collection。
注
当我们有一个或者多个很大的collection时,后续的一些命令可能会变得非常慢。因为每个命令结束后都要花额外的时间去维护这些collection,确保这些collection继续有效。
比如:
1 | icc2_shell > set C1 [get_cells xxx] |
现在有个collection C1,有2M的cell在里面。接着你做eco,删除design里的一个cell A。这时工具会自动更新collection C1,如果A在C1里,则会把A从C1里删除掉。不然,后面使用C1可能会产生各种错误了。这种维护会消耗不少的时间。
所以,当你不再需要个collection时,及时的把它unset掉。不然,它一直存在,一直需要维护,直到退出。
推荐使用append_to_collection代替add_to_collection,特别是在一个loop里,需要非常多次的循环操作时。append_to_collection会快很多,因为它直接修改collection,而不是像add_to_collection那样先加,再返回到一个新的collection。
文件操作
相关命令
文件名拓展
1 | glob pattern1 pattern2 pattern3 ... |
控制结构
if else
switch
switch的三种匹配模式
• The test_value expression and the pattern match exactly (-exact).
• The pattern uses wildcards (-glob).
• The pattern is a regular expression (-regexp).
举例:
1 | switch -exact $vendor_library { |
while
1 | while {expression} {while_command while_command ... } |
举例:
1 | set p 0 |
for
1 | for {init} {test} {reinit} { |
foreach
1 | foreach variable_name list { |
foreach_in_collection
1 | foreach_in_collection collection_item collection { |
循环控制语句
1 | continue; # 继续下一个循环 |
procedure
提供参数默认值的方法
1 | proc max {{a 0} {b 0}} { |
使用特殊参数args实现可变参数
args,放到proedure的argument的最后的位置。那么命令多有多余的argument都会作为args这个list中的一个item
举例
1 | proc demo {first {second "none"} args} { |
Native的TCL command,在proc里的运行速度是直接运行时的2~5倍!所以对于循环次数很多,计算很多的脚本,尽量放在proc里。
其原因是,ICC2在执行proc时,会把proc预编译成byte code,所以会比直接执行TCL快很多。
举例:
一个简单的循环累加脚本:
1 | icc2_shell> time { |
这是一个简单的循环累加,用proc比不用proc快了5倍。
延伸阅读,本号关于tcl相关技巧的文章:
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以邮件至 admin@graymount.top,也可以关注微信公众号"白山头"直接留言。
文章标题:tcl脚本编程知识点总结
本文作者:白山头
发布时间:2020-04-01, 17:15:29
最后更新:2020-04-01, 17:15:40
原始链接:http://graymount.top/2020/04/01/tcl/版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。