Tcl commands
Встроенные команды Tcl
Http
Клиентская часть реализации протокола HTTP/1.0.
- Синтаксис
- Описание
- Команды
- Массив состояния транзакции
СИНТАКСИС
package require http?2.0?::http::config ?options?
::http::geturl url ?options?
::http::formatQuery list
::http::resetk token
::http::wait token
::http::status token
::http::size token
::http::code token
::http::data token
ОПИСАНИЕ
Пакет http обеспечивает клиентскую часть протокола HTTP/1.0 и реализует операции GET, POST и HEAD. Он позволяет конфигурировать сервер-представитель (proxy) для выхода через межсетевые экраны. Пакет совместим с политикой безопасности Safesock.Процедура ::http::geturlвыполняет HTTP транзакцию. В зависимости от заданной опции это может быть GET, POST или HEAD транзакция. Величина, возвращаемая процедурой ::http::geturl, является признаком (token) выполнения транзакции. Кроме того, ее значение совпадает с именем массива в пространстве имен ::http, который содержит информацию о выполнении транзакции. Элементы массива описаны ниже, см. Массив состояния транзакции.
Если процедура вызвана с опцией -command, операция выполняется в фоновом режиме. Процедура ::http::geturl завершается сразу после формирования HTTP запроса, а результаты запроса обрабатываются после их получения. Для успешной работы в таком режиме необходимо, чтобы был запущен обработчик событий. Это всегда так для Tk-приложений. В чисто Tcl ≈ приложениях можно использовать процедуру ::http::wait для запуска обработчика событий.
КОМАНДЫ
::http::config ?options?Команда ::http::config используется, чтобы установить или запросить имя proxy-сервера, порта и пользовательского приложения (User-Agent), используемые в HTTP запросах. Если никакие опции не заданы, возвращается текущая конфигурация. Если задан единственный аргумент, тогда, он должен быть именем одной из опций, описанных ниже. В этом случае возвращается текущая величина указанной опции. В противном случае аргументы состоят из пар: имя опции ≈ присваиваемое значение.
-accept mimetypes::http::geturl url ?options?Определяет типы документов, которые могут быть приняты по запросу. Значение по умолчанию "*/*" означает, что могут быть приняты документы любого типа. Чтобы ограничить список допустимых документов, можно использовать список (через запятую) шаблонов документов следующего вида: image/gif, image/jpeg, text/*.-proxyhost hostnameИмя proxy-сервера, через который осуществляется связь. Если не указано, связь осуществляется напрямую.-proxyport numberИмя proxy-порта.-proxyfilter commandОпределяет команду, которая возвращает имена proxy-сервера и proxy-порта, необходимые для данной связи. В противном случае возвращает пустое значение. В качестве аргумента при вызове команды используется имя сервера (host). Если команда не задана, используются значения опций -proxyhost и -proxyport.-useragent stringОпределяет имя пользовательского приложения (User-Agent). Значение по умолчанию Tcl http client package 2.0.Команда ::http::geturl ≈ основная команда пакета. Если задана опция -query, выполняется операция POST, если задана опция -validate, выполняется операция HEAD. В противном случае выполняется операция GET. Команда возвращает признак ≈ имя массива, который может быть использован для получения дополнительной информации о состоянии транзакции. Подробности см. Массив состояния транзакции. Команда завершается после завершения соответствующей операции, если она вызвана без опции -command. В противном случае команда ::http::geturl завершается немедленно, а по завершении операции вызывается соответствующая команда для обработки ее результатов. Команда ::http::geturl может использоваться с различными опциями:
-blocksize size
Используется при чтении информации. Определяет максимальный размер блока (в байтах), который может быть прочитан за один раз. После каждого чтения блока вызывается команда, определенная с помощью опции -progress.
-channel nameПеренаправляет полученную информация в соответствующий канал вместо того, чтобы сохранять ее в переменной state(body).-command callbackОбеспечивает вызов команды callback после завершения транзакции. При использовании этой опции команда ::http::geturl завершается сразу. Команда callback вызывается с аргументом token, который содержит имя массива, описанного ниже, см. Массив состояния транзакции. Ниже приведен шаблон типовой процедуры для использования в данной опции:proc httpCallback {token} {upvar #0 $token state}
# Далее возможна работа со state как с обычным Tcl-массивом
-handler callbackОпция обеспечивает вызов команды callback как только HTTP данные получены. Команда получает два дополнительных аргумента: HTTP socket и имя массива token, возвращенное командой ::http::geturl (см. Массив состояния транзакции). Команда должна возвращать число байтов, прочитанных из socket. Ниже приведен шаблон подобной процедуры:proc httpHandlerCallback {socket token} {-headers keyvaluelistupvar #0 $token state}
# Получен доступ к socket и Tcl-массиву state
...
(например: set data [read $socket 1000];set nbytes [string length $data])
...
return nbytesОпция используется для включения в заголовок HTTP запроса дополнительных полей. Аргумент должен быть правильным списком с четным числом элементов, состоящим попеременно из ключей и их значений. Ключи используются как имена полей заголовка. Из значений удаляются символы перехода на новую строку, чтобы избежать формирования неправильного заголовка. Например, если keyvaluelist содержит список {Pragma no-cache} будет сформирован следующий заголовок запроса:Pragma: no-cache-progress callbackОпция обеспечивает вызов команды callback для обработки очередной порции данных. Команда callback получает три аргумента: значение token, возвращенное командой ::http::geturl, предполагаемый полный размер данных из мета-данных и текущее количество поступивших данных в байтах. Если едполагаемый полный размер неизвестен, вместо него подставляется 0. Ниже приведен шаблон для процедуры, вызываемой по опции -progress:::http::formatQuery key value?key value...?proc httpProgress {token total current} {upvar #0 $token state
}
-query queryЕсли указана данная опция, ::http::geturl формирует запрос POST и передает его на сервер. Запрос должен быть сформатирован. Для выполнения форматирования может использоваться процедура ::http::formatQuery.-timeout millisecondsЕсли значение milliseconds не равно нулю, устанавливается соответствующее время задержки. Задержка выполняется перед вызовом команды ::http::reset и команды, заданной опцией -command. Во время задержки команда ::http::status возвращает значение timeout.-validate boolean
Если значение boolean не равно нулю, ::http::geturl выполняет HTTP HEAD запрос. Такой запрос возвращает мета информацию об источнике данных (URL), а не его содержание. Мета информация содержится в переменной state(meta) (см. Массив состояния транзакции).Команда выполняет перекодирование запроса. Команда использует четное число аргументов, являющихся соответственно ключами запроса и их значениями. Она преобразует ключи и значения и возвращает одну строку, в которой расставлены необходимые & и = разделители. Результат можно использовать в качестве значения для опции -query команды ::http::geturl.::http::reset token?why?Команда перезапускает HTTP транзакцию token, если такая исполняется. Значение переменной state(status) при этом переустанавливается в why (по умолчанию ≈ reset) и вызывается команда, заданная опцией -command.::http::wait tokenЭта команда обеспечивает ожидание завершения транзакции. Она работает только в надежных интерпретаторах, так как она использует команду vwait.::http::data tokenЭта команда возвращает значение переменной state(body).::http::status tokenЭта команда возвращает значение переменной state(status).::http::code tokenЭта команда возвращает значение переменной state(http).::http::size token
Эта команда возвращает значение переменной state(currentsize).
МАССИВ СОСТОЯНИЯ ТРАНЗАКЦИИ
Команда ::http::geturl возвращает token ≈ имя Tcl-массива, содержащего информацию о HTTP транзакции. Для упрощения доступа к массиву можно использовать следующую конструкцию:
upvar #0 $token state
Массив содержит следующие элементы:
bodyСодержание документа, заданного с помощью URL. Пусто, если указана опция -channel. Значение переменной можно получить также с помощью команды ::http::data.сurrentsizeТекущий объем информации в байтах, полученный от источника. Значение переменной можно получить с помощью команды ::http::size.errorЕсли элемент определен, он содержит строку с сообщением об ошибке, полученную при прерывании HTTP транзакции.httpЭлемент содержит значение HTTP статуса, полученное от сервера. Значение переменной можно получить также с помощью команды ::http::code. Статус представляет собой строку из трех цифр, значения которой соответствуют HTTP стандарту. Код 200 соответствует успешному выполнению транзакции. Коды, начинающиеся с "4" или "5", указывают на ошибку. Коды, начинающиеся с "3", соответствуют ошибкам перенаправления. В этом случае мета данные Location определяют новый источник информации, который содержит запрошенные данные.metaМета данные, описывающие содержание документа. Данный элемент массива содержит список ключей и их значений. Чтобы облегчить доступ к данным можно использовать следующую конструкцию:
Пример:Content-Typearray set meta $state(meta)Некоторые ключи мета данных перечислены ниже, но в HTTP стандарте их перечислено больше, кроме того, сервер может добавлять собственные.Content-LengthТип документа. Например, text/html, image/gif, application/postscript или application/x-tcl.LocationОбъявленный размер документа. Реальный объем информации, полученной с помощью команды ::http::geturl, содержится в переменной state(size).statusИзмененный адрес документа.Возможные значения ok, reset или error. Во время транзакции значение пустое.totalsizeКопия значения мета данных Content-Length.typeКопия значения мета данных Content-Type.urlЗапрошенный адрес.
# Копирование источника в файл и печать мета данных
proc ::http::copy { url file {chunk 4096} } {set out [open $file w]incr max
set token [geturl $url -channel $out -progress ::http::Progress \
-blocksize $chunk]
close $out
# Следующая команда завершает строку, начатую процедурой http::Progress
puts stderr
upvar #0 $token state
set max 0
foreach {name value} $state(meta) {
if {[string length $name] > $max} {set max [string length $name]if {[regexp -nocase ^location$ $name]} {
}# Обработка перенаправления адреса}
puts stderr Location:$value
return [copy [string trim $value] $file $chunk]
}
foreach {name value} $state(meta) {puts [format %-*s %s $max $name: $value]return $token
}}
proc ::http::Progress {args} {
puts -nonewline stderr. ; flush stderr
}
- Синтаксис
- Описание
- Синонимы
- Команды
- Опции
- Безопасность
- Механизм создания и управления
безопасными интерпретаторами.
|
|
|
|
|
|
::safe::interpCreate?slave??options...?
::safe::interpInit slave?options...?
::safe::interpConfigure slave?options...?
::safe::interpDelete slave
::safe::interpAddToAccessPath slave directory
::safe::interpFindInAccessPath slave directory
::safe::setLogCmd?cmd
arg...?
Safe Tcl ≈ это механизм безопасного исполнения ненадежных Tcl скриптов и предоставления этим скриптам опосредованного доступа к потенциально опасным функциям.
Safe Tcl служит для того, чтобы ненадежные скрипты не смогли нарушить работу вызывающего их приложения: он предотвращает покушения на несанкционированный доступ к информации и нарушение целостности вызывающего этот скрипт процесса.
Safe Tcl позволяет интерпретатору-предку создавать безопасные интерпретаторы с ограниченными возможностями, в которых содержится набор предопределенных синонимов для команд source, load, file и exit и сохраняются возможности автозагрузки команд и пакетов.
Безопасный интерпретатор не позволяет получить какую-либо информацию о структуре файловой системы, поскольку для доступа к файлам в безопасном интерпретаторе используются специальные метки. Когда безопасный интерпретатор запрашивает доступ к файлу, он использует метку как часть виртуального имени файла. Родительский интерпретатор заменяет метку на реальное имя каталога и выполняет требуемую операцию с файлом. С помощью опций команд, описанных ниже, можно выбрать требуемый уровень безопасности интерпретатора.
Все команды для работыс безопасными
интерпретаторами содержатся в пространстве имен safe. Команда ::safe::interpCreate
создает безопасный интерпретатор. Возможные опции команды описаны ниже,
см. Опции.
Команда возвращает имя созданного
интерпретатора. Команда ::safe::interpInit
аналогична, но ее первым аргументом должно быть имя интерпретатора, созданного
с помощью команды
interp. Команда
::safe::interpDelete
удаляет интерпретатор, имя которого использовано в качестве аргумента.
Команда ::safe::interpConfigure
позволяет задать опции для безопасного интерпретатора или получить информацию
об заданных ранее опциях. Подробно опции описаны ниже (см. Опции).
Для каждого безопасного интерпретатора, созданного с помощью команды ::safe::interpCreate или инициированного с помощью команды ::safe::interpInit в родительском интерпретаторе создается список доступных каталогов ≈ виртуальный путь. Каждый каталог в пути связывается с реальным каталогом локальной файловой системы и с меткой, доступной в безопасном интерпретаторе. В результате надежный интерпретатор обходится без сведений о реальной файловой системе на машине, на которой исполняется интерпретатор. Когда в надежном интерпретаторе используется метка для доступа к конкретному файлу (например, для выполнения команды source или load), метка заменяется в родительском интерпретаторе на настоящее имя каталога и необходимый файл ищется в файловой системе. Надежный интерпретатор не получает сведений о реальном имени файла в файловой системе. Для работы с виртуальными именами файлов предусмотрены специальные команды. Команда::safe::interpConfigure позволяет задавать новый виртуальный путь для интерпретатора. Команда ::safe::interpAddToAccessPath позволяет добавлять каталоги к виртуальному пути указанного безопасного интерпретатора. Команда ::safe::interpFindInAccessPath позволяет найти каталог в виртуальном пути для безопасного интерпретатора и получить его метку. Если каталог не найден, выдается сообщение об ошибке.
Команда ::safe::setLogCommand
позволяет задать скрипт, который выполняется при каждом событии в безопасном
интерпретаторе. Этот скрипт вызывается с одним аргументом ≈ строкой, содержащей
описание события.
При создании безопасного интерпретатора в нем определяются следующие команды ≈ синонимы:
source fileName
file?options?
В родительском интерпретаторе для работы с безопасными интерпретаторами предусмотрены следующие команды:
::safe::interpCreate?slave??options...?
::safe::interpFindInAccessPathslave
directory
Пример использования команды:
###Создание безопасного интерпретатора
::safe::interpCreate qqq
###Присваивание переменной
tk_library метки соответствующего каталога
qqq eval [list set tk_library
[::safe::interpFindInAccessPath qqq $tk_library]]
###Выполнение команды source
в безопасном интерпретаторе
qqq eval source \$tk_library/msgbox.tcl
qqq eval source \$my_lib/\$my_file
::safe::setLogCmd puts stderr
NOTICE for slave interp10
: Created
NOTICE for slave interp10
: Setting accessPath=(/foo/bar) staticsok=1 nestedok=0 deletehook=()
NOTICE for slave interp10
: auto_path in interp10 has been set to {$p(:0:)}
ERROR for slave interp10
: /foo/bar/init.tcl: no such file or directory
Для команд ::safe::interpCreate, ::safe::interpInit, и :safe::interpConfigure определены перечисленные ниже опции. Имена опций могут быть сокращены до минимальных однозначных имен. Имена опций не чувствительны к регистру, в котором они набраны.
-accessPath?directoryList?
Save Tcl не дает полной гарантии безопасности. В частности, он не защищает от атак на сервер, когда поглощаются все ресурсы процессора и пользователь не может использовать компьютер для полезной работы. Однако такие атаки считаются, как правило, менее опасными, чем несанкционированный доступ к информации и нарушение целостности, от которых безопасный интерпретатор защищает. В безопасном интерпретаторе, помимо безопасного набора команд, который описан в описании команды interp, имеются синонимы для команд source, load, exit и безопасное подмножество подкоманд команды file. В безопасном интерпретаторе возможна автозагрузка библиотек и пакетов. Поскольку эти команды имеют дело с локальной файловой системой, существует потенциальная опасность использования их для доступа к конфиденциальной информации. Чтобы предотвратить эту возможность, в безопасном интерпретаторе используются не настоящие имена каталогов, а специальные метки. Эти метки транслируются в реальные имена файлов только в родительском интерпретаторе.
Чтобы исключить доступ к файлам, которые оказались в силу тех или иных причин в разрешенных для чтения в безопасном интерпретаторе каталогах, синоним команды source обеспечивает доступ только к файлам с расширением tcl, в именах которых содержится ровно одна точка, а общая длина имени не превышает четырнадцати символов.
По умолчанию в Tcl переменной
auto_path
содержатся метки для каталогов, содержащихся в аналогичной переменной в
родительском интерпретаторе и их непосредственных подкаталогов. Первая
метка в списке присваивается также Tcl переменной tcl_library безопасного
интерпретатора. Вы можете сократить этот список, в явном виде задав доступные
каталоги для безопасного интерпретатора с помощью опции
-accessPath.
Safe Tcl ≈ это механизм безопасного исполнения ненадежных Tcl скриптов и предоставления этим скриптам опосредованного доступа к потенциально опасным функциям.
Safe Tcl служит для того, чтобы ненадежные скрипты не смогли нарушить работу вызывающего их приложения: он предотвращает покушения на несанкционированный доступ к информации и нарушение целостности вызывающего этот скрипт процесса.
Safe Tcl позволяет интерпретатору-предку создавать безопасные интерпретаторы с ограниченными возможностями, в которых содержится набор предопределенных синонимов для команд source, load, file и exit и сохраняются возможности автозагрузки команд и пакетов.
Безопасный интерпретатор не позволяет получить какую-либо информацию о структуре файловой системы, поскольку для доступа к файлам в безопасном интерпретаторе используются специальные метки. Когда безопасный интерпретатор запрашивает доступ к файлу, он использует метку как часть виртуального имени файла. Родительский интерпретатор заменяет метку на реальное имя каталога и выполняет требуемую операцию с файлом. С помощью опций команд, описанных ниже, можно выбрать требуемый уровень безопасности интерпретатора.
Все команды для работыс безопасными
интерпретаторами содержатся в пространстве имен safe. Команда ::safe::interpCreate
создает безопасный интерпретатор. Возможные опции команды описаны ниже,
см. Опции.
Команда возвращает имя созданного
интерпретатора. Команда ::safe::interpInit аналогична, но ее первым
аргументом должно быть имя интерпретатора, созданного с помощью команды
interp.
Команда
::safe::interpDelete удаляет интерпретатор, имя которого
использовано в качестве аргумента. Команда ::safe::interpConfigure
позволяет задать опции для безопасного интерпретатора или получить информацию
об заданных ранее опциях. Подробноопции описаны ниже (см. Опции).
Для каждого безопасного интерпретатора, созданного с помощью команды ::safe::interpCreate или инициированного с помощью команды ::safe::interpInit в родительском интерпретаторе создается список доступных каталогов ≈ виртуальный путь. Каждый каталог в пути связывается с реальным каталогом локальной файловой системы и с меткой, доступной в безопасном интерпретаторе. В результате надежный интерпретатор обходится без сведений о реальной файловой системе на машине, на которой исполняется интерпретатор. Когда в надежном интерпретаторе используется метка для доступа к конкретному файлу (например, для выполнения команды source или load), метка заменяется в родительском интерпретаторе на настоящее имя каталога и необходимый файл ищется в файловой системе. Надежный интерпретатор не получает сведений о реальном имени файла в файловой системе. Для работы с виртуальными именами файлов предусмотрены специальные команды. Команда ::safe::interpConfigure позволяет задавать новый виртуальный путь для интерпретатора. Команда ::safe::interpAddToAccessPath позволяет добавлять каталоги к виртуальному пути указанного безопасного интерпретатора. Команда ::safe::interpFindInAccessPath позволяет найти каталог в виртуальном пути для безопасного интерпретатора и получить его метку. Если каталог не найден, выдается сообщение об ошибке.
Команда ::safe::setLogCommand
позволяет задать скрипт, который выполняется при каждом событии в безопасном
интерпретаторе. Этот скрипт вызывается с одним аргументом ≈ строкой, содержащей
описание события.
Синтаксис и семантика языка Tcl определены описанным ниже образом.Скрипт на Tcl представляет собой одну или более команд. Символы точки с запятой (;) и новой строки служат разделителями команд, если не находятся между символами кавычек. Закрывающие скобки служат окончанием тела команды при подстановках команд, если не находятся между символами кавычек.
Команда обрабатывается за два прохода. При первом проходе интерпретатор Tcl разбивает команду на слова и выполняет подстановки, как рассказано ниже. Эти подстановки выполняются одинаково для всех команд. Первое слово считается именем процедуры, которая исполняет команду. Когда процедура найдена, ей передаются остальные слова команды. Процедура может интерпретировать каждое из слов произвольным образом, например, как число, имя переменной, список или Tcl скрипт. Разные командные процедуры интерпретируют свои слова по-разному.
Слова команд разделяются пробельными символами (пробел, табуляция). Символ новой строки разделяет команды.
Если первый символ слова есть двойные кавычки (), то слово должно заканчиваться также на двойные кавычки. Если в промежутке между знаками кавычек находятся точка с запятой, закрывающая скобка или пробельные символы (включая символ новой строки), то они будут поняты как обычные символы в составе слова. Подстановки команд, переменных и подстановки с обратным слешем в таком слове описаны ниже. Двойные кавычки не являются частью слова.
Если слово начинается с открывающей фигурной скобки ({), то оно должно заканчиваться на парную ей закрывающую скобку (}). Внутри фигурных скобок могут также содержаться слова в фигурных скобках. При этом каждая открывающая фигурная скобка должна иметь парную ей закрывающую фигурную скобку. Однако, если открывающая или закрывающая фигурная скобка отмечена обратным слешем, то она не учитывается при поиске парной скобки. Для символов между фигурными скобками не выполняется никаких подстановок, за исключением описанной ниже подстановки обратный слеш ≈ новая строка. Также не приписывается никакого специального смысла символам точки с запятой, новой строки, закрывающей скобки и пробела. Слово будет состоять из символов между скобками, за исключением самих скобок.
Если слово содержит открывающую квадратную скобку ([), то Tcl выполняет подстановку команды. Для этого он рекурсивно вызывает интерпретатор Tcl, который обрабатывает символы, следующие за скобкой, как скрипт Tcl. Скрипт может иметь любое количество команд и должен оканчиваться закрывающей квадратной скобкой (]). Результат выполнения скрипта (т.е., результат его последней команды) подставляется в слово на место скобок и всех символов между ними. В слове может быть любое количество подстановок команд. Подстановки команд не выполняются в словах, заключенных в фигурные скобки.
Если слово содержит символ доллара ($), тогда Tcl выполняет подстановку переменной: символ доллара и последующие символы заменяются в слове на значение этой переменной. Существует три способа подстановки переменной:
$nameЗдесь name ≈ имя скалярной переменной, оно заканчивается любым символом, за исключением буквы, цифры или символа подчеркивания.$name(index)Здесь name есть имя массива данных, а index ≈ имя элемента внутри этого массива. Name должен состоять только из букв, цифр и символов подчеркивания. Все виды подстановок выполняются по отношению к символам index.${name}Здесь name ≈ имя скалярной переменной, оно может состоять из каких угодно символов, кроме закрывающей фигурной скобки.
В слове может быть любое количество подстановок переменных. Подстановки переменных не выполняются для слов, заключенных в фигурные скобки.Если в слове есть символ обратного слеша, то выполняется подстановка с обратным слешем. Во всех случаях, кроме перечисленных ниже, обратный слеш пропускается, а следующий за ним символ обрабатывается как обычный символ и включается в состав слова. Таким способом в слово можно включать такие символы, как двойные кавычки, закрывающие скобки и символ доллара без непреднамеренной специальной обработки. Ниже перечислены последовательности символов, для которых подстановка с обратным слешем выполняется специальным образом, и соответствующие подставляемые значения.
\a | Звуковой сигнал (гудок) (0х7). |
\b | Сдвиг на одну позицию влево (0х8). |
\f | Прогон листа (0хс). |
\n | Новая строка, newline (0ха). |
\r | Возврат каретки (0хd). |
\t | Табуляция (0х9). |
\v | Вертикальная табуляция (0xb). |
\<newline>пробел | Обратный слеш, символ новой строки и все пробелы и табуляции после этого символа заменяются на одиночный пробел. Данная последовательность уникальна в том смысле, что она замещается в отдельном суб-проходе перед тем, как начинается непосредственно анализ команды. Поэтому эта последовательность будет замещена, даже если она стоит между фигурными скобками, и результирующий пробел будет интерпретироваться как разделитель слов, если только он не будет стоять между фигурными скобками или кавычками. |
\\ | Обратный слеш (\). |
\ooo | Цифры ooo (одна, две или все три) дают восьмеричное значение символа. |
\xhh | Шестнадцатеричное число "hh" дает шестнадцатеричное значение символа. Может присутствовать любое количество цифр. |
- Подстановки с обратным слешем
не выполняются в словах, заключенных в фигурные скобки, кроме подстановки
обратный слеш ≈ новая строка.
Если символ "#" будет стоять в том месте, где Tcl предполагает первый символ первого слова команды, то этот символ и все последующие символы до следующего символа новой строки включительно истолковываются как комментарии и игнорируются. Символ комментария действителен только тогда, когда он стоит в начале команды.
При воссоздании слов команды каждый символ обрабатывается интерпретатором Tcl только один раз. Например, если выполнялась подстановка переменной, то в значении переменной никаких подстановок не производится; значение вставляется в слово без изменений. Если выполнялась подстановка команды, то вставленная команда обрабатывается целиком посредством рекурсивного вызова интерпретатора Tcl; не делается никаких подстановок перед рекурсивным вызовом и не делается никаких дополнительных подстановок в результат исполнения вставленного скрипта.
Подстановки не воздействуют на границы слов в команде. Например, при подстановке переменной все значение переменной становится частью одного слова, даже если это значение содержит пробелы.
Команда after указывает, что некоторая команда должна быть выполнена с задержкой по времени.- after
ms
after ms?script script script...?
after cancel id
after cancel script script script...
after idle?script script script...?
after info?id?
Команда используется для того, чтобы отложить выполнение программы или выполнить указанную команду в фоновом режиме в некоторый момент в будущем. У команды есть несколько форм, зависящих от ее первого аргумента.
- Ms ≈ целое число,
задающее задержку в миллисекундах. Команда обеспечивает задержку на соответствующее
число миллисекунд до своего завершения. Во время задержки приложение не
реагирует на события.
- В этой форме команда завершается
немедленно, но при этом она обеспечивает выполнение Tcl-команды script
script script
через соответствующее время. Команда выполняется ровно
один раз в установленный момент времени. Команда формируется объединением
всех перечисленных аргументов
script
таким же образом, как при выполнении
команды concat. Команда выполняется на глобальном
уровне (вне контекста какой-либо Tcl-процедуры). Ошибки во время выполнения
команды (если они происходят) обрабатываются с помощью процедуры bgerror.
Команда
after в этой форме возвращает идентификатор, который может
быть использован для отмены отложенной команды с помощью команды after
cancel.
- Отменяет исполнение ранее
заявленной отложенной команды. Id определяет, какая именно команда
будет отменена. Значение
id должно совпадать со значением, возвращенным
предыдущей командой
after. Если соответствующая команда уже выполнена,
команда
after cancel игнорируется.
- Эта команда также отменяет
выполнение ранее заявленной отложенной команды. Все перечисленные скрипты
script объединяются через пробел таким же образом, как при выполнении
команды
concat. После чего ищется отложенная
команда с аналогичным скриптом. Если такая команда будет найдена, ее исполнение
будет отменено. В противном случае команда after cancel игнорируется.
- Все перечисленные скрипты
объединяются через пробел таким же образом, как при выполнении команды
concat.
Сформированная таким образом Tcl команда выполняется позже. Она выполняется
ровно один раз в первом цикле обработчика событий, в котором не будет других
необработанных событий. Команда after idle возвращает идентификатор,
который может быть использован для отмены отложенной команды. Ошибки во
время выполнения команды (если они происходят) обрабатываются с помощью
процедуры bgerror.
- Эта команда используется
для получения информации об отложенных командах. Если аргумент id
отсутствует , то возвращает список идентификаторов отложенных команд. Если
аргумент
id указан и соответствует идентификатору отложенной команды,
которая не отменена и еще не выполнена, возвращается список из двух элементов.
Первый элемент списка √ Tcl-скрипт соответствующей команды, второй ≈ idle
или timer в зависимости от того, по какому событию предполагается
вызов команды.
Команда дописывает значения аргументов к значению переменной.
СИНТАКСИС
append varName?value value value...?ОПИСАНИЕ
Команда append добавляет все аргументы value к значению переменной varName. Если такой переменной не было, она будет создана, и ее значение будет равно соединению значений аргументов value. Эта команда предоставляет удобный способ постепенного наращивания длинных переменных. сЕли переменная a содержит длинное значение, то команда append a $b" выполняется значительно быстрее, чем set a $a$b" .
ОПИСАНИЕarray option arrayName?arg arg...?
array anymore arrayName searchId
array donesearch arrayName searchId
array exists arrayName
array get arrayName?pattern?
array names arrayName?pattern?
array nextelement arrayName searchId
array set arrayName list
array size arrayName
array startsearch arrayName
Эта команда предназначена для выполнения перечисленных ниже операций с массивами. Если иное не оговорено специально, arrayName должно быть именем существующего массива. Аргумент option определяет конкретную операцию. Для команды определены перечисленные ниже опции.
array anymore arrayName searchId
Возвращает "1" если при выполнении команды поиска (см. ниже) остались невыбранные элементы массива, и "0" в противном случае. SearchId указывает операцию поиска, информация о которой запрашивается (величина searchId возвращается при выполнении команды array startsearch). Эта опция особенно удобна, если массив содержит элемент с пустым именем, поскольку команда array nextelement не позволяет в таком случае определить, закончен ли поиск.array donesearch arrayName searchIdКоманда прерывает поиск элементов массива и удаляет всю связанную с поиском информацию. SearchId указывает операцию поиска, информация о которой удаляется (величина searchId возвращается при выполнении команды array startsearch). Команда возвращает пустую строку.array exists arrayNameВозвращает "1", если arrayName есть имя массива, и "0", если такой переменной не существует или она является скалярной переменной.array get arrayName?pattern?Возвращает список, содержащий пары элементов. Первый элемент пары ≈ имя элемента массива arrayName, второй элемент пары ≈ значение этого элемента. Порядок пар не определен. Если шаблон не задан, то все элементы массива будут включены в результат. Если шаблон задан, то в результат будут включены только те элементы, чьи имена соответствуют шаблону (используя те же правила, что и в команде glob). Если arrayName не является переменной массива или массив не содержит элементов, то возвращается пустой список.array names arrayName?pattern?Возвращает список, содержащий имена всех элементов массива, соответствующих шаблону (используя те же правила, что и в команде glob). Если шаблона нет, то команда возвращает имена всех элементов массива. Если в массиве нет элементов, соответствующих шаблону или arrayName не является именем переменной массива, то возвращается пустая строка.array nextelement arrayName searchIdВозвращает имя следующего элемента массива arrayName, или пустую строку, если все элементы массива уже возвращены. SearchId указывает операцию поиска, (величина searchId возвращается при выполнении команды array startsearch). Предупреждение: если в массив внесен новый элемент или из массива удален один из элементов, то все операции поиска в этом массиве автоматически заканчиваются, как если бы была выполнена команда array donesearch. Соответственно, попытка выполнить после этого команду array nextelement приведет к ошибке.array set arrayName listУстанавливает значение одного или нескольких элементов массива arrayName. Список list должен иметь такую же структуру, как список, возвращаемый командой array get, то есть состоять из четного числа элементов. Все нечетные элементы списка рассматриваются как имена элементов массива arrayName, а следующие за ними четные элементы ≈ как новые значения соответствующих элементов.array size arrayNameВозвращает строку, содержащую десятичное число, равное количеству элементов указанного массива. Если arrayName не является именем массива, возвращается "0".array startsearch arrayNameЭта команда инициализирует процесс поиска элементов указанного массива. После этого имя каждого следующего элемента массива можно получить с помощью команды array nextelement. По завершении поиска необходимо выполнить команду array donesearch. Команда array startsearch возвращает идентификатор процесса поиска, который должен использоваться в командах array nextelement и array donesearch. Благодаря этому механизму возможно проведение нескольких процессов поиска элементов одного и того же массива одновременно.
СИНТАКСИС
Фоновые ошибки ≈ это ошибки в командах, которые не вызваны непосредственно из приложения. Например, фоновыми являются ошибки в командах, вызванных с помощью конструкции after. Для нефоновых ошибок сообщение об ошибке возвращается через вложенные вызовы команд, пока не достигнет верхнего уровня приложения. После этого приложение выдает сообщение об ошибке в одной из команд верхнего уровня. При фоновой ошибке подобный процесс не достигает команд верхнего уровня и формирование сообщения об ошибке оказывается затруднительным.
Когда Tcl обнаруживает фоновую ошибку, он сохраняет информацию об ошибке и вызывает команду bgerror с помощью обработчика событий. Перед вызовом bgerror восстанавливаются значения переменных errorInfo и errorCode, которые были при обнаружении ошибки. После этого вызывается команда bgerror с единственным аргументом ≈ сообщением об ошибке. Предполагается, что в приложении определена команда bgerror и что она выдает сообщение об ошибке надлежащим образом. Если при выполнении команды bgerror не произошло новой ошибки, возвращаемый ею результат игнорируется.
Если при исполнении команды bgerror произошла новая ошибка (например, если эта команда не существует), сообщение об ошибке поступает в канал вывода ошибок.
Если до вызова обработчиком событий команды bgerror произошло несколько фоновых ошибок, то, как правило, команда будет вызвана для каждой из обнаруженных ошибок. Однако, если сама команда bgerror возвращает код break (см. описание команды return), последующие ее вызовы пропускаются.
В чисто Tcl-приложениях команда bgerror не реализована. Однако, в Tk-приложениях определена процедура bgerror, которая выводит сообщение об ошибке в диалоговое окно и позволяет пользователю просмотреть стек, описывающий, где именно эта ошибка произошла.
binary format formatString?arg arg...?
binary
scan string formatString?varName varName...?
- Команда binary format
создает двоичную строку по правилам, заданным с помощью шаблона formatString.
Содержание
этой строки задается дополнительными аргументами arg.
Команда возвращает
сформированную двоичную строку.
Шаблон formatString содержит последовательность из нуля или более спецификаторов преобразования, разделенных одним или более пробелами. Каждый спецификатор преобразования состоит из буквы, за которой может следовать число count. Как правило, спецификатор использует один из аргументов arg чтобы получить величину для форматирования. Буква в спецификаторе указывает тип преобразования (форматирования). Число count обычно указывает сколько объектов для форматирования выбирается из значения arg. Соответственно, count должно быть неотрицательным десятичным числом. Если значение count равно "*", это обычно указывает, что надо использовать все значение аргумента. Если число аргументов arg не соответствует числу спецификаторов, требующих для себя дополнительного аргумента, выдается ошибка.
Обычно результат каждого нового преобразования дописывается в конец возвращаемой строки. Однако, с помощью специальных спецификаторов точку ввода нового значения (курсор) можно передвигать по формируемой строке.
Ниже приведены допустимые
значения спецификаторов преобразований и описаны соответствующие преобразования.
binary format a7a*a alpha bravo charlie
вернет строку, эквивалентную alpha\000\000bravoc.
binary format A6A*A alpha bravo charlie
вернет alpha bravoc.
binary format b5b* 11100 111000011010
вернет строку, эквивалентную
\x07\x87\x05.
binary format B5B* 11100 111000011010
вернет строку, эквивалентную \xe0\xe1\xa0.
Например, команда
вернет строку, эквивалентную
\xba\xed\x0f.
вернет строку, эквивалентную
\xab\xde\xf0.
Например, команда
вернет строку, эквивалентную
\x03\xfd\x80\x01\x02\x05,
тогда как команда
вернет ошибку.
вернет строку, эквивалентную
\x03\x00\xfd\xff\x02\x01.
вернет строку, эквивалентную
\x00\x03\xff\xfd\x01\x02.
вернет строку, эквивалентную
\x03\x00\x00\x00\xfd\xff\xff\xff\x00\x00\x10\x00
вернет строку, эквивалентную
\x00\x00\x00\x03\xff\xff\xff\xfd\x00\x10\x00\x00
вернет строку, эквивалентную
\xcd\xcc\xcc\x3f\x9a\x99\x59\x40.
вернет строку, эквивалентную
\x9a\x99\x99\x99\x99\x99\xf9\x3f.
вернет строку, эквивалентную
abc\000def\000\000ghi.
вернет dghi.
binary format a5@2a1@*a3@10a1 abcde f ghi j
abfdeghi\000\000j.
binary scan\x07\x87\x05 b5b* var1 var2
вернет "2". В
переменной
var1 будет записано "01110". В переменной var2
≈ "1000011100000101".
вернет `2". В
переменной
var1 будет записано 706. В переменной var2
≈ "50`.
вернет "2.". В
переменной
var1 будет записано 078.. В переменной var2
≈ "05".
вернет "2". В
переменной
var1 будет записана строка 7 -122". В переменной
var2
≈ "5". Обратите внимание, что команда возвращает числа со знаком.
Чтобы преобразовать их в числа без знака можно использовать выражение:
binary scan\x05\x00\x07\x00\xf0\xff s2s* var1 var2
вернет "2". В переменной
var1
будет записана строка '5 7'. В переменной var2 ≈ "-16".
Обратите внимание, что команда возвращает числа со знаком. Чтобы преобразовать
их в числа без знака можно использовать выражение:
вернет "2". В
переменной var1 будет записана строка '5 7'. В переменной
var2
≈ "-16".
вернет "2". В переменной var1 будет записана строка 5 7". В переменной var2 ≈ "-16". Обратите внимание, что команда возвращает числа со знаком. В Tcl нет возможности перевести его в число без знака.
binary\x00\x00\x00\x05\x00\x00\x00\x07\xff\xff\xff\xf0 I2I* var1 var2
вернет "2". В переменной var1 будет записана строка 5 7". В переменной var2 ≈ "-16".
вернет "1". В
переменной
var1 будет записано "1.6000000238418579".
binary scan\x9a\x99\x99\x99\x99\x99\xf9\x3f d var1
вернет "1". В переменной var1 будет записано "1.6000000000000001".
вернет "1". В
переменной
var1 будет "0304". Преобразование не требует дополнительной
переменной
varName.
вернет "2". В
переменной
var1 будет "1 2". В переменной var2≈ "020304"..
Преобразование не требует дополнительной переменной varName.
вернет "2". В
переменной
var1 будет "1 2". В переменной var2 ≈ "020304".
Преобразование не требует дополнительной переменной varName.
Обычно данная команда помещается внутрь цикла, например созданного командами for, foreach или while. Команда возвращает код TCL_BREAK, который вызывает завершение исполнения наименьшего охватывающего ее цикла. Цикл завершается нормальным образом (без ошибки) как если бы он отработал до конца. Код TCL_BREAK обрабатывается также в некоторых других ситуация ≈ при исполнении команды catch, при обработке событий и в скрипте самого верхнего уровня.
case
case string?in? {patList body? body...?}
catch
Команда catch обрабатывает все прерывания, в том числе от команд break и continue.
cd
clock
clock option?arg arg...?
Команда выполняет одно из перечисленных ниже действий, с помощью которых можно получить и преобразовать строки или значения, являющиеся той или иной формой записи времени. Параметр option определяет выполняемое командой действие, одно из следующего списка (параметр может быть сокращен):
clock clicks
%% ≈ вставляет
%.
%a ≈ сокращенное название дня недели (Mon, Tue, etc.).
%A ≈ полное название дня недели (Monday, Tuesday, etc.).
%b ≈ сокращенное название месяца (Jan, Feb, etc.).
%B ≈ полное название месяца.
%c ≈ локальные дата и время.
%d ≈ день месяца (01 ≈ 31).
%H ≈ часы в двадцатичетырехчасовом формате (00 ≈ 23).
%I ≈ часы в двенадцатичасовом формате (00 ≈ 12).
%j ≈ день года (001 ≈ 366).
%m ≈ номер месяца (01 ≈ 12).
%M ≈ минуты (00 ≈ 59).
%p ≈ AM/PM индикатор (до/после полудня).
%S ≈ секунды (00 ≈ 59).
%U ≈ неделя года (01 ≈ 52), Воскресенье ≈ первый день недели.
%w ≈ номер дня недели (Воскресенье = 0).
%W ≈ неделя года (01 ≈ 52), Понедельник первый день недели.
%x ≈ локальный формат даты.
%X ≈ локальный формат времени.
%y ≈ год без столетия (00 ≈ 99).
%Y ≈ год со столетием (например, 1990)
%Z ≈ имя часового пояса.
Кроме того, в некоторых операционных системах могут поддерживаться
%D ≈ дата в формате %m/%d/%y.
%e ≈ день месяца (1 ≈ 31), без нулей впереди.
%h ≈ сокращенное имя месяца.
%n ≈ новая строка.
%r ≈ время в формате %I:%M:%S %p.
%R ≈ время в формате %H:%M.
%t ≈ табуляция.
%T ≈ время в формате %H:%M:%S.
Если аргумент -format не задан, используется формат %a %b %d %H:%M:%S %Z %Y. Если задан аргумент -gmt, следующий аргумент должен быть булевой величиной. Значение true означает, что используется время по Гринвичу, значение false означает, что используется время по локальному часовому поясу, который задан для операционной системы.
clock scan dateString?-base clockVal??-gmt boolean?
Если в команде указан флаг -base, следующий аргумент должен содержать время в виде целого числа. По этому числу определяется дата и используется вместо указанной в строке или текущей. Такая возможность полезна при необходимости перевести в целое число время на заданную дату.
Аргумент dateString должен состоять из одной или более спецификаций следующих видов:
Date ≈ Месяц, день и, возможно, год. Допустимые форматы mm/dd?/yy?, monthname dd?, yy?, dd monthname?yy? и day, dd monthname yy. По умолчанию год считается текущим годом. Если год меньше 100, то года 00-38 считаются годами в диапазоне 2000-2038, а года 70-99 считаются годами в диапазоне 1970-1999. Года 39-70 могут быть недопустимыми на некоторых платформах. Для тех платформ, для которых они определены, они считаются годами в диапазоне 1939-1999.
3 weeks. Кроме того, могут использоваться модификаторы: tomorrow, yesterday, today, now, last, this, next, ago.
Реальная дата вычисляется в следующей последовательности. Сначала определяется абсолютная дата и/или время, которые переводятся в целое число. Это число используется как базис, к которому добавляется заданный день недели. Далее используется относительное время. Если задана дата, а время (абсолютное или относительное) отсутствует, считается, что это полночь. И последним шагом производится коррекция вычисленной даты, при которой учитываются летнее время и число дней в различных месяцах.
close channelIdОПИСАНИЕ
Команда close закрывает канал, идентификатор которого задан аргументом channelId. Идентификатор channelId возвращается командами open и socket при открытии канала.Команда отправляет все накопившиеся в выходном буфере данные на выходное устройство канала, удаляет все данные во входном буфере, закрывает назначенное каналу устройство или файл. Доступ к каналу прекращается.
Для каналов в блокирующем и неблокирующем режимах действие команды несколько различно. Если канал находится в блокирующем режиме, команда завершается только после завершения вывода данных из буфера. В противном случае команда завершается немедленно, а вывод данных из буфера производится в фоновом режиме. Канал закрывается после завершения вывода.
Если канал в блокирующем режиме открыт для конвейера, команда close завершается после завершения порожденного процесса.
Если канал совместно используется несколькими интерпретаторами, то команда делает канал channelId недоступным в вызвавшем команду интерпретаторе, но не оказывает никакого другого действия на канал, пока все использующие канал интерпретаторы не закроют его. При выполнении команды в последнем из интерпретаторов, использовавших его, выполняются описанные выше действия. Подробности совместного использования канала несколькими интерпретаторами приведены в описании команды interp.
Команда close возвращает пустую строку. Она может порождать ошибку, если при выводе данных произошла ошибка.
concat
Команда соединяет списки в один общий список.СИНТАКСИС
concat?arg arg...?ОПИСАНИЕ
Аргументы arg считаются списками, команда concat объединяет их в один общий список. При этом она удаляет пробелы в начале и конце arg, и вставляет по одному пробелу между ними. Команда допускает произвольное число аргументов. Например, команда
concat a b {c d e} {f {g h}} возвращает списокa b c d e f {g h}
Если не задано никаких аргументов, то команда возвращает пустую строку.
СИНТАКСИСКоманда continue прекращает выполнение текущего шага цикла.
continue
continueОПИСАНИЕ
Обычно данная команда помещается внутрь цикла, например, созданного командами for, foreach или while. Команда возвращает код TCL_CONTINUE, который вызывает завершение текущей итерации наименьшего охватывающего ее цикла. Управление возвращается команде цикла, которая начинает следующий шаг цикла. Код TCL_CONTINUE обрабатывается также в некоторых других ситуациях ≈ при исполнении команды catch и в скрипте самого верхнего уровня.
СИНТАКСИСКоманда проверяет в канале условие конца файла.
eof
eof channelIdОПИСАНИЕ
Команда eof возвращает "1", если во время последней операции ввода в канале channelId произошло условие конца файла, и 0 ≈ в противном случае.
СИНТАКСИСКоманда генерирует ошибку.
error
error message?info??code?ОПИСАНИЕ
Команда возвращает код TCL_ERROR, прерывающий интерпретацию команды. Строка message возвращается приложению, чтобы указать, что именно произошло.Если задан непустой аргумент info, его значение присваивается глобальной переменной errorInfo.
Переменная errorInfo обычно используется для формирования сведений о вложениях команды, в которой произошла ошибка. Другими словами, как только оказывается, что невыполненная команда была вложена в другую команду, информацию об этой команде добавляется к errorInfo. Если же аргумент info был задан, этого не происходит. Эта особенность позволяет при использовании команды error совместно с командой catch выдать информацию о реальном месте ошибки (а не о месте вызова команды error). Дляэтого можно использовать следующую конструкцию:
Если задан аргумент code, то его значение будет присвоено глобальной переменной errorCode. Эта переменная предназначена для хранения машинного описания ошибки в тех случаях, когда такое описание возможно. Форматы различных сообщений приведены в разделе tell. Если аргумент не задан, переменной errorCode в процессе обработки Tcl-интерпретатором ошибки, порожденной командой, присваивается значение ``NONE''.catch {...} errMsg
set savedInfo $errorInfo
...
error $errMsg $savedInfo
eval
Команда исполняет Tcl-скрипт.
exec
Команда запускает подпроцессы.СИНТАКСИС
Если первые аргументы команды начинаются со знака '-', они считаются ключами команды, а не частью описания конвейера.
Возможные ключи:
- ≈ отмечает конец ключей. Аргумент, следующий за этим ключом, рассматривается как первый аргумент arg, даже если он начинается со знака '-'.
| ≈ разделяет команды в конвейере. Стандартный вывод предыдущей команды направляется на стандартный вход следующей команды.
|& ≈ разделяет команды в конвейере. Стандартный вывод и стандартный вывод ошибок предыдущей команды направляются на стандартный вход следующей команды. Такое выражение перебивает выражения типа "2>" и ">&".
< fileName ≈ файл fileName отрывается и используется как стандартный ввод для первой команды конвейера.
<@ fileId ≈ в этой форме fileId это идентификатор файла, открытого с помощью команды open. Он используется как стандартный ввод для первой команды конвейера. Файл должен быть открыт для чтения.
<< value ≈ value используется как стандартный ввод для первой команды конвейера.
> fileName ≈ Стандартный вывод последней команды перенаправляется в файл fileName и перезаписывает его содержимое.
2> fileName ≈ Стандартный вывод ошибок всех команд в конвейере перенаправляется в файл fileName и перезаписывает его содержимое.
>& fileName ≈ Стандартный вывод последней команды и стандартный вывод ошибок всех команд в конвейере перенаправляется в файл fileName и перезаписывает его содержимое.
>>fileName ≈ Стандартный вывод последней команды перенаправляется в файл fileName и добавляется к его прежнему содержимому.
>@ fileId ≈ в этой
форме fileId это идентификатор файла, открытого с помощью команды
open.
Стандартный вывод последней команды перенаправляется в файл fileName
и перезаписывает его содержимое. Файл должен быть открыт для записи.
>&@ fileId-
в этой форме
fileId это идентификатор файла, открытого с помощью
команды open. Стандартный вывод последней команды
и стандартный вывод ошибок всех команд в конвейере перенаправляется в файл
fileName
и перезаписывает его содержимое. Файл должен быть открыт для записи.
Если стандартный вывод последней команды конвейера не был перенаправлен, то команда exec возвращает его значение. Если одна из команд конвейера вернула код ошибки, была прервана или приостановлена, то команда exec вернет код ошибки. При этом сообщение об ошибке будет включать стандартный вывод конвейера и сообщение об ошибке. В переменной errorCode будет записана дополнительная информация о последней встреченной ошибке. Если хотя бы одна из команд конвейера пишет информацию об ошибках в файл и стандартный вывод ошибок не перенаправлен, команда exec вернет ошибку, сообщение об ошибке будет включать в себя стандартный вывод конвейера, дополненный сообщениями об ошибках (если их было несколько) и стандартным выводом ошибок.
Если последний символ результата
исполнения конвейера или сообщения об ошибке ≈ перевод каретки, то он будет
удален из результата или сообщения соответственно. Это соответствует общему
правилу Tcl, по которому возвращаемая величина, как правило, не оканчивается
символом перевода каретки. Однако, если указана опция -keepnewline,
символ перевода каретки в конце сохраняется.
Если стандартный ввод конвейера
не перенаправлен с помощью символов ``<'', ``<<'' или ``<@'',
стандартный ввод в первую команду конвейера осуществляется со стандартного
ввода приложения.
Если последним аргументом
конвейера является '&', конвейер выполняется в фоновом режиме. В этом
случае команда exec возвращает список идентификаторов всех процессов
конвейера. Стандартный вывод последней команды конвейера, если он не перенаправлен,
выводится на стандартный вывод приложения. Стандартный вывод ошибок, если
он не перенаправлен, осуществляется в стандартный вывод ошибок приложения.
Первое слово в каждой команде считается именем команды. В нем выполняются тильда ≈ подстановки. Если получившийся при этом результат не содержит слешей, соответствующая команда ищется в каталогах, перечисленных в переменной окружения PATH. Если имя команды после подстановок содержит слеши, оно должно указывать на исполняемый файл, доступный из текущего каталога. Никакие другие подстановки в командах, например, принятые в shell подстановки "*" и '?', не выполняются.
Windows (все версии)
В командах допускается использование как прямых, так и обратных слешей при указании пути команды. Однако, если путь является аргументом команды, это может оказаться и не так.
Двойной слеш в путях указывает на сетевой адрес.
expr
Выражения в Tcl отличаются
от выражений в С способом описания операндов. Кроме того, Tcl-выражения
поддерживают нечисловые операнды и сравнение строк.
Выражение Tcl состоит из комбинации операндов, операторов и скобок. Между ними всеми можно ставить пробелы, потому что при вычислении значения пробелы игнорируются. По возможности, все операнды интерпретируются как целые числа, если не задано иное. Целые числа могут быть десятичными числами (обычно), восьмеричными (если первая цифра числа есть 0) или шестнадцатеричными (если первые два символа числа ≈ 0х). Если операнд не подпадает ни под один из названных форматов, он считается числом с плавающей запятой, если это возможно. Числа с плавающей запятой можно задавать любым из способов, воспринимаемым совместимым с ANSI компилятором С. Исключение составляет запрет в большинстве версий на суффиксы f, F, l, и L. Примеры правильных чисел с плавающей запятой: 2.1, 3., 6e4, 7.91e+16. Если числовая интерпретация невозможна, то операнд считается строковым, и работать с ним может только ограниченный набор операторов.
Операнды могут быть заданы одним из следующих способов:
- числовым значением ≈ целым или с плавающей запятой;
- переменной Tcl, используя обычную нотацию со знаком "$". В качестве операнда будет использовано значение переменной;
- строкой символов, заключенной в двойные кавычки. Анализатор выражения выполнит подстановки переменных, подстановки команд и подстановки с обратным слешем; полученное значение будет использовано в качестве операнда;
- строкой, заключенной в фигурные скобки. Все символы между открывающей и закрывающей скобками будут считаться операндом без каких-либо подстановок;
- командой Tcl, заключенной в угловые скобки. Команда будет выполнена, и ее результат будет использован в качестве операнда;
- как вызов математической функции, аргумент которой может иметь любую из перечисленных выше форм, например sin($x). Список допустимых математических функций приведен ниже.
В качестве примеров рассмотрим простые выражения, в которых переменная a имеет значение '3', а значение переменной b есть '6'. Тогда выражение в левой части каждой строки даст значение в ее правой части:
3.1 + $a | 6.1 |
2 + ($a.$b) | 5.6 |
4*[llength (6 2)] | 8 |
{word one} < (word $a) | 0 |
Действующие операторы перечислены ниже в порядке убывания приоритетности исполнения.
- + ~ ! |
Унарный минус, унарный плюс, побитовое неравенство NOT, логическое NOT. Ни один из этих операторов не может быть использован со строковыми операндами, а побитовое NOT может использоваться только с целыми числами. |
* / % |
Умножить, разделить, остаток деления. Ни один из этих операторов не может быть использован со строковыми операндами, а оператор остатка может использоваться только для целых чисел. |
+ - |
Сложение и вычитание. Могут использоваться для любых числовых операндов. |
<< >> |
Сдвиг влево и вправо. Операторы можно использовать только с целыми числами. Сдвиг вправо также сдвигает и знаковый бит. |
< > <= >= |
Операторы булевой алгебры: меньше, больше, не больше, не меньше. Каждый оператор дает результат 1, если неравенство верно, и 0 ≈ в обратном случае. Кроме числовых операндов, операторы можно применять для строковых выражений, в этом случае выполняется сравнение строк. |
== != |
Булевские операторы: равно и не равно. Результат операции ≈ число 0 или 1. Операторы можно применять с любыми аргументами. |
& |
Оператор побитового AND. Используется только с целыми операндами. |
^ |
Оператор побитового исключающего OR. Применяется только с целыми числами. |
| |
Оператор побитового OR. Применяется только с целыми числами. |
&& |
Оператор логического AND. Результат равен 1, если оба операнда равны 1, и 0 ≈ в обратном случае. Операндами могут быть любые числа, как целые, так и с плавающей запятой. |
|| |
Оператор логического OR. Результат равен 0, если оба операнда равны 0, и 1 ≈ в обратном случае. Операндами могут быть любые числа, как целые, так и с плавающей запятой. |
x?y:z |
Конструкция if-then-else, подобная аналогичной конструкции в языке C. Операнд х должен иметь числовое значение. Если значение х не равно нулю, то результат команды будет у. В обратном случае результат будет z. |
Операторы одного уровня приоритета исполнения выполняются по очереди, слева направо. Например, команда
Подобно языку C, операторы '&&', '||', и '?:' имеют свойство ленивого вычисления, т.е., если операнд не нужен для получения результата, то он не вычисляется. Например, в команде
Tcl поддерживает в выражениях следующие математические функции:
acos |
cos |
hypot |
sinh |
asin |
cosh |
log |
sqrt |
atan |
exp |
log10 |
tan |
atan2 |
floor |
pow |
tanh |
ceil |
fmod |
sin |
|
Кроме них можно использовать также перечисленные ниже функции преобразования чисел и генерации случайных чисел.
abs(arg) ≈ возвращает абсолютное значение аргумента. Аргумент может быть целым или числом с плавающей точкой. Результат возвращается в такой же форме.
double(arg) √ переводит аргумент в десятичное число в плавающей точкой.
int(arg)√ переводит аргумент в целое число, обрезая дробную часть.
rand() √ возвращает
случайное десятичное число в интервале [0,1).
Исходное значение, используемое
при генерации, берется от внутренних часов или задается с помощью функции
srand.
round(arg) √ округляет число до целого.
srand(arg) √ аргумент, который должен быть целым числом, используется для генерации последовательности случайных чисел. Возвращает первое случайное число из последовательности. Каждый интерпретатор может использовать собственное значение и порождать собственную последовательность случайных чисел.
Пользовательские приложения
могут определять дополнительные функции, используя процедуру Tcl_CreateMathFunc().
Все внутренние вычисления с целыми числами выполняются с C-типом long, все внутренние вычисления с числами с плавающей запятой выполняются с C-типом double.
В общем случае, обнаружение переполнения и исчезновения значения при операциях с целыми числами зависит от поведения функций конкретной библиотеки С, и потому для промежуточных результатов не может считаться надежным. Переполнение и исчезновение значения при операциях с числами с плавающей запятой обнаруживаются на аппаратном уровне, что обычно надежно обеспечивается.
При необходимости выполняются преобразования внутренних представлений операндов между целыми, строковыми и с плавающей запятой. При арифметических вычислениях используются целые числа до тех пор, пока не будет подставлено или указано число с плавающей запятой. После этого тип данных будет с плавающей запятой.
Числа с плавающей запятой возвращаются либо с точкой, либо с буквой e, так что они заведомо не похожи на целые значения. Например:
expr 5 / ( [string length abcd] + 0.0 )
Выражение
Операторы сравнения могут работать со строковыми аргументами, хотя при вычислении выражений аргументы по возможности интерпретируются как целые или числа с плавающей запятой. Если один из операндов строковый, а другой ≈ число, то числовой операнд будет конвертирован в строковый. Например, обе команды
expr {0y < 0x12}
Если необходимо сравнить
аргументы именно как строки, а операнды могут быть восприняты неоднозначно,
то рекомендуется использовать команду string compare вместо операторов
вида '=='.
Байтовый компилятор Tcl генерирует наиболее быстрый и компактный код, если выражения заключать в скобки. Это связано с тем, что в общем случае, в выражениях подстановки выполняются дважды: один раз ≈ грамматическим анализатором Tcl, и второй раз ≈ командой expr. Наиболее трудным является случай, когда выражение без фигурных скобок содержит подстановки команд.
fblocked
Проверяет, что предыдущая операция ввода исчерпала всю информацию для ввода.СИНТАКСИС
fconfigure channelId name
fconfigure channelId name value?name value...?
Если аргумент newValue равен none, система ввода-вывода будет выводить каждый символ сразу после его поступления.
Значение по умолчанию full для всех каналов, кроме устройств типа терминалов. Для них значение по умолчанию line.
-eofchar {inChar outChar}
-translation{inMode outMode}
Аргумент mode задает представление конца строки для каналов, открытых только на чтение или только на запись. Список {inMode outMode} определяет представление конца строки для каналов ввода ≈ вывода. Пользователь может указать в списке единственный символ, который будет использоваться и для ввода, и для вывода. Однако, при запросе команда возвратит текущие установки в виде списка из двух одинаковых элементов.
Поддерживаются следующие значения опции:
auto
Копирует данные из одного канала в другой.
СИНТАКСИС
Команда fcopy передает данные из канала inchan, пока не будет достигнут конец файла или не будет передано size байтов. Если аргумент -size не задан, передается весь файл. Если опция -command не задана, команда блокирует процесс до завершения копирования и возвращает число переданных байтов.
При наличии аргумента -command команда fcopy работает в фоновом режиме. Она завершается немедленно, а команда callback вызывается позже, когда завершается процесс копирования. Команда callback вызывается с одним или двумя дополнительными аргументами, которые указывают число переданных байтов. Если при исполнении фонового процесса произошла ошибка, второй аргумент ≈ строка описания ошибки. При фоновом выполнении копирования каналы inchan и outchan не обязательно открывать в неблокирующем режиме, команда fcopy выполнит это автоматически. Однако при этом необходимо организовать обработку событий, например, с помощью команды vwait или используя Tk.
Не допускается выполнение других операций ввода ≈ вывода с теми же каналами во время фонового копирования. Если один из каналов во время копирования будет закрыт, процесс копирования будет прерван и вызова команды callback не произойдет. Если будет закрыт канал ввода данных, то все полученные данные, хранящиеся в очереди, будут выданы в выходной канал.
Необходимо отметить, что канал inchan может стать открытым на чтение во время копирования. Все обработчики файловых событий во время фонового копирования должны быть выключены, чтобы они не создавали помех копированию. Любые попытки ввода ≈ вывода с помощью обработчиков файловых событий будут завершены с ошибкой канал занят.
Команда fcopy преобразует
символы конца строк в соответствии со значениями опций -translation
для соответствующих каналов (см. описание команды fconfigure).
Преобразование означает, в частности, что число прочитанных и число переданных
символов может отличаться. В синхронном режиме команда возвращает только
число переданных в outchan канал символов. В фоновом режиме только
это число подается на вход команды callback.
global total
set total $bytes
close $in
сlose $out
if {[string length $error]!= 0} {
}
#### Открыть файл на чтение
set in [open $file1]
#### Открыть сетевое соединение
set out [socket $server $port]
#### Скопировать, по окончании копирования вызвать Cleanup
fcopy $in $out -command [list Cleanup $in $out]
#### Ожидать завершения копирования
vwait total
incr total $bytes
if {([string length $error]!= 0) || [eof $in] {
close $in
close $out
set in [open $file1]
set out [socket $server $port]
#### Установить размер фрагмента для копирования.
set chunk 1024
set total 0
fcopy $in $out -command [list CopyMore $in $out $chunk] -size $chunk
vwait done
Команда для работы с файлами и их именами.СИНТАКСИС
file attributes name?option?
file attributes name?option value option value...?
-owner ≈ возвращает или устанавливает имя хозяина файла. В команде хозяин может быть задан числовым идентификатором, но возвращается всегда имя хозяина.
-permissions возвращает или устанавливает восьмеричный код, используемый командой операционной системы chmod. Символьное описание соответствующих атрибутов файла не поддерживается.
НА WINDOWS-ПЛАТФОРМАХ
file
copy?-force??--? source target
file copy ?-force??--? source?source...? targetDir
Например:
Тильда-подстановки выполняются, только если они необходимы для формирования правильного результата.
Например:
Например:
Аргументы name могут содержать разделитель, это не помешает получить правильный результат для используемой платформы (/ для Unix и Windows, : для Macintosh).
file rename ?-force??--? source?source...? targetDir
На Unix-платформах эти команды всегда используют реальные, а не эффективные идентификаторы пользователя и группы.
См. также filemane.
fileevent
Исполняет скрипт, когда канал открывается на чтение или запись.СИНТАКСИС
fileevent channelId readable?script?ОПИСАНИЕfileevent channelId writable?script?
Эта команда используется для создания обработчиков файловых событий. Обработчик файловых событий связывает канал и скрипт таким образом, что скрипт исполняется, когда канал открывается на чтение или запись. Обработчики файловых событий используются, чтобы получение данных от другого процесса управлялось событиями. При этом получающий процесс, ожидая поступление данных, сможет продолжать взаимодействовать с пользователем. Если приложение выполняет команду get или read из блокирующего канала, оно не способно обслуживать другие события, поэтому оно кажется пользователю замороженным. С использованием файловых событий процесс обратится к команде get или read только когда информация поступит в канал.
Аргумент channelId должен быть идентификатором открытого канала, который вернула предыдущая команда open или socket. Если в команде присутствует аргумент script, команда создает новый обработчик событий: скрипт script будет выполнен, когда канал channelId откроется на чтение или запись (в зависимости от второго аргумента команды). В такой форме команда возвращает пустую строку. Обработчики для обработки открытия файла на чтение или запись соответственно независимы и могут создаваться и удаляться по одному, независимо один от другого. Однако для каждого из событий может быть только один обработчик, так что если команда fileevent выполняется, когда соответствующий обработчик (в текущем интерпретаторе) уже задан, новый скрипт заменит старый.
Если аргумент script не задан, команда fileevent возвратит скрипт, заданный для данного события для канала channelId, или пустую строку, если скрипт не задан. Обработчик событий удаляется автоматически при закрытии канала или удалении интерпретатора.
Канал считается открытым на чтение, если на соответствующем устройстве есть непрочитанные данные. Также канал считается открытым на чтение, если есть непрочитанные данные во входном буфере, кроме того случая, когда команда get не смогла найти в буфере законченную строку. Эта особенность позволяет читать файл построчно в неблокирующем режиме, используя обработчик событий. Канал также считается открытым на чтение, если достигнут конец соответствующего файла или на соответствующем устройстве сгенерирована ошибка. Поэтому скрипт должен уметь распознавать и корректно обрабатывать такие ситуации, чтобы не возникало зацикливаний, когда скрипт не может прочитать данные, завершается и тут же вызывается вновь.
Канал считается открытым на запись, если по крайней мере один байт данных может быть записан в соответствующий файл или передан на соответствующее устройство, или на устройстве (в файле) сгенерирована ошибка.
Событийно управляемый ввод ≈ вывод лучше всего работает с каналами, переведенными в неблокирующий режим с помощью команды fconfigure. В блокирующем режиме команды puts, get или read могут заблокировать процесс, если они не могут быть выполнены сразу (например, при попытке прочитать больше данных, чем доступно в настоящий момент). При этом никакой обработки событий не происходит. В неблокирующем режиме команды puts, get или read никогда не блокируют процесс. Детальное описание работы команд с блокирующими и неблокирующими каналами приведено в описаниях соответствующих команд.
Скрипт обработчика файловых событий выполняется на самом верхнем уровне вне контекста какой-либо процедуры в интерпретаторе, в котором обработчик событий был задан. Если при исполнении скрипта происходит ошибка, сообщение о ней выдается с помощью процедуры bgerror. Кроме того, при ошибке соответствующий обработчик событий удаляется. Это делается для того, чтобы избежать зацикливания из-за ошибок в обработчике.
filename
Правила именования файлов в Tcl.ВВЕДЕНИЕВведение Типы путей Синтаксис путей "Тильда"-подстановки Вопросы перносимости
Все имена файлов поделены на три типа, в зависимости от начальной точки для отсчета пути: абсолютные, относительные и имена внутри тома (volume-relative).СИНТАКСИС ПУТЕЙАбсолютные имена являются самодостаточными, они содержат полный путь файла внутри тома и адрес корневого каталога тома. Относительные имена являются неполными, они указывают положение файла по отношению к текущему каталогу. Имена внутри тома занимают промежуточное положение между первыми двумя, они указывают положение файла относительно корневого каталога текущего тома или относительно текущего каталога указанного тома.
Для определения типа указанного пути можно использовать команду file pathtype.
Пути формируются различным образом для различных платформ. Текущая платформа определяется по значению переменной tcl_platform(platform):
mac
/
В дополнение к правилам, описанным выше, Tcl позволяет использовать тильда -подстановки в стиле cshell. Если имя файла начинается с "~", за которой сразу следует сепаратор, она заменяется на значение переменной окружения $HOME. В противном случае символы от тильды до следующего разделителя интерпретируются как имя пользователя и заменяются на имя домашнего каталога пользователя.
На Macintosh- и Windows-платформах тильда-подстановки с именем пользователя не поддерживаются. При попытке использовать такое имя файла выдается ошибка. Однако тильда без имени пользователя заменяется, как и на Unix-платформах, на значение переменной окружения $HOME.ВОПРОСЫ ПЕРЕНОСИМОСТИ
flush
Команда организует немедленную выдачу выходных данных в канал.СИНТАНСИС
flush channelId
for
Команда for организует цикл.СИНТАНСИС
for start test next body
Команда for является командой цикла. По структуре команда for похожа на аналогичную команду языка С. Здесь аргументы start, next и body должны быть командными строками Tcl, а test ≈ строкой выражения. Сначала команда for запускает интерпретатор Tcl для выполнения start. Затем она вычисляет значение выражения test; если оно не равно нулю, то запускает Tcl-интерпретатор для выполнения body, затем next. Цикл повторяется до тех пор, пока test не станет равно 0. Если при выполнении body будет выполнена команда continue, то последующие команды в body пропускаются и начинает выполняться next, затем test и т.д. Если при исполнении body или next встретится команда break, исполнение команды for немедленно прекращается. Команда for возвращает пустую строку.
Замечание. Строку test почти всегда следует помещать в фигурные скобки. В противном случае подстановки переменных будут выполнены до выполнения команды. Из-за этого измененное в ходе цикла значение переменной может перестать передаваться в выражение, что может породить бесконечный цикл. Если же строка test заключена в фигурные скобки, подстановка значения переменных выполняется в каждом цикле. Для примера можно выполнить следующий скрипт со скобками и без скобок вокруг выражения $x<10:
foreach
Команда цикла по элементам одного или нескольких списков.СИНТАНСИС
Синтаксис Описание Примеры
foreach varlist1 list1?varlist2 list2...? body
В общем случае в команде может быть указано несколько списков значений (например, list1 и list2), и каждый из них может быть связан с одной переменной или со списком переменных цикла (например, varlist1 и varlist2). Во время каждой итерации переменные каждого списка переменных принимают значения последовательных элементов соответствующего списка значений. Значения из списков значений используются последовательно от первого до последнего, и каждое значение используется только один раз. Общее число итераций выбирается таким, чтобы использовать все значения из всех списков значений. Если список значений не содержит достаточного числа значений для всех связанных с ним переменных цикла, вместо недостающих элементов используются пустые значения.
Внутри скрипта body можно использовать команды break и continue, аналогично команде for.
Команда foreachвозвращает пустую строку.ПРИМЕРЫ
В цикле используются переменные цикла i и j для цикла по элементам одного списка
foreach {i j} {a b c d e f} {
При вычислении цикла используются три итерации.
В цикле переменные цикла i и j используются для различных списков значений.
foreach i {a b c} j {d e f g} {
При вычислении цикла используются четыре итерации.
Обе предыдущие формы скомбинированы в следующем цикле
foreach i {a b c} {j k} {d e f g} {
При вычислении цикла используются три итерации.
format
Команда форматирует строку в стиле процедуры sprintf.СИНТАНСИССинтаксиc Введение Процесс формирования Указатель позиции Флаги преобразования Минимальная ширина поля Точность Преобразователь длины Тип преобразования Отличия от ANSI SPRINTF
format formatString?arg arg...?ВВЕДЕНИЕ
Команда немного отличается от sprintf в части отдельных спецификаторов и ключей.ПРОЦЕСС ФОРМИРОВАНИЯ
Каждый из спецификаторов преобразования может содержать до шести различных частей: указатель позиции, набор флагов, минимальная ширина поля, точность, преобразователь длины и тип преобразования. Любые из полей, кроме типа преобразования, могут отсутствовать. Ниже обсуждаются соответствующие разделы спецификаторов.УКАЗАТЕЛЬ ПОЗИЦИИ
Если за символом "%" следуют целое число и знак "$", как например в "%2$d", то величина для преобразования берется не из следующего аргумента, а из аргумента, занимающего соответствующую позицию в списке ("1" соответствует первому аргументу arg). Если спецификатор преобразования требует нескольких аргументов (когда он содержит символ "*"), то используются последовательные аргументы, начиная с указанного. Если один из спецификаторов содержит указание позиции аргумента, то и все остальные спецификаторы должны его содержать.ФЛАГИ ПРЕОБРАЗОВАНИЯ
- | Указывает, что соответствующий аргумент будет выровнен влево (числа обычно выравниваются вправо с добавлением лидирующих пробелов при необходимости). |
+ | Указывает, что числа всегда будут вставлены со знаком, даже если они положительные. |
space | Указывает, что перед числом будет добавлен пробел, если первый символ не знак. |
0 | Указывает, что число будет выровнено с добавлением лидирующих нулей. |
# | Указывает на использование альтернативной формы вывода. Для "o" и "O" преобразований гарантирует, что первой цифрой всегда будет "0". Для "x" и "X" преобразований ≈ что 0x или 0X соответственно будет добавлен в начало числа. Для "e", "E", "f", "g", и "G" ≈ что в числе будет использована десятичная точка. Для "g" и "G" ≈ что конечные нули не будут отброшены. |
Четвертая часть спецификатора определяет точность представления чисел. Она состоит из точки и последующего числа. Число имеет различный смысл при различных преобразованиях. Для "e", "E" и "f" преобразования оно определяет число цифр справа от десятичной точки. Для "g" и "G" ≈ общее число чисел слева и справа от десятичной точки (однако, конечные нули будут обрезаться, если не указан флаг "#"). Для целочисленных преобразований оно определяет минимальное число символов (при необходимости будут добавляться лидирующие нули). Для "s" преобразований определяет максимальное число символов, которое будет выводиться. Если строка длиннее, конечные символы будут отброшены. Если точность указана как "*", а не как число, то в качестве числового значения используется значение следующего аргумента в команде.ПРЕОБРАЗОВАТЕЛЬ ДЛИНЫ
Последняя часть спецификатора представляет собой букву, которая определяет тип преобразования. Допускаются следующие значения.ОТЛИЧИЯ ОТ ANSI SPRINTF
d Преобразует целое число в десятичную строку со знаком. u Преобразует целое число в десятичную строку без знака. i Преобразует целое число в десятичную строку со знаком. Целое может быть десятичным, восьмеричным (с 0 вначале) или шестнадцатеричным (с 0x вначале). o Преобразует целое число в восьмеричную строку без знака. x or X Преобразует целое число в шестнадцатеричную строку без знака. Используются символы `0123456789abcdef'' для x и ``0123456789ABCDEF'' для X. c Преобразует целое число в восьмибитный символ, который оно представляет. s Не преобразует, но просто вставляет строку f Преобразует число с плавающей точкой в десятичное со знаком в форме xx.yyy, где число символов после запятой определяется точностью. e or E Преобразует число с плавающей точкой в число в экспоненциальной форме x.yyye╠zz, где число символов после запятой определяется точностью (по умолчанию 6). Для E в записи числа используется Eвместо e. g or G Если порядок числа меньше √4 или больше, чем точность, или равен точности, преобразует число с плавающей точкой как "%e" или "%E". В противном случае преобразует как "%f". % Просто подставляет символ "%".
Для числовых преобразований аргумент должен быть целым числом или десятичным с плавающей точкой. Аргумент преобразуется в двоичное число, а затем преобразуется обратно в строку в соответствии с указанным типом преобразования.
Поведение команды format отличается от процедуры sprintf в следующих моментах:"%p" и "%n" типы не поддерживаются
Для "%c" аргумент должен быть десятичным числом.
При преобразованиях длины значение l игнорируется.
Если при поиске конца строки был обнаружен конец файла, команда возвращает всю полученную информацию вплоть до конца файла.Если канал находится в неблокирующем режиме и поступила неполная входная строка, то команда не использует поступившие данные и возвращает пустую строку.
Если указана переменная varName и возвращается пустая строка из-за конца файла или из-за неполноты полученной строки, команда возвращает √1.
Обратите внимание, что если аргумент varName не задан, конец файла и неполная строка приведут к тому же результату, что и строка, состоящая из символа конца строки. Команды eof и fblocked позволяют различить эти ситуации.
Команда возвращает имена файлов, удовлетворяющих шаблону.СИНТАКСИС
Команда glob выполняет поиск имен файлов подобно тому, как это делает оболочка csh, и возвращает список имен, удовлетворяющих шаблону pattern. Аргументы, начинающиеся со знака "-", являются управляющими ключами switches.
-nocomplain
? √ Удовлетворяет любому символу;
* ≈ Удовлетворяет любой последовательности из нуля или больше символов;
[chars] √ Удовлетворяет любому символу из chars. Если chars включает последовательность символов типа "a-b", то удовлетворяет всем символам от "a" до "b" (включительно).
\x √ Удовлетворяет символу "x".
{a,b,...}
√ Удовлетворяет любой из строк "a", "b", и т.д.
Если первый символ образца "~", то он указывает на домашний каталог пользователя, чье имя указано после "~". Если сразу после "~" идет "/", то используется значение переменной окружения HOME.
Действие команды glob отличается от работы в csh в следующем:
- она не сортирует составленный ей список;
- она возвращает имена только существующих файлов (в csh проверку наличия файлов надо задавать отдельно, если только шаблон не содержит символов "?", "*", или "[]").
В отличие от другихTcl-команд команда glob может работать с именами файлов только в нотации, поддерживаемой на той платформе, на которой она исполняется. Кроме того, на Windows-платформах специальные символы не допустимы в сетевых именах.
Команда для объявления глобальных переменных.СИНТАКСИС
Данная команда выполняется только при выполнении процедуры, а в остальных случаях игнорируется. Команда объявляет переменныеvarname глобальными. Глобальные переменные ≈ это переменные глобальной области имен.
Только в течение работы данной процедуры и только при выполнении в данной процедуре любая ссылка на значение любого из аргументов varname будет указывать на одноименную глобальную переменную.
history
Число. Если положительное ≈ ссылается на событие с этим номером (все события нумеруются начиная с 1). Если число отрицательное, то оно указывает номер события относительно текущего ("-1" ≈ предыдущее, "-2" ≈ перед предыдущим и т.д.). Событие "0" ссылается на текущее событие.
Строка. Ссылается на наиболее позднее событие, которое удовлетворяет строке. Событие удовлетворяет строке, если оно начинается со строки, или в соответствии с правилами команды string match.
Команда history может принимать одну из следующих форм.
history
history addcommand?exec?
history info?count?
До версии 8.0 Tcl имел весьма сложный механизм переформирования журнала. Новый механизм несколько сокращен за счет старых опций substitute и words. (Взамен добавлена новая опция clear)Опция redo позволяет переформировывать журнал значительно проще. При ее выполнении последнее событие изменяется таким образом, что удаляется служебная команда history, которая реально выполнялась, а вместо нее записывается та команда, которая необходима.
Если вы хотите повторить прежнюю команду, не модифицируя журнал, выполните сначала команду history event, чтобы извлечь описание команды, а затем history add, чтобы выполнить ее.
if
Команда if проверяет соблюдение условия в ходе выполнения скрипта.
Слова then и else необязательны и используются только для простоты понимания команды. Аргумент bodyNтакже может отсутствовать, если отсутствует else.
Команда возвращает значение
выполненного скрипта или пустую строку, если ни одно из выражений не было
равно true, и bodyN отсутствовал.
incr
info
Команда сообщает сведения о состоянии интерпретатора Tcl.СИНТАКСИС
info option?arg arg...?ОПИСАНИЕ
Эта команда обеспечивает доступ к внутренней информации Tcl-интерпретатора. Ниже перечислены поддерживаемые опции (имена которых могут быть сокращены).
info argsprocname
info cmdcount
Аргумент procname должен быть именем Tcl-процедуры, а аргумент arg ≈ именем одного из аргументов этой процедуры. Если указанный аргумент не имеет значения по умолчанию, команда возвращает "0". В противном случае команда возвращает "1" и помещает значение по умолчанию в переменную varname.
info exists varName
Если аргумент pattern не задан, возвращает список имен всех видимых в текущий момент переменных, включая локальные и видимые глобальные. Если аргумент pattern задан, возвращается список только тех имен, которые удовлетворяют шаблону pattern. Правила использования шаблонов такие же, как в команде string match. Шаблон может быть полным именем, например Foo::option*. То есть он может задавать определенное пространство имен и шаблон в нем. В этом случае каждая команда в возвращаемом списке будет представлена полным именем с указанием пространства имен.
Команда создает и управляет Tcl-интерпретаторами.СИНТАКСИС
interp option?arg arg...?ОПИСАНИЕ
Эта команда позволяет создавать один или несколько новых Tcl-интерпретаторов, которые сосуществуют в одном приложении с создавшим их интерпретатором. Создавший интерпретатор называется мастер-интерпретатором, а созданные интерпретаторы называются подчиненными (slave) интерпретаторами. Мастер-интерпретатор может создавать произвольное число подчиненных интерпретаторов, а каждый из подчиненных может в свою очередь создавать подчиненные интерпретаторы, для которых он сам является мастер-интерпретатором. В результате в приложении может создаваться иерархия интерпретаторов.
Каждый интерпретатор независим от остальных. Он имеет собственное пространство имен для команд, процедур и глобальных переменных. Мастер-интерпретатор может создавать связи между подчиненными интерпретаторами и собой, используя механизм алиасов. Алиас ≈ это команда в подчиненном интерпретаторе, которая, при ее вызове, вызывает другую команду в мастер-интерпретаторе или в другом подчиненном интерпретаторе. Кроме механизма алиасов, связь между интерпретаторами поддерживается только через переменные окружения. Массив envобычно является общим для всех интерпретаторов в приложении. Необходимо заметить, что идентификаторы каналов (например, идентификатор, возвращаемый командой open) больше не разделяются между интерпретаторами, как это было в предыдущих версиях Tcl. Чтобы обеспечить совместный доступ к каналам, необходимо использовать явные команды для передачи идентификаторов каналов из интерпретатора в интерпретатор.
Команда interp позволяет также создавать надежные интерпретаторы. Надежный интерпретатор ≈ это интерпретатор с существенно урезанной функциональностью, поэтому он может исполнять ненадежные скрипты без риска нарушить работу вызывающего их приложения. Например, из безопасных интерпретаторов недоступны команды создания каналов и подпроцессов. Более подробно см. Безопасные интерпретаторы. Опасная функциональность не удалена из безопасных интерпретаторов, но скрыта таким образом, что только надежные интерпретаторы могут получить к ней доступ. Более подробно см. Скрытые команды. Механизм алиасов может быть использован для безопасного взаимодействия между подчиненным интерпретатором и его мастер-интерпретатором. Более подробно этот вопрос обсуждается в разделе "Использованиеалиасов".
Полное имя интерпретатора представляет собой список, содержащий имена его предков в иерархии интерпретаторов и заканчивающийся именем интерпретатора в его непосредственном предке. Имена интерпретаторов в списке ≈ это их относительные имена в их непосредственных мастер-интерпретаторах. Например, если a есть подчиненный интерпретатор текущего интерпретатора и, в свою очередь, имеет подчиненный интерпретатор a1, а тот, в свою очередь, имеет подчиненный интерпретатор a11, то полное имя a11 в a есть список {a1 a11}.
В качестве аргумента описанной ниже команды interp используется полное имя интерпретатора. Интерпретатор, в котором исполняется команда, всегда обозначается как {} (пустая строка). Обратите внимание, что в подчиненном интерпретаторе невозможно сослаться на мастер-интерпретатор кроме как через алиасы. Также нет никакого имени, под которому можно было бы сослаться на мастер-интерпретатор, первым созданный в приложении. Оба ограничения вызваны соображениями безопасности.КОМАНДА INTERP
Команда interp используется для создания, удаления и выполнения команд в подчиненном интерпретаторе, а также для разделения или передачи каналов между интерпретаторами. Она может иметь одну из перечисленных ниже форм в зависимости от значения аргумента option.
interp alias srcPath srcCmd
Эта команда создает алиас между двумя подчиненными интерпретаторами (для создания алиаса между подчиненным интерпретатором и мастер-интерпретатором используется команда slave alias). Оба интерпретатора srcPath и targetPath должны быть в иерархии интерпретаторов ниже того интерпретатора, в котором выполняется команда. Аргументы srcPath и srcCmd задают интерпретатор, в котором будет создан алиас и его имя. Аргумент srcPath должен быть Tcl-списком, задающим имя существующего интерпретатора. Например, a b'' определяет интерпретатор b, который является подчиненным интерпретатором интерпретатора a, который в свою очередь является подчиненным интерпретатором текущего интерпретатора. Пустой список соответствует текущему интерпретатору (в котором исполняется команда). Аргумент srcCmd определяет имя новой команды-алиаса, которая будет создана в интерпретаторе srcPath. Аргументы targetPath и targetCmd определяют целевой интерпретатор и команду, а аргументы arg, если они есть, определяют дополнительные аргументы для команды targetCmd, которые будут вставлены перед аргументами, заданным при вызове srcCmd. Команда targetCmd может как существовать, так и не существовать в момент создания алиаса. В последнем случае она не создается командой interp alias.
Команда interp create
возвращает имя нового интерпретатора. Имя подчиненного интерпретатора должно
быть уникальным среди подчиненных интерпретаторов его мастера. Если у мастер-идентификатора
уже существу
Для каждого подчиненного интерпретатора, созданного с помощью команды interp, в мастер-интерпретаторе создается команда с тем же именем, что и подчиненный интерпретатор. Эта команда предназначена для выполнения различных операций в подчиненном интерпретаторе. В общем случае она имеет следующий вид:
slave command?arg arg...?БЕЗОПАСНЫЕ ИНТЕРПРЕТАТОРЫгде slave ≈ имя подчиненного интерпретатора, а аргументы command и arg arg... определяют конкретное назначение команды. Ниже перечислены возможные формы команды.
slave aliases
slave alias srcCmd Возвращает список всех алиасов в подчиненном интерпретаторе slave. Возвращаемые имена ≈ это имена, использовавшиеся при создании соответствующих алиасов. Они могут не совпадать с текущими именами команд, если те были переименованы. slave alias srcCmd {} Возвращает список, состоящий из имени реальной команды и ее аргументов, ассоциированных с алиасом srcCmd. Возвращаются те же значения, что и в команде создания алиаса. Если созданный алиас был переименован, то в команде надо указывать имя srcCmd, которое использовалось при создании алиаса. slave alias srcCmd targetCmd?arg..? Удаляет алиас srcCmd в подчиненном интерпретаторе. Аргумент srcCmd указывает имя алиаса в момент создания. Если после этого он был переименован, удалится переименованная команда. slave eval arg?arg..? Эта команда создает команду ≈ алиас в подчиненном интерпретаторе. Каждый раз, когда в подчиненном интерпретаторе будет вызываться команда srcCmd, реально выполняться будет команда targetCmd в мастер-интерпретаторе. Аргументы arg, если они есть, определяют дополнительные аргументы для команды targetCmd, которые будут вставлены перед аргументами, заданными при вызове srcCmd. Подробнее см. Использование алиасов. slave expose hiddenName?exposedCmdName? Эта команда объединяет все свои аргументы так же, как команда concat, и выполняет сформированный таким образом скрипт в подчиненном интерпретаторе. Результат выполнения (включая информацию об ошибках в переменных errorInfoи errorCode, если произошла ошибка) возвращается в вызывающий интерпретатор. slave hide exposedCmdName?hiddenCmdName? Разрешает использование в подчиненном интерпретаторе скрытой команды hiddenName под новым именем exposedCmdName (в настоящее время поддерживаются только имена в глобальном пространстве имен, не содержащие ::). Если обычная (не скрытая) команда exposedCmdName уже существует, генерируется сообщение об ошибке. Скрытые команды обсуждаются ниже (см. Скрытые команды ). slave hidden Запрещает использование в подчиненном интерпретаторе обычной команды exposedCmdName и переименовывает ее в скрытую команду hiddenCmdName (или в скрытую команду под старым именем, если новое не было задано). Если скрытая команда с заданным именем уже существует, команда возвращает ошибку. В настоящее время exposedCmdName и hiddenCmdName не могут содержать ::. Команды, которые должны быть скрыты с помощью interp hide, ищутся только в глобальном пространстве имен, даже если текущее пространство имен не глобальное. Скрытые команды обсуждаются ниже (см. Скрытые команды ). slave invokehidden?-global hiddenName?arg..? Возвращает список скрытых команд в подчиненном интерпретаторе. slave issafe Вызывает в подчиненном интерпретаторе скрытую команду hiddenCmdName с перечисленными аргументами. Никаких подстановок или вычислений в аргументах не производится. Если указана опция -global, скрытая команда выполняется на глобальном уровне в подчиненном интерпретаторе. В противном случае она выполняется в текущем контексте и может использовать значения локальных переменных и переменных из вышестоящих стеков. Скрытые команды обсуждаются подробно в соответствующем разделе ниже. slave marktrusted Возвращает "1", если подчиненный интерпретатор безопасный, и "0" в противном случае. Отмечает подчиненный интерпретатор как надежный. Не раскрывает скрытые команды. Команда может выполняться только из надежного интерпретатора. Если подчиненный интерпретатор уже надежный, команда не оказывает никакого воздействия.
Безопасный интерпретатор ≈ это интерпретатор с ограниченной функциональностью. Поэтому в нем можно без опасений выполнять произвольные скрипты, даже написанные вашим злейшим врагом, не опасаясь нарушить выполнение вашего приложения или испортить содержимое дисков вашего компьютера. Чтобы обеспечить безопасность, из таких интерпретаторов удалены определенные команды и переменные. Например, команда создания файлов на диске и команда запуска подпроцессов. Тем не менее, в безопасном интерпретаторе можно обеспечить ограниченный доступ к подобным командам с помощью механизма алиасов. В результате при выполнении потенциально опасных команд будут вызываться специально написанные процедуры в мастер-интерпретаторе, которые могут тщательно проверять заданные аргументы и позволять использовать только ограниченный набор средств. Например, создание файлов может быть разрешено только в ограниченном наборе подкаталогов, а запуск подпроцессов разрешен только для ограниченного (и фиксированного) набора хорошо проверенных программ.
Чтобы создаваемый интерпретатор был безопасным, необходимо при его создании указать опцию -safe. Кроме того, любой интерпретатор, созданный из безопасного интерпретатора, также будет безопасным.
Безопасный интерпретатор создается со следующим набором команд:
Следующие команды в безопасном интерпретаторе скрыты:
ИСПОЛЬЗОВАНИЕ АЛИАСОВ
cd exec exit fconfigure file glob load open pwd socket source Эти команды могут быть созданы заново как Tcl-процедуры или алиасы или разрешены к использованию с помощью команды interp expose.
Сверх того, в безопасных интерпретаторах отсутствует массив env, содержащий обычно переменные окружения. Это связано с тем, что в переменных окружения может храниться конфиденциальная информация.
Расширения, загружаемые в безопасный интерпретатор, также обладают ограниченной функциональностью. Более подробно эти вопросы обсуждаются в пп. Safe-Tcl и load .
Механизм алиасов весьма тщательно спроектирован таким образом, чтобы он позволял без опасений выполнять ненадежные скрипты в безопасных подчиненных интерпретаторах, используя для алиасов проверенные команды в мастер-интерпретаторах. Для обеспечения безопасности принципиально важно, чтобы информация из подчиненного интерпретатора никогда не обрабатывалась (то есть скрипты не исполнялись, и в них не производились подстановки) в мастер-интерпретаторе. В противном случае всегда будет оставаться возможность написать такой скрипт для подчиненного интерпретатора, который выполнил бы произвольные действия в мастер-интерпретаторе и мог бы нарушить его безопасность.СКРЫТЫЕ КОМАНДЫКогда в подчиненном интерпретаторе вызывается команда-алиас, необходимые Tcl-подстановки в аргументах выполняются там же, как для обычной Tcl-команды. После этого аргументы объединяются с целевой командой и ее аргументами, определенными при создании алиаса. Так, если команда вызова алиаса имела вид ``srcCmd arg1 arg2... argN'', то сформируется команда `targetCmd arg arg... arg arg1 arg2... argN'', где arg arg... arg √ аргументы, указанные при создании алиаса. После этого сформированная команда выполняется в целевом интерпретаторе (со сформированным набором аргументов). Если в целевом интерпретаторе нет команды targetCmd, будет сгенерирована ошибка. Перед выполнением команды в целевом интерпретаторе больше никаких подстановок в аргументах произведено не будет. Команда будет вызвана напрямую, а не через обычный механизм выполнения. Таким образом, подстановки в каждом слове команды оказываются выполненными ровно один раз: в targetCmd и arg... arg √ при выполнении команды, с помощью которой был создан алиас, а в arg1 ≈ argN ≈ при анализе команды алиаса в соответствующем интерпретаторе.
При написании процедуры targetCmd, которую предполагается использовать для алиаса в безопасном интерпретаторе, нужно придерживаться следующего правила. Недопустимо, чтобы в значениях ее аргументов в теле процедуры производились подстановки, либо чтобы аргументы были скриптами, исполняемыми в теле процедуры. Нарушение этого правила дает возможность подчиненному интерпретатору выполнить произвольный код в мастер-интерпретаторе и нарушить, таким образом, безопасность системы.
Безопасные интерпретаторы существенно ограничивают функциональные возможности выполняемых в них Tcl-скриптов. С одной стороны, это позволяет избежать нежелательных последствий при их исполнении, но, с другой стороны, рано или поздно возникает насущная необходимость выполнить потенциально опасную команду в безопасном интерпретаторе. Например, прочитать дополнительный скрипт с помощью команды source. Или выполнить в Tk-приложении некоторые команды управления окнами.Команда interp обеспечивает решение этой проблемы с помощью механизма скрытых команд. Потенциально опасные команды не удаляются из безопасного интерпретатора, а становятся скрытыми. При этом их невозможно выполнить из скрипта, выполняемого внутри интерпретатора. Но их можно выполнить извне из любого надежного предка интерпретатора с помощью команды interp invoke. Скрытые и обычные (не скрытые) команды размещаются в различных пространствах имен. Это позволяет иметь в одном интерпретаторе скрытую и обычную команды с одним и тем же именем.
Скрытые команды могут использоваться в теле процедуры, использованной при определении алиаса. Например, в подчиненном интерпретаторе можно создать алиас source. Вызываемая при этом процедура в мастер-интерпретаторе проверяет допустимость запрошенной операции (например, что запрошенный файл находится в соответствующем каталоге, к которому разрешен доступ из подчиненного интерпретатора) и вызывает в подчиненном интерпретаторе скрытую команду source. Обратите внимание, что в этом случае в подчиненном интерпретаторе существует две команды source: скрытая и алиас.
Из мастер-интерпретатора возможен вызов скрытых команд подчиненного интерпретатора через механизм алиасов. Поэтому в теле процедур, предназначенных для создания алиаса, необходимо избегать подстановок и команд исполнения для аргументов. См. Использование алиасов .
Безопасные интерпретаторы не могут изнутри вызвать скрытую команду в себе или своих потомках.
Множество скрытых команд может быть изменено из надежного интерпретатора с помощью команд interp expose и interp hide. Безопасный интерпретатор не может изменить набор скрытых команд в себе или своих потомках.
В настоящее время имена скрытых команд не могут содержать имени пространства имен. Поэтому, прежде чем скрыть команду, ее надо перевести в глобальное пространство имен. Команды, которые необходимо скрыть, должны находиться в глобальном пространстве имен. Это позволяет избежать ошибочного скрытия одноименной команды из другого пространства имен.
auto_mkindex dir pattern pattern
Местонахождение библиотеки Tcl можно получить с помощью команды info library. Обычно, помимо этой библиотеки, приложения имеют собственные библиотеки служебных процедур. Местонахождение процедур приложения обычно содержит глобальная переменная $app_library, где app ≈ имя приложения. Например, для Tk это переменная $tk_library.
Для того, чтобы использовать процедуры из Tcl-библиотеки, приложению необходимо прочитать файл init.tcl библиотеки, например, командой
source [file join [info library] init.tcl]
Если в приложении процедура Tcl_AppInit вызывает библиотечную процедуру Tcl_Init, то такая команда выполняется автоматически. Код в файле init.tcl определит процедуру unknown и позволит остальным процедурам загружаться по требованию при помощи механизма автозагрузки, описанного ниже.
auto_execok cmd
В каждом из каталогов, входящих в путь автозагрузки, должен находиться файл tclIndex, список команд, определенных в этом каталоге, и скрипты для загрузки каждой команды. Файл tclIndex должен быть создан с помощью команды auto_mkindex.
Команда auto_load читает индексные файлы только один раз и сохраняет полученную информацию в массиве auto_index. При последующих обращениях к команде auto_load сначала проверяется массив и только если информация о процедуре не найдена, приступает к просмотру индексных файлов. Эта информация может быть удалена с помощью команды auto_reset. После команды auto_reset следующий вызов auto_load к повторному чтению индексных файлов.
auto_mkindexdir pattern pattern...
Команда auto_mkindex просматривает Tcl-скрипты очень простым способом: если в очередной строке, начиная с первого символа, написано слово proc, считается, что это определение процедуры, а следующее слово есть имя процедуры. Процедуры, определение которых не подходит под описанное (например, если перед словом proc стоят пробелы), не попадают в индексный файл.
auto_execs ≈ используется командой auto_execok для записи информации о том, существуют ли конкретная команда в виде исполняемого файла.
auto_index ≈ используется auto_load для сохранения индексной информации, считанной с диска.
auto_noexec ≈ если переменная задана с любым значением, то команда unknown не будет пытаться автоматически исполнить какую-либо команду.
auto_noload ≈ если переменная задана с любым значением, то команда unknown не будет пытаться автоматически загрузить какую-либо команду.
auto_path ≈ если переменная задана, то она должна содержать Tcl-список с каталогами для просмотра при операциях автозагрузки.
env(TCL_LIBRARY) ≈ если переменная задана, то она указывает местоположение каталога с библиотечными скриптами (команда info library возвращает значение этой переменной). Если переменная не определена, то используется значение по умолчанию.
env(TCLLIBPATH) ≈ если переменная задана, то она должна содержать действующий Tcl список каталогов для поиска при операциях автозагрузки. Эта переменная используется только тогда, когда не определена переменная auto_path.
tcl_nonwordchars ≈ переменная содержит регулярное выражение, используемое такими процедурами, как tcl_endOfWord для определения, является ли символ частью слова или нет. Если образец соответствует символу, то символ считается не принадлежащим к слову. В Unix такими символами являются все символы, кроме цифр, букв и символа подчеркивания.
tcl_wordchars ≈ переменная содержит регулярное выражение, используемое такими процедурами, как tcl_endOfWord для определения, является ли символ частью слова или нет. Если образец соответствует символу, то символ считается частью слова. В Unix слова состоят из цифр, букв и символа подчеркивания.
unknown_active ≈ эта
переменная служит флагом для индикации активности команды unknown:
команда сама устанавливает ее. Переменная используется для выявления ошибок,
при которых unknown бесконечно рекурсивно
обращается к себе. Перед окончанием работы unknown
переменная
сбрасывается.
Если index отрицательное число или больше или равно числу элементов, команда возвращает пустое значение. Если значение аргумента index равно end, команда возвращает последний элемент списка.
Команда служит для вставки элементов в список.
ОПИСАНИЕ
Если индекс index меньше
или равен нулю, новые элементы вставляются в начало списка. Если индекс
index
больше или равен числу элементов в списке или равен end, новые элементы
вставляются в конец списка.
list
Команда list несколько отличается от команды concat: тем, что команда concat удаляет один уровень группирования перед образованием списка, тогда как команда list работает непосредственно с исходными аргументами. Например, команда
list a b {c d e} {f {g h}}
load
load fileName packageName
load fileName packageName interp
Как только файл загружен в адресное пространство приложения, вызывается одна из двух процедур инициализации нового кода. Обычно процедура инициализации добавляет в интерпретатор новые Tcl-команды. Имя процедуры определяется исходя из имени библиотеки и из того, является интерпретатор, в который будут добавляться команды, безопасным (см. команду interp). Для обычного интерпретатора имя процедуры pkg_Init, где pkg ≈ имя библиотеки, преобразованное следующим образом: Первая буква переведена в верхний регистр, а все остальные ≈ в нижний. Например, если имя библиотеки Foo, то имя инициализационной процедуры должно быть Foo_Init.
Для безопасного интерпретатора имя процедуры должно быть pkg_SafeInit. Эта функция должна быть написана очень тщательно, чтобы позволить включить в безопасный интерпретатор только те команды библиотеки, которые безопасны при использовании в ненадежном коде. Дополнительная информация приведена в п. Safe.
Процедура инициализации должна соответствовать следующему прототипу:
typedef int Tcl_PackageInitProc(Tcl_Interp *interp);
Аргумент interp определяет интерпретатор, в который библиотека будет загружена. Процедура инициализации должна вернуть код TCL_OK или TCL_ERROR чтобы указать, была ли она завершена успешно. В случае ошибки она должна присвоить переменной interp->result значение указателя на сообщение об ошибке. Результат процедуры инициализации будет возвращен командой load как ее результат.
Реально каждый файл загружается в приложение только один раз. Если команда load вызывается несколько раз, чтобы загрузить один и тот же файл в различные интерпретаторы, то реально загрузка кода выполняется только в первый раз. При последующих вызовах будет выполняться только процедура инициализации библиотеки в соответствующем интерпретаторе. Выгрузить или повторно загрузить библиотеку невозможно.
Команда load также поддерживает библиотеки, статически связанные с приложением, если они зарегистрированы с использованием процедуры Tcl_StaticPackage. Если аргумент fileName есть пустая строка, то необходимо указывать имя библиотеки.
Если аргумент packageName отсутствует или равен пустой строке, Tcl пытается сам сформировать имя библиотеки. На разных платформах это выполняется по-разному. На Unix-платформах обычно для этого берется последний элемент имени файла. Если первые три буквы в нем ≈ lib, то они отбрасываются. После чего берутся все последовательные символы, которые являются буквами или символом подчеркивания. Например, если имя файла libxyz4.2.so, то в качестве имени библиотеки будет сформировано xyz, а при исполнении команды
load bin/last.so {}
Если аргумент fileName равен пустой строке, то должен быть задан аргумент packageName. Команда load в таком случае ищет сначала статически загружаемую библиотеку (то есть, библиотеку, зарегистрированную с помощью процедуры Tcl_StaticPackage) с указанным именем. Если такая будет найдена, то она используется в команде. В противном случае ищется динамически загружаемая процедура с этим именем. Если загружено несколько версий одной и той же библиотеки, то Tcl выбирает ту, которая была загружена первой.
lrange
Команда
Каждый аргумент element
становится
отдельным элементом списка. Если не было задано ни одного аргумента element,
тогда прежние элементы списка с first по last будут просто
удалены.
-exact
Значение по умолчанию -glob.
Команда сортирует элементы списка.
-ascii
Словарный режим. Тоже, что и -ascii, но со следующими отличиями:
-integer
Сортировка в порядке убывания (от больших к меньшим).
-index index
lsort -integer -index 1 {{First
24} {Second 18} {Third 30}}
вернет {Second 18} {First
24} {Third 30}.
Эта опция значительно
более эффективна для данной задачи, чем опция -command с соответствующей
процедурой сравнения.
namespace children?namespace??pattern?
set script [namespace code {foo bar}]
выполняется в пространстве имен ::a::b. Тогда команда
eval $script x y
может быть выполнена в любом пространстве имен и будет иметь тот же эффект, что и команда
namespace eval ::a::b {foo bar x y}.
Эта команда необходима потому, что расширения Tcl, например, Tk, обычно выполняют вызванные по событиям скрипты в глобальном пространстве имен. Обертывающая команда захватывает необходимую команду вместе с ее пространством имен и позволяет корректно выполнить ее позже по соответствующему вызову. Примеры использования данного механизма приведены ниже см. Правила видимости имен.
эквивалентна
namespace eval ::foo [concat
a [list x y z]]
namespace origincommand
Пространство имен ≈ это обособленный набор команд и переменных. Содержащиеся в нем команды и переменные не взаимодействуют с командами и переменными в других пространствах имен. В Tcl всегда был один такой набор, который мы будем называть глобальным пространством имен. В нем содержатся все глобальные переменные и команды. Команда namespace eval позволяет создавать другие пространства имен, например, команда
variable num 0
proc Bump {} {
incr num
}
Переменные пространства имен напоминают глобальные переменные. Они существуют вне процедур, но могут использоваться в процедурах с помощью команды variable, как показано в предыдущем примере.
Пространства имен ≈ динамические образования. В них можно в любой момент добавлять команды и переменные с помощью дополнительных команд namespace eval. Например, то же пространство имен, что и в предыдущем примере, можно было создать с помощью последовательности команд:
proc Bump {} {
return [incr num]
namespace eval Counter {
}
Пространства имен могут иметь
собственные вложенные пространства имен и образовывать иерархию пространств
имен. Вложенное пространство имен содержится в своем предке и не может
взаимодействовать с другими пространствами имен.
Каждое пространство имен имеет собственное имя, например history или ::safe::interp. Полные имена используются для указания команд, переменных или подпространств имен, содержащихся в соответствующем пространстве имен. Полные имена напоминают полные имена файлов в Unix или виджетов в Tk, но в качестве разделителей в них используется не слеш или точка, а двойное двоеточие ::. Самое верхнее или глобальное пространство имен имеет имя " (пустая строка) и "::" как синоним. Как пример, имя ::safe::interp::create ссылается на команду create в пространстве имен interp, которое является подпространством пространства имен ::safe, которое в свою очередь является подпространством глобального пространства имен ::.
Если вы хотите указать команду или переменную в другом пространстве имен, вы можете указать имя пространства имен, в котором она содержится. Например, из глобального пространства имен вызвать процедуру из пространства имен Counter можно следующим образом:
Counter::Reset
Все Tcl-команды, которые работают с именами переменных и команд, поддерживают полные имена. Это значит, что можно использовать полные имена в таких командах, как set, proc, rename, или interp alias. Если вы используете абсолютное имя, начинающееся с ::, то такое имя всегда интерпретируется однозначно. Однако, если вы используете относительное имя, не начинающееся с ::, поиск объекта с соответствующим именем происходит по следующим правилам: команды и переменные сначала ищутся в текущем пространстве имен, а затем (если не найдены) ≈ в глобальном. Имена пространств имен ищутся только в текущем пространстве имен.
В следующем примере
namespace eval Debug {
namespace eval Foo {
namespace eval Debug {
Чтобы разобраться в сложных
ситуациях, можно использовать команду namespace which. Например,
следующая команда:
Как уже упоминалось, относительные имена пространств имен ищутся иначе, чем имена команд и переменных. Они ищутся только в текущем пространстве имен. Это значит, что, например, команда namespace eval всегда создает потомка текущего пространства имен, если только имя нового пространства не начинается с ::.
Tcl не ограничивает доступ к командам, переменным или пространствам имен. Если вы указали имя, которое в соответствие с перечисленными выше правилами ссылается на нужный вам элемент, вы можете использовать этот элемент.
Переменные, определенные
в данном пространстве имен, можно использовать в процедурах в этом же пространстве
имен с помощью команды
variable. Похожая
на команду
global, эта команда создает связь
между локальной переменной в процедуре и одноименной переменной в пространстве
имен. Если необходимо, эта команда также создает и инициализирует эту переменную
(команда global только создает связь с переменной
в глобальном пространстве имен). Команду
variable
можно не использовать, если вы всегда используете полное имя переменной.
Пространств имен часто используются для создания библиотек. Некоторые библиотечные команды могут использоваться так часто, что необходимость использования полных имен станет раздражать. Например, если все команды в такой библиотеке, как BLT, содержатся в пространстве имен Blt. Тогда вы смогли бы использовать их только следующим образом:
Blt::table..g 0,0
table..g 0,0
Как правило, не стоит импортировать все команды из пространства имен, так как при этом может быть сложно отследить все команды, которые вы получите. Лучше указать явно, какие именно команды вам нужны. Например, команда
Если вы попытаетесь импортировать команду, которая уже существует в текущем пространстве имен, то вы получите ошибку. Это предупредит, например, попытки скопировать одну и ту же команду из двух разных библиотек. Однако время от времени (например, при отладке) у вас может появиться желание преодолеть данное ограничение. Для этого нужно указать в команде опцию -force, и тогда существующая команда будет заменена на импортируемую команду без сообщения об ошибке:
Если вы удаляете команду из того пространства имен, где она была создана, например:
Вы можете разрешить экспорт команд из определенного пространства имен:
variable num 0
variable max 100
proc Bump {{by 1}} {
incr num $by
check
return $num
proc Reset {} {
set num 0
}
variable max
if {$num > $max} {
}
Команда namespace import
позволяет импортировать только те команды, которые разрешено экспортировать
из их пространства имен с помощью команды namespace export. Если
в команде
namespace import указана команда, которую нельзя экспортировать,
она не будет импортирована в соответствующее пространство имен.
open fileName access
open fileName access
permissions
Аргумент access, если
он используется, указывает разрешенные режимы доступа к файлу. Аргумент
access
может указываться в одной из двух нотаций. В первой он может иметь следующие
значения:
r | Открывает файл только на чтение. Это значение по умолчанию. |
r+ | Открывает файл на чтение и запись. Файл должен существовать. |
w | Открывает файл только на запись. Удаляет содержимое файла, если он существовал. Если нет, то создает новый файл. |
w+ | Открывает файл на чтение и запись. Удаляет содержимое файла, если он существовал. Если нет, то создает новый файл. |
a | Открывает файл на чтение. Файл должен существовать. Новые данные записываются в конец файла. |
a+ | Открывает файл на чтение и запись. Если файл не существует, создает новый файл. Новые данные записываются в конец файла. |
Во второй нотации аргумент
access
может содержать набор из флагов, описанных ниже. Среди флагов обязательно
должен быть один из следующих: RDONLY, WRONLY или RDWR.
RDONLY | Открывает файл только на чтение. |
WRONLY | Открывает файл только на запись |
RDWR | Открывает файл на чтение и запись. |
APPEND | Переставляет указатель в конец файла перед каждой записью. |
CREAT | Создает файл, если он не существует. Без этого флага попытка открыть несуществующий флаг приведет к ошибке. |
EXCL | Если указан также флаг CREAT, то будет сгенерирована ошибка, если файл уже существует. |
NOCTTY | Если файл открыт для терминального устройства, этот флаг не позволяет ему стать управляющим терминалом процесса. |
NONBLOCK | Позволяет в неблокирующем режиме открыть файл и, возможно, выполнять в этом режиме последующие операции ввода ≈ вывода. Последствия использования этого флага зависят от платформы и устройства. Предпочтительнее вместо него использовать команду fconfigure. Конкретные особенности использования флага описаны в руководстве по вашей операционной системе, системный вызов open, флаг O_NONBLOCK. |
TRUNC | Если файл существует, то его содержимое удаляется. |
Если файл создается при
выполнении команды open, то аргумент permissions (целое число)
используется для установки прав доступа к вновь созданному файлу. Значение
по умолчанию
0666.
Если первый символ вfileName |'', то считается, что остальные символы описывают командный конвейер, который запускается так же, как командой exec. В этом случае идентификатор открытого канала может использоваться для ввода информации в стандартный ввод запущенного конвейера или для чтения его стандартного вывода. в зависимости от значения аргумента access. Если канал открыть только на запись, то стандартный вывод конвейера направляется на текущий стандартный вывод (если он не перенаправлен в конвейере). Если канал открыт только на чтение, стандартный ввод для конвейера берется из текущего стандартного ввода (если он не перенаправлен в конвейере).
-mode baud,parity,data,stop
Эта опция включает 4 величины, записанные через запятую.
baud ≈ число, скорость передачи данных в Бодах (бит в секунду);
parity ≈ четность, может принимать одно из значений n (none), o (odd), e (even), m (mark), s (space);
data ≈ число бит данных (целое от 5 до 8);
stop ≈ число стоп битов (целое 1 или 2).
Аргумент fileName для сериальных портов должен иметь форму comX, где X ≈ число (обычно, от 1 до 4). Попытка открыть несуществующий порт приводит к ошибке.
Windows NT
Проблемы могут возникать при интерактивном выполнении Tcl, поскольку в этом случае консоль используется и для Tcl, и для порожденного подпроцесса.
Windows 95
Сложности при работе с 16-битовыми DOS-приложениями.
Также проблемы могут возникать при интерактивном выполнении Tcl, поскольку в этом случае консоль используется и для Tcl, и для порожденного подпроцесса.
Windows 3.X
Те же проблемы, что и при выполнении команды exec.
Macintosh
Открытие последовательного порта не поддерживается.
Открытие командного конвейера также не поддерживается.
Unix
Обычно для открытия последовательного порта используется значение fileName /dev/ttyX, где X равно a или b, но можно также использовать любой псевдофайл, назначенный на соответствующий порт.
Проблемы могут возникать при интерактивном выполнении Tcl, поскольку в этом случае консоль используется и для Tcl, и для порожденного подпроцесса.
СИНТАКСИС
package forget packagepackage ifneeded package version?script?
package provide package?version?
package require? -exact? package?version?
package unknown? command?
package vcompare version1 version2
package versions package
package vsatisfies version1 version2
ОПИСАНИЕ
Команда поддерживает простую базу данных со сведениями о том, какие пакеты библиотечных функций доступны для использования в данном интерпретаторе, и как их загрузить в интерпретатор. Она поддерживает многоверсионность пакетов и гарантирует загрузку в приложение необходимой версии пакета. При этом она обеспечивает контроль непротиворечивости версий. Обычно в Tcl-скриптах достаточно использовать команды package require и package provide. Остальные команды предназначены в первую очередь для системных скриптов, которые поддерживают базу данных пакетов.
Поведение команды package
определяется ее первым аргументом. Ниже описаны возможные формы команды.
package forget package
Если база данных не содержит необходимой версии, а в интерпретаторе определена команда для packageunknown (см. ниже), то она исполняется, после чего повторно проверяется доступность необходимой версии. Если версия по-прежнему недоступна, команда возвращает ошибку.
Если аргумент command
не указан, возвращает текущий скрипт, заданный для команды package unknown.
Рекомендованный способ работы с пакетами в Tcl состоит в том, чтобы включать в скрипты команды package require и package provide, и использовать процедуру pkg_mkIndex (см. соответствующие пункты) для создания индексных файлов для пакетов. Это обеспечивает автоматическую загрузку необходимых пакетов.
См.также close(n),
filename(n),
gets(n),
read(n),
puts(n),
exec(n)
pid
pkg_mkIndex dir pattern?pattern pattern...?
Процедура pkg_mkIndex представляет собой утилиту для работы с Tcl-библиотеками. Она обеспечивает создание индексных файлов, необходимых для автоматической загрузки пакетов, когда в приложении встречается команда package require. Для создания автоматически загружаемых пакетов необходимо выполнить следующие действия:
Создать один или несколько пакетов. Каждый пакет может состоять из одного или больше файлов с Tcl-скриптами или из бинарных файлов. Бинарные файлы должны быть пригодны для их загрузки с помощью команды load с единственным аргументом -именем файла. Например, если в пакет входит файл test.so, он должен загружаться командой load test.so. Каждый файл Tcl-скриптов должен содержать команду package provide с именем пакета и версией. Каждый бинарный файл должен содержать вызов процедуры Tcl_PkgProvide.
Создать индексные файлы с помощью команды pkg_mkIndex. Аргумент dir указывает имя каталога, в котором лежат файлы пакета, а шаблоны pattern, которые могут содержать специальные символы, как в команде glob, указывают на файлы в этом каталоге. Команда pkg_mkIndex создаст в каталоге dir файл pkgIndex.tcl, содержащий информацию обо всех файлах пакета, заданных с помощью аргументов pattern. Для этого загружаются все файлы пакета, и определяется, какие новые пакеты и какие новые процедуры появились (поэтому в каждом файле пакета и должна быть команда package provide или вызов Tcl_PkgProvide).
Установить пакет как подкаталог одного из каталогов, перечисленных в переменной tcl_pkgPath. Если в списке $tcl_pkgPath больше одного каталога, то бинарные файлы с разделяемыми библиотеками обычно устанавливаются в первом каталоге, а библиотеки Tcl-скриптов ≈ во втором. В этих каталогах должны также находиться файлы pkgIndex.tcl. Пока пакеты будут размещаться в подкаталогах каталогов, перечисленных в переменной tcl_pkgPath, этого будет достаточно для их автоматической загрузки при выполнении команды package require.
Если вы установили пакеты в каких-либо других каталогах, то необходимо, чтобы эти каталоги содержались в переменной auto_path или были бы непосредственными подкаталогами одного из содержащихся там каталогов. Переменная auto_path содержит список каталогов, которые просматриваются как автозагрузчиком, так и загрузчиком пакетов. По умолчанию он включает $tcl_pkgPath. Загрузчик пакетов также просматривает и подкаталоги каталогов, включенных в auto_path. Пользователь может в явном виде включить в приложении необходимые каталоги в auto_path. А можно включить эти каталоги в переменную окружения TCLLIBPATH. Если она существует, то используется для инициализации переменной auto_path при запуске приложения.
Если перечисленные выше шаги выполнены, то для использования необходимого пакета достаточно выполнить в приложении команду package require. Если, например, версии 2.1, 2.3 и 3.1 пакета Test проиндексированы и хранятся в соответствующих каталогах, то команда
Автозагрузчик и загрузчик пакетов во многом имеют сходные возможности, поскольку и тот, и другой предназначены для загрузки файлов по требованию. Однако загрузчик файлов представляет собой механизм более высокого уровня, который использует автозагрузчик на последнем шаге процесса загрузки. Как правило, предпочтительнее индексировать пакеты с помощью команды pkg_mkIndex, чем с помощью команды auto_mkindex, поскольку это обеспечивает подключение механизма версий. Вы можете иметь несколько версий одного и того же пакета и, более того, использовать в различных приложениях различные версии. Напротив, auto_mkindex позволяет работать с единственной версией пакета. Скорее всего, не стоит создавать индексы для пакета с помощью и pkg_mkIndex, и auto_mkindex, поскольку в этом случае трудно контролировать, какой из механизмов загрузки пакета сработает первым, и, соответственно, какая версия пакета будет загружена.
При первом вызове команды package require исполняется скрипт package unknown. При инициализации Tcl-скрипт package unknown задается таким образом, что он выполняет все файлы pkgIndex.tcl в каталогах auto_path. Эти файлы содержат команды package ifneeded для каждой доступной версии каждого доступного пакета. Эти команды в свою очередь вызывают команды package provide, которые объявляют данные версии доступными. Кроме того, они формируют необходимую исходную информацию для автозагрузчика. Данный файл данной версии данного пакета реально загружается только тогда, когда вызывается первая из содержащихся в нем команд. Таким образом, после выполнения команды package require вы не увидите команд пакета в интерпретаторе, но, тем не менее, вы сможете их вызвать и при этом они загрузятся автоматически.
Команда proc создает новую Tcl-процедуру с именем name, если такой процедуры ранее не было, и замещает ранее существовавшую процедуру или команду с таким именем, если она была. При вызове новой процедуры скрипт body передается на выполнение Tcl-интерпретатору. Обычно имя процедуры указывается без указания имени пространства имен. При этом новая процедура создается в текущем пространстве имен. Однако, если пространство имен указано явно, она создается в указанном пространстве. Аргумент args определяет формальные аргументы процедуры и представляет собой список (возможно, пустой), каждый элемент которого представляет описание одного формального параметра. Каждое такое описание само является списком из одного или двух элементов. Первый элемент списка определяет имя формального параметра. Второй элемент списка, если он указан, определяет значение по умолчанию для данного параметра.
При выполнении процедуры для каждого формального параметра создается локальная переменная. Ей присваивается значение соответствующего аргумента, указанного при вызове процедуры, или значение по умолчанию. Аргумент, для которого при определении процедуры указано значение по умолчанию, может не присутствовать в вызове процедуры. Однако общее количество указанных параметров должно быть достаточным для аргументов, не имеющих значения по умолчанию, но не больше общего числа формальных параметров. Если это условие выполнено, все аргументы процедуры собираются в один список (как при исполнении команды list). Эта комбинированная величина присваивается локальной переменной args.
При исполнении тела процедуры имена переменных обычно считаются именами локальных переменных, которые создаются автоматически по мере необходимости и удаляются после завершения процедуры. По одной локальной переменной создается также для каждого аргумента процедуры. Для использования глобальных переменных необходимо использовать команду global или upvar. Для использования переменных из пространства имен необходимо использовать команду variable или upvar.
Команда proc возвращает
пустую строку. При вызове процедуры возвращается величина, заданная в команде
return.
Если в процедуре не выполнялась явная команда return,
она возвращает результат выполнения последней команды, выполнявшейся в
теле процедуры. Если при выполнении процедуры произошла ошибка, то процедура
в целом возвращает эту ошибку.
Команда записывает данные
в канал.
Символы новой строки при выводе заменяются на последовательность, используемую на данной платформе (например, cr lf на Windows-платформах) в соответствии со значением опции канала -translation. Опция может быть изменена с помощью команды fconfigure.
Tcl осуществляет вывод через буфер. Поэтому символы, выданные командой puts, могут и не появиться сразу в выходном устройстве или в файле. Обычно вывод откладывается до заполнения буфера или закрытия канала. Чтобы обеспечить немедленную выдачу данных, можно использовать команду flush.
Когда буфер заполнится, команда puts обычно блокирует процесс до тех пор, пока все данные не будут переданы операционной системе для дальнейшего вывода. Если канал channelId открыт в неблокирующем режиме, процесс не блокируется, даже если операционная система еще не приняла данные. Tcl в этом случае продолжает складывать данные в буфер и в фоновом режиме передает их в соответствующий файл или устройство с той скоростью, с которой они могут принять данные. Чтобы работа в неблокирующем режиме была возможна, необходимо, чтобы был запущен обработчик событий.
При работе в неблокирующем
режиме возможен рост буфера, под который будет выделен неоправданно большой
объем памяти. Чтобы избежать этого, неблокирующие операции ввода ≈ вывода
лучше делать управляемыми по событиям. При этом новая порция данных не
будет передаваться в буфер, пока канал не будет готов к ее приему.
read
read channelIdnumBytes
Если указана опция -nonewline, при выполнении команды отбрасывается символ новой строки в конце файла.
Если канал открыт в неблокирующем режиме, команда может прочитать не указанное количество байтов, а только все доступные. После чего она не заблокирует процесс, дожидаясь дополнительных данных, а завершится. Если команда завершилась до конца файла, то опция -nonewlineигнорируется.
Команда read изменяет
во входных данных последовательность, задающую конец строки, в соответствии
с опцией канала -translation option.Опция может быть
изменена с помощью команды fconfigure.
Если в команде указаны дополнительные аргументы после string, они считаются именами переменных, в которые возвращается информация о том, какие именно части строки соответствуют регулярным выражениям. Переменной присваивается значение, состоящее из части строки, соответствующей всему регулярному выражению. Самой левой в списке переменной subMatchVar присваивается значение, состоящее из части строки, которая соответствует самому левому заключенному в скобки выражению в составе exp. Следующей переменной subMatchVar присваивается значение, соответствующее следующему заключенному в скобки выражению, и так далее.
Если первые аргументы команды начинаются с -, они считаются опциями команды. Ниже перечислены возможные опции.
-nocase
Регулярное выражение состоит из ни одной или более ветвей (branch), разделенных символом '|'. Строка соответствует выражению, если она соответствует одной из его ветвей.
Ветвь состоит из одной или более частей (piece), соединенных друг с другом. строка соответствует ветви, если ее можно разбить на подстроки таким образом, что начальная подстрока соответствует первой части ветви, следующая подстрока ≈ следующей части ветви и так далее.
Часть состоит из атома со следующим за ним необязательным символом '*', '+' или '?'. Атом с последующим символом "*" соответствует любой последовательности из нуля или более подстрок, каждая из которых соответствует атому. Атом с символом '+' после него соответствует любой последовательности из одной или более подстрок, каждая из которых соответствует атому. Атом с символом '?' после него соответствует подстроке, которая соответствует атому, или пустой строке.
Атом может быть регулярным выражением в скобках (в этом случае он соответствует любой строке, которая соответствует этому регулярному выражению), интервалом (см. ниже), символом '.' (соответствует ровно одному произвольному символу), '^' (соответствует нулевой строке в начале string), '$' (соответствует нулевой строке в конце string), '\' с последующим одним символом (соответствует этому символу), или одним символом без какого-либо иного смысла (соответствует этому символу).
Интервал есть последовательность
символов, заключенная в квадратные скобки. Он обычно соответствует любому
символу из этого интервала. Если последовательность начинается с символа
'^', то она соответствует любому символу, кроме символов, стоящих
далее в последовательности. Если два символа в последовательности разделены
символом '-', то это краткая форма для обозначения всех ASCII символов
между этими двумя (например, '[0-9]' соответствует любой десятичной цифре).
Для того, чтобы включить в последовательность символ ']', следует
поставить его на место первого в последовательности (следом за возможным
символом '^'). Для включения в последовательность символа '-'
следует сделать его первым или последним символом.
Вообще говоря, регулярное выражение может соответствовать строке несколькими различными способами. Например, рассмотрим выражение
[1]
Если регулярное выражение соответствует двум разным частям строки, выбирается та часть, которая раньше начинается.
Если обе начинаются в одном и том же месте, то это неопределенный (тяжелый) случай. Его можно объяснить следующим образом.
[2]
Если регулярное выражение содержит символы "|" (то есть состоит из нескольких ветвей), то будет выбрана самая левая ветвь, которой что-либо соответствует
[3]
Для выражений, содержащих '*', '+' и '?", выбираются самые длинные фрагменты строки, соответствующие им.
[4]
Компоненты выражений рассматриваются слева направо.
В приведенном выше примере "(a*)b*" соответствует "aab", так как для "(a*)" выбирается первый соответствующий ему фрагмент, то есть начальные "aa", а затем для "b*" выбирается следующий символ "b". Рассмотрим еще один пример:
regsub? switches? exp string subSpec varName
Команда сравнивает регулярное выражение exp и строку string и копирует string в переменную, заданную именем varName. Если совпадение найдено, то при копировании часть строки string, соответствующая exp, замещается на subSpec. Если subSpec содержит один из символов "&" or "\0", то он заменяется на часть строки string, которая соответствует шаблону exp. Если subSpec содержит "\n", где n √ целое число от "1" до "9", то это выражение заменяется на часть строки string, которая соответствует n-ому заключенному в скобки выражению в exp. Чтобы избежать специальной интерпретации перечисленных символов и символа обратный слеш, их необходимо экранировать символом обратный слеш. Чтобы избежать возможных проблем с интерпретацией символов обратный слеш в exp, проще всего заключить exp в фигурные скобки.
Если начальные аргументы команды начинаются с символа "-", они считаются опциями команды. Ниже приведен список поддерживаемых опций.
-all
При поиске соответствующих фрагментов строки не различаются буквы в верхнем и нижнем регистре. Тем не менее, подстановка производится в исходном регистре.
--
Означает конец опций. Следующий аргумент будет рассматриваться как exp, даже если он начинается с "-".
Команда возвращает количество
найденных (и, соответственно, замещенных) интервалов. Правила соответствия
строк регулярным выражениям приведены в описании команды regexp.
rename oldName newName
Данная команда переименовывает команду по имени oldName в newName. Если newName отсутствует (равно пустой строке), тогда команда oldName удаляется.
Имена oldName и newName
могут содержать квалификаторы областей имен (указатели на имена областей
имен). Если команда переименовывается в другую область имен, то последующие
вызовы этой команды будут происходить в новой области имен. Команда rename
возвращает пустую строку.
resource
return
Обычно опция -code не используется, и процедура завершается успешно (с кодом завершения TCL_OK). Однако, ее можно использовать для генерации других кодов возврата. Ниже перечислены возможные коды.
ok
error
Опции -errorinfo и -errorcode могут использоваться совместно с √code error, чтобы вернуть дополнительную информацию о сгенерированной ошибке. В остальных случаях они игнорируются.
Опция -errorinfo используется для того, чтобы задать исходное значение переменной errorInfo. Если она не будет задана, то в переменную errorInfo будет включена информация о вызове процедуры, вернувшей ошибку, и о более высоких уровнях стека, но не информация непосредственно об ошибке внутри процедуры. Чаще всего для формирования переменной info используется сообщение команды catch, обнаружившей ошибку в процедуре.
Если опция -errorcode
указана, она позволяет задать значение переменной errorCode.
В противном случае ей будет присвоено значение NONE.
scan
Когда команда scan находит спецификатор преобразования в строке format, она пропускает пробельные символы в строке string. Затем она выбирает следующую группу непробельных символов и преобразует их в соответствии со спецификатором преобразования и записывает результат в переменную, соответствующую следующему аргументу команды. Поддерживаются следующие типы преобразований, задаваемые соответствующими символами:
d
Входное поле состоит из всех непробельных символов до следующего пробельного. Все символы копируются в переменную.
e или f или g
Поведение команды scan не отличается от поведения ANSI C процедуры sscanf за исключением следующих моментов:
[1]
Спецификаторы %p и %n не поддерживаются.
[2]
Для спецификатора %c нельзя указывать ширину поля. Только один символ переводится в десятичную величину, которая и присваивается соответствующей переменной.
[3]
Модификаторы l, h
и L игнорируются. Целые числа преобразуются так, как будто никакого
модификатора не было задано, а действительные числа ≈ как при модификаторе
l,
то есть с использованием типа double для внутреннего представления.
seek
Команда изменяет текущую позицию доступа канала, заданного параметром channelId. Значение channelIdдолжно быть идентификатором канала, который вернула предыдущая команда open или socket. Аргументы origin и offset задают новую позицию, в которой будет выполняться следующая операция чтения или записи. Аргумент offset должен быть целым числом (возможно, отрицательным), а аргумент origin может принимать одно из перечисленных ниже значений.
start
Выполнение команды влечет
немедленную передачу всех данных из выходного буфера в файл или на выходное
устройство. Команда не будет завершена до тех пор, пока все данные не будут
переданы, даже если канал находится в неблокирующем режиме. Кроме того,
будут удалены все не прочитанные данные из входного буфера. Команда возвращает
пустую строку. Если команда используется для файла или канала, для которого
не поддерживается произвольный доступ, она вернет ошибку.
set
Если varName содержит открывающую скобку и заканчивается закрывающей скобкой, тогда это элемент массива. Символы до открывающей скобки являются именем массива, символы между скобками есть индекс этого элемента в массиве. В противном случае команда адресуется к скалярной переменной.
Обычно имя переменной указывается без указания пространства имен, в котором она содержится. При этом соответствующая переменная для чтения или записи ищется в текущем пространстве имен. Если же в имени переменной присутствуют имя пространства имен, то она ищется в указанном пространстве имен.
Если команда используется
вне тела процедуры, то
varName есть имя глобальной переменной (если
текущее пространство имен есть глобальное пространство) или переменной
текущего пространства имен. В теле процедуры
varName есть имя параметра
или локальной переменной процедуры, если она не объявлена глобальной переменной
или переменной пространства имен с помощью команды
global
или variable соответственно.
socket?options? host port
socket -server command?options?
port
Эта команда открывает сетевое соединение и возвращает идентификатор канала, который может использоваться в последующих командах read, puts или flush. В настоящее время поддерживается только протокол TCP. Команда может использоваться для открытия соединения как со стороны сервера, так и со стороны клиента.
Если опция -server не указана, то канал открывается со стороны клиента, и возвращаемый идентификатор канала может быть использован для операции чтения и записи. Аргументы portи host задают порт для соединения. По данному порту должен быть сервер, обслуживающий соединение. Аргумент port должен быть целым числом, а host ≈ адресом машины в доменном стиле (например, www.sunlabs.com) или числовым IP-адресом (например, 127.0.0.1.). Для ссылки на локальную машину, на которой выполняется команда, можно использовать значение localhost.
Для задания дополнительной информации о соединении можно использовать следующие опции.
-myaddr addr
Аргумент addr задает доменный или числовой адрес сетевого интерфейса клиентской стороны для упрощения соединения. Эта опция может быть полезна, если на клиентской машине есть несколько сетевых интерфейсов. Если опция не указана, системный интерфейс будет выбран операционной системой.
-myport port
Аргумент port задает номер порта для клиентсткой стороны соединения. Если опция не указана, номер порта для клиента будет определен операционной системой.
-async
Использование опции -async
приведет к тому, что клиент будет подсоединен в асинхронном режиме. Это
значит, что сокет будет создан немедленно, возможно, еще до установления
связи с сервером. Если канал открыт в блокирующем режиме, то при выполнении
команды gets или flush
по такому сокету, команда завершится только после того, как процесс установления
соединения будет завершен. Если канал открыт в неблокирующем режиме, то
в этой ситуации команда завершится немедленно, а команда fblocked
для данного канала возвратит 1.
Если в команде присутствует опция -server, то новый сокет будет сервером для порта port. Tcl будет автоматически устанавливать соединения по данному порту. Для каждого соединения будет создаваться новый канал, который может быть использован для связи с клиентом. При этом Tcl выполняет команду command с тремя дополнительными аргументами: имя нового канала, адрес клиентской машины в сетевой нотации и номер порта клиента.
В команде можно использовать следующие опции:
-myaddr addr
Аргумент addr задает доменный или числовой адрес сетевого интерфейса серверной стороны для упрощения соединения. Эта опция может быть полезна, если на серверной машине есть несколько сетевых интерфейсов. Если опция не указана, сокет связывается со специальным адресом INADDR_ANY, который позволяет принимать соединения от любого интерфейса.
Канал сервера не может быть использован для приема или выдачи данных. Его единственное назначение ≈ принимать новые клиентсткие подсоединения. Каналы, открываемые для каждого клиентского соединения, открываются на чтение и запись. Закрытие серверного канала вызывает отключение сервера, так что никаких новых соединений не может быть выполнено. Однако существующие соединения сохраняются.
Сокет сервера не может обнаружить
новое соединение при незапущенном обработчике событий. Поэтому в приложении
должен быть запущен обработчик событий, например, командой vwait.
Команда fconfigure может получить значения нескольких неизменяемых опций для сокетов:
-sockname
source
Для Macintosh-платформ существуют
дополнительные варианты команды, предназначенные для работы с ресурсами.
split
Примеры.
Команда
string compare string1 string2
Проверяет, соответствует ли строка образцу. Возвращает "1", если соответствует, и "0" ≈ в противном случае. Соответствие проверяется примерно так же, как в C-shell. Строка соответствует шаблону, если они совпадают посимвольно, за исключением перечисленных ниже специальных случаев:
* ≈ Удовлетворяет любой последовательности из нуля или больше символов;
? √ Удовлетворяет любому символу;
[chars] √ Удовлетворяет любому символу из chars. Если chars включает последовательность символов типа a-b, то удовлетворяет всем символам от a до b (включительно).
\x √ Удовлетворяет символу x. Обеспечивает возможность избежать в шаблонах специального смысла символов "*", "?", "[", "]", "\".
string range string first last
subst
subst ?-nobackslashes ? ?-nocommands? ?-novariables? string
Команда subst выполняет подстановки переменных, подстановки команд и подстановки с обратным слешем в строке string и возвращает получившуюся строку. Все подстановки выполняются обычным для Tcl образом. В результате подстановки в строке string выполняются дважды: один раз ≈ анализатором команд Tcl и второй раз ≈ командой subst.
Если задан любой из ключей -nobackslashes, -nocommands или -novariables, то соответствующие подстановки не выполняются.
Внимание! При выполнении подстановок команда subst не обращает внимания на двойные кавычки и фигурные скобки. Например, следующий скрипт
subst {xyz {$a}}
switch
switch?options? string {pattern body?pattern body...?}
Если один или несколько первых аргументов команды начинаются с -, они считаются опциями команды. Возможные опции перечислены ниже.
-exact
-glob
-regexp
-
Команда предполагает
использование одной из двух синтаксических форм для задания образцов и
скриптов. Первая использует отдельные аргументы для каждого образца и скрипта.
Эта форма удобна при необходимости выполнить подстановки в образцах и/или
скриптах. Во второй форме все они помещаются в один аргумент, который должен
быть списком. Элементами этого списка должны быть, соответственно, образцы
и скрипты. Эта форма более удобна для длинных команд, не размещающихся
в одной строке, поскольку она не требует использовать обратный слеш в конце
каждой строки. Но при ее использовании необходимо учитывать, что, поскольку
список содержится в фигурных скобках, подстановки команд и переменных в
образцах и скриптах не производятся. Вследствие этого результат выполнения
команды, записанной в различных формах, может различаться.
Если один из аргументов body равен "-", это означает, что при совпадении строки с данным образцом будет выполняться скрипт body для следующего образца. Если для следующего образца скрипт также равен "-", то будет использован скрипт для следующего за ним образца и т.д.
Ниже приведены примеры использования команды switch.
Команда
Команда
b {format 1}
a* {format 2}
default {format 3}
А команда
-
b
{format 1}
a*
{format 2}
default
{format 3}
Следующие глобальные переменные автоматически создаются при запуске программ. Как правило, они ведутся автоматически и в пользовательском приложении их значения не изменяются.
На Macintosh-платформах, на которых нет переменных окружения, автоматически формируемый массив env, тем не менее, содержит следующие элементы:
ARITH code msg
tcl_precision
Все интерпретаторы в
процессе используют одно и тоже значение tcl_precision. Изменение точности
представления чисел в одном из интерпретаторов ведет к его синхронному
изменению во всех остальных. Однако, в надежных интерпретаторах изменять
точность нельзя.
tcl_rcFileName
tell
tell channelId
Команда tell возвращает десятичную строку, указывающую текущую позицию доступа в канале channelId. Если канал не поддерживает прямой доступ, то возвращается значение "-1".
time script?count?
Команда time вызовет интерпретатор Tcl count раз для выполнения скрипта script или только один раз, если аргумент count не задан. Команда возвратит строку вида
trace
trace option?arg arg...?
Эта команда вызывает выполнение указанных Tcl команда при определенных действиях с переменной. Ниже перечислены возможные опции команды (допускаются сокращения).
trace variable name ops command
r
command name1 name2
op
Команда command
исполняется в том же контексте, что и код, вызвавший срабатывание trace.
То есть если действие с переменной выполнялось в процедуре, то команда
command
может обращаться к локальным переменным этой процедуры. Этот контекст может
отличаться от контекста, в котором выполнялась сама команда trace.
Если команда
conmmand есть вызов процедуры (как обычно и бывает),
то в процедуре необходимо использовать команду upvar
или uplevel чтобы получить доступ к контролируемой
переменной. Как уже говорилось, имена в переменных
name1 и name2не
обязано совпадать с теми, что были заданы в команде
trace variable,
поскольку команда upvar позволяет процедуре
обращаться к переменной по различным именам.
Если команда trace контролирует чтение и запись в переменную, команда command может изменить результат отслеживаемой операции. Если команда command изменяет значение отслеживаемой переменной, то новое значение будет возвращено как результат отслеживаемой операции. Величина, возвращаемая командой command, игнорируется, если только это не ошибка. Тогда отслеживаемая операция также возвращает ошибку с тем же самым сообщением об ошибке, которое было сформировано в команде command, не поясняя, что ошибка произошла в результате отслеживания переменной. Это может приводить к определенным трудностям в определении истиной операции, при выполнении которой возникла ошибка.
При отслеживании записи в переменную команда command вызывается после того, как значение переменной изменено. Поэтому с ее помощью можно изменить присвоенное значение. Если при этом возвращать исходное значение, переменная окажется доступной только для чтения.
При выполнении команды command при отслеживании чтения или записи в переменную механизм слежения временно отключается. То есть выполнение этих операций в command не приведет к новых вызовам command. Однако, если в command выполняется удаление переменной, это приводит к соответствующему вызову.
Когда срабатывает команда trace на удаление переменной, переменная уже удалена. Если удаление переменной произошло вследствие завершения процедуры, команда command вызывается в контексте вызывающей процедуры, поскольку контекст вызвавшейся процедуры уже не существует. Отслеживание не отключается при выполнении command в случае удаления переменной. Поэтому если в command выполняется новая команда trace и удаляется соответствующая переменная, выполнится и соответствующая команда command. Ошибки при отслеживании удаления игнорируются.
Если одна и та же переменная отслеживается с помощью нескольких команда trace, то выполняться все соответствующие команды command с учетом порядка выполнения соответствующих команд trace. Чем позднее она выполнялась, тем раньше будет выполнена соответствующая команда command. Если одна из команд command при этом возвратит ошибку, остальные команды выполняться не будут. Если одна команда используется для отслеживания элемента массива, а другая ≈ для массива в целом, первой выполняется команда отслеживания массива в целом, а затем уже команда отслеживания элемента.
Однажды выполненная команда trace остается активной пока она не удалена с помощью описанной ниже команды trace vdelete, пока не удалена переменная или пока не удален интерпретатор. Удаление элемента массива приведет к прекращению отслеживания этого элемента, но не отслеживания массива в целом.
Команда trace variable возвращает пустую строку.
trace vdelete name ops command
unknown cmdName?arg arg ?
Интерпретатор Tcl выполняет эту команду каждый раз, когда скрипт пытается обратиться к несуществующей команде. Исходный вариант unknown не является функцией ядра Tcl; напротив, это библиотечная процедура, определяемая по умолчанию при запуске Tcl. Разработчик может переопределить ее функциональность так, как ему нужно.
Когда Tcl находит имя команды, которому не соответствует ни одной из существующих команд, тогда он проверяет наличие команды unknown. Если команды unknown нет, то он возвращает ошибку. Если такая команда обнаружена, то она будет вызвана с аргументами, состоящими из имени и аргументов исходной несуществующей команды, в которых выполнены все необходимые подстановки.
Команда unknown обычно выполняет поиск по библиотечным каталогам процедуры с именем cmdName, или поиск полного имени команды, к которой обратились по сокращенному имени, или автоматический запуск неизвестной команды как подпроцесса. При успешном поиске полного имени команды команда unknown заменяет имя на полное и вызывает команду с полным именем. Результат работы команды unknown используется вместо результата неопределенной команды.
Создаваемая по умолчанию процедура unknown выполняет следующие действия.
Сначала она вызывает библиотечную процедуру auto_load чтобы найти и загрузить соответствующую процедуру. Если это удалось, то выполняется исходная команда с ее исходными аргументами.
В противном случае вызывается процедура auto_execok чтобы найти исполняемый файл с именем cmdName. Если файл удалось найти, выполняется команда exec с именем команды и ее аргументами в качестве аргументов.
В противном случае проверяется, была ли неизвестная команда вызвана на самом верхнем уровне вне какого-либо скрипта. Если это было так, процедура unknown выполняет следующие дополнительные действия: проверяется не имеет ли команда одну из следующих форм:!!,!event, или ^old^new?^? и если да, то процедура unknown выполняет для них подстановки по тем же правилам, что и csh.
И при неудаче всех предыдущих попыток процедура unknown проверяет, не является ли cmdName сокращением для известной Tcl процедуры. Если так, то cmdName заменяется на полное имя процедуры и она вызывается с исходными аргументами.
Если же ни одна из попыток не привела к успеху, процедура возвращает ошибку.
Если определена глобальная переменная auto_noload, попытка загрузить процедуру с помощью auto_load не производится.
Если определена глобальная переменная auto_noexec, попытка загрузить процедуру с помощью auto_execok не производится.
Если команду удалось найти,
то процедура
unknown возвращает результат выполнения найденной команды.
Команда возвращает пустую
строку. Если одна из переменных не существует, команда вернет ошибку, а
последующие переменные не будут удалены.
update
Если в команде задана опция idletasks, то новые события и ошибки не обрабатываются, но выполняются все асинхронные вызовы. Команду update idletasks удобно использовать тогда, когда нужно выполнить немедленно действия, которые обычно откладываются, например, обновить отображаемые на дисплее данные или окна. Большинство обновлений изображений на дисплее выполняются в виде фоновых вызовов, и эта команда обеспечит их выполнение. Однако, если изменения были вызваны событиями, они не будут выполнены немедленно.
Команда update без
опций полезна в тех случаях, когда во время долго выполняющихся вычислений
необходимо обеспечить оперативную реакцию приложения на события, например,
на действия пользователя. Вызов команды update и обеспечивает обработку
таких событий.
uplevel
uplevel?level? arg?arg...?
Все аргументы команды объединяются как при выполнении команды concat. Получившийся скрипт выполняется в контексте, указанном level. Команда возвращает результат выполнения скрипта.
Если аргумент level задан как целое число, он указывает на сколько уровней выше уровня контекста текущей процедуры надо подняться в стеке вызовов перед выполнением скрипта. Если аргумент level задан как символ "#" с последующим целым числом, то он задает абсолютный уровень контекста в стеке. Если аргумент level отсутствует, то используется значение по умолчанию "1". Аргумент level должен быть указан, если первый из аргументов arg начинается с цифры или символа "#".
Например, предположим, что на самом верхнем уровне вызвана процедура a из нее вызвана процедура b, а из b вызвана процедура c. Предположим также, что в процедуре c есть вызов команды uplevel. Тогда если аргумент level равен "1" или "#2" или отсутствует, то указанный в команде скрипт будет выполнен в контексте процедуры b. Если аргумент level равен "2" или "#1", то указанный в команде скрипт будет выполнен в контексте процедуры a. Если аргумент level равен "3" или "#0", то указанный в команде скрипт будет выполнен на вернем уровне (уровень глобальных переменных).
При выполнении команды uplevel контекст вызывающей процедуры временно удаляется из стека вызовов процедур. Так, если в приведенном выше примере команда uplevel имеет вид
Команда uplevel позволяет создавать новые управляющие конструкции как Tcl-процедуры.
Команда namespace eval так же, как и вызовы процедур, изменяет контекст, в котором выполняются команды. Соответственно, для каждой команды namespace eval создается дополнительный уровень в стеке. Поэтому при указании уровня контекста в стеке каждую вложенную команду namespace eval надо считать наравне с вызовом процедуры. Это относится также к командам upvar и info level. Например, команда
СИНТАКСИС
upvar?level? otherVar myVar?otherVar myVar...?
ОПИСАНИЕ
Команда позволяет одной или больше локальным переменным текущей процедуры ссылаться на переменные процедуры, стоящей выше в стеке, или на глобальные переменные. Аргумент level может иметь те же формы, что и в команде uplevel, или быть опущен, если первый символ в первой из otherVar отличен от цифры и от # (значение по умолчанию "1"). Для каждой пары аргументов otherVar myVar команда позволяет сделать переменную с именем otherVar из указанного уровня стека (локальную переменную одной из вызывающих процедур или глобальную переменную, если level равно #0) видимой в исполняемой процедуре под именем myVar. Переменная с именем otherVar не обязана существовать в момент исполнения команды. При необходимости она будет создана при первом использовании переменной myVar. В момент исполнения команды не должно быть доступной переменной myVar. Переменная myVar всегда считается простой переменной (не массивом и не переменной массива). Даже если значение myVar выглядит как имя элемента массива, например, a(b), создается простая переменная. Значение otherVar может быть именем простой переменной, массива или элемента массива. Команда upvar всегда возвращает пустую строку.
Команда upvar позволяет упростить передачу параметра по ссылке, а также упрощает создание новых управляющий конструкций. Например, рассмотрим следующую процедуру:
upvar $name x
set x [expr $x+2]
}
Команда namespace eval так же, как и вызовы процедур, изменяет контекст, в котором выполняются команды. Для каждой команды namespace eval создается дополнительный уровень в стеке. Соответственно, при указании уровня контекста в стеке каждую вложенную команду namespace eval надо считать наравне с вызовом процедуры. Это относится также к командам uplevel и info level. Например, команда info level 1 вернет список, описывающий самую верхнюю выполняемую команду, которая является либо вызовом процедуры, либо командой namespace eval . Независимо от использования команда namespace eval команда uplevel #0 выполнит соответствующий скрипт на уровне глобальных переменных (в глобальном пространстве имен).
Если переменная, созданная
с помощью команды upvar, удаляется (например, если добавить в процедуру
add2
строку unset x), то реально будет удалена переменная, связанная с x, а
не сама переменная x. Нет никакого способа удалить созданные таким образом
переменные, кроме как выйти из процедуры, в которой они были созданы. Тем
не менее, возможно связать переменную верхнего уровня с другой локальной
переменной, выполнив еще одну команду upvar.
Если otherVar есть элемент массива, то отслеживание массива в целом, заданной командой trace, не сработает при действиях с myVar (однако, если отслеживание было задано на отдельный элемент массива, оно сработает). В частности, изменения, сделанные с помощью myVar в массиве env, не будут корректно переданы подпроцессу.
variable
variable?namevalue? name?value?
Обычно команду variable выполняют внутри команды namespace eval для создания одной или нескольких переменных в области имен. Каждая переменная name получает начальное значение value. Значение для последней переменной можно не указывать.
Если переменная name не существует, она будет создана. Если указан аргумент value, то переменной присвоится его значение. Если аргумент не указан, то новая переменная останется неопределенной. Если же переменная уже существовала, она сохранит свое значение. Обычно имя создаваемой переменной √ это простое имя, не содержащее имя пространств имен. Соответственно переменная создается в текущем пространстве имен. Если имя содержит имена пространств имен, переменная создается в указанном пространстве имен.
Если команда variable выполняется внутри Tcl процедуры, она создает локальную переменную, связанную с соответствующей переменной пространства имен. В этом случае команда variable напоминает команду global, которая, однако, только связывает локальную переменную с глобальной. Если аргумент value задан, то он используется для изменения значения соответствующей переменной в пространстве имен. Если переменная в пространстве имен не существует, она создается и, при необходимости, инициализируется.
Параметр name не может указывать на элемент массива. В команде variable можно указать только массив в целом, а затем присвоить значения его элементам командами set или array.
vwait?varName?
Команда vwait активизирует обработчик событий (event loop), блокируя приложение до тех пор, пока не в результате какого-либо события не будет присвоено новое значение переменной varName. После присвоения значения переменной varName команда vwait завершит работу сразу после выполнения скрипта, вызванного обработчиком событий.
В некоторых ситуациях команда
не завершается сразу после присвоения значения переменной varName.
Это происходит, например, если вызванный по события скрипт, присвоивший
новое значение переменной
varName, не завершается сразу. Например,
если в нем в свою очередь выполняется команда
vwait, устанавливающая
режим ожидания изменения другой переменной. Во время этого ожидания вышестоящая
команда
vwait блокируется как и приложение до выполнения соответствующего
события.
while
while test body
Команда while вычисляет значение выражения test подобно команде expr. Значение должно быть булевого типа. Если результат есть истина, то скрипт body передается на выполнение Tcl интерпретатору. После этого выражение test снова вычисляется, и процесс повторяется до тех пор, пока его значение не станет ложь. В тексте скрипта body можно использовать команду continue для завершения текущего цикла и команду break для немедленного завершения команды while.
Команда while всегда возвращает пустую строку.
Выражение test почти всегда лучше заключать в фигурные скобки, иначе подстановки команд и переменных в нем будут выполнены до исполнения команды и никакие изменения значений переменных в скрипте body не изменят значения выражения test. Это может привести к возникновению бесконечного цикла. Если же выражение test помещено в фигурные скобки, подстановки в нем выполняются при каждом вычислении (перед каждым выполнением body). Например, если выполнить следующий скрипт с и без скобок вокруг $x<10, то без скобок возникнет бесконечный цикл.
while {$x<10} {
incr x