TCL程序库与软件包

来源:互联网 发布:单片机的仿真软件 编辑:程序博客网 时间:2024/05/05 22:53
1、关于程序库和软件包的说明
TCL程序库是包含了一个或多个实现一系列相关过程的TCL脚本文件的目录。TCL提供了一个标准过程库,实现了它的一些默认行为。
使用info library可以返回TCL库目录的完整路径名称,比如:
% info library
D:/Tcl/lib/tcl8.4
另外全局变量tcl_library也存放着相同的值。
% puts $tcl_library
D:/Tcl/lib/tcl8.4

当然也可以自己创建库。库的创建可以把有用的工具过程集合起来,创建可重用的库代码。依靠过程的自动加载,tcl可以在需要它们时高效地加载而不必显示地source调用它们的文件。
实现自动加载只需要以下几步:
1)库的创建,即创建指定目录的脚本文件集。这些文件通常以.tcl结尾,每个文件的内容可以是多个过程的定义,通常把相关联的过程放在一个文件中。
2)建立索引,使用auto_mkindex命令扫描所有名称与指定模式匹配的文件,建立一个索引,指定哪个过程是由哪个文件提供。
   命令原型为:auto_mkindex . *.tcl,创建的文件为tclIndex。
   下面是用命令生成的一个tclIndex的内容
   % more tclIndex
# Tcl autoload index file, version 2.0
# This file is generated by the "auto_mkindex" command
# and sourced to set up indexing information for one or
# more commands.  Typically each line is a command that
# sets an element in the auto_index array, where the
# element name is the name of a command and the value is
# a script that loads the command.

set auto_index(C85-484-basicinfo) [list source [file join $dir C85_484_basicinfo.tcl]]
set auto_index(C85-486-inband) [list source [file join $dir C85_486_inband.tcl]]
set auto_index(C85-487-bandonu) [list source [file join $dir C85_487_bindonu.tcl]]
set auto_index(C85-488-vlan) [list source [file join $dir C85_488_vlan.tcl]]
set auto_index(C85-489-saveconfig) [list source [file join $dir C85_489_saveconfig.tcl]]
set auto_index(exitmachine) [list source [file join $dir exitmachine.tcl]]
set auto_index(loginmachine) [list source [file join $dir loginmachine.tcl]]
set auto_index(readconfig) [list source [file join $dir readconfig.tcl]]
set auto_index(readtxt) [list source [file join $dir readtxt.tcl]]
set auto_index(stcbasicdata) [list source [file join $dir stcbasicdata.tcl]]
set auto_index(VlanTaggedFrames) [list source [file join $dir VlanTaggedFrames.tcl]]
3)设置auto_path的值,将建立的库的路径附加到auto_path中。一般来说,调用自动加载时,它会依次搜索auto_path列表中的各个目录,在它们的tclIndex文件中查找需要的过程。如果同名的过程在多个文件中定义,那么会加载按auto_path的目录顺序最先找到的那个过程。
如果要将路径放在最前面,可以这样做:
% set auto_path [linsert $auto_path 0 D:/TS/C8500]
D:/TS/C8500 D:/Tcl/lib/tcl8.4 D:/Tcl/lib D:/lib d:/tcl/lib/teapot/package/win32-
ix86/lib d:/tcl/lib/teapot/package/tcl/lib

    下面是我用unknown命令跑某个程序的例子,由于相关参数没配,只能跑一点点。
    % unknown C85-484-basicinfo
---D:/TS/C85_484_basicinfo.txt---
couldn't read file "readconfig.tcl": no such file or directory

