TCL脚本语言-10-名字空间
Tcl语言基础教程

set x 10
set y 100 + $x
这时,y的值还不是我们想要的值110,而是10+100,因为Tcl解释器把10+100看成是一个字符串而不是表达式;y要想得到值
110,还必须用命令置换,使得Tcl会把10+100看成一个表达式并求值。
string tolower string [first] [last]
string replace string first last [newstring]
string equal [-nocase] [-length int] string1 string2
string match [-nocase] pattern string如果pattern匹配string,那么返回1,否则返回0.
Tcl变量根据其结构的复杂程度分为“简单变量”和“数组变量”两类。
(1)简单变量
一个Tcl的简单变量包含两个部分:名字和值,其中名字和值都可以是任意字符串。不过为了更好的使用变量置换功能,变量名
最好按C\C++语言中标识符的命名规则命名。这是因为Tcl解释器在分析一个变量置换时,只把从$符号往后直到第一个不是字母、数
个新字符串,并返回。例如:
set msg [format "%s is %d years old" $name $age]
【scab】
语法:scan string formatsting varName varName ...
scan命令可以认为是format命令的逆,其功能类似于ANSI C中的sscanf函数。它按formatsting提供的格式分析string字
tcl define_proc用法 -回复

tcl define_proc用法-回复Tcl是一种解释性的脚本语言,常用于自动化测试、网络编程和图形用户界面(GUI)开发。
在Tcl中,使用define_proc命令可以定义过程(procedure),也就是函数。
本文将逐步介绍define_proc的用法,并为读者提供一些实际的代码示例。
define_proc是Tcl的一个内置命令,它有两个主要的语法形式。
第一种形式如下:define_proc name args body这种形式用于定义一个过程,其中name是过程的名称,args是参数列表,body是过程的主体逻辑。
从语法上看,args可以是一个参数名称的列表,也可以是一个格式为{argName default}的列表,其中argName 是参数名称,default是默认值。
例如,下面的代码定义了一个名为`sum`的过程,用于计算两个数的和:define_proc sum {x y} {expr {x + y}}在这个例子中,过程名为sum,它有两个参数x和y。
过程主体使用`expr`命令计算x和y的和,并返回结果。
第二种形式的define_proc命令允许在一个命名空间内定义多个过程。
它的语法如下:define_proc namespace name args body其中,namespace是命名空间的名称,name是过程名称,args和body 的含义与前一种形式相同。
下面的示例展示了第二种形式的用法:namespace eval math {define_proc add {x y} {expr {x + y}}define_proc subtract {x y} {expr {x - y}}}在这个例子中,我们创建了一个名为math的命名空间,并在该命名空间内定义了两个过程:add和subtract。
这些过程可以使用`::math::add`和`::math::subtract`的形式进行调用。
TCL编程高级教程讲解

为解决上述问题和进一步提高TCL 的扩展能力,较新版 本的TCL提供了更好的程序包机制。
脚本库和程序包
• 程序包
Q:什么是程序包? A:由于脚本库的局限性,TCL提供了更好的
TCL已经有一个这样的集合,就是我们指的 全局命名空间。全局命名空间将所有的全局变量 和命令放在一起。 命名空间也叫做名称空间、名 称域、命名域 等。
命名空间
• 命名空间创建:
用 namespace eval 命令创建一个新的命名空间
• 命名空间查询
如果要在命名空间XXX之外查询命名空间内部变 量的值xxx,可以用如下语句: set :: XXX::xxx
命名空间
• 输入命令和输出命令
命名空间常常用来描述库,需要频繁使用命名空间前缀, 用输入命令和输出命令可以省略命令前面的命名空间前缀。
输入命令: namespace import 输出命令: namespace export
命名空间
• 输入命令
➢ namespace import 命令只输入命名空间中用namespace export命令输 出的命令
package 机制来实现对TCL的共用和扩展,也就 是程序包 。
脚本库和程序包
• 创建TCL程序包:
把你想包含在某个包中的所有自定义过程 放到一个TCL脚本文件中,然后在文件的开头 使用 package provide 命令指明这个包的名字和 版本即可。
脚本库和程序包
– 如果一个函数在几个脚本库中都有定义的话,TCL会按照搜索顺序自动加 载在 auto_path 中位置靠前的那个库。因此,如果加载的脚本库要先被搜 索的话,可以使用 linsert 命令将其插入到 auto_path 中靠前的位置中, 例如: % set auto_path [linsert $auto_path 0 c:/tcllib/lib1]
vivado tcl语句

