Как найти место проведения процедуры TCL?

Как можно найти расположение процедуры (функции) в TCL. Под расположением я подразумеваю исходный файл, в котором оно объявлено.

Я пытаюсь читать иностранный исходный код и не могу найти объявление ни одной процедуры, например:

set MSISDNElement [regexp -all -inline {ISDN +[0-9]+} $Command]

if { $MSISDNElement != "" } {
    foreach elm $MSISDNElement {
        set MSISDNValue [list ISDN [getInternationalFormat [lindex $elm 1]]]
    }
}

set EptData [list [lindex $Command 1]]

InitEptData 3
foreach Element $EptData {
    SetEptData [lindex $Element 0] [lindex $Element 1]
}

Для функций InitEptData и SetEptData я не могу найти объявления. Может ли кто-нибудь, кто более глубоко знаком с TCL, объяснить, как решить проблему, с которой я столкнулся? Заранее спасибо!


person nenito    schedule 29.09.2012    source источник
comment
Как правило, вы не можете найти место для процедуры (поскольку Tcl дает вам eval возможность определить ее на лету, динамически, во время выполнения). На практике вы можете использовать текстовый поиск (например, grep в Linux), чтобы найти определяющее вхождение некоторого имени.   -  person Basile Starynkevitch    schedule 29.09.2012
comment
Кроме того, некоторые процедуры на самом деле определяются некоторым исполняемым кодом, скомпилированным из C.   -  person Basile Starynkevitch    schedule 29.09.2012
comment
@Basile Starynkevich: Да, здесь так и есть! Спасибо!   -  person nenito    schedule 29.09.2012


Ответы (2)


На это нет универсального ответа, поскольку Tcl позволяет вам объявлять процедуры на лету, поэтому у них может не быть фактической ссылки на файл.

Есть некоторые попытки улучшить ситуацию для процедур, у которых есть определяющий файл, например TIP280, который фактически доступен как info frameв последних версиях 8.5, и TIP 86, который только обсуждается.

Но если простой grep не работает, вы можете отследить момент создания процедуры или команды.

Это происходит в разных местах (Tcl OO может добавить еще несколько, не уверен):

  • Во время команды load, когда двоичное расширение регистрирует свои функции обработчика команд с помощью Tcl_CreateCommand или более современная Tcl_CreateObjCommand.
  • Во время команды source, когда загружается файл с определениями proc
  • При выполнении самой команды proc для определения новой процедуры

Используя команды info commands и namespace children, вы можете пройтись по всему дереву пространства имен, чтобы получить список определенных команд до и после выполняемой команды. Таким образом, вы можете создать оболочку, которая отслеживает любые новые команды. См. http://wiki.tcl.tk/1489, чтобы узнать, как это сделать.

Или просто используйте отладчик, такой как RamDebugger http://www.compassis.com/ramdebugger/Intro. или коммерческий отладчик ActiveStates.

person schlenk    schedule 29.09.2012
comment
Короткое предложение: когда определяется новая команда, она обычно удаляет старую (вместо этого rename выдает ошибку). Таким образом, nop-процедура с таким именем и трассировкой удаления сообщает вам, когда старая команда удалена. - person Johannes Kuhn; 29.05.2013

Из оболочки bash я использую:

 find . -name "*.tcl" -exec grep -H proc_name_to_find {} \; | grep proc

Это находит все файлы tcl, затем выполняет grep для каждого файла для поиска proc_name_to_find, а затем вывод еще раз обрабатывается для тех строк, которые содержат «proc».

Поскольку grep -H выводит имена файлов вместе с выходной строкой, это показывает вывод, необходимый для поиска определения в вашем редакторе.

Пример:

$ find . -name "*.tcl" -exec grep -H set_prime {} \; | grep proc
./my_lib.tcl:proc prime_test::set_prime {{quiet 0} {no_compare 0}} {

Есть и другие решения с xargs...

person user3870893    schedule 23.07.2014