上面我们展示了库的用法及其好处,然而TCL库也有其缺陷,如无法提供版本管理以及更好地代码分割方式(如果有两个同名的过程,那么auto_path的库路径中首先被找到的那个会被调用。
通过包的创建,可以进行版本管理,并且更好地组织库代码。在测试的时候,可以编写一个主程序,让主程序来调用不同软件包中的命令。这时就要给主程序提供一种机制,告诉它到什么地方找到相应的软件包,如何能从软件包中调入需要的命令等等。有了这些机制,主程序就可以在需要的时候调用对应命令,而不需要将所有软件包都加载。

2、软件包定位
   Tcl解释器有一个全局变量auto_path,它在tclsh 或wish启动的时候被初始化。
   auto_path中包含了Tcl或Tk脚本文件的库目录的列表。可以用set命令来查询,用lappend命令来设定这个变量来定位所需要的软件包路径。
   示例如下
D:\TS>tclsh
% set auto_path
D:/Tcl/lib/tcl8.4 D:/Tcl/lib D:/lib d:/tcl/lib/teapot/package/win32-ix86/lib d:/
tcl/lib/teapot/package/tcl/lib
%
% lappend auto_path D:/TS
D:/Tcl/lib/tcl8.4 D:/Tcl/lib D:/lib d:/tcl/lib/teapot/package/win32-ix86/lib d:/
tcl/lib/teapot/package/tcl/lib D:/Tcl/lib/tcllib1.12 D:/Tcl/lib/tklib0.5 D:/Tcl/
lib/vfs1.4.1/template example/ example/ D:/TS
%

3、 软件包声明
    把脚本存放到库目录下并设置了auto_path,还不一定能正确使用软件包,还必须在脚本文件中用package provide来声明脚本是属于或提供哪个软件包。
    例如在Sprient Testcenter的安装包下面有2个tcl文件:SpirentTestCenter.tcl和stclib.tcl
    在SpirentTestCenter.tcl开头两行声明了本文件中的源码提供名为SpirentTestCenter和stc的包,版本号都为3.50;
    package provide SpirentTestCenter 3.50
    package provide stc 3.50
    在stclib.tcl中声明了本文件中的源码提供名为stclib的包,版本号为2.20
    package provide stclib 2.20

4、 软件包加载
    使用软件包的内容之前,需要用package require命令来将对应的软件包加载到tcl解释器中。
    [语法] package require ?-exact? pkgName ?version?
pkgName为要加载软件包的名字,version为指定版本号(可选),-exact选项进行版本精确匹配。如果不指定version,则加载版本最高的那个软件包。如果指定version,则加载的第一个package版本是系统中可用的最新版本,只要它满足version指定的最低版本号,且主版本号与version相同。如果指定-exact选项,则软件仅接受version版本号的包
    package require SpirentTestCenter
    package require stc 3.50
    package require -exact stclib 2.20
    package require

5、软件包索引
package require命令会遍历在auto_path列出的路径,并取相关软件包,但不是直接从库路径中的所有脚本文件或者库文件中搜索所需软件包,而是通过source库路径下的pkgIndex.tcl脚本完成的。
例如为了能在tcl解析器中调用testcenter包,可以将TestCenter安装路径下的pkgIndex.tcl文件复制到TCL的lib文件的stc3.5(新建的,如果是2.0则名称为stc2.0)目录下。并修改pkgIndex.tcl文件的内容(主要是修改路径)。
原来的内容如下:
package ifneeded SpirentTestCenterConformance 3.50 "[list set env(STC_CONFIGURATION_FILE) ctsbll.ini]; [list source [file join CTS_INSTALL_DIR    SpirentTestCenter.tcl]]; [list package provide SpirentTestCenterConformance 3.50]"
    package ifneeded SpirentTestCenter 3.50 [list source [file join STC_INSTALL_DIR SpirentTestCenter.tcl]]
    package ifneeded stc 3.50 [list source [file join STC_INSTALL_DIR SpirentTestCenter.tcl]]
    package ifneeded stclib 3.50 [list source [file join STC_INSTALL_DIR stclib.tcl]]


修改后的内容如下:
set dir "D:\\Program Files\\Spirent TestCenter Application"

package ifneeded SpirentTestCenter 3.50 [list source [file join $dir SpirentTestCenter.tcl]]
package ifneeded stc 3.50 [list source [file join $dir SpirentTestCenter.tcl]]
package ifneeded stclib 3.50 [list source [file join $dir stclib.tcl]]


6、pkgIndex.tcl的自动生成
pkgIndex.tcl包含一条或多条package ifneeded语句,以及与其相应的用于包的加载的脚本。用户可以自己手动创建,也可以使用pkg_mkIndex过程自动生成。pkg_mkIndex过程用于创建TCL包系统管理包的加载所需要的索引文件。和auto_mkindex一样,它不是内建命令,而是TCL脚本库中的一个过程。
创建索引的命令基本格式如下,它会查找当前目录中所有名称以.tcl结尾的文件,并在该目录下创建文件pkgIndex.tcl:
pkg_mkIndex . *.tcl
下面是我在expect目录下(需要先进到该目录)自动创建的索引文件中的信息,经比对和原来文件是一样的。
# Tcl package index file, version 1.1
# This file is generated by the "pkg_mkIndex" command
# and sourced either when an application starts up or
# by a "package unknown" script.  It invokes the
# "package ifneeded" command to set up package-related
# information so that packages will be loaded automatically
# in response to "package require" commands.  When this
# script is sourced, the variable $dir must contain the
# full path name of this file's directory.

package ifneeded Expect 5.43 [list source [file join $dir expect.tcl]]

package ifneeded:表明可以提供特定版本的特定数据包,通过执行后面脚本可以将数据包加载到解释器中。


0 0
原创粉丝点击