vivado tcl语句1. 什么是Vivado TCL语句?Vivado是一种由赛灵思公司开发的综合工具套件,用于设计和实现复杂的数字电路。
TCL(Tool Command Language)是一种脚本语言,由约翰·奥斯汀(John Ousterhout)于1988年开发,用于自动化软件任务。
在Vivado中,你可以使用TCL语句来定义和执行各种操作,例如创建设计工程,生成约束文件,运行综合和实现流程等。
2. 使用TCL语句的优势有哪些?使用TCL语句可以带来许多优势。
首先,TCL是一种脚本语言,它允许你编写一系列命令来执行复杂的任务,无需逐个手动输入命令。
这大大提高了工作效率,减少了错误的可能性。
其次,TCL语句是可编程的,这意味着你可以使用条件语句、循环和函数等控制结构来编写更加灵活和智能的代码。
你可以根据特定需求自定义脚本,以便自动执行一系列任务,而不是手动操作。
此外,TCL语句还可以与其他脚本语言和工具进行交互,例如Python和Shell脚本。
这意味着你可以在TCL脚本中调用其他脚本或工具的功能,以实现更高级的自动化和集成。
3. 如何使用Vivado TCL语句?使用Vivado TCL语句有一些基本步骤。
首先,你需要打开Vivado软件,并创建或打开一个设计工程。
在Vivado界面中,你可以打开"TCL Console"窗口,它允许你在其中输入和执行TCL命令。
接下来,你可以使用TCL语句来执行各种操作,例如创建设计工程、添加源文件、设置约束、运行综合和实现等。
可以使用"source"命令执行一个TCL脚本文件,或者逐个输入命令。
通过在命令前加上"puts"命令,你还可以打印输出结果,以便进行调试和验证。
此外,Vivado还提供了TCL命令的完整文档和参考手册,你可以在其中查找各种命令和用法的详细信息。
这些文档可以帮助你学习和理解TCL 语句的功能和用法。
TCL语言.

TCL语言Tcl(最早称为“工具命令语言”"Tool Command Language", 但是目前已经不是这个含义,不过我们仍然称呼它为TCL)是一种脚本语言。
由John Ousterhout创建。
TCL很好学,功能很强大。
TCL经常被用于快速原型开发,脚本编程,GUI和测试等方面。
TCL念作“踢叩” "tickle". Tcl的特性包括:* 任何东西都是一条命令,包括语法结构(for, if等)。
* 任何事物都可以重新定义和重载。
* 所有的数据类型都可以看作字符串。
* 语法规则相当简单* 提供事件驱动给Socket和文件。
基于时间或者用户定义的事件也可以。
* 动态的域定义。
* 很容易用C, C++,或者Java扩展。
* 解释语言,代码能够动态的改变。
* 完全的Unicode支持。
* 平台无关。
Win32, UNIX, Mac上都可以跑。
* 和Windows的GUI紧密集成。
Tk* 代码紧凑,易于维护。
TCL本身不提供面向对象的支持。
但是语言本身很容易扩展到支持面向对象。
许多C语言扩展都提供面向对象能力,包括XOTcl, Incr Tcl 等。
另外SNIT扩展本身就是用TCL写的。
使用最广泛的TCL扩展是TK。
TK提供了各种OS平台下的图形用户界面GUI。
连强大的Python语言都不单独提供自己的GUI,而是提供接口适配到TK上。
另一个流行的扩展包是Expect. Expect提供了通过终端自动执行命令的能力,例如(pass wd, ftp, telnet等命令驱动的外壳).下面是TCL程序的例子:#!/bin/sh# next line restarts using tclsh in path \exec tclsh ${1+"$@"}# echo server that can handle multiple# simultaneous connections.proc newConnection { sock addr port } {# client connections will be handled in# line-buffered, non-blocking modefconfigure $sock -blocking no -buffering line# call handleData when socket is readablefileevent $sock readable [ list handleData $sock ]}proc handleData {puts $sock [ gets $sock ]if { [ eof $sock ] } {close $sock}}# handle all connections to port given# as argument when server was invoked# by calling newConnectionset port [ lindex $argv 0 ]socket -server newConnection $port# enter the event loop by waiting# on a dummy variable that is otherwise# unused.vwait forever另外一个TK的例子(来自 A simple A/D clock) 它使用了定时器时间,3行就显示了一个时钟。
TCL脚本语言-9-过程和变量

