Пакет 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 запросах.
Если никакие опции не заданы, возвращается текущая конфигурация. Если задан
единственный аргумент, тогда, он должен быть именем одной из опций, описанных
ниже. В этом случае возвращается текущая величина указанной опции. В противном
случае аргументы состоят из пар: имя опции ≈ присваиваемое значение.
-acceptmimetypes
Определяет типы
документов, которые могут быть приняты по запросу. Значение по умолчанию
▒*/*▓ означает, что могут быть приняты документы любого типа. Чтобы ограничить
список допустимых документов, можно использовать список (через запятую)
шаблонов документов следующего вида: ⌠image/gif, image/jpeg, text/*■.
-proxyhosthostname
Имя proxy-сервера,
через который осуществляется связь. Если не указано, связь осуществляется
напрямую.
-proxyportnumber
Имя proxy-порта.
-proxyfilter
command
Определяет команду,
которая возвращает имена proxy-сервера и proxy-порта, необходимые для данной
связи. В противном случае возвращает пустое значение. В качестве аргумента
при вызове команды используется имя сервера (host). Если команда не задана,
используются значения опций -proxyhost и -proxyport.
-useragentstring
Определяет имя пользовательского
приложения (User-Agent). Значение по умолчанию ⌠Tcl http client package
2.0.■
::http::geturl
url ?options?
Команда ::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} {
upvar #0 $token
state
# Получен доступ к socket
и Tcl-массиву state
...
(например: set data [read
$socket 1000];set nbytes [string length $data])
...
return nbytes
}
-headers keyvaluelist
Опция используется
для включения в заголовок HTTP запроса дополнительных полей. Аргумент должен
быть правильным списком с четным числом элементов, состоящим попеременно
из ключей и их значений. Ключи используются как имена полей заголовка.
Из значений удаляются символы перехода на новую строку, чтобы избежать
формирования неправильного заголовка. Например, если keyvaluelist
содержит список {Pragma no-cache} будет сформирован следующий заголовок
запроса:
Pragma: no-cache
-progresscallback
Опция обеспечивает
вызов команды
callback для обработки очередной порции данных. Команда
callback
получает три аргумента: значение token, возвращенное командой ::http::geturl,
предполагаемый полный размер данных из мета-данных и текущее количество
поступивших данных в байтах. Если едполагаемый полный размер неизвестен,
вместо него подставляется 0. Ниже приведен шаблон для процедуры, вызываемой
по опции -progress:
proc httpProgress
{token total current} {
upvar #0 $token state
}
-query query
Если указана данная
опция,
::http::geturl формирует запрос POST и передает его на сервер.
Запрос должен быть сформатирован. Для выполнения форматирования может использоваться
процедура ::http::formatQuery.
-timeoutmilliseconds
Если значение milliseconds
не равно нулю, устанавливается соответствующее время задержки. Задержка
выполняется перед вызовом команды ::http::reset
и команды, заданной опцией -command. Во время задержки команда ::http::status
возвращает значение timeout.
-validateboolean
Если значение boolean
не равно нулю, ::http::geturl выполняет HTTP HEAD запрос. Такой
запрос возвращает мета информацию об источнике данных (URL), а не его содержание.
Мета информация содержится в переменной state(meta) (см. ⌠Массив
состояния транзакции■).
::http::formatQuery
key
value?key value...?
Команда выполняет
перекодирование запроса. Команда использует четное число аргументов, являющихся
соответственно ключами запроса и их значениями. Она преобразует ключи и
значения и возвращает одну строку, в которой расставлены необходимые ⌠&■
и ⌠=■ разделители. Результат можно использовать в качестве значения
для опции
-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
Мета данные, описывающие
содержание документа. Данный элемент массива содержит список ключей и их
значений. Чтобы облегчить доступ к данным можно использовать следующую
конструкцию:
array set meta $state(meta)
Некоторые ключи мета данных
перечислены ниже, но в HTTP стандарте их перечислено больше, кроме того,
сервер может добавлять собственные.
Content-Type
Тип документа. Например,
text/html,
image/gif, application/postscript или application/x-tcl.
Content-Length
Объявленный размер
документа. Реальный объем информации, полученной с помощью команды ::http::geturl,
содержится в переменной
state(size).
Location
Измененный адрес
документа.
status
Возможные значения
ok,
reset
или error. Во время транзакции значение пустое.
totalsize
Копия значения мета
данных
Content-Length.
type
Копия значения мета
данных
Content-Type.
url
Запрошенный адрес.
Пример:
# Копирование источника
в файл и печать мета данных
proc ::http::copy { url
file {chunk 4096} } {
set out [open $file
w]
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} {
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
Аналогична команде source,
однако позволяет работать только с файлами в виртуальном пути безопасного
интерпретатора. Имя файла fileName должно содержать одну из меток,
определенных для каталогов в виртуальном пути. Допустимые имена файлов
более подробно описаны ниже (см. ⌠Безопасность■).load fileName Требуемый файл (обычно,
объектный файл из разделяемой библиотеки) загружается в безопасный интерпретатор,
если его удается найти. Имя файла должно содержать одну из меток для каталогов
виртуального пути. Кроме того, разделяемый объектный файл должен содержать
безопасную точку входа. Подробности приведены в описании команды load.
file?options?
Синоним команды file
содержит только безопасные подкоманды обычной команды file,
а именно: dirname, join,
extension,
root,
tail,
pathname
иsplit. Назначение
подкоманд приведено в описании команды file.exitПри выполнении команды
безопасный интерпретатор удаляется, вычисления в нем прерываются, но родительский
интерпретатор продолжает существовать.
КОМАНДЫ
В родительском интерпретаторе
для работы с безопасными интерпретаторами предусмотрены следующие команды:
::safe::interpCreate?slave??options...?
Создает безопасный интерпретатор,
инициализирует в нем команды ≈ синонимы, описанные выше, и механизмы автозагрузки
команд и пакетов в соответствии с заданными опциями (см. ⌠Опции■).
Если аргумент slave отсутствует, имя интерпретатора формируется автоматически.
Команда всегда возвращает имя созданного интерпретатора.::safe::interpInit
slave?options...?Команда аналогична предыдущей,
однако интерпретатор должен быть уже создан каким-либо иным способом, например
с помощью команды
::interp create-safe.::safe::interpConfigure
slave?options...?Если опции не заданы, возвращает
значения всех опций для указанного безопасного интерпретатора. В противном
случае устанавливает указанные значения опций (подробнее см. ⌠Опции■).::safe::interpDeleteslave Удаляет безопасный интерпретатор
и вычищает в родительском интерпретаторе информацию о нем. Перед удалением
выполняется скрипт, заданный с помощью опции -deletehook, если он
был задан. К скрипту добавляется дополнительный аргумент ≈ имя удаляемого
интерпретатора.
::safe::interpFindInAccessPathslave
directory
Команда возвращает метку,
которую можно использовать в безопасном интерпретаторе для каталога 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
::safe::interpAddToAccessPathslave
directoryКоманда позволяет добавить
к виртуальному пути указанного безопасного интерпретатора каталог directory.
Команда возвращает значение метки для каталога directory. Если каталог
уже содержался в виртуальном пути, команда только возвращает его метку
и не добавляет его в виртуальный путь. Пример использования команды (см.
пример к предыдущей команде):
::safe::interpAddToAccessPath
qqq $my_lib
qqq eval source \$my_lib/\$my_file::safe::setLogCmd?cmd
arg...?Эта команда позволяет задать
скрипт, который будет выполняться при различных событиях, связанных с безопасными
интерпретаторами. Если команда вызвана без аргументов, то она возвращает
установленный ранее скрипт. Вызванная с одним аргументом ≈ пустой строкой
≈ команда удаляет установленный ранее скрипт и отменяет процесс журнализации.
Установленный скрипт выполняется с одним дополнительным аргументом ≈ строкой,
описывающей событие. Основное назначение команды ≈ использование при отладке
скриптов, выполняемых в безопасных интерпретаторах. Используя ее, вы сможете
получить полную информацию об ошибке, в то время как безопасный интерпретатор
возвращает только обобщенное сообщение об ошибке (это позволяет избежать
разглашения в сообщении об ошибке конфиденциальной информации, например,
о реальных именах файлов). Пример использования:
::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?
Опция задает список каталогов,
к которым может иметь доступ безопасный интерпретатор, и возвращает метки
соответствующих каталогов. Если список не задан или если он пуст, безопасный
интерпретатор получает доступ к каталогам, используемым для автозагрузки
в родительском интерпретаторе. Подробнее см. ⌠Безопасность■.-noStaticsЕсли эта опция задана,
то не допускается загрузка статически связанных пакетов (как load {}
Tk). По умолчанию загрузка таких пакетов разрешена.-nestedLoadOkЕсли эта опция задана,
безопасный интерпретатор может загружать пакеты в собственные подинтерпретаторы.
По умолчанию загрузка пакетов в подинтерпретаторы запрещена.-deleteHook?script?Если скрипт задан, он выполняется
в родительском интерпретаторе (с дополнительным аргументом ≈ именем безопасного
интерпретатора) перед удалением безопасного интерпретатора. Если скрипт
не задан, то удаляется заданный ранее скрипт (если такой был) и никаких
дополнительных действий перед удалением безопасного интерпретатора не производится.
По умолчанию скрипт не задан.
БЕЗОПАСНОСТЬ
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. Скрипт может иметь любое количество
команд и должен оканчиваться закрывающей квадратной скобкой (]). Результат
выполнения скрипта (т.е., результат его последней команды) подставляется
в слово на место скобок и всех символов между ними. В слове может быть
любое количество подстановок команд. Подстановки команд не выполняются
в словах, заключенных в фигурные скобки.
Если слово содержит символ
доллара ($), тогда 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 указывает,
что некоторая команда должна быть выполнена с задержкой по времени.
Команда используется для
того, чтобы отложить выполнение программы или выполнить указанную команду
в фоновом режиме в некоторый момент в будущем. У команды есть несколько
форм, зависящих от ее первого аргумента.
afterms
Ms ≈ целое число,
задающее задержку в миллисекундах. Команда обеспечивает задержку на соответствующее
число миллисекунд до своего завершения. Во время задержки приложение не
реагирует на события.
after
ms?script
script script...?
В этой форме команда завершается
немедленно, но при этом она обеспечивает выполнение Tcl-команды script
script script
через соответствующее время. Команда выполняется ровно
один раз в установленный момент времени. Команда формируется объединением
всех перечисленных аргументов
script
таким же образом, как при выполнении
команды concat. Команда выполняется на глобальном
уровне (вне контекста какой-либо Tcl-процедуры). Ошибки во время выполнения
команды (если они происходят) обрабатываются с помощью процедуры bgerror.
Команда
after в этой форме возвращает идентификатор, который может
быть использован для отмены отложенной команды с помощью команды after
cancel.
after
cancel id
Отменяет исполнение ранее
заявленной отложенной команды. Id определяет, какая именно команда
будет отменена. Значение
id должно совпадать со значением, возвращенным
предыдущей командой
after. Если соответствующая команда уже выполнена,
команда
after cancel игнорируется.
after
cancel script script...
Эта команда также отменяет
выполнение ранее заявленной отложенной команды. Все перечисленные скрипты
script объединяются через пробел таким же образом, как при выполнении
команды
concat. После чего ищется отложенная
команда с аналогичным скриптом. Если такая команда будет найдена, ее исполнение
будет отменено. В противном случае команда after cancel игнорируется.
after
idle
script?script script...?
Все перечисленные скрипты
объединяются через пробел таким же образом, как при выполнении команды
concat.
Сформированная таким образом Tcl команда выполняется позже. Она выполняется
ровно один раз в первом цикле обработчика событий, в котором не будет других
необработанных событий. Команда after idle возвращает идентификатор,
который может быть использован для отмены отложенной команды. Ошибки во
время выполнения команды (если они происходят) обрабатываются с помощью
процедуры bgerror.
after
info?id?
Эта команда используется
для получения информации об отложенных командах. Если аргумент id
отсутствует , то возвращает список идентификаторов отложенных команд. Если
аргумент
id указан и соответствует идентификатору отложенной команды,
которая не отменена и еще не выполнена, возвращается список из двух элементов.
Первый элемент списка √ Tcl-скрипт соответствующей команды, второй ≈ idle
или timer в зависимости от того, по какому событию предполагается
вызов команды.
Команды afterms
и after idle предполагают, что приложение управляется событиями.
Отложенные команды не выполняются, если в приложении не активизирован цикл
обработки событий. В приложениях, в которых он обычно не активизирован,
таких как
tclsh, цикл обработки событий может быть активизирован
с помощью команд vwait и update.
append
Команда дописывает
значения аргументов к значению переменной.
СИНТАКСИС
append
varName?value value value...?
ОПИСАНИЕ
Команда append
добавляет все аргументы
value к значению переменной varName.
Если такой переменной не было, она будет создана, и ее значение будет равно
соединению значений аргументов
value. Эта команда предоставляет
удобный способ постепенного наращивания длинных переменных. сЕли переменная
a содержит длинное значение, то команда ⌠append a $b" выполняется
значительно быстрее, чем ⌠set a $a$b"
.
Эта команда предназначена для
выполнения перечисленных ниже операций с массивами. Если иное не оговорено
специально, arrayName должно быть именем существующего массива.
Аргумент
option определяет конкретную операцию. Для команды определены
перечисленные ниже опции.
array
anymore arrayName searchId
Возвращает ▒1▓ если
при выполнении команды поиска (см. ниже) остались невыбранные элементы
массива, и ▒0▓ в противном случае. SearchId указывает операцию поиска,
информация о которой запрашивается (величина searchId возвращается
при выполнении команды
array startsearch).
Эта опция особенно удобна, если массив содержит элемент с пустым именем,
поскольку команда array nextelement
не позволяет в таком случае определить, закончен ли поиск.
array
donesearch arrayName searchId
Команда прерывает
поиск элементов массива и удаляет всю связанную с поиском информацию. SearchId
указывает операцию поиска, информация о которой удаляется (величина searchId
возвращается при выполнении команды array
startsearch). Команда возвращает пустую строку.
array
existsarrayName
Возвращает ▒1▓,
если
arrayName есть имя массива, и ▒0▓, если такой переменной
не существует или она является скалярной переменной.
array
getarrayName?pattern?
Возвращает список,
содержащий пары элементов. Первый элемент пары ≈ имя элемента массива arrayName,
второй элемент пары ≈ значение этого элемента. Порядок пар не определен.
Если шаблон не задан, то все элементы массива будут включены в результат.
Если шаблон задан, то в результат будут включены только те элементы, чьи
имена соответствуют шаблону (используя те же правила, что и в команде glob).
Если arrayName не является переменной массива или массив не содержит
элементов, то возвращается пустой список.
array
names arrayName?pattern?
Возвращает список,
содержащий имена всех элементов массива, соответствующих шаблону (используя
те же правила, что и в команде glob).
Если шаблона нет, то команда возвращает имена всех элементов массива. Если
в массиве нет элементов, соответствующих шаблону или arrayName не
является именем переменной массива, то возвращается пустая строка.
array
nextelement arrayName searchId
Возвращает имя следующего
элемента массива
arrayName, или пустую строку, если все элементы
массива уже возвращены.
SearchId указывает операцию поиска, (величина
searchId
возвращается при выполнении команды array
startsearch). Предупреждение: если в массив внесен новый элемент
или из массива удален один из элементов, то все операции поиска в этом
массиве автоматически заканчиваются, как если бы была выполнена команда
array
donesearch. Соответственно, попытка выполнить после этого команду
array nextelement приведет к ошибке.
array
setarrayName
list
Устанавливает значение
одного или нескольких элементов массива arrayName. Список list
должен иметь такую же структуру, как список, возвращаемый командой array
get, то есть состоять из четного числа элементов. Все нечетные
элементы списка рассматриваются как имена элементов массива arrayName,
а следующие за ними четные элементы ≈ как новые значения соответствующих
элементов.
array
size arrayName
Возвращает строку,
содержащую десятичное число, равное количеству элементов указанного массива.
Если
arrayName не является именем массива, возвращается ▒0▓.
array
startsearch arrayName
Эта команда инициализирует
процесс поиска элементов указанного массива. После этого имя каждого следующего
элемента массива можно получить с помощью команды array
nextelement. По завершении поиска необходимо выполнить команду
array
donesearch. Команда
array startsearch
возвращает идентификатор процесса поиска, который должен использоваться
в командах
array nextelement и
array
donesearch. Благодаря этому механизму возможно проведение нескольких
процессов поиска элементов одного и того же массива одновременно.
bgerror
Команда bgerror предназначена
для обработки фоновых ошибок
(backgrounderrors).
СИНТАКСИС
bgerror сообщениеОПИСАНИЕВ Tcl нет встроенной команды
bgerror.
Если в приложении тем не менее необходимо обрабатывать фоновые ошибки,
пользователь может определить собственную команду bgerror, например,
как Tcl-процедуру.
Фоновые ошибки ≈ это ошибки
в командах, которые не вызваны непосредственно из приложения. Например,
фоновыми являются ошибки в командах, вызванных с помощью конструкции after.
Для нефоновых ошибок сообщение об ошибке возвращается через вложенные вызовы
команд, пока не достигнет верхнего уровня приложения. После этого приложение
выдает сообщение об ошибке в одной из команд верхнего уровня. При фоновой
ошибке подобный процесс не достигает команд верхнего уровня и формирование
сообщения об ошибке оказывается затруднительным.
Когда Tcl обнаруживает фоновую
ошибку, он сохраняет информацию об ошибке и вызывает команду bgerror
с помощью обработчика событий. Перед вызовом bgerror восстанавливаются
значения переменных errorInfo и errorCode,
которые были при обнаружении ошибки. После этого вызывается команда bgerror
с единственным аргументом ≈ сообщением об ошибке. Предполагается, что в
приложении определена команда
bgerror и что она выдает сообщение
об ошибке надлежащим образом. Если при выполнении команды bgerror
не произошло новой ошибки, возвращаемый ею результат игнорируется.
Если при исполнении команды
bgerror
произошла новая ошибка (например, если эта команда не существует), сообщение
об ошибке поступает в канал вывода ошибок.
Если до вызова обработчиком
событий команды
bgerror произошло несколько фоновых ошибок, то,
как правило, команда будет вызвана для каждой из обнаруженных ошибок. Однако,
если сама команда
bgerror возвращает код break (см. описание команды
return),
последующие ее вызовы пропускаются.
В чисто Tcl-приложениях команда
bgerror
не реализована. Однако, в Tk-приложениях определена процедура
bgerror,
которая выводит сообщение об ошибке в диалоговое окно и позволяет пользователю
просмотреть стек, описывающий, где именно эта ошибка произошла.
binary
Команда вставляет и извлекает
поля из двоичных строк.
Команда binary предоставляет
средства для манипулирования двоичными данными. Первая из форм команды
конвертирует обычные Tcl-значения arg в двоичное число. Например,
вызванная с аргументами ▒16▓ и ▒22▓, она вернет 8-байтовое двоичную строку,
состоящую из двух 4-байтовых чисел, представляющих соответственно ▒16▓
и ▒22▓. Вторая форма команды выполняет обратное действие, она извлекает
из двоичной строки данные и возвращает их как обычные Tcl строки.
binary
format
Команда binary format
создает двоичную строку по правилам, заданным с помощью шаблона formatString.
Содержание
этой строки задается дополнительными аргументами arg.
Команда возвращает
сформированную двоичную строку.
Шаблон formatString содержит
последовательность из нуля или более спецификаторов преобразования, разделенных
одним или более пробелами. Каждый спецификатор преобразования состоит из
буквы, за которой может следовать число count. Как правило, спецификатор
использует один из аргументов arg чтобы получить величину для форматирования.
Буква в спецификаторе указывает тип преобразования (форматирования). Число
count
обычно указывает сколько объектов для форматирования выбирается из значения
arg.
Соответственно, count должно быть неотрицательным десятичным числом.
Если значение count равно ▒*▓, это обычно указывает, что надо использовать
все значение аргумента. Если число аргументов arg
не соответствует
числу спецификаторов, требующих для себя дополнительного аргумента, выдается
ошибка.
Обычно результат каждого
нового преобразования дописывается в конец возвращаемой строки. Однако,
с помощью специальных спецификаторов точку ввода нового значения (курсор)
можно передвигать по формируемой строке.
Ниже приведены допустимые
значения спецификаторов преобразований и описаны соответствующие преобразования.
a?count?Передает в выходную строку
count
символов из соответствующего аргумента arg. Если в
arg содержится
меньше count байт, добавляются нулевые байты. Если в arg содержится
больше count байт, ⌠лишние■ байты игнорируются. Если count равно
▒*▓, используются все байты из arg. Если
count отсутствует,
используется один байт. Например, команда
binary format a7a*a alpha
bravo charlie
вернет строку, эквивалентную
alpha\000\000bravoc.
A?count?То же, что и a, за исключением
того, что для заполнения используются не нулевые байты, а пробелы. Например,
команда
binary format A6A*A alpha
bravo charlie
вернет alpha bravoc.
b?count?Передает в выходную строку
count
бит в порядке от младших к старшим в каждом байте. Аргумент
arg
должен состоять из последовательности нулей и единиц. Порядок байтов в
выходной строке тот же, что и во входной информации. Лишние биты отсекаются,
недостающие дополняются нулями. По умолчанию форматируется один бит. Если
число форматируемых битов не соответствует целому числу байтов, недостающие
биты дополняются нулями. Например, команда
binary format b5b* 11100
111000011010
вернет строку, эквивалентную
\x07\x87\x05.
B?count?Тоже, что и b, но биты
выдаются в порядке от старших к младшим. Например, команда
binary format B5B* 11100
111000011010
вернет строку, эквивалентную
\xe0\xe1\xa0.
h?count?Передает в выходную строку
count
шестнадцатеричных чисел в порядке от младших к старшим в каждом байте.
Аргумент arg должен состоять из последовательности символов, содержащихся
в множестве: ⌠0123456789abcdefABCDEF■. Порядок байтов в выходной строке
тот же, что и во входной информации. Лишние символы отсекаются, недостающие
дополняются нулями. По умолчанию форматируется одно шестнадцатеричное число.
Если число форматируемых чисел не соответствует целому числу байтов, недостающие
биты дополняются нулями.
Например, команда
binary format h3h* AB
def
вернет строку, эквивалентную
\xba\xed\x0f.
H?count?Тоже, что и b, но биты
выдаются в порядке от старших к младшим. Например, команда
binary format H3H* ab
DEF
вернет строку, эквивалентную
\xab\xde\xf0.
c?count?Передает в выходную строку
одно или несколько восьмибитных чисел. Если count не указан, аргумент
argдолжен
состоять из одного целого числа. В противном случае он должен состоять
из списка, содержащего не менее count целых чисел. Последние 8 бит
каждого числа сохраняются как один байт в выходной строке. Если count
равно
▒*▓, форматируются все числа в списке. Если в списке меньше чисел, чем
count,
выдается ошибка. Лишние числа в списке игнорируются.
Например, команда
binary format c3cc*
{3 -3 128 1} 257 {2 5}
вернет строку, эквивалентную
\x03\xfd\x80\x01\x02\x05, тогда как команда
binary format c {2 5}
вернет ошибку.
s?count?Эта форма аналогична c,
за исключением того, что она сохраняет 16-тибитовые числа. Последние шестнадцать
бит числа сохраняются как два байта, последний байт первым. Например, команда
binary format s3 {3
-3 258 1}
f?count?Эта форма аналогична c,
за исключением того, что она сохраняет числа с плавающей запятой в машинном
представлении (используемом для конкретной платформы). Например, на Windows
платформе с процессором Pentium команда
binary format f2 {1.6
3.4}
d?count?Эта форма аналогична f,
за исключением того, что используется представление для десятичных чисел
с двойной точностью. Например, на Windows платформе с процессором Pentium
команда
binary format d1 {1.6}
x?count?Записывает в выходную строку
count
нулевых байтов. Если count не задан, записывает один нулевой байт.
Если
count равно ▒*▓, выдает ошибку. Ни один из аргументов
arg
при форматировании не используется. Например, командаbinary format a3xa3x2a3
abc def ghi
X?count?Передвигает место будущей
вставки в выходную строку (курсор) на count байтов назад. Если аргумент
count
равен ▒*▓ или больше текущей позиции, передвигает курсор на начало строки.
Если
count не указан, передвигает его на один байт. Ни один из аргументов
arg
при форматировании не используется. Например, командаbinary format a3X*a3X2a3
abc def ghi
вернет dghi.
@ ?count?Передвигает место будущей
вставки в выходную строку (курсор) на абсолютную позицию count.
Позиция 0 соответствует первому байту в строке. Если count больше
текущей длины строки, она дополняется до необходимой позиции нулевыми байтами.
▒*▓ указывает на конец строки. Если аргумент count не указан, команда
возвращает ошибку.. Ни один из аргументов arg при форматировании
не используется. Например, команда
binary format a5@2a1@*a3@10a1
abcde f ghi j
вернет
abfdeghi\000\000j.binary
scanКоманда binary scan
просматривает двоичную строку
string, возвращая число выполненных
преобразований. Строка formatString содержит последовательность
спецификаторов преобразования. Каждый из аргументов varName содержит имя
переменной, в которую записывается результат очередного преобразования.
Поскольку спецификаторы преобразований
строятся по тем же правилам, что и для binary format, ниже приведены
примеры их использования с минимальными пояснениями. Принципиальным моментом
при исполнении команды binary scan является то, что если для очередного
преобразования, указанного в formatString, требуется больше байтов,
чем осталось до конца строки, то команда немедленно завершается, а соответствующая
переменная (в которую должен был записываться результат преобразования)
остается неизмененной. Если для записи результата очередного преобразования
не осталось переменной, команда возвращает ошибку.
a?count?Команда
binary scan abcde\000fghi
a6a10 var1 var2
вернет значение 1. В
переменной
var1 будет записана строка abcde\000, а переменная
var2
не изменится.A?count?Команда
binary scan "abc efghi\000"
a* var1
вернет ▒1▓. В переменной
var1
будет записана строка ⌠abc efghi".b?count?Команда
binary scan\x07\x87\x05
b5b* var1 var2
вернет 2. В переменной
var1
будет записано ▒11100▓, в переменной var2 будет
записано ▒1110000110100000▓.B?count?Команда
binary scan\x70\x87\x05
b5b* var1 var2
вернет ▒2▓. В
переменной
var1 будет записано ▒01110▓. В переменной var2
≈ ▒1000011100000101▓.
вернет ▒2▓. В
переменной
var1 будет записана строка ⌠7 -122". В переменной
var2
≈ ▒5▓. Обратите внимание, что команда возвращает числа со знаком.
Чтобы преобразовать их в числа без знака можно использовать выражение:
вернет ▒2▓. В переменной
var1
будет записана строка '5 7'. В переменной var2 ≈ ▒-16▓.
Обратите внимание, что команда возвращает числа со знаком. Чтобы преобразовать
их в числа без знака можно использовать выражение:
вернет ▒2▓. В
переменной var1 будет записана строка '5 7'. В переменной
var2
≈ ▒-16▓.
i?count?Командаbinary can\x05\x00\x00\x00\x07\x00\x00\x00\xf0\xff\xff\xff
i2i* var1 var2 вернет ▒2▓. В переменной
var1
будет записана строка ⌠5 7". В переменной var2 ≈ ▒-16▓.
Обратите внимание, что команда возвращает числа со знаком. В Tcl нет возможности
перевести его в число без знака.
I?count?Команда
вернет ▒2▓. В
переменной
var1 будет ▒1 2▓. В переменной var2 ≈ ▒020304▓.
Преобразование не требует дополнительной переменной varName.
break
Команда прекращает выполнение
цикла.
СИНТАКСИСbreakОПИСАНИЕ Обычно данная команда помещается
внутрь цикла, например созданного командами for,
foreach
или while. Команда возвращает код TCL_BREAK,
который вызывает завершение исполнения наименьшего охватывающего ее цикла.
Цикл завершается нормальным образом (без ошибки) как если бы он отработал
до конца. Код TCL_BREAK обрабатывается также в некоторых других ситуация
≈ при исполнении команды catch, при обработке
событий и в скрипте самого верхнего уровня.
case
Команда case исполняет
один из нескольких скриптов в зависимости от полученного значения.
СИНТАКСИСcase string?in?
patList body?patList body...?
casestring?in?
{patList body? body...?}
ОПИСАНИЕЗамечание. Команда
case
≈ устаревшая, она поддерживается только для совместимости с предыдущими
версиями. В последующих версиях она может быть опущена. Поэтому предпочтительнее
использование командыswitch.
Команда сравнивает string
со всеми аргументами patList по очереди. Каждый аргумент patList
представляет собой один или несколько (список) образцов. Если string
соответствует одному из образцов, то case рекурсивно вызывает интерпретатор
Tcl, передает ему следующий за этим списком образцов скрипт body
для выполнения и возвращает результат этого выполнения. Каждый аргумент
patList
состоит из одного или нескольких образцов. Каждый образец может содержать
спецсимволы, как в команде string match.
Кроме того, есть специальный образец default. Соответствующий ему
скрипт выполняется, если string не соответствует никакому другому
образцу.
Если string не соответствует
ни одному из образцов, а образец default не используется, то case
вернет пустую строку.
У команды есть две формы записи
для аргументов
patList и body. Первая использует отдельные
аргументы для каждого шаблона и команды. Эта форма более удобна, если в
образцах или командах желательно выполнить какие-либо подстановки. Во второй
форме все шаблоны и команды объединены в один аргумент, который должен
быть списком, состоящим из шаблонов и команд. Вторая форма позволяет проще
записывать многострочные команды, поскольку при этом фигурные скобки вокруг
списка позволяют не ставить обратный слеш в конце каждой строки. Однако
из-за этих фигурных скобок подстановки в шаблонах и командах не производятся.
Поэтому одна и та же команда, записанная в различных формах, может работать
по-разному.
catch
Команда выполняет скрипт
и обрабатывает ошибки, если они возникают.СИНТАКСИСcatch script?varName?ОПИСАНИЕДанную команду можно использовать
для того, чтобы не дать возникшим ошибкам прекратить процесс интерпретации
команд. Для исполнения скрипта script команда catch рекурсивно
вызывает интерпретатор Tcl и всегда возвращает код TCL_OK, независимо от
возможно возникших при исполнении скрипта script ошибок.
Команда catch возвращает
десятичную строку, содержащую код, возвращаемый Tcl-интерпретатором по
исполнению скрипта. Если при исполнении скрипта не возникло ошибок, возвращается
код 0 (TCL_OK). В противном случае возвращается ненулевое значение, соответствующее
коду прерывания (см. файл tcl.h). Если задан аргумент varName, он
определяет имя переменной, которой присваивается значение, возвращаемое
скриптом (результат выполнения или сообщение об ошибке).
Команда catch обрабатывает
все прерывания, в том числе от командbreak и
continue.
cd
Команда предназначена для
перехода в другой каталог.СИНТАКСИСcd ?dirName?ОПИСАНИЕ
Команда делает текущим каталогом
каталог
dirName, или, если параметр dirName не указан, каталог,
заданный в переменной окружения HOME. Команда возвращает пустую строку.
clock
С помощью команды clock
можно
получить и преобразовать значение времени.СИНТАКСИС clockoption?arg
arg...?ОПИСАНИЕ Команда выполняет одно из
перечисленных ниже действий, с помощью которых можно получить и преобразовать
строки или значения, являющиеся той или иной формой записи времени. Параметр
option
определяет выполняемое командой действие, одно из следующего списка (параметр
может быть сокращен):
clockclicks
Возвращает целое число,
с высокой точностью представляющее машинное время. Единица измерения зависит
от операционной системы и компьютера и представляет собой минимальную доступную
величину, например, счетчик циклов процессора. Эта величина может использоваться
только для относительного измерения пройденного времени.clock format clockValue?-format
string??-gmt boolean? Переводит целое число,
возвращаемое командами
clock seconds,
clock scan или командами
file
atime,
file mtimeи file ctime
в удобочитаемую форму. Если в команде присутствует аргумент-format,
следующий аргумент должен быть строкой, описывающей формат представления
времени. Строка состоит из описаний полей, состоящих из символа ▒%▓
и буквы. Все остальные символы в строке просто копируются в результат.
Ниже перечислены допустимые описания полей.
%% ≈ вставляет
%.
%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 означает, что используется
время по локальному часовому поясу, который задан для операционной системы.
Переводит дату dateString
в целое число (см.clockseconds).
Команда
может перевести в число любую стандартную строку, содержащую время и/или
дату, включая название часового пояса. Если строка содержит только время,
предполагается текущая дата. Если название часового пояса не указано, предполагается
локальный часовой пояс (если значение опции -gmt не равно true.
В этом случае предполагается, что время задано по Гринвичу).
Если в команде указан флаг
-base,
следующий аргумент должен содержать время в виде целого числа. По этому
числу определяется дата и используется вместо указанной в строке или текущей.
Такая возможность полезна при необходимости перевести в целое число время
на заданную дату.
Аргумент dateString
должен состоять из одной или более спецификаций следующих видов:
time ≈ Время суток
в форме:
hh?:mm?:ss???meridian??zone? или в форме hhmm?meridian??zone?,
где meridian ≈ индикатор AM или PM, zone ≈ имя часового пояса.
Если индикатор meridian не определен, hh считается числом
часов в двадцатичетырехчасовом формате.
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.
relative time ≈ Время
относительно текущего момента. Формат ≈ число единица измерения. Возможные
единицы измерения year,
fortnight,
month, week,
day,
hour,
minute(илиmin),
иsecond(илиsec).
Единицы измерения могут указываться во множественном числе, например
3 weeks. Кроме того, могут
использоваться модификаторы: tomorrow,
yesterday,
today,
now,
last,
this,
next,
ago.
Реальная дата вычисляется
в следующей последовательности. Сначала определяется абсолютная дата и/или
время, которые переводятся в целое число. Это число используется как базис,
к которому добавляется заданный день недели. Далее используется относительное
время. Если задана дата, а время (абсолютное или относительное) отсутствует,
считается, что это полночь. И последним шагом производится коррекция вычисленной
даты, при которой учитываются летнее время и число дней в различных месяцах.
clock
seconds
Возвращает время в секундах
от начала ⌠эпохи■. Может использоваться для вычисления разности времен.
⌠Эпоха■ зависит от используемой операционной системы и компьютера.
close
Команда закрывает открытый канал.СИНТАКСИС
closechannelId
ОПИСАНИЕ
Команда 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
Команда проверяет в канале условие
конца файла.
СИНТАКСИС
eofchannelId
ОПИСАНИЕ
Команда eof возвращает
▒1▓, если во время последней операции ввода в канале channelId произошло
условие конца файла, и 0 ≈ в противном случае.
error
Команда генерирует ошибку.
СИНТАКСИС
errormessage?info??code?
ОПИСАНИЕ
Команда возвращает
код TCL_ERROR, прерывающий интерпретацию команды. Строка message
возвращается приложению, чтобы указать, что именно произошло.
Если задан непустой аргумент
info,
его
значение присваивается глобальной переменнойerrorInfo.
ПеременнаяerrorInfo
обычно используется для формирования сведений о вложениях команды, в которой
произошла ошибка. Другими словами, как только оказывается, что невыполненная
команда была вложена в другую команду, информацию об этой команде добавляется
к errorInfo. Если же аргумент info
был задан, этого не происходит. Эта особенность позволяет при использовании
команды error совместно с командой catch
выдать
информацию о реальном месте ошибки (а не о месте вызова команды error).
Дляэтого
можно использовать следующую конструкцию:
catch {...} errMsg set savedInfo $errorInfo ... error $errMsg $savedInfo
Если задан аргументcode,
то его значение будет присвоено глобальной переменной errorCode.
Эта переменная предназначена для хранения машинного описания ошибки в тех
случаях, когда такое описание возможно. Форматы различных сообщений приведены
в разделе tell. Если аргумент не задан, переменной
errorCode
в процессе обработки Tcl-интерпретатором ошибки, порожденной командой,
присваивается значение ``NONE''.
eval
Команда исполняет Tcl-скрипт.СИНТАКСИСeval arg?arg...?ОПИСАНИЕАргументы команды eval
вместе образуют Tcl-скрипт, состоящий из одной или нескольких команд. Команда
соединяет аргументы (подобно команде concat)
и передает их рекурсивно запущенному интерпретатору Tcl. Команда возвращает
результат работы интерпретатора (или обнаруженную им ошибку).
exec
Команда запускает
подпроцессы.
СИНТАКСИСexec?switches?
arg?arg...?ОПИСАНИЕАргументы команды определяют
один или нескольких подпроцессов, которые необходимо выполнить. Аргументы
принимают форму конвейера, в котором каждый arg задает одно слово
команды, а каждая отдельная команда порождает подпроцесс.
Если первые аргументы команды
начинаются со знака '-', они считаются ключами команды, а не частью описания
конвейера.
Возможные ключи:
-keepnewline
≈ сохраняет конечные пробелы в выходных данных конвейера. Обычно они отсекаются.
- ≈ отмечает
конец ключей. Аргумент, следующий за этим ключом, рассматривается как первый
аргумент
arg, даже если он начинается со знака '-'.
Перечисленные ниже аргументы
(пары аргументов) используют не для определения подпроцессов, а для перенаправления
потоков ввода и вывода между ними. В выражения типа ``< fileName''
fileName может писаться как отдельно, так и слитно (``<fileName>'').
| ≈ разделяет команды в конвейере.
Стандартный вывод предыдущей команды направляется на стандартный вход следующей
команды.
|& ≈ разделяет
команды в конвейере. Стандартный вывод и стандартный вывод ошибок предыдущей
команды направляются на стандартный вход следующей команды. Такое выражение
перебивает выражения типа ▒2>▓ и ▒>&▓.
< fileName ≈ файл
fileName
отрывается и используется как стандартный ввод для первой команды конвейера.
<@ fileId ≈ в этой
форме
fileId это идентификатор файла, открытого с помощью команды
open.
Он используется как стандартный ввод для первой команды конвейера. Файл
должен быть открыт для чтения.
<< value ≈ value
используется как стандартный ввод для первой команды конвейера.
> fileName ≈ Стандартный
вывод последней команды перенаправляется в файл fileName и перезаписывает
его содержимое.
2> fileName ≈ Стандартный
вывод ошибок всех команд в конвейере перенаправляется в файл
fileName
и перезаписывает его содержимое.
>& fileName ≈
Стандартный вывод последней команды и стандартный вывод ошибок всех команд
в конвейере перенаправляется в файл fileName и перезаписывает его
содержимое.
>>fileName ≈ Стандартный
вывод последней команды перенаправляется в файл fileName и добавляется
к его прежнему содержимому.
2>>fileName Стандартный
вывод ошибок всех команд в конвейере перенаправляется в файл fileName
и добавляется к его прежнему содержимому.>>& fileName ≈ Стандартный
вывод последней команды и стандартный вывод ошибок всех команд в конвейере
перенаправляется в файл fileName и добавляется к его прежнему содержимому.
>@ fileId ≈ в этой
форме fileId это идентификатор файла, открытого с помощью команды
open.
Стандартный вывод последней команды перенаправляется в файл fileName
и перезаписывает его содержимое. Файл должен быть открыт для записи.
2>@ fileId- в этой
форме fileId это идентификатор файла, открытого с помощью команды
open.
Стандартный вывод ошибок всех команд в конвейере перенаправляется в файл
fileName
и перезаписывает его содержимое. Файл должен быть открыт для записи.
>&@ fileId-
в этой форме
fileId это идентификатор файла, открытого с помощью
команды open. Стандартный вывод последней команды
и стандартный вывод ошибок всех команд в конвейере перенаправляется в файл
fileName
и перезаписывает его содержимое. Файл должен быть открыт для записи.
Если стандартный вывод последней
команды конвейера не был перенаправлен, то команда exec возвращает
его значение. Если одна из команд конвейера вернула код ошибки, была прервана
или приостановлена, то команда exec вернет код ошибки. При этом
сообщение об ошибке будет включать стандартный вывод конвейера и сообщение
об ошибке. В переменной
errorCode будет
записана дополнительная информация о последней встреченной ошибке. Если
хотя бы одна из команд конвейера пишет информацию об ошибках в файл и стандартный
вывод ошибок не перенаправлен, команда exec вернет ошибку, сообщение
об ошибке будет включать в себя стандартный вывод конвейера, дополненный
сообщениями об ошибках (если их было несколько) и стандартным выводом ошибок.
Если последний символ результата
исполнения конвейера или сообщения об ошибке ≈ перевод каретки, то он будет
удален из результата или сообщения соответственно. Это соответствует общему
правилу Tcl, по которому возвращаемая величина, как правило, не оканчивается
символом перевода каретки. Однако, если указана опция -keepnewline,
символ перевода каретки в конце сохраняется.
Если стандартный ввод конвейера
не перенаправлен с помощью символов ``<'', ``<<'' или ``<@'',
стандартный ввод в первую команду конвейера осуществляется со стандартного
ввода приложения.
Если последним аргументом
конвейера является '&', конвейер выполняется в фоновом режиме. В этом
случае команда exec возвращает список идентификаторов всех процессов
конвейера. Стандартный вывод последней команды конвейера, если он не перенаправлен,
выводится на стандартный вывод приложения. Стандартный вывод ошибок, если
он не перенаправлен, осуществляется в стандартный вывод ошибок приложения.
Первое слово в каждой команде
считается именем команды. В нем выполняются тильда ≈ подстановки. Если
получившийся при этом результат не содержит слешей, соответствующая команда
ищется в каталогах, перечисленных в переменной окружения PATH. Если имя
команды после подстановок содержит слеши, оно должно указывать на исполняемый
файл, доступный из текущего каталога. Никакие другие подстановки в командах,
например, принятые в shell подстановки ▒*▓ и '?', не выполняются.
ВОПРОСЫ ПЕРЕНОСИМОСТИ НА
ДРУГИЕ ПЛАТФОРМЫ Windows (все версии)
Чтение и запись с использование
``@
fileId'' не работают. Исполнение 16- и 32-разрядных приложений различается
между собой и отличается от описанного выше. Tk консоль не реализует всех
стандартных возможностей ввода/вывода.
В командах допускается использование
как прямых, так и обратных слешей при указании пути команды. Однако, если
путь является аргументом команды, это может оказаться и не так.
Двойной слеш в путях указывает
на сетевой адрес.
Windows NT
Для выполнения встроенных команд
shell, таких, как dir или copy, перед ними необходимо указать
``cmd.exe /c ''.
Windows 95
Для выполнения встроенных команд
shell, таких, как dir или copy, перед ними необходимо указать
``command.com /c ''.
Windows 3.X
Возможности команды exec
сильно ограничены.
Macintosh
Команда exec не реализована.
Unix
Команда exec позволяет
исполнять любые приложения и действует как описано выше.
exit
Команда exit прекращает
исполнение приложения.СИНТАКСИСexit?returnCode?ОПИСАНИЕПрекращает процесс и возвращает
системеreturnCode в качестве кода завершения. Если returnCode
не определен, то команда использует значение по умолчанию 0.
СИНТАКСИСexpr arg?arg
arg...?ОПИСАНИЕКоманда соединяет аргументыarg
через пробел в одно Tcl-выражение, вычисляет и возвращает его значение.
Допустимые в Tcl-выражениях операторы математических действий составляют
подмножество операторов языка С, и имеют такое же значение и порядок выполнения,
что и соответствующие операторы С. Почти всегда результатом вычисления
является число: целое или с плавающей запятой. Например, результат выражения
expr 8.2 + 6
равен ▒14.2▓.
Выражения в 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.
Более подробные описания
операторов можно найти в любом руководстве по языку С.
Операторы одного уровня приоритета
исполнения выполняются по очереди, слева направо. Например, команда
expr 4*2 < 7
возвращает результат ▒0▓.
Подобно языку C, операторы
'&&', '||', и '?:' имеют свойство ⌠ленивого вычисления■,
т.е., если операнд не нужен для получения результата, то он не вычисляется.
Например, в команде
expr {$v? [a] : [b]}
будет вычислено только одно
из выражений
[a] и [b], в зависимости от значения $v.
Однако, это справедливо только тогда, когда все выражение заключено в фигурные
скобки. В противном случае анализатор Tcl сначала вычислит [a] и
[b],
и только потом вызовет команду expr.МАТЕМАТИЧЕСКИЕ
ФУНКЦИИ 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 / 4
вернет ▒1▓, тогда как
expr 5 / 4.0
expr 5 / ( [string length
⌠abcd■] + 0.0 )
оба вернут ▒1.25▓.
Выражение
expr 20.0/5.0
вернет ▒4.0▓, а не ▒4▓.ОПЕРАЦИИ
СО СТРОКАМИ Операторы сравнения могут
работать со строковыми аргументами, хотя при вычислении выражений аргументы
по возможности интерпретируются как целые или числа с плавающей запятой.
Если один из операндов строковый, а другой ≈ число, то числовой операнд
будет конвертирован в строковый. Например, обе команды
expr {■0x03■ > ⌠2■}
expr {■0y■ < ⌠0x12■}
вернут ▒1▓. При этом
первое сравнение будет выполнено как сравнение чисел, а второе будет выполнено
как сравнение строк, после того как второй операнд будет преобразован в
строку ▒18▓.
Если необходимо сравнить
аргументы именно как строки, а операнды могут быть восприняты неоднозначно,
то рекомендуется использовать команду string compare вместо операторов
вида '=='.
ПРОИЗВОДИТЕЛЬНОСТЬ ПРИЛОЖЕНИЙ Байтовый компилятор Tcl
генерирует наиболее быстрый и компактный код, если выражения заключать
в скобки. Это связано с тем, что в общем случае, в выражениях подстановки
выполняются дважды: один раз ≈ грамматическим анализатором Tcl, и второй
раз ≈ командой expr. Наиболее трудным является случай, когда выражение
без фигурных скобок содержит подстановки команд.
fblocked
Проверяет, что предыдущая
операция ввода исчерпала всю информацию для ввода.
СИНТАКСИСfblocked channelIdОПИСАНИЕ
Команда fblocked возвращает
▒1▓, если последняя операция ввода по каналу channelId возвратила
меньше информации, чем было запрошено, поскольку вся доступная информация
уже исчерпана. Например, если команда gets вызвана,
когда для ввода доступны только три символа без символов конца строки,
команда gets вернет пустую строку, последующий
вызов команды fblocked вернет 1.
См. также gets
и read.
Fconfigure
fconfigure ≈ устанавливает
и читает опции канала.
СИНТАКСИСfconfigure channelId
fconfigure channelId
name
fconfigure channelId
name value?name value...?
ОПИСАНИЕ
Команда fconfigure устанавливает
и читает опции каналов. Аргумент channelId определяет конкретный
канал, с которым работает команда. Если аргументы name и value
отсутствуют, команда возвращает список, содержащий поочередно имена опций
и их значения для канала. Если имя опции указано, а значение ≈ нет, команда
возвращает текущее значение указанной опции. Если в команде указаны одна
или больше пар имен и значений, то команда устанавливает каждой из перечисленных
опций указанное значение. В этом случае команда возвращает пустую строку.
Описанные ниже опции поддерживаются
для всех типов каналов. Кроме того, каждый тип канала может иметь дополнительно
собственные опции. Они приведены в описаниях команд создания каналов, например,
в описании команды socket.-blockingbooleanОпция -blocking
определяет, вызывают ли команды ввода/вывода блокировку процесса. Величина
этой опции должна быть правильным булевым выражением. Обычно каналы открываются
в блокирующем режиме. Если канал переведен в неблокирующий режим, это окажет
влияние на выполнение команд gets,
read,
puts,
flush
и close (смотри описание соответствующих команд).
Чтобы работа в неблокиоующем режиме выполнялась корректно, в приложении
должен быть запущен обработчик событий (например, с помощью команды vwait).-bufferingnewValueЕсли аргумент newValue
равен
full, система ввода-вывода будет накапливать вывод в буфере,
пока буфер не заполнится целиком. После этого буфер будет выдан в канал.
Если аргумент newValue
равен line, система ввода-вывода будет выдавать буфер в канал каждый
раз при поступлении символа конца строки.
Если аргумент newValue
равен
none, система ввода-вывода будет выводить каждый символ сразу
после его поступления.
Значение по умолчанию full
для всех каналов, кроме устройств типа терминалов. Для них значение по
умолчанию
line.
-buffersizenewSizeАргумент newSize
должен быть целым числом. Его значение определяет размер буфера (в байтах),
используемый для данного канала. Величина newSize должна быть в
пределах от десяти до миллиона, что позволяет задавать величину буфера
от десяти до миллиона байт.-eofcharchar
-eofchar{inChar
outChar}
Эти опции поддерживают
структуру файлов DOS, в которой символ Control-z (\x1a) используется как
символ конца файла. Если аргумент char не равен пустой строке, то
этот символ, если он встречается во вводе, означает конец файла. При выводе
информации символ конца файла выдается при закрытии канала. Если аргумент
char
равен пустой строке, то специальный символ конца файла отсутствует. Для
каналов ввода-вывода элементы списка {inChar outChar} определяют
символы конца файла для ввода и вывода соответственно. Пользователь может
указать в списке единственный символ, который будет использоваться и для
ввода, и для вывода. Однако, при запросе команда возвратит текущие установки
в виде списка из двух одинаковых элементов. Значения по умолчанию для символов
конца файла ≈ пустая строка всегда, кроме файлов Windows. В этом случае
inChar
равно Control-z (\x1a), outChar ≈ пустой строке.-translationmode
-translation{inMode
outMode}
В Tcl-скриптах конец строки
всегда представляется единственным символом новой строки (\n). Однако,
в реальных файлах и устройствах конец строки может быть представлен разными
символами или наборами символов в зависимости от используемой платформы
или даже конкретного устройства. Например, на UNIX- платформах символ новой
строки используется в файлах, в то время как для сетевых соединений используется
последовательность ⌠возврат каретки ≈ новая строка■. При вводе данных (например,
при исполнении команд
gets или read)
система ввода ≈ вывода Tcl сама автоматически преобразует внешнее представление
конца строк во внутреннее представление (символ новой строки). При выводе
(например, при команде
puts) также происходит
преобразование ко внешнему формату представления конца строки. Значение
аргумента по умолчанию равно auto. При этом символы конца строки
для большинства ситуаций правильно определяются автоматически. Однако,
опция -translation позволяет при необходимости задать соответствующие
символы в явном виде.
Аргумент mode задает
представление конца строки для каналов, открытых только на чтение или только
на запись. Список {inMode outMode} определяет представление конца
строки для каналов ввода ≈ вывода. Пользователь может указать в списке
единственный символ, который будет использоваться и для ввода, и для вывода.
Однако, при запросе команда возвратит текущие установки в виде списка из
двух одинаковых элементов.
Поддерживаются следующие
значения опции:
autoПри вводе в качестве конца
строки могут использоваться символ возврата каретки (cr), символ
новой строки (lf), или их последовательность (crlf). Причем
разные строки могут заканчиваться по-разному. Все эти представления будут
переведены в символ новой строки. При выводе используется разное представление
для различных платформ и каналов. Для сетевых соединений на всех платформах
используется crlf, для всех Unix- платформ ≈ lf, для Macintosh
≈ cr, а для всех Windows-платформ ≈ crlf.binaryНикакого преобразования
символов конца строки не производится. Это значение опции очень схоже со
значением
lf, однако, при значении binary
пустая строка воспринимается как конец файла (см. описание опции -eofchar).crВ качестве символа конца
строки используется возврат каретки (cr). Соответственно, при вводе
символ возврата каретки преобразуется в символ новой строки, а при выводе,
наоборот, символ новой строки преобразуется в символ возврата каретки.
Это значение опции используется, обычно, на Macintosh-платформах.crlfВ качестве символа конца
строки используется последовательность ⌠возврат каретки ≈ новая строка■
(crlf). Соответственно, при вводе последовательность ⌠возврат каретки
≈ новая строка■ преобразуется в символ новой строки, а при выводе, наоборот,
символ новой строки преобразуется в последовательность ⌠возврат каретки
≈ новая строка■. Это значение опции используется обычно на Windows-платформах
и при сетевых соединениях.lfВ качестве символа конца
строки используется символ новой строки (lf). Никакого преобразования
символов конца строки при вводе и выводе не происходит. Это значение опции
используется, обычно, на UNIX-платформах.
См. также close(n),
flush(n),
gets(n),
puts(n),
read(n),
socket(n)
fcopy
Копирует данные
из одного канала в другой.
СИНТАКСИС
fcopy inchan outchan?-size
size??-command callback?ОПИСАНИЕКоманда fcopy копирует
данные из одного канала ввода ≈ вывода, заданного идентификатором канала
inchan,
в другой канал ввода ≈ вывода, заданный идентификатором канала outchan.
Команда позволяет упростить буфферизацию и избежать излишнего копирования
в Tcl-системе ввода ≈ вывода, а также избежать использования больших объемов
памяти при копировании данных по таким медленным каналам, как сетевые соединения.
Команда fcopy передает
данные из канала inchan, пока не будет достигнут конец файла или
не будет передано size байтов. Если аргумент -size
не задан, передается весь файл. Если опция -command не задана,
команда блокирует процесс до завершения копирования и возвращает число
переданных байтов.
При наличии аргумента -command
команда fcopy работает в фоновом режиме. Она завершается немедленно,
а команда callback вызывается позже, когда завершается процесс копирования.
Команда callback вызывается с одним или двумя дополнительными аргументами,
которые указывают число переданных байтов. Если при исполнении фонового
процесса произошла ошибка, второй аргумент ≈ строка описания ошибки. При
фоновом выполнении копирования каналы inchan и outchan не
обязательно открывать в неблокирующем режиме, команда fcopy выполнит
это автоматически. Однако при этом необходимо организовать обработку событий,
например, с помощью команды vwait или используя
Tk.
Не допускается выполнение
других операций ввода ≈ вывода с теми же каналами во время фонового копирования.
Если один из каналов во время копирования будет закрыт, процесс копирования
будет прерван и вызова команды callback не произойдет. Если будет
закрыт канал ввода данных, то все полученные данные, хранящиеся в очереди,
будут выданы в выходной канал.
Необходимо отметить, что
канал inchan может стать открытым на чтение во время копирования.
Все обработчики файловых событий во время фонового копирования должны быть
выключены, чтобы они не создавали помех копированию. Любые попытки ввода
≈ вывода с помощью обработчиков файловых событий будут завершены с ошибкой
⌠канал занят■.
Команда fcopy преобразует
символы конца строк в соответствии со значениями опций -translation
для соответствующих каналов (см. описание команды fconfigure).
Преобразование означает, в частности, что число прочитанных и число переданных
символов может отличаться. В синхронном режиме команда возвращает только
число переданных в outchan канал символов. В фоновом режиме только
это число подается на вход команды callback.
ПРИМЕРЫПервый пример показывает,
как в фоновом режиме получить число переданных байтов. Конечно, это показательный
пример, поскольку то же самое может быть сделано проще без использования
фонового режима.
proc Cleanup {in out bytes
{error {}}} {
global total
set total $bytes
close $in
сlose $out
if {[string length $error]!=
0} {
# error occurred during
the copy
}
}
#### Открыть файл на чтение
set in [open $file1]
#### Открыть сетевое соединение
set out [socket $server
$port]
#### Скопировать, по окончании
копирования вызвать Cleanup
fcopy $in $out -command
[list Cleanup $in $out]
#### Ожидать завершения
копирования
vwait total
Второй пример показывает, как
можно организовать копирование файла по фрагментам и проверять конец файла.
proc CopyMore {in out chunk
bytes {error {}}} {
global total done
incr total $bytes
if {([string length $error]!=
0) || [eof $in] {set done $total
close $in
close $out} else {fcopy $in $out -command
[list CopyMore $in $out $chunk] \-size $chunk}
}
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
См. также eof(n),
fblocked(n),
fconfigure(n)
file
Команда для работы
с файлами и их именами.
СИНТАКСИСfile option name?arg
arg...?ОПИСАНИЕЭта команда осуществляет
различные действия с файлами, их именами или свойствами. Аргумент name
содержит имя файла. Если он начинается с символа ⌠~■, то перед выполнением
команды выполняются ⌠тильда■-подстановки, как описано в filename
. Опция команды указывает, какие действия необходимо выполнить с файлом.
Ниже приведены возможные опции. В команде их имена могут быть сокращены
до уровня, сохраняющего уникальность их имен.
file
atimename
Возвращает десятичную строку,
содержащую время последнего доступа к файлу name. Время представляется
стандартным для POSIX образом в числе секунд от фиксированного начального
момента (обычно, с 1 января 1970 г.). Если файл не существует или время
последнего доступа не может быть получено, выдается сообщение об ошибке.file
attributes name
file attributesname?option?
file attributesname?option
value option value...?
Эта подкоманда возвращает
или устанавливает зависящие от платформы атрибуты файла. Первая форма возвращает
список атрибутов и их значений, вторая возвращает значение указанного атрибута,
а третья ≈ позволяет установить значения одного или нескольких атрибутов.
Возможные атрибуты перечислены ниже.НА UNIX-ПЛАТФОРМАХ:-group ≈ возвращает
или устанавливает имя группы. В команде группа может быть задана числовым
идентификатором, но возвращается всегда имя группы.
-owner ≈ возвращает
или устанавливает имя ⌠хозяина■ файла. В команде хозяин может быть задан
числовым идентификатором, но возвращается всегда имя хозяина.
-permissions
возвращает или устанавливает восьмеричный код, используемый командой операционной
системы chmod. Символьное описание соответствующих атрибутов файла не поддерживается.
НА WINDOWS-ПЛАТФОРМАХ
На Windows-платформах поддерживаются
атрибуты -archive,
-hidden, -longname (атрибут не
может быть установлен), -readonly,
-shortname (атрибут не
может быть установлен),
-system.НА MACINTOSH-ПЛАТФОРМАХ На Macintosh-платформах
поддерживаются атрибуты-creator, -hidden, -readonly, -type.
file
copy?-force??--? source target
filecopy ?-force??--?
source?source...? targetDir
Первая форма используется
для того, чтобы скопировать файл или каталог source соответственно
в файл или каталог target. Вторая форма используется, чтобы скопировать
файл(ы) или каталог(и) внутрь существующего каталога targetDir.
Если один из аргументов source есть имя каталога, то этот каталог
копируется рекурсивно вместе со всем его содержимым. При копировании существующие
файлы не перезаписываются, если только не указана опция -force.
Попытки перезаписать непустой каталог, а также перезаписать каталог файлом
или файл каталогом приводят к ошибке, даже если опция -force
указана.
Аргументы команды обрабатываются в порядке перечисления до первой ошибки.
Отметка ⌠--■ означает конец опций. Следующий аргумент считается именем
файла или каталога, даже если он начинается с символа ⌠-■.file
delete ?-force??--? pathname?pathname...?Удаляет файлы или каталоги,
заданные аргументами
pathname. Непустые каталоги удаляются, только
если задана опция
-force. Попытка удалить несуществующий
файл не рассматривается как ошибка. Попытка удалить файл, доступный только
для чтения, приведет к удаления файла, даже если опция
-force
не задана. Аргументы команды обрабатываются в порядке перечисления до первой
ошибки. Отметка ⌠--■ означает конец опций. Следующий аргумент считается
именем файла или каталога, даже если он начинается с символа ⌠-■.filedirname
nameВозвращает имя, составленное
из всех элементов
name, кроме последнего. Если name ≈ относительное
имя файла и состоит из единственного элемента, возвращает ⌠.■ (■:■ для
Macintosh). Если имя указывает на корневой каталог, возвращается имя корневого
каталога.
Например:
file dirname c:/
вернет ▒c:/▓.
⌠Тильда■-подстановки выполняются,
только если они необходимы для формирования правильного результата.
Например:
file dirname ~/src/foo.c
вернет ▒~/src▓, тогда
как
file dirname ~
вернет ▒/home▓ (или что-то
подобное).file
executable nameВозвращает ▒1▓,
если файл
name исполнимый, и ▒0▓ в противном случае.file existsnameВозвращает ▒1▓,
если файл
name существует, и пользователь имеет права на просмотр
каталога, в котором лежит файл, и ▒0▓ в противном случае.file
extension
nameВозвращает все символы
в name, начиная с последней точки в последнем элементе. Если в последнем
элементе нет точек, возвращается пустая строка.file isdirectorynameВозвращает ▒1▓,
если name ≈ имя каталога, и ▒0▓ в противном случае.
file isfile name
Возвращает ▒1▓, если
файл name ≈ регулярный файл, и ▒0▓ в противном случае.
file
join name?name...?
Соединяет аргументы name
в одно имя с помощью разделителя, используемого на данной платформе. Если
очередной аргумент
name представляет собой относительное имя, он
присоединяется к предыдущим, в противном случае предыдущие аргументы отбрасываются,
и процесс формирования имени начинается заново с текущего аргумента.
Например:
file join a b /foo bar
вернет ▒/foo/bar▓.
Аргументы name могут
содержать разделитель, это не помешает получить правильный результат для
используемой платформы (■/■ для Unix и Windows, ⌠:■ для Macintosh).
file
lstat name varName
То же самое, что опция
stat,
описанная ниже, за исключением того, что используется команда ядра lstat
вместо
stat. Это означает, что если name есть имя связи,
то команда вернет данные о связи, а не об исходном файле. Для платформ,
не поддерживающих связи, команды полностью идентичны.file
mkdir dir?dir...?Создает все перечисленные
каталоги. Для каждого аргумента dir команда создает все несуществующие
родительские каталоги и сам каталог dir. Если указан существующий
каталог, ничего не происходит. При этом команда считается выполненной успешно.
Попытка перезаписать существующий файл каталогом приведет к ошибке. Аргументы
команды обрабатываются в порядке перечисления до первой ошибки.file
mtimenameВозвращает десятичную строку,
содержащую время последнего изменения файла name. Время представляется
стандартным для POSIX образом в числе секунд от фиксированного начального
момента (обычно, с 1 января 1970 г.). Если файл не существует или время
последнего изменения не может быть получено, выдается сообщение об ошибке.file nativenamenameВозвращает имя файла в
виде, характерном для используемой платформы. Опция полезна для подготовки
исполнения файла с помощью команды
exec под
Windows.file ownednameВозвращает ▒1▓, если файл
name
принадлежит пользователю, и 0 в противном случае.file pathtypenameВозвращает одно из значений
absolute,
relative,
volumerelative. Если name
указывает на определенный файл в определенном томе, возвращается
absolute.
Если name указывает на имя файла относительно текущего рабочего
каталога ≈ возвращается
relative. Если name указывает имя
файла относительно текущего рабочего каталога в определенном томе или на
определенный файл в текущем рабочем томе, возвращается
volumerelative.file readablenameВозвращает ▒1▓,
если файл
name доступен для чтения пользователю, и ▒0▓ в
противном случае.file readlink nameВозвращает имя связи name
(например, имя файла, на который указывает name). Если name
не есть связь, или ее невозможно прочитать, возвращает ошибку. На платформах,
на которых связи не поддерживаются, опция не определена.file rename ?-force??--?
source target
Первая форма используется
для того, чтобы переименовать файл или каталог source соответственно
в файл или каталог target (и переместить их в соответствующий каталог,
если это необходимо). Вторая форма используется, чтобы переместить файл(ы)
или каталог(и) внутрь существующего каталога targetDir. Если один
из аргументов source есть имя каталога, то этот каталог перемещается
рекурсивно вместе со всем его содержимым. При перемещении существующие
файлы не перезаписываются, если только не указана опция -force.
Попытки перезаписать непустой каталог, а также перезаписать каталог файлом
или файл каталогом приводят к ошибке, даже если опция -force
указана. Аргументы команды обрабатываются в порядке перечисления до первой
ошибки. Отметка ⌠-■ означает конец опций. Следующий аргумент считается
именем файла или каталога, даже если он начинается с символа ⌠-■.file
rootname nameВозвращает все символы
в name за исключением последней точки в последнем элементе. Если
в последнем элементе нет точек, возвращается name.file size nameВозвращает десятичную строку,
содержащую размер файла в байтах. Если файл не существует или его размер
не может быть получен, выдается ошибка.file
split nameВозвращает список элементов
пути name. Первый элемент списка при этом имеет тот же тип пути, что и
name. Все остальные элементы ≈ относительные. Разделители удаляются, если
только они не необходимы для указания на относительный тип элементов. Например,
под Unix
file split /foo/~bar/baz
вернет ▒/ foo./~bar baz▓,
чтобы гарантировать, что последующие команды не попытаются выполнить ⌠тильда■-
подстановку в третьем элементеfile statname
varNameИсполняет вызов функции
ядра stat и записывает возвращаемую информацию о name в элементы
массива varName. Формируются следующие элементы массива: atime,
ctime, dev, gid, ino, mode, mtime, nlink, size, type, uid. Значения
всех элементов, кроме type, ≈ десятичные строки. Описания их приведены
в описании команды ядра stat. Элемент type содержит тип файла
в том же виде, в каком он возвращается командой file type. Команда
file
stat возвращает пустую строку.file
tail nameВозвращает все символы
в name после последнего разделителя каталогов. Если в name
нет каталогов, возвращает name.file typename
Возвращает строку, содержащую
тип файла. Возможные значения file, directory, characterSpecial, blockSpecial,
fifo, link
или
socket.file volumeВозвращает список, содержащий
абсолютные пути ко всем подмонтированным томам. На Macintosh-платформах
это список всех подмонтированных дисков, локальных и сетевых. На Unix-платформах
команда всегда возвращает '/', поскольку все файловые системы монтируются
как локальные. На Windows-платформах команда возвращает список локальных
дисков (например, {a:/ c:/}).file writablenameВозвращает ▒1▓, если файл
name
доступен для записи, и ▒0▓ в противном случае.
ПРОБЛЕМЫ ПЕРЕНОСИМОСТИUnix
На Unix-платформах эти команды
всегда используют реальные, а не эффективные идентификаторы пользователя
и группы.
Исполняет скрипт,
когда канал открывается на чтение или запись.
СИНТАКСИС
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.
Кроме того, при ошибке соответствующий обработчик событий удаляется. Это
делается для того, чтобы избежать зацикливания из-за ошибок в обработчике.
ВВЕДЕНИЕВсе команды Tcl и процедуры
С, использующие имена файлов в качестве аргументов, позволяют использовать
имена в форме, установленной для данной платформы. Кроме того, на всех
платформах Tcl поддерживается синтаксис UNIX с целью предоставления удобного
способа составления простых имен файлов. Тем не менее, скрипты, предназначенные
для переноса между платформами, не должны пользоваться конкретной формой
имен файлов. Вместо этого такие скрипты должны использовать команды file
splitи file joinдля преобразования
имен к нужной форме.ТИПЫ
ПУТЕЙ
Все имена файлов
поделены на три типа, в зависимости от начальной точки для отсчета пути:
абсолютные, относительные и имена внутри тома (volume-relative).
Абсолютные имена являются
самодостаточными, они содержат полный путь файла внутри тома и адрес корневого
каталога тома. Относительные имена являются неполными, они указывают положение
файла по отношению к текущему каталогу. Имена внутри тома занимают промежуточное
положение между первыми двумя, они указывают положение файла относительно
корневого каталога текущего тома или относительно текущего каталога указанного
тома.
Для определения типа указанного
пути можно использовать команду file pathtype.
СИНТАКСИС
ПУТЕЙ
Пути формируются
различным образом для различных платформ. Текущая платформа определяется
по значению переменной tcl_platform(platform):
mac
Для Macintosh-платформ
Tcl поддерживает две формы представления путей: с двоеточием, в обычном
для Macintosh стиле, и со слешем, в Unix-стиле. Если путь не содержит двоеточий,
то он считается путем в в Unix-стиле. При этом ⌠.■ означает текущий каталог,
⌠..■ ≈ родительский каталог для текущего каталога. Однако такие имена,
как ▒/▓' или ▒/..▓ считаются именами каталогов
в Macintosh-стиле. При этом команды, генерирующие имена файлов, возвращают
их в Macintosh-стиле, тогда как команды, использующие имена файлов, могут
получать их и в Macintosh-стиле, и в Unix-стиле.unixНа Unix-платформах используются
пути, которые содержат компоненты, разделенные символом слеш. Пути могут
быть абсолютными или относительными, имена файлов могут содержать любые
символы, кроме слеша. Имена файлов. и. являются специальными и обозначают
текущий каталог и родительский каталог текущего каталога, соответственно.
Несколько слешей подряд понимаются как один разделитель.
Ниже приведено несколько примеров
различных типов путей:
/
Абсолютный путь к корневому
каталогу./etc/passwdАбсолютный путь к файлу
passwd
к каталогу etc в корневом каталоге..Относительный путь к текущему
каталогу.fooОтносительный путь к файлу
foo
в
текущем каталогеfoo/barОтносительный путь к файлу
bar
в
подкаталоге
fooтекущего каталога../fooОтносительный путь к файлу
foo
в
каталоге над текущим.windowsДля Windows-платформ Tcl
поддерживает дисковые и сетевые имена. В обоих типах имен можно использовать
в качестве разделителя как прямой, так и обратный слеш. Дисковые имена
состоят из (при необходимости) имени диска и последующего абсолютного или
относительного пути. Сетевые пути обычно имеют вид \\servername\sharename\path\file.
В обеих формах ⌠.■ и ⌠..■ ссылаются соответственно на текущий
каталог и его предка."ТИЛЬДА"-ПОДСТАНОВКИ
В дополнение к правилам,
описанным выше, Tcl позволяет использовать ⌠тильда■ -подстановки в стиле
cshell. Если имя файла начинается с ▒~▓, за которой сразу следует
сепаратор, она заменяется на значение переменной окружения $HOME.
В противном случае символы от ⌠тильды■ до следующего разделителя интерпретируются
как имя пользователя и заменяются на имя домашнего каталога пользователя.
На Macintosh- и
Windows-платформах ⌠тильда■-подстановки с именем пользователя не поддерживаются.
При попытке использовать такое имя файла выдается ошибка. Однако ⌠тильда■
без имени пользователя заменяется, как и на Unix-платформах, на значение
переменной окружения $HOME.
ВОПРОСЫ
ПЕРЕНОСИМОСТИ
При разработке переносимых
приложений необходимо учитывать, что не все файловые системы различают
заглавные и прописные буквы. Поэтому следует избегать использования имен
файлов, различающихся только регистром букв. Кроме того, необходимо отказаться
от использования символов, имеющих специальное назначение хотя бы на одной
из платформ, например, ▒<▒, ▒>▒, ▒:▓,▓ ■ ▒, ▒/\▓, ▒|▓. А также,
если предполагается использовать программу на Windows 3.1, необходимо учитывать,
что имена файлов при этом должны быть ограничены восемью буквами, а расширения
≈ тремя.
flush
Команда организует
немедленную выдачу выходных данных в канал.
СИНТАНСИС flushchannelIdОПИСАНИЕКоманда направляет накопленные
в выходном буфере данные в канал с идентификатором channelId (значение
идентификатора возвращается командами открытия каналаopen
или socket), который должен быть открыт для
записи. Если канал находится в блокирующем режиме, то команда будет оставаться
незавершенной до тех пор, пока все содержимое буфера не будет отправлено
в канал. Если канал находится в неблокирующем режиме, то команда может
завершиться до окончания отправки выходных данных в канал. Остающиеся данные
будут передаваться в канал в фоновом режиме с такой скоростью, с какой
назначенный каналу файл или устройство сможет принимать их.
for
Команда for
организует цикл.
СИНТАНСИС forstart 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:
for {set x 0} {$x<10}
{incr x} {
puts ⌠x is $x■
}
foreach
Команда цикла по
элементам одного или нескольких списков.
ОПИСАНИЕКоманда организует выполнение
цикла, в котором переменные цикла последовательно принимают все значения
из списков значений. В простейшем случае имеется одна переменная цикла
varname
и один список значений
list
для присвоения переменной цикла. Аргумент
body
есть скрипт Tcl. Для каждого элемента списка
list, по очереди с
первого до последнего,
foreach присваивает содержимое очередного
элемента списка переменной
varname и затем вызывает интерпретатор
Tcl для исполнения body.
В общем случае в
команде может быть указано несколько списков значений (например, list1
и list2), и каждый из них может быть связан с одной переменной или
со списком переменных цикла (например,
varlist1 и varlist2).
Во время каждой итерации переменные каждого списка переменных принимают
значения последовательных элементов соответствующего списка значений. Значения
из списков значений используются последовательно от первого до последнего,
и каждое значение используется только один раз. Общее число итераций выбирается
таким, чтобы использовать все значения из всех списков значений. Если список
значений не содержит достаточного числа значений для всех связанных с ним
переменных цикла, вместо недостающих элементов используются пустые значения.
Внутри скрипта body
можно использовать команды
break и
continue,
аналогично
команде
for.
Команда foreachвозвращает
пустую строку.
ПРИМЕРЫ
В цикле используются
переменные цикла i и j для цикла по элементам одного списка
set x {}
foreach {i j} {a b c d e
f} {
lappend x $j $i
}
В результате величина x равна
⌠b a d c f e■.
При вычислении цикла используются
три итерации.
В цикле переменные
цикла i и j используются для различных списков значений.
set x {}
foreach i {a b c} j {d e
f g} {
lappend x $i $j
}
В результате величина x равна
⌠a d b e c f {} g■.
При вычислении цикла используются
четыре итерации.
Обе предыдущие формы скомбинированы
в следующем цикле
set x {}
foreach i {a b c} {j k}
{d e f g} {
lappend x $i $j $k
}
В результате величина x равна
⌠a d e b f g c {} {}■.
При вычислении цикла
используются три итерации.
format
Команда форматирует
строку в стиле процедуры
sprintf.
ВВЕДЕНИЕДанная команда создает
и возвращает программе форматированную строку так же, как это делает процедура
ANSI C sprintf (эта процедура используется в реализации команды). Подобно
sprintf,
formatString указывает с помощью спецификаторов преобразований,как
именно сформатировать результат, а возможные дополнительные аргументы предназначены
для подстановки в результат.
Команда немного
отличается от sprintf в части отдельных спецификаторов и ключей.
ПРОЦЕСС
ФОРМИРОВАНИЯКоманда просматривает строку
formatString
слева направо. Все символы из строки непосредственно переносятся в результирующую
строку, кроме символа ▒%▓ и следующих непосредственно за ним. Такая
последовательность символов рассматривается как спецификатор преобразования.
Этот спецификатор управляет преобразованием очередного аргумента arg
в указанный формат, после чего тот добавляется к результирующей строке
вместо соответствующего спецификатора. Если в строке
formatString
содержится несколько спецификаторов, каждый из них управляет преобразованием
одного дополнительного аргумента. Число таких аргументов должно быть достаточным
для всех спецификаторов в строке.
Каждый из спецификаторов
преобразования может содержать до шести различных частей: указатель позиции,
набор флагов, минимальная ширина поля, точность, преобразователь длины
и тип преобразования. Любые из полей, кроме типа преобразования, могут
отсутствовать. Ниже обсуждаются соответствующие разделы спецификаторов.
УКАЗАТЕЛЬ
ПОЗИЦИИ
Если за символом
▒%▓ следуют целое число и знак ▒$▓, как например в
▒%2$d▓, то величина для преобразования берется не из следующего
аргумента, а из аргумента, занимающего соответствующую позицию в списке
(▒1▓ соответствует первому аргументу arg). Если спецификатор
преобразования требует нескольких аргументов (когда он содержит символ
▒*▓), то используются последовательные аргументы, начиная с указанного.
Если один из спецификаторов содержит указание позиции аргумента, то и все
остальные спецификаторы должны его содержать.
ФЛАГИ
ПРЕОБРАЗОВАНИЯВторой раздел спецификатора
может содержать в произвольном порядке любые флаги из перечисленных ниже.
-
Указывает,
что соответствующий аргумент будет выровнен влево (числа обычно выравниваются
вправо с добавлением лидирующих пробелов при необходимости).
+
Указывает,
что числа всегда будут вставлены со знаком, даже если они положительные.
space
Указывает,
что перед числом будет добавлен пробел, если первый символ не знак.
0
Указывает,
что число будет выровнено с добавлением лидирующих нулей.
#
Указывает
на использование альтернативной формы вывода. Для ▒o▓ и ▒O▓
преобразований гарантирует, что первой цифрой всегда будет ▒0▓.
Для ▒x▓ и ▒X▓ преобразований ≈ что 0x или 0X
соответственно будет добавлен в начало числа. Для ▒e▓, ▒E▓, ▒f▓, ▒g▓,
и ▒G▓ ≈ что в числе будет использована десятичная точка. Для ▒g▓
и ▒G▓ ≈ что конечные нули не будут отброшены.
МИНИМАЛЬНАЯ
ШИРИНА ПОЛЯТретья часть спецификатора
преобразования представляет собой число, задающее минимальную ширину поля
для данного преобразования. Обычно она используется для формирования данных
в таблицу. Если преобразуемое значение не содержит указанного числа символов,
одно будет дополнено до необходимого размера. Обычно поле заполняется пробелами
слева, однако, указанные выше флаги '0' и '≈' позволяют заполнять
его нулями слева или пробелами справа. Если минимальная ширина поля указана
как ▒*▓, а не как число, то в качестве числового значения используется
значение следующего аргумента в команде.ТОЧНОСТЬ
Четвертая часть
спецификатора определяет точность представления чисел. Она состоит из точки
и последующего числа. Число имеет различный смысл при различных преобразованиях.
Для ▒e▓, ▒E▓ и ▒f▓ преобразования оно определяет число цифр
справа от десятичной точки. Для ▒g▓ и ▒G▓ ≈ общее число чисел
слева и справа от десятичной точки (однако, конечные нули будут обрезаться,
если не указан флаг ▒#▓). Для целочисленных преобразований оно определяет
минимальное число символов (при необходимости будут добавляться лидирующие
нули). Для ▒s▓ преобразований определяет максимальное число символов,
которое будет выводиться. Если строка длиннее, конечные символы будут отброшены.
Если точность указана как ▒*▓, а не как число, то в качестве числового
значения используется значение следующего аргумента в команде.
ПРЕОБРАЗОВАТЕЛЬ
ДЛИНЫПятая часть спецификатора
может принимать значения ▒h▓или ▒l▓. Значение ▒h▓
означает, что все числовые значения предварительно обрезаются до 16 бит.
Значение ▒l▓ означает, что никаких предварительных преобразований
не производится.ТИП
ПРЕОБРАЗОВАНИЯ
Последняя часть
спецификатора представляет собой букву, которая определяет тип преобразования.
Допускаются следующие значения.
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▓.
%
Просто
подставляет символ ▒%▓.
Для числовых преобразований
аргумент должен быть целым числом или десятичным с плавающей точкой. Аргумент
преобразуется в двоичное число, а затем преобразуется обратно в строку
в соответствии с указанным типом преобразования.
ОТЛИЧИЯ
ОТ ANSI SPRINTF
Поведение команды
format
отличается от процедуры sprintf в следующих моментах:
▒%p▓ и ▒%n▓
типы не поддерживаются
Для ▒%c▓ аргумент
должен быть десятичным числом.
При преобразованиях длины
значение
l игнорируется.
gets
Команда читает строку из
канала.СИНТАКСИСgetschannelId?varName?ОПИСАНИЕКоманда gets читает
из канала channelId очередную строку символов. Если имя переменной
varName
не задано, тогда команда возвращает полученную строку за исключением символов
конца строки. Если varName задано, тогда команда записывает полученную
строку в переменную и возвращает количество символов в принятой строке.
Если при поиске
конца строки был обнаружен конец файла, команда возвращает всю полученную
информацию вплоть до конца файла.
Если канал находится в неблокирующем
режиме и поступила неполная входная строка, то команда не использует поступившие
данные и возвращает пустую строку.
Если указана переменная varName
и возвращается пустая строка из-за конца файла или из-за неполноты полученной
строки, команда возвращает √1.
Обратите внимание, что если
аргумент
varName не задан, конец файла и неполная строка приведут
к тому же результату, что и строка, состоящая из символа конца строки.
Команды eof и fblocked
позволяют различить эти ситуации.
Команда glob
выполняет поиск имен файлов подобно тому, как это делает оболочка csh,
и возвращает список имен, удовлетворяющих шаблону pattern. Аргументы,
начинающиеся со знака ▒-▓, являются управляющими ключами switches.
Возможные ключи:
-nocomplainПозволяет вернуть пустой
список без генерации ошибки. Если ключ не задан, то при пустом списке формируется
ошибка.--Означает конец ключей.
Аргумент после этого ключа считается шаблоном, даже если он начинается
с ▒-▓.
Шаблоны могут включать следующие
специальные символы:
? √ Удовлетворяет
любому символу;
* ≈ Удовлетворяет
любой последовательности из нуля или больше символов;
[chars]
√ Удовлетворяет любому символу из chars. Если chars включает
последовательность символов типа ▒a-b▓, то удовлетворяет всем символам
от ▒a▓ до ▒b▓
(включительно).
\x √ Удовлетворяет
символу ▒x▓.
{a,b,...}
√ Удовлетворяет любой из строк ▒a▓, ▒b▓, и т.д.
Как и в csh, символ ▒.▓
в начале имени файла или сразу после ▒/▓ должен соответствовать
явно или с помощью конструкции ⌠{}■.
Если первый символ образца
▒~▓, то он указывает на домашний каталог пользователя, чье имя указано
после ▒~▓. Если сразу после ▒~▓ идет ▒/▓, то используется
значение переменной окружения HOME.
Действие команды glob
отличается от работы в csh в следующем:
она не сортирует составленный
ей список;
она возвращает имена только
существующих файлов (в csh проверку наличия файлов надо задавать отдельно,
если только шаблон не содержит символов ▒?▓, ▒*▓, или ▒[]▓).
ОСОБЕННОСТИ РАБОТЫ НА РАЗЛИЧНЫХ
ПЛАТФОРМАХ
В отличие от другихTcl-команд
команда
glob может работать с именами файлов только в нотации, поддерживаемой
на той платформе, на которой она исполняется. Кроме того, на Windows-платформах
специальные символы не допустимы в сетевых именах.
global
Команда для объявления
глобальных переменных.
СИНТАКСИСglobalvarname?varname
┘?ОПИСАНИЕ
Данная команда выполняется
только при выполнении процедуры, а в остальных случаях игнорируется. Команда
объявляет переменныеvarname глобальными. Глобальные переменные ≈
это переменные глобальной области имен.
Только в течение
работы данной процедуры и только при выполнении в данной процедуре любая
ссылка на значение любого из аргументов
varname будет указывать
на одноименную глобальную переменную.
Команда работает со списком
выполнявшихся команд.СИНТАКСИСhistory?option??arg
arg ┘?ОПИСАНИЕКоманда history
выполняет действия по отношению к недавно выполненным командам, занесенным
в журнал. Каждая из этих зарегистрированных команд обозначается термином
⌠событие■. Ссылаться на события в команде history можно одним из
следующих способов:
Число. Если положительное
≈ ссылается на событие с этим номером (все события нумеруются начиная с
1). Если число отрицательное, то оно указывает номер события относительно
текущего (▒-1▓ ≈ предыдущее, ▒-2▓ ≈ перед предыдущим и т.д.).
Событие ▒0▓ ссылается на текущее событие.
Строка. Ссылается
на наиболее позднее событие, которое удовлетворяет строке. Событие удовлетворяет
строке, если оно начинается со строки, или в соответствии с правилами команды
string
match.
Команда history может
принимать одну из следующих форм.
history
То же самое, что команда
history
info, описанная ниже.
history addcommand?exec?
Добавляет аргумент command
в журнал как новое событие. Если присутствует аргумент exec(или
произвольное сокращение), то команда command выполняется и возвращается
ее результат. В противном случае возвращается пустая строка.history changenewValue?event?Заменяет описание события
event
на newValue. Аргумент event определяет событие, описание
которого будет заменено. По умолчанию ≈ текущее событие (даже не предыдущее!).
Эта форма команды предназначается для использования в тех случаях, когда
переформировывается журнал событий и позволяет заменить текущее событие
(переформирование журнала) на необходимое. Команда возвращает пустую строку.history clearУдаляет журнал событий.
Количество запоминаемых событий (см. history keep) сохраняется.
Нумерация событий начинается сначала.history event?event?Возвращает описания события
event.
Значение по умолчанию ▒-1▓.
history info?count?
Возвращает в удобном для
чтения виде список, состоящий из номеров и описаний событий (кроме текущего).
Если аргумент count задан, то только count последних событий
возвращаются.history keep?count?Команда изменяет размер
журнала на
count событий. Исходно в журнале сохраняются 20 последних
событий. Если аргумент
count не указан, команда возвращает текущее
значение размера журнала.history nextidВозвращает номер следующего
события, которое будет записано в журнал. Полезно, например, для вывода
номера события в приглашении командной строки.history redo?event?
Повторно выполняет команду,
указанную с помощью аргумента event. Значение аргумента по умолчанию
▒-1▓. Эта команда вызывает переформирование журнала, см. ниже.
ПЕРЕФОРМИРОВАНИЕ
ЖУРНАЛА
До версии 8.0 Tcl
имел весьма сложный механизм переформирования журнала. Новый механизм несколько
сокращен за счет старых опций substitute и words. (Взамен
добавлена новая опция clear)
Опция redo позволяет
переформировывать журнал значительно проще. При ее выполнении последнее
событие изменяется таким образом, что удаляется ⌠служебная■ команда history,
которая реально выполнялась, а вместо нее записывается та команда, которая
необходима.
Если вы хотите повторить
прежнюю команду, не модифицируя журнал, выполните сначала команду history
event, чтобы извлечь описание команды, а затем history add,
чтобы выполнить ее.
if
Команда if
проверяет соблюдение условия в ходе выполнения скрипта.
СИНТАКСИСif expr1?then?
body1elseifexpr2?then?
body2elseif
┘?else??bodyN?ОПИСАНИЕКоманда вычисляет значение
выражения expr1 (Точно так, как это делает команда expr).
Это и все остальные выражения expr должны быть булева типа (то есть
это должна быть числовая величина, причем 0 соответствует false,
а все остальные значения √ true, либо строка со значениями true
или yes для true и false или no для false).
Если выражение равно true, то скрипт body1 передается на
выполнение интерпретатору Tcl. Если нет, то вычисляется значение выражения
expr2,
и если оно равно true, то исполняется body2, и так далее.
Если ни одно из выражений не равно true, тогда выполняется
bodyN.
Слова then и
else
необязательны
и используются только для простоты понимания команды. Аргумент bodyNтакже
может отсутствовать, если отсутствует else.
Команда возвращает значение
выполненного скрипта или пустую строку, если ни одно из выражений не было
равно true, и bodyN отсутствовал.
incr
Команда увеличивает значение
переменной на заданную величину.СИНТАКСИСincrvarName?increment?ОПИСАНИЕКоманда incr увеличивает
значение переменной varName на величину increment. И значение
переменной, и increment должны быть целыми числами. По умолчанию
increment
равно 1. Новое значение переменной сохраняется в виде десятичной строки
и одновременно возвращается командой.
info
Команда сообщает
сведения о состоянии интерпретатора Tcl.
СИНТАКСИС
infooption?arg
arg...?
ОПИСАНИЕ
Эта команда обеспечивает
доступ к внутренней информации Tcl-интерпретатора. Ниже перечислены поддерживаемые
опции (имена которых могут быть сокращены).
info argsprocname
Возвращает список имен
аргументов процедуры procname в том порядке, в котором они определены
при описании процедуры. Аргумент
procname должен содержать имя Tcl-процедуры.info bodyprocname Возвращает тело процедуры
procname.
Аргумент
procname должен содержать имя Tcl-процедуры.
info cmdcount
Возвращает полное число
команд, введенных в данный интерпретатор.info commands?pattern?Если аргумент pattern
не задан, возвращает полный список команд в текущем пространстве имен,
включая как встроенные команды, написанные на C, так и процедуры, заданные
с помощью команды proc. Если аргумент pattern
задан, возвращается список только тех имен, которые удовлетворяют шаблону
pattern.
Правила использования шаблонов такие же, как в команде
string match.
Шаблон может быть полным именем, например Foo::print*. То есть он
может задавать определенное пространство имен и шаблон в нем. В этом случае
каждая команда в возвращаемом списке будет представлена полным именем с
указанием пространства имен.info completecommandВозвращает ▒1▓,
если команда
command есть завершенная Tcl-команда, то есть не содержит
⌠незакрытых■ кавычек, квадратных или фигурных скобок и имен массивов. В
противном случае возвращается ▒0▓. Эта команда обычно используется
при построчном вводе команд пользователем для того, чтобы позволить ему
вводить команды из нескольких строк. Для этого, если введенный скрипт не
представляет собой законченную команду, его исполнение откладывается до
завершения следующей строки.info defaultprocname
arg varname
Аргумент procname
должен быть именем Tcl-процедуры, а аргумент arg ≈ именем одного
из аргументов этой процедуры. Если указанный аргумент не имеет значения
по умолчанию, команда возвращает ▒0▓. В противном случае команда
возвращает ▒1▓ и помещает значение по умолчанию в переменную varname.
info exists
varName
Возвращает ▒1▓,
если переменная
varName существует в текущем контексте как локальная
или как глобальная переменная. В противном случае возвращает ▒0▓.info globals?pattern? Если аргумент pattern
не задан, возвращает список имен определенных в данный момент глобальных
переменных (переменных, определенных в глобальном пространстве имен). Если
шаблон задан, возвращаются только имена, удовлетворяющие шаблону. Правила
использования шаблонов такие же, как в команде string match.info hostname Возвращает имя компьютера,
на котором выполняется этот вызов.info
level
?number? Если аргумент number
не задан, возвращает уровень стека выполняемой процедуры, или ▒0▓,
если команда выполняется на верхнем уровне. Если аргумент number
указан, команда возвращает список, состоящий из имени и аргументов процедуры,
находящейся в стеке вызовов на соответствующем месте. Если number
положительное число, оно указывает номер уровня в стеке (▒1▓ ≈ самая верхняя
вызванная процедура, ▒2▓ ≈ процедура, вызванная из процедуры ▒1▓, и так
далее), если же number отрицательное, оно указывает уровень относительно
уровня выполняемой процедуры ('0▓ ≈ выполняемая процедура, ▒-1▓ ≈ процедура,
из которой вызвана исполняемая, и так далее). Более подробно уровни стека
описаны в uplevel .info
libraryВозвращает имя каталога,
в котором хранятся стандартные Tcl-скрипты. Обычно совпадает со значением
переменной
tcl_library и может быть изменено с помощью переопределения
этой переменной. Дополнительная информация приведена в tclvarsinfo loaded?interp?Возвращает список библиотек
(package), загруженных в интерпретатор с помощью команды load.
Каждый элемент списка представляет собой подсписок из двух элементов: имени
файла и имени библиотеки. Для статически загруженных библиотек имя файла
отсутствует. Если имя интерпретатора
interp отсутствует, возвращается
список всех библиотек, загруженных во все интерпретаторы. Чтобы получить
список библиотек, загруженных в текущий интерпретатор, используйте пустую
строку в качестве аргумента interp.info locals?pattern?Если образец не задан,
возвращает имена всех определенных в текущий момент локальных переменных,
включая аргументы процедуры, если они есть. Переменные, заданные с помощью
команд
global и upvar,
не возвращаются. Если шаблон задан, возвращаются только имена, удовлетворяющие
шаблону. Правила использования шаблонов такие же, как в команде string
match.info nameofexecutable Возвращает полное имя бинарного
файла, с помощью которого приложение было запущено. Если Tcl не может определить
файл, возвращается пустая строка.info
patchlevel Возвращает значение глобальной
переменной
tcl_patchLevel. См. также раздел tclvars.info procs?pattern? Если аргумент pattern
не задан, возвращает полный список Tcl-процедур в текущем пространстве
имен. Если аргумент pattern задан, возвращается список только тех
имен, которые удовлетворяют шаблону
pattern. Правила использования
шаблонов такие же, как в команде string match.info scriptЕсли в данный момент обрабатывается
Tcl-скрипт (например, вызванный с помощью команды source),
то команда возвращает имя файла, содержащего самый внутренний обрабатываемый
скрипт. В противном случае возвращает пустую строку.info sharedlibextension Возвращает расширение,
используемое на текущей платформе для файлов разделяемых библиотек (например,.so
для Solaris). Если разделяемые библиотеки на текущей платформе не поддерживаются,
возвращает пустую строку.info
tclversion Возвращает значение глобальной
переменной
tcl_version. Дополнительная информация приведена в tclvars.info vars?pattern?
Если аргумент pattern
не задан, возвращает список имен всех видимых в текущий момент переменных,
включая локальные и видимые глобальные. Если аргумент pattern задан,
возвращается список только тех имен, которые удовлетворяют шаблону pattern.
Правила использования шаблонов такие же, как в команде stringmatch.
Шаблон может быть полным именем, например Foo::option*. То
есть он может задавать определенное пространство имен и шаблон в нем. В
этом случае каждая команда в возвращаемом списке будет представлена полным
именем с указанием пространства имен.
interp
Команда создает
и управляет 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
Возвращает список, состоящий
из исходной команды и аргументов, связанных с алиасом srcCmd в интерпретатореsrcPath
(возвращаются значения, использовавшиеся при создании алиаса, так как имя
команды могло быть изменено с помощью команды rename).interp aliassrcPath
srcCmd {}Удаляет алиас srcCmd
в подчиненном интерпретаторе
srcPath. Имя srcCmd ≈ это имя,
под которым алиас был создан. Если созданная команда была переименована,
то будет удалена переименованная команда.interp aliassrcPath
srcCmd targetPath targetCmd?arg arg...?
Эта команда создает
алиас между двумя подчиненными интерпретаторами (для создания алиаса между
подчиненным интерпретатором и мастер-интерпретатором используется команда
slave
alias). Оба интерпретатора srcPath и targetPath должны
быть в иерархии интерпретаторов ниже того интерпретатора, в котором выполняется
команда. Аргументы srcPath и srcCmd задают интерпретатор,
в котором будет создан алиас и его имя. Аргумент srcPath должен
быть Tcl-списком, задающим имя существующего интерпретатора. Например,
⌠a b'' определяет интерпретатор b, который является подчиненным
интерпретатором интерпретатора
a, который в свою очередь является
подчиненным интерпретатором текущего интерпретатора. Пустой список соответствует
текущему интерпретатору (в котором исполняется команда). Аргумент srcCmd
определяет имя новой команды-алиаса, которая будет создана в интерпретаторе
srcPath. Аргументы targetPath и targetCmd определяют
целевой интерпретатор и команду, а аргументы
arg, если они есть,
определяют дополнительные аргументы для команды
targetCmd, которые
будут вставлены перед аргументами, заданным при вызове srcCmd. Команда
targetCmd
может как существовать, так и не существовать в момент создания алиаса.
В последнем случае она не создается командой
interp alias.
Алиас позволяет использовать
команду
targetCmd в интерпретаторе targetPath каждый раз,
когда вызывается команда-алиасsrcCmd в интерпретаторе srcPath.
Подробнее см. ⌠Использование алиасов■.interp aliases?path?Эта команда возвращает
список имен всех команд-алиасов, определенных в интерпретаторе path.interp create?-safe??--??path?Создает подчиненный интерпретатор
с именем path и новую команду для работы с этим интерпретатором,
называемую также подчиненной (slave) командой. Имя подчиненной команды
совпадает с последним элементом списка path. Новый подчиненный интерпретатор
и подчиненная команда создаются в интерпретаторе, имя которого состоит
из всех элементов списка
path, кроме последнего. Например, если
аргумент path равен
a b c, то в результате в интерпретаторе
a
b будет создан подчиненный интерпретатор
c и подчиненная команда
c.
Синтаксис подчиненной команды описан ниже см. ⌠Команда работы с интерпретатором■.
Если аргумент path отсутствует, Tcl создает уникальное имя в форме
interpx,
где x ≈ целое число, и использует его для подчиненного интерпретатора
и подчиненной команды. Если в команде указана опция -safe
или если мастер-интерпретатор сам является безопасным интерпретатором,
новый подчиненный интерпретатор будет безопасным, то есть с ограниченной
функциональностью. В противном случае новый интерпретатор будет включать
полный набор встроенных Tcl-команд и переменных. Аргумент - используется
для того, чтобы обозначить конец опций. Следующий аргумент будет использоваться
как имя интерпретатора, даже если он равен -safe.
Команда interp create
возвращает имя нового интерпретатора. Имя подчиненного интерпретатора должно
быть уникальным среди подчиненных интерпретаторов его мастера. Если у мастер-идентификатора
уже существу
interp delete?path...?Удаляет ноль или больше
интерпретаторов с именем
path. Для каждого удаляемого интерпретатора
удаляются также его подчиненные интерпретаторы. Если для одного из аргументов
path
интерпретатора с таким именем не существует, команда генерирует ошибку.interp evalpath
arg?arg...?Команда объединяет все
аргументы так же, как команда
concat, а затем
исполняет сформированный скрипт в подчиненном интерпретаторе, заданном
аргументом path. Результат выполнения (включая информацию об ошибках
в переменных errorInfo и errorCode,
если произошла ошибка) возвращается в вызывающий интерпретатор.interp
existspathВозвращает ▒1▓,
если подчиненный интерпретатор с именем path существует в его мастер-интерпретаторе.
В противном случае возвращает ▒0▓. Если аргумент path представляет
относительное имя, то он ищется в том интерпретаторе, в котором выполняется
команда.interp
expose path hiddenName?exposedCmdName?Разрешает использование
в интерпретаторе
path скрытой команды hiddenName под новым
именем exposedCmdName (в настоящее время поддерживаются только имена
в глобальном пространстве имен, не содержащие ⌠::■). Если обычная
(не скрытая) команда exposedCmdName уже существует, генерируется
сообщение об ошибке. Скрытые команды обсуждаются подробно см. ⌠Скрытые
команды■.interp
hidepath exposedCmdName?hiddenCmdName?Запрещает использование
в интерпретаторе
path обычной команды exposedCmdName и переименовывает
ее в скрытую команду
hiddenCmdName (или в скрытую команду под старым
именем, если новое не было задано). Если скрытая команда с заданным именем
уже существует, команда возвращает ошибку. В настоящее время exposedCmdName
и hiddenCmdName не могут содержать ⌠::■. Команды, которые
должны быть скрыты с помощью
interp hide, ищутся только в глобальном
пространстве имен, даже если текущее пространство имен не глобальное. Скрытые
команды обсуждаются подробно ниже (см. ⌠Скрытые
команды■).interp hiddenpathВозвращает список скрытых
команд интерпретатора
path.interp invokehidden
path?-global? hiddenCmdName?arg...?Вызывает в интерпретаторе
path
скрытую команду
hiddenCmdName с перечисленными аргументами. Никаких
подстановок или вычислений в аргументах не производится. Если указана опция
-global,
скрытая команда выполняется на глобальном уровне в целевом интерпретаторе.
В противном случае она выполняется в текущем контексте и может использовать
значения локальных переменных и переменных из вышестоящих стеков. Скрытые
команды обсуждаются подробно в соответствующем разделе ниже.interp issafe?path?Возвращает ▒1▓,
если интерпретатор path безопасный, и ▒0▓ в противном случае.interp marktrustedpathОтмечает интерпретатор
path
как надежный. Не раскрывает скрытые команды. Команда interp marktrusted
может выполняться только из надежного интерпретатора. Если интерпретатор
path
уже надежный, команда не оказывает никакого воздействия.interp sharesrcPath
channelId destPathПозволяет разделить канал
ввода ≈ вывода channelId между интерпретаторами srcPath и
destPath.
Оба интерпретатора после этого будут иметь одинаковые права на канал. Каналы
ввода ≈ вывода, доступные в интерпретаторе, автоматически закрываются,
когда удаляется интерпретатор.interp slaves?path?Возвращает список подчиненных
интерпретаторов для интерпретатора path. Если аргумент path
отсутствует, возвращает список подчиненных интерпретаторов для интерпретатора,
в котором выполняется команда.interp targetpath
aliasВозвращает список, описывающий
целевой интерпретатор (интерпретатор, в котором выполняется реальная команда
при вызове команды-алиаса) для алиаса alias. Алиас задается именем
интерпретатора
path и команды-алиаса alias как в команде
interp
alias выше. Имя целевого интерпретатора возвращается как имя интерпретатора
относительно имени интерпретатора, в котором выполняется команда. Если
это текущий интерпретатор, то возвращается пустой список. Если этот интерпретатор
не является потомком интерпретатора, в котором выполняется команда, генерируется
ошибка. Реальная команда не обязана быть определена в момент выполнения
данной команды.interp transfersrcPath
channelId destPathДелает канал ввода ≈ вывода
channelId
доступным в интерпретаторе destPath и недоступным в интерпретаторе
srcPath.КОМАНДА
РАБОТЫ С ИНТЕРПРЕТАТОРОМ (ПОДЧИНЕННАЯ КОМАНДА)
Для каждого подчиненного
интерпретатора, созданного с помощью команды interp, в мастер-интерпретаторе
создается команда с тем же именем, что и подчиненный интерпретатор. Эта
команда предназначена для выполнения различных операций в подчиненном интерпретаторе.
В общем случае она имеет следующий вид:
slave command?arg
arg...?
где slave ≈ имя подчиненного
интерпретатора, а аргументы command и arg arg... определяют
конкретное назначение команды. Ниже перечислены возможные формы команды.
slave aliases
Возвращает список всех
алиасов в подчиненном интерпретаторе
slave. Возвращаемые имена ≈
это имена, использовавшиеся при создании соответствующих алиасов. Они могут
не совпадать с текущими именами команд, если те были переименованы.slave alias
srcCmdВозвращает список, состоящий
из имени реальной команды и ее аргументов, ассоциированных с алиасом srcCmd.
Возвращаются те же значения, что и в команде создания алиаса. Если созданный
алиас был переименован, то в команде надо указывать имя srcCmd,
которое использовалось при создании алиаса.slave alias
srcCmd
{}Удаляет алиас srcCmd
в подчиненном интерпретаторе. Аргумент srcCmd указывает имя алиаса
в момент создания. Если после этого он был переименован, удалится переименованная
команда.slave alias
srcCmd targetCmd?arg..?Эта команда создает команду
≈ алиас в подчиненном интерпретаторе. Каждый раз, когда в подчиненном интерпретаторе
будет вызываться команда srcCmd, реально выполняться будет команда
targetCmd
в мастер-интерпретаторе. Аргументы arg, если они есть, определяют
дополнительные аргументы для команды targetCmd, которые будут вставлены
перед аргументами, заданными при вызове srcCmd. Подробнее см. ⌠Использование
алиасов■.slave eval
arg?arg..?Эта команда объединяет
все свои аргументы так же, как команда concat,
и выполняет сформированный таким образом скрипт в подчиненном интерпретаторе.
Результат выполнения (включая информацию об ошибках в переменных errorInfoи
errorCode,
если произошла ошибка) возвращается в вызывающий интерпретатор.slave expose
hiddenName?exposedCmdName?Разрешает использование
в подчиненном интерпретаторе скрытой команды hiddenName под новым
именем exposedCmdName (в настоящее время поддерживаются только имена
в глобальном пространстве имен, не содержащие ⌠::■). Если обычная
(не скрытая) команда exposedCmdName уже существует, генерируется
сообщение об ошибке. Скрытые команды обсуждаются ниже (см. ■Скрытые
команды ■).slave hide
exposedCmdName?hiddenCmdName?Запрещает использование
в подчиненном интерпретаторе обычной команды exposedCmdName и переименовывает
ее в скрытую команду
hiddenCmdName (или в скрытую команду под старым
именем, если новое не было задано). Если скрытая команда с заданным именем
уже существует, команда возвращает ошибку. В настоящее время exposedCmdName
и hiddenCmdName не могут содержать ⌠::■. Команды, которые
должны быть скрыты с помощью
interp hide, ищутся только в глобальном
пространстве имен, даже если текущее пространство имен не глобальное. Скрытые
команды обсуждаются ниже (см.
■Скрытые команды
■).slave hiddenВозвращает список скрытых
команд в подчиненном интерпретаторе.slave invokehidden?-global
hiddenName?arg..?Вызывает в подчиненном
интерпретаторе скрытую команду
hiddenCmdName с перечисленными аргументами.
Никаких подстановок или вычислений в аргументах не производится. Если указана
опция
-global, скрытая команда выполняется на глобальном
уровне в подчиненном интерпретаторе. В противном случае она выполняется
в текущем контексте и может использовать значения локальных переменных
и переменных из вышестоящих стеков. Скрытые команды обсуждаются подробно
в соответствующем разделе ниже.slave issafeВозвращает ▒1▓,
если подчиненный интерпретатор безопасный, и ▒0▓ в противном случае.slave marktrustedОтмечает подчиненный интерпретатор
как надежный. Не раскрывает скрытые команды. Команда может выполняться
только из надежного интерпретатора. Если подчиненный интерпретатор уже
надежный, команда не оказывает никакого воздействия.
БЕЗОПАСНЫЕ
ИНТЕРПРЕТАТОРЫ
Безопасный интерпретатор
≈ это интерпретатор с ограниченной функциональностью. Поэтому в нем можно
без опасений выполнять произвольные скрипты, даже написанные вашим злейшим
врагом, не опасаясь нарушить выполнение вашего приложения или испортить
содержимое дисков вашего компьютера. Чтобы обеспечить безопасность, из
таких интерпретаторов удалены определенные команды и переменные. Например,
команда создания файлов на диске и команда запуска подпроцессов. Тем не
менее, в безопасном интерпретаторе можно обеспечить ограниченный доступ
к подобным командам с помощью механизма алиасов. В результате при выполнении
потенциально опасных команд будут вызываться специально написанные процедуры
в мастер-интерпретаторе, которые могут тщательно проверять заданные аргументы
и позволять использовать только ограниченный набор средств. Например, создание
файлов может быть разрешено только в ограниченном наборе подкаталогов,
а запуск подпроцессов разрешен только для ограниченного (и фиксированного)
набора хорошо проверенных программ.
Чтобы создаваемый
интерпретатор был безопасным, необходимо при его создании указать опцию
-safe.
Кроме того, любой интерпретатор, созданный из безопасного интерпретатора,
также будет безопасным.
Безопасный интерпретатор
создается со следующим набором команд:
Эти команды могут быть созданы
заново как 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 и interphide.
Безопасный интерпретатор не может изменить набор скрытых команд в себе
или своих потомках.
В настоящее время имена скрытых
команд не могут содержать имени пространства имен. Поэтому, прежде чем
скрыть команду, ее надо перевести в глобальное пространство имен. Команды,
которые необходимо скрыть, должны находиться в глобальном пространстве
имен. Это позволяет избежать ошибочного скрытия одноименной команды из
другого пространства имен.
join
Команда соединяет элементы
списка в одну строку.СИНТАКСИСjoin list ?joinString?ОПИСАНИЕКоманда возвращает строковое
значение, состоящее из всех элементов спискаlist, отделенных друг
от друга символом
joinString. Список list должен быть Tcl-списком,
joinString
по умолчанию есть пробел.
lappend
Команда дополняет переменную
элементами списка.СИНТАКСИСlappendvarName?value
value value ┘?ОПИСАНИЕКоманда добавляет в список
varName
каждый из аргументов value как новый элемент, отделенный пробелом.
Если
varName не существует, то он будет создан с элементами, заданными
value.
Команда lappend подобна команде append,
за исключением того, что аргументы добавляются в качестве элементов списка,
а не просто текста. С помощью этой команды можно эффективно создавать большие
списки. Например, для больших списков команда
lappend a $b
намного эффективнее, чем
set a [concat $a [list
$b]]'
library
Команды стандартной библиотеки
процедур Tcl.СИНТАКСИСauto_execok
cmd
ОПИСАНИЕTcl содержит библиотеку
Tcl-процедур общего назначения.
Местонахождение библиотеки
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 и позволит остальным
процедурам загружаться по требованию при помощи механизма автозагрузки,
описанного ниже.
КОМАНДНЫЕ ПРОЦЕДУРЫБиблиотека Tcl предоставляет
пользователю следующие процедуры:
auto_execok
cmdЭта команда просматривает
каталоги в текущем пути поиска (заданном переменной окружения PATH) и проверяет,
есть ли в каталогах исполняемый файл по имениcmd. Если файл
присутствует, то команда возвращает ▒1▓, если нет ≈ то ▒0▓.
Команда запоминает сведения о предыдущем поиске в массиве auto_execs,
это позволяет обходиться без поиска в каталогах при последующих вызовах
этой же команды. Для удаления из памяти этой информации можно использовать
команду
auto_reset.auto_load
cmdЭта команда загружает определение
для Tcl-командыcmd. Для этого она просматривает путь автозагрузки,
являющийся списком из одного или более каталогов. Он содержится в глобальной
переменной auto_path, если она существует. В противном случае используется
переменная окружения TCLLIBPATH. Если же и она не существует, список автозагрузки
состоит из каталога, в котором находится Tcl-библиотека.
В каждом из каталогов, входящих
в путь автозагрузки, должен находиться файл tclIndex, список команд,
определенных в этом каталоге, и скрипты для загрузки каждой команды. Файл
tclIndex
должен быть создан с помощью команды auto_mkindex.
Если команда была успешно загружена,
то
auto_load возвращает ▒1▓. Команда возвращает ▒0▓,
если нужная команда не была найдена в списках команд или указанная команда
загрузки не позволила создать команду (например, если файл tclIndex
устарел). Если при выполнении указанного загрузочного скрипта возникла
ошибка, команда возвращает ошибку.
Команда auto_load
читает индексные файлы только один раз и сохраняет полученную информацию
в массиве auto_index. При последующих обращениях к команде auto_load
сначала проверяется массив и только если информация о процедуре не найдена,
приступает к просмотру индексных файлов. Эта информация может быть удалена
с помощью команды auto_reset. После команды auto_reset следующий
вызов auto_load к повторному чтению индексных файлов.
auto_mkindexdir
pattern pattern...
Команда создает индекс
для использования его командой
auto_load. Для этого команда просматривает
каталог
dir
в поисках файлов с именами, удовлетворяющими аргументам
pattern
(сравнение
выполняется командой
glob), и создает индекс
всех командных процедур Tcl, определенных в обнаруженных файлах, и сохраняет
индекс в файле tclIndex в этой dir. Если не задано ни одного
шаблона
pattern, то по умолчанию принимается
*.tcl. Например,
команда
auto_mkindex foo *.tcl
просматривает все.tcl-файлы
в каталоге
foo и создает новый индексный файл foo/tclIndex.
Команда auto_mkindex
просматривает Tcl-скрипты очень простым способом: если в очередной строке,
начиная с первого символа, написано слово proc,
считается, что это определение процедуры, а следующее слово есть имя процедуры.
Процедуры, определение которых не подходит под описанное (например, если
перед словом
proc стоят пробелы), не попадают
в индексный файл.
auto_resetКоманда удаляет всю информацию,
накопленную командами
auto_execok и auto_load. При следующем
обращении к этой информации она будет считана с диска заново. Эта команда
также удаляет все процедуры, перечисленные в массиве auto_index,
так что при следующем обращении к ним будут загружены новые копии.parrayarrayNameКоманда выдает на стандартный
выход имена и значения элементов массива arrayName. Массив должен
быть доступен в контексте вызова. Он может быть как локальным, так и глобальным.tcl_endOfWord
str startВозвращает индекс первого
конца слова после указанного индекса start в строке str.
Первым концом слова считается первый символ, не принадлежащий слову, следующий
за первым после начальной точки символом слова. Возвращает
-1, если
после начальной точки больше нет концов слова. Способ распознавания символов
слов, используемый в Tcl, приведен в описании переменных tcl_wordchars
и tcl_nonwordchars.tcl_startOfNextWordstr
startВозвращает индекс первого
начала слова после указанного индекса start в строке str.
Первым началом слова считается первый символ слова, следующий за символом,
не принадлежащим слову. Возвращает
-1, если после начальной точки
больше нет начала слова.tcl_startOfPreviousWordstr
startВозвращает индекс первого
начала слова до указанного индекса start в строке str. Возвращает
▓-1▓, если после начальной точки больше нет начала слова.tcl_wordBreakAfterstr
startВозвращает индекс первой
границы слова после указанного индекса start в строке str.
Возвращает ▒-1▓, если в указанной строке после начальной точки больше
нет границ слова. Возвращаемый индекс относится ко второму символу пары,
образующей границу.tcl_wordBreakBeforestr
startВозвращает индекс первой
границы слова до указанного индекса start в строке str. Возвращает
▒-1▓, если в указанной строке до начальной точки больше нет границ
слова. Возвращаемый индекс относится ко второму символу пары, образующей
границу.ПЕРЕМЕННЫЕПроцедуры Tcl используют
или определяют следующие глобальные переменные.
auto_execs ≈ используется
командой auto_execok для записи информации о том, существуют ли
конкретная команда в виде исполняемого файла.
auto_index ≈ используется
auto_load
для сохранения индексной информации, считанной с диска.
auto_noexec ≈ если
переменная задана с любым значением, то команда unknown
не будет пытаться автоматически исполнить какую-либо команду.
auto_noload ≈ если
переменная задана с любым значением, то команда unknown
не будет пытаться автоматически загрузить какую-либо команду.
auto_path ≈ если переменная
задана, то она должна содержать Tcl-список с каталогами для просмотра при
операциях автозагрузки.
env(TCL_LIBRARY) ≈ если
переменная задана, то она указывает местоположение каталога с библиотечными
скриптами (команда infolibrary возвращает
значение этой переменной). Если переменная не определена, то используется
значение по умолчанию.
env(TCLLIBPATH) ≈
если переменная задана, то она должна содержать действующий Tcl список
каталогов для поиска при операциях автозагрузки. Эта переменная используется
только тогда, когда не определена переменная auto_path.
tcl_nonwordchars ≈
переменная содержит регулярное выражение, используемое такими процедурами,
как tcl_endOfWord для определения, является ли символ частью слова
или нет. Если образец соответствует символу, то символ считается не принадлежащим
к слову. В Unix такими символами являются все символы, кроме цифр, букв
и символа подчеркивания.
tcl_wordchars ≈ переменная
содержит регулярное выражение, используемое такими процедурами, как tcl_endOfWord
для определения, является ли символ частью слова или нет. Если образец
соответствует символу, то символ считается частью слова. В Unix слова состоят
из цифр, букв и символа подчеркивания.
unknown_active ≈ эта
переменная служит флагом для индикации активности команды unknown:
команда сама устанавливает ее. Переменная используется для выявления ошибок,
при которых unknown бесконечно рекурсивно
обращается к себе. Перед окончанием работы unknown
переменная
сбрасывается.
lindex
Команда извлекает элемент
списка.СИНТАКСИСlindexlist indexОПИСАНИЕКоманда lindex считает
list
Tcl
списком и возвращает index-ный элемент этого списка. Для
index
значение
0 соответствует первому элементу списка, а значение end
≈ последнему. При выполнении команды соблюдаются общие правила интерпретатора
Tcl относительно фигурных скобок, двойных кавычек и обратного слеша, хотя
подстановки переменных и команд не происходят.
Если index отрицательное
число или больше или равно числу элементов, команда возвращает пустое значение.
Если значение аргумента index равно end, команда возвращает
последний элемент списка.
linsert
Команда служит для вставки
элементов в список.
СИНТАКСИСlinsertlist
index element?element element ┘?
ОПИСАНИЕ
Данная команда создает
из list
новый список при помощи вставки аргументов element
непосредственно перед
index-ным элементом списка list. Каждый
из аргументов
element станет отдельным элементом нового списка.
Если индекс index меньше
или равен нулю, новые элементы вставляются в начало списка. Если индекс
index
больше или равен числу элементов в списке или равен end, новые элементы
вставляются в конец списка.
list
Команда создает список.СИНТАКСИСlist?arg arg
┘?ОПИСАНИЕКоманда list возвращает
новый список из всех элементов arg или пустой список, если аргументы
не указаны. При формировании списка по необходимости используются фигурные
скобки и обратные слеши, что позволяет потом использовать команду
index
для извлечения исходных аргументов, а также использовать команду
eval
для исполнения результирующего списка, с arg1, содержащим имя команды,
и остальными arg в качестве ее аргументов.
Команда list несколько
отличается от команды
concat: тем, что
команда concat удаляет один уровень группирования
перед образованием списка, тогда как команда
list работает непосредственно
с исходными аргументами. Например, команда
list a b {c d
e} {f {g h}}
вернет
a b {c d e} {f {g h}}
Тогда как команда concat
с теми же аргументами вернет
a b c d e f {g h}
llength
Команда подсчитывает количество
элементов в списке.СИНТАКСИСllengthlistОПИСАНИЕ
Аргументlist
истолковывается как список; команда возвращает строку с десятичным числом,
равным количеству элементов в этом списке.
load
Команда загружает машинный
код и инициализирует новые команды.СИНТАКСИСload fileName
load fileName packageName
load fileName packageName
interp
ОПИСАНИЕЭта команда загружает двоичный
код из файла в адресное пространство приложения и вызывает инициализирующую
процедуру библиотеки, чтобы включить ее в интерпретатор. АргументfileName
есть имя файла, содержащего код. Конкретная форма кода различна на разных
платформах, но чаще всего он должен быть разделяемой библиотекой, такой
как.so-файлы для Solaris и.dll-файлы для Windows.
Аргумент packageName есть имя библиотеки. Оно используется для определения
имени инициализационной процедуры. Аргумент interp содержит имя
интерпретатора (см. описание команды
interp).
Если аргумент
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
{}
сформируется имя библиотеки
last. Если аргумент fileName
равен пустой строке, то должен быть задан аргумент packageName.
Команда
load в таком случае ищет сначала статически загружаемую
библиотеку (то есть, библиотеку, зарегистрированную с помощью процедуры
Tcl_StaticPackage)
с указанным именем. Если такая будет найдена, то она используется в команде.
В противном случае ищется динамически загружаемая процедура с этим именем.
Если загружено несколько версий одной и той же библиотеки, то Tcl выбирает
ту, которая была загружена первой.ОШИБКИЕсли одна и та же библиотека
загружается несколько раз из различных файлов, на некоторых платформах
она будет загружена в адресное пространство несколько раз.
lrange
Команда возвращает один
или несколько последовательных элементов списка.СИНТАКСИСlrangelist first
lastОПИСАНИЕКоманда возвращает новый
список ≈ подмножество Tcl-списка
list, начиная с элемента first
и
заканчивая элементом
last включительно. Для обозначения последнего
элемента списка list в аргументе first
или
last можно
использовать значение end. Если аргумент
first
меньше нуля,
он считается равным нулю. Если аргумент last больше или равен числу
элементов в списке, он считается равным end. Если аргумент
first
больше,
чем last, то команда возвращает пустой список.
Команда
lrangelist first
first
не всегда возвращает тот же
результат, что и
lindexlist
first
(хотя это обычно так при простых
элементах списка, которые не заключены в фигурные скобки). Но она всегда
возвращает тот же результат, что и команда
list
[lindex list
first]
lreplace
Команда замещает элементы
списка новыми элементами.СИНТАКСИСlreplacelist
first last?element element ┘?ОПИСАНИЕКоманда lreplace
возвращает новый список, образованный из списка list путем замены
его элементов, начиная с first до last, на аргументы element.
Если аргумент first меньше нуля, он считается равным нулю. Если
аргумент last больше или равен числу элементов в списке, он считается
равным end. Если last меньше, чем first, тогда не
будет удалено ни одного прежнего элемента, и новые элементы будут просто
вставлены перед first. Для аргументов first и last можно
использовать значение end для ссылки на последний элемент списка.
Каждый аргумент element
становится
отдельным элементом списка. Если не было задано ни одного аргумента element,
тогда прежние элементы списка с first по last будут просто
удалены.
lsearch
Команда проверяет наличие
заданного элемента в списке.СИНТАКСИСlsearch?mode?
list
patternОПИСАНИЕДанная команда просматривает
по очереди элементы спискаlist
с целью найти первый из них, совпадающий
с заданным образцом pattern. Команда возвращает индекс первого найденного
такого элемента или ▒-1▓, если такой элемент не найден. Аргумент
mode
указывает
конкретный способ сравнения элементов списка и образца. Возможные значения
аргумента:
-exact
Означает, что элемент списка
должен быть в точности равен образцу-globОзначает, что используются
такие же правила сравнения, как в команде string match.-regexpОзначает, что образец считается
регулярным выражением, и для сравнения используются те же правила, что
и в команде
regexp. Значение по умолчанию -glob.
lsort
Команда сортирует элементы
списка.
СИНТАКСИСlsort ?options?
listОПИСАНИЕДанная команда сортирует
элементы спискаlist и возвращает новый список с уже упорядоченными
элементами. По умолчанию используется упорядочивание в порядке возрастания
символов в таблице ASCII. Кроме того, для управления процессом сортировки
в команде можно указать произвольные из перечисленных ниже опций (допускаются
уникальные сокращения).
-ascii
Упорядочивание в порядке
возрастания символов в таблице ASCII. Значение по умолчанию.-dictionary
Словарный режим. Тоже, что
и -ascii, но со следующими отличиями:
регистр не учитывается;
если две строки содержат цифры,
то числа сравниваются как целые, а не как символы ASCII.
Например, bigBoy окажется
между
bigbang и bigboy, а x10y между x9y и
x11y.
-integer
Режим целых чисел, когда
все элементы списка конвертируются в целые числа и при сравнении трактуются
именно как целые числа.-realРежим чисел с плавающей
запятой; этот режим аналогичен предыдущему и используется для действительных
чисел.-commandcommandРежим сортировки при помощи
произвольной команды пользователя. Для сравнения двух элементов списка
выполняется скрипт, состоящий из command и дополненный соответствующими
элементами списка. Скрипт должен вернуть целое число, большее нуля, равное
нулю, или меньшее нуля в зависимости от того, считается ли первый элемент
больше второго, равен ему или меньше его.-increasingСортировка в порядке возрастания
(от меньших к большим). Это значение по умолчанию.-decreasing
Сортировка в порядке убывания
(от больших к меньшим).
-indexindex
Эта опция может использоваться,
если каждый из элементов списка сам есть список (то есть list есть
список списков). Опция позволяет отсортировать список по ⌠одной из колонок■,
то есть по элементам подсписков с фиксированным индексом index.
Значение аргумента
index, равное end, означает генерацию
по последнему элементу подсписков. Например, команда
Эта опция значительно
более эффективна для данной задачи, чем опция -command с соответствующей
процедурой сравнения.
namespace
Команда предназначена для
создания и управления областями имен для команд и переменных.СИНТАКСИСnamespace ?option??arg
┘?ОПИСАНИЕКоманда позволяет создавать,
обращаться и уничтожать отдельные области имен для команд и переменных.
Более детально назначение и использование команды описаны ниже см. ⌠Пространства
имен■. Действия, выполняемые командой, зависят от значения аргументаoption.
Ниже
приведены возможные опции команды.
namespace children?namespace??pattern?
Позволяет получить список
областей-потомков для области имен namespace. Если аргумент namespace
отсутствует, то возвращается список областей-потомков для текущего пространства
имен. Команда возвращает полные имена, начинающиеся с ::. Если указан
аргумент pattern, команда возвращает только те имена, которые удовлетворяют
шаблону pattern. Проверка на соответствие производится по тем же
правилам, что и в команде glob. При этом шаблон,
начинающийся с ::, используется непосредственно, в противном случае
используемый шаблон составляется из namespace (или полного имени
текущего пространства имен) и pattern.namespace codescriptПозволяет захватить контекст
текущей области имен для скрипта script с тем, чтобы потом использовать
этот контекст при выполнении данного скрипта. Команда возвращает новый
скрипт, в котором старый скрипт ⌠завернут■ в команду namespace code.
Новый скрипт имеет две важные особенности: во-первых, он может быть вызван
в произвольном пространстве имен, при этом реально он будет выполняться
в текущем пространстве имен (том, в котором выполнялась команда namespace
code). Во-вторых, к созданному таким образом скрипту можно дописывать
произвольные аргументы и они действительно будут использоваться как дополнительные
аргументы. Например, предположим, что команда
set script [namespace code
{foo bar}]
выполняется в пространстве
имен ::a::b. Тогда команда
eval ⌠$script x y■
может быть выполнена в любом
пространстве имен и будет иметь тот же эффект, что и команда
namespace eval ::a::b
{foo bar x y}.
Эта команда необходима потому,
что расширения Tcl, например, Tk, обычно выполняют вызванные по событиям
скрипты в глобальном пространстве имен. Обертывающая команда захватывает
необходимую команду вместе с ее пространством имен и позволяет корректно
выполнить ее позже по соответствующему вызову. Примеры использования данного
механизма приведены ниже см. ⌠Правила
видимости имен■.
namespace currentПозволяет получить полное
имя текущей области имен. Хотя реальное имя глобального пространства имен
⌠■ (пустая строка), эта команда возвращает для него ::, поскольку
это часто бывает удобнее при программировании.namespace delete?namespace
namespace...?Позволяет удалить одну
или несколько областей имен, при этом удаляются все переменные, процедуры
и области-потомки заданной области имен. Если внутри одного из удаляемых
пространств имен выполняется какая-либо процедура, оно будет сохранено
до завершения процедуры, но помечено, как приготовленное к удалению, чтобы
исключить вызов других процедур. Если указанное пространство имен не существует,
команда возвращает ошибку. Если ни одно пространство имен не указано, команда
не делает ничего.namespace
evalnamespace
arg?arg...?Позволяет активизировать
пространство имен namespace и выполнить в его контексте заданный
код. Если пространство имен namespace не существует, оно будет создано.
Если пространство имен должно быть предком несуществующего пространства
имен, то оно тоже создается. Если задано более одного аргумента, все они
объединяются в одну строку через пробел (как при выполнении команды eval)
и полученный скрипт выполняется.namespace export?-clear?
?pattern pattern...?Позволяет указать, какие
команды разрешено экспортировать из данного пространства имен. Эти команды
потом могут быть импортированы в другие пространства имен с помощью команды
namespace
import. Можно разрешать экспорт как команд, созданных в данном пространстве
имен, так и команд, ранее импортированных из других пространств. Команда,
разрешаемая для экспорта, может в данный момент не существовать. Каждый
из шаблонов
pattern может содержать специальные символы как в команде
glob,
но не может содержать имени пространства имен. То есть шаблон может указывать
команды только в текущем пространстве имен. Каждый из шаблонов добавляется
к списку шаблонов команд, разрешенных для импорта из данного пространства
имен. Если в команде указан флаг -clear, команда предварительно
удаляет старый список. Если не указаны ни флаг, ни шаблоны, команда возвращает
текущий список шаблонов.namespace forget?pattern
pattern...?Удаляет из пространства
имен ранее импортированные команды. Каждый образец pattern должен
быть полным именем команды с указанием хотя бы одного пространства имен
и может содержать специальные символы, как в команде glob,
например:
foo::x или a::b::p*. Специальные символы нельзя
использовать в именах пространств имен. При выполнении данной команды сначала
ищутся команды, удовлетворяющие шаблону и разрешенные к экспорту из соответствующих
пространств имен. Далее проверяется, какие из них были импортированы в
текущее пространство имен. После чего импортированные команды удаляются.
То есть команда выполняет действия, противоположные действиям команды namespace
import.namespace
import?-force??pattern pattern...?Импортирует команды в текущее
пространство имен. Каждый образец pattern должен быть полным именем
команды с указанием хотя бы одного пространства имен и может содержать
специальные символы, как в команде glob, например
foo::x
или a::b::p*. Специальные символы нельзя использовать в именах пространств
имен. Все команды, которые удовлетворяют шаблонам и разрешены для экспорта,
добавляются к текущему пространству имен. Для этого в текущем пространстве
имен создается новая команда, которая указывает на экспортируемую команду
в исходном пространстве имен. При вызове этой новой команды она вызывает
исходную команду. Если в текущем пространстве имен уже есть команда с таким
именем, возвращается ошибка, если не указана опция -force.
В противном случае импортируемая команда заменяет команду, определенную
ранее. Команда
namespace import импортирует в текущее пространство
имен только те функции, которые в момент исполнения существуют в соответствующем
пространстве имен. Если позже там будут созданы новые команды с именами,
удовлетворяющими шаблонам, разрешающим экспорт, и шаблонам, определяющим
импорт, то они не импортируются автоматически.namespace inscopenamespace
arg?arg...?Выполняет скрипт в контексте
пространства имен
namespace. Эта команда не предназначена для непосредственного
исполнения программистом. Ее вызовы создаются автоматически при использовании
команды
namespace code для создания скриптов, выполняемых в фоновом
режиме, например, для Tk-виджетов. Команда namespace inscope похожа
на команду
namespace eval, но отличается от нее наличием возможности
указывать дополнительные аргументы и тем, что пространство имен namespace
должно существовать в момент выполнения команды. При выполнении команды
первый аргумент рассматривается как список, к которому остальные аргументы
добавляются как элементы списка. Так команда
namespace inscope ::foo
a x y z
эквивалентна
namespace eval ::foo [concat
a [list x y z]]
Такая семантика весьма удобна
при формировании скриптов, выполняемых в фоновом режиме.
namespace origincommand
Возвращает полное имя оригинальной
команды command, от которой происходит заданная импортированная
команда. При импорте команды в текущем пространстве имен создается новая
команда, которая указывает на экспортируемую команду в исходном пространстве
имен. Если команда последовательно импортировать в пространства имен a,
b,...,n, причем в каждое последующее пространство имен она импортировалась
из предыдущего, то namespace origin вернет полное имя команды в
первом пространстве имен, то есть a. Если команда command
не импортирована, то
namespace origin вернет ее полное имя.namespace parent?namespace?Возвращает полное имя родительского
пространства имен для пространства namespace. Если аргумент namespace
не указан, возвращает полное имя предка текущего пространства имен.namespace qualifiersstringВозвращает полное имя пространства
имен для string, то есть часть строки string от начала до
последнего символа ▒::▓ (но не включая его). Например, для строки
▒::foo::bar::x▓ эта команда вернет ▒::foo::bar▓, а для ▒::▓
≈ ⌠■ (пустую строку). Команда является парной для команды namespace
tail. При выполнении команды проверка существования соответствующих
пространств имен не производится.namespace tailstringВозвращает простое имя,
завершающее полное имя
string, то есть часть строки string
от последнего символа ▒::▓
(но не включая его) до конца строки.
Например, для строки ▒::foo::bar::x▓ эта команда вернет ▒x▓,
а для ▒::▓ ≈ ⌠■ (пустую строку). Команда является парной для команды
namespace
qualifiers. При выполнении команды проверка существования соответствующих
пространств имен не производится.namespacewhich?-command??-variable?
nameРассматривает name
как имя команды или переменной (в зависимости от указанной опции; по умолчанию
≈ как имя команды) и возвращает ее полное имя. Например, если name
не существует в текущем пространстве имен, но существует в глобальном,
то возвращает полное имя в глобальном пространстве имен. Если команда или
переменная не существует, данная команда возвращает пустую строку. Более
подробно правила поиска имен см. ⌠Правила
видимости имен■.ЧТО
ТАКОЕ ПРОСТРАНСТВО ИМЕН? Пространство имен ≈ это
обособленный набор команд и переменных. Содержащиеся в нем команды и переменные
не взаимодействуют с командами и переменными в других пространствах имен.
В Tcl всегда был один такой набор, который мы будем называть глобальным
пространством имен. В нем содержатся все глобальные переменные и команды.
Команда namespace eval позволяет создавать другие пространства имен,
например, команда
namespace eval Counter
{namespace export Bump variable num 0 proc Bump {} {variable num incr num}
}
создает новое пространство имен,
содержащее переменную
num и процедуру Bump. Команды и переменные
в этом пространстве имен изолированы от других команд и имен в той же программе.
Например, в глобальном пространстве имен может существовать другая команда
Bump.
Переменные пространства имен
напоминают глобальные переменные. Они существуют вне процедур, но могут
использоваться в процедурах с помощью команды variable,
как показано в предыдущем примере.
Пространства имен ≈ динамические
образования. В них можно в любой момент добавлять команды и переменные
с помощью дополнительных команд namespaceeval. Например,
то же пространство имен, что и в предыдущем примере, можно было создать
с помощью последовательности команд:
namespace eval Counter
{variable num 0 proc Bump {} {variable num return [incr num]}} namespace eval Counter
{proc test {args} {return $args}}namespace eval Counter
{rename test ⌠■ }
Обратите внимание, что процедура
test
создана в пространстве имен Counter, а затем удалена с помощью команды
rename.
Пространства имен могут иметь
собственные вложенные пространства имен и образовывать иерархию пространств
имен. Вложенное пространство имен содержится в своем предке и не может
взаимодействовать с другими пространствами имен.
ПОЛНЫЕ
ИМЕНА Каждое пространство имен
имеет собственное имя, например
history или
::safe::interp.
Полные имена используются для указания команд, переменных или подпространств
имен, содержащихся в соответствующем пространстве имен. Полные имена напоминают
полные имена файлов в Unix или виджетов в Tk, но в качестве разделителей
в них используется не слеш или точка, а двойное двоеточие ⌠::■.
Самое верхнее или глобальное пространство имен имеет имя ⌠"(пустая
строка) и ▒::▓ как синоним. Как пример, имя
::safe::interp::create
ссылается на команду
create в пространстве имен interp,
которое является подпространством пространства имен ::safe, которое
в свою очередь является подпространством глобального пространства имен
::.
Если вы хотите указать команду
или переменную в другом пространстве имен, вы можете указать имя пространства
имен, в котором она содержится. Например, из глобального пространства имен
вызвать процедуру из пространства имен Counter можно следующим образом:
Counter::Bump 5
Counter::Reset
А вывести текущее значение переменной
count
можно с помощью команды
puts ⌠count = $Counter::num■
Если одно пространство имен
содержит другое, может понадобиться более длинное имя. Если пространство
имен Foo содержит пространство имен Counter, то чтобы вызвать
процедуру Bump в последнем из глобального пространства имен, нужно
воспользоваться именем
Foo::Counter::Bump 3
Полное имя может использоваться
при создании или переименовании команд. Например, можно добавить процедуру
в пространство имен Foo следующей командой:
proc Foo::Test {args}
{return $args}
А переопределить ее в другом
пространстве имен командой:
rename Foo::Test Bar::Test
Дополнительные замечания. Имена
пространств имен, за исключением глобального, не могут быть пустой строкой.
Сочетание
:: запрещено в именах простых команд, переменных и пространств
имен кроме как в роли разделителя имен пространств имен. Дополнительные
символы
:
в полных именах игнорируются, то есть два или больше символов
:
подряд считаются одним разделителем. Сочетание :: в конце имени
команды или переменной указывает на команду или переменную с именем
{}
(пустая строка). Однако в полном имени пространства имен :: на конце
игнорируется.ПРАВИЛА
ВИДИМОСТИ ИМЕН
Все Tcl-команды, которые
работают с именами переменных и команд, поддерживают полные имена. Это
значит, что можно использовать полные имена в таких командах, как set,
proc,
rename,
или interp alias. Если вы используете
абсолютное имя, начинающееся с ::, то такое имя всегда интерпретируется
однозначно. Однако, если вы используете относительное имя, не начинающееся
с ::, поиск объекта с соответствующим именем происходит по следующим
правилам: команды и переменные сначала ищутся в текущем пространстве имен,
а затем (если не найдены) ≈ в глобальном. Имена пространств имен ищутся
только в текущем пространстве имен.
В следующем примере
set traceLevel 0 namespace eval Debug
{printTrace $traceLevel}
Tcl ищет переменную traceLevel
в пространстве имен Debug и затем в глобальном пространстве имен.
Аналогично ищется и процедура printTrace. Чтобы не оставлять неясностей,
рассмотрим еще один пример:
set traceLevel 0 namespace eval Foo {variable traceLevel
3 namespace eval Debug
{printTrace $traceLevel}}
Здесь Tcl ищет переменную traceLevel
в пространстве имен Foo::Debug. Поскольку там ее нет, он продолжает
поиск в глобальном пространстве имен. Переменная Foo::traceLevel
в процессе поиска полностью игнорируется.
Чтобы разобраться в сложных
ситуациях, можно использовать команду namespace which. Например,
следующая команда:
namespace eval Foo::Debug
{namespace which -variable traceLevel}
вернет ::traceLevel.
С другой стороны, команда:
namespace eval Foo {namespace
which -variable traceLevel}
вернет ::Foo::traceLevel.
Как уже упоминалось, относительные
имена пространств имен ищутся иначе, чем имена команд и переменных. Они
ищутся только в текущем пространстве имен. Это значит, что, например, команда
namespace
eval всегда создает потомка текущего пространства имен, если только
имя нового пространства не начинается с ::.
Tcl не ограничивает доступ
к командам, переменным или пространствам имен. Если вы указали имя, которое
в соответствие с перечисленными выше правилами ссылается на нужный вам
элемент, вы можете использовать этот элемент.
Переменные, определенные
в данном пространстве имен, можно использовать в процедурах в этом же пространстве
имен с помощью команды
variable. Похожая
на команду
global, эта команда создает связь
между локальной переменной в процедуре и одноименной переменной в пространстве
имен. Если необходимо, эта команда также создает и инициализирует эту переменную
(команда global только создает связь с переменной
в глобальном пространстве имен). Команду
variable
можно не использовать, если вы всегда используете полное имя переменной.
ИМПОРТ КОМАНД
Пространств имен часто используются
для создания библиотек. Некоторые библиотечные команды могут использоваться
так часто, что необходимость использования полных имен станет раздражать.
Например, если все команды в такой библиотеке, как BLT, содержатся в пространстве
имен Blt. Тогда вы смогли бы использовать их только следующим образом:
Blt::graph.g -background
red
Blt::table..g 0,0
Если Вы используете команды
graph
и table регулярно, предпочтительнее использовать их без префикса
Blt::.
Для этого достаточно импортировать эти команды в текущее пространство имен,
например, следующим образом:
namespace import Blt::*
В результате выполнения этой
команды все команды из пространства имен Blt будут экспортированы
в текущее пространство имен, и вы сможете использовать их без соответствующего
префикса:
graph.g -background
red
table..g 0,0
Команда namespace import
импортирует только те команды, экспорт которых разрешен с помощью команды
namespace
export.
Как правило, не стоит импортировать
все команды из пространства имен, так как при этом может быть сложно отследить
все команды, которые вы получите. Лучше указать явно, какие именно команды
вам нужны. Например, команда
namespace import Blt::graph
Blt::table
импортирует только команды graph
и table.
Если вы попытаетесь импортировать
команду, которая уже существует в текущем пространстве имен, то вы получите
ошибку. Это предупредит, например, попытки скопировать одну и ту же команду
из двух разных библиотек. Однако время от времени (например, при отладке)
у вас может появиться желание преодолеть данное ограничение. Для этого
нужно указать в команде опцию -force, и тогда существующая
команда будет заменена на импортируемую команду без сообщения об ошибке:
namespace import -force
Blt::graph Blt::table
Если вам почему-либо надо прекратить
использование библиотечной команды, это можно сделать следующим образом:
namespace forget Blt::*
Эта команда ищет в текущем пространстве
имен все команды, импортированные из Blt, и удаляет их. Если таких
команд не оказалось, команда ничего не делает. После исполнения команды
namespace
forget Blt::* команды из пространства имен Blt можно использовать
только с префиксом Blt::.
Если вы удаляете команду
из того пространства имен, где она была создана, например:
rename Blt::graph ⌠■
то она будет удалена из всех
пространств имен, в которые она была импортирована.ЭКСПОРТ
КОМАНД Вы можете разрешить экспорт
команд из определенного пространства имен:
namespace eval Counter
{namespace export Bump
Reset variable num 0 variable max 100 proc Bump {{by 1}} {variable num incr num $by check return $num} proc Reset {} {variable num set num 0 }proc check {} {variable num variable max if {$num > $max} {error ⌠too high!■ }}}
После этого процедуры Bump
и Reset можно импортировать, например, с помощью команды:
namespace import Counter::*
Но экспорт процедуры check
не разрешен, и она не будет импортирована этой командой.
Команда namespace import
позволяет импортировать только те команды, которые разрешено экспортировать
из их пространства имен с помощью команды namespace export. Если
в команде
namespace import указана команда, которую нельзя экспортировать,
она не будет импортирована в соответствующее пространство имен.
open
Открывает канал для связи с
файлом или программой.СИНТАКСИСopen fileName
open fileName access
open fileName access
permissions
ОПИСАНИЕЭта команда открывает файл,
последовательный порт или командный конвейер и возвращает идентификатор
канала, который может использоваться в дальнейшем в таких командах, как
read,
puts
и
close.
Если первый символ атрибута
fileName не равен ⌠|■, то команда
отрывает файл fileName, соответственно значение аргумента fileName
должно соответствовать обычным соглашениям, описанным в п. filename
.
Аргумент 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.
Если канал открыть только на запись, то стандартный вывод конвейера направляется
на текущий стандартный вывод (если он не перенаправлен в конвейере). Если
канал открыт только на чтение, стандартный ввод для конвейера берется из
текущего стандартного ввода (если он не перенаправлен в конвейере).ПОСЛЕДОВАТЕЛЬНЫЙ
ПОРТ
Если аргумент fileName
указывает на параллельный порт, то соответствующий порт открывается и инициализируется
(реальные действия в зависимости от платформы). Допустимые значения fileName
для различных платформ см. ⌠Особенности
реализации на различных платформах■.КОНФИГУРИРОВАНИЕ
Команда fconfigure
может быть использована для определения и изменения текущей конфигурации
канала. Для последовательного порта можно использовать следующие опции.
-mode
baud,parity,data,stop
Эта опция включает 4 величины,
записанные через запятую.
baud ≈ число, скорость
передачи данных в Бодах (бит в секунду);
parity ≈ четность,
может принимать одно из значений n (none), o (odd), e (even),
m
(mark), s (space);
data ≈ число бит данных
(целое от 5 до 8);
stop ≈ число стоп
битов (целое 1 или 2).
ОСОБЕННОСТИ
РЕАЛИЗАЦИИ НА РАЗЛИЧНЫХ ПЛАТФОРМАХWindows (все версии)
Аргумент 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
Команда загрузки пакетов библиотек
и контроля версий.
Команда поддерживает простую
базу данных со сведениями о том, какие пакеты библиотечных функций доступны
для использования в данном интерпретаторе, и как их загрузить в интерпретатор.
Она поддерживает многоверсионность пакетов и гарантирует загрузку в приложение
необходимой версии пакета. При этом она обеспечивает контроль непротиворечивости
версий. Обычно в Tcl-скриптах достаточно использовать команды package
require и package provide. Остальные команды предназначены в
первую очередь для системных скриптов, которые поддерживают базу данных
пакетов.
Поведение команды package
определяется ее первым аргументом. Ниже описаны возможные формы команды.
package
forget package
Удаляет информацию о пакете
из интерпретатора, включая как информацию, возвращаемую командой package
ifneeded, так и информацию, возвращаемую командой package provide.package
ifneededpackage
version?script?Команда используется в
системных скриптах. Если указана конкретная версия и скрипт, заносит в
базу данных информацию о том, что соответствующая версия пакета доступна
и может быть загружена в интерпретатор с помощью скрипта script.
Если в базе данных уже хранится информация о скрипте, она обновляется.
Если скрипт не указан, возвращается текущий скрипт.package
namesВозвращает список всех
пакетов в интерпретаторе, для которых известна доступная версия (заданная
с помощью команды package provide) или скрипт загрузки (заданный
командой
package ifneeded).package
providepackage?version?Команда используется для
того, чтобы указать, что версия version пакета package загружена
в интерпретатор. Если ранее была загружена другая версия, возвращает ошибку.
Если версия не указана, возвращает загруженную версию.package
require?-exact?
package?version?Команда используется, если
для выполнения дальнейшего кода необходим библиотечный пакет package
версии version. Команда возвращает номер загруженной версии или
ошибку. Если присутствуют оба аргумента -exact и version,
то команда загружает именно указанную версию (или выдает ошибку, если эта
версия недоступна). Если присутствует номер версии, а
-exact
опущено, то команда загружает указанную версию или более позднюю, но с
тем же старшим номером версии (2.7, но не 3.1, когда указана версия 2.5).
Если база данных не содержит
необходимой версии, а в интерпретаторе определена команда для packageunknown
(см. ниже), то она исполняется, после чего повторно проверяется доступность
необходимой версии. Если версия по-прежнему недоступна, команда возвращает
ошибку.
package
unknown ?command?Команда ⌠последней надежды■
при поиске необходимой версии пакета. Если аргумент command указан,
то он дополняется именем пакета и версии и полученный скрипт выполняется.
Если версия не указана, подставляется пустая строка.
Если аргумент command
не указан, возвращает текущий скрипт, заданный для команды package unknown.
package
vcompareversion1
version2Команда сравнения версий.
Возвращает ▒-1▓, если version1 более ранняя версия, чем version2,
▒1▓ ≈ в противном случае, и ▒0▓, если они равны.package
versionspackage Возвращает список всех
доступных версий пакета (информация о которых занесена в базу данных с
помощью команды
package ifneeded).package
vsatisfiesversion1 version2возвращает ▒1▓,
если у version1 и
version2 совпадают старшие номера, а младший
номер у version1 не меньше, чем у version2, и ▒0▓ ≈ в противном
случае.ИНДЕКСЫ
ПАКЕТОВ
Рекомендованный
способ работы с пакетами в Tcl состоит в том, чтобы включать в скрипты
команды package require и package
provide, и использовать процедуру pkg_mkIndex
(см. соответствующие пункты) для создания индексных файлов для пакетов.
Это обеспечивает автоматическую загрузку необходимых пакетов.
Команда сообщает идентификаторы
процессов.СИНТАКСИСpid ?fileId?ОПИСАНИЕЕсли задан аргумент
fileId, то он должен указывать на конвейер процессов (process pipeline),
открытый командой open. В этом случае команда
представит список идентификаторов всех процессов в конвейере, по порядку.
Если fileId указывает на открытый файл, не являющийся конвейером
процессов, то список будет пустой. Если аргумент
fileId не задан,
то будет возвращен идентификатор текущего процесса. Все идентификаторы
представлены десятичными строками.
pkg_mkIndex
Создает индексный файл для автоматической
загрузки пакета.СИНТАКСИС 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
проиндексированы
и хранятся в соответствующих каталогах, то команда
package require Test
загрузит версию 3.1. А команда
package require -exact
Test 2.1
загрузит версию 2.1. В различных
каталогах могут храниться много версий одного и того же пакета, но в данный
интерпретатор может быть загружена только одна из них ≈ та, которая будет
затребована первой. Однако, в различных интерпретаторах одного приложения
могут быть загружены различные версии одного и того же пакета.ЗАГРУЗЧИК ПАКЕТОВ И АВТОЗАГРУЗЧИК Автозагрузчик и загрузчик
пакетов во многом имеют сходные возможности, поскольку и тот, и другой
предназначены для загрузки файлов по требованию. Однако загрузчик файлов
представляет собой механизм более высокого уровня, который использует автозагрузчик
на последнем шаге процесса загрузки. Как правило, предпочтительнее индексировать
пакеты с помощью команды 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-процедуры.СИНТАКСИСproc name args
bodyОПИСАНИЕ Команда proc создает
новую Tcl-процедуру с именем name, если такой процедуры ранее не
было, и замещает ранее существовавшую процедуру или команду с таким именем,
если она была. При вызове новой процедуры скрипт body передается
на выполнение Tcl-интерпретатору. Обычно имя процедуры указывается без
указания имени пространства имен. При этом новая процедура создается в
текущем пространстве имен. Однако, если пространство имен указано явно,
она создается в указанном пространстве. Аргумент args определяет
формальные аргументы процедуры и представляет собой список (возможно, пустой),
каждый элемент которого представляет описание одного формального параметра.
Каждое такое описание само является списком из одного или двух элементов.
Первый элемент списка определяет имя формального параметра. Второй элемент
списка, если он указан, определяет значение по умолчанию для данного параметра.
При выполнении процедуры
для каждого формального параметра создается локальная переменная. Ей присваивается
значение соответствующего аргумента, указанного при вызове процедуры, или
значение по умолчанию. Аргумент, для которого при определении процедуры
указано значение по умолчанию, может не присутствовать в вызове процедуры.
Однако общее количество указанных параметров должно быть достаточным для
аргументов, не имеющих значения по умолчанию, но не больше общего числа
формальных параметров. Если это условие выполнено, все аргументы процедуры
собираются в один список (как при исполнении команды list).
Эта комбинированная величина присваивается локальной переменной args.
При исполнении тела процедуры
имена переменных обычно считаются именами локальных переменных, которые
создаются автоматически по мере необходимости и удаляются после завершения
процедуры. По одной локальной переменной создается также для каждого аргумента
процедуры. Для использования глобальных переменных необходимо использовать
команду
global или upvar.
Для использования переменных из пространства имен необходимо использовать
команду variable или upvar.
Команда proc возвращает
пустую строку. При вызове процедуры возвращается величина, заданная в команде
return.
Если в процедуре не выполнялась явная команда return,
она возвращает результат выполнения последней команды, выполнявшейся в
теле процедуры. Если при выполнении процедуры произошла ошибка, то процедура
в целом возвращает эту ошибку.
puts
Команда записывает данные
в канал.
СИНТАКСИС puts?-nonewline??channelId?
stringОПИСАНИЕ Записывает символы из аргументаstring
в канал channelId. Значение channelId должно быть идентификатором
канала, который вернула предыдущая команда open
или socket. Соответствующий канал должен быть
открыт на запись. Если аргумент channelId не указан, значение по
умолчанию соответствует стандартному выводу. Команда
puts обычно
выдает после string символ новой строки, однако, если указана опция
-nonewline,
этого не происходит.
Символы новой строки при
выводе заменяются на последовательность, используемую на данной платформе
(например, cr lf на Windows-платформах) в соответствии со значением опции
канала -translation. Опция может быть изменена с помощью
команды fconfigure.
Tcl осуществляет вывод через
буфер. Поэтому символы, выданные командой puts, могут и не
появиться сразу в выходном устройстве или в файле. Обычно вывод откладывается
до заполнения буфера или закрытия канала. Чтобы обеспечить немедленную
выдачу данных, можно использовать команду flush.
Когда буфер заполнится, команда
puts
обычно блокирует процесс до тех пор, пока все данные не будут переданы
операционной системе для дальнейшего вывода. Если канал channelId
открыт в неблокирующем режиме, процесс не блокируется, даже если операционная
система еще не приняла данные. Tcl в этом случае продолжает складывать
данные в буфер и в фоновом режиме передает их в соответствующий файл или
устройство с той скоростью, с которой они могут принять данные. Чтобы работа
в неблокирующем режиме была возможна, необходимо, чтобы был запущен обработчик
событий.
При работе в неблокирующем
режиме возможен рост буфера, под который будет выделен неоправданно большой
объем памяти. Чтобы избежать этого, неблокирующие операции ввода ≈ вывода
лучше делать управляемыми по событиям. При этом новая порция данных не
будет передаваться в буфер, пока канал не будет готов к ее приему.
pwd
Команда pwd возвращает
путь к текущему каталогу.СИНТАКСИСpwdОПИСАНИЕ Команда pwd возвращает
полный путь к текущему каталогу.
read
Команда выполняет чтение
данных из канала.СИНТАКСИС read ?-nonewline?
channelId
readchannelIdnumBytes
ОПИСАНИЕ Команда read зачитывает
из канала channelId либо весь файл до символа конца файла (при первой
форме записи), либо заданное параметром numBytes количество байтов
(вторая форма). Если во втором случае в файле оказалось меньше байтов,
чем задано numBytes, тогда возвращаются все байты, что остались.
Если указана опция -nonewline,
при выполнении команды отбрасывается символ новой строки в конце файла.
Если канал открыт в неблокирующем
режиме, команда может прочитать не указанное количество байтов, а только
все доступные. После чего она не заблокирует процесс, дожидаясь дополнительных
данных, а завершится. Если команда завершилась до конца файла, то опция
-nonewlineигнорируется.
Команда read изменяет
во входных данных последовательность, задающую конец строки, в соответствии
с опцией канала-translation option.Опция может быть
изменена с помощью команды fconfigure.
regexp
Сравнивает строку и регулярное
выражение.СИНТАКСИСregexp?switches? exp
string?matchVar??subMatchVar subMatchVar...?ОПИСАНИЕКоманда определяет, соответствует
ли регулярное выражениеexp какой-либо части строки string
или всей строке, и возвращает ▒1▓, если соответствует, и ▒0▓
≈ в противном случае.
Если в команде указаны дополнительные
аргументы после
string, они считаются именами переменных, в которые
возвращается информация о том, какие именно части строки соответствуют
регулярным выражениям. Переменной присваивается значение, состоящее из
части строки, соответствующей всему регулярному выражению. Самой левой
в списке переменной subMatchVar присваивается значение, состоящее
из части строки, которая соответствует самому левому заключенному в скобки
выражению в составе exp. Следующей переменной subMatchVar присваивается
значение, соответствующее следующему заключенному в скобки выражению, и
так далее.
Если первые аргументы команды
начинаются с ⌠-■, они считаются опциями команды. Ниже перечислены
возможные опции.
-nocase
При сравнении не различает
буквы в верхнем и нижнем регистре.-indicesВ переменных subMatchVars
сохраняются не части строки, а списки из двух десятичных чисел ≈ индексов
начала и конца соответствующей области строки.--Означает конец опций. следующий
аргумент будет рассматриваться как exp, даже если он начинается
с ⌠-■.
Если в команде указано больше
переменных
subMatchVar, чем выражений в скобках в exp, или
если для одного из выражений не удалось найти соответствующую ему часть
строки, то соответствующей переменной будет присвоено значение ⌠-1 -1■
или пустая строка, в зависимости от того, была ли задана опция -indices.РЕГУЛЯРНЫЕ
ВЫРАЖЕНИЯ Регулярное выражение состоит
из ни одной или более
ветвей (branch), разделенных символом '|'.
Строка соответствует выражению, если она соответствует одной из его ветвей.
Ветвь состоит из одной или
более частей (piece), соединенных друг с другом. строка соответствует
ветви, если ее можно разбить на подстроки таким образом, что начальная
подстрока соответствует первой части ветви, следующая подстрока ≈ следующей
части ветви и так далее.
Часть состоит из атома со
следующим за ним необязательным символом '*', '+' или '?'.
Атом с последующим символом ▒*▓ соответствует любой последовательности
из нуля или более подстрок, каждая из которых соответствует атому. Атом
с символом '+' после него соответствует любой последовательности
из одной или более подстрок, каждая из которых соответствует атому. Атом
с символом '?' после него соответствует подстроке, которая соответствует
атому, или пустой строке.
Атом может быть регулярным
выражением в скобках (в этом случае он соответствует любой строке, которая
соответствует этому регулярному выражению), интервалом (см. ниже),
символом '.' (соответствует ровно одному произвольному символу),
'^' (соответствует нулевой строке в начале string), '$'
(соответствует нулевой строке в конце string), '\' с последующим
одним символом (соответствует этому символу), или одним символом без какого-либо
иного смысла (соответствует этому символу).
Интервал есть последовательность
символов, заключенная в квадратные скобки. Он обычно соответствует любому
символу из этого интервала. Если последовательность начинается с символа
'^', то она соответствует любому символу, кроме символов, стоящих
далее в последовательности. Если два символа в последовательности разделены
символом '-', то это краткая форма для обозначения всех ASCII символов
между этими двумя (например, '[0-9]' соответствует любой десятичной цифре).
Для того, чтобы включить в последовательность символ ']', следует
поставить его на место первого в последовательности (следом за возможным
символом '^'). Для включения в последовательность символа '-'
следует сделать его первым или последним символом.
ВЫБОР ИЗ АЛЬТЕРНАТИВНЫХ СОСТОЯНИЙ Вообще говоря, регулярное
выражение может соответствовать строке несколькими различными способами.
Например, рассмотрим выражение
regexp (a*)b* aabaaabb
x y
В соответствии с описанными
выше правилами переменные
x и y могут принять значение aabb
и aa, aaab и aaa, ab и a или одну из еще нескольких
возможных комбинаций. Чтобы избежать этой потенциальной неопределенности
команда regexp выбирает между возможными вариантами по правилу ⌠первый
и самый длинный■. Другими словами, строка и регулярное выражение просматриваются
слева направо, при этом выбирается часть строки максимально возможной длины.
Говоря точнее, при выборе используются следующие правила в порядке убывания
приоритета.
[1]
Если регулярное выражение
соответствует двум разным частям строки, выбирается та часть, которая раньше
начинается.
Если обе начинаются в одном
и том же месте, то это неопределенный (тяжелый) случай. Его можно объяснить
следующим образом.
[2]
Если регулярное выражение
содержит символы ▒|▓ (то есть состоит из нескольких ветвей), то
будет выбрана самая левая ветвь, которой что-либо соответствует
[3]
Для выражений, содержащих
'*', '+' и '?▓, выбираются самые длинные фрагменты строки, соответствующие
им.
[4]
Компоненты выражений рассматриваются
слева направо.
В приведенном выше примере
▒(a*)b*▓ соответствует ▒aab▓, так как для ▒(a*)▓ выбирается
первый соответствующий ему фрагмент, то есть начальные ▒aa▓, а затем
для ▒b*▓ выбирается следующий символ ▒b▓. Рассмотрим еще
один пример:
regexp (ab|a)(b*)c abc
x y z
После выполнения команды переменная
x
будет содержать значение ▒abc▓, переменная y ≈ ▒ab▓ и переменная
z
будет содержать пустую строку. Правило [4] определяет, что поиск начнется
с выражения (ab|a), а правило [2], что поиск начнется с подвыражения
▒ab▓. Поэтому символ ▒b▓ в строке будет использован, и выражение
▒(b*)▓ будет соответствовать пустой строке.
regsub
Команда выполняет подстановки,
используя регулярные выражения.СИНТАКСИС 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
Ищутся все подобласти string,
соответствующие
exp, и для каждой из них производится замена. Символы
▒&▓ и ▒\n▓ замещаются на очередной фрагмент string,
соответствующий
exp. То есть каждый раз они могут замещаться на
различные выражения.-nocase
При поиске соответствующих
фрагментов строки не различаются буквы в верхнем и нижнем регистре. Тем
не менее, подстановка производится в исходном регистре.
--
Означает конец опций. Следующий
аргумент будет рассматриваться как exp, даже если он начинается с ▒-▓.
Команда возвращает количество
найденных (и, соответственно, замещенных) интервалов. Правила соответствия
строк регулярным выражениям приведены в описании команды regexp.
rename
Команда rename переименовывает
или удаляет команду.СИНТАКСИС rename oldName
newNameОПИСАНИЕ Данная команда переименовывает
команду по имени
oldName
в
newName. Если newName отсутствует
(равно пустой строке), тогда команда oldName
удаляется.
Имена oldName и newName
могут содержать квалификаторы областей имен (указатели на имена областей
имен). Если команда переименовывается в другую область имен, то последующие
вызовы этой команды будут происходить в новой области имен. Команда rename
возвращает пустую строку.
resource
Управляет Macintosh-ресурсамиСИНТАКСИСresourceoption?arg
arg...?ОПИСАНИЕКоманда resource
позволяет управлять ресурсами на платформах Macintosh. На остальных платформах
не поддерживается.
return
Команда осуществляет возврат
из процедуры.СИНТАКСИСreturn ?-code
code??
-errorinfo
info??
-errorcode
code??string?ОПИСАНИЕКоманда немедленно осуществляет
возврат из текущей процедуры (или команды верхнего уровня, или команды
source)
со значением, заданным string. Если аргумент string не задан,
возвращает пустую строку.
Обычно опция -code
не используется, и процедура завершается успешно (с кодом завершения TCL_OK).
Однако, ее можно использовать для генерации других кодов возврата. Ниже
перечислены возможные коды.
ok
Успешное завершение. То
же самое, что отсутствие кода.
error
Возвращает ошибку. То же
самое, что использовать команду error
для прекращения выполнения процедуры за исключением обработки переменных
errorInfo
и errorCode (см. ниже).returnТекущая процедура вернет
код TCL_RETURN, который вызовет немедленный возврат также и из вызывающей
процедуры.breakТекущая процедура вернет
код TCL_BREAK, который вызовет немедленное прекращение выполнения самого
внутреннего из вложенных циклов, из которого была вызвана процедура.continueТекущая процедура вернет
код TCL_CONTINUE, который вызовет немедленное прекращение выполнения текущей
итерации самого внутреннего из вложенных циклов, из которого была вызвана
процедура.valueЗначение value должно
быть целым числом. Оно будет возвращено как код выполнения процедуры.
Опция -code используется
относительно редко. Она предусмотрена для того, чтобы процедуры, реализующие
новые управляющие команды, могли вернуть вызывающим их процедурам исключительные
условия.
Опции -errorinfo
и -errorcode могут использоваться совместно с √code error,
чтобы вернуть дополнительную информацию о сгенерированной ошибке. В остальных
случаях они игнорируются.
Опция -errorinfo
используется для того, чтобы задать исходное значение переменной errorInfo.
Если она не будет задана, то в переменную errorInfo
будет включена информация о вызове процедуры, вернувшей ошибку, и о более
высоких уровнях стека, но не информация непосредственно об ошибке внутри
процедуры. Чаще всего для формирования переменной info используется
сообщение команды
catch, обнаружившей ошибку
в процедуре.
Если опция -errorcode
указана, она позволяет задать значение переменной errorCode.
В противном случае ей будет присвоено значение NONE.
scan
Производит разбор строки
в стиле процедуры sscanfСИНТАКСИСscan string format
varName?varName...?ВВЕДЕНИЕДанная команда, подобно
ANSI C процедуре
sscanf, просматривает строку string, выбирает
поля и преобразует их в соответствии с очередным спецификатором преобразования
в строке format. Выбранные значения преобразуются обратно в строковый
вид и последовательно записываются в переменные varName.ПРОЦЕСС СКАНИРОВАНИЯКоманда scan просматривает
одновременно строки
string и format. Если очередной символ
в строке format ≈ пробел или табуляция, то он соответствует любому
числу (включая ноль) пробельных символов (пробел, табуляция, новая строка)
в строке string. Если в строке format встретился символ ▒%▓,
он означает начало очередного спецификатора преобразования. Спецификатор
преобразования включает в себя до трех полей после символа ▒%▓:
первое поле может содержать символ ▒*▓, означающий, что преобразуемая
величина будет удалена, а не записана в очередную переменную, второе поле
может содержать число, указывающее максимальную ширину поля, и третье поле
содержит букву, определяющую тип преобразования. Обязательным является
только третье поле.
Когда команда scan
находит спецификатор преобразования в строке format, она пропускает
пробельные символы в строке string. Затем она выбирает следующую
группу непробельных символов и преобразует их в соответствии со спецификатором
преобразования и записывает результат в переменную, соответствующую следующему
аргументу команды. Поддерживаются следующие типы преобразований, задаваемые
соответствующими символами:
d
Входное поле должно быть
десятичным числом. Результат записывается как десятичная строка.oВходное поле должно быть
восьмеричным числом. Результат преобразуется в десятичную строку.xВходное поле должно быть
шестнадцатеричным числом. Результат преобразуется в десятичную строку.cЧитается один символ, его
двоичная величина преобразуется и записывается в переменную как десятичная
строка. Начальные пробельные символы в этом случае не пропускаются. В отличие
от ANSI C процедуры sscanf входное поле всегда состоит ровно из
одного символа, а ширина поля не может быть задана.s
Входное поле состоит из всех
непробельных символов до следующего пробельного. Все символы копируются
в переменную.
e или f или
g
Входное поле должно быть
числом с плавающей точкой, состоящим из знака (не обязательно), строки
десятичных цифр, возможно с десятичной точкой и порядка (не обязательно),
состоящего из буквы e или E, знака порядка (не обязательно)
и строки десятичных цифр.[chars]Входное поле состоит из
произвольного числа символов из chars. Соответствующая строка записывается
в переменную. Если первый символ в скобках ▒]▓, то он рассматривается
как часть
chars, а не как закрывающая скобка для множества символов[^chars]Входное поле состоит из
произвольного числа символов, не содержащихся в chars. Соответствующая
строка записывается в переменную. Если первый символ в скобках после ▒^▓
есть ▒]▓, то он рассматривается как часть chars, а не как
закрывающая скобка для множества символов.
Число символов, которое выбирается
для преобразования, это максимально возможное число символов для соответствующего
преобразования (например, так много десятичных цифр, как это возможно для
%d,
или так много восьмеричных цифр, как это возможно для %o). Поле,
выбираемое для очередного преобразования, закрывается, как только в строке
string
встречается пробельный символ или как только поле достигает указанного
максимального размера (в зависимости от того, что происходит раньше). Если
в спецификаторе преобразования для очередного поля присутствует символ
▒*▓,
то выбранное значение не присваивает никакой переменной, а очередной аргумент
команды scan по-прежнему считается неиспользованным.ОТЛИЧИЯ ОТ ANSI SSCANF Поведение команды scan
не отличается от поведения ANSI C процедуры sscanf за исключением
следующих моментов:
[1]
Спецификаторы %p и
%n
не поддерживаются.
[2]
Для спецификатора %c
нельзя указывать ширину поля. Только один символ переводится в десятичную
величину, которая и присваивается соответствующей переменной.
[3]
Модификаторы l, h
и L игнорируются. Целые числа преобразуются так, как будто никакого
модификатора не было задано, а действительные числа ≈ как при модификаторе
l,
то есть с использованием типа double для внутреннего представления.
seek
Команда изменяет позицию
доступа открытого канала.СИНТАКСИСseek channelIdoffset
?origin?ОПИСАНИЕ Команда изменяет текущую
позицию доступа канала, заданного параметром channelId. Значение
channelIdдолжно
быть идентификатором канала, который вернула предыдущая команда
open
или socket. Аргументы origin и offset
задают новую позицию, в которой будет выполняться следующая операция чтения
или записи. Аргумент offset
должен быть целым числом (возможно,
отрицательным), а аргумент origin может принимать одно из перечисленных
ниже значений.
start
Следующая позиция будет
на расстоянии
offset байтов от начала соответствующего файла или
устройства.currentСледующая позиция будет
на расстоянии
offset байтов от текущей позиции. Отрицательное значение
offset
передвигает позицию назад.endСледующая позиция будет
на расстоянии
offset байтов от конца файла или устройства. Отрицательное
значение
offset указывает на позицию до конца файла, а положительное
√ на позицию после конца файла.
Значение по умолчанию для аргумента
origin
равно
start.
Выполнение команды влечет
немедленную передачу всех данных из выходного буфера в файл или на выходное
устройство. Команда не будет завершена до тех пор, пока все данные не будут
переданы, даже если канал находится в неблокирующем режиме. Кроме того,
будут удалены все не прочитанные данные из входного буфера. Команда возвращает
пустую строку. Если команда используется для файла или канала, для которого
не поддерживается произвольный доступ, она вернет ошибку.
set
Команда читает и записывает
значения переменных.СИНТАКСИСset varName?value?ОПИСАНИЕКоманда set возвращает
значение переменной
varName. Если задан параметр value, то
команда присваивает переменной varName значение value и возвращает
значение value. Если такой переменной не существовало, тогда она
создается вновь.
Если varName содержит
открывающую скобку и заканчивается закрывающей скобкой, тогда это элемент
массива. Символы до открывающей скобки являются именем массива, символы
между скобками есть индекс этого элемента в массиве. В противном случае
команда адресуется к скалярной переменной.
Обычно имя переменной указывается
без указания пространства имен, в котором она содержится. При этом соответствующая
переменная для чтения или записи ищется в текущем пространстве имен. Если
же в имени переменной присутствуют имя пространства имен, то она ищется
в указанном пространстве имен.
Если команда используется
вне тела процедуры, то
varName есть имя глобальной переменной (если
текущее пространство имен есть глобальное пространство) или переменной
текущего пространства имен. В теле процедуры
varName есть имя параметра
или локальной переменной процедуры, если она не объявлена глобальной переменной
или переменной пространства имен с помощью команды
global
или variable соответственно.
ОПИСАНИЕ Эта команда открывает сетевое
соединение и возвращает идентификатор канала, который может использоваться
в последующих командах
read,
puts
или
flush.
В настоящее время поддерживается только протокол TCP. Команда может использоваться
для открытия соединения как со стороны сервера, так и со стороны клиента.КЛИЕНТСКОЕ
СОЕДИНЕНИЕ Если опция -server
не указана, то канал открывается со стороны клиента, и возвращаемый идентификатор
канала может быть использован для операции чтения и записи. Аргументы portи
host
задают порт для соединения. По данному порту должен быть сервер, обслуживающий
соединение. Аргумент port должен быть целым числом, а host
≈ адресом машины в доменном стиле (например, www.sunlabs.com) или
числовым IP-адресом (например, 127.0.0.1.). Для ссылки на локальную
машину, на которой выполняется команда, можно использовать значение localhost.
Для задания дополнительной
информации о соединении можно использовать следующие опции.
-myaddraddr
Аргумент addr задает
доменный или числовой адрес сетевого интерфейса клиентской стороны для
упрощения соединения. Эта опция может быть полезна, если на клиентской
машине есть несколько сетевых интерфейсов. Если опция не указана, системный
интерфейс будет выбран операционной системой.
-myport port
Аргумент port задает
номер порта для клиентсткой стороны соединения. Если опция не указана,
номер порта для клиента будет определен операционной системой.
-async
Использование опции -async
приведет к тому, что клиент будет подсоединен в асинхронном режиме. Это
значит, что сокет будет создан немедленно, возможно, еще до установления
связи с сервером. Если канал открыт в блокирующем режиме, то при выполнении
команды gets или flush
по такому сокету, команда завершится только после того, как процесс установления
соединения будет завершен. Если канал открыт в неблокирующем режиме, то
в этой ситуации команда завершится немедленно, а команда fblocked
для данного канала возвратит 1.
СЕРВЕРНОЕ
СОЕДИНЕНИЕ Если в команде присутствует
опция
-server, то новый сокет будет сервером для порта port.
Tcl будет автоматически устанавливать соединения по данному порту. Для
каждого соединения будет создаваться новый канал, который может быть использован
для связи с клиентом. При этом Tcl выполняет команду command с тремя
дополнительными аргументами: имя нового канала, адрес клиентской машины
в сетевой нотации и номер порта клиента.
В команде можно использовать
следующие опции:
-myaddraddr
Аргумент addr задает
доменный или числовой адрес сетевого интерфейса серверной стороны для упрощения
соединения. Эта опция может быть полезна, если на серверной машине есть
несколько сетевых интерфейсов. Если опция не указана, сокет связывается
со специальным адресом INADDR_ANY, который позволяет принимать соединения
от любого интерфейса.
Канал сервера не может быть
использован для приема или выдачи данных. Его единственное назначение ≈
принимать новые клиентсткие подсоединения. Каналы, открываемые для каждого
клиентского соединения, открываются на чтение и запись. Закрытие серверного
канала вызывает отключение сервера, так что никаких новых соединений не
может быть выполнено. Однако существующие соединения сохраняются.
Сокет сервера не может обнаружить
новое соединение при незапущенном обработчике событий. Поэтому в приложении
должен быть запущен обработчик событий, например, командой vwait.
КОНФИГУРАЦИОННЫЕ
ОПЦИИ Команда fconfigure
может получить значения нескольких неизменяемых опций для сокетов:
-sockname
Эта опция возвращает список
из трех элементов: адреса, имени хоста и номера порта для сокета. Если
имя хоста не может быть определено, второй элемент списка совпадает с первым
≈ адресом.-peernameЭта опция не поддерживается
для сокетов сервера. Для сокетов клиента и установленных соединений она
выдает список из трех элементов: адреса, имени хоста и номера порта для
сокета. Если имя хоста не может быть определено, второй элемент списка
совпадает с первым ≈ адресом.
source
Команда source исполняет
скрипт, содержащийся в файле.СИНТАКСИСsource fileNameОПИСАНИЕДанная команда передает
интерпретатору Tcl содержимое названного файла в качестве исполняемого
скрипта. Команда возвращает результат выполнения последней выполненной
команды скрипта. Если при выполнении скрипта возникла ошибка, то команда
source
возвратит эту ошибку. Если при выполнении скрипта была вызвана команда
return,
то выполнение скрипта прекращается, и команда завершается. При этом она
возвращает результат выполнения команды
return.
Для Macintosh-платформ существуют
дополнительные варианты команды, предназначенные для работы с ресурсами.
split
Команда разделяет строку
на части и создает из них правильный Tcl-список.СИНТАКСИСsplit string?splitChars?ОПИСАНИЕКоманда делит строку string
в каждом месте, где есть символ, содержащийся в splitChars. Каждый
элемент списка образован частью исходной строки, заключенной между двумя
последовательными вхождениями символов из splitChars в строку. В
списке формируется пустой элемент, если два символа из splitChars
встречаются подряд или если первый или последний символ string содержится
в splitChars. Если splitChars есть пустая строка, то строка
разбивается на отдельные символы. По умолчанию splitChars содержит
пробельные символы (пробел, табуляция, новая строка).
Примеры.
Команда
split ⌠comp.unix.misc■.
вернет ⌠comp unix misc■, а команда
split ⌠Hello world■
{}
вернет ⌠H e l l o { } w o r
l d■.
string
Команда для работы со строками.СИНТАКСИСstringoption
arg?arg...?ОПИСАНИЕВыполняет одну из перечисленных
ниже строковых операций в зависимости от заданной опции option.
string
comparestring1
string2
Выполняет посимвольное
сравнение строк string1 и string2 так же, как С-процедура
strcmp.
Возвращает -1, 0 или 1, в зависимости от того, будет ли строка
string1
больше, равна или меньше (при лексикографическом сравнении) строки string2.string first string1
string2Ищет в строке string2
последовательность символов, в точности совпадающую со string1.
Если такая последовательность есть, возвращает индекс первой буквы в первой
найденной последовательности. В противном случае возвращает -▓1▓.string indexstring
charIndexВозвращает charIndex-ный
символ в строке
string. Значение charIndex, равное ▒0▓,
соответствует первому символу в строке. Если значение charIndex
меньше ▒0▓ или не меньше длины строки ≈ возвращает пустую строку.string laststring1
string2Ищет в строке string2
последовательность символов, в точности совпадающую со string1.
Если такая последовательность есть, возвращает индекс первой буквы в последней
найденной последовательности. В противном случае возвращает ▒-1▓.string lengthstringВозвращает десятичную строку,
содержащую число символов в строке.string
matchpattern
string
Проверяет, соответствует
ли строка образцу. Возвращает ▒1▓, если соответствует, и ▒0▓
≈ в противном случае. Соответствие проверяется примерно так же, как
в C-shell. Строка соответствует шаблону, если они совпадают посимвольно,
за исключением перечисленных ниже специальных случаев:
* ≈ Удовлетворяет
любой последовательности из нуля или больше символов;
? √ Удовлетворяет
любому символу;
[chars]
√ Удовлетворяет любому символу из chars. Если chars включает
последовательность символов типа a-b, то удовлетворяет всем символам
от a до b (включительно).
\x √ Удовлетворяет
символу x. Обеспечивает возможность избежать в шаблонах специального смысла
символов ▒*▓, ▓?▓, ▒[▒, ▒]▓, ▒\▓.
string range string
first last
Возвращает подстроку строки
string,
начиная с символа с индексом first и кончая символом с индексом
last.
Индекс ▒0▓ указывает на первый символ строки. Индекс
end (или
любое его сокращение) указывает на последний символ строки. Если значение
first
меньше ▒0▓, используется значение ▒0▓. Если last больше
значения индекса последнего символа в строке, используется значение end.
Если first больше, чем
last, команда возвращает пустую строку.string tolowerstringВозвращает строку, тождественную
string, за исключением того, что все символы верхнего регистра в ней
переведены в нижний регистр.stringtoupperstringВозвращает строку, тождественную
string,
за исключением того, что все символы нижнего регистра в ней переведены
в верхний регистр.string trim string?chars?Возвращает строку, тождественную
string,
за исключением того, что из нее удалены все начальные и конечные символы,
входящие в chars. Если аргумент chars не указан, удаляются
пробельные символы (пробелы, табуляция, символы новой строки).string trimleftstring?chars?Возвращает строку, тождественную
string,
за исключением того, что из нее удалены все начальные символы, входящие
в chars. Если аргумент chars не указан, удаляются пробельные
символы (пробелы, табуляция, символы новой строки).string trimrightstring?chars?Возвращает строку, тождественнуюstring,
за исключением того, что из нее удалены все конечные символы, входящие
в chars. Если аргумент chars не указан, удаляются пробельные
символы (пробелы, табуляция, символы новой строки).string wordendstring
indexВозвращает индекс символа,
идущего сразу после последнего символа в слове, содержащем index-ный
символ строки string. Словом считается любая непрерывная последовательность
из букв, цифр и символа подчеркивания, или любой другой одиночный символ.string wordstartstring
indexВозвращает индекс первого
символа в слове, содержащем
index-ный символ строки string.
Словом считается любая непрерывная последовательность из букв, цифр и символа
подчеркивания, или любой другой одиночный символ.
subst
Команда выполняет подстановки
переменных, команд и подстановки с обратным слешем.СИНТАКСИС subst ?-nobackslashes
?
?-nocommands? ?-novariables?
stringОПИСАНИЕ Команда subst выполняет
подстановки переменных, подстановки команд и подстановки с обратным слешем
в строке
string и возвращает получившуюся строку. Все подстановки
выполняются обычным для Tcl образом. В результате подстановки в строке
string
выполняются дважды: один раз ≈ анализатором команд Tcl и второй раз ≈ командой
subst.
Если задан любой из ключей
-nobackslashes,
-nocommands или -novariables, то соответствующие подстановки
не выполняются.
Внимание! При выполнении
подстановок команда subst не обращает внимания на двойные кавычки
и фигурные скобки. Например, следующий скрипт
set a 44
subst {xyz {$a}}
вернет ⌠xyz {44}■, а
не ⌠xyz {$a}■.
switch
Команда выполняет один
из нескольких скриптов в зависимости от полученного значения.СИНТАКСИСswitch?options?
string pattern body?pattern body...?
ОПИСАНИЕКоманда switch сравнивает
аргумент string по очереди с каждым из образцов, заданных аргументами
pattern.
Если строка string соответствует очередному образцу, выполняется
соответствующий скрипт body и команда возвращает результат его выполнения.
Если последний из образцов равен default, то ему соответствует любая
строка. Если строка не соответствует ни одному из образцов (что значит,
в частности, что образец default отсутствует), то никакой скрипт
не выполняется и команда возвращает пустое значение.
Если один или несколько первых
аргументов команды начинаются с ⌠-■, они считаются опциями команды.
Возможные опции перечислены ниже.
-exact
Строка считается соответствующей
образцу, только если она в точности с ним совпадает. Этот режим используется
по умолчанию.
-glob
При сравнении строки с
образцом используются те же правила, что и в команде string match.
-regexp
При сравнении строки с
образцом используются те же правила, что и в команде regexp.
-
Обозначает конец опций.
Следующий аргумент считается строкой string, даже если он начинается
с символа ⌠-■.
Команда предполагает
использование одной из двух синтаксических форм для задания образцов и
скриптов. Первая использует отдельные аргументы для каждого образца и скрипта.
Эта форма удобна при необходимости выполнить подстановки в образцах и/или
скриптах. Во второй форме все они помещаются в один аргумент, который должен
быть списком. Элементами этого списка должны быть, соответственно, образцы
и скрипты. Эта форма более удобна для длинных команд, не размещающихся
в одной строке, поскольку она не требует использовать обратный слеш в конце
каждой строки. Но при ее использовании необходимо учитывать, что, поскольку
список содержится в фигурных скобках, подстановки команд и переменных в
образцах и скриптах не производятся. Вследствие этого результат выполнения
команды, записанной в различных формах, может различаться.
Если один из аргументов body
равен ▒-▓, это означает, что при совпадении строки с данным образцом
будет выполняться скрипт body для следующего образца. Если для следующего
образца скрипт также равен ▒-▓, то будет использован скрипт для
следующего за ним образца и т.д.
Ниже приведены примеры использования
команды switch.
Команда
switch abc a ≈ b {format
1} abc {format 2} default {format 3}
вернет значение ▒2▓.
Команда
switch -regexp aaab
{^a.*b$ - b {format 1} a* {format 2} default {format 3}}
вернет значение ▒1▓.
А команда
switch xyz {a - b {format 1} a* {format 2} default {format 3}}
вернет значение ▒3▓.
tclvars
Переменные, используемые
Tcl.ОПИСАНИЕ Следующие глобальные переменные
автоматически создаются при запуске программ. Как правило, они ведутся
автоматически и в пользовательском приложении их значения не изменяются.
env
Эта переменная представляет
собой массив, элементы которого соответствуют переменным окружения. Присвоение
значения элементу массива приводит к изменению значения (или созданию)
соответствующей переменной окружения. Удаление элемента массива с помощью
команды unset удаляет соответствующую
переменную окружения. Модифицированное состояние массива используется для
процессов ≈ потомков, запущенных командой exec.
На Windows-платформах переменные
PATH,
COMSPEC
и WINDIR всегда пишутся в верхнем регистре. Все остальные переменные
оставляются в том виде, в каком они заданы в операционной системе.
На Macintosh-платформах,
на которых нет переменных окружения, автоматически формируемый массив env,
тем не менее, содержит следующие элементы:
LOGIN, USER, SYS_FOLDER,
APPLE_M_FOLDER, CP_FOLDER, DESK_FOLDER, EXT_FOLDER, PREF_FOLDER, PRINT_MON_FOLDER,
SHARED_TRASH_FOLDER, TRASH_FOLDER, START_UP_FOLDER, PWDerrorCodeПри возникновении ошибки
эта переменная содержит дополнительную информацию об ошибке в форме, удобной
для автоматической обработки. Эта информация содержится в виде списка из
одного или более элементов. Первый элемент списка содержит имя класса ошибки.
Его значение определяет формат остальной части списка. Стандартно используются
следующие классы ошибок (в приложении могут определяться и дополнительные
классы):
ARITH code msgЭтот класс ошибки формируется
при арифметической ошибке (например, при попытке делить на ноль в команде
expr).
Код code определяет конкретный тип ошибки, а msg содержит
текст с описанием ошибки. Возможные значения кода DIVZERO (попытка
делить на нуль), DOMAIN (аргумент не принадлежит области определения
функции, например acos(2)), IOVERFLOW (переполнение при целочисленных
операциях), OVERFLOW (переполнение при вычислениях с плавающей запятой)
или UNKNOWN (если не удается определить тип ошибки).CHILDKILLED pid sigName
msgЭтот класс ошибки используется,
если выполнение процесса ≈ потомка прервано сигналом. Второй элемент списка
(pid) содержит в этом случае идентификатор прерванного процесса.
Элемент sigName содержит символьное имя сигнала, например SIGPIPE,
а в элементе
msg содержит текст с описанием сигнала, например ``write
on pipe with no readers''.CHILDSTATUS pid codeЭтот класс ошибки используется,
когда процесс ≈ потомок завершается с кодом ошибки. Второй элемент списка
(pid) содержит в этом случае идентификатор прерванного процесса
а третий элемент (code) ≈ значение кода ошибки.CHILDSUSP pid sigName
msgЭтот класс ошибки используется,
когда выполнение процесса-потомка приостановлено из-за сигнала. Элементы
списка имеют тот же смысл, что и для CHILDKILLED.NONEЭтот класс используется
для тех ошибок, для которых дополнительная информация не может быть получена,
поскольку при попытке ее выдать произошла ошибка.POSIX errName msgЭтот класс используется
для тех ошибок, которые происходят при выполнении вызовов POSIX.
Второй элемент списка содержит символическое имя ошибки, например, ENOENT,
а в элементе
msg содержит текст с описанием ошибки, например, ``no
such file or directory''.errorInfoПри возникновении ошибки
эта переменная содержит описание команды или процедуры, в которой произошла
последняя ошибка. Описание построено в виде описания стека, указывающего
вложенные Tcl-команды, выполнявшиеся при возникновении ошибки.tcl_libraryВ этой переменной хранится
имя каталога, содержащего системную библиотеку Tcl-скриптов, используемых,
в частности, при автозагрузке. Величина этой переменной возвращается командой
info
library. Начальное значение переменной формируется в результате
просмотра ряда каталогов и поиска в них соответствующих скриптов. Если
задана переменная окружения
TCL_LIBRARY, указанный в ней каталог
проверяется первым. Если переменная
TCL_LIBRARY не задана или в
ней не содержатся необходимые файлы, то просматриваются еще несколько каталогов,
зависящих от расположения каталогов Tcl и текущего каталога.tcl_patchLevelВ этой переменной хранится
информация о текущей версии Tcl, например 7.3p2 для второй доработки
версии 7.3. или
7.4b4 для четвертого бета релиза версии 7.4. Значение
переменной возвращается командойinfo patchlevel.tcl_pkgPathПеременная содержит список
каталогов, используемых для размещения пакетов библиотек. Обычно список
состоит из двух элементов ≈ каталога для бинарных файлов и каталога для
скриптов. Пакеты обычно устанавливаются как подкаталоги этих каталогов.
Исходное значение переменной добавляется к списку каталогов в auto_path
и используются для поиска пакетов при выполнении команды package
require. Последующие изменения в
tcl_pkgPath не отражаются
в переменной auto_path. Поэтому дополнительные каталоги для поиска
пакетов необходимо указывать (если это нужно) непосредственно в переменной
auto_path.tcl_platformЭта переменная является
ассоциативным массивом, в элементах которого содержится информация о платформе.
Ниже содержится список элементов массива (расширения и приложения могут
хранить информацию о себе в дополнительных элементах этого массива).byteOrderИсходный порядок байтов
в слове: littleEndian или bigEndianmachineНабор команд, исполняемых
на машине, например intel, PPC, 68k или sun4m. На Unix ≈
платформах совпадает с величиной, возвращаемой командой uname -m.osИмя операционной системы,
например
Win32s, Windows NT, MacOS или SunOS. На Unix ≈ платформах
совпадает с величиной, возвращаемой командой uname -s.osVersionВерсия операционной системы.
На Unix ≈ платформах совпадает с величиной, возвращаемой командой uname
-r.platform Может принимать одно из
значений
windows, macintosh или unix.
tcl_precision
Переменная управляет числом
цифр при переводе десятичных чисел в строки. Значение по умолчанию 12.
Максимальное значение 17 позволяет переводить числа из двоичного представления
в строковое и обратно без потери точности. Однако при этом отключается
округление. В результате команда
expr 1.4
вернет значение ▒1.3999999999999999▓,
если tcl_precision равна ▒17▓, и значение. ▒1.4▓ если tcl_precision равна
▒12▓.
Все интерпретаторы в
процессе используют одно и тоже значение tcl_precision. Изменение точности
представления чисел в одном из интерпретаторов ведет к его синхронному
изменению во всех остальных. Однако, в надежных интерпретаторах изменять
точность нельзя.
tcl_rcFileName
Эта переменная используется
при инициализации для определения имени пользовательского фала, исполняемого
при запуске. Для
wish обычно
ее значение
~/.wishrc
для Unix платформ и ~/wishrc.tcl для
Windows платформ. Если соответствующий файл найден, он читается командой
source.tcl_rcRsrcNameИспользуется только на
Macintosh платформах для задания TEXT ресурса.tcl_traceCompileЭта переменная позволяет
управлять объемом информации, формирующейся при компиляции Tcl в байт-код.
По умолчанию значение переменной равно ▒0▓ и никакая информация не выводится.
Если присвоить
tcl_traceCompile значение ▒1▓, то при компиляции
каждой процедуры или команды верхнего уровня на стандартный выход посылается
одна строка комментариев. Если присвоить
tcl_traceCompile значение
▒2▓, то при компиляции в стандартный вывод выдается подробный листинг.
Это бывает полезно при проблемах, возникающих в процессе компиляции, особенно,
при переводе старых программ на Tcl8.0.tcl_traceExecЭта переменная позволяет
управлять объемом информации, выводящейся при исполнении байт-кода. По
умолчанию
tcl_traceExec равна ▒0▓ и никакая информация не выводится.
Если присвоить tcl_traceExec значение ▒1▓, то при исполнении процедур
в стандартный вывод выдается одна строка текста. Если присвоить tcl_traceExec
значение ▒1▓, то строка текста выдается также при выполнении каждой команды,
а если присвоить tcl_traceExec значение ▒3▓, то выдается информация
о выполнении каждой инструкции байт-кода. Это бывает полезно при проблемах,
возникающих в процессе компиляции и исполнения, особенно, при переводе
старых программ на Tcl8.0.tcl_versionЭта переменная содержит
номер версии Tcl в форме x.y. Обычно изменение x может означать потерю
совместимости с предыдущими версиями, тогда как изменение y означает небольшие
улучшения и исправление ошибок. Значение переменной возвращается командой
info
tclversion.
tell
Команда возвращает текущую
позицию поиска открытого канала.СИНТАКСИС tell channelIdОПИСАНИЕ Команда tell возвращает
десятичную строку, указывающую текущую позицию доступа в канале channelId.
Если канал не поддерживает прямой доступ, то возвращается значение ▒-1▓.
time
Команда выполняет скрипт
заданное количество раз.СИНТАКСИС time script?count?ОПИСАНИЕ Команда time вызовет
интерпретатор Tcl count раз для выполнения скрипта script
или только один раз, если аргумент
count не задан. Команда возвратит
строку вида
503 microseconds per iteration
отображающую среднее время в
микросекундах, израсходованное на одну итерацию. В строке указывается прошедшее
время, а не время работы процессора.
trace
Команда отслеживает работу
с переменными.СИНТАКСИС traceoption?arg
arg...?ОПИСАНИЕ Эта команда вызывает выполнение
указанных Tcl команда при определенных действиях с переменной. Ниже перечислены
возможные опции команды (допускаются сокращения).
trace variablename
ops command
Обеспечивает выполнение
команды command при определенных действиях с переменной name.
Ниже перечислены возможные значения аргумента ops и какие действия
с переменной при этом отслеживаются. Аргумент name может содержать
имя простой переменной, имя элемента массива или имя массива. Если name
содержит имя массива, то команда
command выполняется при соответствующих
действиях с любым элементом массива.
Аргумент ops состоит
из одной или больше букв, перечисленных ниже.
r
Вызывает команду command
при чтении переменной.wВызывает команду command
при присвоении значения переменной.uВызывает команду command
при удалении переменной. Переменная может удаляться как явно (с помощью
команды
unset), так и неявно (при завершении
процедуры). переменная также удаляется при удалении интерпретатора, в котором
она была создана. Однако, при этом соответствующая команда не вызывается,
так как уже нет интерпретатора, в котором ее можно было бы выполнить.
Когда срабатывает команда trace,
то исполняемая команда command дополняется тремя аргументами, как
указано ниже
command name1 name2
op
Здесь name1 это
имя переменной, действия с которой вызвали срабатывание команды. Если это
элемент массива, то name1 это имя массива, а name2 ≈ имя
конкретного элемента массива. В противном случае name2 ≈ пустая
строка. Если в команде
trace было указано имя массива и он удаляется,
то name2 также будет пустой строкой. Имена в переменных name1
и name2 не обязано совпадать с теми, что были заданы в команде trace
variable, поскольку команда
upvar позволяет
процедуре обращаться к переменной по различным именам. Аргумент
op
указывает какое именно действие выполнялось с переменной и может принимать
значения
r, w или u как указано выше.
Команда 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 vdeletename
ops command
Если задано отслеживание
переменной
name с перечнем действий ops и командой command,
то оно будет удалено. Соответственно команда command никогда не
будет вызвана. Команда trace vdelete возвращает пустую строку.trace vinfonameВозвращает список, содержащий
по одному элементу для каждого заданного отслеживания для переменной name.
Каждый элемент списка содержит два элемента, содержащие значения ops
и command из команды trace, которой было задано соответствующее
отслеживание. Если переменная name не существует или для нее не задано
отслеживания, команда возвращает пустую строку.
unknown
Команда unknown
обрабатывает попытки обратиться к несуществующей команде.СИНТАКСИС 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 возвращает результат выполнения найденной команды.
unset
Команда удаляет переменные.СИНТАКСИСunset name?name
name ┘?ОПИСАНИЕКоманда unset удаляет
переменные
name. Правила именования переменных точно такие же, как
для команды
set. Если в команде указано имя
элемента массива, то этот элемент будет удален из массива, не влияя на
остальную часть массива. Если указано имя массива без индекса в скобках,
то будет удален весь массив.
Команда возвращает пустую
строку. Если одна из переменных не существует, команда вернет ошибку, а
последующие переменные не будут удалены.
update
Команда update обрабатывает
события, находящиеся в состоянии ожидания, и обратные вызовы (idle callbacks).СИНТАКСИСupdate?idletasks?ОПИСАНИЕС помощью этой команды
обновляется состояние приложения, поскольку при ее вызове обрабатываются
все необработанные события и выполняются все асинхронные вызовы (idle callbacks).
Если в команде задана опция
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 1 {set x 43;
d}
где d ≈ имя другой Tcl ≈ процедуры,
то команда set изменит переменную x в контексте
процедуры b, а процедура d будет выполняться на третьем уровне стека, как
если бы она была вызвана непосредственно из b. Если в процедуре d в свою
очередь содержится команда
uplevel {set x 42}
то команда set
изменит значение той же переменной x в контексте процедуры b. Процедура
c во время выполнения процедуры d не будет видна в стеке. Соответственно
команда info levelвозвратит уровень текущей
процедуры.
Команда uplevel
позволяет создавать новые управляющие конструкции как Tcl-процедуры.
Команда namespace
evalтак же, как и вызовы процедур, изменяет контекст, в котором
выполняются команды. Соответственно, для каждой команды namespace
eval создается дополнительный уровень в стеке. Поэтому при
указании уровня контекста в стеке каждую вложенную команду namespace
eval надо считать наравне с вызовом процедуры. Это относится
также к командам upvar и info
level. Например, команда
info level 1
вернет список, описывающий самую
верхнюю выполняемую команду, которая является либо вызовом процедуры, либо
командой namespace eval. Независимо от использования команда namespace
eval команда
uplevel #0 выполнит соответствующий скрипт
на уровне глобальных переменных (в глобальном пространстве имен).
upvar
Команда создает связи между
переменными различных уровней стека
СИНТАКСИС
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 позволяет упростить
передачу параметра по ссылке, а также упрощает создание новых управляющий
конструкций. Например, рассмотрим следующую процедуру:
proc add2 name {
upvar $name x
set x [expr $x+2]
}
Процедура add2 вызывается
с аргументом, содержащим имя переменной и увеличивает значение этой переменной
на два. Хотя тот же результат мог быть получен с помощью команды uplevel,
команда upvar позволяет легче работать с переменными из стека вызывающей
процедуры.
Команда 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
Команда задает обработку
событий до тех пор, пока не будет записано значение переменной.СИНТАКСИС 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, то без скобок возникнет бесконечный
цикл.