方法列出Tcl文件中的所有过程

时间:2013-10-18 14:03:04

标签: tcl expect

有没有办法在myFile.tcl中使用另一个tcl文件或同一文件列出所有程序(proc)。

4 个答案:

答案 0 :(得分:1)

最便宜的方法是打开文件并使用regexp来挑选名称。它并不完全准确,但它做得相当不错。

set f [open "sourcefile.tcl"]
set data [read $f]
close $f

foreach {dummy procName} [regexp -all -inline -line {^[\s:]*proc (\S+)} $data] {
    puts "Found procedure $procName"
}

它是否涉及所有案件?不。它是否涉及有用的子集?是。子集足够大吗?很可能。

答案 1 :(得分:0)

是的,虽然不那么容易。基本思想是在修改后的slave interp中获取文件,该interp只执行一些命令:

proc proc_handler {name arguments body} {
    puts $name
}
set i [interp create -safe]
interp eval $i {proc unknown args {}}
interp alias $i proc {} proc_handler
interp invokehidden source yourfile.tcl

如果文件需要其他包(package require不起作用),这种方法将失败,依赖于一些通常的auto_load'ed命令的结果等。

它也不考虑名称空间。 (namespace eval ::foo {proc bar a {}}创建名为::foo::bar

的过程

对于更复杂的实现,您可以查看auto.tcl的auto_mkindex,它具有类似的目标。

答案 2 :(得分:0)

这是一种不同的方法:

  1. 创建临时名称空间
  2. 来源(包括)有问题的剧本,然后
  3. 使用info procs命令获取过程列表
  4. 完成后删除临时命名空间
  5. 这是我的脚本,* list_procs.tcl *:

    #!/usr/bin/env tclsh
    
    # Script to scan a Tcl script and list all the procs
    
    proc listProcsFromFile {fileName} {
        namespace eval TempNamespace {
            source $fileName
            set procsList [info procs]
        }
        set result $::TempNamespace::procsList
        namespace delete TempNamespace
        return $result
    }
    
    set fileName [lindex $::argv 0]
    set procsList [listProcsFromFile $fileName]
    puts "File $fileName contains the following procs: $procsList"
    

    例如,如果您有以下脚本, procs.tcl

    proc foo {a b c} {}
    proc bar {a} {}
    

    然后运行脚本将产生:

    $ tclsh list_procs.tcl procs.tcl 
    File procs.tcl contains the following procs: foo bar
    

答案 3 :(得分:0)

您可以在获取相关文件之前和之后使用[info procs],并比较结果以确定添加了哪些过程。例如:

proc diff {before after} {
    set result [list]
    foreach name $before {
        set procs($name) 1
    }
    foreach name $after {
        if { ![info exists procs($name)] } {
            lappend result $name
        }
    }
    return [lsort $result]
}

set __before [info procs]
source myFile.tcl
set __after  [info procs]
puts "Added procs: [diff $__before $__after]"

我喜欢这个解决方案的一件事是diff过程实际上只是一个通用的集合差异实用程序 - 它并不特定于比较已定义过程的列表。