过程和变量前面的章节中我们对过程和变量已经有了较多的接触了,还定义了一些自己的过程,并且对列表和数组等有了深入的了解。
本章节中我们将系统的深入了解TCL中的过程和变量相关的知识。
首先从过程定义开始。
定义过程TCL中,“过程”和“函数”没有差别,这一点和C语言类似。
在这本书当中,TCL的“过程”和“函数”是两个完全等价,可以互相替换的概念和术语。
TCL定义任何过程的语法如下:proc name arglist bodyproc是标准的TCL核心命令之一,用来定义一个过程。
它带有三个参数:过程名字、过程的参数列表以及过程体。
1.过程名字可以是任意的字符串。
当然了,本着易读和可维护性的原则,我们建议按照C语言语法惯例来命名。
如果你喜欢中文,也可以给你定义的过程一个中文名字。
如果定义的过程已经存在了,那么新定义的过程会替换掉原来的定义,这一点和C不同。
在C中,函数是不能够被重复定义的。
2.参数列表用来声明本过程的调用参数形式,它应该是一个TCL列表。
列表的每一个元素就是一个过程的形式参数。
当然列表可以为空,表示本过程不需要参数。
3.过程体是一块TCL脚本,当本过程被调用的时候,就执行该脚本。
4.过程返回值可以直接在body中调用return来返回,如果没有执行return就返回,那么body中最后被执行的那条命令的返回值就是过程的返回值。
TCL中的过程支持递归,包括直接递归和间接递归。
下面我们定义一个阶乘函数:proc Factorial {n} {if {$n==1} {return 1}return [expr {$n * [Factorial [expr $n-1]] }] ;#递归调用}puts [Factorial 4]其中Factorial是过程名;{n}是参数列表,只有一个元素,表示过程Factorial只有一个参数;过程内部通过递归调用来计算参数n的阶乘。
全局、局部TCL中的变量也有作用范围之说。
tcl脚本教程

puts "x is $x"
} 循环里可以有break ,continue。实际上,for 的语法形式很简单,你完全 可以用C的语法来考虑它。 表达式也可以是复合的:
% for { set x 0; set y 10 } { $x <3 && $y < 13 } {incr x ;incr y } { puts "$x -- $y"
infoexistsvarnamesetvarnamesomevarjoin和splitsplitsomestring把一个字符串解成listsplitsomestring以为分隔符把一个字符串解成listjoinsomelist把一个list合成一个字符串joinsomelist以为分隔符把一个list合成一个字符串语法要点续list及相关操作listarg1argn把各个参数合成一个listllengthsomelist返回list的长度元素个数lindexsomelist返回list的第一个元素lindexsomelistend返回list的最后一个元素end是list操作的保留字lindexsomelistexprllengthsomelist什么意思
gets channelId ?varName? gets 从一个channel取一个行到指定变量;同时它本身也返回这个行, 所以gets还有第二种用法:
gets stdin Name
变量
• 变量是程序的基础。 • 变量:变量名、变量值 • 变量名:任何字符串都可作为变量名,如下所示,皆可作变量名
% puts $Name
% set x puts
tcl脚本语言中文详解

T C L用法祥述一TCL语法1 脚本、命令和单词符号一个TCL脚本可以包含一个或多个命令。
命令之间必须用换行符或分号隔开,下面的两个脚本都是合法的:set a 1set b 2或set a 1;set b 2TCL的每一个命令包含一个或几个单词,第一个单词代表命令名,另外的单词则是这个命令的参数,单词之间必须用空格或TAB键隔开。
TCL解释器对一个命令的求值过程分为两部分:分析和执行。
在分析阶段,TCL 解释器运用规则把命令分成一个个独立的单词,同时进行必要的置换(substitution);在执行阶段,TCL 解释器会把第一个单词当作命令名,并查看这个命令是否有定义,如果有定义就激活这个命令对应的C/C++过程,并把所有的单词作为参数传递给该命令过程,让命令过程进行处理。
2 置换(substitution)注:在下面的所有章节的例子中,'%'为TCL的命令提示符,输入命令回车后,TCL会在接着的一行输出命令执行结果。
'//'后面是我自己加上的说明,不是例子的一部分。
TCL解释器在分析命令时,把所有的命令参数都当作字符串看待,例如:%set x 10 //定义变量x,并把x的值赋为1010%set y x+100 //y的值是x+100,而不是我们期望的110x+100上例的第二个命令中,x被看作字符串x+100的一部分,如果我们想使用x的值'10' ,就必须告诉TCL解释器:我们在这里期望的是变量x的值,而非字符'x'。
怎么告诉TCL解释器呢,这就要用到TCL语言中提供的置换功能。
TCL提供三种形式的置换:变量置换、命令置换和反斜杠置换。
每种置换都会导致一个或多个单词本身被其他的值所代替。
置换可以发生在包括命令名在内的每一个单词中,而且置换可以嵌套。
1) 变量置换(variable subtitution)变量置换由一个$符号标记,变量置换会导致变量的值插入一个单词中。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
TCL、Python 和软件测试自动化
::set myage 23
119
不过这样总有画蛇添足的嫌疑。 例如前面代码中,为了在全局名字空间中调用 Print 过程,我们写出如下的代码: ::Counter::Operator::Print 如果我们直接写 Print 来调用,TCL 解释器是无法找到这个过程的。同样,如果需要在 全局名字空间中引用 Counter 中的变量 m_counter,也需要这样写: puts $::Counter::m_counter 名字空间中变量名和过程名的解析,有一定的规则。如果它们有名字空间来修饰,那么 就按照指定的名字空间来定位寻找,否则,先在当前名字空间中寻找,如果没有找到,就到 全局名字空间中寻找,如果还没有找到,那么就报告错误。下面是一个嗲行的例子: set m “Global ::m” ;#全局的变量 m
作者:雷雨后 Email: leiyuhou010@
TCL、Python 和软件测试自动化
set m_count 0 } ; }{ #! ! !这里应该有分号,否则会出错! ! !
116
#这里定义过程 Increase,增加计数器,默认参数为 1 proc Increase { {m 1} } { variable m_count incr m_count $m } } #名字空间已经 Counter 存在,继续在 Counter 中执行如下代码 namespace eval Counter { #定义过程 GetCounter,返回得到计数器的实际值 proc GetCounter {} { variable m_count return $m_count } #定义子名字空间 Operator,里面定义了一个函数 Print namespace eval Operator { proc Print {} { variable ::Counter::m_count puts "The counter is $m_count" ;#打印计数器当前值 } } } #下面是测试代码,增加计数器技术,然后打印计数器的值 Counter::Reset for {set i 0} {$i<10} {incr i} { Counter::Increase } puts [Counter::GetCounter] ::Counter::Operator::Print ;#直接打印计数器的值 ;#调用内部定义过程来打印
第一个 namespace eval 命令带有三个参数:名字为 Counter,剩下的两个参数是两块代 码, 用来在 Counter 之中执行, 分别定义了两个过程 Reset 和 Increase。 因为该 namesapce eval
作者:雷雨后 Email: leiyuhou010@
variable 命令
variable 一般用在 namespace eval 的语句块中,定义该名字空间内部的全局变量。这里 要区分全局和局部的概念:局部(local)表示在过程内部生成的变量,过程外部的变量都是 全局(global)的变量。但是在名字空间出现后,也存在一个全局的概念,这就是全局名字 空间,比如 TCL 内建的命令 set 等命令都属于全局名字空间。这里不要搞混淆了。 每一个名字空间,都可以有自己的全局变量,variable 就可以用来定义以及引用这些全 局变量。该命令的语法如下: variable ?name value…? name ?value? 命令 variable 执行的时候,如果 name 指定的变量还不存在,那么就创建这个变量。在 这种情况下,如果指定了 value,那么就给变量赋值为 value,否则变量处于未定义状态;如 果变量已经存在,那么当 value 参数有的时候,就直接给该变量赋值,否则变量值保持不变。 如果 variable 是在某一个 TCL 过程中被调用, 那么就会创建一个同名的局部变量, 和对 应的全局变量关联起来。在这种情况下,variable 命令和 global 非常的类似,它们的差别在 于:global 关联的是全局名字空间(::)中的全局变量,而 varialbe 关联的是命令所在名字空 间的全局变量。 例如上面的 Counter 中,就有如下两种语句: 1. variable m_counter 0 2. variable m_counter 第一个我们是在 Counter 中任何过程外面调用的,并且给出了初始值,那么该语句就在 Counter 中创建了一个全局变量 m_counter 并且初始值未 0;第二个则是在 Counter 内部定义 的过程中调用的,没有给出 value 参数,那么它的功能就是在过程内部创建一个同名的局部 变量并且和全局变量关联起来,然后我们就可以象使用局部变量一样使用全局变量。 variable 命令的 name 参数可以带有名字空间来修饰,例如上面代码中的 Print 过程,这 个过程是在::Counter::Operator 中定义的, 其内部就使用了 variable ::Counter::m_counter 语句, 用来声明一个局部变量 m_counter,和其他名字空间中的变量关联起来。我们一般不推荐这
proc print {args} { puts "I am ::print . Value is : $args" } namespace eval a { set m “ m in ::a”
;#全局的过程 print
;创建::a::m 变量,也是全局,但是属于 a
proc print {args} { puts "I am a::print .Value is : $args" } namespace eval b { ;#定义名字空间 b print $m ;#直接打印变量 m
TCL、Python 和软件测试自动化
117
执行的时候 Counter 还不存在, 所以就创建了该名字空间。 紧接着后面的一个 namespace eval 命令,用来在名字空间 Counter 中创建过程 GetCounter。再往下就是测试代码,用来检查一 下这个计数器名字空间是否正常工作。最后的打印结果是“10” 细致的读者可能会发现,过程 Reset 定义结束后,后面跟了一个分号,有什么用处?分 号的用处在于,如果后面有多个语句块,那么在将它们连接成一个字符串之后,不会因为没 有命令分隔而出现错误。一般情况下我们不赞成象上面的代码那样后面跟多个 arg 参数,而 是把所有的代码全部放到一对花括号之中。 名字空间是可以嵌套的,一个名字空间可以包含多个孩子名字空间,例如上面的代码就 定义了嵌套的名字空间 Operator,并且在其中定义了过程 Print。 上面的代码中还出现了一个我们没有见过的命令 variable,下面我们详细讨论:
TCL、Python 和软件测试自动化
115
名字空间
TCL 为什么要引入名字空间的概念呢?这是因为随着程序规模的增加, 参与代码编写的 人员数量的增加,就有可能在全局变量名字,过程名字的命名上产生重复和冲突。对于 C 这样的语言还好,编译器会报告重复定义的编译错误或者链接错误;对于 TCL 而言,命令 是可以重复定义的,这样一旦程序运行产生错误,查找起来将会非常的困难。 可能有人会说了,脚本语言开发程序,基本上都是我一个人搞定,怎么可能会有很多人 参与呢?不要忘了,TCL 是与网络紧密结合的、开放源代码的语言,在网络上存在无数的人 来为 TCL 开发各种各样的程序库和扩展包,他们互相之间既有可能根本不认识,所以命令 同名是在太有可能发生了,比如象 Create、Initial 和 Close 等等这些都要被用滥了的名字。 为了解决这些问题,名字空间应运而生。名字空间 namespace,顾名思义,可以理解成 有名字的空间,它包含了那些属于该空间的变量名和过程名。不同名字空间里面,即使包含 同名的命令,TCL 解释器也能够区分它们,看待成不同的命令。 TCL 中所有和名字空间相关的命令只有一个,就是 namespace,命令的第一个参数决定 了完成什么功能,下面我们逐一介绍。
;#这是过程 a::print
proc print {args} { puts "I am a::b::print . Value is : $args" } variable m “m in ::a::b” ;#定义变量::a::b::m print $m ;#再次打印变量 m } } 上面的代码执行结果如下:
创建名字空间
TCL 中没有 namespace create xxx 这样的命令来创建名字空间, 使用的是另外一个命令: namespce eval,其语法如下: namespace eval namespace arg ?arg? 其中第二个参数 namespace 是名字空间的名字;后面的参数是需要在这个名字空间中执 行的代码,如果 arg 参数有多个,那么命令会先把它们用空格连接起来组装成一个字符串。 该命令在名字空间 namespace 中执行后面的代码,如果参数 namespace 指定的名字空间还不 存在,那么就会先创建这个名字空间。 下面是一个简单的名字空间,实现一个计数器以及相关的操作: #―――――――――――――――――――――――――――― #创建名字空间 Counter namespace eval Counter { namespace export * variable m_count 0 ;#定义名字空间内部变量 #定义过程 Reset,将计数器复位 proc Reset {} { variable m_count
作者:雷雨后 Email: leiyuhou010@
TCL、Python 和软件会问,如果我使用的变量是数组,应该如何给其赋初始值?可不可以象下面这 样写? variable m_days {1 Mon 2 Tru 3 Wed} 回答是可以这样下,但是结果不是我们要的,m_days 是一个列表!正确的方法是:使 用 variable 来声明变量, 省略掉后面的 value 参数, 然后调用 arrar set 等方法来为数组变量赋 值?例如: variable m_days array set m_days {1 Mon 2 Tru 3 Wed } 还有读者会问:过程中调用 variable 关联变量的时候,这个变量必须存在吗?必须是用 variable 声明并且创建的吗?两个问题的答案都是否定的。例如下面的代码: proc t {} { variable m 100 ;#定义全局变量,初值为 100 puts "In procedure t : $m" } t ;#调用该过程 puts "Global variable m = $m" 上面代码执行如下: In procedure t : 100 Global variable m = 100 variable 命令使用很灵活,常见用法,总结一下: 1. 在名字空间中创建全局变量,并且为其赋值! 2. 在名字空间中的过程中调用 variable,可以象局部变量一样引用该变量! 总之,variable 使用非常灵活,我们要求把握的是该命令的本质!