Пакет: tcl-devel
- Версия
- 8.6.16
- Релиз
- 1.niceos5
- Архитектура
- x86_64
- Хэш GOST
- ad2ff4375bcc3254621d87e2c6195d14c948bc70dd1dc7b0b0883b0c3c009995
- Хэш MD5
- f9eb8e5f76ac5565a3f5b766caf87036
- Хэш SHA256
- 5252e8aec7824a770a00ee80413428f7e956983af63ef0440ea0f116aae77750
- Лицензия
- LGPLv2+
- Дата сборки
- 12 мая 2025 г.
- Размер
- 1,677 ГиБ
- Совместимые ОС
- rpm файл:
- tcl-devel-8.6.16-1.niceos5.x86_64.rpm
Основной пакет
Этот подпакет входит в состав основного пакета: tcl
Зависимости
Имя | Тип | Версия |
---|---|---|
pkgconfig(zlib) | runtime | - |
tcl | runtime | - |
Граф зависимостей
Файлы пакета
-
-
- /usr/include/fakemysql.h 8,731 КиБ
- /usr/include/fakepq.h 1,161 КиБ
- /usr/include/fakesql.h 6,366 КиБ
- /usr/include/itcl.h 5,529 КиБ
- /usr/include/itcl2TclOO.h 1,762 КиБ
- /usr/include/itclDecls.h 6,86 КиБ
- /usr/include/itclInt.h 36,187 КиБ
- /usr/include/itclIntDecls.h 41,746 КиБ
- /usr/include/itclMigrate2TclCore.h 2,853 КиБ
- /usr/include/itclTclIntStubsFcn.h 1,683 КиБ
- /usr/include/mysqlStubs.h 5,518 КиБ
- /usr/include/odbcStubs.h 5,058 КиБ
- /usr/include/pqStubs.h 3,5 КиБ
- /usr/include/tcl.h 92,029 КиБ
- /usr/include/tclDecls.h 171,278 КиБ
- /usr/include/tclOO.h 4,157 КиБ
- /usr/include/tclOODecls.h 9,45 КиБ
- /usr/include/tclPlatDecls.h 4,003 КиБ
- /usr/include/tclThread.h 821 Б
- /usr/include/tclTomMath.h 30,192 КиБ
- /usr/include/tclTomMathDecls.h 26,773 КиБ
- /usr/include/tdbc.h 1,621 КиБ
- /usr/include/tdbcDecls.h 1,459 КиБ
- /usr/include/tdbcInt.h 1,239 КиБ
-
-
- /usr/lib/libtclstub8.6.a 7,824 КиБ
-
- /usr/lib/pkgconfig/tcl.pc 441 Б
-
-
-
-
-
- /usr/share/man/man3/DString.3.gz 4,168 КиБ
- /usr/share/man/man3/Notifier.3.gz 10,847 КиБ
- /usr/share/man/man3/RegExp.3.gz 6,78 КиБ
- /usr/share/man/man3/TCL_MEM_DEBUG.3.gz 3,857 КиБ
- /usr/share/man/man3/Tcl_Access.3.gz 3,557 КиБ
- /usr/share/man/man3/Tcl_AddErrorInfo.3.gz 6,686 КиБ
- /usr/share/man/man3/Tcl_AddObjErrorInfo.3.gz 6,686 КиБ
- /usr/share/man/man3/Tcl_AlertNotifier.3.gz 10,847 КиБ
- /usr/share/man/man3/Tcl_Alloc.3.gz 3,577 КиБ
- /usr/share/man/man3/Tcl_AllocStatBuf.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_AllowExceptions.3.gz 3,012 КиБ
- /usr/share/man/man3/Tcl_AppInit.3.gz 3,482 КиБ
- /usr/share/man/man3/Tcl_AppendAllObjTypes.3.gz 5,64 КиБ
- /usr/share/man/man3/Tcl_AppendElement.3.gz 5,872 КиБ
- /usr/share/man/man3/Tcl_AppendExportList.3.gz 4,346 КиБ
- /usr/share/man/man3/Tcl_AppendFormatToObj.3.gz 7,407 КиБ
- /usr/share/man/man3/Tcl_AppendLimitedToObj.3.gz 7,407 КиБ
- /usr/share/man/man3/Tcl_AppendObjToErrorInfo.3.gz 6,686 КиБ
- /usr/share/man/man3/Tcl_AppendObjToObj.3.gz 7,407 КиБ
- /usr/share/man/man3/Tcl_AppendPrintfToObj.3.gz 7,407 КиБ
- /usr/share/man/man3/Tcl_AppendResult.3.gz 5,872 КиБ
- /usr/share/man/man3/Tcl_AppendResultVA.3.gz 5,872 КиБ
- /usr/share/man/man3/Tcl_AppendStringsToObj.3.gz 7,407 КиБ
- /usr/share/man/man3/Tcl_AppendStringsToObjVA.3.gz 7,407 КиБ
- /usr/share/man/man3/Tcl_AppendToObj.3.gz 7,407 КиБ
- /usr/share/man/man3/Tcl_AppendUnicodeToObj.3.gz 7,407 КиБ
- /usr/share/man/man3/Tcl_AsyncCreate.3.gz 4,626 КиБ
- /usr/share/man/man3/Tcl_AsyncDelete.3.gz 4,626 КиБ
- /usr/share/man/man3/Tcl_AsyncInvoke.3.gz 4,626 КиБ
- /usr/share/man/man3/Tcl_AsyncMark.3.gz 4,626 КиБ
- /usr/share/man/man3/Tcl_AsyncReady.3.gz 4,626 КиБ
- /usr/share/man/man3/Tcl_AttemptAlloc.3.gz 3,577 КиБ
- /usr/share/man/man3/Tcl_AttemptRealloc.3.gz 3,577 КиБ
- /usr/share/man/man3/Tcl_AttemptSetObjLength.3.gz 7,407 КиБ
- /usr/share/man/man3/Tcl_BackgroundError.3.gz 3,479 КиБ
- /usr/share/man/man3/Tcl_BackgroundException.3.gz 3,479 КиБ
- /usr/share/man/man3/Tcl_Backslash.3.gz 2,922 КиБ
- /usr/share/man/man3/Tcl_BadChannelOption.3.gz 11,557 КиБ
- /usr/share/man/man3/Tcl_CallWhenDeleted.3.gz 3,229 КиБ
- /usr/share/man/man3/Tcl_CancelEval.3.gz 3,422 КиБ
- /usr/share/man/man3/Tcl_CancelIdleCall.3.gz 3,645 КиБ
- /usr/share/man/man3/Tcl_Canceled.3.gz 3,422 КиБ
- /usr/share/man/man3/Tcl_ChannelBlockModeProc.3.gz 11,557 КиБ
- /usr/share/man/man3/Tcl_ChannelBuffered.3.gz 11,557 КиБ
- /usr/share/man/man3/Tcl_ChannelClose2Proc.3.gz 11,557 КиБ
- /usr/share/man/man3/Tcl_ChannelCloseProc.3.gz 11,557 КиБ
- /usr/share/man/man3/Tcl_ChannelFlushProc.3.gz 11,557 КиБ
- /usr/share/man/man3/Tcl_ChannelGetHandleProc.3.gz 11,557 КиБ
- /usr/share/man/man3/Tcl_ChannelGetOptionProc.3.gz 11,557 КиБ
- /usr/share/man/man3/Tcl_ChannelHandlerProc.3.gz 11,557 КиБ
- /usr/share/man/man3/Tcl_ChannelInputProc.3.gz 11,557 КиБ
- /usr/share/man/man3/Tcl_ChannelName.3.gz 11,557 КиБ
- /usr/share/man/man3/Tcl_ChannelOutputProc.3.gz 11,557 КиБ
- /usr/share/man/man3/Tcl_ChannelSeekProc.3.gz 11,557 КиБ
- /usr/share/man/man3/Tcl_ChannelSetOptionProc.3.gz 11,557 КиБ
- /usr/share/man/man3/Tcl_ChannelThreadActionProc.3.gz 11,557 КиБ
- /usr/share/man/man3/Tcl_ChannelTruncateProc.3.gz 11,557 КиБ
- /usr/share/man/man3/Tcl_ChannelVersion.3.gz 11,557 КиБ
- /usr/share/man/man3/Tcl_ChannelWatchProc.3.gz 11,557 КиБ
- /usr/share/man/man3/Tcl_ChannelWideSeekProc.3.gz 11,557 КиБ
- /usr/share/man/man3/Tcl_Chdir.3.gz 3,047 КиБ
- /usr/share/man/man3/Tcl_ClassGetMetadata.3.gz 5,946 КиБ
- /usr/share/man/man3/Tcl_ClassSetConstructor.3.gz 5,502 КиБ
- /usr/share/man/man3/Tcl_ClassSetDestructor.3.gz 5,502 КиБ
- /usr/share/man/man3/Tcl_ClassSetMetadata.3.gz 5,946 КиБ
- /usr/share/man/man3/Tcl_ClearChannelHandlers.3.gz 11,557 КиБ
- /usr/share/man/man3/Tcl_Close.3.gz 10,567 КиБ
- /usr/share/man/man3/Tcl_CommandComplete.3.gz 2,747 КиБ
- /usr/share/man/man3/Tcl_CommandTraceInfo.3.gz 4,629 КиБ
- /usr/share/man/man3/Tcl_Concat.3.gz 3,069 КиБ
- /usr/share/man/man3/Tcl_ConcatObj.3.gz 7,407 КиБ
- /usr/share/man/man3/Tcl_ConditionFinalize.3.gz 5,739 КиБ
- /usr/share/man/man3/Tcl_ConditionNotify.3.gz 5,739 КиБ
- /usr/share/man/man3/Tcl_ConditionWait.3.gz 5,739 КиБ
- /usr/share/man/man3/Tcl_ConvertCountedElement.3.gz 4,94 КиБ
- /usr/share/man/man3/Tcl_ConvertElement.3.gz 4,94 КиБ
- /usr/share/man/man3/Tcl_ConvertToType.3.gz 5,64 КиБ
- /usr/share/man/man3/Tcl_CopyObjectInstance.3.gz 5,946 КиБ
- /usr/share/man/man3/Tcl_CreateAlias.3.gz 5,246 КиБ
- /usr/share/man/man3/Tcl_CreateAliasObj.3.gz 5,246 КиБ
- /usr/share/man/man3/Tcl_CreateChannel.3.gz 11,557 КиБ
- /usr/share/man/man3/Tcl_CreateChannelHandler.3.gz 3,677 КиБ
- /usr/share/man/man3/Tcl_CreateChild.3.gz 5,246 КиБ
- /usr/share/man/man3/Tcl_CreateCloseHandler.3.gz 2,971 КиБ
- /usr/share/man/man3/Tcl_CreateCommand.3.gz 4,498 КиБ
- /usr/share/man/man3/Tcl_CreateEncoding.3.gz 10,378 КиБ
- /usr/share/man/man3/Tcl_CreateEnsemble.3.gz 4,842 КиБ
- /usr/share/man/man3/Tcl_CreateEventSource.3.gz 10,847 КиБ
- /usr/share/man/man3/Tcl_CreateExitHandler.3.gz 4,297 КиБ
- /usr/share/man/man3/Tcl_CreateFileHandler.3.gz 3,745 КиБ
- /usr/share/man/man3/Tcl_CreateHashEntry.3.gz 6,495 КиБ
- /usr/share/man/man3/Tcl_CreateInterp.3.gz 4,736 КиБ
- /usr/share/man/man3/Tcl_CreateMathFunc.3.gz 4,68 КиБ
- /usr/share/man/man3/Tcl_CreateNamespace.3.gz 4,346 КиБ
- /usr/share/man/man3/Tcl_CreateObjCommand.3.gz 6,057 КиБ
- /usr/share/man/man3/Tcl_CreateObjTrace.3.gz 4,991 КиБ
- /usr/share/man/man3/Tcl_CreateSlave.3.gz 5,246 КиБ
- /usr/share/man/man3/Tcl_CreateThread.3.gz 5,739 КиБ
- /usr/share/man/man3/Tcl_CreateThreadExitHandler.3.gz 4,297 КиБ
- /usr/share/man/man3/Tcl_CreateTimerHandler.3.gz 3,4 КиБ
- /usr/share/man/man3/Tcl_CreateTrace.3.gz 4,991 КиБ
- /usr/share/man/man3/Tcl_CutChannel.3.gz 11,557 КиБ
- /usr/share/man/man3/Tcl_DStringAppend.3.gz 4,168 КиБ
- /usr/share/man/man3/Tcl_DStringAppendElement.3.gz 4,168 КиБ
- /usr/share/man/man3/Tcl_DStringEndSublist.3.gz 4,168 КиБ
- /usr/share/man/man3/Tcl_DStringFree.3.gz 4,168 КиБ
- /usr/share/man/man3/Tcl_DStringGetResult.3.gz 4,168 КиБ
- /usr/share/man/man3/Tcl_DStringInit.3.gz 4,168 КиБ
- /usr/share/man/man3/Tcl_DStringLength.3.gz 4,168 КиБ
- /usr/share/man/man3/Tcl_DStringResult.3.gz 4,168 КиБ
- /usr/share/man/man3/Tcl_DStringSetLength.3.gz 4,168 КиБ
- /usr/share/man/man3/Tcl_DStringStartSublist.3.gz 4,168 КиБ
- /usr/share/man/man3/Tcl_DStringTrunc.3.gz 4,168 КиБ
- /usr/share/man/man3/Tcl_DStringValue.3.gz 4,168 КиБ
- /usr/share/man/man3/Tcl_DecrRefCount.3.gz 6,903 КиБ
- /usr/share/man/man3/Tcl_DeleteAssocData.3.gz 3,544 КиБ
- /usr/share/man/man3/Tcl_DeleteChannelHandler.3.gz 3,677 КиБ
- /usr/share/man/man3/Tcl_DeleteCloseHandler.3.gz 2,971 КиБ
- /usr/share/man/man3/Tcl_DeleteCommand.3.gz 6,057 КиБ
- /usr/share/man/man3/Tcl_DeleteCommandFromToken.3.gz 6,057 КиБ
- /usr/share/man/man3/Tcl_DeleteEventSource.3.gz 10,847 КиБ
- /usr/share/man/man3/Tcl_DeleteEvents.3.gz 10,847 КиБ
- /usr/share/man/man3/Tcl_DeleteExitHandler.3.gz 4,297 КиБ
- /usr/share/man/man3/Tcl_DeleteFileHandler.3.gz 3,745 КиБ
- /usr/share/man/man3/Tcl_DeleteHashEntry.3.gz 6,495 КиБ
- /usr/share/man/man3/Tcl_DeleteHashTable.3.gz 6,495 КиБ
- /usr/share/man/man3/Tcl_DeleteInterp.3.gz 4,736 КиБ
- /usr/share/man/man3/Tcl_DeleteNamespace.3.gz 4,346 КиБ
- /usr/share/man/man3/Tcl_DeleteThreadExitHandler.3.gz 4,297 КиБ
- /usr/share/man/man3/Tcl_DeleteTimerHandler.3.gz 3,4 КиБ
- /usr/share/man/man3/Tcl_DeleteTrace.3.gz 4,991 КиБ
- /usr/share/man/man3/Tcl_DetachChannel.3.gz 10,567 КиБ
- /usr/share/man/man3/Tcl_DetachPids.3.gz 3,522 КиБ
- /usr/share/man/man3/Tcl_DictObjDone.3.gz 5,617 КиБ
- /usr/share/man/man3/Tcl_DictObjFirst.3.gz 5,617 КиБ
- /usr/share/man/man3/Tcl_DictObjGet.3.gz 5,617 КиБ
- /usr/share/man/man3/Tcl_DictObjNext.3.gz 5,617 КиБ
- /usr/share/man/man3/Tcl_DictObjPut.3.gz 5,617 КиБ
- /usr/share/man/man3/Tcl_DictObjPutKeyList.3.gz 5,617 КиБ
- /usr/share/man/man3/Tcl_DictObjRemove.3.gz 5,617 КиБ
- /usr/share/man/man3/Tcl_DictObjRemoveKeyList.3.gz 5,617 КиБ
- /usr/share/man/man3/Tcl_DictObjSize.3.gz 5,617 КиБ
- /usr/share/man/man3/Tcl_DiscardInterpState.3.gz 3,989 КиБ
- /usr/share/man/man3/Tcl_DiscardResult.3.gz 3,989 КиБ
- /usr/share/man/man3/Tcl_DoOneEvent.3.gz 3,816 КиБ
- /usr/share/man/man3/Tcl_DoWhenIdle.3.gz 3,645 КиБ
- /usr/share/man/man3/Tcl_DontCallWhenDeleted.3.gz 3,229 КиБ
- /usr/share/man/man3/Tcl_DumpActiveMemory.3.gz 3,186 КиБ
- /usr/share/man/man3/Tcl_DuplicateObj.3.gz 6,903 КиБ
- /usr/share/man/man3/Tcl_Eof.3.gz 10,567 КиБ
- /usr/share/man/man3/Tcl_ErrnoId.3.gz 3,091 КиБ
- /usr/share/man/man3/Tcl_ErrnoMsg.3.gz 3,091 КиБ
- /usr/share/man/man3/Tcl_Eval.3.gz 5,332 КиБ
- /usr/share/man/man3/Tcl_EvalEx.3.gz 5,332 КиБ
- /usr/share/man/man3/Tcl_EvalFile.3.gz 5,332 КиБ
- /usr/share/man/man3/Tcl_EvalObjEx.3.gz 5,332 КиБ
- /usr/share/man/man3/Tcl_EvalObjv.3.gz 5,332 КиБ
- /usr/share/man/man3/Tcl_EvalTokens.3.gz 7,451 КиБ
- /usr/share/man/man3/Tcl_EvalTokensStandard.3.gz 7,451 КиБ
- /usr/share/man/man3/Tcl_EventuallyFree.3.gz 3,948 КиБ
- /usr/share/man/man3/Tcl_Exit.3.gz 4,297 КиБ
- /usr/share/man/man3/Tcl_ExitThread.3.gz 4,297 КиБ
- /usr/share/man/man3/Tcl_Export.3.gz 4,346 КиБ
- /usr/share/man/man3/Tcl_ExposeCommand.3.gz 5,246 КиБ
- /usr/share/man/man3/Tcl_ExprBoolean.3.gz 3,515 КиБ
- /usr/share/man/man3/Tcl_ExprBooleanObj.3.gz 3,485 КиБ
- /usr/share/man/man3/Tcl_ExprDouble.3.gz 3,515 КиБ
- /usr/share/man/man3/Tcl_ExprDoubleObj.3.gz 3,485 КиБ
- /usr/share/man/man3/Tcl_ExprLong.3.gz 3,515 КиБ
- /usr/share/man/man3/Tcl_ExprLongObj.3.gz 3,485 КиБ
- /usr/share/man/man3/Tcl_ExprObj.3.gz 3,485 КиБ
- /usr/share/man/man3/Tcl_ExprString.3.gz 3,515 КиБ
- /usr/share/man/man3/Tcl_ExternalToUtf.3.gz 10,378 КиБ
- /usr/share/man/man3/Tcl_ExternalToUtfDString.3.gz 10,378 КиБ
- /usr/share/man/man3/Tcl_FSAccess.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_FSChdir.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_FSConvertToPathType.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_FSCopyDirectory.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_FSCopyFile.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_FSCreateDirectory.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_FSData.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_FSDeleteFile.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_FSEqualPaths.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_FSEvalFile.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_FSEvalFileEx.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_FSFileAttrStrings.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_FSFileAttrsGet.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_FSFileAttrsSet.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_FSFileSystemInfo.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_FSGetCwd.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_FSGetFileSystemForPath.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_FSGetInternalRep.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_FSGetNativePath.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_FSGetNormalizedPath.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_FSGetPathType.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_FSGetTranslatedPath.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_FSGetTranslatedStringPath.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_FSJoinPath.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_FSJoinToPath.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_FSLink.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_FSListVolumes.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_FSLoadFile.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_FSLstat.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_FSMatchInDirectory.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_FSMountsChanged.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_FSNewNativePath.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_FSOpenFileChannel.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_FSPathSeparator.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_FSRegister.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_FSRemoveDirectory.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_FSRenameFile.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_FSSplitPath.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_FSStat.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_FSUnloadFile.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_FSUnregister.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_FSUtime.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_Finalize.3.gz 4,297 КиБ
- /usr/share/man/man3/Tcl_FinalizeNotifier.3.gz 10,847 КиБ
- /usr/share/man/man3/Tcl_FinalizeThread.3.gz 4,297 КиБ
- /usr/share/man/man3/Tcl_FindCommand.3.gz 4,346 КиБ
- /usr/share/man/man3/Tcl_FindEnsemble.3.gz 4,842 КиБ
- /usr/share/man/man3/Tcl_FindExecutable.3.gz 3,236 КиБ
- /usr/share/man/man3/Tcl_FindHashEntry.3.gz 6,495 КиБ
- /usr/share/man/man3/Tcl_FindNamespace.3.gz 4,346 КиБ
- /usr/share/man/man3/Tcl_FindSymbol.3.gz 3,476 КиБ
- /usr/share/man/man3/Tcl_FirstHashEntry.3.gz 6,495 КиБ
- /usr/share/man/man3/Tcl_Flush.3.gz 10,567 КиБ
- /usr/share/man/man3/Tcl_ForgetImport.3.gz 4,346 КиБ
- /usr/share/man/man3/Tcl_Format.3.gz 7,407 КиБ
- /usr/share/man/man3/Tcl_Free.3.gz 3,577 КиБ
- /usr/share/man/man3/Tcl_FreeEncoding.3.gz 10,378 КиБ
- /usr/share/man/man3/Tcl_FreeParse.3.gz 7,451 КиБ
- /usr/share/man/man3/Tcl_FreeResult.3.gz 5,872 КиБ
- /usr/share/man/man3/Tcl_GetAccessTimeFromStat.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_GetAlias.3.gz 5,246 КиБ
- /usr/share/man/man3/Tcl_GetAliasObj.3.gz 5,246 КиБ
- /usr/share/man/man3/Tcl_GetAssocData.3.gz 3,544 КиБ
- /usr/share/man/man3/Tcl_GetBignumFromObj.3.gz 4,209 КиБ
- /usr/share/man/man3/Tcl_GetBlockSizeFromStat.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_GetBlocksFromStat.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_GetBoolean.3.gz 3,622 КиБ
- /usr/share/man/man3/Tcl_GetBooleanFromObj.3.gz 3,581 КиБ
- /usr/share/man/man3/Tcl_GetByteArrayFromObj.3.gz 3,71 КиБ
- /usr/share/man/man3/Tcl_GetChangeTimeFromStat.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_GetChannel.3.gz 10,567 КиБ
- /usr/share/man/man3/Tcl_GetChannelBufferSize.3.gz 11,557 КиБ
- /usr/share/man/man3/Tcl_GetChannelError.3.gz 4,059 КиБ
- /usr/share/man/man3/Tcl_GetChannelErrorInterp.3.gz 4,059 КиБ
- /usr/share/man/man3/Tcl_GetChannelHandle.3.gz 11,557 КиБ
- /usr/share/man/man3/Tcl_GetChannelInstanceData.3.gz 11,557 КиБ
- /usr/share/man/man3/Tcl_GetChannelMode.3.gz 11,557 КиБ
- /usr/share/man/man3/Tcl_GetChannelName.3.gz 11,557 КиБ
- /usr/share/man/man3/Tcl_GetChannelNames.3.gz 10,567 КиБ
- /usr/share/man/man3/Tcl_GetChannelNamesEx.3.gz 10,567 КиБ
- /usr/share/man/man3/Tcl_GetChannelOption.3.gz 10,567 КиБ
- /usr/share/man/man3/Tcl_GetChannelThread.3.gz 11,557 КиБ
- /usr/share/man/man3/Tcl_GetChannelType.3.gz 11,557 КиБ
- /usr/share/man/man3/Tcl_GetCharLength.3.gz 7,407 КиБ
- /usr/share/man/man3/Tcl_GetChild.3.gz 5,246 КиБ
- /usr/share/man/man3/Tcl_GetClassAsObject.3.gz 5,946 КиБ
- /usr/share/man/man3/Tcl_GetCommandFromObj.3.gz 6,057 КиБ
- /usr/share/man/man3/Tcl_GetCommandFullName.3.gz 6,057 КиБ
- /usr/share/man/man3/Tcl_GetCommandInfo.3.gz 6,057 КиБ
- /usr/share/man/man3/Tcl_GetCommandInfoFromToken.3.gz 6,057 КиБ
- /usr/share/man/man3/Tcl_GetCommandName.3.gz 6,057 КиБ
- /usr/share/man/man3/Tcl_GetCurrentNamespace.3.gz 4,346 КиБ
- /usr/share/man/man3/Tcl_GetCurrentThread.3.gz 10,847 КиБ
- /usr/share/man/man3/Tcl_GetCwd.3.gz 3,047 КиБ
- /usr/share/man/man3/Tcl_GetDefaultEncodingDir.3.gz 10,378 КиБ
- /usr/share/man/man3/Tcl_GetDeviceTypeFromStat.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_GetDouble.3.gz 3,622 КиБ
- /usr/share/man/man3/Tcl_GetDoubleFromObj.3.gz 3,27 КиБ
- /usr/share/man/man3/Tcl_GetEncoding.3.gz 10,378 КиБ
- /usr/share/man/man3/Tcl_GetEncodingFromObj.3.gz 10,378 КиБ
- /usr/share/man/man3/Tcl_GetEncodingName.3.gz 10,378 КиБ
- /usr/share/man/man3/Tcl_GetEncodingNameFromEnvironment.3.gz 10,378 КиБ
- /usr/share/man/man3/Tcl_GetEncodingNames.3.gz 10,378 КиБ
- /usr/share/man/man3/Tcl_GetEncodingSearchPath.3.gz 10,378 КиБ
- /usr/share/man/man3/Tcl_GetEnsembleFlags.3.gz 4,842 КиБ
- /usr/share/man/man3/Tcl_GetEnsembleMappingDict.3.gz 4,842 КиБ
- /usr/share/man/man3/Tcl_GetEnsembleNamespace.3.gz 4,842 КиБ
- /usr/share/man/man3/Tcl_GetEnsembleParameterList.3.gz 4,842 КиБ
- /usr/share/man/man3/Tcl_GetEnsembleSubcommandList.3.gz 4,842 КиБ
- /usr/share/man/man3/Tcl_GetEnsembleUnknownHandler.3.gz 4,842 КиБ
- /usr/share/man/man3/Tcl_GetErrno.3.gz 3,091 КиБ
- /usr/share/man/man3/Tcl_GetErrorLine.3.gz 6,686 КиБ
- /usr/share/man/man3/Tcl_GetFSDeviceFromStat.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_GetFSInodeFromStat.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_GetGlobalNamespace.3.gz 4,346 КиБ
- /usr/share/man/man3/Tcl_GetGroupIdFromStat.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_GetHashKey.3.gz 6,495 КиБ
- /usr/share/man/man3/Tcl_GetHashValue.3.gz 6,495 КиБ
- /usr/share/man/man3/Tcl_GetHostName.3.gz 2,605 КиБ
- /usr/share/man/man3/Tcl_GetIndexFromObj.3.gz 4,016 КиБ
- /usr/share/man/man3/Tcl_GetIndexFromObjStruct.3.gz 4,016 КиБ
- /usr/share/man/man3/Tcl_GetInt.3.gz 3,622 КиБ
- /usr/share/man/man3/Tcl_GetIntFromObj.3.gz 4,209 КиБ
- /usr/share/man/man3/Tcl_GetInterpPath.3.gz 5,246 КиБ
- /usr/share/man/man3/Tcl_GetLinkCountFromStat.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_GetLongFromObj.3.gz 4,209 КиБ
- /usr/share/man/man3/Tcl_GetMaster.3.gz 5,246 КиБ
- /usr/share/man/man3/Tcl_GetMathFuncInfo.3.gz 4,68 КиБ
- /usr/share/man/man3/Tcl_GetMemoryInfo.3.gz 3,577 КиБ
- /usr/share/man/man3/Tcl_GetModeFromStat.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_GetModificationTimeFromStat.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_GetNameOfExecutable.3.gz 3,236 КиБ
- /usr/share/man/man3/Tcl_GetNamespaceUnknownHandler.3.gz 4,346 КиБ
- /usr/share/man/man3/Tcl_GetObjResult.3.gz 5,872 КиБ
- /usr/share/man/man3/Tcl_GetObjType.3.gz 5,64 КиБ
- /usr/share/man/man3/Tcl_GetObjectAsClass.3.gz 5,946 КиБ
- /usr/share/man/man3/Tcl_GetObjectCommand.3.gz 5,946 КиБ
- /usr/share/man/man3/Tcl_GetObjectFromObj.3.gz 5,946 КиБ
- /usr/share/man/man3/Tcl_GetObjectName.3.gz 5,946 КиБ
- /usr/share/man/man3/Tcl_GetObjectNamespace.3.gz 5,946 КиБ
- /usr/share/man/man3/Tcl_GetOpenFile.3.gz 3,184 КиБ
- /usr/share/man/man3/Tcl_GetParent.3.gz 5,246 КиБ
- /usr/share/man/man3/Tcl_GetPathType.3.gz 3,657 КиБ
- /usr/share/man/man3/Tcl_GetRange.3.gz 7,407 КиБ
- /usr/share/man/man3/Tcl_GetRegExpFromObj.3.gz 6,78 КиБ
- /usr/share/man/man3/Tcl_GetReturnOptions.3.gz 6,686 КиБ
- /usr/share/man/man3/Tcl_GetServiceMode.3.gz 10,847 КиБ
- /usr/share/man/man3/Tcl_GetSizeFromStat.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_GetSlave.3.gz 5,246 КиБ
- /usr/share/man/man3/Tcl_GetStackedChannel.3.gz 3,75 КиБ
- /usr/share/man/man3/Tcl_GetStartupScript.3.gz 5,37 КиБ
- /usr/share/man/man3/Tcl_GetStdChannel.3.gz 3,583 КиБ
- /usr/share/man/man3/Tcl_GetString.3.gz 7,407 КиБ
- /usr/share/man/man3/Tcl_GetStringFromObj.3.gz 7,407 КиБ
- /usr/share/man/man3/Tcl_GetStringResult.3.gz 5,872 КиБ
- /usr/share/man/man3/Tcl_GetThreadData.3.gz 5,739 КиБ
- /usr/share/man/man3/Tcl_GetTime.3.gz 3,948 КиБ
- /usr/share/man/man3/Tcl_GetTopChannel.3.gz 3,75 КиБ
- /usr/share/man/man3/Tcl_GetUniChar.3.gz 7,407 КиБ
- /usr/share/man/man3/Tcl_GetUnicode.3.gz 7,407 КиБ
- /usr/share/man/man3/Tcl_GetUnicodeFromObj.3.gz 7,407 КиБ
- /usr/share/man/man3/Tcl_GetUserIdFromStat.3.gz 20,102 КиБ
- /usr/share/man/man3/Tcl_GetVar.3.gz 5,038 КиБ
- /usr/share/man/man3/Tcl_GetVar2.3.gz 5,038 КиБ
- /usr/share/man/man3/Tcl_GetVar2Ex.3.gz 5,038 КиБ
- /usr/share/man/man3/Tcl_GetVersion.3.gz 2,987 КиБ
- /usr/share/man/man3/Tcl_GetWideIntFromObj.3.gz 4,209 КиБ
- /usr/share/man/man3/Tcl_Gets.3.gz 10,567 КиБ
- /usr/share/man/man3/Tcl_GetsObj.3.gz 10,567 КиБ
- /usr/share/man/man3/Tcl_GlobalEval.3.gz 5,332 КиБ
- /usr/share/man/man3/Tcl_GlobalEvalObj.3.gz 5,332 КиБ
- /usr/share/man/man3/Tcl_HashStats.3.gz 6,495 КиБ
- /usr/share/man/man3/Tcl_HideCommand.3.gz 5,246 КиБ
- /usr/share/man/man3/Tcl_Import.3.gz 4,346 КиБ
- /usr/share/man/man3/Tcl_IncrRefCount.3.gz 6,903 КиБ
- /usr/share/man/man3/Tcl_Init.3.gz 2,621 КиБ
- /usr/share/man/man3/Tcl_InitCustomHashTable.3.gz 6,495 КиБ
- /usr/share/man/man3/Tcl_InitHashTable.3.gz 6,495 КиБ
- /usr/share/man/man3/Tcl_InitMemory.3.gz 3,186 КиБ
- /usr/share/man/man3/Tcl_InitNotifier.3.gz 10,847 КиБ
- /usr/share/man/man3/Tcl_InitObjHashTable.3.gz 6,495 КиБ
- /usr/share/man/man3/Tcl_InitStubs.3.gz 3,695 КиБ
- /usr/share/man/man3/Tcl_InputBlocked.3.gz 10,567 КиБ
- /usr/share/man/man3/Tcl_InputBuffered.3.gz 10,567 КиБ
- /usr/share/man/man3/Tcl_Interp.3.gz 4,501 КиБ
- /usr/share/man/man3/Tcl_InterpActive.3.gz 4,736 КиБ
- /usr/share/man/man3/Tcl_InterpDeleted.3.gz 4,736 КиБ
- /usr/share/man/man3/Tcl_InvalidateStringRep.3.gz 6,903 КиБ
- /usr/share/man/man3/Tcl_IsChannelExisting.3.gz 11,557 КиБ
- /usr/share/man/man3/Tcl_IsChannelRegistered.3.gz 11,557 КиБ
- /usr/share/man/man3/Tcl_IsChannelShared.3.gz 11,557 КиБ
- /usr/share/man/man3/Tcl_IsEnsemble.3.gz 4,842 КиБ
- /usr/share/man/man3/Tcl_IsSafe.3.gz 5,246 КиБ
- /usr/share/man/man3/Tcl_IsShared.3.gz 6,903 КиБ
- /usr/share/man/man3/Tcl_IsStandardChannel.3.gz 10,567 КиБ
- /usr/share/man/man3/Tcl_JoinPath.3.gz 3,657 КиБ
- /usr/share/man/man3/Tcl_JoinThread.3.gz 5,739 КиБ
- /usr/share/man/man3/Tcl_LimitAddHandler.3.gz 4,891 КиБ
- /usr/share/man/man3/Tcl_LimitCheck.3.gz 4,891 КиБ
- /usr/share/man/man3/Tcl_LimitExceeded.3.gz 4,891 КиБ
- /usr/share/man/man3/Tcl_LimitGetCommands.3.gz 4,891 КиБ
- /usr/share/man/man3/Tcl_LimitGetGranularity.3.gz 4,891 КиБ
- /usr/share/man/man3/Tcl_LimitGetTime.3.gz 4,891 КиБ
- /usr/share/man/man3/Tcl_LimitReady.3.gz 4,891 КиБ
- /usr/share/man/man3/Tcl_LimitRemoveHandler.3.gz 4,891 КиБ
- /usr/share/man/man3/Tcl_LimitSetCommands.3.gz 4,891 КиБ
- /usr/share/man/man3/Tcl_LimitSetGranularity.3.gz 4,891 КиБ
- /usr/share/man/man3/Tcl_LimitSetTime.3.gz 4,891 КиБ
- /usr/share/man/man3/Tcl_LimitTypeEnabled.3.gz 4,891 КиБ
- /usr/share/man/man3/Tcl_LimitTypeExceeded.3.gz 4,891 КиБ
- /usr/share/man/man3/Tcl_LimitTypeReset.3.gz 4,891 КиБ
- /usr/share/man/man3/Tcl_LimitTypeSet.3.gz 4,891 КиБ
- /usr/share/man/man3/Tcl_LinkVar.3.gz 4,603 КиБ
- /usr/share/man/man3/Tcl_ListMathFuncs.3.gz 4,68 КиБ
- /usr/share/man/man3/Tcl_ListObjAppendElement.3.gz 4,909 КиБ
- /usr/share/man/man3/Tcl_ListObjAppendList.3.gz 4,909 КиБ
- /usr/share/man/man3/Tcl_ListObjGetElements.3.gz 4,909 КиБ
- /usr/share/man/man3/Tcl_ListObjIndex.3.gz 4,909 КиБ
- /usr/share/man/man3/Tcl_ListObjLength.3.gz 4,909 КиБ
- /usr/share/man/man3/Tcl_ListObjReplace.3.gz 4,909 КиБ
- /usr/share/man/man3/Tcl_LoadFile.3.gz 3,476 КиБ
- /usr/share/man/man3/Tcl_LogCommandInfo.3.gz 6,686 КиБ
- /usr/share/man/man3/Tcl_Main.3.gz 5,37 КиБ
- /usr/share/man/man3/Tcl_MainEx.3.gz 5,37 КиБ
- /usr/share/man/man3/Tcl_MainExW.3.gz 5,37 КиБ
- /usr/share/man/man3/Tcl_MakeFileChannel.3.gz 10,567 КиБ
- /usr/share/man/man3/Tcl_MakeSafe.3.gz 5,246 КиБ
- /usr/share/man/man3/Tcl_MakeTcpClientChannel.3.gz 4,723 КиБ
- /usr/share/man/man3/Tcl_Merge.3.gz 4,94 КиБ
- /usr/share/man/man3/Tcl_MethodDeclarerClass.3.gz 5,502 КиБ
- /usr/share/man/man3/Tcl_MethodDeclarerObject.3.gz 5,502 КиБ
- /usr/share/man/man3/Tcl_MethodIsPublic.3.gz 5,502 КиБ
- /usr/share/man/man3/Tcl_MethodIsType.3.gz 5,502 КиБ
- /usr/share/man/man3/Tcl_MethodName.3.gz 5,502 КиБ
- /usr/share/man/man3/Tcl_MutexFinalize.3.gz 5,739 КиБ
- /usr/share/man/man3/Tcl_MutexLock.3.gz 5,739 КиБ
- /usr/share/man/man3/Tcl_MutexUnlock.3.gz 5,739 КиБ
- /usr/share/man/man3/Tcl_NRAddCallback.3.gz 4,806 КиБ
- /usr/share/man/man3/Tcl_NRCallObjProc.3.gz 4,806 КиБ
- /usr/share/man/man3/Tcl_NRCmdSwap.3.gz 4,806 КиБ
- /usr/share/man/man3/Tcl_NRCreateCommand.3.gz 4,806 КиБ
- /usr/share/man/man3/Tcl_NREvalObj.3.gz 4,806 КиБ
- /usr/share/man/man3/Tcl_NREvalObjv.3.gz 4,806 КиБ
- /usr/share/man/man3/Tcl_NRExprObj.3.gz 4,806 КиБ
- /usr/share/man/man3/Tcl_NewBignumObj.3.gz 4,209 КиБ
- /usr/share/man/man3/Tcl_NewBooleanObj.3.gz 3,581 КиБ
- /usr/share/man/man3/Tcl_NewByteArrayObj.3.gz 3,71 КиБ
- /usr/share/man/man3/Tcl_NewDictObj.3.gz 5,617 КиБ
- /usr/share/man/man3/Tcl_NewDoubleObj.3.gz 3,27 КиБ
- /usr/share/man/man3/Tcl_NewInstanceMethod.3.gz 5,502 КиБ
- /usr/share/man/man3/Tcl_NewIntObj.3.gz 4,209 КиБ
- /usr/share/man/man3/Tcl_NewListObj.3.gz 4,909 КиБ
- /usr/share/man/man3/Tcl_NewLongObj.3.gz 4,209 КиБ
- /usr/share/man/man3/Tcl_NewMethod.3.gz 5,502 КиБ
- /usr/share/man/man3/Tcl_NewObj.3.gz 6,903 КиБ
- /usr/share/man/man3/Tcl_NewObjectInstance.3.gz 5,946 КиБ
- /usr/share/man/man3/Tcl_NewStringObj.3.gz 7,407 КиБ
- /usr/share/man/man3/Tcl_NewUnicodeObj.3.gz 7,407 КиБ
- /usr/share/man/man3/Tcl_NewWideIntObj.3.gz 4,209 КиБ
- /usr/share/man/man3/Tcl_NextHashEntry.3.gz 6,495 КиБ
- /usr/share/man/man3/Tcl_NotifyChannel.3.gz 11,557 КиБ
- /usr/share/man/man3/Tcl_NumUtfChars.3.gz 5,568 КиБ
- /usr/share/man/man3/Tcl_OOInitStubs.3.gz 3,188 КиБ
- /usr/share/man/man3/Tcl_ObjGetVar2.3.gz 5,038 КиБ
- /usr/share/man/man3/Tcl_ObjPrintf.3.gz 7,407 КиБ
- /usr/share/man/man3/Tcl_ObjSetVar2.3.gz 5,038 КиБ
- /usr/share/man/man3/Tcl_ObjectContextInvokeNext.3.gz 5,502 КиБ
- /usr/share/man/man3/Tcl_ObjectContextIsFiltering.3.gz 5,502 КиБ
- /usr/share/man/man3/Tcl_ObjectContextMethod.3.gz 5,502 КиБ
- /usr/share/man/man3/Tcl_ObjectContextObject.3.gz 5,502 КиБ
- /usr/share/man/man3/Tcl_ObjectContextSkippedArgs.3.gz 5,502 КиБ
- /usr/share/man/man3/Tcl_ObjectDeleted.3.gz 5,946 КиБ
- /usr/share/man/man3/Tcl_ObjectGetMetadata.3.gz 5,946 КиБ
- /usr/share/man/man3/Tcl_ObjectGetMethodNameMapper.3.gz 5,946 КиБ
- /usr/share/man/man3/Tcl_ObjectSetMetadata.3.gz 5,946 КиБ
- /usr/share/man/man3/Tcl_ObjectSetMethodNameMapper.3.gz 5,946 КиБ
- /usr/share/man/man3/Tcl_OpenCommandChannel.3.gz 10,567 КиБ
- /usr/share/man/man3/Tcl_OpenFileChannel.3.gz 10,567 КиБ
- /usr/share/man/man3/Tcl_OpenTcpClient.3.gz 4,723 КиБ
- /usr/share/man/man3/Tcl_OpenTcpServer.3.gz 4,723 КиБ
- /usr/share/man/man3/Tcl_OutputBuffered.3.gz 10,567 КиБ
- /usr/share/man/man3/Tcl_Panic.3.gz 3,586 КиБ
- /usr/share/man/man3/Tcl_PanicVA.3.gz 3,586 КиБ
- /usr/share/man/man3/Tcl_ParseArgsObjv.3.gz 4,614 КиБ
- /usr/share/man/man3/Tcl_ParseBraces.3.gz 7,451 КиБ
- /usr/share/man/man3/Tcl_ParseCommand.3.gz 7,451 КиБ
- /usr/share/man/man3/Tcl_ParseExpr.3.gz 7,451 КиБ
- /usr/share/man/man3/Tcl_ParseQuotedString.3.gz 7,451 КиБ
- /usr/share/man/man3/Tcl_ParseVar.3.gz 7,451 КиБ
- /usr/share/man/man3/Tcl_ParseVarName.3.gz 7,451 КиБ
- /usr/share/man/man3/Tcl_PkgPresent.3.gz 3,457 КиБ
- /usr/share/man/man3/Tcl_PkgPresentEx.3.gz 3,457 КиБ
- /usr/share/man/man3/Tcl_PkgProvide.3.gz 3,457 КиБ
- /usr/share/man/man3/Tcl_PkgProvideEx.3.gz 3,457 КиБ
- /usr/share/man/man3/Tcl_PkgRequire.3.gz 3,457 КиБ
- /usr/share/man/man3/Tcl_PkgRequireEx.3.gz 3,457 КиБ
- /usr/share/man/man3/Tcl_PkgRequireProc.3.gz 3,457 КиБ
- /usr/share/man/man3/Tcl_PosixError.3.gz 6,686 КиБ
- /usr/share/man/man3/Tcl_Preserve.3.gz 3,948 КиБ
- /usr/share/man/man3/Tcl_PrintDouble.3.gz 3,138 КиБ
- /usr/share/man/man3/Tcl_PutEnv.3.gz 2,785 КиБ
- /usr/share/man/man3/Tcl_QueryTimeProc.3.gz 3,948 КиБ
- /usr/share/man/man3/Tcl_QueueEvent.3.gz 10,847 КиБ
- /usr/share/man/man3/Tcl_Read.3.gz 10,567 КиБ
- /usr/share/man/man3/Tcl_ReadChars.3.gz 10,567 КиБ
- /usr/share/man/man3/Tcl_ReadRaw.3.gz 10,567 КиБ
- /usr/share/man/man3/Tcl_Realloc.3.gz 3,577 КиБ
- /usr/share/man/man3/Tcl_ReapDetachedProcs.3.gz 3,522 КиБ
- /usr/share/man/man3/Tcl_RecordAndEval.3.gz 3,146 КиБ
- /usr/share/man/man3/Tcl_RecordAndEvalObj.3.gz 3,097 КиБ
- /usr/share/man/man3/Tcl_RegExpCompile.3.gz 6,78 КиБ
- /usr/share/man/man3/Tcl_RegExpExec.3.gz 6,78 КиБ
- /usr/share/man/man3/Tcl_RegExpExecObj.3.gz 6,78 КиБ
- /usr/share/man/man3/Tcl_RegExpGetInfo.3.gz 6,78 КиБ
- /usr/share/man/man3/Tcl_RegExpMatch.3.gz 6,78 КиБ
- /usr/share/man/man3/Tcl_RegExpMatchObj.3.gz 6,78 КиБ
- /usr/share/man/man3/Tcl_RegExpRange.3.gz 6,78 КиБ
- /usr/share/man/man3/Tcl_RegisterChannel.3.gz 10,567 КиБ
- /usr/share/man/man3/Tcl_RegisterConfig.3.gz 3,882 КиБ
- /usr/share/man/man3/Tcl_RegisterObjType.3.gz 5,64 КиБ
- /usr/share/man/man3/Tcl_Release.3.gz 3,948 КиБ
- /usr/share/man/man3/Tcl_ResetResult.3.gz 5,872 КиБ
- /usr/share/man/man3/Tcl_RestoreInterpState.3.gz 3,989 КиБ
- /usr/share/man/man3/Tcl_RestoreResult.3.gz 3,989 КиБ
- /usr/share/man/man3/Tcl_SaveInterpState.3.gz 3,989 КиБ
- /usr/share/man/man3/Tcl_SaveResult.3.gz 3,989 КиБ
- /usr/share/man/man3/Tcl_ScanCountedElement.3.gz 4,94 КиБ
- /usr/share/man/man3/Tcl_ScanElement.3.gz 4,94 КиБ
- /usr/share/man/man3/Tcl_Seek.3.gz 10,567 КиБ
- /usr/share/man/man3/Tcl_ServiceAll.3.gz 10,847 КиБ
- /usr/share/man/man3/Tcl_ServiceEvent.3.gz 10,847 КиБ
- /usr/share/man/man3/Tcl_ServiceModeHook.3.gz 10,847 КиБ
- /usr/share/man/man3/Tcl_SetAssocData.3.gz 3,544 КиБ
- /usr/share/man/man3/Tcl_SetBignumObj.3.gz 4,209 КиБ
- /usr/share/man/man3/Tcl_SetBooleanObj.3.gz 3,581 КиБ
- /usr/share/man/man3/Tcl_SetByteArrayLength.3.gz 3,71 КиБ
- /usr/share/man/man3/Tcl_SetByteArrayObj.3.gz 3,71 КиБ
- /usr/share/man/man3/Tcl_SetChannelBufferSize.3.gz 11,557 КиБ
- /usr/share/man/man3/Tcl_SetChannelError.3.gz 4,059 КиБ
- /usr/share/man/man3/Tcl_SetChannelErrorInterp.3.gz 4,059 КиБ
- /usr/share/man/man3/Tcl_SetChannelOption.3.gz 10,567 КиБ
- /usr/share/man/man3/Tcl_SetCommandInfo.3.gz 6,057 КиБ
- /usr/share/man/man3/Tcl_SetCommandInfoFromToken.3.gz 6,057 КиБ
- /usr/share/man/man3/Tcl_SetDefaultEncodingDir.3.gz 10,378 КиБ
- /usr/share/man/man3/Tcl_SetDoubleObj.3.gz 3,27 КиБ
- /usr/share/man/man3/Tcl_SetEncodingSearchPath.3.gz 10,378 КиБ
- /usr/share/man/man3/Tcl_SetEnsembleFlags.3.gz 4,842 КиБ
- /usr/share/man/man3/Tcl_SetEnsembleMappingDict.3.gz 4,842 КиБ
- /usr/share/man/man3/Tcl_SetEnsembleParameterList.3.gz 4,842 КиБ
- /usr/share/man/man3/Tcl_SetEnsembleSubcommandList.3.gz 4,842 КиБ
- /usr/share/man/man3/Tcl_SetEnsembleUnknownHandler.3.gz 4,842 КиБ
- /usr/share/man/man3/Tcl_SetErrno.3.gz 3,091 КиБ
- /usr/share/man/man3/Tcl_SetErrorCode.3.gz 6,686 КиБ
- /usr/share/man/man3/Tcl_SetErrorCodeVA.3.gz 6,686 КиБ
- /usr/share/man/man3/Tcl_SetErrorLine.3.gz 6,686 КиБ
- /usr/share/man/man3/Tcl_SetExitProc.3.gz 4,297 КиБ
- /usr/share/man/man3/Tcl_SetHashValue.3.gz 6,495 КиБ
- /usr/share/man/man3/Tcl_SetIntObj.3.gz 4,209 КиБ
- /usr/share/man/man3/Tcl_SetListObj.3.gz 4,909 КиБ
- /usr/share/man/man3/Tcl_SetLongObj.3.gz 4,209 КиБ
- /usr/share/man/man3/Tcl_SetMainLoop.3.gz 5,37 КиБ
- /usr/share/man/man3/Tcl_SetMaxBlockTime.3.gz 10,847 КиБ
- /usr/share/man/man3/Tcl_SetNamespaceUnknownHandler.3.gz 4,346 КиБ
- /usr/share/man/man3/Tcl_SetNotifier.3.gz 10,847 КиБ
- /usr/share/man/man3/Tcl_SetObjErrorCode.3.gz 6,686 КиБ
- /usr/share/man/man3/Tcl_SetObjLength.3.gz 7,407 КиБ
- /usr/share/man/man3/Tcl_SetObjResult.3.gz 5,872 КиБ
- /usr/share/man/man3/Tcl_SetPanicProc.3.gz 3,586 КиБ
- /usr/share/man/man3/Tcl_SetRecursionLimit.3.gz 3,07 КиБ
- /usr/share/man/man3/Tcl_SetResult.3.gz 5,872 КиБ
- /usr/share/man/man3/Tcl_SetReturnOptions.3.gz 6,686 КиБ
- /usr/share/man/man3/Tcl_SetServiceMode.3.gz 10,847 КиБ
- /usr/share/man/man3/Tcl_SetStartupScript.3.gz 5,37 КиБ
- /usr/share/man/man3/Tcl_SetStdChannel.3.gz 3,583 КиБ
- /usr/share/man/man3/Tcl_SetStringObj.3.gz 7,407 КиБ
- /usr/share/man/man3/Tcl_SetSystemEncoding.3.gz 10,378 КиБ
- /usr/share/man/man3/Tcl_SetTimeProc.3.gz 3,948 КиБ
- /usr/share/man/man3/Tcl_SetTimer.3.gz 10,847 КиБ
- /usr/share/man/man3/Tcl_SetUnicodeObj.3.gz 7,407 КиБ
- /usr/share/man/man3/Tcl_SetVar.3.gz 5,038 КиБ
- /usr/share/man/man3/Tcl_SetVar2.3.gz 5,038 КиБ
- /usr/share/man/man3/Tcl_SetVar2Ex.3.gz 5,038 КиБ
- /usr/share/man/man3/Tcl_SetWideIntObj.3.gz 4,209 КиБ
- /usr/share/man/man3/Tcl_SignalId.3.gz 2,75 КиБ
- /usr/share/man/man3/Tcl_SignalMsg.3.gz 2,75 КиБ
- /usr/share/man/man3/Tcl_Sleep.3.gz 2,811 КиБ
- /usr/share/man/man3/Tcl_SourceRCFile.3.gz 2,685 КиБ
- /usr/share/man/man3/Tcl_SpliceChannel.3.gz 11,557 КиБ
- /usr/share/man/man3/Tcl_SplitList.3.gz 4,94 КиБ
- /usr/share/man/man3/Tcl_SplitPath.3.gz 3,657 КиБ
- /usr/share/man/man3/Tcl_StackChannel.3.gz 3,75 КиБ
- /usr/share/man/man3/Tcl_StandardChannels.3.gz 3,953 КиБ
- /usr/share/man/man3/Tcl_Stat.3.gz 3,557 КиБ
- /usr/share/man/man3/Tcl_StaticPackage.3.gz 3,413 КиБ
- /usr/share/man/man3/Tcl_StringCaseMatch.3.gz 3 КиБ
- /usr/share/man/man3/Tcl_StringMatch.3.gz 3 КиБ
- /usr/share/man/man3/Tcl_SubstObj.3.gz 3,314 КиБ
- /usr/share/man/man3/Tcl_TakeBignumFromObj.3.gz 4,209 КиБ
- /usr/share/man/man3/Tcl_Tell.3.gz 10,567 КиБ
- /usr/share/man/man3/Tcl_ThreadAlert.3.gz 10,847 КиБ
- /usr/share/man/man3/Tcl_ThreadQueueEvent.3.gz 10,847 КиБ
- /usr/share/man/man3/Tcl_TraceCommand.3.gz 4,629 КиБ
- /usr/share/man/man3/Tcl_TraceVar.3.gz 7,401 КиБ
- /usr/share/man/man3/Tcl_TraceVar2.3.gz 7,401 КиБ
- /usr/share/man/man3/Tcl_TransferResult.3.gz 5,872 КиБ
- /usr/share/man/man3/Tcl_TranslateFileName.3.gz 3,472 КиБ
- /usr/share/man/man3/Tcl_TruncateChannel.3.gz 10,567 КиБ
- /usr/share/man/man3/Tcl_Ungets.3.gz 10,567 КиБ
- /usr/share/man/man3/Tcl_UniChar.3.gz 5,568 КиБ
- /usr/share/man/man3/Tcl_UniCharAtIndex.3.gz 5,568 КиБ
- /usr/share/man/man3/Tcl_UniCharCaseMatch.3.gz 5,568 КиБ
- /usr/share/man/man3/Tcl_UniCharIsAlnum.3.gz 2,983 КиБ
- /usr/share/man/man3/Tcl_UniCharIsAlpha.3.gz 2,983 КиБ
- /usr/share/man/man3/Tcl_UniCharIsControl.3.gz 2,983 КиБ
- /usr/share/man/man3/Tcl_UniCharIsDigit.3.gz 2,983 КиБ
- /usr/share/man/man3/Tcl_UniCharIsGraph.3.gz 2,983 КиБ
- /usr/share/man/man3/Tcl_UniCharIsLower.3.gz 2,983 КиБ
- /usr/share/man/man3/Tcl_UniCharIsPrint.3.gz 2,983 КиБ
- /usr/share/man/man3/Tcl_UniCharIsPunct.3.gz 2,983 КиБ
- /usr/share/man/man3/Tcl_UniCharIsSpace.3.gz 2,983 КиБ
- /usr/share/man/man3/Tcl_UniCharIsUpper.3.gz 2,983 КиБ
- /usr/share/man/man3/Tcl_UniCharIsWordChar.3.gz 2,983 КиБ
- /usr/share/man/man3/Tcl_UniCharLen.3.gz 5,568 КиБ
- /usr/share/man/man3/Tcl_UniCharNcasecmp.3.gz 5,568 КиБ
- /usr/share/man/man3/Tcl_UniCharNcmp.3.gz 5,568 КиБ
- /usr/share/man/man3/Tcl_UniCharToLower.3.gz 3,28 КиБ
- /usr/share/man/man3/Tcl_UniCharToTitle.3.gz 3,28 КиБ
- /usr/share/man/man3/Tcl_UniCharToUpper.3.gz 3,28 КиБ
- /usr/share/man/man3/Tcl_UniCharToUtf.3.gz 5,568 КиБ
- /usr/share/man/man3/Tcl_UniCharToUtfDString.3.gz 5,568 КиБ
- /usr/share/man/man3/Tcl_UnlinkVar.3.gz 4,603 КиБ
- /usr/share/man/man3/Tcl_UnregisterChannel.3.gz 10,567 КиБ
- /usr/share/man/man3/Tcl_UnsetVar.3.gz 5,038 КиБ
- /usr/share/man/man3/Tcl_UnsetVar2.3.gz 5,038 КиБ
- /usr/share/man/man3/Tcl_UnstackChannel.3.gz 3,75 КиБ
- /usr/share/man/man3/Tcl_UntraceCommand.3.gz 4,629 КиБ
- /usr/share/man/man3/Tcl_UntraceVar.3.gz 7,401 КиБ
- /usr/share/man/man3/Tcl_UntraceVar2.3.gz 7,401 КиБ
- /usr/share/man/man3/Tcl_UpVar.3.gz 3,434 КиБ
- /usr/share/man/man3/Tcl_UpVar2.3.gz 3,434 КиБ
- /usr/share/man/man3/Tcl_UpdateLinkedVar.3.gz 4,603 КиБ
- /usr/share/man/man3/Tcl_UtfAtIndex.3.gz 5,568 КиБ
- /usr/share/man/man3/Tcl_UtfBackslash.3.gz 5,568 КиБ
- /usr/share/man/man3/Tcl_UtfCharComplete.3.gz 5,568 КиБ
- /usr/share/man/man3/Tcl_UtfFindFirst.3.gz 5,568 КиБ
- /usr/share/man/man3/Tcl_UtfFindLast.3.gz 5,568 КиБ
- /usr/share/man/man3/Tcl_UtfNcasecmp.3.gz 5,568 КиБ
- /usr/share/man/man3/Tcl_UtfNcmp.3.gz 5,568 КиБ
- /usr/share/man/man3/Tcl_UtfNext.3.gz 5,568 КиБ
- /usr/share/man/man3/Tcl_UtfPrev.3.gz 5,568 КиБ
- /usr/share/man/man3/Tcl_UtfToExternal.3.gz 10,378 КиБ
- /usr/share/man/man3/Tcl_UtfToExternalDString.3.gz 10,378 КиБ
- /usr/share/man/man3/Tcl_UtfToLower.3.gz 3,28 КиБ
- /usr/share/man/man3/Tcl_UtfToTitle.3.gz 3,28 КиБ
- /usr/share/man/man3/Tcl_UtfToUniChar.3.gz 5,568 КиБ
- /usr/share/man/man3/Tcl_UtfToUniCharDString.3.gz 5,568 КиБ
- /usr/share/man/man3/Tcl_UtfToUpper.3.gz 3,28 КиБ
- /usr/share/man/man3/Tcl_ValidateAllMemory.3.gz 3,186 КиБ
- /usr/share/man/man3/Tcl_VarEval.3.gz 5,332 КиБ
- /usr/share/man/man3/Tcl_VarEvalVA.3.gz 5,332 КиБ
- /usr/share/man/man3/Tcl_VarTraceInfo.3.gz 7,401 КиБ
- /usr/share/man/man3/Tcl_VarTraceInfo2.3.gz 7,401 КиБ
- /usr/share/man/man3/Tcl_WaitForEvent.3.gz 10,847 КиБ
- /usr/share/man/man3/Tcl_WaitPid.3.gz 3,522 КиБ
- /usr/share/man/man3/Tcl_WinTCharToUtf.3.gz 10,378 КиБ
- /usr/share/man/man3/Tcl_WinUtfToTChar.3.gz 10,378 КиБ
- /usr/share/man/man3/Tcl_Write.3.gz 10,567 КиБ
- /usr/share/man/man3/Tcl_WriteChars.3.gz 10,567 КиБ
- /usr/share/man/man3/Tcl_WriteObj.3.gz 10,567 КиБ
- /usr/share/man/man3/Tcl_WriteRaw.3.gz 10,567 КиБ
- /usr/share/man/man3/Tcl_WrongNumArgs.3.gz 3,366 КиБ
- /usr/share/man/man3/Tcl_ZlibAdler32.3.gz 6,654 КиБ
- /usr/share/man/man3/Tcl_ZlibCRC32.3.gz 6,654 КиБ
- /usr/share/man/man3/Tcl_ZlibDeflate.3.gz 6,654 КиБ
- /usr/share/man/man3/Tcl_ZlibInflate.3.gz 6,654 КиБ
- /usr/share/man/man3/Tcl_ZlibStreamChecksum.3.gz 6,654 КиБ
- /usr/share/man/man3/Tcl_ZlibStreamClose.3.gz 6,654 КиБ
- /usr/share/man/man3/Tcl_ZlibStreamEof.3.gz 6,654 КиБ
- /usr/share/man/man3/Tcl_ZlibStreamGet.3.gz 6,654 КиБ
- /usr/share/man/man3/Tcl_ZlibStreamGetCommandName.3.gz 6,654 КиБ
- /usr/share/man/man3/Tcl_ZlibStreamInit.3.gz 6,654 КиБ
- /usr/share/man/man3/Tcl_ZlibStreamPut.3.gz 6,654 КиБ
- /usr/share/man/man3/Tdbc_Init.3.gz 2,017 КиБ
- /usr/share/man/man3/attemptckalloc.3.gz 3,577 КиБ
- /usr/share/man/man3/attemptckrealloc.3.gz 3,577 КиБ
- /usr/share/man/man3/ckalloc.3.gz 3,577 КиБ
- /usr/share/man/man3/ckfree.3.gz 3,577 КиБ
- /usr/share/man/man3/ckrealloc.3.gz 3,577 КиБ
-
-
- /usr/share/man/mann/Tcl.n.gz 5,718 КиБ
- /usr/share/man/mann/after.n.gz 4,401 КиБ
- /usr/share/man/mann/append.n.gz 2,945 КиБ
- /usr/share/man/mann/apply.n.gz 3,649 КиБ
- /usr/share/man/mann/argc.n.gz 9,47 КиБ
- /usr/share/man/mann/argv.n.gz 9,47 КиБ
- /usr/share/man/mann/argv0.n.gz 9,47 КиБ
- /usr/share/man/mann/array.n.gz 4,606 КиБ
- /usr/share/man/mann/auto_execok.n.gz 6,881 КиБ
- /usr/share/man/mann/auto_import.n.gz 6,881 КиБ
- /usr/share/man/mann/auto_load.n.gz 6,881 КиБ
- /usr/share/man/mann/auto_mkindex.n.gz 6,881 КиБ
- /usr/share/man/mann/auto_path.n.gz 9,47 КиБ
- /usr/share/man/mann/auto_qualify.n.gz 6,881 КиБ
- /usr/share/man/mann/auto_reset.n.gz 6,881 КиБ
- /usr/share/man/mann/bgerror.n.gz 3,926 КиБ
- /usr/share/man/mann/binary.n.gz 10,34 КиБ
- /usr/share/man/mann/body.n.gz 3,866 КиБ
- /usr/share/man/mann/break.n.gz 2,969 КиБ
- /usr/share/man/mann/case.n.gz 3,341 КиБ
- /usr/share/man/mann/catch.n.gz 4,359 КиБ
- /usr/share/man/mann/cd.n.gz 2,815 КиБ
- /usr/share/man/mann/chan.n.gz 14,592 КиБ
- /usr/share/man/mann/class.n.gz 8,509 КиБ
- /usr/share/man/mann/clock.n.gz 13,409 КиБ
- /usr/share/man/mann/close.n.gz 4,127 КиБ
- /usr/share/man/mann/code.n.gz 3,486 КиБ
- /usr/share/man/mann/concat.n.gz 3,063 КиБ
- /usr/share/man/mann/configbody.n.gz 3,751 КиБ
- /usr/share/man/mann/continue.n.gz 2,971 КиБ
- /usr/share/man/mann/coroutine.n.gz 4,675 КиБ
- /usr/share/man/mann/dde.n.gz 4,919 КиБ
- /usr/share/man/mann/delete.n.gz 3,218 КиБ
- /usr/share/man/mann/dict.n.gz 7,937 КиБ
- /usr/share/man/mann/encoding.n.gz 3,729 КиБ
- /usr/share/man/mann/ensemble.n.gz 4,359 КиБ
- /usr/share/man/mann/env.n.gz 9,47 КиБ
- /usr/share/man/mann/eof.n.gz 2,997 КиБ
- /usr/share/man/mann/error.n.gz 3,337 КиБ
- /usr/share/man/mann/errorCode.n.gz 9,47 КиБ
- /usr/share/man/mann/errorInfo.n.gz 9,47 КиБ
- /usr/share/man/mann/eval.n.gz 3,586 КиБ
- /usr/share/man/mann/exec.n.gz 8,48 КиБ
- /usr/share/man/mann/exit.n.gz 2,979 КиБ
- /usr/share/man/mann/expr.n.gz 8,236 КиБ
- /usr/share/man/mann/fblocked.n.gz 1,154 КиБ
- /usr/share/man/mann/fconfigure.n.gz 6,578 КиБ
- /usr/share/man/mann/fcopy.n.gz 4,684 КиБ
- /usr/share/man/mann/file.n.gz 9,26 КиБ
- /usr/share/man/mann/fileevent.n.gz 4,705 КиБ
- /usr/share/man/mann/filename.n.gz 4,959 КиБ
- /usr/share/man/mann/find.n.gz 3,146 КиБ
- /usr/share/man/mann/flush.n.gz 3,021 КиБ
- /usr/share/man/mann/for.n.gz 3,49 КиБ
- /usr/share/man/mann/foreach.n.gz 3,578 КиБ
- /usr/share/man/mann/format.n.gz 6,04 КиБ
- /usr/share/man/mann/gets.n.gz 3,37 КиБ
- /usr/share/man/mann/glob.n.gz 5,482 КиБ
- /usr/share/man/mann/global.n.gz 3,14 КиБ
- /usr/share/man/mann/history.n.gz 3,831 КиБ
- /usr/share/man/mann/http.n.gz 12,869 КиБ
- /usr/share/man/mann/if.n.gz 3,271 КиБ
- /usr/share/man/mann/incr.n.gz 2,958 КиБ
- /usr/share/man/mann/info.n.gz 9,868 КиБ
- /usr/share/man/mann/interp.n.gz 13,664 КиБ
- /usr/share/man/mann/is.n.gz 3,138 КиБ
- /usr/share/man/mann/itcl.n.gz 5,034 КиБ
- /usr/share/man/mann/itclcomponent.n.gz 2,924 КиБ
- /usr/share/man/mann/itcldelegate.n.gz 4,316 КиБ
- /usr/share/man/mann/itclextendedclass.n.gz 8,521 КиБ
- /usr/share/man/mann/itcloption.n.gz 4,005 КиБ
- /usr/share/man/mann/itclvars.n.gz 3,778 КиБ
- /usr/share/man/mann/itclwidget.n.gz 8,526 КиБ
- /usr/share/man/mann/join.n.gz 2,852 КиБ
- /usr/share/man/mann/lappend.n.gz 2,999 КиБ
- /usr/share/man/mann/lassign.n.gz 3,052 КиБ
- /usr/share/man/mann/library.n.gz 6,881 КиБ
- /usr/share/man/mann/lindex.n.gz 3,559 КиБ
- /usr/share/man/mann/linsert.n.gz 3,227 КиБ
- /usr/share/man/mann/list.n.gz 3,059 КиБ
- /usr/share/man/mann/llength.n.gz 2,906 КиБ
- /usr/share/man/mann/lmap.n.gz 3,573 КиБ
- /usr/share/man/mann/load.n.gz 5,187 КиБ
- /usr/share/man/mann/local.n.gz 3,104 КиБ
- /usr/share/man/mann/lrange.n.gz 3,214 КиБ
- /usr/share/man/mann/lrepeat.n.gz 2,807 КиБ
- /usr/share/man/mann/lreplace.n.gz 3,52 КиБ
- /usr/share/man/mann/lreverse.n.gz 2,722 КиБ
- /usr/share/man/mann/lsearch.n.gz 4,87 КиБ
- /usr/share/man/mann/lset.n.gz 3,855 КиБ
- /usr/share/man/mann/lsort.n.gz 4,997 КиБ
- /usr/share/man/mann/mathfunc.n.gz 5,12 КиБ
- /usr/share/man/mann/mathop.n.gz 4,965 КиБ
- /usr/share/man/mann/memory.n.gz 4,048 КиБ
- /usr/share/man/mann/msgcat.n.gz 9,341 КиБ
- /usr/share/man/mann/my.n.gz 3,034 КиБ
- /usr/share/man/mann/namespace.n.gz 12,417 КиБ
- /usr/share/man/mann/next.n.gz 4,83 КиБ
- /usr/share/man/mann/nextto.n.gz 4,83 КиБ
- /usr/share/man/mann/oo_Slot.n.gz 7,08 КиБ
- /usr/share/man/mann/oo_class.n.gz 3,854 КиБ
- /usr/share/man/mann/oo_copy.n.gz 3,458 КиБ
- /usr/share/man/mann/oo_define.n.gz 7,08 КиБ
- /usr/share/man/mann/oo_objdefine.n.gz 7,08 КиБ
- /usr/share/man/mann/oo_object.n.gz 4,161 КиБ
- /usr/share/man/mann/open.n.gz 8,255 КиБ
- /usr/share/man/mann/package.n.gz 6,553 КиБ
- /usr/share/man/mann/packagens.n.gz 2,98 КиБ
- /usr/share/man/mann/parray.n.gz 6,881 КиБ
- /usr/share/man/mann/pid.n.gz 2,966 КиБ
- /usr/share/man/mann/pkgMkIndex.n.gz 5,937 КиБ
- /usr/share/man/mann/pkg_create.n.gz 2,98 КиБ
- /usr/share/man/mann/pkg_mkIndex.n.gz 5,937 КиБ
- /usr/share/man/mann/platform.n.gz 3,584 КиБ
- /usr/share/man/mann/platform_shell.n.gz 3,118 КиБ
- /usr/share/man/mann/proc.n.gz 4,162 КиБ
- /usr/share/man/mann/puts.n.gz 3,695 КиБ
- /usr/share/man/mann/pwd.n.gz 2,861 КиБ
- /usr/share/man/mann/re_syntax.n.gz 11,454 КиБ
- /usr/share/man/mann/read.n.gz 3,744 КиБ
- /usr/share/man/mann/refchan.n.gz 6,58 КиБ
- /usr/share/man/mann/regexp.n.gz 4,747 КиБ
- /usr/share/man/mann/registry.n.gz 4,924 КиБ
- /usr/share/man/mann/regsub.n.gz 4,539 КиБ
- /usr/share/man/mann/rename.n.gz 2,951 КиБ
- /usr/share/man/mann/return.n.gz 6,194 КиБ
- /usr/share/man/mann/safe.n.gz 7,386 КиБ
- /usr/share/man/mann/scan.n.gz 5,989 КиБ
- /usr/share/man/mann/scope.n.gz 3,359 КиБ
- /usr/share/man/mann/seek.n.gz 3,44 КиБ
- /usr/share/man/mann/self.n.gz 3,912 КиБ
- /usr/share/man/mann/set.n.gz 3,306 КиБ
- /usr/share/man/mann/socket.n.gz 5,683 КиБ
- /usr/share/man/mann/source.n.gz 3,239 КиБ
- /usr/share/man/mann/split.n.gz 3,436 КиБ
- /usr/share/man/mann/sqlite3.n.gz 327 Б
- /usr/share/man/mann/string.n.gz 7,59 КиБ
- /usr/share/man/mann/subst.n.gz 3,844 КиБ
- /usr/share/man/mann/switch.n.gz 4,532 КиБ
- /usr/share/man/mann/tailcall.n.gz 3,126 КиБ
- /usr/share/man/mann/tcl_endOfWord.n.gz 6,881 КиБ
- /usr/share/man/mann/tcl_findLibrary.n.gz 6,881 КиБ
- /usr/share/man/mann/tcl_interactive.n.gz 9,47 КиБ
- /usr/share/man/mann/tcl_library.n.gz 9,47 КиБ
- /usr/share/man/mann/tcl_nonwordchars.n.gz 9,47 КиБ
- /usr/share/man/mann/tcl_patchLevel.n.gz 9,47 КиБ
- /usr/share/man/mann/tcl_pkgPath.n.gz 9,47 КиБ
- /usr/share/man/mann/tcl_platform.n.gz 9,47 КиБ
- /usr/share/man/mann/tcl_precision.n.gz 9,47 КиБ
- /usr/share/man/mann/tcl_prefix.n.gz 3,526 КиБ
- /usr/share/man/mann/tcl_rcFileName.n.gz 9,47 КиБ
- /usr/share/man/mann/tcl_startOfNextWord.n.gz 6,881 КиБ
- /usr/share/man/mann/tcl_startOfPreviousWord.n.gz 6,881 КиБ
- /usr/share/man/mann/tcl_traceCompile.n.gz 9,47 КиБ
- /usr/share/man/mann/tcl_traceExec.n.gz 9,47 КиБ
- /usr/share/man/mann/tcl_version.n.gz 9,47 КиБ
- /usr/share/man/mann/tcl_wordBreakAfter.n.gz 6,881 КиБ
- /usr/share/man/mann/tcl_wordBreakBefore.n.gz 6,881 КиБ
- /usr/share/man/mann/tcl_wordchars.n.gz 9,47 КиБ
- /usr/share/man/mann/tcltest.n.gz 15,235 КиБ
- /usr/share/man/mann/tdbc.n.gz 1,185 КиБ
- /usr/share/man/mann/tdbc_connection.n.gz 4,932 КиБ
- /usr/share/man/mann/tdbc_mapSqlState.n.gz 1,15 КиБ
- /usr/share/man/mann/tdbc_mysql.n.gz 2,599 КиБ
- /usr/share/man/mann/tdbc_odbc.n.gz 3,271 КиБ
- /usr/share/man/mann/tdbc_postgres.n.gz 2,4 КиБ
- /usr/share/man/mann/tdbc_resultset.n.gz 2,565 КиБ
- /usr/share/man/mann/tdbc_sqlite3.n.gz 1,825 КиБ
- /usr/share/man/mann/tdbc_statement.n.gz 3,1 КиБ
- /usr/share/man/mann/tdbc_tokenize.n.gz 1,244 КиБ
- /usr/share/man/mann/tell.n.gz 3,04 КиБ
- /usr/share/man/mann/thread.n.gz 9,677 КиБ
- /usr/share/man/mann/throw.n.gz 3,124 КиБ
- /usr/share/man/mann/time.n.gz 2,889 КиБ
- /usr/share/man/mann/timerate.n.gz 4,267 КиБ
- /usr/share/man/mann/tm.n.gz 6,185 КиБ
- /usr/share/man/mann/tpool.n.gz 5,704 КиБ
- /usr/share/man/mann/trace.n.gz 6,884 КиБ
- /usr/share/man/mann/transchan.n.gz 4,38 КиБ
- /usr/share/man/mann/try.n.gz 3,847 КиБ
- /usr/share/man/mann/tsv.n.gz 6,343 КиБ
- /usr/share/man/mann/ttrace.n.gz 5,146 КиБ
- /usr/share/man/mann/unknown.n.gz 3,896 КиБ
- /usr/share/man/mann/unload.n.gz 4,949 КиБ
- /usr/share/man/mann/unset.n.gz 3,271 КиБ
- /usr/share/man/mann/update.n.gz 3,354 КиБ
- /usr/share/man/mann/uplevel.n.gz 3,808 КиБ
- /usr/share/man/mann/upvar.n.gz 4,106 КиБ
- /usr/share/man/mann/variable.n.gz 3,46 КиБ
- /usr/share/man/mann/vwait.n.gz 4,803 КиБ
- /usr/share/man/mann/while.n.gz 3,26 КиБ
- /usr/share/man/mann/yield.n.gz 4,675 КиБ
- /usr/share/man/mann/yieldto.n.gz 4,675 КиБ
- /usr/share/man/mann/zlib.n.gz 6,764 КиБ
-
-
-
-
Документация (man-страницы)
Tcl_SetRecursionLimit(3) Tcl Library Procedures Tcl_SetRecursionLimit(3) ______________________________________________________________________________ NAME Tcl_SetRecursionLimit - установить максимальную допустимую глубину вложенности в интерпретаторе SYNOPSIS #include <tcl.h> int Tcl_SetRecursionLimit(interp, depth) ARGUMENTS Tcl_Interp *interp (in) Интерпретатор, для которого устанавливается лимит рекурсии. Должен быть больше нуля. int depth (in) Новый лимит для вложенных вызовов Tcl_Eval для interp. ______________________________________________________________________________ DESCRIPTION В любой данный момент Tcl enforces a limit on the number of recursive calls that may be active for Tcl_Eval and related procedures such as Tcl_GlobalEval. Любой вызов Tcl_Eval, превышающий эту глубину, прерывается с ошибкой. По умолчанию лимит рекурсии составляет 1000. Tcl_SetRecursionLimit может быть использован для изменения максимальной допустимой глубины вложенности для интерпретатора. Аргумент depth specifies a new limit for interp, and Tcl_SetRecursionLimit returns the old limit. Чтобы прочитать старый лимит без его изменения, вызовите Tcl_SetRecursionLimit с depth, равным 0. Tcl_SetRecursionLimit only sets the size of the Tcl call stack: it cannot by itself prevent stack overflows on the C stack being used by the application. If your machine has a limit on the size of the C stack, you may get stack overflows before reaching the limit set by Tcl_SetRecursionLimit. If this happens, see if there is a mechanism in your system for increasing the maximum size of the C stack. KEYWORDS глубина вложенности, рекурсия Tcl 7.0 Tcl_SetRecursionLimit(3)
Tcl_SetRecursionLimit(3) Tcl Library Procedures Tcl_SetRecursionLimit(3) ______________________________________________________________________________ NAME Tcl_SetRecursionLimit - set maximum allowable nesting depth in inter‐ preter SYNOPSIS #include <tcl.h> int Tcl_SetRecursionLimit(interp, depth) ARGUMENTS Tcl_Interp *interp (in) Interpreter whose recursion limit is to be set. Must be greater than zero. int depth (in) New limit for nested calls to Tcl_Eval for interp. ______________________________________________________________________________ DESCRIPTION At any given time Tcl enforces a limit on the number of recursive calls that may be active for Tcl_Eval and related procedures such as Tcl_GlobalEval. Any call to Tcl_Eval that exceeds this depth is aborted with an error. By default the recursion limit is 1000. Tcl_SetRecursionLimit may be used to change the maximum allowable nest‐ ing depth for an interpreter. The depth argument specifies a new limit for interp, and Tcl_SetRecursionLimit returns the old limit. To read out the old limit without modifying it, invoke Tcl_SetRecursionLimit with depth equal to 0. The Tcl_SetRecursionLimit only sets the size of the Tcl call stack: it cannot by itself prevent stack overflows on the C stack being used by the application. If your machine has a limit on the size of the C stack, you may get stack overflows before reaching the limit set by Tcl_SetRecursionLimit. If this happens, see if there is a mechanism in your system for increasing the maximum size of the C stack. KEYWORDS nesting depth, recursion Tcl 7.0 Tcl_SetRecursionLimit(3)
Tcl_Method(3) Функции библиотеки TclOO Tcl_Method(3) ______________________________________________________________________________ NAME Tcl_ClassSetConstructor, Tcl_ClassSetDestructor, Tcl_MethodDeclar‐ erClass, Tcl_MethodDeclarerObject, Tcl_MethodIsPublic, Tcl_MethodIs‐ Type, Tcl_MethodName, Tcl_NewInstanceMethod, Tcl_NewMethod, Tcl_Object‐ ContextInvokeNext, Tcl_ObjectContextIsFiltering, Tcl_ObjectCon‐ textMethod, Tcl_ObjectContextObject, Tcl_ObjectContextSkippedArgs - манипулировать методами и контекстами вызова методов SYNOPSIS #include <tclOO.h> Tcl_Method Tcl_NewMethod(interp, class, nameObj, isPublic, methodTypePtr, clientData) Tcl_Method Tcl_NewInstanceMethod(interp, object, nameObj, isPublic, methodTypePtr, clientData) Tcl_ClassSetConstructor(interp, class, method) Tcl_ClassSetDestructor(interp, class, method) Tcl_Class Tcl_MethodDeclarerClass(method) Tcl_Object Tcl_MethodDeclarerObject(method) Tcl_Obj * Tcl_MethodName(method) int Tcl_MethodIsPublic(method) int Tcl_MethodIsType(method, methodTypePtr, clientDataPtr) int Tcl_ObjectContextInvokeNext(interp, context, objc, objv, skip) int Tcl_ObjectContextIsFiltering(context) Tcl_Method Tcl_ObjectContextMethod(context) Tcl_Object Tcl_ObjectContextObject(context) int Tcl_ObjectContextSkippedArgs(context) ARGUMENTS Tcl_Interp *interp (in/out) Интерпретатор, содержащий объект или класс, в котором создается или обновляется метод. Tcl_Object object (in) Объект, в котором создается метод. Tcl_Class class (in) Класс, в котором создается метод. Tcl_Obj *nameObj (in) Имя метода для создания. Не должно быть NULL, если не создаются конструкторы или деструкторы. int isPublic (in) Флаг, указывающий видимость метода. Поддерживаемые значения: 0 для неэкспортируемого метода и 1 для экспортируемого метода. Tcl_MethodType *methodTypePtr (in) Описание типа метода для создания или для сравнения. ClientData clientData (in) Данные, передаваемые реализации метода без интерпретации. ClientData *clientDataPtr (out) Указатель на переменную, в которую записывается значение clientData, указанное при создании метода. Если NULL, значение не будет получено. Tcl_Method method (in) Ссылка на метод для запроса. Tcl_ObjectContext context (in) Ссылка на контекст вызова метода. Обратите внимание, что код клиента не должен сохранять ссылку на контекст. int objc (in) Количество аргументов для передачи реализации метода. Tcl_Obj *const *objv (in) Массив аргументов для передачи реализации метода. int skip (in) Количество аргументов, передаваемых реализации метода, которые не представляют "реальные" аргументы. ______________________________________________________________________________ DESCRIPTION Метод - это операция, выполняемая над объектом и связанная с ним. Каждый метод должен быть прикреплен либо к объекту, либо к классу; методы, прикрепленные к классу, ассоциированы со всеми экземплярами (прямыми и косвенными) этого класса. Для заданного метода сущность, объявившая его, может быть найдена с помощью Tcl_MethodDeclarerClass, которая возвращает класс, к которому прикреплен метод (или NULL, если метод не прикреплен к классу), и Tcl_MethodDeclarerObject, которая возвращает объект, к которому прикреплен метод (или NULL, если метод не прикреплен к объекту). Имя метода можно получить с помощью Tcl_MethodName, а то, экспортируется ли метод, - с помощью Tcl_MethodIsPublic. Тип метода также можно интроспектировать в ограниченной степени; функция Tcl_MethodIsType возвращает, является ли метод определенного типа, и присваивает per-method clientData переменной, на которую указывает clientDataPtr (если она не NULL), если тип совпадает. СОЗДАНИЕ МЕТОДОВ Методы создаются с помощью Tcl_NewMethod и Tcl_NewInstanceMethod, которые создают метод, прикрепленный к классу или объекту соответственно. В обоих случаях аргумент nameObj задает имя метода для создания, аргумент isPublic указывает, должен ли метод быть экспортирован изначально, аргумент methodTypePtr описывает реализацию метода (см. раздел ТИПЫ МЕТОДОВ ниже), а аргумент clientData предоставляет некоторые специфические для реализации данные, которые передаются реализации метода при его вызове. Если аргумент nameObj для Tcl_NewMethod равен NULL, создается неназванный метод, который используется для конструкторов и деструкторов. Конструкторы должны устанавливаться в свой класс с помощью функции Tcl_ClassSetConstructor, а деструкторы (которые не должны требовать никаких аргументов) должны устанавливаться в свой класс с помощью функции Tcl_ClassSetDestructor. Неназванные методы не должны использоваться для других целей, а именованные методы не должны использоваться в качестве конструкторов или деструкторов. Также обратите внимание, что NULL methodTypePtr используется для внутренней сигнализации и не должен использоваться в коде клиента. КОНТЕКСТЫ ВЫЗОВА МЕТОДОВ При вызове метода ссылка на контекст вызова метода передается в качестве одного из аргументов функции реализации. Этот контекст можно инспектировать для получения информации о вызывающем, но его не следует сохранять за пределами момента завершения вызова метода. Метод, который вызывается, можно получить из контекста с помощью Tcl_ObjectContextMethod, а объект, вызвавший метод, - с помощью Tcl_ObjectContextObject. Количество аргументов, которые нужно пропустить (например, имя объекта и имя метода в обычном вызове метода), читается с помощью Tcl_ObjectContextSkippedArgs, и контекст также может сообщить, работает ли он в качестве фильтра для другого метода через Tcl_ObjectContextIsFiltering. Во время выполнения метода реализация метода может выбрать вызов этапов цепочки вызова метода, следующих за текущей реализацией метода. Это (ядро команды next) выполняется с помощью Tcl_ObjectContextInvokeNext. Обратите внимание, что эта функция не манипулирует стеком вызовов, в отличие от команды next; если реализация метода добавила один или несколько дополнительных фреймов в стек в рамках своей реализации, она также несет ответственность за временное удаление этих фреймов из стека во время выполнения функции Tcl_ObjectContextInvokeNext. Обратите также внимание, что контекст вызова метода никогда не удаляется во время выполнения этой функции. ТИПЫ МЕТОДОВ Типы методов описываются указателем на структуру Tcl_MethodType, которая определяется как: typedef struct { int version; const char *name; Tcl_MethodCallProc *callProc; Tcl_MethodDeleteProc *deleteProc; Tcl_CloneProc *cloneProc; } Tcl_MethodType; Поле version позволяет для будущего расширения структуры и всегда должно быть объявлено равным TCL_OO_METHOD_VERSION_CURRENT. Поле name предоставляет удобочитаемое имя для типа и является значением, которое отображается через команды Tcl info class methodtype и info object methodtype. Поле callProc задает функцию, которая вызывается при вызове метода; оно никогда не должно быть NULL. Поле deleteProc задает функцию, которая используется для удаления конкретного метода и вызывается, когда метод заменяется или удаляется; если поле равно NULL, предполагается, что clientData метода не требует специальных действий для удаления. Поле cloneProc либо функция, которая используется для копирования clientData метода (в рамках Tcl_CopyObjectInstance), либо NULL, чтобы указать, что clientData может быть просто скопировано напрямую. ПОДПИСЬ ФУНКЦИИ TCL_METHODCALLPROC Функции, соответствующие этой подписи, вызываются при вызове метода. typedef int Tcl_MethodCallProc( ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext, int objc, Tcl_Obj *const *objv); Аргумент clientData для Tcl_MethodCallProc - это значение, которое было задано при создании метода, interp - место для выполнения скриптов и доступа к переменным, а также для размещения результата метода, а поля objc и objv дают объекты параметров метода. Контекст вызова метода можно обнаружить через аргумент objectContext, а возвращаемое значение из Tcl_MethodCallProc - любой код возврата Tcl (например, TCL_OK, TCL_ERROR). ПОДПИСЬ ФУНКЦИИ TCL_METHODDELETEPROC Функции, соответствующие этой подписи, используются при удалении метода, будь то через создание нового метода или из-за удаления объекта или класса. typedef void Tcl_MethodDeleteProc( ClientData clientData); Аргумент clientData для Tcl_MethodDeleteProc будет таким же, как значение, переданное аргументу clientData в Tcl_NewMethod или Tcl_NewInstanceMethod при создании метода. ПОДПИСЬ ФУНКЦИИ TCL_CLONEPROC Функции, соответствующие этой подписи, используются для копирования метода при копировании объекта или класса с помощью Tcl_CopyObjectInstance (или oo::copy). typedef int Tcl_CloneProc( Tcl_Interp *interp, ClientData oldClientData, ClientData *newClientDataPtr); Аргумент interp дает место для записи сообщения об ошибке, когда попытка клонирования объекта не удалась, в этом случае процедура клонирования также должна вернуть TCL_ERROR; в противном случае она должна вернуть TCL_OK. Поле oldClientData для Tcl_CloneProc дает значение из метода, из которого копируется, а поле newClientDataPtr будет указывать на переменную, в которую нужно записать значение для метода, в который копируется. SEE ALSO Class(3), oo::class(n), oo::define(n), oo::object(n) KEYWORDS constructor, method, object TclOO 0.1 Tcl_Method(3)
Tcl_Method(3) TclOO Library Functions Tcl_Method(3) ______________________________________________________________________________ NAME Tcl_ClassSetConstructor, Tcl_ClassSetDestructor, Tcl_MethodDeclar‐ erClass, Tcl_MethodDeclarerObject, Tcl_MethodIsPublic, Tcl_MethodIs‐ Type, Tcl_MethodName, Tcl_NewInstanceMethod, Tcl_NewMethod, Tcl_Object‐ ContextInvokeNext, Tcl_ObjectContextIsFiltering, Tcl_ObjectCon‐ textMethod, Tcl_ObjectContextObject, Tcl_ObjectContextSkippedArgs - ma‐ nipulate methods and method-call contexts SYNOPSIS #include <tclOO.h> Tcl_Method Tcl_NewMethod(interp, class, nameObj, isPublic, methodTypePtr, clientData) Tcl_Method Tcl_NewInstanceMethod(interp, object, nameObj, isPublic, methodTypePtr, clientData) Tcl_ClassSetConstructor(interp, class, method) Tcl_ClassSetDestructor(interp, class, method) Tcl_Class Tcl_MethodDeclarerClass(method) Tcl_Object Tcl_MethodDeclarerObject(method) Tcl_Obj * Tcl_MethodName(method) int Tcl_MethodIsPublic(method) int Tcl_MethodIsType(method, methodTypePtr, clientDataPtr) int Tcl_ObjectContextInvokeNext(interp, context, objc, objv, skip) int Tcl_ObjectContextIsFiltering(context) Tcl_Method Tcl_ObjectContextMethod(context) Tcl_Object Tcl_ObjectContextObject(context) int Tcl_ObjectContextSkippedArgs(context) ARGUMENTS Tcl_Interp *interp (in/out) The interpreter holding the object or class to create or update a method in. Tcl_Object object (in) The object to create the method in. Tcl_Class class (in) The class to create the method in. Tcl_Obj *nameObj (in) The name of the method to create. Should not be NULL unless creating constructors or destructors. int isPublic (in) A flag saying what the visibility of the method is. The only sup‐ ported public values of this flag are 0 for a non-exported method, and 1 for an exported method. Tcl_MethodType *methodTypePtr (in) A description of the type of the method to create, or the type of method to compare against. ClientData clientData (in) A piece of data that is passed to the implementation of the method without interpretation. ClientData *clientDataPtr (out) A pointer to a variable in which to write the clientData value supplied when the method was created. If NULL, the clientData value will not be retrieved. Tcl_Method method (in) A reference to a method to query. Tcl_ObjectContext context (in) A reference to a method-call con‐ text. Note that client code must not retain a reference to a con‐ text. int objc (in) The number of arguments to pass to the method implementation. Tcl_Obj *const *objv (in) An array of arguments to pass to the method implementation. int skip (in) The number of arguments passed to the method implementation that do not represent "real" arguments. ______________________________________________________________________________ DESCRIPTION A method is an operation carried out on an object that is associated with the object. Every method must be attached to either an object or a class; methods attached to a class are associated with all instances (direct and indirect) of that class. Given a method, the entity that declared it can be found using Tcl_MethodDeclarerClass which returns the class that the method is at‐ tached to (or NULL if the method is not attached to any class) and Tcl_MethodDeclarerObject which returns the object that the method is attached to (or NULL if the method is not attached to an object). The name of the method can be retrieved with Tcl_MethodName and whether the method is exported is retrieved with Tcl_MethodIsPublic. The type of the method can also be introspected upon to a limited degree; the func‐ tion Tcl_MethodIsType returns whether a method is of a particular type, assigning the per-method clientData to the variable pointed to by clientDataPtr if (that is non-NULL) if the type is matched. METHOD CREATION Methods are created by Tcl_NewMethod and Tcl_NewInstanceMethod, which create a method attached to a class or an object respectively. In both cases, the nameObj argument gives the name of the method to create, the isPublic argument states whether the method should be exported ini‐ tially, the methodTypePtr argument describes the implementation of the method (see the METHOD TYPES section below) and the clientData argument gives some implementation-specific data that is passed on to the imple‐ mentation of the method when it is called. When the nameObj argument to Tcl_NewMethod is NULL, an unnamed method is created, which is used for constructors and destructors. Construc‐ tors should be installed into their class using the Tcl_ClassSetCon‐ structor function, and destructors (which must not require any argu‐ ments) should be installed into their class using the Tcl_ClassSetDe‐ structor function. Unnamed methods should not be used for any other purpose, and named methods should not be used as either constructors or destructors. Also note that a NULL methodTypePtr is used to provide in‐ ternal signaling, and should not be used in client code. METHOD CALL CONTEXTS When a method is called, a method-call context reference is passed in as one of the arguments to the implementation function. This context can be inspected to provide information about the caller, but should not be retained beyond the moment when the method call terminates. The method that is being called can be retrieved from the context by using Tcl_ObjectContextMethod, and the object that caused the method to be invoked can be retrieved with Tcl_ObjectContextObject. The number of arguments that are to be skipped (e.g. the object name and method name in a normal method call) is read with Tcl_ObjectContextSkippedArgs, and the context can also report whether it is working as a filter for an‐ other method through Tcl_ObjectContextIsFiltering. During the execution of a method, the method implementation may choose to invoke the stages of the method call chain that come after the cur‐ rent method implementation. This (the core of the next command) is done using Tcl_ObjectContextInvokeNext. Note that this function does not ma‐ nipulate the call-frame stack, unlike the next command; if the method implementation has pushed one or more extra frames on the stack as part of its implementation, it is also responsible for temporarily popping those frames from the stack while the Tcl_ObjectContextInvokeNext func‐ tion is executing. Note also that the method-call context is never deleted during the execution of this function. METHOD TYPES The types of methods are described by a pointer to a Tcl_MethodType structure, which is defined as: typedef struct { int version; const char *name; Tcl_MethodCallProc *callProc; Tcl_MethodDeleteProc *deleteProc; Tcl_CloneProc *cloneProc; } Tcl_MethodType; The version field allows for future expansion of the structure, and should always be declared equal to TCL_OO_METHOD_VERSION_CURRENT. The name field provides a human-readable name for the type, and is the value that is exposed via the info class methodtype and info object methodtype Tcl commands. The callProc field gives a function that is called when the method is invoked; it must never be NULL. The deleteProc field gives a function that is used to delete a particu‐ lar method, and is called when the method is replaced or removed; if the field is NULL, it is assumed that the method's clientData needs no special action to delete. The cloneProc field is either a function that is used to copy a method's clientData (as part of Tcl_CopyObjectInstance) or NULL to in‐ dicate that the clientData can just be copied directly. TCL_METHODCALLPROC FUNCTION SIGNATURE Functions matching this signature are called when the method is in‐ voked. typedef int Tcl_MethodCallProc( ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext, int objc, Tcl_Obj *const *objv); The clientData argument to a Tcl_MethodCallProc is the value that was given when the method was created, the interp is a place in which to execute scripts and access variables as well as being where to put the result of the method, and the objc and objv fields give the parameter objects to the method. The calling context of the method can be discov‐ ered through the objectContext argument, and the return value from a Tcl_MethodCallProc is any Tcl return code (e.g. TCL_OK, TCL_ERROR). TCL_METHODDELETEPROC FUNCTION SIGNATURE Functions matching this signature are used when a method is deleted, whether through a new method being created or because the object or class is deleted. typedef void Tcl_MethodDeleteProc( ClientData clientData); The clientData argument to a Tcl_MethodDeleteProc will be the same as the value passed to the clientData argument to Tcl_NewMethod or Tcl_NewInstanceMethod when the method was created. TCL_CLONEPROC FUNCTION SIGNATURE Functions matching this signature are used to copy a method when the object or class is copied using Tcl_CopyObjectInstance (or oo::copy). typedef int Tcl_CloneProc( Tcl_Interp *interp, ClientData oldClientData, ClientData *newClientDataPtr); The interp argument gives a place to write an error message when the attempt to clone the object is to fail, in which case the clone proce‐ dure must also return TCL_ERROR; it should return TCL_OK otherwise. The oldClientData field to a Tcl_CloneProc gives the value from the method being copied from, and the newClientDataPtr field will point to a variable in which to write the value for the method being copied to. SEE ALSO Class(3), oo::class(n), oo::define(n), oo::object(n) KEYWORDS constructor, method, object TclOO 0.1 Tcl_Method(3)
Tcl_Namespace(3) Процедуры библиотеки Tcl Tcl_Namespace(3) ______________________________________________________________________________ NAME Tcl_AppendExportList, Tcl_CreateNamespace, Tcl_DeleteNamespace, Tcl_Ex‐ port, Tcl_FindCommand, Tcl_FindNamespace, Tcl_ForgetImport, Tcl_GetCur‐ rentNamespace, Tcl_GetGlobalNamespace, Tcl_GetNamespaceUnknownHandler, Tcl_Import, Tcl_SetNamespaceUnknownHandler - управление пространствами имён SYNOPSIS #include <tcl.h> Tcl_Namespace * Tcl_CreateNamespace(interp, name, clientData, deleteProc) Tcl_DeleteNamespace(nsPtr) int Tcl_AppendExportList(interp, nsPtr, objPtr) int Tcl_Export(interp, nsPtr, pattern, resetListFirst) int Tcl_Import(interp, nsPtr, pattern, allowOverwrite) int Tcl_ForgetImport(interp, nsPtr, pattern) Tcl_Namespace * Tcl_GetCurrentNamespace(interp) Tcl_Namespace * Tcl_GetGlobalNamespace(interp) Tcl_Namespace * Tcl_FindNamespace(interp, name, contextNsPtr, flags) Tcl_Command Tcl_FindCommand(interp, name, contextNsPtr, flags) Tcl_Obj * Tcl_GetNamespaceUnknownHandler(interp, nsPtr) int Tcl_SetNamespaceUnknownHandler(interp, nsPtr, handlerPtr) ARGUMENTS Tcl_Interp *interp (in/out) Интерпретатор, в котором существует пространство имён и где выполняются поиски имён. Также здесь записываются сообщения об ошибках. const char *name (in) Имя пространства имён или команды, которая создаётся или доступна. ClientData clientData (in) Указатель на контекст, предоставленный создателем пространства имён. Tcl не интерпретирует его. Tcl_NamespaceDeleteProc *deleteProc (in) Указатель на функцию, которую следует вызвать при удалении пространства имён, или NULL, если такого вызова не требуется. Tcl_Namespace *nsPtr (in) Пространство имён, которое нужно манипулировать, или NULL (для других, кроме Tcl_DeleteNamespace), чтобы манипулировать текущим пространством имён. Tcl_Obj *objPtr (out) Ссылка на неподелённое значение, в которое функция запишет свой вывод. const char *pattern (in) Шаблон в стиле glob (см. Tcl_StringMatch), описывающий команды, которые нужно импортировать или экспортировать. int resetListFirst (in) Флаг, указывающий, нужно ли сбросить список шаблонов экспорта перед добавлением текущего шаблона. int allowOverwrite (in) Флаг, указывающий, могут ли новые команды, созданные этим действием импорта, перезаписывать существующие команды. Tcl_Namespace *contextNsPtr (in) Место в иерархии пространств имён, относительно которого должен проводиться поиск пространства имён или команды, если поисковый термин не начинается с глобального пространства имён. NULL указывает на текущее пространство имён. int flags (in) Комбинация бит, объединённых через OR, управляющих тем, как выполняется поиск. Поддерживаются следующие флаги: TCL_GLOBAL_ONLY (указывает, что поиск всегда должен проводиться относительно глобального пространства имён), TCL_NAMESPACE_ONLY (только для Tcl_FindCommand; указывает, что поиск всегда должен проводиться относительно контекстного пространства имён) и TCL_LEAVE_ERR_MSG (указывает, что сообщение об ошибке должно остаться в интерпретаторе, если поиск не удался). Tcl_Obj *handlerPtr (in) Фрагмент скрипта, который устанавливается в качестве обработчика неизвестных команд для пространства имён, или NULL, чтобы сбросить обработчик на значение по умолчанию. ______________________________________________________________________________ DESCRIPTION Пространства имён являются иерархическими контекстами именования, которые могут содержать команды и переменные. Они также поддерживают список шаблонов, описывающих, какие команды экспортируются, и могут импортировать команды, экспортированные другими пространствами имён. Пространства имён также можно манипулировать с помощью команды Tcl namespace. Структура Tcl_Namespace инкапсулирует пространство имён и гарантированно содержит следующие поля: name (локальное имя пространства имён без разделителей пространств имён, пустая строка обозначает глобальное пространство имён), fullName (полностью указанное имя пространства имён), clientData, deleteProc (значения, указанные в вызове Tcl_CreateNamespace) и parentPtr (указатель на содержащее пространство имён или NULL для глобального пространства имён). Tcl_CreateNamespace создаёт новое пространство имён. Функция deleteProc будет иметь следующий сигнатуру типа: typedef void Tcl_NamespaceDeleteProc( ClientData clientData); Tcl_DeleteNamespace удаляет пространство имён, вызывая deleteProc, определённую для этого пространства имён (если она существует). Tcl_AppendExportList получает шаблоны экспорта для пространства имён и добавляет их (как элементы списка) в objPtr. Tcl_Export устанавливает и добавляет шаблоны экспорта для пространства имён. Шаблоны добавляются, если флаг resetListFirst не установлен. Tcl_Import импортирует команды, соответствующие шаблону, в пространство имён. Обратите внимание, что шаблон должен включать имя пространства имён, из которого происходит импорт. Эта функция возвращает TCL_ERROR, если попытка импортировать команду поверх существующей команды, если флаг allowOverwrite не установлен. Tcl_ForgetImport удаляет импорты, соответствующие шаблону. Tcl_GetCurrentNamespace возвращает текущее пространство имён для интерпретатора. Tcl_GetGlobalNamespace возвращает глобальное пространство имён для интерпретатора. Tcl_FindNamespace ищет пространство имён с именем name в контексте пространства имён contextNsPtr. Если пространство имён не найдено, возвращается NULL. Tcl_FindCommand ищет команду с именем name в контексте пространства имён contextNsPtr. Если команда не найдена, возвращается NULL. Tcl_GetNamespaceUnknownHandler возвращает обработчик неизвестных команд для пространства имён или NULL, если он не установлен. Tcl_SetNamespaceUnknownHandler устанавливает обработчик неизвестных команд для пространства имён. Если handlerPtr равен NULL, то обработчик сбрасывается на значение по умолчанию. SEE ALSO Tcl_CreateCommand(3), Tcl_ListObjAppendList(3), Tcl_SetVar(3) KEYWORDS namespace, command Tcl 8.5 Tcl_Namespace(3)
Tcl_Namespace(3) Tcl Library Procedures Tcl_Namespace(3) ______________________________________________________________________________ NAME Tcl_AppendExportList, Tcl_CreateNamespace, Tcl_DeleteNamespace, Tcl_Ex‐ port, Tcl_FindCommand, Tcl_FindNamespace, Tcl_ForgetImport, Tcl_GetCur‐ rentNamespace, Tcl_GetGlobalNamespace, Tcl_GetNamespaceUnknownHandler, Tcl_Import, Tcl_SetNamespaceUnknownHandler - manipulate namespaces SYNOPSIS #include <tcl.h> Tcl_Namespace * Tcl_CreateNamespace(interp, name, clientData, deleteProc) Tcl_DeleteNamespace(nsPtr) int Tcl_AppendExportList(interp, nsPtr, objPtr) int Tcl_Export(interp, nsPtr, pattern, resetListFirst) int Tcl_Import(interp, nsPtr, pattern, allowOverwrite) int Tcl_ForgetImport(interp, nsPtr, pattern) Tcl_Namespace * Tcl_GetCurrentNamespace(interp) Tcl_Namespace * Tcl_GetGlobalNamespace(interp) Tcl_Namespace * Tcl_FindNamespace(interp, name, contextNsPtr, flags) Tcl_Command Tcl_FindCommand(interp, name, contextNsPtr, flags) Tcl_Obj * Tcl_GetNamespaceUnknownHandler(interp, nsPtr) int Tcl_SetNamespaceUnknownHandler(interp, nsPtr, handlerPtr) ARGUMENTS Tcl_Interp *interp (in/out) The interpreter in which the name‐ space exists and where name lookups are performed. Also where error result messages are written. const char *name (in) The name of the namespace or com‐ mand to be created or accessed. ClientData clientData (in) A context pointer by the creator of the namespace. Not interpreted by Tcl at all. Tcl_NamespaceDeleteProc *deleteProc (in) A pointer to func‐ tion to call when the namespace is deleted, or NULL if no such call‐ back is to be per‐ formed. Tcl_Namespace *nsPtr (in) The namespace to be manipulated, or NULL (for other than Tcl_Delete‐ Namespace) to ma‐ nipulate the cur‐ rent namespace. Tcl_Obj *objPtr (out) A reference to an unshared value to which the function output will be written. const char *pattern (in) The glob-style pattern (see Tcl_StringMatch) that describes the commands to be im‐ ported or ex‐ ported. int resetListFirst (in) Whether the list of export patterns should be reset before adding the current pattern to it. int allowOverwrite (in) Whether new com‐ mands created by this import action can overwrite ex‐ isting commands. Tcl_Namespace *contextNsPtr (in) The location in the namespace hi‐ erarchy where the search for a name‐ space or command should be con‐ ducted relative to when the search term is not rooted at the global namespace. NULL indicates the cur‐ rent namespace. int flags (in) OR-ed combination of bits control‐ ling how the search is to be performed. The following flags are supported: TCL_GLOBAL_ONLY (indicates that the search is al‐ ways to be con‐ ducted relative to the global name‐ space), TCL_NAME‐ SPACE_ONLY (just for Tcl_FindCom‐ mand; indicates that the search is always to be con‐ ducted relative to the context name‐ space), and TCL_LEAVE_ERR_MSG (indicates that an error message should be left in the interpreter if the search fails.) Tcl_Obj *handlerPtr (in) A script fragment to be installed as the unknown com‐ mand handler for the namespace, or NULL to reset the handler to its de‐ fault. ______________________________________________________________________________ DESCRIPTION Namespaces are hierarchic naming contexts that can contain commands and variables. They also maintain a list of patterns that describes what commands are exported, and can import commands that have been exported by other namespaces. Namespaces can also be manipulated through the Tcl command namespace. The Tcl_Namespace structure encapsulates a namespace, and is guaranteed to have the following fields in it: name (the local name of the name‐ space, with no namespace separator characters in it, with empty denot‐ ing the global namespace), fullName (the fully specified name of the namespace), clientData, deleteProc (the values specified in the call to Tcl_CreateNamespace), and parentPtr (a pointer to the containing name‐ space, or NULL for the global namespace.) Tcl_CreateNamespace creates a new namespace. The deleteProc will have the following type signature: typedef void Tcl_NamespaceDeleteProc( ClientData clientData); Tcl_DeleteNamespace deletes a namespace, calling the deleteProc defined for the namespace (if any). Tcl_AppendExportList retrieves the export patterns for a namespace given namespace and appends them (as list items) to objPtr. Tcl_Export sets and appends to the export patterns for a namespace. Patterns are appended unless the resetListFirst flag is true. Tcl_Import imports commands matching a pattern into a namespace. Note that the pattern must include the name of the namespace to import from. This function returns TCL_ERROR if an attempt to import a command over an existing command is made, unless the allowOverwrite flag has been set. Tcl_ForgetImport removes imports matching a pattern. Tcl_GetCurrentNamespace returns the current namespace for an inter‐ preter. Tcl_GetGlobalNamespace returns the global namespace for an interpreter. Tcl_FindNamespace searches for a namespace named name within the con‐ text of the namespace contextNsPtr. If the namespace cannot be found, NULL is returned. Tcl_FindCommand searches for a command named name within the context of the namespace contextNsPtr. If the command cannot be found, NULL is returned. Tcl_GetNamespaceUnknownHandler returns the unknown command handler for the namespace, or NULL if none is set. Tcl_SetNamespaceUnknownHandler sets the unknown command handler for the namespace. If handlerPtr is NULL, then the handler is reset to its de‐ fault. SEE ALSO Tcl_CreateCommand(3), Tcl_ListObjAppendList(3), Tcl_SetVar(3) KEYWORDS namespace, command Tcl 8.5 Tcl_Namespace(3)
Tcl_RegExpMatch(3) Процедуры библиотеки Tcl Tcl_RegExpMatch(3) ______________________________________________________________________________ NAME Tcl_RegExpMatch, Tcl_RegExpCompile, Tcl_RegExpExec, Tcl_RegExpRange, Tcl_GetRegExpFromObj, Tcl_RegExpMatchObj, Tcl_RegExpExecObj, Tcl_Reg‐ ExpGetInfo - Сопоставление шаблонов с регулярными выражениями SYNOPSIS #include <tcl.h> int Tcl_RegExpMatchObj(interp, textObj, patObj) int Tcl_RegExpMatch(interp, text, pattern) Tcl_RegExp Tcl_RegExpCompile(interp, pattern) int Tcl_RegExpExec(interp, regexp, text, start) void Tcl_RegExpRange(regexp, index, startPtr, endPtr) Tcl_RegExp Tcl_GetRegExpFromObj(interp, patObj, cflags) int Tcl_RegExpExecObj(interp, regexp, textObj, offset, nmatches, eflags) void Tcl_RegExpGetInfo(regexp, infoPtr) ARGUMENTS Tcl_Interp *interp (in) Интерпретатор Tcl для отчета об ошибках. Интерпретатор может быть NULL, если отчет об ошибках не требуется. Tcl_Obj *textObj (in/out) Ссылка на значение, из которого извлекается текст для поиска. Внутреннее представление значения может быть преобразовано в форму, подходящую для эффективного поиска. Tcl_Obj *patObj (in/out) Ссылка на значение, из которого извлекается регулярное выражение. Скомпилированное регулярное выражение кэшируется в значении. const char *text (in) Текст для поиска совпадения с регулярным выражением. const char *pattern (in) Строка в форме шаблона регулярного выражения. Tcl_RegExp regexp (in) Скомпилированное регулярное выражение. Должно быть возвращено ранее функцией Tcl_GetRegExpFromObj или Tcl_RegExpCompile. const char *start (in) Если text является частью другой строки, этот аргумент указывает на начало более большой строки. Если он не совпадает с text, то совпадения "^" не будут разрешены. int index (in) Указывает, какой диапазон требуется: 0 означает диапазон всего совпадения, 1 или больше означает диапазон, соответствующий скобочной подвыражению. const char **startPtr (out) Здесь хранится адрес первого символа в диапазоне, или NULL, если такого диапазона нет. const char **endPtr (out) Здесь хранится адрес символа сразу после последнего в диапазоне, или NULL, если такого диапазона нет. int cflags (in) Комбинация флагов компиляции, объединенных через OR: TCL_REG_ADVANCED, TCL_REG_EXTENDED, TCL_REG_BASIC, TCL_REG_EXPANDED, TCL_REG_QUOTE, TCL_REG_NOCASE, TCL_REG_NEWLINE, TCL_REG_NLSTOP, TCL_REG_NLANCH, TCL_REG_NOSUB и TCL_REG_CANMATCH. См. ниже для дополнительной информации. int offset (in) Смещение символа в тексте, с которого должно начаться сопоставление. Значение смещения не влияет на совпадения "^". Это поведение управляется флагами eflags. int nmatches (in) Количество подвыражений, совпадения которых следует запомнить для последующего использования. Если значение равно 0, то информация о совпадениях подвыражений не будет вычислена. Если значение равно -1, то все совпадения подвыражений будут запомнены. Любое другое значение будет интерпретировано как максимальное количество подвыражений для запоминания. int eflags (in) Комбинация флагов выполнения, объединенных через OR: TCL_REG_NOTBOL и TCL_REG_NOTEOL. См. ниже для дополнительной информации. Tcl_RegExpInfo *infoPtr (out) Адрес места, где Tcl_RegExpGetInfo должно хранить информацию о предыдущем совпадении. ______________________________________________________________________________ DESCRIPTION Tcl_RegExpMatch определяет, соответствует ли аргумент pattern выражению regexp, где regexp интерпретируется как регулярное выражение по правилам, описанным в справочной странице re_syntax. Если совпадение найдено, Tcl_RegExpMatch возвращает 1. Если совпадение не найдено, Tcl_RegExpMatch возвращает 0. Если во время процесса сопоставления возникает ошибка (например, pattern не является допустимым регулярным выражением), Tcl_RegExpMatch возвращает -1 и оставляет сообщение об ошибке в результате интерпретатора. Tcl_RegExpMatchObj похож на Tcl_RegExpMatch, за исключением того, что работает с значениями Tcl textObj и patObj вместо строк UTF. Tcl_RegExpMatchObj обычно более эффективен, чем Tcl_RegExpMatch, поэтому это предпочтительный интерфейс. Tcl_RegExpCompile, Tcl_RegExpExec и Tcl_RegExpRange предоставляют низкоуровневый доступ к сопоставителю шаблонов регулярных выражений. Tcl_RegExpCompile компилирует строку регулярного выражения во внутреннюю форму для эффективного сопоставления шаблонов. Возвращаемое значение является токеном для этой скомпилированной формы, который можно использовать в последующих вызовах Tcl_RegExpExec или Tcl_RegExpRange. Если при компиляции регулярного выражения возникает ошибка, Tcl_RegExpCompile возвращает NULL и оставляет сообщение об ошибке в результате интерпретатора. Примечание: возвращаемое значение от Tcl_RegExpCompile допустимо только до следующего вызова Tcl_RegExpCompile; его небезопасно сохранять на длительное время. Tcl_RegExpExec выполняет сопоставитель шаблонов регулярных выражений. Он возвращает 1, если text содержит диапазон символов, соответствующий regexp, 0, если совпадение не найдено, и -1, если возникает ошибка. В случае ошибки Tcl_RegExpExec оставляет сообщение об ошибке в результате интерпретатора. При поиске строки на несколько совпадений шаблона важно различать начало исходной строки и начало текущего поиска. Например, при поиске второго совпадения аргумент text может указывать на символ сразу после первого совпадения; однако для сопоставителя шаблона важно знать, что это не начало всей строки, чтобы не разрешать совпадения атомов "^". Аргумент start предоставляет эту информацию, указывая на начало общей строки, содержащей text. Start будет меньше или равен text; если он меньше text, то совпадения "^" не будут разрешены. Tcl_RegExpRange можно вызвать после возврата Tcl_RegExpExec; он предоставляет подробную информацию о том, какие диапазоны строки соответствуют каким частям шаблона. Tcl_RegExpRange возвращает пару указателей в *startPtr и *endPtr, которые идентифицируют диапазон символов в исходной строке для последнего вызова Tcl_RegExpExec. Index указывает, какой из нескольких диапазонов требуется: если index равно 0, возвращается информация об общем диапазоне символов, соответствующих всему шаблону; в противном случае возвращается информация о диапазоне символов, соответствующем index'ому скобочному подвыражению в шаблоне. Если диапазон, соответствующий index, отсутствует, то в *startPtr и *endPtr хранится NULL. Tcl_GetRegExpFromObj, Tcl_RegExpExecObj и Tcl_RegExpGetInfo являются интерфейсами для значений, которые предоставляют наиболее прямой контроль над библиотекой регулярных выражений Henry Spencer. Для пользователей, которым нужно напрямую изменять опции компиляции и выполнения, рекомендуется использовать эти интерфейсы вместо вызова внутренних функций regexp. Эти интерфейсы обрабатывают детали перевода UTF в Unicode, а также обеспечивают лучшую производительность за счет кэширования в значениях шаблона и строки. Tcl_GetRegExpFromObj пытается вернуть скомпилированное регулярное выражение из patObj. Если значение не содержит скомпилированного регулярного выражения, оно попытается создать его из строки в значении и присвоить его внутреннему представлению patObj. Возвращаемое значение этого функции имеет тип Tcl_RegExp. Возвращаемое значение является токеном для этой скомпилированной формы, который можно использовать в последующих вызовах Tcl_RegExpExecObj или Tcl_RegExpGetInfo. Если при компиляции регулярного выражения возникает ошибка, Tcl_GetRegExpFromObj возвращает NULL и оставляет сообщение об ошибке в результате интерпретатора. Токен регулярного выражения можно использовать, пока внутреннее представление patObj относится к скомпилированной форме. Аргумент cflags является побитовым OR из нуля или более из следующих флагов, которые управляют компиляцией patObj: TCL_REG_ADVANCED Компилировать расширенные регулярные выражения ("ARE"). Этот режим соответствует нормальному синтаксису регулярных выражений, принятым командами Tcl regexp и regsub. TCL_REG_EXTENDED Компилировать расширенные регулярные выражения ("ERE"). Этот режим соответствует синтаксису регулярных выражений, recognized версиями Tcl 8.0 и ранее. TCL_REG_BASIC Компилировать базовые регулярные выражения ("BRE"). Этот режим соответствует синтаксису регулярных выражений, recognized общими Unix-утилитами, такими как sed и grep. Это значение по умолчанию, если флаги не указаны. TCL_REG_EXPANDED Компилировать регулярное выражение (базовое, расширенное или расширенное) с использованием расширенного синтаксиса, который позволяет комментарии и пробелы. Этот режим игнорирует неэкранированные пробелы, не входящие в скобочные выражения, и комментарии от # до конца строки. TCL_REG_QUOTE Компилировать буквальную строку, где все символы трактуются как обычные. TCL_REG_NOCASE Компилировать для сопоставления, игнорирующего различия регистра. TCL_REG_NEWLINE Компилировать для сопоставления, чувствительного к новой строке. По умолчанию, новая строка является обычным символом без специального значения в регулярных выражениях или строках. С этим флагом скобочные выражения "[^" и символ "." никогда не совпадают с новой строкой, "^" совпадает с пустой строкой после любой новой строки, помимо своей нормальной функции, а "$" совпадает с пустой строкой перед любой новой строкой, помимо своей нормальной функции. TCL_REG_NEWLINE является побитовым OR флагов TCL_REG_NLSTOP и TCL_REG_NLANCH. TCL_REG_NLSTOP Компилировать для частичного сопоставления, чувствительного к новой строке, где поведение скобочных выражений "[^" и символа "." затрагивается, но не поведение "^" и "$". В этом режиме скобочные выражения "[^" и символ "." никогда не совпадают с новой строкой. TCL_REG_NLANCH Компилировать для обратного частичного сопоставления, чувствительного к новой строке, где поведение "^" и "$" (якоря) затрагивается, но не поведение скобочных выражений "[^" и символа ".". В этом режиме "^" совпадает с пустой строкой после любой новой строки, помимо своей нормальной функции, а "$" совпадает с пустой строкой перед любой новой строкой, помимо своей нормальной функции. TCL_REG_NOSUB Компилировать для сопоставления, которое сообщает только об успехе или неудаче, а не о том, что было совпадено. Это сокращает накладные расходы на компиляцию и может улучшить производительность. Последующие вызовы Tcl_RegExpGetInfo или Tcl_RegExpRange не будут сообщать информацию о совпадениях. TCL_REG_CANMATCH Компилировать для сопоставления, которое сообщает о возможности завершить частичное совпадение при добавлении больше текста (см. ниже). Можно указать только один из TCL_REG_EXTENDED, TCL_REG_ADVANCED, TCL_REG_BASIC или TCL_REG_QUOTE. Tcl_RegExpExecObj выполняет сопоставитель шаблонов регулярных выражений. Он возвращает 1, если objPtr содержит диапазон символов, соответствующий regexp, 0, если совпадение не найдено, и -1, если возникает ошибка. В случае ошибки Tcl_RegExpExecObj оставляет сообщение об ошибке в результате интерпретатора. Значение nmatches указывает сопоставителю, сколько подвыражений представляют интерес. Если nmatches равно 0, то информация о совпадениях подвыражений не записывается, что может позволить сопоставителю выполнить различные оптимизации. Если значение равно -1, то все подвыражения в шаблоне будут запомнены. Если значение является положительным целым числом, то только это количество подвыражений будет запомнено. Сопоставление начинается с указанного индекса символа Unicode, заданного offset. В отличие от Tcl_RegExpExec, поведение якорей не затрагивается значением offset. Вместо этого поведение якорей явно управляется аргументом eflags, который является побитовым OR из нуля или более из следующих флагов: TCL_REG_NOTBOL Начальный символ не будет рассматриваться как начало строки или начало строки, поэтому "^" не будет совпадать там. Обратите внимание, что этот флаг не влияет на то, как совпадает "\A". TCL_REG_NOTEOL Последний символ в строке не будет рассматриваться как конец строки или конец строки, поэтому "$" не будет совпадать там. Обратите внимание, что этот флаг не влияет на то, как совпадает "\Z". Tcl_RegExpGetInfo извлекает информацию о последнем совпадении, выполненном с данным регулярным выражением regexp. Аргумент infoPtr содержит указатель на структуру, определяемую следующим образом: typedef struct Tcl_RegExpInfo { int nsubs; Tcl_RegExpIndices *matches; long extendStart; } Tcl_RegExpInfo; Поле nsubs содержит количество скобочных подвыражений в регулярном выражении. Если использовался TCL_REG_NOSUB, то это значение будет равно нулю. Поле matches указывает на массив из nsubs+1 значений, которые указывают границы каждого совпадения подвыражения. Первый элемент в массиве относится к диапазону, совпавшему с полным регулярным выражением, а последующие элементы относятся к скобочным подвыражениям в порядке их появления в шаблоне. Каждый элемент является структурой, определяемой следующим образом: typedef struct Tcl_RegExpIndices { long start; long end; } Tcl_RegExpIndices; Значения start и end являются индексами символов Unicode относительно расположения offset в objPtr, где началось сопоставление. Индекс start идентифицирует первый символ совпадения подвыражения. Индекс end идентифицирует первый символ после совпадения подвыражения. Если подвыражение совпало с пустой строкой, то start и end будут равны. Если подвыражение не участвовало в совпадении, то start и end будут установлены в -1. Поле extendStart в Tcl_RegExpInfo устанавливается только если использовался флаг TCL_REG_CANMATCH. Оно указывает на первый символ в строке, где может произойти совпадение. Если совпадение найдено, это будет то же, что и начало текущего совпадения. Если совпадение не найдено, то оно указывает на earliest точку, где может произойти совпадение, если к строке добавить дополнительный текст. Если совпадение невозможно даже с дополнительным текстом, это поле будет установлено в -1. SEE ALSO re_syntax(n) KEYWORDS match, pattern, regular expression, string, subexpression, Tcl_RegEx‐ pIndices, Tcl_RegExpInfo Tcl 8.1 Tcl_RegExpMatch(3)
Tcl_RegExpMatch(3) Tcl Library Procedures Tcl_RegExpMatch(3) ______________________________________________________________________________ NAME Tcl_RegExpMatch, Tcl_RegExpCompile, Tcl_RegExpExec, Tcl_RegExpRange, Tcl_GetRegExpFromObj, Tcl_RegExpMatchObj, Tcl_RegExpExecObj, Tcl_Reg‐ ExpGetInfo - Pattern matching with regular expressions SYNOPSIS #include <tcl.h> int Tcl_RegExpMatchObj(interp, textObj, patObj) int Tcl_RegExpMatch(interp, text, pattern) Tcl_RegExp Tcl_RegExpCompile(interp, pattern) int Tcl_RegExpExec(interp, regexp, text, start) void Tcl_RegExpRange(regexp, index, startPtr, endPtr) Tcl_RegExp Tcl_GetRegExpFromObj(interp, patObj, cflags) int Tcl_RegExpExecObj(interp, regexp, textObj, offset, nmatches, eflags) void Tcl_RegExpGetInfo(regexp, infoPtr) ARGUMENTS Tcl_Interp *interp (in) Tcl interpreter to use for error reporting. The interpreter may be NULL if no error reporting is de‐ sired. Tcl_Obj *textObj (in/out) Refers to the value from which to get the text to search. The in‐ ternal representation of the value may be converted to a form that can be efficiently searched. Tcl_Obj *patObj (in/out) Refers to the value from which to get a regular expression. The com‐ piled regular expression is cached in the value. const char *text (in) Text to search for a match with a regular expression. const char *pattern (in) String in the form of a regular expression pattern. Tcl_RegExp regexp (in) Compiled regular expression. Must have been returned previously by Tcl_GetRegExpFromObj or Tcl_RegEx‐ pCompile. const char *start (in) If text is just a portion of some other string, this argument iden‐ tifies the beginning of the larger string. If it is not the same as text, then no “^” matches will be allowed. int index (in) Specifies which range is desired: 0 means the range of the entire match, 1 or greater means the range that matched a parenthesized sub-expression. const char **startPtr (out) The address of the first character in the range is stored here, or NULL if there is no such range. const char **endPtr (out) The address of the character just after the last one in the range is stored here, or NULL if there is no such range. int cflags (in) OR-ed combination of the compila‐ tion flags TCL_REG_ADVANCED, TCL_REG_EXTENDED, TCL_REG_BASIC, TCL_REG_EXPANDED, TCL_REG_QUOTE, TCL_REG_NOCASE, TCL_REG_NEWLINE, TCL_REG_NLSTOP, TCL_REG_NLANCH, TCL_REG_NOSUB, and TCL_REG_CAN‐ MATCH. See below for more informa‐ tion. int offset (in) The character offset into the text where matching should begin. The value of the offset has no impact on ^ matches. This behavior is controlled by eflags. int nmatches (in) The number of matching subexpres‐ sions that should be remembered for later use. If this value is 0, then no subexpression match in‐ formation will be computed. If the value is -1, then all of the matching subexpressions will be remembered. Any other value will be taken as the maximum number of subexpressions to remember. int eflags (in) OR-ed combination of the execution flags TCL_REG_NOTBOL and TCL_REG_NOTEOL. See below for more information. Tcl_RegExpInfo *infoPtr (out) The address of the location where information about a previous match should be stored by Tcl_RegExpGet‐ Info. ______________________________________________________________________________ DESCRIPTION Tcl_RegExpMatch determines whether its pattern argument matches regexp, where regexp is interpreted as a regular expression using the rules in the re_syntax reference page. If there is a match then Tcl_RegExpMatch returns 1. If there is no match then Tcl_RegExpMatch returns 0. If an error occurs in the matching process (e.g. pattern is not a valid regu‐ lar expression) then Tcl_RegExpMatch returns -1 and leaves an error message in the interpreter result. Tcl_RegExpMatchObj is similar to Tcl_RegExpMatch except it operates on the Tcl values textObj and patObj instead of UTF strings. Tcl_RegExpMatchObj is generally more efficient than Tcl_RegExpMatch, so it is the preferred interface. Tcl_RegExpCompile, Tcl_RegExpExec, and Tcl_RegExpRange provide lower- level access to the regular expression pattern matcher. Tcl_RegExpCom‐ pile compiles a regular expression string into the internal form used for efficient pattern matching. The return value is a token for this compiled form, which can be used in subsequent calls to Tcl_RegExpExec or Tcl_RegExpRange. If an error occurs while compiling the regular ex‐ pression then Tcl_RegExpCompile returns NULL and leaves an error mes‐ sage in the interpreter result. Note: the return value from Tcl_Reg‐ ExpCompile is only valid up to the next call to Tcl_RegExpCompile; it is not safe to retain these values for long periods of time. Tcl_RegExpExec executes the regular expression pattern matcher. It re‐ turns 1 if text contains a range of characters that match regexp, 0 if no match is found, and -1 if an error occurs. In the case of an error, Tcl_RegExpExec leaves an error message in the interpreter result. When searching a string for multiple matches of a pattern, it is important to distinguish between the start of the original string and the start of the current search. For example, when searching for the second oc‐ currence of a match, the text argument might point to the character just after the first match; however, it is important for the pattern matcher to know that this is not the start of the entire string, so that it does not allow “^” atoms in the pattern to match. The start argument provides this information by pointing to the start of the overall string containing text. Start will be less than or equal to text; if it is less than text then no ^ matches will be allowed. Tcl_RegExpRange may be invoked after Tcl_RegExpExec returns; it pro‐ vides detailed information about what ranges of the string matched what parts of the pattern. Tcl_RegExpRange returns a pair of pointers in *startPtr and *endPtr that identify a range of characters in the source string for the most recent call to Tcl_RegExpExec. Index indicates which of several ranges is desired: if index is 0, information is re‐ turned about the overall range of characters that matched the entire pattern; otherwise, information is returned about the range of charac‐ ters that matched the index'th parenthesized subexpression within the pattern. If there is no range corresponding to index then NULL is stored in *startPtr and *endPtr. Tcl_GetRegExpFromObj, Tcl_RegExpExecObj, and Tcl_RegExpGetInfo are value interfaces that provide the most direct control of Henry Spencer's regular expression library. For users that need to modify compilation and execution options directly, it is recommended that you use these interfaces instead of calling the internal regexp functions. These interfaces handle the details of UTF to Unicode translations as well as providing improved performance through caching in the pattern and string values. Tcl_GetRegExpFromObj attempts to return a compiled regular expression from the patObj. If the value does not already contain a compiled reg‐ ular expression it will attempt to create one from the string in the value and assign it to the internal representation of the patObj. The return value of this function is of type Tcl_RegExp. The return value is a token for this compiled form, which can be used in subsequent calls to Tcl_RegExpExecObj or Tcl_RegExpGetInfo. If an error occurs while compiling the regular expression then Tcl_GetRegExpFromObj re‐ turns NULL and leaves an error message in the interpreter result. The regular expression token can be used as long as the internal represen‐ tation of patObj refers to the compiled form. The cflags argument is a bit-wise OR of zero or more of the following flags that control the compilation of patObj: TCL_REG_ADVANCED Compile advanced regular expressions (“ARE”s). This mode cor‐ responds to the normal regular expression syntax accepted by the Tcl regexp and regsub commands. TCL_REG_EXTENDED Compile extended regular expressions (“ERE”s). This mode cor‐ responds to the regular expression syntax recognized by Tcl 8.0 and earlier versions. TCL_REG_BASIC Compile basic regular expressions (“BRE”s). This mode corre‐ sponds to the regular expression syntax recognized by common Unix utilities like sed and grep. This is the default if no flags are specified. TCL_REG_EXPANDED Compile the regular expression (basic, extended, or advanced) using an expanded syntax that allows comments and whitespace. This mode causes non-backslashed non-bracket-expression white space and #-to-end-of-line comments to be ignored. TCL_REG_QUOTE Compile a literal string, with all characters treated as ordi‐ nary characters. TCL_REG_NOCASE Compile for matching that ignores upper/lower case distinc‐ tions. TCL_REG_NEWLINE Compile for newline-sensitive matching. By default, newline is a completely ordinary character with no special meaning in either regular expressions or strings. With this flag, “[^” bracket expressions and “.” never match newline, “^” matches an empty string after any newline in addition to its normal function, and “$” matches an empty string before any newline in addition to its normal function. REG_NEWLINE is the bit- wise OR of REG_NLSTOP and REG_NLANCH. TCL_REG_NLSTOP Compile for partial newline-sensitive matching, with the be‐ havior of “[^” bracket expressions and “.” affected, but not the behavior of “^” and “$”. In this mode, “[^” bracket ex‐ pressions and “.” never match newline. TCL_REG_NLANCH Compile for inverse partial newline-sensitive matching, with the behavior of “^” and “$” (the “anchors”) affected, but not the behavior of “[^” bracket expressions and “.”. In this mode “^” matches an empty string after any newline in addition to its normal function, and “$” matches an empty string before any newline in addition to its normal function. TCL_REG_NOSUB Compile for matching that reports only success or failure, not what was matched. This reduces compile overhead and may im‐ prove performance. Subsequent calls to Tcl_RegExpGetInfo or Tcl_RegExpRange will not report any match information. TCL_REG_CANMATCH Compile for matching that reports the potential to complete a partial match given more text (see below). Only one of TCL_REG_EXTENDED, TCL_REG_ADVANCED, TCL_REG_BASIC, and TCL_REG_QUOTE may be specified. Tcl_RegExpExecObj executes the regular expression pattern matcher. It returns 1 if objPtr contains a range of characters that match regexp, 0 if no match is found, and -1 if an error occurs. In the case of an er‐ ror, Tcl_RegExpExecObj leaves an error message in the interpreter re‐ sult. The nmatches value indicates to the matcher how many subexpres‐ sions are of interest. If nmatches is 0, then no subexpression match information is recorded, which may allow the matcher to make various optimizations. If the value is -1, then all of the subexpressions in the pattern are remembered. If the value is a positive integer, then only that number of subexpressions will be remembered. Matching begins at the specified Unicode character index given by offset. Unlike Tcl_RegExpExec, the behavior of anchors is not affected by the offset value. Instead the behavior of the anchors is explicitly controlled by the eflags argument, which is a bit-wise OR of zero or more of the fol‐ lowing flags: TCL_REG_NOTBOL The starting character will not be treated as the beginning of a line or the beginning of the string, so “^” will not match there. Note that this flag has no effect on how “\A” matches. TCL_REG_NOTEOL The last character in the string will not be treated as the end of a line or the end of the string, so “$” will not match there. Note that this flag has no effect on how “\Z” matches. Tcl_RegExpGetInfo retrieves information about the last match performed with a given regular expression regexp. The infoPtr argument contains a pointer to a structure that is defined as follows: typedef struct Tcl_RegExpInfo { int nsubs; Tcl_RegExpIndices *matches; long extendStart; } Tcl_RegExpInfo; The nsubs field contains a count of the number of parenthesized subex‐ pressions within the regular expression. If the TCL_REG_NOSUB was used, then this value will be zero. The matches field points to an ar‐ ray of nsubs+1 values that indicate the bounds of each subexpression matched. The first element in the array refers to the range matched by the entire regular expression, and subsequent elements refer to the parenthesized subexpressions in the order that they appear in the pat‐ tern. Each element is a structure that is defined as follows: typedef struct Tcl_RegExpIndices { long start; long end; } Tcl_RegExpIndices; The start and end values are Unicode character indices relative to the offset location within objPtr where matching began. The start index identifies the first character of the matched subexpression. The end index identifies the first character after the matched subexpression. If the subexpression matched the empty string, then start and end will be equal. If the subexpression did not participate in the match, then start and end will be set to -1. The extendStart field in Tcl_RegExpInfo is only set if the TCL_REG_CAN‐ MATCH flag was used. It indicates the first character in the string where a match could occur. If a match was found, this will be the same as the beginning of the current match. If no match was found, then it indicates the earliest point at which a match might occur if additional text is appended to the string. If it is no match is possible even with further text, this field will be set to -1. SEE ALSO re_syntax(n) KEYWORDS match, pattern, regular expression, string, subexpression, Tcl_RegEx‐ pIndices, Tcl_RegExpInfo Tcl 8.1 Tcl_RegExpMatch(3)
Tcl_Method(3) Функции библиотеки TclOO Tcl_Method(3) ______________________________________________________________________________ NAME Tcl_ClassSetConstructor, Tcl_ClassSetDestructor, Tcl_MethodDeclar‐ erClass, Tcl_MethodDeclarerObject, Tcl_MethodIsPublic, Tcl_MethodIs‐ Type, Tcl_MethodName, Tcl_NewInstanceMethod, Tcl_NewMethod, Tcl_Object‐ ContextInvokeNext, Tcl_ObjectContextIsFiltering, Tcl_ObjectCon‐ textMethod, Tcl_ObjectContextObject, Tcl_ObjectContextSkippedArgs - ра‐ бота с методами и контекстами вызова методов SYNOPSIS #include <tclOO.h> Tcl_Method Tcl_NewMethod(interp, class, nameObj, isPublic, methodTypePtr, clientData) Tcl_Method Tcl_NewInstanceMethod(interp, object, nameObj, isPublic, methodTypePtr, clientData) Tcl_ClassSetConstructor(interp, class, method) Tcl_ClassSetDestructor(interp, class, method) Tcl_Class Tcl_MethodDeclarerClass(method) Tcl_Object Tcl_MethodDeclarerObject(method) Tcl_Obj * Tcl_MethodName(method) int Tcl_MethodIsPublic(method) int Tcl_MethodIsType(method, methodTypePtr, clientDataPtr) int Tcl_ObjectContextInvokeNext(interp, context, objc, objv, skip) int Tcl_ObjectContextIsFiltering(context) Tcl_Method Tcl_ObjectContextMethod(context) Tcl_Object Tcl_ObjectContextObject(context) int Tcl_ObjectContextSkippedArgs(context) ARGUMENTS Tcl_Interp *interp (in/out) Интерпретатор, содержащий объект или класс, в котором создается или обновляется метод. Tcl_Object object (in) Объект, в котором создается метод. Tcl_Class class (in) Класс, в котором создается метод. Tcl_Obj *nameObj (in) Имя метода для создания. Не должно быть NULL, кроме случаев создания конструкторов или деструкторов. int isPublic (in) Флаг, указывающий видимость метода. Поддерживаемые значения: 0 для неэкспортируемого метода и 1 для экспортируемого метода. Tcl_MethodType *methodTypePtr (in) Описание типа метода для создания или для сравнения. ClientData clientData (in) Данные, передаваемые реализации метода без интерпретации. ClientData *clientDataPtr (out) Указатель на переменную, в которую записывается значение clientData, указанное при создании метода. Если NULL, значение не извлекается. Tcl_Method method (in) Ссылка на метод для запроса. Tcl_ObjectContext context (in) Ссылка на контекст вызова метода. Обратите внимание, что код клиента не должен сохранять ссылку на контекст. int objc (in) Количество аргументов для передачи реализации метода. Tcl_Obj *const *objv (in) Массив аргументов для передачи реализации метода. int skip (in) Количество аргументов, передаваемых реализации метода, которые не представляют "реальные" аргументы. ______________________________________________________________________________ DESCRIPTION Метод является операцией, выполняемой над объектом и связанной с ним. Каждый метод должен быть привязан либо к объекту, либо к классу; методы, привязанные к классу, ассоциированы со всеми экземплярами (прямыми и косвенными) этого класса. Для данного метода сущность, объявившая его, может быть найдена с помощью Tcl_MethodDeclarerClass, которая возвращает класс, к которому привязан метод (или NULL, если метод не привязан к какому-либо классу), и Tcl_MethodDeclarerObject, которая возвращает объект, к которому привязан метод (или NULL, если метод не привязан к объекту). Имя метода можно получить с помощью Tcl_MethodName, а информацию о том, экспортируется ли метод, - с помощью Tcl_MethodIsPublic. Тип метода также может быть интроспектирован в ограниченной степени; функция Tcl_MethodIsType возвращает, является ли метод определенного типа, присваивая per-method clientData переменной, на которую указывает clientDataPtr (если она не NULL), если тип совпадает. СОЗДАНИЕ МЕТОДОВ Методы создаются с помощью Tcl_NewMethod и Tcl_NewInstanceMethod, что создает метод, привязанный к классу или объекту соответственно. В обоих случаях аргумент nameObj задает имя метода для создания, аргумент isPublic указывает, должен ли метод быть экспортирован изначально, аргумент methodTypePtr описывает реализацию метода (см. раздел ТИПЫ МЕТОДОВ ниже), а аргумент clientData предоставляет некоторые специфические для реализации данные, которые передаются реализации метода при его вызове. Если аргумент nameObj для Tcl_NewMethod равен NULL, создается неназванный метод, который используется для конструкторов и деструкторов. Конструкторы должны устанавливаться в свой класс с помощью функции Tcl_ClassSetConstructor, а деструкторы (которые не должны требовать никаких аргументов) должны устанавливаться в свой класс с помощью функции Tcl_ClassSetDestructor. Неназванные методы не должны использоваться для других целей, а названные методы не должны использоваться как конструкторы или деструкторы. Также обратите внимание, что NULL methodTypePtr используется для внутреннего сигнализации и не должен использоваться в коде клиента. КОНТЕКСТЫ ВЫЗОВА МЕТОДОВ При вызове метода ссылка на контекст вызова метода передается как один из аргументов функции реализации. Этот контекст можно осмотреть, чтобы получить информацию о вызывающем, но его не следует сохранять за пределами момента завершения вызова метода. Метод, который вызывается, можно получить из контекста с помощью Tcl_ObjectContextMethod, а объект, вызвавший метод, - с помощью Tcl_ObjectContextObject. Количество аргументов, которые нужно пропустить (например, имя объекта и имя метода в обычном вызове метода), читается с помощью Tcl_ObjectContextSkippedArgs, и контекст также может сообщить, работает ли он как фильтр для другого метода через Tcl_ObjectContextIsFiltering. Во время выполнения метода реализация метода может выбрать вызов этапов цепочки вызова метода, следующих за текущей реализацией. Это (ядро команды next) выполняется с помощью Tcl_ObjectContextInvokeNext. Обратите внимание, что эта функция не манипулирует стеком кадров вызова, в отличие от команды next; если реализация метода добавила один или несколько дополнительных кадров в стек в рамках своей реализации, она также несет ответственность за временное удаление этих кадров из стека во время выполнения функции Tcl_ObjectContextInvokeNext. Обратите внимание также, что контекст вызова метода никогда не удаляется во время выполнения этой функции. ТИПЫ МЕТОДОВ Типы методов описываются указателем на структуру Tcl_MethodType, которая определяется как: typedef struct { int version; const char *name; Tcl_MethodCallProc *callProc; Tcl_MethodDeleteProc *deleteProc; Tcl_CloneProc *cloneProc; } Tcl_MethodType; Поле version позволяет для будущего расширения структуры и всегда должно быть объявлено равным TCL_OO_METHOD_VERSION_CURRENT. Поле name предоставляет читаемое для человека имя типа и является значением, которое отображется через команды Tcl info class methodtype и info object methodtype. Поле callProc задает функцию, которая вызывается при вызове метода; оно никогда не должно быть NULL. Поле deleteProc задает функцию, которая используется для удаления конкретного метода, и вызывается, когда метод заменяется или удаляется; если поле равно NULL, предполагается, что clientData метода не требует специальных действий для удаления. Поле cloneProc либо функция, которая используется для копирования clientData метода (в рамках Tcl_CopyObjectInstance), либо NULL, чтобы указать, что clientData может быть просто скопировано напрямую. ПОДПИСЬ ФУНКЦИИ TCL_METHODCALLPROC Функции, соответствующие этой подписи, вызываются при вызове метода. typedef int Tcl_MethodCallProc( ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext, int objc, Tcl_Obj *const *objv); Аргумент clientData для Tcl_MethodCallProc - это значение, указанное при создании метода, interp - место для выполнения скриптов и доступа к переменным, а также для размещения результата метода, а поля objc и objv дают объекты параметров метода. Контекст вызова метода можно обнаружить через аргумент objectContext, и возвращаемое значение из Tcl_MethodCallProc - любой код возврата Tcl (например, TCL_OK, TCL_ERROR). ПОДПИСЬ ФУНКЦИИ TCL_METHODDELETEPROC Функции, соответствующие этой подписи, используются при удалении метода, будь то через создание нового метода или из-за удаления объекта или класса. typedef void Tcl_MethodDeleteProc( ClientData clientData); Аргумент clientData для Tcl_MethodDeleteProc будет таким же, как значение, переданное аргументу clientData для Tcl_NewMethod или Tcl_NewInstanceMethod при создании метода. ПОДПИСЬ ФУНКЦИИ TCL_CLONEPROC Функции, соответствующие этой подписи, используются для копирования метода при копировании объекта или класса с помощью Tcl_CopyObjectInstance (или oo::copy). typedef int Tcl_CloneProc( Tcl_Interp *interp, ClientData oldClientData, ClientData *newClientDataPtr); Аргумент interp дает место для записи сообщения об ошибке, когда попытка клонирования объекта терпит неудачу, в этом случае процедура клонирования также должна вернуть TCL_ERROR; в противном случае она должна возвращать TCL_OK. Поле oldClientData для Tcl_CloneProc дает значение из метода, из которого копируется, а поле newClientDataPtr укажет на переменную, в которую нужно записать значение для метода, в который копируется. SEE ALSO Class(3), oo::class(n), oo::define(n), oo::object(n) KEYWORDS constructor, method, object TclOO 0.1 Tcl_Method(3)
Tcl_Method(3) TclOO Library Functions Tcl_Method(3) ______________________________________________________________________________ NAME Tcl_ClassSetConstructor, Tcl_ClassSetDestructor, Tcl_MethodDeclar‐ erClass, Tcl_MethodDeclarerObject, Tcl_MethodIsPublic, Tcl_MethodIs‐ Type, Tcl_MethodName, Tcl_NewInstanceMethod, Tcl_NewMethod, Tcl_Object‐ ContextInvokeNext, Tcl_ObjectContextIsFiltering, Tcl_ObjectCon‐ textMethod, Tcl_ObjectContextObject, Tcl_ObjectContextSkippedArgs - ma‐ nipulate methods and method-call contexts SYNOPSIS #include <tclOO.h> Tcl_Method Tcl_NewMethod(interp, class, nameObj, isPublic, methodTypePtr, clientData) Tcl_Method Tcl_NewInstanceMethod(interp, object, nameObj, isPublic, methodTypePtr, clientData) Tcl_ClassSetConstructor(interp, class, method) Tcl_ClassSetDestructor(interp, class, method) Tcl_Class Tcl_MethodDeclarerClass(method) Tcl_Object Tcl_MethodDeclarerObject(method) Tcl_Obj * Tcl_MethodName(method) int Tcl_MethodIsPublic(method) int Tcl_MethodIsType(method, methodTypePtr, clientDataPtr) int Tcl_ObjectContextInvokeNext(interp, context, objc, objv, skip) int Tcl_ObjectContextIsFiltering(context) Tcl_Method Tcl_ObjectContextMethod(context) Tcl_Object Tcl_ObjectContextObject(context) int Tcl_ObjectContextSkippedArgs(context) ARGUMENTS Tcl_Interp *interp (in/out) The interpreter holding the object or class to create or update a method in. Tcl_Object object (in) The object to create the method in. Tcl_Class class (in) The class to create the method in. Tcl_Obj *nameObj (in) The name of the method to create. Should not be NULL unless creating constructors or destructors. int isPublic (in) A flag saying what the visibility of the method is. The only sup‐ ported public values of this flag are 0 for a non-exported method, and 1 for an exported method. Tcl_MethodType *methodTypePtr (in) A description of the type of the method to create, or the type of method to compare against. ClientData clientData (in) A piece of data that is passed to the implementation of the method without interpretation. ClientData *clientDataPtr (out) A pointer to a variable in which to write the clientData value supplied when the method was created. If NULL, the clientData value will not be retrieved. Tcl_Method method (in) A reference to a method to query. Tcl_ObjectContext context (in) A reference to a method-call con‐ text. Note that client code must not retain a reference to a con‐ text. int objc (in) The number of arguments to pass to the method implementation. Tcl_Obj *const *objv (in) An array of arguments to pass to the method implementation. int skip (in) The number of arguments passed to the method implementation that do not represent "real" arguments. ______________________________________________________________________________ DESCRIPTION A method is an operation carried out on an object that is associated with the object. Every method must be attached to either an object or a class; methods attached to a class are associated with all instances (direct and indirect) of that class. Given a method, the entity that declared it can be found using Tcl_MethodDeclarerClass which returns the class that the method is at‐ tached to (or NULL if the method is not attached to any class) and Tcl_MethodDeclarerObject which returns the object that the method is attached to (or NULL if the method is not attached to an object). The name of the method can be retrieved with Tcl_MethodName and whether the method is exported is retrieved with Tcl_MethodIsPublic. The type of the method can also be introspected upon to a limited degree; the func‐ tion Tcl_MethodIsType returns whether a method is of a particular type, assigning the per-method clientData to the variable pointed to by clientDataPtr if (that is non-NULL) if the type is matched. METHOD CREATION Methods are created by Tcl_NewMethod and Tcl_NewInstanceMethod, which create a method attached to a class or an object respectively. In both cases, the nameObj argument gives the name of the method to create, the isPublic argument states whether the method should be exported ini‐ tially, the methodTypePtr argument describes the implementation of the method (see the METHOD TYPES section below) and the clientData argument gives some implementation-specific data that is passed on to the imple‐ mentation of the method when it is called. When the nameObj argument to Tcl_NewMethod is NULL, an unnamed method is created, which is used for constructors and destructors. Construc‐ tors should be installed into their class using the Tcl_ClassSetCon‐ structor function, and destructors (which must not require any argu‐ ments) should be installed into their class using the Tcl_ClassSetDe‐ structor function. Unnamed methods should not be used for any other purpose, and named methods should not be used as either constructors or destructors. Also note that a NULL methodTypePtr is used to provide in‐ ternal signaling, and should not be used in client code. METHOD CALL CONTEXTS When a method is called, a method-call context reference is passed in as one of the arguments to the implementation function. This context can be inspected to provide information about the caller, but should not be retained beyond the moment when the method call terminates. The method that is being called can be retrieved from the context by using Tcl_ObjectContextMethod, and the object that caused the method to be invoked can be retrieved with Tcl_ObjectContextObject. The number of arguments that are to be skipped (e.g. the object name and method name in a normal method call) is read with Tcl_ObjectContextSkippedArgs, and the context can also report whether it is working as a filter for an‐ other method through Tcl_ObjectContextIsFiltering. During the execution of a method, the method implementation may choose to invoke the stages of the method call chain that come after the cur‐ rent method implementation. This (the core of the next command) is done using Tcl_ObjectContextInvokeNext. Note that this function does not ma‐ nipulate the call-frame stack, unlike the next command; if the method implementation has pushed one or more extra frames on the stack as part of its implementation, it is also responsible for temporarily popping those frames from the stack while the Tcl_ObjectContextInvokeNext func‐ tion is executing. Note also that the method-call context is never deleted during the execution of this function. METHOD TYPES The types of methods are described by a pointer to a Tcl_MethodType structure, which is defined as: typedef struct { int version; const char *name; Tcl_MethodCallProc *callProc; Tcl_MethodDeleteProc *deleteProc; Tcl_CloneProc *cloneProc; } Tcl_MethodType; The version field allows for future expansion of the structure, and should always be declared equal to TCL_OO_METHOD_VERSION_CURRENT. The name field provides a human-readable name for the type, and is the value that is exposed via the info class methodtype and info object methodtype Tcl commands. The callProc field gives a function that is called when the method is invoked; it must never be NULL. The deleteProc field gives a function that is used to delete a particu‐ lar method, and is called when the method is replaced or removed; if the field is NULL, it is assumed that the method's clientData needs no special action to delete. The cloneProc field is either a function that is used to copy a method's clientData (as part of Tcl_CopyObjectInstance) or NULL to in‐ dicate that the clientData can just be copied directly. TCL_METHODCALLPROC FUNCTION SIGNATURE Functions matching this signature are called when the method is in‐ voked. typedef int Tcl_MethodCallProc( ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext, int objc, Tcl_Obj *const *objv); The clientData argument to a Tcl_MethodCallProc is the value that was given when the method was created, the interp is a place in which to execute scripts and access variables as well as being where to put the result of the method, and the objc and objv fields give the parameter objects to the method. The calling context of the method can be discov‐ ered through the objectContext argument, and the return value from a Tcl_MethodCallProc is any Tcl return code (e.g. TCL_OK, TCL_ERROR). TCL_METHODDELETEPROC FUNCTION SIGNATURE Functions matching this signature are used when a method is deleted, whether through a new method being created or because the object or class is deleted. typedef void Tcl_MethodDeleteProc( ClientData clientData); The clientData argument to a Tcl_MethodDeleteProc will be the same as the value passed to the clientData argument to Tcl_NewMethod or Tcl_NewInstanceMethod when the method was created. TCL_CLONEPROC FUNCTION SIGNATURE Functions matching this signature are used to copy a method when the object or class is copied using Tcl_CopyObjectInstance (or oo::copy). typedef int Tcl_CloneProc( Tcl_Interp *interp, ClientData oldClientData, ClientData *newClientDataPtr); The interp argument gives a place to write an error message when the attempt to clone the object is to fail, in which case the clone proce‐ dure must also return TCL_ERROR; it should return TCL_OK otherwise. The oldClientData field to a Tcl_CloneProc gives the value from the method being copied from, and the newClientDataPtr field will point to a variable in which to write the value for the method being copied to. SEE ALSO Class(3), oo::class(n), oo::define(n), oo::object(n) KEYWORDS constructor, method, object TclOO 0.1 Tcl_Method(3)
Файловая система(3) Процедуры Tcl Library Файловая система(3) ______________________________________________________________________________ NAME Tcl_FSRegister, Tcl_FSUnregister, Tcl_FSData, Tcl_FSMountsChanged, Tcl_FSGetFileSystemForPath, Tcl_FSGetPathType, Tcl_FSCopyFile, Tcl_FS‐ CopyDirectory, Tcl_FSCreateDirectory, Tcl_FSDeleteFile, Tcl_FSRemoveDi‐ rectory, Tcl_FSRenameFile, Tcl_FSListVolumes, Tcl_FSEvalFile, Tcl_FSE‐ valFileEx, Tcl_FSLoadFile, Tcl_FSUnloadFile, Tcl_FSMatchInDirectory, Tcl_FSLink, Tcl_FSLstat, Tcl_FSUtime, Tcl_FSFileAttrsGet, Tcl_FSFileAt‐ trsSet, Tcl_FSFileAttrStrings, Tcl_FSStat, Tcl_FSAccess, Tcl_FSOpen‐ FileChannel, Tcl_FSGetCwd, Tcl_FSChdir, Tcl_FSPathSeparator, Tcl_FSJoinPath, Tcl_FSSplitPath, Tcl_FSEqualPaths, Tcl_FSGetNormalized‐ Path, Tcl_FSJoinToPath, Tcl_FSConvertToPathType, Tcl_FSGetInternalRep, Tcl_FSGetTranslatedPath, Tcl_FSGetTranslatedStringPath, Tcl_FSNewNa‐ tivePath, Tcl_FSGetNativePath, Tcl_FSFileSystemInfo, Tcl_GetAccessTime‐ FromStat, Tcl_GetBlockSizeFromStat, Tcl_GetBlocksFromStat, Tcl_GetChangeTimeFromStat, Tcl_GetDeviceTypeFromStat, Tcl_GetFSDevice‐ FromStat, Tcl_GetFSInodeFromStat, Tcl_GetGroupIdFromStat, Tcl_GetLinkCountFromStat, Tcl_GetModeFromStat, Tcl_GetModificationTime‐ FromStat, Tcl_GetSizeFromStat, Tcl_GetUserIdFromStat, Tcl_AllocStatBuf - процедуры для взаимодействия с любой файловой системой SYNOPSIS #include <tcl.h> int Tcl_FSRegister(clientData, fsPtr) int Tcl_FSUnregister(fsPtr) void * Tcl_FSData(fsPtr) Tcl_FSMountsChanged(fsPtr) const Tcl_Filesystem * Tcl_FSGetFileSystemForPath(pathPtr) Tcl_PathType Tcl_FSGetPathType(pathPtr) int Tcl_FSCopyFile(srcPathPtr, destPathPtr) int Tcl_FSCopyDirectory(srcPathPtr, destPathPtr, errorPtr) int Tcl_FSCreateDirectory(pathPtr) int Tcl_FSDeleteFile(pathPtr) int Tcl_FSRemoveDirectory(pathPtr, recursive, errorPtr) int Tcl_FSRenameFile(srcPathPtr, destPathPtr) Tcl_Obj * Tcl_FSListVolumes(void) int Tcl_FSEvalFileEx(interp, pathPtr, encodingName) int Tcl_FSEvalFile(interp, pathPtr) int Tcl_FSLoadFile(interp, pathPtr, sym1, sym2, proc1Ptr, proc2Ptr, loadHandlePtr, unloadProcPtr) int │ Tcl_FSUnloadFile(interp, loadHandle) │ int Tcl_FSMatchInDirectory(interp, resultPtr, pathPtr, pattern, types) Tcl_Obj * Tcl_FSLink(linkNamePtr, toPtr, linkAction) int Tcl_FSLstat(pathPtr, statPtr) int Tcl_FSUtime(pathPtr, tval) int Tcl_FSFileAttrsGet(interp, index, pathPtr, objPtrRef) int Tcl_FSFileAttrsSet(interp, index, pathPtr, objPtr) const char *const * Tcl_FSFileAttrStrings(pathPtr, objPtrRef) int Tcl_FSStat(pathPtr, statPtr) int Tcl_FSAccess(pathPtr, mode) Tcl_Channel Tcl_FSOpenFileChannel(interp, pathPtr, modeString, permissions) Tcl_Obj * Tcl_FSGetCwd(interp) int Tcl_FSChdir(pathPtr) Tcl_Obj * Tcl_FSPathSeparator(pathPtr) Tcl_Obj * Tcl_FSJoinPath(listObj, elements) Tcl_Obj * Tcl_FSSplitPath(pathPtr, lenPtr) int Tcl_FSEqualPaths(firstPtr, secondPtr) Tcl_Obj * Tcl_FSGetNormalizedPath(interp, pathPtr) Tcl_Obj * Tcl_FSJoinToPath(basePtr, objc, objv) int Tcl_FSConvertToPathType(interp, pathPtr) void * Tcl_FSGetInternalRep(pathPtr, fsPtr) Tcl_Obj * Tcl_FSGetTranslatedPath(interp, pathPtr) const char * Tcl_FSGetTranslatedStringPath(interp, pathPtr) Tcl_Obj * Tcl_FSNewNativePath(fsPtr, clientData) const void * Tcl_FSGetNativePath(pathPtr) Tcl_Obj * Tcl_FSFileSystemInfo(pathPtr) Tcl_StatBuf * Tcl_AllocStatBuf() Tcl_WideInt │ Tcl_GetAccessTimeFromStat(statPtr) │ unsigned │ Tcl_GetBlockSizeFromStat(statPtr) │ Tcl_WideUInt │ Tcl_GetBlocksFromStat(statPtr) │ Tcl_WideInt │ Tcl_GetChangeTimeFromStat(statPtr) │ int │ Tcl_GetDeviceTypeFromStat(statPtr) │ unsigned │ Tcl_GetFSDeviceFromStat(statPtr) │ unsigned │ Tcl_GetFSInodeFromStat(statPtr) │ int │ Tcl_GetGroupIdFromStat(statPtr) │ int │ Tcl_GetLinkCountFromStat(statPtr) │ unsigned │ Tcl_GetModeFromStat(statPtr) │ Tcl_WideInt │ Tcl_GetModificationTimeFromStat(statPtr) │ Tcl_WideUInt │ Tcl_GetSizeFromStat(statPtr) │ int │ Tcl_GetUserIdFromStat(statPtr) │ ARGUMENTS const Tcl_Filesystem *fsPtr (in) Указывает на структуру, содержащую адреса процедур, которые могут быть вызваны для выполнения различных операций файловой системы. Tcl_Obj *pathPtr (in) Путь, представленный этим значением, используется для операции. Если значение ещё не имеет внутреннего представления пути, оно будет преобразовано в такое. Tcl_Obj *srcPathPtr (in) Как и для pathPtr, но используется для исходного файла операции копирования или переименования. Tcl_Obj *destPathPtr (in) Как и для pathPtr, но используется для имени файла-назначения операции копирования или переименования. int recursive (in) Флаг, указывающий, нужно ли удалять поддиректории и их содержимое тоже. const char *encodingName (in) Кодировка данных, хранящихся в файле, идентифицированном pathPtr, и которые будут оцениваться. const char *pattern (in) Будут возвращены только файлы или директории, соответствующие этому шаблону. Tcl_GlobTypeData *types (in) Будут возвращены только файлы или директории, соответствующие описаниям типов, содержащимся в этой структуре. Этот параметр может быть NULL. Tcl_Interp *interp (in) Интерпретатор, используемый либо для результатов, либо для оценки, или для сообщений об ошибках. void *clientData (in) Родное описание значения пути для создания. Tcl_Obj *firstPtr (in) Первый из двух путей для сравнения. Значение может быть преобразовано в тип пути. Tcl_Obj *secondPtr (in) Второй из двух путей для сравнения. Значение может быть преобразовано в тип пути. Tcl_Obj *listObj (in) Список элементов пути для операций объединения. int elements (in) Количество элементов в listObj, которые должны быть объединены. Если отрицательное, то все элементы объединяются. Tcl_Obj **errorPtr (out) В случае ошибки, заполняется значением, содержащим имя файла, который вызвал ошибку в различных операциях копирования/переименования. int index (in) Индекс атрибута в вопросе. Tcl_Obj *objPtr (in) Значение для установки в операции. Tcl_Obj **objPtrRef (out) Заполняется значением, содержащим результат операции. Tcl_Obj *resultPtr (out) Предварительно выделенное значение, в которое нужно хранить (используя Tcl_ListObjAppendElement) список файлов или директорий, которые успешно совпали. int mode (in) Маска, состоящая из одного или нескольких из R_OK, W_OK, X_OK и F_OK. R_OK, W_OK и X_OK запрашивают проверку, существует ли файл и имеет ли он права на чтение, запись и выполнение соответственно. F_OK запрашивает только проверку существования файла. Tcl_StatBuf *statPtr (out) Структура, которая содержит результат операции stat или lstat. const char *sym1 (in) Имя процедуры для поиска в таблице символов файла const char *sym2 (in) Имя процедуры для поиска в таблице символов файла Tcl_PackageInitProc **proc1Ptr (out) Заполняется функцией инициализации для этого кода. Tcl_PackageInitProc **proc2Ptr (out) Заполняется функцией безопасной инициализации для этого кода. void **clientDataPtr (out) Заполняется значением clientData, которое будет передано функции выгрузки этого кода при её вызове. Tcl_LoadHandle *loadHandlePtr (out) Заполняется абстрактным токеном, представляющим загруженный файл. Tcl_FSUnloadFileProc **unloadProcPtr (out) Заполняется функцией для выгрузки этого фрагмента кода. Tcl_LoadHandle loadHandle (in) Дескриптор загруженной библиотеки, которая должна быть выгружена. utimbuf *tval (in) В этой структуре читаются и используются времена доступа и модификации для установки этих значений для данного файла. const char *modeString (in) Указывает, как файл должен быть доступен. Может иметь любое из значений, разрешенных для аргумента mode команды Tcl open. int permissions (in) Флаги разрешений в стиле POSIX, такие как 0644. Если создается новый файл, эти разрешения будут установлены на созданном файле. int *lenPtr (out) Если не NULL, заполняется количеством элементов в разделенном пути. Tcl_Obj *basePtr (in) Базовый путь, к которому нужно присоединить данные элементы. Может быть NULL. int objc (in) Количество элементов в objv. Tcl_Obj *const objv[] (in) Элементы для присоединения к данному базовому пути. Tcl_Obj *linkNamePtr (in) Имя ссылки, которая должна быть создана или прочитана. Tcl_Obj *toPtr (in) На что должна ссылаться ссылка, называемая linkNamePtr, или NULL, если символическая ссылка, указанная linkNamePtr, должна быть прочитана. int linkAction (in) Комбинация флагов, объединенных по OR, указывающая, какой тип ссылки должен быть создан (будет игнорироваться, если toPtr равно NULL). Допустимые биты для установки - TCL_CREATE_SYM‐ BOLIC_LINK и TCL_CREATE_HARD_LINK. Когда оба флага установлены и базовая файловая система может использовать любой из них, предпочтение отдается символическим ссылкам. ______________________________________________________________________________ ОПИСАНИЕ Существует несколько причин для вызова функций Tcl_FS API (например, Tcl_FSAccess и Tcl_FSStat) вместо прямого вызова системных функций, таких как access и stat. Во-первых, они работают кросс-платформенно, поэтому расширение, которое их вызывает, должно работать без изменений на Unix и Windows. Во-вторых, реализация Windows некоторых из этих функций исправляет ошибки в системных вызовах. В-третьих, эти вызовы функций обрабатывают любые необходимые преобразования "Utf в родное для платформы" для путей (и могут кэшировать результаты таких преобразований для большей эффективности при последующих вызовах). В-четвертых, и, возможно, самое важное, все эти функции "осведомлены о виртуальной файловой системе". Любая зарегистрированная виртуальная файловая система (VFS) может перенаправить доступ к файлам на альтернативные носители или методы доступа. Это означает, что все эти функции (а следовательно, и соответствующие команды Tcl, такие как file, glob, pwd, cd, open и т.д.) могут работать с "файлами", которые не являются родными файлами в родной файловой системе. Это также означает, что любое расширение Tcl, которое обращается к файловой системе (FS) через этот API, автоматически "осведомлено о виртуальной файловой системе". Конечно, если расширение напрямую обращается к родной файловой системе (через API, специфичные для платформы, например), то Tcl не может перехватить такие вызовы. Если подходящие VFS зарегистрированы, "файлы" могут, например, быть удаленными (например, находиться на удаленном сервере FTP) или архивированными (например, лежать внутри архива .zip). Такие зарегистрированные файловые системы предоставляют таблицу поиска функций для реализации всего или части функциональности, перечисленной здесь. Наконец, вызовы Tcl_FSStat и Tcl_FSLstat абстрагируют от того, что на самом деле представляет собой буфер "struct stat", что позволяет использовать один и тот же код как на системах с поддержкой, так и на системах без поддержки файлов размером более 2 ГБ. API Tcl_FS основан на Tcl_Obj и может кэшировать внутренние представления и другие строки, связанные с путями (например, текущую рабочую директорию). Один из побочных эффектов этого заключается в том, что нельзя передавать значения с нулевым счетчиком ссылок в любую из этих функций. Если такие вызовы обрабатываются, они могут привести к утечкам памяти (в некоторых обстоятельствах код файловой системы может захотеть сохранить ссылку на переданное значение, поэтому нельзя предполагать, что после любого из этих вызовов значение по-прежнему имеет нулевой счетчик ссылок - он мог быть увеличен) или к прямому нарушению сегментации (или другой ошибке доступа к памяти) из-за освобождения значения на полпути через сложную манипуляцию значениями, необходимую для обеспечения того, чтобы путь был полностью нормализован и абсолютным для определения файловой системы. Практический урок из этого заключается в том, что Tcl_Obj *path = Tcl_NewStringObj(...); Tcl_FSWhatever(path); Tcl_DecrRefCount(path); неверно и может вызвать ошибки памяти. Путь должен иметь увеличенный счетчик ссылок перед передачей его, или до вызова его уменьшения. Для этого значения с нулевым счетчиком ссылок считаются недействительными путями файловой системы, и вызов любой функции Tcl_FS API с таким значением приведет к тому, что никаких действий не будет предпринято. ФУНКЦИИ API FS Tcl_FSCopyFile пытается скопировать файл, указанный srcPathPtr, в путь, указанный destPathPtr. Если два указанных пути лежат в одной файловой системе (согласно Tcl_FSGetFileSystemForPath), то вызывается функция "копирование файла" этой файловой системы (если она не NULL). В противном случае функция возвращает -1 и устанавливает глобальную переменную C errno на код POSIX-ошибки "EXDEV" (что означает "ссылка между доменами"). Tcl_FSCopyDirectory пытается скопировать директорию, указанную srcPathPtr, в путь, указанный destPathPtr. Если два указанных пути лежат в одной файловой системе (согласно Tcl_FSGetFileSystemForPath), то вызывается функция "копирование файла" этой файловой системы (если она не NULL). В противном случае функция возвращает -1 и устанавливает глобальную переменную C errno на код POSIX-ошибки "EXDEV" (что означает "ссылка между доменами"). Tcl_FSCreateDirectory пытается создать директорию, указанную pathPtr, вызывая функцию "создать директорию" владельца. Tcl_FSDeleteFile пытается удалить файл, указанный pathPtr, вызывая функцию "удалить файл" владельца. Tcl_FSRemoveDirectory пытается удалить директорию, указанную pathPtr, вызывая функцию "удалить директорию" владельца. Tcl_FSRenameFile пытается переименовать файл или директорию, указанную srcPathPtr, в путь, указанный destPathPtr. Если два указанных пути лежат в одной файловой системе (согласно Tcl_FSGetFileSystemForPath), то вызывается функция "переименовать файл" этой файловой системы (если она не NULL). В противном случае функция возвращает -1 и устанавливает глобальную переменную C errno на код POSIX-ошибки "EXDEV" (что означает "ссылка между доменами"). Tcl_FSListVolumes вызывает каждую файловую систему, у которой есть непустая функция "список томов", и запрашивает у них их список корневых томов. Она накапливает возвращаемые значения в списке, который возвращается вызывающему (с счетчиком ссылок 0). Tcl_FSEvalFileEx читает файл, указанный pathPtr, используя кодировку, идентифицированную encodingName, и оценивает его содержимое как скрипт Tcl. Она возвращает ту же информацию, что и Tcl_EvalObjEx. Если encodingName равно NULL, используется системная кодировка для чтения содержимого файла. Если файл не удалось прочитать, возвращается ошибка Tcl, описывающая, почему файл не удалось прочитать. Символ конца файла для файлов - "\x1A" (^Z) для всех платформ. Если требуется "^Z" в коде для строкового сравнения, можно использовать "\x1A", который будет безопасно заменен интерпретатором Tcl на "^Z". Tcl_FSEvalFile - это упрощенная версия Tcl_FSEvalFileEx, которая всегда использует системную кодировку при чтении файла. Tcl_FSLoadFile динамически загружает файл двоичного кода в память и возвращает адреса двух процедур внутри этого файла, если они определены. Будет вызвана подходящая функция для файловой системы, к которой принадлежит pathPtr. Если эта файловая система не реализует эту функцию (большинство виртуальных файловых систем не будут, из-за ограничений ОС в динамической загрузке двоичного кода), Tcl попытается скопировать файл в временный каталог и загрузить этот временный файл. │ Tcl_FSUnloadFile │ отменяет операцию, запрашивая удаление библиотеки, указанной в load- │ Handle, из процесса. Обратите внимание, что, в отличие от команды │ unload, это не дает библиотеке возможности очистить. │ Обе указанные функции возвращают стандартный код завершения Tcl. Если возникает ошибка, сообщение об ошибке оставляется в результате интерпретатора. Токен, предоставленный через переменную, указанную loadHandlePtr, может │ использоваться с Tcl_FindSymbol. Tcl_FSMatchInDirectory используется кодом glob для поиска в директории всех файлов, которые соответствуют данному шаблону. Будет вызвана подходящая функция для файловой системы, к которой принадлежит pathPtr. Возвращаемое значение - стандартный результат Tcl, указывающий, возникла ли ошибка в процессе glob. Сообщения об ошибках размещаются в interp (если interp не NULL, что разрешено), но хорошие результаты размещаются в данном resultPtr. Обратите внимание, что код glob реализует рекурсивные шаблоны внутренне, поэтому эта функция будет передавать только простые шаблоны. Для обработки рекурсии Tcl будет вызывать эту функцию часто, запрашивая только возвращение директорий. Специальный случай вызова с NULL-шаблоном указывает, что путь нужно проверить только на правильный тип. Tcl_FSLink заменяет библиотечную версию readlink и расширяет её для поддержки создания ссылок. Будет вызвана подходящая функция для файловой системы, к которой принадлежит linkNamePtr. Если toPtr равно NULL, выполняется действие "прочитать ссылку". Результат - Tcl_Obj, указывающий содержимое символической ссылки, данной linkNamePtr, или NULL, если ссылку не удалось прочитать. Результат принадлежит вызывающему, который должен вызвать Tcl_DecrRefCount, когда результат больше не нужен. Если toPtr не NULL, Tcl должна создать ссылку одного из типов, переданных в флаге linkAction. Этот флаг - комбинация по OR из TCL_CREATE_SYMBOLIC_LINK и TCL_CREATE_HARD_LINK. Где есть выбор (т.е. более одного флага передано), соглашение Tcl - отдавать предпочтение символическим ссылкам. Когда ссылка успешно создана, возвращаемое значение должно быть toPtr (которое уже принадлежит вызывающему). Если неудачно, возвращается NULL. Tcl_FSLstat заполняет структуру Tcl_StatBuf statPtr информацией об указанном файле. Для получения этой информации права доступа к файлу не требуются, но нужны права поиска во всех директориях, указанных в пути, ведущем к файлу. Структура Tcl_StatBuf включает информацию о устройстве, inode (всегда 0 на Windows), привилегированном режиме, nlink (всегда 1 на Windows), идентификаторе пользователя (всегда 0 на Windows), идентификаторе группы (всегда 0 на Windows), rdev (то же, что и устройство на Windows), размере, времени последнего доступа, времени последней модификации и времени последней смены метаданных. См. PORTABLE STAT RESULT API для описания, как писать переносимый код для выделения и доступа к структуре Tcl_StatBuf. Если путь существует, Tcl_FSLstat возвращает 0, и структура stat заполняется данными. В противном случае возвращается -1, и информация stat не предоставляется. Tcl_FSUtime заменяет библиотечную версию utime. Это возвращает 0 при успешном выполнении и -1 при ошибке (как в документации utime). При успешном выполнении функция обновит значения "atime" и "mtime" для данного файла. Tcl_FSFileAttrsGet реализует чтение для подкоманды хуков атрибутов файла. Будет вызвана подходящая функция для файловой системы, к которой принадлежит pathPtr. Если результат TCL_OK, то значение размещено в objPtrRef, которое будет временно действительным (если не вызывать Tcl_IncrRefCount). Tcl_FSFileAttrsSet реализует запись для подкоманды хуков атрибутов файла. Будет вызвана подходящая функция для файловой системы, к которой принадлежит pathPtr. Tcl_FSFileAttrStrings реализует часть подкоманды хуков атрибутов файла. Будет вызвана подходящая функция для файловой системы, к которой принадлежит pathPtr. Вызванная процедура может либо вернуть массив строк, либо вместо этого вернуть NULL и поместить список Tcl в данный objPtrRef. Tcl возьмет этот список и сначала увеличит его счетчик ссылок перед использованием. По завершении этого использования Tcl уменьшит его счетчик ссылок. Следовательно, если список должен быть удален Tcl, когда он закончен, он должен иметь счетчик ссылок ноль, и если список не должен быть удален, файловая система должна убедиться, что возвращается значение с счетчиком ссылок как минимум один. Tcl_FSAccess проверяет, будет ли процесс разрешен для чтения, записи или проверки существования файла (или другого объекта файловой системы), имя которого - pathname. Если pathname - символическая ссылка на Unix, то проверяются разрешения файла, на который ссылается эта символическая ссылка. При успешном выполнении (все запрошенные разрешения предоставлены) возвращается ноль. При ошибке (хотя бы один бит в mode запрашивал разрешение, которое запрещено, или возникла другая ошибка) возвращается -1. Tcl_FSStat заполняет структуру Tcl_StatBuf statPtr информацией об указанном файле. Для получения этой информации права доступа к файлу не требуются, но нужны права поиска во всех директориях, указанных в пути, ведущем к файлу. Структура Tcl_StatBuf включает информацию о устройстве, inode (всегда 0 на Windows), привилегированном режиме, nlink (всегда 1 на Windows), идентификаторе пользователя (всегда 0 на Windows), идентификаторе группы (всегда 0 на Windows), rdev (то же, что и устройство на Windows), размере, времени последнего доступа, времени последней модификации и времени последней смены метаданных. См. PORTABLE STAT RESULT API для описания, как писать переносимый код для выделения и доступа к структуре Tcl_StatBuf. Если путь существует, Tcl_FSStat возвращает 0, и структура stat заполняется данными. В противном случае возвращается -1, и информация stat не предоставляется. Tcl_FSOpenFileChannel открывает файл, указанный pathPtr, и возвращает дескриптор канала, который можно использовать для ввода и вывода в файл. Этот API моделируется по процедуре fopen стандартной библиотеки ввода/вывода Unix. Синтаксис и значение всех аргументов аналогичны тем, что дано в команде Tcl open при открытии файла. Если возникает ошибка при открытии канала, Tcl_FSOpenFileChannel возвращает NULL и фиксирует код POSIX-ошибки, который можно получить с помощью Tcl_GetErrno. Кроме того, если interp не NULL, Tcl_FSOpenFileChannel оставляет сообщение об ошибке в результате interp после любой ошибки. Только что созданный канал не регистрируется в предоставленном интерпретаторе; для регистрации используйте Tcl_RegisterChannel. Если один из стандартных каналов, stdin, stdout или stderr, был ранее закрыт, действие по созданию нового канала также назначает его в качестве замены стандартного канала. Tcl_FSGetCwd заменяет библиотечную версию getcwd. Она возвращает текущую рабочую директорию библиотеки Tcl. Это может отличаться от рабочей директории родной платформы, что происходит, когда текущая рабочая директория не в родной файловой системе. Результат - указатель на Tcl_Obj, указывающий текущую директорию, или NULL, если текущая директория не может быть определена. Если возвращается NULL, сообщение об ошибке оставляется в результате interp. Результат уже имеет увеличенный счетчик ссылок для вызывающего. Когда он больше не нужен, этот счетчик ссылок должен быть уменьшен. Это нужно для обеспечения потокобезопасности, чтобы позволить нескольким потокам получать доступ к этому и связанным функциям, при этом обеспечивая, что результаты всегда действительны. Tcl_FSChdir заменяет библиотечную версию chdir. Путь нормализуется, а затем передается файловой системе, которая его заявляет. Если эта файловая система не реализует эту функцию, Tcl перейдет на комбинацию stat и access, чтобы проверить, существует ли директория и имеет ли она подходящие разрешения. Для результатов см. документацию chdir. При успешном выполнении мы сохраняем запись успешного пути в cwdPathPtr для последующих вызовов Tcl_FSGetCwd. Tcl_FSPathSeparator возвращает символ(ы) разделителя для наиболее конкретного элемента пути, указанного pathPtr (т.е. последней части пути). Разделитель возвращается как Tcl_Obj, содержащий строку длиной 1. Если путь недействителен, возвращается NULL. Tcl_FSJoinPath берет данный Tcl_Obj, который должен быть допустимым списком (который может иметь счетчик ссылок ноль), и возвращает значение пути, полученное путем рассмотрения первых элементов элементов как допустимых сегментов пути (каждый сегмент пути может быть полным путем, частичным путем или просто одним возможным именем директории или файла). Если любой сегмент пути на самом деле является абсолютным путем, то все предыдущие сегменты пути отбрасываются. Если elements меньше 0, мы используем весь список. Возможность, что возвращаемое значение фактически является элементом данного списка, поэтому вызывающий должен увеличить счетчик ссылок результата перед освобождением списка. Возвращаемое значение, обычно с счетчиком ссылок ноль (но оно может быть общим в некоторых условиях), содержит объединенный путь. Вызывающий должен добавить счетчик ссылок к значению перед его использованием. В частности, возвращаемое значение может быть элементом данного списка, поэтому освобождение списка может освободить значение преждевременно, если счетчик ссылок не был взят. Если количество элементов равно нулю, то возвращаемое значение будет Tcl_Obj с пустой строкой. Tcl_FSSplitPath берет данный Tcl_Obj, который должен быть допустимым путем, и возвращает значение списка Tcl, содержащее каждый сегмент этого пути как элемент. Он возвращает значение списка с счетчиком ссылок ноль. Если переданный lenPtr не NULL, переменная, на которую он указывает, будет обновлена для содержания количества элементов в возвращенном списке. Tcl_FSEqualPaths проверяет, представляют ли два указанных пути один и тот же объект файловой системы. Возвращает 1, если пути равны, и 0, если они разные. Если любой путь равен NULL, всегда возвращается 0. Tcl_FSGetNormalizedPath пытается извлечь из данного Tcl_Obj уникальное нормализованное представление пути, строковое значение которого может использоваться в качестве уникального идентификатора для файла. Он возвращает нормализованное значение пути, принадлежащее Tcl, или NULL, если путь недействителен или его нельзя успешно преобразовать. Извлечение абсолютных, нормализованных путей очень эффективно (поскольку файловая система работает с этими представлениями внутренне), хотя результат, когда файловая система содержит множество символических ссылок, может не быть самой удобной для пользователя версией пути. Возвращаемое значение принадлежит Tcl и имеет срок действия, эквивалентный сроку действия pathPtr (если это относительный путь, то нормализованное значение пути может быть освобождено в любое время, когда cwd изменяется) - вызывающий, конечно, может увеличить счетчик ссылок, если желает сохранить копию на более длительный срок. Tcl_FSJoinToPath берет данное значение, которое обычно должно быть допустимым путем или NULL, и присоединяет к нему массив сегментов путей, указанных. Возвращает значение, обычно с счетчиком ссылок ноль (но оно может быть общим в некоторых условиях), содержащее объединенный путь. Вызывающий должен добавить счетчик ссылок к значению перед его использованием. Если любое из значений, переданных в эту функцию (pathPtr или элементы пути), имеет счетчик ссылок ноль, они будут освобождены, когда функция вернется. Tcl_FSConvertToPathType пытается преобразовать данное Tcl_Obj в допустимый тип пути Tcl, учитывая тот факт, что cwd может измениться, даже если это значение уже якобы правильного типа. Имя файла может начинаться с "~" (для обозначения домашней директории текущего пользователя) или "~<user>" (для обозначения домашней директории любого пользователя). Если преобразование удается (т.е. значение является допустимым путем в одной из текущих файловых систем), то возвращается TCL_OK. В противном случае возвращается TCL_ERROR, и сообщение об ошибке может быть оставлено в интерпретаторе. Tcl_FSGetInternalRep извлекает внутреннее представление данного значения пути в данной файловой системе. Если значение пути принадлежит другой файловой системе, возвращается NULL. Если внутреннее представление в настоящее время NULL, мы пытаемся сгенерировать его, вызывая процедуру Tcl_FSCreateInternalRepProc файловой системы. Возвращает NULL или допустимое внутреннее представление пути. Это внутреннее представление кэшируется, поэтому повторные вызовы этой функции не потребуют дополнительных преобразований. Tcl_FSGetTranslatedPath пытается извлечь переведенный путь из данного Tcl_Obj. Если перевод успешен (т.е. значение является допустимым путем), то он возвращается. В противном случае возвращается NULL, и сообщение об ошибке может быть оставлено в интерпретаторе. "Переведенный" путь - это тот, который не содержит последовательностей "~" или "~user" (они были расширены до их текущего представления в файловой системе). Возвращаемое значение принадлежит вызывающему, который должен хранить его или вызвать Tcl_DecrRefCount, чтобы обеспечить освобождение памяти. Эта функция мало практического использования, и Tcl_FSGetNormalizedPath или Tcl_FSGetNativePath обычно лучше использовать для большинства целей. Tcl_FSGetTranslatedStringPath делает то же, что и Tcl_FSGetTranslatedPath, но возвращает символьную строку или NULL. Возвращаемая строка динамически выделяется и принадлежит вызывающему, который должен хранить её или вызвать ckfree, чтобы обеспечить её освобождение. Опять же, Tcl_FSGetNormalizedPath или Tcl_FSGetNativePath обычно лучше использовать для большинства целей. Tcl_FSNewNativePath выполняет что-то вроде обратного обычных преобразований obj->path->nativerep. Если какой-то код извлекает путь в родной форме (из, например, readlink или родного диалога), и этот путь должен использоваться на уровне Tcl, то вызов этой функции - эффективный способ создания подходящего типа значения пути. Полученное значение - чистое "значение пути", которое получит строковое представление в UTF-8 только в том случае, если это требуется каким-то кодом Tcl. Tcl_FSGetNativePath предназначен для использования файловыми системами Win/Unix, чтобы они могли легко получить родное (char* или TCHAR*) представление пути. Эта функция - удобная обертка вокруг Tcl_FSGetInternalRep. В будущем может быть желательно иметь представления, не основанные на строках (например, на macOS представление с использованием структуры fileSpec или FSRef будет более эффективным). На Windows полное представление Unicode позволит использовать пути неограниченной длины. В настоящее время представление - просто символьная строка, которая может содержать либо относительный путь, либо полный, абсолютный нормализованный путь в родной кодировке (сложные условия определяют, какое из них будет предоставлено, так что ни одно не может быть использовано, если путь известен как абсолютный). Если нужен родной путь, который должен быть абсолютным, то нужно запросить родную версию нормализованного пути. Если по какой-то причине нужен родной путь, который не является абсолютным и не нормализованным, то его нужно построить отдельно (например, с использованием Tcl_FSGetTranslatedPath). Родное представление кэшируется, поэтому повторные вызовы этой функции не потребуют дополнительных преобразований. Возвращаемое значение принадлежит Tcl и имеет срок действия, эквивалентный сроку действия pathPtr (если это относительный путь, то родное представление может быть освобождено в любое время, когда cwd изменяется). Tcl_FSFileSystemInfo возвращает список из двух элементов. Первый элемент - имя файловой системы (например, "native", "vfs", "zip" или "prowrap"), а второй - конкретный тип данного пути в этой файловой системе (что зависит от файловой системы). Второй элемент может быть пустым, если файловая система не предоставляет дальнейшую категоризацию файлов. Возвращается допустимое значение списка, если значение пути распознано, в противном случае возвращается NULL. Tcl_FSGetFileSystemForPath возвращает указатель на Tcl_Filesystem, которая принимает этот путь как допустимый. Если ни одна файловая система не примет путь, возвращается NULL. Tcl_FSGetPathType определяет, является ли данный путь относительным к текущей директории, относительным к текущему тому или абсолютным. Он возвращает одно из TCL_PATH_ABSOLUTE, TCL_PATH_RELATIVE или TCL_PATH_VOLUME_RELATIVE. PORTABLE STAT RESULT API Tcl_AllocStatBuf выделяет Tcl_StatBuf на системной куче (которая может │ быть освобождена путем передачи в ckfree). Это позволяет расширениям │ вызывать Tcl_FSStat и Tcl_FSLstat без зависимости от размера буфера. │ Это, в свою очередь, зависит от флагов, используемых для сборки Tcl. │ Портативные поля Tcl_StatBuf можно читать с помощью следующих │ функций, каждая из которых возвращает значение соответствующего │ поля, перечисленного в таблице ниже. Обратите внимание, что на │ некоторых платформах в Tcl_StatBuf может быть другие поля, поскольку │ это псевдоним подходящей системной структуры, но только портативные │ сделаны доступными здесь. См. документацию вашей системы для полного │ описания этих полей. │ Access Function Field │ Tcl_GetFSDeviceFromStat st_dev │ Tcl_GetFSInodeFromStat st_ino │ Tcl_GetModeFromStat st_mode │ Tcl_GetLinkCountFromStat st_nlink │ Tcl_GetUserIdFromStat st_uid │ Tcl_GetGroupIdFromStat st_gid │ Tcl_GetDeviceTypeFromStat st_rdev │ Tcl_GetAccessTimeFromStat st_atime │ Tcl_GetModificationTimeFromStat st_mtime │ Tcl_GetChangeTimeFromStat st_ctime │ Tcl_GetSizeFromStat st_size │ Tcl_GetBlocksFromStat st_blocks │ Tcl_GetBlockSizeFromStat st_blksize │ THE VIRTUAL FILESYSTEM API Файловая система предоставляет структуру Tcl_Filesystem, которая содержит указатели на функции, реализующие различные операции над файловой системой; эти операции вызываются по необходимости общим слоем, что обычно происходит через функции, перечисленные выше. Структуры Tcl_Filesystem манипулируются с помощью следующих методов. Tcl_FSRegister принимает указатель на структуру файловой системы и необязательный фрагмент данных для ассоциации с этой файловой системой. При вызове этой функции Tcl прикрепит файловую систему к списку известных файловых систем, и она станет полностью функциональной немедленно. Tcl не проверяет, регистрируется ли одна и та же файловая система несколько раз (и в общем это нехорошая вещь делать). Будет возвращено TCL_OK. Tcl_FSUnregister удаляет данную структуру файловой системы из списка известных файловых систем, если она известна, и возвращает TCL_OK. Если файловая система в настоящее время не зарегистрирована, возвращается TCL_ERROR. Tcl_FSData вернет clientData, связанный с данной файловой системой, если эта файловая система зарегистрирована. В противном случае вернет NULL. Tcl_FSMountsChanged используется для информирования ядра Tcl о том, что набор точек монтирования для данной (уже зарегистрированной) файловой системы изменился, и поэтому кэшированные представления файлов могут больше не быть правильными. СТРУКТУРА TCL_FILESYSTEM Структура Tcl_Filesystem содержит следующие поля: typedef struct Tcl_Filesystem { const char *typeName; int structureLength; Tcl_FSVersion version; Tcl_FSPathInFilesystemProc *pathInFilesystemProc; Tcl_FSDupInternalRepProc *dupInternalRepProc; Tcl_FSFreeInternalRepProc *freeInternalRepProc; Tcl_FSInternalToNormalizedProc *internalToNormalizedProc; Tcl_FSCreateInternalRepProc *createInternalRepProc; Tcl_FSNormalizePathProc *normalizePathProc; Tcl_FSFilesystemPathTypeProc *filesystemPathTypeProc; Tcl_FSFilesystemSeparatorProc *filesystemSeparatorProc; Tcl_FSStatProc *statProc; Tcl_FSAccessProc *accessProc; Tcl_FSOpenFileChannelProc *openFileChannelProc; Tcl_FSMatchInDirectoryProc *matchInDirectoryProc; Tcl_FSUtimeProc *utimeProc; Tcl_FSLinkProc *linkProc; Tcl_FSListVolumesProc *listVolumesProc; Tcl_FSFileAttrStringsProc *fileAttrStringsProc; Tcl_FSFileAttrsGetProc *fileAttrsGetProc; Tcl_FSFileAttrsSetProc *fileAttrsSetProc; Tcl_FSCreateDirectoryProc *createDirectoryProc; Tcl_FSRemoveDirectoryProc *removeDirectoryProc; Tcl_FSDeleteFileProc *deleteFileProc; Tcl_FSCopyFileProc *copyFileProc; Tcl_FSRenameFileProc *renameFileProc; Tcl_FSCopyDirectoryProc *copyDirectoryProc; Tcl_FSLstatProc *lstatProc; Tcl_FSLoadFileProc *loadFileProc; Tcl_FSGetCwdProc *getCwdProc; Tcl_FSChdirProc *chdirProc; } Tcl_Filesystem; За исключением первых трех полей в этой структуре, которые содержат простые элементы данных, все записи содержат адреса функций, вызываемых общим слоем файловой системы для выполнения полного диапазона действий, связанных с файловой системой. Многие функции в этой структуре разбиты на три категории: функции инфраструктуры (почти все из которых должны быть реализованы), операционные функции (которые должны быть реализованы, если предоставляется полная файловая система) и функции эффективности (которые нужно реализовывать только в том случае, если они могут быть реализованы эффективно или если у них есть побочные эффекты, требуемые файловой системой; Tcl имеет менее эффективные эмуляции, на которые он может перейти). Важно отметить, что в текущей версии Tcl большинство из этих резервных копий используются только для обработки команд, инициированных в Tcl, а не в C. Это означает, что если команда переименования файла выдается в Tcl, и соответствующие файловая(ые) система(ы) не реализуют свою Tcl_FSRenameFileProc, ядро Tcl вместо этого перейдет на комбинацию других функций файловой системы (оно использует Tcl_FSCopyFileProc, за которой следует Tcl_FSDeleteFileProc, и если Tcl_FSCopyFileProc не реализовано, есть дальнейший резерв). Однако, если Tcl_FSRenameFileProc вызывается на уровне C, такие резервные копии не происходят. Это верно, за исключением последних четырех записей в таблице файловой системы (lstat, load, getcwd и chdir), для которых резервные копии на самом деле происходят на уровне C. Любые функции, которые принимают имена путей в форме Tcl_Obj, принимают эти имена в форме UTF-8. API инфраструктуры файловой системы предназначено для поддержки эффективного, кэшированного преобразования этих путей UTF-8 в другие родные представления. ИНФРАСТРУКТУРА ФАЙЛОВОЙ СИСТЕМЫ Эти поля содержат базовую информацию о структуре файловой системы и адреса функций, которые используются для ассоциации определенной файловой системы с путем файла и обработки внутренних представлений путей, например копирования и освобождения таких представлений. TYPENAME Поле typeName содержит завершенную нулем строку, которая идентифицирует тип реализованной файловой системы, например "native", "zip" или "vfs". STRUCTURE LENGTH Поле structureLength обычно реализуется как sizeof(Tcl_Filesystem) и предназначено для облегчения обратимой двоичной совместимости, если размер структуры изменится в будущей версии Tcl. VERSION Поле version должно быть установлено на TCL_FILESYSTEM_VERSION_1. PATHINFILESYSTEMPROC Поле pathInFilesystemProc содержит адрес функции, которая вызывается для определения, принадлежит ли данное значение пути этой файловой системе или нет. Tcl будет вызывать остальные функции файловой системы только с путем, для которого эта функция вернула TCL_OK. Если путь не принадлежит, должно быть возвращено -1 (поведение Tcl для любого другого возвращаемого значения не определено). Если возвращается TCL_OK, то необязательный выходной параметр clientDataPtr можно использовать для возврата внутреннего (специфичного для файловой системы) представления пути, который будет кэширован внутри значения пути и может быть получен эффективно другими функциями файловой системы. Tcl будет одновременно кэшировать тот факт, что этот путь принадлежит этой файловой системе. Такие кэши инвалидируются при добавлении или удалении структур файловых систем из внутреннего списка известных файловых систем Tcl. typedef int Tcl_FSPathInFilesystemProc( Tcl_Obj *pathPtr, ClientData *clientDataPtr); DUPINTERNALREPPROC Эта функция создает копию внутреннего представления пути и вызывается, когда Tcl нужно дублировать значение пути. Если NULL, Tcl просто не скопирует внутреннее представление, которое затем может потребовать повторной генерации позже. typedef ClientData Tcl_FSDupInternalRepProc( ClientData clientData); FREEINTERNALREPPROC Освободить внутреннее представление. Это должно быть реализовано, если внутренние представления нуждаются в освобождении (т.е. если некоторое пространство выделяется при генерации внутреннего представления), но в противном случае может быть NULL. typedef void Tcl_FSFreeInternalRepProc( ClientData clientData); INTERNALTONORMALIZEDPROC Функция для преобразования внутреннего представления в нормализованный путь. Требуется только в том случае, если файловая система создает чистые значения пути без строкового/путевого представления. Возвращаемое значение - значение Tcl, строковое представление которого - нормализованный путь. typedef Tcl_Obj *Tcl_FSInternalToNormalizedProc( ClientData clientData); CREATEINTERNALREPPROC Функция для взятия значения пути и расчета внутреннего представления для него и хранения этого родного представления в значении. Может быть NULL, если пути не имеют внутреннего представления, или если Tcl_FSPathInFilesystemProc для этой файловой системы всегда немедленно создает внутреннее представление для путей, которые она принимает. typedef ClientData Tcl_FSCreateInternalRepProc( Tcl_Obj *pathPtr); NORMALIZEPATHPROC Функция для нормализации пути. Должна быть реализована для всех файловых систем, которые могут иметь несколько строковых представлений для одного и того же значения пути. В Tcl каждый "путь" должен иметь одно уникальное "нормализованное" строковое представление. В зависимости от файловой системы может быть более одного ненормализованного строкового представления, которое относится к этому пути (например, относительный путь, путь с разным регистром символов, если файловая система нечувствительна к регистру, путь, содержащий ссылку на домашнюю директорию, такую как "~", путь, содержащий символические ссылки и т.д.). Если самый последний компонент в пути является символической ссылкой, он не должен быть преобразован в значение, на которое он указывает (но его регистр или другие аспекты должны быть сделаны уникальными). Все остальные компоненты пути должны быть преобразованы из символических ссылок. Это одно исключение требуется для согласия с семантикой Tcl с file delete, file rename, file copy, действующими на символические ссылки. Эта функция может быть вызвана с nextCheckpoint либо в начале пути (т.е. ноль), либо в конце пути, либо в любой промежуточной разделительной точке пути. Она никогда не будет указывать на любое другое произвольное положение в пути. В последнем из трех допустимых случаев реализация может предположить, что путь до и включая разделитель файла известен и нормализован. typedef int Tcl_FSNormalizePathProc( Tcl_Interp *interp, Tcl_Obj *pathPtr, int nextCheckpoint); ОПЕРАЦИИ ФАЙЛОВОЙ СИСТЕМЫ Поля в этом разделе структуры содержат адреса функций, которые вызываются для выполнения базовых операций файловой системы. Для файловой системы, которая ожидает использоваться с полным стандартным набором команд Tcl, все из них должны быть реализованы. Если некоторые из них не реализованы, то определенные команды Tcl могут не сработать при работе с путями в этой файловой системе. Однако в некоторых случаях это может быть желательно (например, файловая система только для чтения не должна реализовывать последние четыре функции, а файловая система, которая не поддерживает символические ссылки, не нуждается в реализации функции readlink и т.д. Ядро Tcl ожидает, что файловые системы будут вести себя так). FILESYSTEMPATHTYPEPROC Функция для определения типа пути в этой файловой системе. Может быть NULL, в этом случае информация о типе не будет доступна пользователям файловой системы. "Тип" используется только в информационных целях и должен быть возвращен как строковое представление Tcl_Obj, которое возвращается. Типичное возвращаемое значение может быть "networked", "zip" или "ftp". Результат Tcl_Obj принадлежит файловой системе, поэтому Tcl увеличит счетчик ссылок этого значения, если захочет сохранить ссылку на него. typedef Tcl_Obj *Tcl_FSFilesystemPathTypeProc( Tcl_Obj *pathPtr); FILESYSTEMSEPARATORPROC Функция для возврата символа(ов) разделителя для этой файловой системы. Это нужно реализовывать только в том случае, если файловая система желает использовать другой разделитель, чем стандартную строку "/". Среди прочего, она возвращается командой file separator. Возвращаемое значение должно быть значением с счетчиком ссылок ноль. typedef Tcl_Obj *Tcl_FSFilesystemSeparatorProc( Tcl_Obj *pathPtr); STATPROC Функция для обработки вызова Tcl_FSStat. Должна быть реализована для любой разумной файловой системы, поскольку многие команды Tcl критически зависят от нее (например, file atime, file isdirectory, file size, glob). typedef int Tcl_FSStatProc( Tcl_Obj *pathPtr, Tcl_StatBuf *statPtr); Tcl_FSStatProc заполняет структуру stat информацией об указанном файле. Для получения этой информации права доступа к файлу не требуются, но нужны права поиска во всех директориях, указанных в пути, ведущем к файлу. Структура stat включает информацию о устройстве, inode (всегда 0 на Windows), привилегированном режиме, nlink (всегда 1 на Windows), идентификаторе пользователя (всегда 0 на Windows), идентификаторе группы (всегда 0 на Windows), rdev (то же, что и устройство на Windows), размере, времени последнего доступа, времени последней модификации и времени последней смены метаданных. Если файл, представленный pathPtr, существует, Tcl_FSStatProc возвращает 0, и структура stat заполняется данными. В противном случае возвращается -1, и информация stat не предоставляется. ACCESSPROC Функция для обработки вызова Tcl_FSAccess. Должна быть реализована для любой разумной файловой системы, поскольку многие команды Tcl критически зависят от нее (например, file exists, file readable). typedef int Tcl_FSAccessProc( Tcl_Obj *pathPtr, int mode); Tcl_FSAccessProc проверяет, будет ли процесс разрешен для чтения, записи или проверки существования файла (или другого объекта файловой системы), имя которого находится в pathPtr. Если pathname относится к символической ссылке, то проверяются разрешения файла, на который ссылается эта символическая ссылка. При успешном выполнении (все запрошенные разрешения предоставлены) возвращается ноль. При ошибке (хотя бы один бит в mode запрашивал разрешение, которое запрещено, или возникла другая ошибка) возвращается -1. OPENFILECHANNELPROC Функция для обработки вызова Tcl_FSOpenFileChannel. Должна быть реализована для любой разумной файловой системы, поскольку любые операции, требующие открытия или доступа к содержимому файла, будут использовать её (например, open, encoding и многие команды Tk). typedef Tcl_Channel Tcl_FSOpenFileChannelProc( Tcl_Interp *interp, Tcl_Obj *pathPtr, int mode, int permissions); Tcl_FSOpenFileChannelProc открывает файл, указанный pathPtr, и возвращает дескриптор канала, который можно использовать для ввода и вывода в файл. Этот API моделируется по процедуре fopen стандартной библиотеки ввода/вывода Unix. Синтаксис и значение всех аргументов аналогичны тем, что дано в команде Tcl open при открытии файла, где аргумент mode - комбинация флагов POSIX O_RDONLY, O_WRONLY и т.д. Если возникает ошибка при открытии канала, Tcl_FSOpenFileChannelProc возвращает NULL и фиксирует код POSIX-ошибки, который можно получить с помощью Tcl_GetErrno. Кроме того, если interp не NULL, Tcl_FSOpenFileChannelProc оставляет сообщение об ошибке в результате interp после любой ошибки. Только что созданный канал не должен регистрироваться в предоставленном интерпретаторе Tcl_FSOpenFileChannelProc; это задача вызывающего (если необходимо). Если один из стандартных каналов, stdin, stdout или stderr, был ранее закрыт, действие по созданию нового канала также назначает его в качестве замены стандартного канала. MATCHINDIRECTORYPROC Функция для обработки вызова Tcl_FSMatchInDirectory. Если не реализована, то функциональность glob и рекурсивного копирования будет отсутствовать в файловой системе (и это может повлиять на команды, такие как encoding names, которые используют функциональность glob внутренне). typedef int Tcl_FSMatchInDirectoryProc( Tcl_Interp *interp, Tcl_Obj *resultPtr, Tcl_Obj *pathPtr, const char *pattern, Tcl_GlobTypeData *types); Функция должна возвращать все файлы или директории (или другие объекты файловой системы), которые соответствуют данному шаблону и соответствуют указанной спецификации типов. Есть два способа, в которых эта функция может быть вызвана. Если pattern равно NULL, то pathPtr - полное спецификация пути для одного файла или директории, которая должна быть проверена на существование и правильный тип. В противном случае pathPtr - директория, содержимое которой функция должна искать для файлов или директорий, которые имеют правильный тип. В любом случае pathPtr можно считать как непустым и не NULL. В настоящее время не задокументировано, будет ли pathPtr иметь разделитель файла в конце или нет, так что код должен быть гибким для обоих возможностей. Возвращаемое значение - стандартный результат Tcl, указывающий, возникла ли ошибка в процессе сопоставления. Сообщения об ошибках размещаются в interp, если interp не NULL (что разрешено), в противном случае сообщение об ошибке не нужно генерировать; при результате TCL_OK результаты должны быть добавлены к данному значению resultPtr (которое можно считать допустимым неспециализированным списком Tcl). Соответствия, добавленные к resultPtr, должны включать любой префикс пути, данный в pathPtr (это обычно означает, что они будут абсолютными спецификациями пути). Обратите внимание, что если совпадений не найдено, это просто приводит к пустому результату; ошибки сигнализируются только для реальных проблем с файлами или файловой системой, которые могут возникнуть во время процесса сопоставления. Структура Tcl_GlobTypeData, переданная в параметре types, содержит следующие поля: typedef struct Tcl_GlobTypeData { /* Соответствует bcdpfls как в 'find -t' */ int type; /* Соответствует разрешениям файла */ int perm; /* Допустимый тип mac */ Tcl_Obj *macType; /* Допустимый создатель mac */ Tcl_Obj *macCreator; } Tcl_GlobTypeData; Есть два конкретных случая, которые важно правильно обработать, оба, когда types не NULL. Два случая - когда types->types & TCL_GLOB_TYPE_DIR или types->types & TCL_GLOB_TYPE_MOUNT истинны (и в частности, когда другие флаги ложны). В первом из этих случаев функция должна перечислить содержащиеся директории. Tcl использует это для реализации рекурсивного globbing, так что критически важно, чтобы файловые системы правильно реализовывали сопоставление директорий. Во втором из этих случаев, с TCL_GLOB_TYPE_MOUNT, файловая система должна перечислить точки монтирования, которые лежат внутри данного pathPtr (и в этом случае pathPtr не обязательно лежит в той же файловой системе - в отличие от всех других случаев, в которых эта функция вызывается). Поддержка этого критически важна, чтобы Tcl мог иметь бесшовные переходы от одной файловой системы к другой. UTIMEPROC Функция для обработки вызова Tcl_FSUtime. Требуется для установки (но не чтения) времен с помощью file mtime, file atime и реализации open-r/open-w/fcopy команды file copy. typedef int Tcl_FSUtimeProc( Tcl_Obj *pathPtr, struct utimbuf *tval); Времена доступа и модификации файла, указанного pathPtr, должны быть изменены на значения, данные в структуре tval. Возвращаемое значение должно быть 0 при успешном выполнении и -1 при ошибке, как в системной utime. LINKPROC Функция для обработки вызова Tcl_FSLink. Должна быть реализована только в том случае, если файловая система поддерживает ссылки, и в противном случае может быть NULL. typedef Tcl_Obj *Tcl_FSLinkProc( Tcl_Obj *linkNamePtr, Tcl_Obj *toPtr, int linkAction); Если toPtr равно NULL, функция запрашивается для чтения содержимого ссылки. Результат - Tcl_Obj, указывающий содержимое символической ссылки, данной linkNamePtr, или NULL, если ссылку не удалось прочитать. Результат принадлежит вызывающему, который должен вызвать Tcl_DecrRefCount, когда результат больше не нужен. Если toPtr не NULL, функция должна попытаться создать ссылку. Результат в этом случае должен быть toPtr, если ссылка успешна, и NULL в противном случае. В этом случае результат не принадлежит вызывающему (т.е. манипуляции счетчиком ссылок с обеих сторон не нужны). См. документацию для Tcl_FSLink для правильной интерпретации флагов linkAction. LISTVOLUMESPROC Функция для перечисления любых томов файловой системы, добавленных этой файловой системой. Должна быть реализована только в том случае, если файловая система добавляет тома в начале файловой системы, чтобы их можно было возвращать командой file volumes. typedef Tcl_Obj *Tcl_FSListVolumesProc(void); Результат должен быть списком томов, добавленных этой файловой системой, или NULL (или пустым списком), если тома не предоставляются. Значение результата считается принадлежащим файловой системе (не ядру Tcl), но должно быть дано счетчик ссылок для Tcl. Tcl использует содержимое списка, а затем уменьшит этот счетчик ссылок. Это позволяет файловым системам выбрать, хотят ли они на самом деле сохранить "глобальный список" томов или нет (если нет, они генерируют список на лету и передают его Tcl с счетчиком ссылок 1, а затем забывают о списке, если да, то они просто увеличивают счетчик ссылок своего глобального списка и передают его Tcl, который скопирует содержимое, а затем уменьшит счетчик назад до того, что он был). Следовательно, Tcl считает возвращаемые значения из этой процедуры только для чтения. FILEATTRSTRINGSPROC Функция для перечисления всех строк атрибутов, которые действительны для этой файловой системы. Если не реализована, файловая система не будет поддерживать команду file attributes. Это позволяет прикрепить произвольную дополнительную информацию к файлам в файловой системе. Если это не реализовано, нет необходимости реализовывать методы получения и установки. typedef const char *const *Tcl_FSFileAttrStringsProc( Tcl_Obj *pathPtr, Tcl_Obj **objPtrRef); Вызванная функция может либо вернуть массив строк, либо вместо этого вернуть NULL и поместить список Tcl в данный objPtrRef. Tcl возьмет этот список и сначала увеличит его счетчик ссылок перед использованием. По завершении этого использования Tcl уменьшит его счетчик ссылок. FILEATTRSGETPROC Функция для обработки вызова Tcl_FSFileAttrsGet, используемого file attributes. typedef int Tcl_FSFileAttrsGetProc( Tcl_Interp *interp, int index, Tcl_Obj *pathPtr, Tcl_Obj **objPtrRef); Возвращает стандартный код возврата Tcl. Полученное значение атрибута, которое соответствует index'ному элементу в списке, возвращенном Tcl_FSFileAttrStringsProc, - Tcl_Obj, размещенное в objPtrRef (если возвращается TCL_OK) и, вероятно, имеет счетчик ссылок ноль. В любом случае мы должны либо хранить его где-то (например, в результате Tcl), либо Incr/Decr его счетчик ссылок, чтобы обеспечить правильное освобождение. FILEATTRSSETPROC Функция для обработки вызова Tcl_FSFileAttrsSet, используемого file attributes. Если файловая система только для чтения, нет необходимости реализовывать это. typedef int Tcl_FSFileAttrsSetProc( Tcl_Interp *interp, int index, Tcl_Obj *pathPtr, Tcl_Obj *objPtr); Значение атрибута index'ного элемента в списке, возвращенном Tcl_FSFileAttrStringsProc, должно быть установлено на данное objPtr. CREATEDIRECTORYPROC Функция для обработки вызова Tcl_FSCreateDirectory. Должна быть реализована, если FS только для чтения. typedef int Tcl_FSCreateDirectoryProc( Tcl_Obj *pathPtr); Возвращаемое значение - стандартный результат Tcl, указывающий, возникла ли ошибка в процессе. При успешном выполнении новая директория должна быть добавлена в файловую систему в месте, указанном pathPtr. REMOVEDIRECTORYPROC Функция для обработки вызова Tcl_FSRemoveDirectory. Должна быть реализована, если FS только для чтения. typedef int Tcl_FSRemoveDirectoryProc( Tcl_Obj *pathPtr, int recursive, Tcl_Obj **errorPtr); Возвращаемое значение - стандартный результат Tcl, указывающий, возникла ли ошибка в процессе. При успешном выполнении директория, указанная pathPtr, должна быть удалена из файловой системы. Если флаг recursive указан, то непустая директория должна быть удалена без ошибки. Если этот флаг не указан, то и директория непустая, должна сигнализироваться ошибка POSIX "EEXIST". Если возникает ошибка, имя файла или директории, которая вызвала ошибку, должно быть размещено в errorPtr. DELETEFILEPROC Функция для обработки вызова Tcl_FSDeleteFile. Должна быть реализована, если FS только для чтения. typedef int Tcl_FSDeleteFileProc( Tcl_Obj *pathPtr); Возвращаемое значение - стандартный результат Tcl, указывающий, возникла ли ошибка в процессе. При успешном выполнении файл, указанный pathPtr, должен быть удален из файловой системы. Обратите внимание, что, если файловая система поддерживает символические ссылки, Tcl всегда будет вызывать эту функцию и не Tcl_FSRemoveDirectoryProc при необходимости удалить их (даже если они являются символическими ссылками на директории). ЭФФЕКТИВНОСТЬ ФАЙЛОВОЙ СИСТЕМЫ Эти функции необязательны для реализации для конкретной файловой системы, потому что ядро имеет доступную резервную реализацию. См. каждое индивидуальное описание для последствий оставления поля NULL. LSTATPROC Функция для обработки вызова Tcl_FSLstat. Если не реализовано, Tcl попытается использовать statProc, определенную выше. Следовательно, ее нужно реализовывать только в том случае, если файловая система может различать вызовы stat и lstat. typedef int Tcl_FSLstatProc( Tcl_Obj *pathPtr, Tcl_StatBuf *statPtr); Поведение этой функции очень похоже на то, что определено для Tcl_FSStatProc выше, за исключением того, что если она применяется к символической ссылке, она возвращает информацию о ссылке, а не о целевом файле. COPYFILEPROC Функция для обработки вызова Tcl_FSCopyFile. Если не реализовано, Tcl перейдет на open-r, open-w и fcopy как механизм копирования. Следовательно, ее нужно реализовывать только в том случае, если файловая система может выполнить это действие более эффективно. typedef int Tcl_FSCopyFileProc( Tcl_Obj *srcPathPtr, Tcl_Obj *destPathPtr); Возвращаемое значение - стандартный результат Tcl, указывающий, возникла ли ошибка в процессе копирования. Обратите внимание, что destPathPtr - имя файла, который должен стать копией srcPathPtr. Это никогда не имя директории, в которую srcPathPtr может быть скопировано (т.е. функция гораздо проще, чем подкоманда копирования файла на уровне Tcl). Обратите внимание, что, если файловая система поддерживает символические ссылки, Tcl всегда будет вызывать эту функцию и не copyDirectoryProc при необходимости копировать их (даже если они являются символическими ссылками на директории). Наконец, если файловая система определяет, что не может поддерживать действие копирования файла, вызов Tcl_SetErrno(EXDEV) и возврат не-TCL_OK результата скажет Tcl использовать свои стандартные резервные механизмы. RENAMEFILEPROC Функция для обработки вызова Tcl_FSRenameFile. Если не реализовано, Tcl перейдет на механизм копирования и удаления. Следовательно, ее нужно реализовывать только в том случае, если файловая система может выполнить это действие более эффективно. typedef int Tcl_FSRenameFileProc( Tcl_Obj *srcPathPtr, Tcl_Obj *destPathPtr); Возвращаемое значение - стандартный результат Tcl, указывающий, возникла ли ошибка в процессе переименования. Если файловая система определяет, что не может поддерживать действие переименования файла, вызов Tcl_SetErrno(EXDEV) и возврат не-TCL_OK результата скажет Tcl использовать свои стандартные резервные механизмы. COPYDIRECTORYPROC Функция для обработки вызова Tcl_FSCopyDirectory. Если не реализовано, Tcl перейдет на рекурсивный механизм mkdir, file copy. Следовательно, ее нужно реализовывать только в том случае, если файловая система может выполнить это действие более эффективно. typedef int Tcl_FSCopyDirectoryProc( Tcl_Obj *srcPathPtr, Tcl_Obj *destPathPtr, Tcl_Obj **errorPtr); Возвращаемое значение - стандартный результат Tcl, указывающий, возникла ли ошибка в процессе копирования. Если возникает ошибка, имя файла или директории, которая вызвала ошибку, должно быть размещено в errorPtr. Обратите внимание, что destPathPtr - имя имени директории, которая должна стать зеркальным отображением srcPathPtr. Это не имя директории, в которую srcPathPtr должен быть скопировано (т.е. функция гораздо проще, чем подкоманда копирования файла на уровне Tcl). Наконец, если файловая система определяет, что не может поддерживать действие копирования директории, вызов Tcl_SetErrno(EXDEV) и возврат не-TCL_OK результата скажет Tcl использовать свои стандартные резервные механизмы. LOADFILEPROC Функция для обработки вызова Tcl_FSLoadFile. Если не реализовано, Tcl перейдет на копирование в родной-temp, за которым следует Tcl_FSLoadFile на этой временной копии. Следовательно, ее нужно реализовывать только в том случае, если файловая система может загружать код напрямую или ее можно реализовать просто для возврата TCL_ERROR, чтобы отключить функциональность загрузки в этой файловой системе полностью. typedef int Tcl_FSLoadFileProc( Tcl_Interp *interp, Tcl_Obj *pathPtr, Tcl_LoadHandle *handlePtr, Tcl_FSUnloadFileProc *unloadProcPtr); Возвращает стандартный код завершения Tcl. Если возникает ошибка, сообщение об ошибке оставляется в результате интерпретатора. Функция динамически загружает файл двоичного кода в память. При успешной загрузке handlePtr должно быть заполнено токеном для динамически загруженного файла, а unloadProcPtr должно быть заполнено адресом процедуры. Процедура выгрузки будет вызвана с данным Tcl_LoadHandle в качестве своего единственного параметра, когда Tcl нужно выгрузить файл. Например, для родной файловой системы, Tcl_LoadHandle, возвращаемый в настоящее время, является токеном, который можно использовать в частной TclpFindSymbol для доступа к функциям в новом коде. Каждая файловая система свободна определять Tcl_LoadHandle так, как ей требуется. Наконец, если файловая система определяет, что не может поддерживать действие загрузки файла, вызов Tcl_SetErrno(EXDEV) и возврат не-TCL_OK результата скажет Tcl использовать свои стандартные резервные механизмы. UNLOADFILEPROC Функция для выгрузки ранее успешно загруженного файла. Если load был реализован, то это также должно быть реализовано, если требуется какое-либо действие очистки. typedef void Tcl_FSUnloadFileProc( Tcl_LoadHandle loadHandle); GETCWDPROC Функция для обработки вызова Tcl_FSGetCwd. Большинству файловых систем не нужно реализовывать это. Она обычно будет вызвана только один раз, если getcwd вызывается перед chdir. Может быть NULL. typedef Tcl_Obj *Tcl_FSGetCwdProc( Tcl_Interp *interp); Если файловая система поддерживает родное понятие текущей рабочей директории (которая может измениться независимо от Tcl), эта функция должна возвращать эту cwd как результат, или NULL, если текущая директория не может быть определена (например, пользователь не имеет подходящих разрешений на директорию cwd). Если возвращается NULL, сообщение об ошибке оставляется в результате interp. CHDIRPROC Функция для обработки вызова Tcl_FSChdir. Если файловые системы не реализуют это, оно будет эмулировано серией проверок доступа к директориям. В противном случае виртуальные файловые системы, которые реализуют это, должны только ответить положительным результатом, если pathPtr - допустимая, доступная директория в их файловой системе. Им не нужно помнить результат, поскольку он будет автоматически запомнен для использования Tcl_FSGetCwd. Реальные файловые системы должны выполнить правильное действие (т.е. вызвать правильный системный API chdir). typedef int Tcl_FSChdirProc( Tcl_Obj *pathPtr); Tcl_FSChdirProc изменяет текущую рабочую директорию приложения на значение, указанное в pathPtr. Функция возвращает -1 при ошибке или 0 при успешном выполнении. SEE ALSO cd(n), file(n), filename(n), load(n), open(n), pwd(n), source(n), unload(n) KEYWORDS stat, access, filesystem, vfs, virtual filesystem
Filesystem(3) Tcl Library Procedures Filesystem(3) ______________________________________________________________________________ NAME Tcl_FSRegister, Tcl_FSUnregister, Tcl_FSData, Tcl_FSMountsChanged, Tcl_FSGetFileSystemForPath, Tcl_FSGetPathType, Tcl_FSCopyFile, Tcl_FS‐ CopyDirectory, Tcl_FSCreateDirectory, Tcl_FSDeleteFile, Tcl_FSRemoveDi‐ rectory, Tcl_FSRenameFile, Tcl_FSListVolumes, Tcl_FSEvalFile, Tcl_FSE‐ valFileEx, Tcl_FSLoadFile, Tcl_FSUnloadFile, Tcl_FSMatchInDirectory, Tcl_FSLink, Tcl_FSLstat, Tcl_FSUtime, Tcl_FSFileAttrsGet, Tcl_FSFileAt‐ trsSet, Tcl_FSFileAttrStrings, Tcl_FSStat, Tcl_FSAccess, Tcl_FSOpen‐ FileChannel, Tcl_FSGetCwd, Tcl_FSChdir, Tcl_FSPathSeparator, Tcl_FSJoinPath, Tcl_FSSplitPath, Tcl_FSEqualPaths, Tcl_FSGetNormalized‐ Path, Tcl_FSJoinToPath, Tcl_FSConvertToPathType, Tcl_FSGetInternalRep, Tcl_FSGetTranslatedPath, Tcl_FSGetTranslatedStringPath, Tcl_FSNewNa‐ tivePath, Tcl_FSGetNativePath, Tcl_FSFileSystemInfo, Tcl_GetAccessTime‐ FromStat, Tcl_GetBlockSizeFromStat, Tcl_GetBlocksFromStat, Tcl_GetChangeTimeFromStat, Tcl_GetDeviceTypeFromStat, Tcl_GetFSDevice‐ FromStat, Tcl_GetFSInodeFromStat, Tcl_GetGroupIdFromStat, Tcl_GetLinkCountFromStat, Tcl_GetModeFromStat, Tcl_GetModificationTime‐ FromStat, Tcl_GetSizeFromStat, Tcl_GetUserIdFromStat, Tcl_AllocStatBuf - procedures to interact with any filesystem SYNOPSIS #include <tcl.h> int Tcl_FSRegister(clientData, fsPtr) int Tcl_FSUnregister(fsPtr) void * Tcl_FSData(fsPtr) Tcl_FSMountsChanged(fsPtr) const Tcl_Filesystem * Tcl_FSGetFileSystemForPath(pathPtr) Tcl_PathType Tcl_FSGetPathType(pathPtr) int Tcl_FSCopyFile(srcPathPtr, destPathPtr) int Tcl_FSCopyDirectory(srcPathPtr, destPathPtr, errorPtr) int Tcl_FSCreateDirectory(pathPtr) int Tcl_FSDeleteFile(pathPtr) int Tcl_FSRemoveDirectory(pathPtr, recursive, errorPtr) int Tcl_FSRenameFile(srcPathPtr, destPathPtr) Tcl_Obj * Tcl_FSListVolumes(void) int Tcl_FSEvalFileEx(interp, pathPtr, encodingName) int Tcl_FSEvalFile(interp, pathPtr) int Tcl_FSLoadFile(interp, pathPtr, sym1, sym2, proc1Ptr, proc2Ptr, loadHandlePtr, unloadProcPtr) int │ Tcl_FSUnloadFile(interp, loadHandle) │ int Tcl_FSMatchInDirectory(interp, resultPtr, pathPtr, pattern, types) Tcl_Obj * Tcl_FSLink(linkNamePtr, toPtr, linkAction) int Tcl_FSLstat(pathPtr, statPtr) int Tcl_FSUtime(pathPtr, tval) int Tcl_FSFileAttrsGet(interp, index, pathPtr, objPtrRef) int Tcl_FSFileAttrsSet(interp, index, pathPtr, objPtr) const char *const * Tcl_FSFileAttrStrings(pathPtr, objPtrRef) int Tcl_FSStat(pathPtr, statPtr) int Tcl_FSAccess(pathPtr, mode) Tcl_Channel Tcl_FSOpenFileChannel(interp, pathPtr, modeString, permissions) Tcl_Obj * Tcl_FSGetCwd(interp) int Tcl_FSChdir(pathPtr) Tcl_Obj * Tcl_FSPathSeparator(pathPtr) Tcl_Obj * Tcl_FSJoinPath(listObj, elements) Tcl_Obj * Tcl_FSSplitPath(pathPtr, lenPtr) int Tcl_FSEqualPaths(firstPtr, secondPtr) Tcl_Obj * Tcl_FSGetNormalizedPath(interp, pathPtr) Tcl_Obj * Tcl_FSJoinToPath(basePtr, objc, objv) int Tcl_FSConvertToPathType(interp, pathPtr) void * Tcl_FSGetInternalRep(pathPtr, fsPtr) Tcl_Obj * Tcl_FSGetTranslatedPath(interp, pathPtr) const char * Tcl_FSGetTranslatedStringPath(interp, pathPtr) Tcl_Obj * Tcl_FSNewNativePath(fsPtr, clientData) const void * Tcl_FSGetNativePath(pathPtr) Tcl_Obj * Tcl_FSFileSystemInfo(pathPtr) Tcl_StatBuf * Tcl_AllocStatBuf() Tcl_WideInt │ Tcl_GetAccessTimeFromStat(statPtr) │ unsigned │ Tcl_GetBlockSizeFromStat(statPtr) │ Tcl_WideUInt │ Tcl_GetBlocksFromStat(statPtr) │ Tcl_WideInt │ Tcl_GetChangeTimeFromStat(statPtr) │ int │ Tcl_GetDeviceTypeFromStat(statPtr) │ unsigned │ Tcl_GetFSDeviceFromStat(statPtr) │ unsigned │ Tcl_GetFSInodeFromStat(statPtr) │ int │ Tcl_GetGroupIdFromStat(statPtr) │ int │ Tcl_GetLinkCountFromStat(statPtr) │ unsigned │ Tcl_GetModeFromStat(statPtr) │ Tcl_WideInt │ Tcl_GetModificationTimeFromStat(statPtr) │ Tcl_WideUInt │ Tcl_GetSizeFromStat(statPtr) │ int │ Tcl_GetUserIdFromStat(statPtr) │ ARGUMENTS const Tcl_Filesystem *fsPtr (in) Points to a structure con‐ taining the addresses of procedures that can be called to perform the vari‐ ous filesystem operations. Tcl_Obj *pathPtr (in) The path represented by this value is used for the operation in question. If the value does not already have an internal path rep‐ resentation, it will be converted to have one. Tcl_Obj *srcPathPtr (in) As for pathPtr, but used for the source file for a copy or rename operation. Tcl_Obj *destPathPtr (in) As for pathPtr, but used for the destination file‐ name for a copy or rename operation. int recursive (in) Whether to remove subdirec‐ tories and their contents as well. const char *encodingName (in) The encoding of the data stored in the file identi‐ fied by pathPtr and to be evaluated. const char *pattern (in) Only files or directories matching this pattern will be returned. Tcl_GlobTypeData *types (in) Only files or directories matching the type descrip‐ tions contained in this structure will be returned. This parameter may be NULL. Tcl_Interp *interp (in) Interpreter to use either for results, evaluation, or reporting error messages. void *clientData (in) The native description of the path value to create. Tcl_Obj *firstPtr (in) The first of two path val‐ ues to compare. The value may be converted to path type. Tcl_Obj *secondPtr (in) The second of two path val‐ ues to compare. The value may be converted to path type. Tcl_Obj *listObj (in) The list of path elements to operate on with a join operation. int elements (in) The number of elements in the listObj which should be joined together. If nega‐ tive, then all elements are joined. Tcl_Obj **errorPtr (out) In the case of an error, filled with a value con‐ taining the name of the file which caused an error in the various copy/rename operations. int index (in) The index of the attribute in question. Tcl_Obj *objPtr (in) The value to set in the op‐ eration. Tcl_Obj **objPtrRef (out) Filled with a value con‐ taining the result of the operation. Tcl_Obj *resultPtr (out) Preallocated value in which to store (using Tcl_ListOb‐ jAppendElement) the list of files or directories which are successfully matched. int mode (in) Mask consisting of one or more of R_OK, W_OK, X_OK and F_OK. R_OK, W_OK and X_OK request checking whether the file exists and has read, write and exe‐ cute permissions, respec‐ tively. F_OK just requests checking for the existence of the file. Tcl_StatBuf *statPtr (out) The structure that contains the result of a stat or lstat operation. const char *sym1 (in) Name of a procedure to look up in the file's symbol ta‐ ble const char *sym2 (in) Name of a procedure to look up in the file's symbol ta‐ ble Tcl_PackageInitProc **proc1Ptr (out) Filled with the init func‐ tion for this code. Tcl_PackageInitProc **proc2Ptr (out) Filled with the safe-init function for this code. void **clientDataPtr (out) Filled with the clientData value to pass to this code's unload function when it is called. Tcl_LoadHandle *loadHandlePtr (out) Filled with an abstract to‐ ken representing the loaded file. Tcl_FSUnloadFileProc **unloadProcPtr (out) Filled with the function to use to unload this piece of code. Tcl_LoadHandle loadHandle (in) Handle to the loaded li‐ brary to be unloaded. utimbuf *tval (in) The access and modification times in this structure are read and used to set those values for a given file. const char *modeString (in) Specifies how the file is to be accessed. May have any of the values allowed for the mode argument to the Tcl open command. int permissions (in) POSIX-style permission flags such as 0644. If a new file is created, these permissions will be set on the created file. int *lenPtr (out) If non-NULL, filled with the number of elements in the split path. Tcl_Obj *basePtr (in) The base path on to which to join the given elements. May be NULL. int objc (in) The number of elements in objv. Tcl_Obj *const objv[] (in) The elements to join to the given base path. Tcl_Obj *linkNamePtr (in) The name of the link to be created or read. Tcl_Obj *toPtr (in) What the link called linkNamePtr should be linked to, or NULL if the symbolic link specified by linkNamePtr is to be read. int linkAction (in) OR-ed combination of flags indicating what kind of link should be created (will be ignored if toPtr is NULL). Valid bits to set are TCL_CREATE_SYM‐ BOLIC_LINK and TCL_CRE‐ ATE_HARD_LINK. When both flags are set and the un‐ derlying filesystem can do either, symbolic links are preferred. ______________________________________________________________________________ DESCRIPTION There are several reasons for calling the Tcl_FS API functions (e.g. Tcl_FSAccess and Tcl_FSStat) rather than calling system level functions like access and stat directly. First, they will work cross- platform, so an extension which calls them should work unmodified on Unix and Windows. Second, the Windows implementation of some of these functions fixes some bugs in the system level calls. Third, these func‐ tion calls deal with any “Utf to platform-native” path conversions which may be required (and may cache the results of such conversions for greater efficiency on subsequent calls). Fourth, and perhaps most importantly, all of these functions are “virtual filesystem aware”. Any virtual filesystem (VFS for short) which has been registered (through Tcl_FSRegister) may reroute file access to alternative media or access methods. This means that all of these functions (and there‐ fore the corresponding file, glob, pwd, cd, open, etc. Tcl commands) may be operate on “files” which are not native files in the native filesystem. This also means that any Tcl extension which accesses the filesystem (FS for short) through this API is automatically “virtual filesystem aware”. Of course, if an extension accesses the native filesystem directly (through platform-specific APIs, for example), then Tcl cannot intercept such calls. If appropriate VFSes have been registered, the “files” may, to give two examples, be remote (e.g. situated on a remote ftp server) or archived (e.g. lying inside a .zip archive). Such registered filesystems provide a lookup table of functions to implement all or some of the functional‐ ity listed here. Finally, the Tcl_FSStat and Tcl_FSLstat calls abstract away from what the “struct stat” buffer is actually declared to be, al‐ lowing the same code to be used both on systems with and systems with‐ out support for files larger than 2GB in size. The Tcl_FS API is Tcl_Obj-ified and may cache internal representations and other path-related strings (e.g. the current working directory). One side-effect of this is that one must not pass in values with a ref‐ erence count of zero to any of these functions. If such calls were han‐ dled, they might result in memory leaks (under some circumstances, the filesystem code may wish to retain a reference to the passed in value, and so one must not assume that after any of these calls return, the value still has a reference count of zero - it may have been incre‐ mented) or in a direct segmentation fault (or other memory access er‐ ror) due to the value being freed part way through the complex value manipulation required to ensure that the path is fully normalized and absolute for filesystem determination. The practical lesson to learn from this is that Tcl_Obj *path = Tcl_NewStringObj(...); Tcl_FSWhatever(path); Tcl_DecrRefCount(path); is wrong, and may cause memory errors. The path must have its reference count incremented before passing it in, or decrementing it. For this reason, values with a reference count of zero are considered not to be valid filesystem paths and calling any Tcl_FS API function with such a value will result in no action being taken. FS API FUNCTIONS Tcl_FSCopyFile attempts to copy the file given by srcPathPtr to the path name given by destPathPtr. If the two paths given lie in the same filesystem (according to Tcl_FSGetFileSystemForPath) then that filesys‐ tem's “copy file” function is called (if it is non-NULL). Otherwise the function returns -1 and sets the errno global C variable to the “EXDEV” POSIX error code (which signifies a “cross-domain link”). Tcl_FSCopyDirectory attempts to copy the directory given by srcPathPtr to the path name given by destPathPtr. If the two paths given lie in the same filesystem (according to Tcl_FSGetFileSystemForPath) then that filesystem's “copy file” function is called (if it is non-NULL). Oth‐ erwise the function returns -1 and sets the errno global C variable to the “EXDEV” POSIX error code (which signifies a “cross-domain link”). Tcl_FSCreateDirectory attempts to create the directory given by pathPtr by calling the owning filesystem's “create directory” function. Tcl_FSDeleteFile attempts to delete the file given by pathPtr by call‐ ing the owning filesystem's “delete file” function. Tcl_FSRemoveDirectory attempts to remove the directory given by pathPtr by calling the owning filesystem's “remove directory” function. Tcl_FSRenameFile attempts to rename the file or directory given by src‐ PathPtr to the path name given by destPathPtr. If the two paths given lie in the same filesystem (according to Tcl_FSGetFileSystemForPath) then that filesystem's “rename file” function is called (if it is non- NULL). Otherwise the function returns -1 and sets the errno global C variable to the “EXDEV” POSIX error code (which signifies a “cross-do‐ main link”). Tcl_FSListVolumes calls each filesystem which has a non-NULL “list vol‐ umes” function and asks them to return their list of root volumes. It accumulates the return values in a list which is returned to the caller (with a reference count of 0). Tcl_FSEvalFileEx reads the file given by pathPtr using the encoding identified by encodingName and evaluates its contents as a Tcl script. It returns the same information as Tcl_EvalObjEx. If encodingName is NULL, the system encoding is used for reading the file contents. If the file could not be read then a Tcl error is returned to describe why the file could not be read. The eofchar for files is “\x1A” (^Z) for all platforms. If you require a “^Z” in code for string comparison, you can use “\x1A”, which will be safely substituted by the Tcl inter‐ preter into “^Z”. Tcl_FSEvalFile is a simpler version of Tcl_FSEval‐ FileEx that always uses the system encoding when reading the file. Tcl_FSLoadFile dynamically loads a binary code file into memory and re‐ turns the addresses of two procedures within that file, if they are de‐ fined. The appropriate function for the filesystem to which pathPtr be‐ longs will be called. If that filesystem does not implement this func‐ tion (most virtual filesystems will not, because of OS limitations in dynamically loading binary code), Tcl will attempt to copy the file to a temporary directory and load that temporary file. Tcl_FSUnloadFile │ reverses the operation, asking for the library indicated by the load‐ │ Handle to be removed from the process. Note that, unlike with the un‐ │ load command, this does not give the library any opportunity to clean │ up. Both the above functions return a standard Tcl completion code. If an error occurs, an error message is left in the interp's result. The token provided via the variable indicated by loadHandlePtr may be │ used with Tcl_FindSymbol. Tcl_FSMatchInDirectory is used by the globbing code to search a direc‐ tory for all files which match a given pattern. The appropriate func‐ tion for the filesystem to which pathPtr belongs will be called. The return value is a standard Tcl result indicating whether an error occurred in globbing. Error messages are placed in interp (unless in‐ terp is NULL, which is allowed), but good results are placed in the re‐ sultPtr given. Note that the glob code implements recursive patterns internally, so this function will only ever be passed simple patterns, which can be matched using the logic of string match. To handle recursion, Tcl will call this function frequently asking only for directories to be re‐ turned. A special case of being called with a NULL pattern indicates that the path needs to be checked only for the correct type. Tcl_FSLink replaces the library version of readlink, and extends it to support the creation of links. The appropriate function for the filesystem to which linkNamePtr belongs will be called. If the toPtr is NULL, a “read link” action is performed. The result is a Tcl_Obj specifying the contents of the symbolic link given by linkNamePtr, or NULL if the link could not be read. The result is owned by the caller, which should call Tcl_DecrRefCount when the result is no longer needed. If the toPtr is not NULL, Tcl should create a link of one of the types passed in in the linkAction flag. This flag is an OR'ed combination of TCL_CREATE_SYMBOLIC_LINK and TCL_CREATE_HARD_LINK. Where a choice exists (i.e. more than one flag is passed in), the Tcl convention is to prefer symbolic links. When a link is successfully created, the return value should be toPtr (which is therefore already owned by the caller). If unsuccessful, NULL is returned. Tcl_FSLstat fills the Tcl_StatBuf structure statPtr with information about the specified file. You do not need any access rights to the file to get this information but you need search rights to all directories named in the path leading to the file. The Tcl_StatBuf structure in‐ cludes info regarding device, inode (always 0 on Windows), privilege mode, nlink (always 1 on Windows), user id (always 0 on Windows), group id (always 0 on Windows), rdev (same as device on Windows), size, last access time, last modification time, and last metadata change time. See PORTABLE STAT RESULT API for a description of how to write portable code to allocate and access the Tcl_StatBuf structure. If path exists, Tcl_FSLstat returns 0 and the stat structure is filled with data. Otherwise, -1 is returned, and no stat info is given. Tcl_FSUtime replaces the library version of utime. This returns 0 on success and -1 on error (as per the utime documenta‐ tion). If successful, the function will update the “atime” and “mtime” values of the file given. Tcl_FSFileAttrsGet implements read access for the hookable file at‐ tributes subcommand. The appropriate function for the filesystem to which pathPtr belongs will be called. If the result is TCL_OK, then a value was placed in objPtrRef, which will only be temporarily valid (unless Tcl_IncrRefCount is called). Tcl_FSFileAttrsSet implements write access for the hookable file at‐ tributes subcommand. The appropriate function for the filesystem to which pathPtr belongs will be called. Tcl_FSFileAttrStrings implements part of the hookable file attributes subcommand. The appropriate function for the filesystem to which path‐ Ptr belongs will be called. The called procedure may either return an array of strings, or may in‐ stead return NULL and place a Tcl list into the given objPtrRef. Tcl will take that list and first increment its reference count before us‐ ing it. On completion of that use, Tcl will decrement its reference count. Hence if the list should be disposed of by Tcl when done, it should have a reference count of zero, and if the list should not be disposed of, the filesystem should ensure it retains a reference count to the value. Tcl_FSAccess checks whether the process would be allowed to read, write or test for existence of the file (or other filesystem object) whose name is pathname. If pathname is a symbolic link on Unix, then permis‐ sions of the file referred by this symbolic link are tested. On success (all requested permissions granted), zero is returned. On error (at least one bit in mode asked for a permission that is denied, or some other error occurred), -1 is returned. Tcl_FSStat fills the Tcl_StatBuf structure statPtr with information about the specified file. You do not need any access rights to the file to get this information but you need search rights to all directories named in the path leading to the file. The Tcl_StatBuf structure in‐ cludes info regarding device, inode (always 0 on Windows), privilege mode, nlink (always 1 on Windows), user id (always 0 on Windows), group id (always 0 on Windows), rdev (same as device on Windows), size, last access time, last modification time, and last metadata change time. See PORTABLE STAT RESULT API for a description of how to write portable code to allocate and access the Tcl_StatBuf structure. If path exists, Tcl_FSStat returns 0 and the stat structure is filled with data. Otherwise, -1 is returned, and no stat info is given. Tcl_FSOpenFileChannel opens a file specified by pathPtr and returns a channel handle that can be used to perform input and output on the file. This API is modeled after the fopen procedure of the Unix stan‐ dard I/O library. The syntax and meaning of all arguments is similar to those given in the Tcl open command when opening a file. If an er‐ ror occurs while opening the channel, Tcl_FSOpenFileChannel returns NULL and records a POSIX error code that can be retrieved with Tcl_GetErrno. In addition, if interp is non-NULL, Tcl_FSOpenFileChan‐ nel leaves an error message in interp's result after any error. The newly created channel is not registered in the supplied inter‐ preter; to register it, use Tcl_RegisterChannel. If one of the stan‐ dard channels, stdin, stdout or stderr was previously closed, the act of creating the new channel also assigns it as a replacement for the standard channel. Tcl_FSGetCwd replaces the library version of getcwd. It returns the Tcl library's current working directory. This may be different to the native platform's working directory, which happens when the current working directory is not in the native filesystem. The result is a pointer to a Tcl_Obj specifying the current directory, or NULL if the current directory could not be determined. If NULL is returned, an error message is left in the interp's result. The result already has its reference count incremented for the caller. When it is no longer needed, that reference count should be decre‐ mented. This is needed for thread-safety purposes, to allow multiple threads to access this and related functions, while ensuring the re‐ sults are always valid. Tcl_FSChdir replaces the library version of chdir. The path is normal‐ ized and then passed to the filesystem which claims it. If that filesystem does not implement this function, Tcl will fallback to a combination of stat and access to check whether the directory exists and has appropriate permissions. For results, see chdir documentation. If successful, we keep a record of the successful path in cwdPathPtr for subsequent calls to Tcl_FS‐ GetCwd. Tcl_FSPathSeparator returns the separator character to be used for most specific element of the path specified by pathPtr (i.e. the last part of the path). The separator is returned as a Tcl_Obj containing a string of length 1. If the path is invalid, NULL is returned. Tcl_FSJoinPath takes the given Tcl_Obj, which must be a valid list (which is allowed to have a reference count of zero), and returns the path value given by considering the first elements elements as valid path segments (each path segment may be a complete path, a partial path or just a single possible directory or file name). If any path segment is actually an absolute path, then all prior path segments are dis‐ carded. If elements is less than 0, we use the entire list. It is possible that the returned value is actually an element of the given list, so the caller should be careful to increment the reference count of the result before freeing the list. The returned value, typically with a reference count of zero (but it could be shared under some conditions), contains the joined path. The caller must add a reference count to the value before using it. In par‐ ticular, the returned value could be an element of the given list, so freeing the list might free the value prematurely if no reference count has been taken. If the number of elements is zero, then the returned value will be an empty-string Tcl_Obj. Tcl_FSSplitPath takes the given Tcl_Obj, which should be a valid path, and returns a Tcl list value containing each segment of that path as an element. It returns a list value with a reference count of zero. If the passed in lenPtr is non-NULL, the variable it points to will be up‐ dated to contain the number of elements in the returned list. Tcl_FSEqualPaths tests whether the two paths given represent the same filesystem object. It returns 1 if the paths are equal, and 0 if they are different. If either path is NULL, 0 is always returned. Tcl_FSGetNormalizedPath attempts to extract from the given Tcl_Obj a unique normalized path representation, whose string value can be used as a unique identifier for the file. It returns the normalized path value, owned by Tcl, or NULL if the path was invalid or could otherwise not be successfully converted. Extrac‐ tion of absolute, normalized paths is very efficient (because the filesystem operates on these representations internally), although the result when the filesystem contains numerous symbolic links may not be the most user-friendly version of a path. The return value is owned by Tcl and has a lifetime equivalent to that of the pathPtr passed in (un‐ less that is a relative path, in which case the normalized path value may be freed any time the cwd changes) - the caller can of course in‐ crement the reference count if it wishes to maintain a copy for longer. Tcl_FSJoinToPath takes the given value, which should usually be a valid path or NULL, and joins onto it the array of paths segments given. Returns a value, typically with reference count of zero (but it could be shared under some conditions), containing the joined path. The caller must add a reference count to the value before using it. If any of the values passed into this function (pathPtr or path elements) have a reference count of zero, they will be freed when this function re‐ turns. Tcl_FSConvertToPathType tries to convert the given Tcl_Obj to a valid Tcl path type, taking account of the fact that the cwd may have changed even if this value is already supposedly of the correct type. The filename may begin with “~” (to indicate current user's home directory) or “~<user>” (to indicate any user's home directory). If the conversion succeeds (i.e. the value is a valid path in one of the current filesystems), then TCL_OK is returned. Otherwise TCL_ERROR is returned, and an error message may be left in the interpreter. Tcl_FSGetInternalRep extracts the internal representation of a given path value, in the given filesystem. If the path value belongs to a different filesystem, we return NULL. If the internal representation is currently NULL, we attempt to generate it, by calling the filesystem's Tcl_FSCreateInternalRepProc. Returns NULL or a valid internal path representation. This internal representation is cached, so that repeated calls to this function will not require additional conversions. Tcl_FSGetTranslatedPath attempts to extract the translated path from the given Tcl_Obj. If the translation succeeds (i.e. the value is a valid path), then it is returned. Otherwise NULL will be returned, and an error message may be left in the interpreter. A “translated” path is one which contains no “~” or “~user” sequences (these have been expanded to their current representation in the filesystem). The value returned is owned by the caller, which must store it or call Tcl_DecrRefCount to ensure memory is freed. This function is of little practical use, and Tcl_FSGetNor‐ malizedPath or Tcl_FSGetNativePath are usually better functions to use for most purposes. Tcl_FSGetTranslatedStringPath does the same as Tcl_FSGetTranslatedPath, but returns a character string or NULL. The string returned is dynami‐ cally allocated and owned by the caller, which must store it or call ckfree to ensure it is freed. Again, Tcl_FSGetNormalizedPath or Tcl_FS‐ GetNativePath are usually better functions to use for most purposes. Tcl_FSNewNativePath performs something like the reverse of the usual obj->path->nativerep conversions. If some code retrieves a path in na‐ tive form (from, e.g. readlink or a native dialog), and that path is to be used at the Tcl level, then calling this function is an efficient way of creating the appropriate path value type. The resulting value is a pure “path” value, which will only receive a UTF-8 string representation if that is required by some Tcl code. Tcl_FSGetNativePath is for use by the Win/Unix native filesystems, so that they can easily retrieve the native (char* or TCHAR*) representa‐ tion of a path. This function is a convenience wrapper around Tcl_FS‐ GetInternalRep. It may be desirable in the future to have non-string- based native representations (for example, on macOS, a representation using a fileSpec of FSRef structure would probably be more efficient). On Windows a full Unicode representation would allow for paths of un‐ limited length. Currently the representation is simply a character string which may contain either the relative path or a complete, abso‐ lute normalized path in the native encoding (complex conditions dictate which of these will be provided, so neither can be relied upon, unless the path is known to be absolute). If you need a native path which must be absolute, then you should ask for the native version of a normalized path. If for some reason a non-absolute, non-normalized version of the path is needed, that must be constructed separately (e.g. using Tcl_FS‐ GetTranslatedPath). The native representation is cached so that repeated calls to this function will not require additional conversions. The return value is owned by Tcl and has a lifetime equivalent to that of the pathPtr passed in (unless that is a relative path, in which case the native representation may be freed any time the cwd changes). Tcl_FSFileSystemInfo returns a list of two elements. The first element is the name of the filesystem (e.g. “native”, “vfs”, “zip”, or “prowrap”, perhaps), and the second is the particular type of the given path within that filesystem (which is filesystem dependent). The second element may be empty if the filesystem does not provide a further cate‐ gorization of files. A valid list value is returned, unless the path value is not recog‐ nized, when NULL will be returned. Tcl_FSGetFileSystemForPath returns a pointer to the Tcl_Filesystem which accepts this path as valid. If no filesystem will accept the path, NULL is returned. Tcl_FSGetPathType determines whether the given path is relative to the current directory, relative to the current volume, or absolute. It returns one of TCL_PATH_ABSOLUTE, TCL_PATH_RELATIVE, or TCL_PATH_VOLUME_RELATIVE PORTABLE STAT RESULT API Tcl_AllocStatBuf allocates a Tcl_StatBuf on the system heap (which may be deallocated by being passed to ckfree). This allows extensions to invoke Tcl_FSStat and Tcl_FSLstat without being dependent on the size of the buffer. That in turn depends on the flags used to build Tcl. The portable fields of a Tcl_StatBuf may be read using the following │ functions, each of which returns the value of the corresponding field │ listed in the table below. Note that on some platforms there may be │ other fields in the Tcl_StatBuf as it is an alias for a suitable system │ structure, but only the portable ones are made available here. See your │ system documentation for a full description of these fields. │ Access Function Field │ Tcl_GetFSDeviceFromStat st_dev │ Tcl_GetFSInodeFromStat st_ino │ Tcl_GetModeFromStat st_mode │ Tcl_GetLinkCountFromStat st_nlink │ Tcl_GetUserIdFromStat st_uid │ Tcl_GetGroupIdFromStat st_gid │ Tcl_GetDeviceTypeFromStat st_rdev │ Tcl_GetAccessTimeFromStat st_atime │ Tcl_GetModificationTimeFromStat st_mtime │ Tcl_GetChangeTimeFromStat st_ctime │ Tcl_GetSizeFromStat st_size │ Tcl_GetBlocksFromStat st_blocks │ Tcl_GetBlockSizeFromStat st_blksize │ THE VIRTUAL FILESYSTEM API A filesystem provides a Tcl_Filesystem structure that contains pointers to functions that implement the various operations on a filesystem; these operations are invoked as needed by the generic layer, which gen‐ erally occurs through the functions listed above. The Tcl_Filesystem structures are manipulated using the following meth‐ ods. Tcl_FSRegister takes a pointer to a filesystem structure and an op‐ tional piece of data to associated with that filesystem. On calling this function, Tcl will attach the filesystem to the list of known filesystems, and it will become fully functional immediately. Tcl does not check if the same filesystem is registered multiple times (and in general that is not a good thing to do). TCL_OK will be returned. Tcl_FSUnregister removes the given filesystem structure from the list of known filesystems, if it is known, and returns TCL_OK. If the filesystem is not currently registered, TCL_ERROR is returned. Tcl_FSData will return the clientData associated with the given filesystem, if that filesystem is registered. Otherwise it will return NULL. Tcl_FSMountsChanged is used to inform the Tcl's core that the set of mount points for the given (already registered) filesystem have changed, and that cached file representations may therefore no longer be correct. THE TCL_FILESYSTEM STRUCTURE The Tcl_Filesystem structure contains the following fields: typedef struct Tcl_Filesystem { const char *typeName; int structureLength; Tcl_FSVersion version; Tcl_FSPathInFilesystemProc *pathInFilesystemProc; Tcl_FSDupInternalRepProc *dupInternalRepProc; Tcl_FSFreeInternalRepProc *freeInternalRepProc; Tcl_FSInternalToNormalizedProc *internalToNormalizedProc; Tcl_FSCreateInternalRepProc *createInternalRepProc; Tcl_FSNormalizePathProc *normalizePathProc; Tcl_FSFilesystemPathTypeProc *filesystemPathTypeProc; Tcl_FSFilesystemSeparatorProc *filesystemSeparatorProc; Tcl_FSStatProc *statProc; Tcl_FSAccessProc *accessProc; Tcl_FSOpenFileChannelProc *openFileChannelProc; Tcl_FSMatchInDirectoryProc *matchInDirectoryProc; Tcl_FSUtimeProc *utimeProc; Tcl_FSLinkProc *linkProc; Tcl_FSListVolumesProc *listVolumesProc; Tcl_FSFileAttrStringsProc *fileAttrStringsProc; Tcl_FSFileAttrsGetProc *fileAttrsGetProc; Tcl_FSFileAttrsSetProc *fileAttrsSetProc; Tcl_FSCreateDirectoryProc *createDirectoryProc; Tcl_FSRemoveDirectoryProc *removeDirectoryProc; Tcl_FSDeleteFileProc *deleteFileProc; Tcl_FSCopyFileProc *copyFileProc; Tcl_FSRenameFileProc *renameFileProc; Tcl_FSCopyDirectoryProc *copyDirectoryProc; Tcl_FSLstatProc *lstatProc; Tcl_FSLoadFileProc *loadFileProc; Tcl_FSGetCwdProc *getCwdProc; Tcl_FSChdirProc *chdirProc; } Tcl_Filesystem; Except for the first three fields in this structure which contain sim‐ ple data elements, all entries contain addresses of functions called by the generic filesystem layer to perform the complete range of filesys‐ tem related actions. The many functions in this structure are broken down into three cate‐ gories: infrastructure functions (almost all of which must be imple‐ mented), operational functions (which must be implemented if a complete filesystem is provided), and efficiency functions (which need only be implemented if they can be done so efficiently, or if they have side- effects which are required by the filesystem; Tcl has less efficient emulations it can fall back on). It is important to note that, in the current version of Tcl, most of these fallbacks are only used to handle commands initiated in Tcl, not in C. What this means is, that if a file rename command is issued in Tcl, and the relevant filesystem(s) do not implement their Tcl_FSRenameFileProc, Tcl's core will instead fallback on a combination of other filesystem functions (it will use Tcl_FSCopy‐ FileProc followed by Tcl_FSDeleteFileProc, and if Tcl_FSCopyFileProc is not implemented there is a further fallback). However, if a Tcl_FSRe‐ nameFileProc command is issued at the C level, no such fallbacks occur. This is true except for the last four entries in the filesystem table (lstat, load, getcwd and chdir) for which fallbacks do in fact occur at the C level. Any functions which take path names in Tcl_Obj form take those names in UTF-8 form. The filesystem infrastructure API is designed to support efficient, cached conversion of these UTF-8 paths to other native rep‐ resentations. EXAMPLE FILESYSTEM DEFINITION Here is the filesystem lookup table used by the “vfs” extension which allows filesystem actions to be implemented in Tcl. static Tcl_Filesystem vfsFilesystem = { "tclvfs", sizeof(Tcl_Filesystem), TCL_FILESYSTEM_VERSION_1, &VfsPathInFilesystem, &VfsDupInternalRep, &VfsFreeInternalRep, /* No internal to normalized, since we don't create * any pure 'internal' Tcl_Obj path representations */ NULL, /* No create native rep function, since we don't use * it and don't choose to support uses of * Tcl_FSNewNativePath */ NULL, /* Normalize path isn't needed - we assume paths only * have one representation */ NULL, &VfsFilesystemPathType, &VfsFilesystemSeparator, &VfsStat, &VfsAccess, &VfsOpenFileChannel, &VfsMatchInDirectory, &VfsUtime, /* We choose not to support symbolic links inside our * VFS's */ NULL, &VfsListVolumes, &VfsFileAttrStrings, &VfsFileAttrsGet, &VfsFileAttrsSet, &VfsCreateDirectory, &VfsRemoveDirectory, &VfsDeleteFile, /* No copy file; use the core fallback mechanism */ NULL, /* No rename file; use the core fallback mechanism */ NULL, /* No copy directory; use the core fallback mechanism */ NULL, /* Core will use stat for lstat */ NULL, /* No load; use the core fallback mechanism */ NULL, /* We don't need a getcwd or chdir; the core's own * internal value is suitable */ NULL, NULL }; FILESYSTEM INFRASTRUCTURE These fields contain basic information about the filesystem structure and addresses of functions which are used to associate a particular filesystem with a file path, and deal with the internal handling of path representations, for example copying and freeing such representa‐ tions. TYPENAME The typeName field contains a null-terminated string that identifies the type of the filesystem implemented, e.g. “native”, “zip” or “vfs”. STRUCTURE LENGTH The structureLength field is generally implemented as sizeof(Tcl_Filesystem), and is there to allow easier binary backwards compatibility if the size of the structure changes in a future Tcl re‐ lease. VERSION The version field should be set to TCL_FILESYSTEM_VERSION_1. PATHINFILESYSTEMPROC The pathInFilesystemProc field contains the address of a function which is called to determine whether a given path value belongs to this filesystem or not. Tcl will only call the rest of the filesystem func‐ tions with a path for which this function has returned TCL_OK. If the path does not belong, -1 should be returned (the behavior of Tcl for any other return value is not defined). If TCL_OK is returned, then the optional clientDataPtr output parameter can be used to return an inter‐ nal (filesystem specific) representation of the path, which will be cached inside the path value, and may be retrieved efficiently by the other filesystem functions. Tcl will simultaneously cache the fact that this path belongs to this filesystem. Such caches are invalidated when filesystem structures are added or removed from Tcl's internal list of known filesystems. typedef int Tcl_FSPathInFilesystemProc( Tcl_Obj *pathPtr, ClientData *clientDataPtr); DUPINTERNALREPPROC This function makes a copy of a path's internal representation, and is called when Tcl needs to duplicate a path value. If NULL, Tcl will sim‐ ply not copy the internal representation, which may then need to be re‐ generated later. typedef ClientData Tcl_FSDupInternalRepProc( ClientData clientData); FREEINTERNALREPPROC Free the internal representation. This must be implemented if internal representations need freeing (i.e. if some memory is allocated when an internal representation is generated), but may otherwise be NULL. typedef void Tcl_FSFreeInternalRepProc( ClientData clientData); INTERNALTONORMALIZEDPROC Function to convert internal representation to a normalized path. Only required if the filesystem creates pure path values with no string/path representation. The return value is a Tcl value whose string represen‐ tation is the normalized path. typedef Tcl_Obj *Tcl_FSInternalToNormalizedProc( ClientData clientData); CREATEINTERNALREPPROC Function to take a path value, and calculate an internal representation for it, and store that native representation in the value. May be NULL if paths have no internal representation, or if the Tcl_FSPathIn‐ FilesystemProc for this filesystem always immediately creates an inter‐ nal representation for paths it accepts. typedef ClientData Tcl_FSCreateInternalRepProc( Tcl_Obj *pathPtr); NORMALIZEPATHPROC Function to normalize a path. Should be implemented for all filesystems which can have multiple string representations for the same path value. In Tcl, every “path” must have a single unique “normalized” string rep‐ resentation. Depending on the filesystem, there may be more than one unnormalized string representation which refers to that path (e.g. a relative path, a path with different character case if the filesystem is case insensitive, a path contain a reference to a home directory such as “~”, a path containing symbolic links, etc). If the very last component in the path is a symbolic link, it should not be converted into the value it points to (but its case or other aspects should be made unique). All other path components should be converted from sym‐ bolic links. This one exception is required to agree with Tcl's seman‐ tics with file delete, file rename, file copy operating on symbolic links. This function may be called with nextCheckpoint either at the beginning of the path (i.e. zero), at the end of the path, or at any intermediate file separator in the path. It will never point to any other arbitrary position in the path. In the last of the three valid cases, the implementation can assume that the path up to and including the file separator is known and normalized. typedef int Tcl_FSNormalizePathProc( Tcl_Interp *interp, Tcl_Obj *pathPtr, int nextCheckpoint); FILESYSTEM OPERATIONS The fields in this section of the structure contain addresses of func‐ tions which are called to carry out the basic filesystem operations. A filesystem which expects to be used with the complete standard Tcl com‐ mand set must implement all of these. If some of them are not imple‐ mented, then certain Tcl commands may fail when operating on paths within that filesystem. However, in some instances this may be desir‐ able (for example, a read-only filesystem should not implement the last four functions, and a filesystem which does not support symbolic links need not implement the readlink function, etc. The Tcl core expects filesystems to behave in this way). FILESYSTEMPATHTYPEPROC Function to determine the type of a path in this filesystem. May be NULL, in which case no type information will be available to users of the filesystem. The “type” is used only for informational purposes, and should be returned as the string representation of the Tcl_Obj which is returned. A typical return value might be “networked”, “zip” or “ftp”. The Tcl_Obj result is owned by the filesystem and so Tcl will increment the reference count of that value if it wishes to retain a reference to it. typedef Tcl_Obj *Tcl_FSFilesystemPathTypeProc( Tcl_Obj *pathPtr); FILESYSTEMSEPARATORPROC Function to return the separator character(s) for this filesystem. This need only be implemented if the filesystem wishes to use a differ‐ ent separator than the standard string “/”. Amongst other uses, it is returned by the file separator command. The return value should be a value with reference count of zero. typedef Tcl_Obj *Tcl_FSFilesystemSeparatorProc( Tcl_Obj *pathPtr); STATPROC Function to process a Tcl_FSStat call. Must be implemented for any rea‐ sonable filesystem, since many Tcl level commands depend crucially upon it (e.g. file atime, file isdirectory, file size, glob). typedef int Tcl_FSStatProc( Tcl_Obj *pathPtr, Tcl_StatBuf *statPtr); The Tcl_FSStatProc fills the stat structure statPtr with information about the specified file. You do not need any access rights to the file to get this information but you need search rights to all directories named in the path leading to the file. The stat structure includes info regarding device, inode (always 0 on Windows), privilege mode, nlink (always 1 on Windows), user id (always 0 on Windows), group id (always 0 on Windows), rdev (same as device on Windows), size, last access time, last modification time, and last metadata change time. If the file represented by pathPtr exists, the Tcl_FSStatProc returns 0 and the stat structure is filled with data. Otherwise, -1 is returned, and no stat info is given. ACCESSPROC Function to process a Tcl_FSAccess call. Must be implemented for any reasonable filesystem, since many Tcl level commands depend crucially upon it (e.g. file exists, file readable). typedef int Tcl_FSAccessProc( Tcl_Obj *pathPtr, int mode); The Tcl_FSAccessProc checks whether the process would be allowed to read, write or test for existence of the file (or other filesystem ob‐ ject) whose name is in pathPtr. If the pathname refers to a symbolic link, then the permissions of the file referred by this symbolic link should be tested. On success (all requested permissions granted), zero is returned. On error (at least one bit in mode asked for a permission that is denied, or some other error occurred), -1 is returned. OPENFILECHANNELPROC Function to process a Tcl_FSOpenFileChannel call. Must be implemented for any reasonable filesystem, since any operations which require open or accessing a file's contents will use it (e.g. open, encoding, and many Tk commands). typedef Tcl_Channel Tcl_FSOpenFileChannelProc( Tcl_Interp *interp, Tcl_Obj *pathPtr, int mode, int permissions); The Tcl_FSOpenFileChannelProc opens a file specified by pathPtr and re‐ turns a channel handle that can be used to perform input and output on the file. This API is modeled after the fopen procedure of the Unix standard I/O library. The syntax and meaning of all arguments is simi‐ lar to those given in the Tcl open command when opening a file, where the mode argument is a combination of the POSIX flags O_RDONLY, O_WRONLY, etc. If an error occurs while opening the channel, the Tcl_FSOpenFileChannelProc returns NULL and records a POSIX error code that can be retrieved with Tcl_GetErrno. In addition, if interp is non-NULL, the Tcl_FSOpenFileChannelProc leaves an error message in in‐ terp's result after any error. The newly created channel must not be registered in the supplied inter‐ preter by a Tcl_FSOpenFileChannelProc; that task is up to the caller of Tcl_FSOpenFileChannel (if necessary). If one of the standard channels, stdin, stdout or stderr was previously closed, the act of creating the new channel also assigns it as a replacement for the standard channel. MATCHINDIRECTORYPROC Function to process a Tcl_FSMatchInDirectory call. If not implemented, then glob and recursive copy functionality will be lacking in the filesystem (and this may impact commands like encoding names which use glob functionality internally). typedef int Tcl_FSMatchInDirectoryProc( Tcl_Interp *interp, Tcl_Obj *resultPtr, Tcl_Obj *pathPtr, const char *pattern, Tcl_GlobTypeData *types); The function should return all files or directories (or other filesys‐ tem objects) which match the given pattern and accord with the types specification given. There are two ways in which this function may be called. If pattern is NULL, then pathPtr is a full path specification of a single file or directory which should be checked for existence and correct type. Otherwise, pathPtr is a directory, the contents of which the function should search for files or directories which have the cor‐ rect type. In either case, pathPtr can be assumed to be both non-NULL and non-empty. It is not currently documented whether pathPtr will have a file separator at its end of not, so code should be flexible to both possibilities. The return value is a standard Tcl result indicating whether an error occurred in the matching process. Error messages are placed in interp, unless interp in NULL in which case no error message need be generated; on a TCL_OK result, results should be added to the resultPtr value given (which can be assumed to be a valid unshared Tcl list). The matches added to resultPtr should include any path prefix given in pathPtr (this usually means they will be absolute path specifications). Note that if no matches are found, that simply leads to an empty re‐ sult; errors are only signaled for actual file or filesystem problems which may occur during the matching process. The Tcl_GlobTypeData structure passed in the types parameter contains the following fields: typedef struct Tcl_GlobTypeData { /* Corresponds to bcdpfls as in 'find -t' */ int type; /* Corresponds to file permissions */ int perm; /* Acceptable mac type */ Tcl_Obj *macType; /* Acceptable mac creator */ Tcl_Obj *macCreator; } Tcl_GlobTypeData; There are two specific cases which it is important to handle correctly, both when types is non-NULL. The two cases are when types->types & TCL_GLOB_TYPE_DIR or types->types & TCL_GLOB_TYPE_MOUNT are true (and in particular when the other flags are false). In the first of these cases, the function must list the contained directories. Tcl uses this to implement recursive globbing, so it is critical that filesystems im‐ plement directory matching correctly. In the second of these cases, with TCL_GLOB_TYPE_MOUNT, the filesystem must list the mount points which lie within the given pathPtr (and in this case, pathPtr need not lie within the same filesystem - different to all other cases in which this function is called). Support for this is critical if Tcl is to have seamless transitions between from one filesystem to another. UTIMEPROC Function to process a Tcl_FSUtime call. Required to allow setting (not reading) of times with file mtime, file atime and the open-r/open- w/fcopy implementation of file copy. typedef int Tcl_FSUtimeProc( Tcl_Obj *pathPtr, struct utimbuf *tval); The access and modification times of the file specified by pathPtr should be changed to the values given in the tval structure. The return value should be 0 on success and -1 on an error, as with the system utime. LINKPROC Function to process a Tcl_FSLink call. Should be implemented only if the filesystem supports links, and may otherwise be NULL. typedef Tcl_Obj *Tcl_FSLinkProc( Tcl_Obj *linkNamePtr, Tcl_Obj *toPtr, int linkAction); If toPtr is NULL, the function is being asked to read the contents of a link. The result is a Tcl_Obj specifying the contents of the link given by linkNamePtr, or NULL if the link could not be read. The result is owned by the caller (and should therefore have its ref count incre‐ mented before being returned). Any callers should call Tcl_DecrRefCount on this result when it is no longer needed. If toPtr is not NULL, the function should attempt to create a link. The result in this case should be toPtr if the link was successful and NULL otherwise. In this case the result is not owned by the caller (i.e. no reference count ma‐ nipulations on either end are needed). See the documentation for Tcl_FSLink for the correct interpretation of the linkAction flags. LISTVOLUMESPROC Function to list any filesystem volumes added by this filesystem. Should be implemented only if the filesystem adds volumes at the head of the filesystem, so that they can be returned by file volumes. typedef Tcl_Obj *Tcl_FSListVolumesProc(void); The result should be a list of volumes added by this filesystem, or NULL (or an empty list) if no volumes are provided. The result value is considered to be owned by the filesystem (not by Tcl's core), but should be given a reference count for Tcl. Tcl will use the contents of the list and then decrement that reference count. This allows filesys‐ tems to choose whether they actually want to retain a “global list” of volumes or not (if not, they generate the list on the fly and pass it to Tcl with a reference count of 1 and then forget about the list, if yes, then they simply increment the reference count of their global list and pass it to Tcl which will copy the contents and then decrement the count back to where it was). Therefore, Tcl considers return values from this proc to be read-only. FILEATTRSTRINGSPROC Function to list all attribute strings which are valid for this filesystem. If not implemented the filesystem will not support the file attributes command. This allows arbitrary additional information to be attached to files in the filesystem. If it is not implemented, there is no need to implement the get and set methods. typedef const char *const *Tcl_FSFileAttrStringsProc( Tcl_Obj *pathPtr, Tcl_Obj **objPtrRef); The called function may either return an array of strings, or may in‐ stead return NULL and place a Tcl list into the given objPtrRef. Tcl will take that list and first increment its reference count before us‐ ing it. On completion of that use, Tcl will decrement its reference count. Hence if the list should be disposed of by Tcl when done, it should have a reference count of zero, and if the list should not be disposed of, the filesystem should ensure it returns a value with a reference count of at least one. FILEATTRSGETPROC Function to process a Tcl_FSFileAttrsGet call, used by file attributes. typedef int Tcl_FSFileAttrsGetProc( Tcl_Interp *interp, int index, Tcl_Obj *pathPtr, Tcl_Obj **objPtrRef); Returns a standard Tcl return code. The attribute value retrieved, which corresponds to the index'th element in the list returned by the Tcl_FSFileAttrStringsProc, is a Tcl_Obj placed in objPtrRef (if TCL_OK was returned) and is likely to have a reference count of zero. Either way we must either store it somewhere (e.g. the Tcl result), or Incr/Decr its reference count to ensure it is properly freed. FILEATTRSSETPROC Function to process a Tcl_FSFileAttrsSet call, used by file attributes. If the filesystem is read-only, there is no need to implement this. typedef int Tcl_FSFileAttrsSetProc( Tcl_Interp *interp, int index, Tcl_Obj *pathPtr, Tcl_Obj *objPtr); The attribute value of the index'th element in the list returned by the Tcl_FSFileAttrStringsProc should be set to the objPtr given. CREATEDIRECTORYPROC Function to process a Tcl_FSCreateDirectory call. Should be implemented unless the FS is read-only. typedef int Tcl_FSCreateDirectoryProc( Tcl_Obj *pathPtr); The return value is a standard Tcl result indicating whether an error occurred in the process. If successful, a new directory should have been added to the filesystem in the location specified by pathPtr. REMOVEDIRECTORYPROC Function to process a Tcl_FSRemoveDirectory call. Should be implemented unless the FS is read-only. typedef int Tcl_FSRemoveDirectoryProc( Tcl_Obj *pathPtr, int recursive, Tcl_Obj **errorPtr); The return value is a standard Tcl result indicating whether an error occurred in the process. If successful, the directory specified by pathPtr should have been removed from the filesystem. If the recursive flag is given, then a non-empty directory should be deleted without er‐ ror. If this flag is not given, then and the directory is non-empty a POSIX “EEXIST” error should be signaled. If an error does occur, the name of the file or directory which caused the error should be placed in errorPtr. DELETEFILEPROC Function to process a Tcl_FSDeleteFile call. Should be implemented un‐ less the FS is read-only. typedef int Tcl_FSDeleteFileProc( Tcl_Obj *pathPtr); The return value is a standard Tcl result indicating whether an error occurred in the process. If successful, the file specified by pathPtr should have been removed from the filesystem. Note that, if the filesystem supports symbolic links, Tcl will always call this function and not Tcl_FSRemoveDirectoryProc when needed to delete them (even if they are symbolic links to directories). FILESYSTEM EFFICIENCY These functions need not be implemented for a particular filesystem be‐ cause the core has a fallback implementation available. See each indi‐ vidual description for the consequences of leaving the field NULL. LSTATPROC Function to process a Tcl_FSLstat call. If not implemented, Tcl will attempt to use the statProc defined above instead. Therefore it need only be implemented if a filesystem can differentiate between stat and lstat calls. typedef int Tcl_FSLstatProc( Tcl_Obj *pathPtr, Tcl_StatBuf *statPtr); The behavior of this function is very similar to that of the Tcl_FSStatProc defined above, except that if it is applied to a sym‐ bolic link, it returns information about the link, not about the target file. COPYFILEPROC Function to process a Tcl_FSCopyFile call. If not implemented Tcl will fall back on open-r, open-w and fcopy as a copying mechanism. There‐ fore it need only be implemented if the filesystem can perform that ac‐ tion more efficiently. typedef int Tcl_FSCopyFileProc( Tcl_Obj *srcPathPtr, Tcl_Obj *destPathPtr); The return value is a standard Tcl result indicating whether an error occurred in the copying process. Note that, destPathPtr is the name of the file which should become the copy of srcPathPtr. It is never the name of a directory into which srcPathPtr could be copied (i.e. the function is much simpler than the Tcl level file copy subcommand). Note that, if the filesystem supports symbolic links, Tcl will always call this function and not copyDirectoryProc when needed to copy them (even if they are symbolic links to directories). Finally, if the filesystem determines it cannot support the file copy action, calling Tcl_SetEr‐ rno(EXDEV) and returning a non-TCL_OK result will tell Tcl to use its standard fallback mechanisms. RENAMEFILEPROC Function to process a Tcl_FSRenameFile call. If not implemented, Tcl will fall back on a copy and delete mechanism. Therefore it need only be implemented if the filesystem can perform that action more effi‐ ciently. typedef int Tcl_FSRenameFileProc( Tcl_Obj *srcPathPtr, Tcl_Obj *destPathPtr); The return value is a standard Tcl result indicating whether an error occurred in the renaming process. If the filesystem determines it can‐ not support the file rename action, calling Tcl_SetErrno(EXDEV) and re‐ turning a non-TCL_OK result will tell Tcl to use its standard fallback mechanisms. COPYDIRECTORYPROC Function to process a Tcl_FSCopyDirectory call. If not implemented, Tcl will fall back on a recursive file mkdir, file copy mechanism. There‐ fore it need only be implemented if the filesystem can perform that ac‐ tion more efficiently. typedef int Tcl_FSCopyDirectoryProc( Tcl_Obj *srcPathPtr, Tcl_Obj *destPathPtr, Tcl_Obj **errorPtr); The return value is a standard Tcl result indicating whether an error occurred in the copying process. If an error does occur, the name of the file or directory which caused the error should be placed in er‐ rorPtr. Note that, destPathPtr is the name of the directory-name which should become the mirror-image of srcPathPtr. It is not the name of a directory into which srcPathPtr should be copied (i.e. the function is much simpler than the Tcl level file copy subcommand). Finally, if the filesystem determines it cannot support the directory copy action, calling Tcl_SetErrno(EXDEV) and returning a non-TCL_OK result will tell Tcl to use its standard fallback mechanisms. LOADFILEPROC Function to process a Tcl_FSLoadFile call. If not implemented, Tcl will fall back on a copy to native-temp followed by a Tcl_FSLoadFile on that temporary copy. Therefore it need only be implemented if the filesystem can load code directly, or it can be implemented simply to return TCL_ERROR to disable load functionality in this filesystem entirely. typedef int Tcl_FSLoadFileProc( Tcl_Interp *interp, Tcl_Obj *pathPtr, Tcl_LoadHandle *handlePtr, Tcl_FSUnloadFileProc *unloadProcPtr); Returns a standard Tcl completion code. If an error occurs, an error message is left in the interp's result. The function dynamically loads a binary code file into memory. On a successful load, the handlePtr should be filled with a token for the dynamically loaded file, and the unloadProcPtr should be filled in with the address of a procedure. The unload procedure will be called with the given Tcl_LoadHandle as its only parameter when Tcl needs to unload the file. For example, for the native filesystem, the Tcl_LoadHandle returned is currently a token which can be used in the private TclpFindSymbol to access functions in the new code. Each filesystem is free to define the Tcl_LoadHandle as it requires. Finally, if the filesystem determines it cannot support the file load action, calling Tcl_SetErrno(EXDEV) and returning a non- TCL_OK result will tell Tcl to use its standard fallback mechanisms. UNLOADFILEPROC Function to unload a previously successfully loaded file. If load was implemented, then this should also be implemented, if there is any cleanup action required. typedef void Tcl_FSUnloadFileProc( Tcl_LoadHandle loadHandle); GETCWDPROC Function to process a Tcl_FSGetCwd call. Most filesystems need not im‐ plement this. It will usually only be called once, if getcwd is called before chdir. May be NULL. typedef Tcl_Obj *Tcl_FSGetCwdProc( Tcl_Interp *interp); If the filesystem supports a native notion of a current working direc‐ tory (which might perhaps change independent of Tcl), this function should return that cwd as the result, or NULL if the current directory could not be determined (e.g. the user does not have appropriate per‐ missions on the cwd directory). If NULL is returned, an error message is left in the interp's result. CHDIRPROC Function to process a Tcl_FSChdir call. If filesystems do not implement this, it will be emulated by a series of directory access checks. Oth‐ erwise, virtual filesystems which do implement it need only respond with a positive return result if the pathPtr is a valid, accessible di‐ rectory in their filesystem. They need not remember the result, since that will be automatically remembered for use by Tcl_FSGetCwd. Real filesystems should carry out the correct action (i.e. call the correct system chdir API). typedef int Tcl_FSChdirProc( Tcl_Obj *pathPtr); The Tcl_FSChdirProc changes the applications current working directory to the value specified in pathPtr. The function returns -1 on error or 0 on success. SEE ALSO cd(n), file(n), filename(n), load(n), open(n), pwd(n), source(n), un‐ load(n) KEYWORDS stat, access, filesystem, vfs, virtual filesystem Tcl 8.4 Filesystem(3)
Tcl_SetResult(3) Процедуры библиотеки Tcl Tcl_SetResult(3) ______________________________________________________________________________ NAME Tcl_SetObjResult, Tcl_GetObjResult, Tcl_SetResult, Tcl_GetStringResult, Tcl_AppendResult, Tcl_AppendResultVA, Tcl_AppendElement, Tcl_ResetRe‐ sult, Tcl_TransferResult, Tcl_FreeResult - управление результатом Tcl SYNOPSIS #include <tcl.h> Tcl_SetObjResult(interp, objPtr) Tcl_Obj * Tcl_GetObjResult(interp) Tcl_SetResult(interp, result, freeProc) const char * Tcl_GetStringResult(interp) Tcl_AppendResult(interp, result, result, ... , (char *)NULL) Tcl_AppendResultVA(interp, argList) Tcl_ResetResult(interp) Tcl_TransferResult(sourceInterp, code, targetInterp) │ Tcl_AppendElement(interp, element) Tcl_FreeResult(interp) ARGUMENTS Tcl_Interp *interp (out) Интерпретатор, результат кото‐ рого будет изменён или прочитан. Tcl_Obj *objPtr (in) Значение Tcl, которое станет ре‐ зультатом для interp. char *result (in) Строковое значение, которое ста‐ нет результатом для interp или будет добавлено к существующе‐ му результату. const char *element (in) Строковое значение, которое бу‐ дет добавлено как элемент спи‐ ска к существующему результату interp. Tcl_FreeProc *freeProc (in) Адрес процедуры, которую нужно вызвать для освобождения храни‐ лища по адресу result, или TCL_STATIC, TCL_DYNAMIC, или TCL_VOLATILE. va_list argList (in) Список аргументов, который дол‐ жен быть инициализирован с по‐ мощью va_start и очищен с помо‐ щью va_end. Tcl_Interp *sourceInterp (in) Интерпретатор, из которого дол‐ │ жны быть перенесены результат │ и опции возврата. │ Tcl_Interp *targetInterp (in) Интерпретатор, в который долж‐ │ ны быть перенесены результат │ и опции возврата. │ int code (in) Значение кода возврата, которое │ управляет переносом опций воз‐ │ врата. ______________________________________________________________________________ DESCRIPTION Процедуры, описанные здесь, являются утилитами для управления значени‐ ем результата в интерпретаторе Tcl. Результат интерпретатора может пред‐ ставлять собой либо значение Tcl, либо строку. Например, Tcl_SetObjRe‐ sult и Tcl_SetResult устанавливают результат интерпретатора, соответст‐ венно, на значение и строку. Аналогично, Tcl_GetObjResult и Tcl_GetStr‐ ingResult возвращают результат интерпретатора как значение и как строку. Процедуры всегда поддерживают согласованность между строковой и значен‐ ческой формами результата интерпретатора. Например, если Tcl_SetObjRe‐ sult вызывается для установки результата на значение, а затем вызыва‐ ется Tcl_GetStringResult, то оно вернёт строковое представление значе‐ ния. Tcl_SetObjResult устанавливает objPtr в качестве результата для interp, заменяя любой существующий результат. Результат остаётся указывающим на значение, на которое ссылается objPtr. Счётчик ссылок objPtr увеличивается, поскольку теперь имеется новая ссылка на него из interp. Счётчик ссыл‐ ок для любого старого значения результата уменьшается, и старое значе‐ ние результата освобождается, если на него больше нет ссылок. Tcl_GetObjResult возвращает результат для interp в виде значения. Счёт‐ чик ссылок значения не увеличивается; если вызывающий код нуждается в долгосрочном указателе на значение, он должен использовать Tcl_IncrRef‐ Count для увеличения счётчика ссылок, чтобы предотвратить слишком ран‐ нее освобождение или случайное изменение. Tcl_SetResult устанавливает result в качестве результата для текущей команды Tcl в interp, заменяя любой существующий результат. Аргумент freeProc указывает, как управлять хранилищем для аргумента result; он обсуждается в разделе АРГУМЕНТ TCL_FREEPROC В TCL_SETRESULT ниже. Если result равно NULL, то freeProc игнорируется, и Tcl_SetResult переиници‐ ализирует результат interp, чтобы он указывал на пустую строку. Tcl_GetStringResult возвращает результат для interp в виде строки. Ес‐ ли результат был установлен на значение с помощью вызова Tcl_SetObjRe‐ sult, то форма значения будет преобразована в строку и возвращена. Ес‐ ли строковое представление значения содержит нулевые байты, это преоб‐ разование приведёт к потере информации. По этой причине рекомендуется программистам писать код с использованием новых процедур API значений и вызывать Tcl_GetObjResult вместо этого. Tcl_ResetResult очищает результат для interp и оставляет результат в нормальном пустом инициализированном состоянии. Если результат является значением, его счётчик ссылок уменьшается, и результат указывает на не‐ разделяемое значение, представляющее пустую строку. Если результат яв‐ ляется динамически выделенной строкой, её память освобождается, и ре‐ зультат оставляется как пустая строка. Tcl_ResetResult также очищает состояние ошибки, управляемое Tcl_AddErrorInfo, Tcl_AddObjErrorInfo и Tcl_SetErrorCode. Tcl_AppendResult упрощает сборку результатов Tcl по частям. Она берёт каждый из своих аргументов result и добавляет их по порядку к текущему результату, связанному с interp. Если результат находится в инициализи‐ рованном пустом состоянии (например, только что была вызвана процедура команды или Tcl_ResetResult), то Tcl_AppendResult устанавливает резуль‐ тат на конкатенацию своих аргументов result. Tcl_AppendResult может вы‐ зываться несколько раз по мере появления дополнительных частей результа‐ та. Tcl_AppendResult занимается всеми вопросами управления хранилищем, связанными с результатом interp, такими как выделение большего област‐ и результата, если это необходимо. Она также управляет преобразовани‐ ем в и из поля результата interp, чтобы обеспечить обратную совместимость со старыми расширениями. В одном вызове может быть передано любое ко‐ личество аргументов result; последний аргумент в списке должен быть (char *)NULL. Tcl_AppendResultVA аналогична Tcl_AppendResult, за исключением того, что вместо переменного количества аргументов она принимает список ар- гментов. Tcl_TransferResult переносит состояние интерпретатора из sourceInterp │ в targetInterp. Два интерпретатора должны быть созданы в одном потоке. │ Если sourceInterp и targetInterp совпадают, ничего не делается. Иначе, │ Tcl_TransferResult перемещает результат из sourceInterp в targetInterp, │ и сбрасывает результат в sourceInterp. Она также перемещает словарь оп‐ │ ций возврата в соответствии со значением кода возврата code, подобно │ Tcl_GetReturnOptions. DEPRECATED INTERFACES OLD STRING PROCEDURES Использование следующих процедур устарело, поскольку они манипулируют результатом Tcl как строкой. Процедуры, такие как Tcl_SetObjResult, ко‐ торые манипулируют результатом как значением, могут быть значительно эффективнее. Tcl_AppendElement подобна Tcl_AppendResult в том, что позволяет собирать результаты по частям. Однако Tcl_AppendElement принимает только один аргумент element и добавляет этот аргумент к текущему результату как правильный элемент списка Tcl. Tcl_AppendElement добавляет обратные слэши или фигурные скобки, если это необходимо, чтобы обеспечить, что результат interp может быть разобраен как список и что element будет извлечён как отдельный элемент. В нормальных условиях Tcl_AppendElement добавит символ пробела к результату interp непосредственно перед добав‐ лением нового элемента списка, чтобы элементы списка в результате бы‐ ли правильно разделены. Однако, если новый элемент списка является пер‐ вым в списке или подсписке (т.е. текущий результат interp пуст, или со‐ стоит из одного символа "{", или заканчивается на " {"), то пробел не добавляется. Tcl_FreeResult выполняет часть работы Tcl_ResetResult. Она освобождает память, связанную с результатом interp. Она также устанавливает interp->freeProc в ноль, но не изменяет interp->result и не очищает состояние ошибки. Tcl_FreeResult чаще всего используется, когда проце‐ дура собирается заменить одно значение результата на другое. DIRECT ACCESS TO INTERP->RESULT Ранее было разрешено программам напрямую читать и записывать interp->re‐ sult для манипуляции результатом интерпретатора. Заголовки Tcl больше не разрешают этот доступ по умолчанию, и код C, который всё ещё это де‐ лает, должен быть обновлён для использования поддерживаемых процедур Tcl_GetObjResult, Tcl_GetStringResult, Tcl_SetObjResult и Tcl_SetResult. Как вспомогательное средство для миграции доступ можно восстановить с помощью директивы компилятора #define USE_INTERP_RESULT но это предназначено только для поддержки устаревшего кода. THE TCL_FREEPROC ARGUMENT TO TCL_SETRESULT Аргумент freeProc в Tcl_SetResult указывает, как система Tcl должна управлять хранилищем для аргумента result. Если Tcl_SetResult или Tcl_SetObjResult вызываются в момент, когда interp содержит строковый результат, они выполняют всё необходимое для удаления старого строково‐ го результата (см. руководство Tcl_Interp для деталей об этом). Если freeProc равно TCL_STATIC, это означает, что result указывает на область статического хранилища, которая гарантированно не будет изме‐ нена до как минимум следующего вызова Tcl_Eval. Если freeProc равно TCL_DYNAMIC, это означает, что result было выделено с помощью вызова Tcl_Alloc и теперь является собственностью системы Tcl. Tcl_SetResult организует освобождение хранилища строки путём вызова Tcl_Free, когда оно больше не понадобится. Если freeProc равно TCL_VOLATILE, это зна‐ чит, что result указывает на область памяти, которая, вероятно, будет перезаписана при возврате Tcl_SetResult (например, оно указывает на что- то в стековом фрейме). В этом случае Tcl_SetResult сделает копию строки в динамически выделенном хранилище и организует, чтобы копия стала ре‐ зультатом для текущей команды Tcl. Если freeProc не равно одному из значений TCL_STATIC, TCL_DYNAMIC и TCL_VOLATILE, то это адрес процедуры, которую Tcl должна вызвать для освобождения строки. Это позволяет приложениям использовать нестандарт‐ ные распределители хранилища. Когда Tcl больше не нуждается в хранилище для строки, она вызовет freeProc. У freeProc должны быть аргументы и результат, соответствующие типу Tcl_FreeProc: typedef void Tcl_FreeProc( char *blockPtr); При вызове freeProc её blockPtr будет установлен на значение result, переданное Tcl_SetResult. SEE ALSO Tcl_AddErrorInfo, Tcl_CreateObjCommand, Tcl_SetErrorCode, Tcl_Interp, Tcl_GetReturnOptions KEYWORDS append, command, element, list, value, result, return value, inter‐ preter Tcl 8.6 Tcl_SetResult(3)
Tcl_SetResult(3) Tcl Library Procedures Tcl_SetResult(3) ______________________________________________________________________________ NAME Tcl_SetObjResult, Tcl_GetObjResult, Tcl_SetResult, Tcl_GetStringResult, Tcl_AppendResult, Tcl_AppendResultVA, Tcl_AppendElement, Tcl_ResetRe‐ sult, Tcl_TransferResult, Tcl_FreeResult - manipulate Tcl result SYNOPSIS #include <tcl.h> Tcl_SetObjResult(interp, objPtr) Tcl_Obj * Tcl_GetObjResult(interp) Tcl_SetResult(interp, result, freeProc) const char * Tcl_GetStringResult(interp) Tcl_AppendResult(interp, result, result, ... , (char *)NULL) Tcl_AppendResultVA(interp, argList) Tcl_ResetResult(interp) Tcl_TransferResult(sourceInterp, code, targetInterp) │ Tcl_AppendElement(interp, element) Tcl_FreeResult(interp) ARGUMENTS Tcl_Interp *interp (out) Interpreter whose result is to be modified or read. Tcl_Obj *objPtr (in) Tcl value to become result for interp. char *result (in) String value to become result for interp or to be appended to the existing result. const char *element (in) String value to append as a list element to the existing result of interp. Tcl_FreeProc *freeProc (in) Address of procedure to call to release storage at result, or TCL_STATIC, TCL_DYNAMIC, or TCL_VOLATILE. va_list argList (in) An argument list which must have been initialized using va_start, and cleared using va_end. Tcl_Interp *sourceInterp (in) Interpreter that the result and │ return options should be trans‐ │ ferred from. Tcl_Interp *targetInterp (in) Interpreter that the result and │ return options should be trans‐ │ ferred to. int code (in) Return code value that controls │ transfer of return options. ______________________________________________________________________________ DESCRIPTION The procedures described here are utilities for manipulating the result value in a Tcl interpreter. The interpreter result may be either a Tcl value or a string. For example, Tcl_SetObjResult and Tcl_SetResult set the interpreter result to, respectively, a value and a string. Simi‐ larly, Tcl_GetObjResult and Tcl_GetStringResult return the interpreter result as a value and as a string. The procedures always keep the string and value forms of the interpreter result consistent. For exam‐ ple, if Tcl_SetObjResult is called to set the result to a value, then Tcl_GetStringResult is called, it will return the value's string repre‐ sentation. Tcl_SetObjResult arranges for objPtr to be the result for interp, re‐ placing any existing result. The result is left pointing to the value referenced by objPtr. objPtr's reference count is incremented since there is now a new reference to it from interp. The reference count for any old result value is decremented and the old result value is freed if no references to it remain. Tcl_GetObjResult returns the result for interp as a value. The value's reference count is not incremented; if the caller needs to retain a long-term pointer to the value they should use Tcl_IncrRefCount to in‐ crement its reference count in order to keep it from being freed too early or accidentally changed. Tcl_SetResult arranges for result to be the result for the current Tcl command in interp, replacing any existing result. The freeProc argu‐ ment specifies how to manage the storage for the result argument; it is discussed in the section THE TCL_FREEPROC ARGUMENT TO TCL_SETRESULT be‐ low. If result is NULL, then freeProc is ignored and Tcl_SetResult re- initializes interp's result to point to an empty string. Tcl_GetStringResult returns the result for interp as a string. If the result was set to a value by a Tcl_SetObjResult call, the value form will be converted to a string and returned. If the value's string rep‐ resentation contains null bytes, this conversion will lose information. For this reason, programmers are encouraged to write their code to use the new value API procedures and to call Tcl_GetObjResult instead. Tcl_ResetResult clears the result for interp and leaves the result in its normal empty initialized state. If the result is a value, its ref‐ erence count is decremented and the result is left pointing to an un‐ shared value representing an empty string. If the result is a dynami‐ cally allocated string, its memory is free*d and the result is left as a empty string. Tcl_ResetResult also clears the error state managed by Tcl_AddErrorInfo, Tcl_AddObjErrorInfo, and Tcl_SetErrorCode. Tcl_AppendResult makes it easy to build up Tcl results in pieces. It takes each of its result arguments and appends them in order to the current result associated with interp. If the result is in its ini‐ tialized empty state (e.g. a command procedure was just invoked or Tcl_ResetResult was just called), then Tcl_AppendResult sets the result to the concatenation of its result arguments. Tcl_AppendResult may be called repeatedly as additional pieces of the result are produced. Tcl_AppendResult takes care of all the storage management issues asso‐ ciated with managing interp's result, such as allocating a larger re‐ sult area if necessary. It also manages conversion to and from the re‐ sult field of the interp so as to handle backward-compatibility with old-style extensions. Any number of result arguments may be passed in a single call; the last argument in the list must be (char *)NULL. Tcl_AppendResultVA is the same as Tcl_AppendResult except that instead of taking a variable number of arguments it takes an argument list. Tcl_TransferResult transfers interpreter state from sourceInterp to │ targetInterp. The two interpreters must have been created in the same │ thread. If sourceInterp and targetInterp are the same, nothing is │ done. Otherwise, Tcl_TransferResult moves the result from sourceInterp │ to targetInterp, and resets the result in sourceInterp. It also moves │ the return options dictionary as controlled by the return code value │ code in the same manner as Tcl_GetReturnOptions. DEPRECATED INTERFACES OLD STRING PROCEDURES Use of the following procedures is deprecated since they manipulate the Tcl result as a string. Procedures such as Tcl_SetObjResult that ma‐ nipulate the result as a value can be significantly more efficient. Tcl_AppendElement is similar to Tcl_AppendResult in that it allows re‐ sults to be built up in pieces. However, Tcl_AppendElement takes only a single element argument and it appends that argument to the current result as a proper Tcl list element. Tcl_AppendElement adds back‐ slashes or braces if necessary to ensure that interp's result can be parsed as a list and that element will be extracted as a single ele‐ ment. Under normal conditions, Tcl_AppendElement will add a space character to interp's result just before adding the new list element, so that the list elements in the result are properly separated. How‐ ever if the new list element is the first in a list or sub-list (i.e. interp's current result is empty, or consists of the single character “{”, or ends in the characters “ {”) then no space is added. Tcl_FreeResult performs part of the work of Tcl_ResetResult. It frees up the memory associated with interp's result. It also sets in‐ terp->freeProc to zero, but does not change interp->result or clear er‐ ror state. Tcl_FreeResult is most commonly used when a procedure is about to replace one result value with another. DIRECT ACCESS TO INTERP->RESULT It used to be legal for programs to directly read and write interp->re‐ sult to manipulate the interpreter result. The Tcl headers no longer permit this access by default, and C code still doing this must be up‐ dated to use supported routines Tcl_GetObjResult, Tcl_GetStringResult, Tcl_SetObjResult, and Tcl_SetResult. As a migration aid, access can be restored with the compiler directive #define USE_INTERP_RESULT but this is meant only to offer life support to otherwise dead code. THE TCL_FREEPROC ARGUMENT TO TCL_SETRESULT Tcl_SetResult's freeProc argument specifies how the Tcl system is to manage the storage for the result argument. If Tcl_SetResult or Tcl_SetObjResult are called at a time when interp holds a string re‐ sult, they do whatever is necessary to dispose of the old string result (see the Tcl_Interp manual entry for details on this). If freeProc is TCL_STATIC it means that result refers to an area of static storage that is guaranteed not to be modified until at least the next call to Tcl_Eval. If freeProc is TCL_DYNAMIC it means that result was allocated with a call to Tcl_Alloc and is now the property of the Tcl system. Tcl_SetResult will arrange for the string's storage to be released by calling Tcl_Free when it is no longer needed. If freeProc is TCL_VOLATILE it means that result points to an area of memory that is likely to be overwritten when Tcl_SetResult returns (e.g. it points to something in a stack frame). In this case Tcl_SetResult will make a copy of the string in dynamically allocated storage and arrange for the copy to be the result for the current Tcl command. If freeProc is not one of the values TCL_STATIC, TCL_DYNAMIC, and TCL_VOLATILE, then it is the address of a procedure that Tcl should call to free the string. This allows applications to use non-standard storage allocators. When Tcl no longer needs the storage for the string, it will call freeProc. FreeProc should have arguments and re‐ sult that match the type Tcl_FreeProc: typedef void Tcl_FreeProc( char *blockPtr); When freeProc is called, its blockPtr will be set to the value of re‐ sult passed to Tcl_SetResult. SEE ALSO Tcl_AddErrorInfo, Tcl_CreateObjCommand, Tcl_SetErrorCode, Tcl_Interp, Tcl_GetReturnOptions KEYWORDS append, command, element, list, value, result, return value, inter‐ preter Tcl 8.6 Tcl_SetResult(3)
Tcl_IntObj(3) Процедуры библиотеки Tcl Tcl_IntObj(3) ______________________________________________________________________________ NAME Tcl_NewIntObj, Tcl_NewLongObj, Tcl_NewWideIntObj, Tcl_SetIntObj, Tcl_SetLongObj, Tcl_SetWideIntObj, Tcl_GetIntFromObj, Tcl_GetLongFro‐ mObj, Tcl_GetWideIntFromObj, Tcl_NewBignumObj, Tcl_SetBignumObj, Tcl_GetBignumFromObj, Tcl_TakeBignumFromObj - управлять значениями Tcl как целыми числами SYNOPSIS #include <tcl.h> Tcl_Obj * Tcl_NewIntObj(intValue) Tcl_Obj * Tcl_NewLongObj(longValue) Tcl_Obj * Tcl_NewWideIntObj(wideValue) Tcl_SetIntObj(objPtr, intValue) Tcl_SetLongObj(objPtr, longValue) Tcl_SetWideIntObj(objPtr, wideValue) int Tcl_GetIntFromObj(interp, objPtr, intPtr) int Tcl_GetLongFromObj(interp, objPtr, longPtr) int Tcl_GetWideIntFromObj(interp, objPtr, widePtr) #include <tclTomMath.h> Tcl_Obj * Tcl_NewBignumObj(bigValue) Tcl_SetBignumObj(objPtr, bigValue) int Tcl_GetBignumFromObj(interp, objPtr, bigValue) int Tcl_TakeBignumFromObj(interp, objPtr, bigValue) int Tcl_InitBignumFromDouble(interp, doubleValue, bigValue) ARGUMENTS int intValue (in) Целое число, используемое для инициализации или установки значения Tcl. long longValue (in) Длинное целое число, используемое для иници‐ ализации или установки значения Tcl. Tcl_WideInt wideValue (in) Широкое целое число, используемое для иници‐ ализации или установки значения Tcl. Tcl_Obj *objPtr (in/out) Для Tcl_SetIntObj, Tcl_SetLongObj, Tcl_SetWideIntObj и Tcl_SetBignumObj это указывает на значение, в которое нужно сохранить целочисленное значение. Для Tcl_GetIntFromObj, Tcl_GetLongFromObj, Tcl_GetWideIntFromObj, Tcl_GetBignumFromObj и Tcl_TakeBignumFromObj это относится к значению, из которого нужно извлечь целочисленное значение. Tcl_Interp *interp (in/out) Если не равно NULL, сообщение об ошибке оставляется здесь, когда извлечение целочисленного значения не удаётся. int *intPtr (out) Указывает на место для хранения целочисленного значения, извлечённого из objPtr. long *longPtr (out) Указывает на место для хранения длинного целочисленного значения, извлечённого из objPtr. Tcl_WideInt *widePtr (out) Указывает на место для хранения широкого целочисленного значения, извлечённого из objPtr. mp_int *bigValue (in/out) Указывает на структуру многократной точности целого числа, объявленную библиотекой LibTomMath. double doubleValue (in) Значение типа double, из которого определяется целочисленная часть и используется для инициализации значения целого числа с многократной точностью. ______________________________________________________________________________ DESCRIPTION Эти процедуры используются для создания, изменения и чтения значений Tcl, которые содержат целочисленные значения. Разные процедуры существуют для поддержки различных целочисленных типов в C, с которыми могут обмениваться значения. Целочисленные типы C, для которых Tcl предоставляет процедуры обмена значениями, — это int, long int, Tcl_WideInt и mp_int. Типы int и long int предоставляются стандартом языка C. Тип Tcl_WideInt — это typedef, определяемый как подписанный целочисленный тип, который охватывает как минимум диапазон 64-битных целых чисел (-9223372036854775808 до 9223372036854775807). В зависимости от платформы и компилятора C, фактический тип может быть long int, long long int, __int64 или что-то другое. Тип mp_int — это тип целого числа с многократной точностью, определяемый библиотекой LibTomMath для целых чисел с многократной точностью. Процедуры Tcl_NewIntObj, Tcl_NewLongObj, Tcl_NewWideIntObj и Tcl_NewBignumObj каждая создают и возвращают новое значение Tcl, инициализированное целочисленным значением аргумента. Возвращаемое значение Tcl несвязанное. Процедуры Tcl_SetIntObj, Tcl_SetLongObj, Tcl_SetWideIntObj и Tcl_SetBignumObj каждая устанавливают значение существующего значения Tcl, на которое указывает objPtr, в целочисленное значение, предоставленное другим аргументом. Аргумент objPtr должен указывать на несвязанное значение Tcl. Любая попытка установить значение связанного значения Tcl нарушает политику копирования-на-запись Tcl. Любое существующее строковое представление или внутреннее представление в несвязанном значении Tcl будет освобождено в результате установки нового значения. Процедуры Tcl_GetIntFromObj, Tcl_GetLongFromObj, Tcl_GetWideIntFromObj, Tcl_GetBignumFromObj и Tcl_TakeBignumFromObj пытаются извлечь целочисленное значение соответствующего типа из значения Tcl objPtr. Если попытка удаётся, возвращается TCL_OK, и значение записывается в хранилище, предоставленное вызывающим. Попытка может не удаться, если objPtr не содержит целочисленного значения или если значение превышает диапазон целевого типа. Если попытка не удалась, возвращается TCL_ERROR, и если interp не равно NULL, сообщение об ошибке оставляется в interp. Tcl_ObjType objPtr может быть изменён, чтобы сделать последующие вызовы той же процедуры более эффективными. В отличие от других функций, Tcl_TakeBignumFromObj может установить содержимое значения Tcl objPtr в пустую строку в процессе извлечения значения целого числа с многократной точностью. Выбор между Tcl_GetBignumFromObj и Tcl_TakeBignumFromObj определяется тем, как вызывающий будет продолжать использовать objPtr. Если после извлечения значения mp_int из objPtr вызывающий больше не будет использовать objPtr, то использование Tcl_TakeBignumFromObj позволяет Tcl обнаружить, когда несвязанное objPtr позволяет переместить значение вместо копирования, что должно быть более эффективным. Если позже в вызывающем требуется, чтобы objPtr продолжал содержать то же значение, то нужно выбрать Tcl_GetBignumFromObj. Процедура Tcl_InitBignumFromDouble — это вспомогательная процедура, которая извлекает целочисленную часть doubleValue и сохраняет это целочисленное значение в значении mp_int bigValue. SEE ALSO Tcl_NewObj, Tcl_DecrRefCount, Tcl_IncrRefCount, Tcl_GetObjResult KEYWORDS integer, значение целого числа, тип целого числа, внутреннее представление, значение, тип значения, строковое представление Tcl 8.5 Tcl_IntObj(3)
Tcl_IntObj(3) Tcl Library Procedures Tcl_IntObj(3) ______________________________________________________________________________ NAME Tcl_NewIntObj, Tcl_NewLongObj, Tcl_NewWideIntObj, Tcl_SetIntObj, Tcl_SetLongObj, Tcl_SetWideIntObj, Tcl_GetIntFromObj, Tcl_GetLongFro‐ mObj, Tcl_GetWideIntFromObj, Tcl_NewBignumObj, Tcl_SetBignumObj, Tcl_GetBignumFromObj, Tcl_TakeBignumFromObj - manipulate Tcl values as integers SYNOPSIS #include <tcl.h> Tcl_Obj * Tcl_NewIntObj(intValue) Tcl_Obj * Tcl_NewLongObj(longValue) Tcl_Obj * Tcl_NewWideIntObj(wideValue) Tcl_SetIntObj(objPtr, intValue) Tcl_SetLongObj(objPtr, longValue) Tcl_SetWideIntObj(objPtr, wideValue) int Tcl_GetIntFromObj(interp, objPtr, intPtr) int Tcl_GetLongFromObj(interp, objPtr, longPtr) int Tcl_GetWideIntFromObj(interp, objPtr, widePtr) #include <tclTomMath.h> Tcl_Obj * Tcl_NewBignumObj(bigValue) Tcl_SetBignumObj(objPtr, bigValue) int Tcl_GetBignumFromObj(interp, objPtr, bigValue) int Tcl_TakeBignumFromObj(interp, objPtr, bigValue) int Tcl_InitBignumFromDouble(interp, doubleValue, bigValue) ARGUMENTS int intValue (in) Integer value used to initialize or set a Tcl value. long longValue (in) Long integer value used to ini‐ tialize or set a Tcl value. Tcl_WideInt wideValue (in) Wide integer value used to ini‐ tialize or set a Tcl value. Tcl_Obj *objPtr (in/out) For Tcl_SetIntObj, Tcl_SetLon‐ gObj, Tcl_SetWideIntObj, and Tcl_SetBignumObj, this points to the value in which to store an integral value. For Tcl_GetInt‐ FromObj, Tcl_GetLongFromObj, Tcl_GetWideIntFromObj, Tcl_Get‐ BignumFromObj, and Tcl_Take‐ BignumFromObj, this refers to the value from which to retrieve an integral value. Tcl_Interp *interp (in/out) When non-NULL, an error message is left here when integral value retrieval fails. int *intPtr (out) Points to place to store the in‐ teger value retrieved from ob‐ jPtr. long *longPtr (out) Points to place to store the long integer value retrieved from ob‐ jPtr. Tcl_WideInt *widePtr (out) Points to place to store the wide integer value retrieved from ob‐ jPtr. mp_int *bigValue (in/out) Points to a multi-precision inte‐ ger structure declared by the LibTomMath library. double doubleValue (in) Double value from which the inte‐ ger part is determined and used to initialize a multi-precision integer value. ______________________________________________________________________________ DESCRIPTION These procedures are used to create, modify, and read Tcl values that hold integral values. The different routines exist to accommodate different integral types in C with which values might be exchanged. The C integral types for which Tcl provides value exchange routines are int, long int, Tcl_WideInt, and mp_int. The int and long int types are provided by the C language standard. The Tcl_WideInt type is a typedef defined to be whatever signed integral type covers at least the 64-bit integer range (-9223372036854775808 to 9223372036854775807). Depending on the plat‐ form and the C compiler, the actual type might be long int, long long int, __int64, or something else. The mp_int type is a multiple-preci‐ sion integer type defined by the LibTomMath multiple-precision integer library. The Tcl_NewIntObj, Tcl_NewLongObj, Tcl_NewWideIntObj, and Tcl_NewBignu‐ mObj routines each create and return a new Tcl value initialized to the integral value of the argument. The returned Tcl value is unshared. The Tcl_SetIntObj, Tcl_SetLongObj, Tcl_SetWideIntObj, and Tcl_SetBignu‐ mObj routines each set the value of an existing Tcl value pointed to by objPtr to the integral value provided by the other argument. The ob‐ jPtr argument must point to an unshared Tcl value. Any attempt to set the value of a shared Tcl value violates Tcl's copy-on-write policy. Any existing string representation or internal representation in the unshared Tcl value will be freed as a consequence of setting the new value. The Tcl_GetIntFromObj, Tcl_GetLongFromObj, Tcl_GetWideIntFromObj, Tcl_GetBignumFromObj, and Tcl_TakeBignumFromObj routines attempt to re‐ trieve an integral value of the appropriate type from the Tcl value ob‐ jPtr. If the attempt succeeds, then TCL_OK is returned, and the value is written to the storage provided by the caller. The attempt might fail if objPtr does not hold an integral value, or if the value exceeds the range of the target type. If the attempt fails, then TCL_ERROR is returned, and if interp is non-NULL, an error message is left in in‐ terp. The Tcl_ObjType of objPtr may be changed to make subsequent calls to the same routine more efficient. Unlike the other functions, Tcl_TakeBignumFromObj may set the content of the Tcl value objPtr to an empty string in the process of retrieving the multiple-precision inte‐ ger value. The choice between Tcl_GetBignumFromObj and Tcl_TakeBignumFromObj is governed by how the caller will continue to use objPtr. If after the mp_int value is retrieved from objPtr, the caller will make no more use of objPtr, then using Tcl_TakeBignumFromObj permits Tcl to detect when an unshared objPtr permits the value to be moved instead of copied, which should be more efficient. If anything later in the caller re‐ quires objPtr to continue to hold the same value, then Tcl_GetBignum‐ FromObj must be chosen. The Tcl_InitBignumFromDouble routine is a utility procedure that ex‐ tracts the integer part of doubleValue and stores that integer value in the mp_int value bigValue. SEE ALSO Tcl_NewObj, Tcl_DecrRefCount, Tcl_IncrRefCount, Tcl_GetObjResult KEYWORDS integer, integer value, integer type, internal representation, value, value type, string representation Tcl 8.5 Tcl_IntObj(3)
Tcl_Eval(3) Процедуры библиотеки Tcl Tcl_Eval(3) ______________________________________________________________________________ NAME Tcl_EvalObjEx, Tcl_EvalFile, Tcl_EvalObjv, Tcl_Eval, Tcl_EvalEx, Tcl_GlobalEval, Tcl_GlobalEvalObj, Tcl_VarEval, Tcl_VarEvalVA - выполнить Tcl-скрипты SYNOPSIS #include <tcl.h> int Tcl_EvalObjEx(interp, objPtr, flags) int Tcl_EvalFile(interp, fileName) int Tcl_EvalObjv(interp, objc, objv, flags) int Tcl_Eval(interp, script) int Tcl_EvalEx(interp, script, numBytes, flags) int Tcl_GlobalEval(interp, script) int Tcl_GlobalEvalObj(interp, objPtr) int Tcl_VarEval(interp, part, part, ... (char *)NULL) int Tcl_VarEvalVA(interp, argList) ARGUMENTS Tcl_Interp *interp (in) Интерпретатор, в котором выполнять скрипт. Результат интерпретатора изменяется для хранения результата или сообщения об ошибке от скрипта. Tcl_Obj *objPtr (in) Значение Tcl, содержащее скрипт для выполнения. int flags (in) Комбинация бит флагов, объединенных с помощью OR, которые указывают дополнительные опции. Поддерживаются TCL_EVAL_GLOBAL и TCL_EVAL_DIRECT. const char *fileName (in) Имя файла, содержащего Tcl-скрипт. int objc (in) Количество значений в массиве, на который указывает objv; это также количество слов в команде. Tcl_Obj **objv (in) Указатель на массив указателей на значения; каждое значение содержит значение одного слова в команде для выполнения. int numBytes (in) Количество байтов в script, не включая завершающий нулевой символ. Если -1, то используются все символы до первого нулевого байта. const char *script (in) Указатель на первый байт скрипта для выполнения (завершается нулевым символом и является UTF-8). const char *part (in) Строка, образующая часть Tcl-скрипта. va_list argList (in) Список аргументов, который должен быть инициализирован с помощью va_start и очищен с помощью va_end. ______________________________________________________________________________ DESCRIPTION Процедуры, описанные здесь, вызываются для выполнения Tcl-скриптов в различных формах. Tcl_EvalObjEx является основной процедурой и используется многими другими. Она выполняет команды в скрипте, хранящемся в objPtr, до тех пор, пока не произойдет ошибка или не будет достигнут конец скрипта. Если это первое выполнение objPtr, его команды компилируются в инструкции байт-кода, которые затем выполняются. Байт-код сохраняется в objPtr, чтобы пропустить шаг компиляции, если значение будет оценено снова в будущем. Значение возврата от Tcl_EvalObjEx (и всех других описанных здесь процедур) является кодом завершения Tcl с одним из значений TCL_OK, TCL_ERROR, TCL_RETURN, TCL_BREAK или TCL_CONTINUE, или, возможно, каким-то другим целочисленным значением, происходящим из расширения. Кроме того, значение результата или сообщение об ошибке оставляется в результате interp; его можно получить с помощью Tcl_GetObjResult. Tcl_EvalFile читает файл, указанный в fileName, и оценивает его содержимое как Tcl-скрипт. Он возвращает ту же информацию, что и Tcl_EvalOb‐ jEx. Если файл не удалось прочитать, возвращается ошибка Tcl, описывающая, почему файл не удалось прочитать. Символ конца файла для файлов — "\32" (^Z) для всех платформ. Если вам нужен "^Z" в коде для сравнения строк, вы можете использовать "\032" или "\u001a", который будет безопасно заменен интерпретатором Tcl на "^Z". Tcl_EvalObjv выполняет одну предварительно разобранную команду вместо скрипта. Аргументы objc и objv содержат значения слов для команды Tcl, одно слово в каждом значении в objv. Tcl_EvalObjv оценивает команду и возвращает код завершения и результат, как и Tcl_EvalOb‐ jEx. Вызывающий Tcl_EvalObjv должен управлять счетчиком ссылок элементов objv, обеспечивая, что значения действительны до возврата Tcl_EvalObjv. Tcl_Eval похож на Tcl_EvalObjEx, за исключением того, что скрипт для выполнения предоставляется в виде строки вместо значения и компиляция не происходит. Строка должна быть правильной строкой UTF-8, как преобразованной Tcl_ExternalToUtfDString или Tcl_ExternalToUtf, когда известно, что она может содержать символы верхнего ASCII, возможные комбинации которых могут быть специальным кодом UTF-8. Строка разбирается и выполняется напрямую (с помощью Tcl_EvalObjv) вместо компиляции и выполнения байт-кода. В ситуациях, где известно, что скрипт никогда не будет выполнен снова, Tcl_Eval может быть быстрее, чем Tcl_EvalObjEx. Tcl_Eval возвращает код завершения и результат, как и Tcl_EvalObjEx. Примечание: для обратной совместимости с версиями до Tcl 8.0, Tcl_Eval копирует значение результата в interp в interp->result (использование устарело), где его можно получить напрямую. Это делает Tcl_Eval немного медленнее, чем Tcl_EvalEx, который не выполняет копирование. Tcl_EvalEx является расширенной версией Tcl_Eval, которая принимает дополнительные аргументы numBytes и flags. По причинам эффективности, указанным выше, Tcl_EvalEx обычно предпочтительнее, чем Tcl_Eval. Tcl_GlobalEval и Tcl_GlobalEvalObj являются старыми процедурами, которые теперь устарели. Они похожи на Tcl_EvalEx и Tcl_EvalObjEx, за исключением того, что скрипт оценивается в глобальном пространстве имен, и его контекст переменных состоит только из глобальных переменных (он игнорирует любые активные Tcl-процедуры). Эти функции эквивалентны использованию флага TCL_EVAL_GLOBAL (см. ниже). Tcl_VarEval принимает любое количество строковых аргументов любой длины, объединяет их в одну строку, затем вызывает Tcl_Eval для выполнения этой строки как Tcl-команды. Он возвращает результат команды и также изменяет interp->result так же, как Tcl_Eval. Последний аргумент Tcl_VarEval должен быть (char *)NULL, чтобы указать конец аргументов. Tcl_VarEvalVA аналогичен Tcl_VarEval, за исключением того, что вместо переменного количества аргументов он принимает список аргументов. Tcl_VarEvalVA теперь устарел. FLAG BITS Любая комбинация следующих значений, объединенных с помощью OR, может использоваться для аргумента flags в процедурах, таких как Tcl_EvalObjEx: TCL_EVAL_DIRECT Этот флаг используется только Tcl_EvalObjEx; он игнорируется другими процедурами. Если этот бит флага установлен, скрипт не компилируется в байт-код; вместо этого он выполняется напрямую, как в Tcl_EvalEx. Флаг TCL_EVAL_DIRECT полезен в ситуациях, где содержимое значения изменится немедленно, поэтому байт-код не будет повторно использоваться в будущем выполнении. В этом случае быстрее выполнить скрипт напрямую. TCL_EVAL_GLOBAL Если этот флаг установлен, скрипт оценивается в глобальном пространстве имен вместо текущего пространства имен, и его контекст переменных состоит только из глобальных переменных (он игнорирует любые активные Tcl-процедуры). MISCELLANEOUS DETAILS Во время обработки Tcl-команды допустимо делать вложенные вызовы для оценки других команд (это то, как реализуются процедуры и некоторые структуры управления). Если код, отличный от TCL_OK, возвращается из вложенного вызова Tcl_EvalObjEx, вызывающий обычно должен вернуться немедленно, передавая этот же код возврата своему вызывающему, и так далее, пока не будет достигнуто приложение верхнего уровня. Несколько команд, таких как for, проверяют определенные коды возврата, такие как TCL_BREAK и TCL_CONTINUE, и обрабатывают их специально без возврата. Tcl_EvalObjEx отслеживает, сколько вложенных вызовов Tcl_EvalObjEx выполняется для interp. Если код TCL_RETURN, TCL_BREAK или TCL_CONTINUE готовится к возврату из верхнего Tcl_EvalObjEx вызова для interp, он преобразует код возврата в TCL_ERROR и устанавливает результат interp в сообщение об ошибке, указывающее, что команда return, break или continue была вызвана в неподходящем месте. Это значит, что приложения верхнего уровня никогда не должны видеть код возврата от Tcl_EvalObjEx, отличный от TCL_OK или TCL_ERROR. KEYWORDS execute, file, global, result, script, value Tcl 8.1 Tcl_Eval(3)
Tcl_Eval(3) Tcl Library Procedures Tcl_Eval(3) ______________________________________________________________________________ NAME Tcl_EvalObjEx, Tcl_EvalFile, Tcl_EvalObjv, Tcl_Eval, Tcl_EvalEx, Tcl_GlobalEval, Tcl_GlobalEvalObj, Tcl_VarEval, Tcl_VarEvalVA - execute Tcl scripts SYNOPSIS #include <tcl.h> int Tcl_EvalObjEx(interp, objPtr, flags) int Tcl_EvalFile(interp, fileName) int Tcl_EvalObjv(interp, objc, objv, flags) int Tcl_Eval(interp, script) int Tcl_EvalEx(interp, script, numBytes, flags) int Tcl_GlobalEval(interp, script) int Tcl_GlobalEvalObj(interp, objPtr) int Tcl_VarEval(interp, part, part, ... (char *)NULL) int Tcl_VarEvalVA(interp, argList) ARGUMENTS Tcl_Interp *interp (in) Interpreter in which to execute the script. The interpreter's result is modified to hold the result or error message from the script. Tcl_Obj *objPtr (in) A Tcl value containing the script to execute. int flags (in) OR'ed combination of flag bits that specify additional options. TCL_EVAL_GLOBAL and TCL_EVAL_DIRECT are currently supported. const char *fileName (in) Name of a file containing a Tcl script. int objc (in) The number of values in the array pointed to by objv; this is also the number of words in the command. Tcl_Obj **objv (in) Points to an array of pointers to values; each value holds the value of a single word in the command to execute. int numBytes (in) The number of bytes in script, not including any null terminating char‐ acter. If -1, then all characters up to the first null byte are used. const char *script (in) Points to first byte of script to execute (null-terminated and UTF-8). const char *part (in) String forming part of a Tcl script. va_list argList (in) An argument list which must have been initialized using va_start, and cleared using va_end. ______________________________________________________________________________ DESCRIPTION The procedures described here are invoked to execute Tcl scripts in various forms. Tcl_EvalObjEx is the core procedure and is used by many of the others. It executes the commands in the script stored in objPtr until either an error occurs or the end of the script is reached. If this is the first time objPtr has been executed, its commands are com‐ piled into bytecode instructions which are then executed. The byte‐ codes are saved in objPtr so that the compilation step can be skipped if the value is evaluated again in the future. The return value from Tcl_EvalObjEx (and all the other procedures de‐ scribed here) is a Tcl completion code with one of the values TCL_OK, TCL_ERROR, TCL_RETURN, TCL_BREAK, or TCL_CONTINUE, or possibly some other integer value originating in an extension. In addition, a result value or error message is left in interp's result; it can be retrieved using Tcl_GetObjResult. Tcl_EvalFile reads the file given by fileName and evaluates its con‐ tents as a Tcl script. It returns the same information as Tcl_EvalOb‐ jEx. If the file could not be read then a Tcl error is returned to de‐ scribe why the file could not be read. The eofchar for files is “\32” (^Z) for all platforms. If you require a “^Z” in code for string com‐ parison, you can use “\032” or “\u001a”, which will be safely substi‐ tuted by the Tcl interpreter into “^Z”. Tcl_EvalObjv executes a single preparsed command instead of a script. The objc and objv arguments contain the values of the words for the Tcl command, one word in each value in objv. Tcl_EvalObjv evaluates the command and returns a completion code and result just like Tcl_EvalOb‐ jEx. The caller of Tcl_EvalObjv has to manage the reference count of the elements of objv, insuring that the values are valid until Tcl_EvalObjv returns. Tcl_Eval is similar to Tcl_EvalObjEx except that the script to be exe‐ cuted is supplied as a string instead of a value and no compilation oc‐ curs. The string should be a proper UTF-8 string as converted by Tcl_ExternalToUtfDString or Tcl_ExternalToUtf when it is known to pos‐ sibly contain upper ASCII characters whose possible combinations might be a UTF-8 special code. The string is parsed and executed directly (using Tcl_EvalObjv) instead of compiling it and executing the byte‐ codes. In situations where it is known that the script will never be executed again, Tcl_Eval may be faster than Tcl_EvalObjEx. Tcl_Eval returns a completion code and result just like Tcl_EvalObjEx. Note: for backward compatibility with versions before Tcl 8.0, Tcl_Eval copies the value result in interp to interp->result (use is deprecated) where it can be accessed directly. This makes Tcl_Eval somewhat slower than Tcl_EvalEx, which does not do the copy. Tcl_EvalEx is an extended version of Tcl_Eval that takes additional ar‐ guments numBytes and flags. For the efficiency reason given above, Tcl_EvalEx is generally preferred over Tcl_Eval. Tcl_GlobalEval and Tcl_GlobalEvalObj are older procedures that are now deprecated. They are similar to Tcl_EvalEx and Tcl_EvalObjEx except that the script is evaluated in the global namespace and its variable context consists of global variables only (it ignores any Tcl proce‐ dures that are active). These functions are equivalent to using the TCL_EVAL_GLOBAL flag (see below). Tcl_VarEval takes any number of string arguments of any length, con‐ catenates them into a single string, then calls Tcl_Eval to execute that string as a Tcl command. It returns the result of the command and also modifies interp->result in the same way as Tcl_Eval. The last ar‐ gument to Tcl_VarEval must be (char *)NULL to indicate the end of argu‐ ments. Tcl_VarEvalVA is the same as Tcl_VarEval except that instead of taking a variable number of arguments it takes an argument list. Tcl_VarEvalVA is now deprecated. FLAG BITS Any OR'ed combination of the following values may be used for the flags argument to procedures such as Tcl_EvalObjEx: TCL_EVAL_DIRECT This flag is only used by Tcl_EvalObjEx; it is ignored by other procedures. If this flag bit is set, the script is not compiled to bytecodes; instead it is executed directly as is done by Tcl_EvalEx. The TCL_EVAL_DIRECT flag is useful in situations where the contents of a value are going to change immediately, so the bytecodes will not be reused in a future execution. In this case, it is faster to execute the script directly. TCL_EVAL_GLOBAL If this flag is set, the script is evaluated in the global namespace instead of the current namespace and its variable context consists of global variables only (it ignores any Tcl proce‐ dures that are active). MISCELLANEOUS DETAILS During the processing of a Tcl command it is legal to make nested calls to evaluate other commands (this is how procedures and some control structures are implemented). If a code other than TCL_OK is returned from a nested Tcl_EvalObjEx invocation, then the caller should normally return immediately, passing that same return code back to its caller, and so on until the top-level application is reached. A few commands, like for, will check for certain return codes, like TCL_BREAK and TCL_CONTINUE, and process them specially without returning. Tcl_EvalObjEx keeps track of how many nested Tcl_EvalObjEx invocations are in progress for interp. If a code of TCL_RETURN, TCL_BREAK, or TCL_CONTINUE is about to be returned from the topmost Tcl_EvalObjEx in‐ vocation for interp, it converts the return code to TCL_ERROR and sets interp's result to an error message indicating that the return, break, or continue command was invoked in an inappropriate place. This means that top-level applications should never see a return code from Tcl_EvalObjEx other than TCL_OK or TCL_ERROR. KEYWORDS execute, file, global, result, script, value Tcl 8.1 Tcl_Eval(3)
Tcl_CreateChannel(3) Процедуры Tcl Библиотеки Tcl_CreateChannel(3) ______________________________________________________________________________ NAME Tcl_CreateChannel, Tcl_GetChannelInstanceData, Tcl_GetChannelType, Tcl_GetChannelName, Tcl_GetChannelHandle, Tcl_GetChannelMode, Tcl_GetChannelBufferSize, Tcl_SetChannelBufferSize, Tcl_NotifyChannel, Tcl_BadChannelOption, Tcl_ChannelName, Tcl_ChannelVersion, Tcl_Channel‐ BlockModeProc, Tcl_ChannelCloseProc, Tcl_ChannelClose2Proc, Tcl_Chan‐ nelInputProc, Tcl_ChannelOutputProc, Tcl_ChannelSeekProc, Tcl_Channel‐ WideSeekProc, Tcl_ChannelTruncateProc, Tcl_ChannelSetOptionProc, Tcl_ChannelGetOptionProc, Tcl_ChannelWatchProc, Tcl_ChannelGetH‐ andleProc, Tcl_ChannelFlushProc, Tcl_ChannelHandlerProc, Tcl_Chan‐ nelThreadActionProc, Tcl_IsChannelShared, Tcl_IsChannelRegistered, Tcl_CutChannel, Tcl_SpliceChannel, Tcl_IsChannelExisting, Tcl_ClearChannelHandlers, Tcl_GetChannelThread, Tcl_ChannelBuffered - процедуры для создания и манипулирования каналами SYNOPSIS #include <tcl.h> Tcl_Channel Tcl_CreateChannel(typePtr, channelName, instanceData, mask) ClientData Tcl_GetChannelInstanceData(channel) const Tcl_ChannelType * Tcl_GetChannelType(channel) const char * Tcl_GetChannelName(channel) int Tcl_GetChannelHandle(channel, direction, handlePtr) Tcl_ThreadId Tcl_GetChannelThread(channel) int Tcl_GetChannelMode(channel) int Tcl_GetChannelBufferSize(channel) Tcl_SetChannelBufferSize(channel, size) Tcl_NotifyChannel(channel, mask) int Tcl_BadChannelOption(interp, optionName, optionList) int Tcl_IsChannelShared(channel) int Tcl_IsChannelRegistered(interp, channel) int Tcl_IsChannelExisting(channelName) void Tcl_CutChannel(channel) void Tcl_SpliceChannel(channel) void Tcl_ClearChannelHandlers(channel) int Tcl_ChannelBuffered(channel) const char * Tcl_ChannelName(typePtr) Tcl_ChannelTypeVersion Tcl_ChannelVersion(typePtr) Tcl_DriverBlockModeProc * Tcl_ChannelBlockModeProc(typePtr) Tcl_DriverCloseProc * Tcl_ChannelCloseProc(typePtr) Tcl_DriverClose2Proc * Tcl_ChannelClose2Proc(typePtr) Tcl_DriverInputProc * Tcl_ChannelInputProc(typePtr) Tcl_DriverOutputProc * Tcl_ChannelOutputProc(typePtr) Tcl_DriverSeekProc * Tcl_ChannelSeekProc(typePtr) Tcl_DriverWideSeekProc * Tcl_ChannelWideSeekProc(typePtr) Tcl_DriverThreadActionProc * Tcl_ChannelThreadActionProc(typePtr) Tcl_DriverTruncateProc * Tcl_ChannelTruncateProc(typePtr) Tcl_DriverSetOptionProc * Tcl_ChannelSetOptionProc(typePtr) Tcl_DriverGetOptionProc * Tcl_ChannelGetOptionProc(typePtr) Tcl_DriverWatchProc * Tcl_ChannelWatchProc(typePtr) Tcl_DriverGetHandleProc * Tcl_ChannelGetHandleProc(typePtr) Tcl_DriverFlushProc * Tcl_ChannelFlushProc(typePtr) Tcl_DriverHandlerProc * Tcl_ChannelHandlerProc(typePtr) ARGUMENTS const Tcl_ChannelType *typePtr (in) Указывает на структуру, содержащую адреса процедур, которые могут быть вызваны для выполнения ввода-вывода и других функций на канале. const char *channelName (in) Имя этого канала, такое как file3; не должно использоваться ни в каком другом канале. Может быть NULL, в этом случае канал создается без имени. Если созданный канал назначается одному из стандартных каналов (stdin, stdout или stderr), то назначенное имя канала будет именем стандартного канала. ClientData instanceData (in) Произвольное значение одного слова, связанное с этим каналом. Это значение передается процедурам в typePtr при их вызове. int mask (in) Комбинация, объединенная операцией ИЛИ, из TCL_READABLE и TCL_WRITABLE, указывающая, читаем ли канал и записываем ли в него. Tcl_Channel channel (in) Канал, на котором выполняется операция. int direction (in) TCL_READABLE означает, что требуется дескриптор ввода; TCL_WRITABLE означает, что требуется дескриптор вывода. ClientData *handlePtr (out) Указывает на место, где должен быть сохранен требуемый специфичный для ОС дескриптор. int size (in) Размер, в байтах, буферов, которые будут выделены в этом канале. int mask (in) Комбинация, объединенная операцией ИЛИ, из TCL_READABLE, TCL_WRITABLE и TCL_EXCEPTION, указывающая события, которые произошли на этом канале. Tcl_Interp *interp (in) Текущий интерпретатор. (может быть NULL) const char *optionName (in) Имя недопустимого параметра. const char *optionList (in) Специфический список параметров (слова, разделенные пробелами, без "-"), который добавляется к стандартному списку общих параметров. Может быть NULL для сообщения об ошибке только общих параметров. ______________________________________________________________________________ DESCRIPTION Tcl использует двухуровневую архитектуру каналов. Она предоставляет общий верхний уровень для того, чтобы программы на C и Tcl могли выполнять ввод и вывод с использованием одних и тех же API для различных файлов, устройств, сокетов и т.д. Общие API на C описаны в руководстве по Tcl_OpenFileChannel. Нижний уровень предоставляет специфические для типа драйверы каналов для каждого типа устройства, поддерживаемого на каждой платформе. Это руководство описывает API на C, используемые для общения между общим уровнем и специфическими для типа драйверами каналов. Оно также объясняет, как добавить новые типы каналов, предоставив новые драйверы каналов. Драйверы каналов состоят из нескольких компонентов: Во-первых, каждый драйвер канала предоставляет структуру Tcl_ChannelType, содержащую указатели на функции, реализующие различные операции, используемые общим уровнем для общения с драйвером канала. Структура Tcl_ChannelType и функции, на которые она ссылается, описаны в разделе TCL_CHANNELTYPE ниже. Во-вторых, драйверы каналов обычно предоставляют команду Tcl для создания экземпляров этого типа канала. Например, команда Tcl open создает каналы, которые используют драйверы файлов и команд, а команда Tcl socket создает каналы, которые используют TCP-сокеты для сетевой связи. В-третьих, драйвер канала опционально предоставляет функцию C для открытия экземпляров канала этого типа. Например, Tcl_OpenFileChannel открывает канал, который использует драйвер файлового канала, а Tcl_OpenTcpClient открывает канал, который использует протокол TCP сети. Эти функции создания обычно используют Tcl_CreateChannel внутренне для открытия канала. Чтобы добавить новый тип канала, вы должны реализовать API на C или команду Tcl, которая открывает канал, вызывая Tcl_CreateChannel. Когда ваш драйвер вызывает Tcl_CreateChannel, он передает структуру Tcl_ChannelType, описывающую процедуры ввода-вывода драйвера. Общий уровень затем вызовет функции, на которые ссылается в этой структуре, для выполнения операций на канале. Tcl_CreateChannel открывает новый канал и связывает с ним предоставленный typePtr и instanceData. Канал открывается в режиме, указанном mask. Для обсуждения драйверов каналов, их операций и структуры Tcl_ChannelType см. раздел TCL_CHANNELTYPE ниже. Tcl_CreateChannel взаимодействует с кодом, управляющим стандартными каналами. После того, как стандартный канал был инициализирован либо через вызов Tcl_GetStdChannel, либо через вызов Tcl_SetStdChannel, закрытие этого стандартного канала приведет к тому, что следующий вызов Tcl_CreateChannel сделает новый канал новым стандартным каналом тоже. См. Tcl_StandardChannels для общего трактата о стандартных каналах и поведении библиотеки Tcl по отношению к ним. Tcl_GetChannelInstanceData возвращает данные экземпляра, связанные с каналом в channel. Это то же самое, что и аргумент instanceData в вызове Tcl_CreateChannel, который создал этот канал. Tcl_GetChannelType возвращает указатель на структуру Tcl_ChannelType, используемую каналом в аргументе channel. Это то же самое, что и аргумент typePtr в вызове Tcl_CreateChannel, который создал этот канал. Tcl_GetChannelName возвращает строку, содержащую имя, связанное с каналом, или NULL, если аргумент channelName в Tcl_CreateChannel был NULL. Tcl_GetChannelHandle размещает специфичный для ОС дескриптор устройства, связанный с каналом для заданного направления, в месте, указанном handlePtr, и возвращает TCL_OK. Если канал не имеет дескриптора устройства для указанного направления, то возвращается TCL_ERROR. Разные драйверы каналов вернут разные типы дескрипторов. Обращайтесь к руководствам для каждого драйвера, чтобы определить, какой тип дескриптора возвращается. Tcl_GetChannelThread возвращает идентификатор потока, который в настоящее время управляет указанным каналом. Это позволяет драйверам каналов отправлять свои события файлов в правильную очередь событий, даже для многопоточного ядра. Tcl_GetChannelMode возвращает комбинацию, объединенную операцией ИЛИ, из TCL_READABLE и TCL_WRITABLE, указывающую, открыт ли канал для ввода и вывода. Tcl_GetChannelBufferSize возвращает размер, в байтах, буферов, выделенных для хранения ввода или вывода в канале. Если значение не было установлено предыдущим вызовом Tcl_SetChannelBufferSize, описанным ниже, то возвращается значение по умолчанию 4096. Tcl_SetChannelBufferSize устанавливает размер, в байтах, буферов, которые будут выделены в последующих операциях на канале для хранения ввода или вывода. Аргумент size должен быть от одного до одного миллиона, позволяя буферам от одного байта до одного миллиона байт. Если size выходит за пределы этого диапазона, Tcl_SetChannelBufferSize устанавливает размер буфера в 4096. Tcl_NotifyChannel вызывается драйвером канала, чтобы указать общему уровню, что события, указанные mask, произошли на канале. Драйверы каналов несут ответственность за вызов этой функции всякий раз, когда обработчики канала должны быть вызваны для канала (или должны быть выполнены другие ожидающие задачи, такие как слив записи). См. WATCHPROC ниже для получения более подробной информации. Tcl_BadChannelOption вызывается из setOptionProc или getOptionProc, специфичных для драйвера, для генерации полного сообщения об ошибке. Tcl_ChannelBuffered возвращает количество байтов ввода, в настоящее время буферизованных во внутреннем буфере (области отката) самого канала. Он не сообщает о данных в общих буферах для стека каналов, к которому принадлежит поставляемый канал. Tcl_IsChannelShared проверяет счетчик ссылок указанного канала и возвращает, делится ли канал между несколькими интерпретаторами (результат == 1) или нет (результат == 0). Tcl_IsChannelRegistered проверяет, зарегистрирован ли указанный канал в данном интерпретаторе (результат == 1) или нет (результат == 0). Tcl_IsChannelExisting проверяет, существует ли канал с указанным именем в (потоково)-глобальном списке всех каналов (результат == 1) или нет (результат == 0). Tcl_CutChannel удаляет указанный канал из (потоково)-глобального списка всех каналов (текущего потока). Применение к каналу, все еще зарегистрированному в каком-то интерпретаторе, не допускается. Также уведомляет драйвер, если версия Tcl_ChannelType равна TCL_CHANNEL_VERSION_4 (или выше), и Tcl_DriverThreadActionProc определена для него. Tcl_SpliceChannel добавляет указанный канал в (потоково)-глобальный список всех каналов (текущего потока). Применение к каналу, зарегистрированному в каком-то интерпретаторе, не допускается. Также уведомляет драйвер, если версия Tcl_ChannelType равна TCL_CHANNEL_VERSION_4 (или выше), и Tcl_DriverThreadActionProc определена для него. Tcl_ClearChannelHandlers удаляет все обработчики канала и сценарии событий, связанные с указанным каналом, тем самым отключая всю обработку событий для этого канала. TCL_CHANNELTYPE Драйвер канала предоставляет структуру Tcl_ChannelType, содержащую указатели на функции, реализующие различные операции на канале; эти операции вызываются по необходимости общим уровнем. Структура была версионирована, начиная с Tcl 8.3.2/8.4, для исправления проблемы со стековыми драйверами каналов. См. раздел OLD CHANNEL TYPES ниже для деталей о старой структуре. Структура Tcl_ChannelType содержит следующие поля: typedef struct Tcl_ChannelType { const char *typeName; Tcl_ChannelTypeVersion version; Tcl_DriverCloseProc *closeProc; Tcl_DriverInputProc *inputProc; Tcl_DriverOutputProc *outputProc; Tcl_DriverSeekProc *seekProc; Tcl_DriverSetOptionProc *setOptionProc; Tcl_DriverGetOptionProc *getOptionProc; Tcl_DriverWatchProc *watchProc; Tcl_DriverGetHandleProc *getHandleProc; Tcl_DriverClose2Proc *close2Proc; Tcl_DriverBlockModeProc *blockModeProc; Tcl_DriverFlushProc *flushProc; Tcl_DriverHandlerProc *handlerProc; Tcl_DriverWideSeekProc *wideSeekProc; Tcl_DriverThreadActionProc *threadActionProc; Tcl_DriverTruncateProc *truncateProc; } Tcl_ChannelType; Не обязательно предоставлять реализации для всех операций канала. Те, которые не нужны, могут быть установлены в NULL в структуре: blockModeProc, seekProc, setOptionProc, getOptionProc, getHandleProc и close2Proc, в дополнение к flushProc, handlerProc, threadActionProc и truncateProc. Другие функции, которые не могут быть реализованы осмысленным образом, должны возвращать EINVAL при вызове, чтобы указать, что операции, которые они представляют, недоступны. Также отметьте, что wideSeekProc может быть NULL, если seekProc таковым является. Пользователь должен использовать только вышеуказанную структуру для инстанцирования Tcl_ChannelType. При ссылке на поля в структуре Tcl_ChannelType следует использовать следующие функции для получения значений: Tcl_ChannelName, Tcl_ChannelVersion, Tcl_ChannelBlockModeProc, Tcl_ChannelCloseProc, Tcl_ChannelClose2Proc, Tcl_ChannelInputProc, Tcl_ChannelOutputProc, Tcl_ChannelSeekProc, Tcl_ChannelWideSeekProc, Tcl_ChannelThreadActionProc, Tcl_ChannelTruncateProc, Tcl_ChannelSetOptionProc, Tcl_ChannelGetOptionProc, Tcl_ChannelWatchProc, Tcl_ChannelGetHandleProc, Tcl_ChannelFlushProc или Tcl_ChannelHandlerProc. Изменение структуры было сделано так, чтобы стандартные типы каналов были бинарно совместимы. Однако, типы каналов, которые используют стековые каналы (т.е. TLS, Trf), имеют новые версии, соответствующие вышеуказанному изменению, поскольку предыдущий код для стековых каналов имел проблемы. TYPENAME Поле typeName содержит нулем завершаемую строку, которая идентифицирует тип устройства, реализованного этим драйвером, например, file или socket. Это значение можно получить с помощью Tcl_ChannelName, которое возвращает указатель на строку. VERSION Поле version должно быть установлено в версию структуры, которую вы требуете. TCL_CHANNEL_VERSION_2 является минимально рекомендуемой. TCL_CHANNEL_VERSION_3 должно быть установлено для указания члена wideSeekProc. TCL_CHANNEL_VERSION_4 должно быть установлено для указания члена threadActionProc (включая wideSeekProc). TCL_CHANNEL_VERSION_5 должно быть установлено для указания членов truncateProc (включая wideSeekProc и threadActionProc). Если оно не установлено ни в одно из этих, то предполагается, что Tcl_ChannelType имеет исходную структуру. См. OLD CHANNEL TYPES для получения более подробной информации. Хотя Tcl будет распознавать и работать с любой из этих структур, стековые каналы должны быть как минимум TCL_CHANNEL_VERSION_2, чтобы работать правильно. Это значение можно получить с помощью Tcl_ChannelVersion, которое возвращает одно из TCL_CHANNEL_VERSION_5, TCL_CHANNEL_VERSION_4, TCL_CHANNEL_VERSION_3, TCL_CHANNEL_VERSION_2 или TCL_CHANNEL_VERSION_1. BLOCKMODEPROC Поле blockModeProc содержит адрес функции, вызываемой общим уровнем для установки режима блокировки и неблокировки на устройстве. BlockModeProc должна соответствовать следующему прототипу: typedef int Tcl_DriverBlockModeProc( ClientData instanceData, int mode); Аргумент instanceData такой же, как значение, переданное Tcl_CreateChannel при создании этого канала. Аргумент mode равен либо TCL_MODE_BLOCKING, либо TCL_MODE_NONBLOCKING для установки устройства в режим блокировки или неблокировки. Функция должна возвращать ноль, если операция прошла успешно, или ненулевой код ошибки POSIX, если операция завершилась неудачей. Если операция успешна, функция может изменить предоставленный instanceData для записи того, что канал вошел в режим блокировки или неблокировки, и для реализации поведения блокировки или неблокировки. Для некоторых типов устройств поведение блокировки и неблокировки может быть реализовано базовой операционной системой; для других типов устройств поведение должно эмулироваться в драйвере канала. Это значение можно получить с помощью Tcl_ChannelBlockModeProc, которое возвращает указатель на функцию. Драйвер канала, не предоставляющий blockModeProc, должен быть очень, очень осторожным. Он должен точно сообщить общему уровню, какой режим блокировки приемлем для него, и также задокументировать это для пользователя, чтобы режим блокировки канала не изменился на неприемлемое значение. Любая путаница здесь может привести интерпретатор в тупик (ложный и трудно обнаруживаемый). CLOSEPROC AND CLOSE2PROC Поле closeProc содержит адрес функции, вызываемой общим уровнем для очистки информации, связанной с драйвером, при закрытии канала. CloseProc должна соответствовать следующему прототипу: typedef int Tcl_DriverCloseProc( ClientData instanceData, Tcl_Interp *interp); Аргумент instanceData такой же, как значение, предоставленное Tcl_CreateChannel при создании канала. Функция должна освободить любое хранилище, поддерживаемое драйвером канала для этого канала, и закрыть устройства ввода и вывода, инкапсулированные этим каналом. Все очередированный вывод будет слит в устройство перед вызовом этой функции, и никакие дальнейшие операции драйвера не будут вызваны для этого экземпляра после вызова closeProc. Если операция закрытия прошла успешно, процедура должна возвращать ноль; в противном случае она должна возвращать ненулевой код ошибки POSIX. Кроме того, если возникает ошибка и interp не равно NULL, процедура должна хранить сообщение об ошибке в результате интерпретатора. В качестве альтернативы, каналы, которые поддерживают закрытие сторон чтения и записи независимо, могут установить closeProc в TCL_CLOSE2PROC и установить close2Proc на адрес функции, которая соответствует следующему прототипу: typedef int Tcl_DriverClose2Proc( ClientData instanceData, Tcl_Interp *interp, int flags); Close2Proc будет вызвана с флагами, установленными в комбинацию, объединенную операцией ИЛИ, TCL_CLOSE_READ или TCL_CLOSE_WRITE, чтобы указать, что драйвер должен закрыть сторону чтения и/или записи канала. Драйвер канала может быть вызван для выполнения дополнительных операций на канале после вызова close2Proc для закрытия одной или обеих сторон канала. Если флаги равны 0 (нулю), драйвер должен закрыть канал так, как описано выше для closeProc. Никакие дальнейшие операции не будут вызваны для этого экземпляра после вызова close2Proc со всеми флагами, очищенными. Во всех случаях функция close2Proc должна возвращать ноль, если операция закрытия прошла успешно; в противном случае она должна возвращать ненулевой код ошибки POSIX. Кроме того, если возникает ошибка и interp не равно NULL, процедура должна хранить сообщение об ошибке в результате интерпретатора. Значения closeProc и close2Proc можно получить с помощью Tcl_ChannelCloseProc или Tcl_ChannelClose2Proc, которые возвращают указатель на соответствующую функцию. INPUTPROC Поле inputProc содержит адрес функции, вызываемой общим уровнем для чтения данных из файла или устройства и хранения их во внутреннем буфере. InputProc должна соответствовать следующему прототипу: typedef int Tcl_DriverInputProc( ClientData instanceData, char *buf, int bufSize, int *errorCodePtr); InstanceData такой же, как значение, переданное Tcl_CreateChannel при создании канала. Аргумент buf указывает на массив байтов, в который следует хранить ввод из устройства, а аргумент bufSize указывает, сколько байтов доступно в buf. Аргумент errorCodePtr указывает на переменную целого числа, предоставленную общим уровнем. Если возникает ошибка, функция должна установить эту переменную в код ошибки POSIX, который идентифицирует возникшую ошибку. Функция должна читать данные из устройства ввода, инкапсулированного каналом, и хранить их в buf. При успехе функция должна возвращать неотрицательное целое число, указывающее, сколько байтов было прочитано из устройства ввода и сохранено в buf. При ошибке функция должна возвращать -1. Если ошибка возникает после того, как некоторые данные были прочитаны из устройства, эти данные потеряны. Если inputProc может определить, что устройство ввода имеет некоторые доступные данные, но меньше, чем запрошено аргументом bufSize, функция должна попытаться прочитать только столько данных, сколько доступно, и вернуться без блокировки. Если устройство ввода не имеет доступных данных и канал находится в неблокирующем режиме, функция должна возвращать ошибку EAGAIN. Если устройство ввода не имеет доступных данных и канал находится в блокирующем режиме, функция должна блокироваться на наименьшее возможное время, пока не сможет прочитать хотя бы один байт данных из устройства; затем она должна возвращать столько данных, сколько может прочитать без блокировки. Это значение можно получить с помощью Tcl_ChannelInputProc, которое возвращает указатель на функцию. OUTPUTPROC Поле outputProc содержит адрес функции, вызываемой общим уровнем для переноса данных из внутреннего буфера в устройство вывода. OutputProc должна соответствовать следующему прототипу: typedef int Tcl_DriverOutputProc( ClientData instanceData, const char *buf, int toWrite, int *errorCodePtr); InstanceData такой же, как значение, переданное Tcl_CreateChannel при создании канала. Аргумент buf содержит массив байтов для записи в устройство, а аргумент toWrite указывает, сколько байтов следует записать из buf. Аргумент errorCodePtr указывает на переменную целого числа, предоставленную общим уровнем. Если возникает ошибка, функция должна установить эту переменную в код ошибки POSIX, который идентифицирует ошибку. Функция должна записывать данные в buf в устройство вывода, инкапсулированное каналом. При успехе функция должна возвращать неотрицательное целое число, указывающее, сколько байтов было записано в устройство вывода. Значение возврата обычно такое же, как toWrite, но может быть меньше в некоторых случаях, например, если операция вывода прерывается сигналом. Если возникает ошибка, функция должна возвращать -1. В случае ошибки некоторые данные могли быть записаны в устройство. Если канал неблокирующий и устройство вывода не может поглотить никаких данных, функция должна возвращать -1 с ошибкой EAGAIN без записи каких-либо данных. Это значение можно получить с помощью Tcl_ChannelOutputProc, которое возвращает указатель на функцию. SEEKPROC AND WIDESEEKPROC Поле seekProc содержит адрес функции, вызываемой общим уровнем для перемещения точки доступа, к которой будут применяться последующие операции ввода или вывода. SeekProc должна соответствовать следующему прототипу: typedef int Tcl_DriverSeekProc( ClientData instanceData, long offset, int seekMode, int *errorCodePtr); Аргумент instanceData такой же, как значение, данное Tcl_CreateChannel при создании этого канала. Offset и seekMode имеют то же значение, что и для процедуры Tcl_Seek (описанной в руководстве по Tcl_OpenFileChannel). Аргумент errorCodePtr указывает на переменную целого числа, предоставленную общим уровнем для возврата значений errno из функции. Функция должна установить эту переменную в код ошибки POSIX, если возникает ошибка. Функция должна хранить код ошибки EINVAL, если тип канала не реализует поиск. Возвращаемое значение - это новая точка доступа или -1 в случае ошибки. Если возникла ошибка, функция не должна перемещать точку доступа. Если есть ненулевое поле seekProc, поле wideSeekProc может содержать адрес альтернативной функции для использования, которая обрабатывает широкие (т.е. большие, чем 32-битные) смещения, что позволяет искать в файлах больше 2 ГБ. WideSeekProc будет вызвана в предпочтении seekProc, но оба должны быть определены, если wideSeekProc определено. WideSeekProc должна соответствовать следующему прототипу: typedef Tcl_WideInt Tcl_DriverWideSeekProc( ClientData instanceData, Tcl_WideInt offset, int seekMode, int *errorCodePtr); Аргументы и возвращаемые значения имеют то же значение, что и в seekProc выше, за исключением того, что тип смещений и тип возврата отличаются. Значение seekProc можно получить с помощью Tcl_ChannelSeekProc, которое возвращает указатель на функцию, а wideSeekProc аналогично можно получить с помощью Tcl_ChannelWideSeekProc. SETOPTIONPROC Поле setOptionProc содержит адрес функции, вызываемой общим уровнем для установки параметра, специфичного для типа канала, на канале. SetOptionProc должна соответствовать следующему прототипу: typedef int Tcl_DriverSetOptionProc( ClientData instanceData, Tcl_Interp *interp, const char *optionName, const char *newValue); OptionName - имя параметра для установки, а newValue - новое значение для этого параметра в виде строки. InstanceData такой же, как значение, данное Tcl_CreateChannel при создании этого канала. Функция должна выполнять любые действия, специфичные для типа канала, необходимые для реализации нового значения параметра. Некоторые параметры обрабатываются общим кодом, и эта функция никогда не вызывается для их установки, например, -blockmode. Другие параметры специфичны для каждого типа канала, и процедура setOptionProc драйвера канала будет вызвана для их реализации. Поле setOptionProc может быть NULL, что указывает, что этот тип канала не поддерживает никаких специфичных для типа параметров. Если значение параметра успешно изменено на новое значение, функция возвращает TCL_OK. Она должна вызвать Tcl_BadChannelOption, которая сама возвращает TCL_ERROR, если optionName не распознано. Если newValue указывает значение для параметра, которое не поддерживается, или если возникает системный вызов ошибки, функция должна оставить сообщение об ошибке в результате interp, если interp не равно NULL. Функция также должна вызвать Tcl_SetErrno для хранения подходящего кода ошибки POSIX. Это значение можно получить с помощью Tcl_ChannelSetOptionProc, которое возвращает указатель на функцию. GETOPTIONPROC Поле getOptionProc содержит адрес функции, вызываемой общим уровнем для получения значения параметра, специфичного для типа канала, на канале. GetOptionProc должна соответствовать следующему прототипу: typedef int Tcl_DriverGetOptionProc( ClientData instanceData, Tcl_Interp *interp, const char *optionName, Tcl_DString *optionValue); OptionName - имя параметра, поддерживаемого этим типом канала. Если имя параметра не NULL, функция хранит его текущее значение в виде строки в динамической строке Tcl optionValue. Если optionName равно NULL, функция хранит в optionValue чередующийся список всех поддерживаемых параметров и их текущих значений. При успехе функция возвращает TCL_OK. Она должна вызвать Tcl_BadChannelOption, которая сама возвращает TCL_ERROR, если optionName не распознано. Если возникает системный вызов ошибки, функция должна оставить сообщение об ошибке в результате interp, если interp не равно NULL. Функция также должна вызвать Tcl_SetErrno для хранения подходящего кода ошибки POSIX. Некоторые параметры обрабатываются общим кодом, и эта функция никогда не вызывается для получения их значения, например, -blockmode. Другие параметры специфичны для каждого типа канала, и процедура getOptionProc драйвера канала будет вызвана для их реализации. Поле getOptionProc может быть NULL, что указывает, что этот тип канала не поддерживает никаких специфичных для типа параметров. Это значение можно получить с помощью Tcl_ChannelGetOptionProc, которое возвращает указатель на функцию. WATCHPROC Поле watchProc содержит адрес функции, вызываемой общим уровнем для инициализации механизма уведомления событий для обнаружения событий, интересующих на этом канале. WatchProc должна соответствовать следующему прототипу: typedef void Tcl_DriverWatchProc( ClientData instanceData, int mask); Аргумент instanceData такой же, как значение, переданное Tcl_CreateChannel при создании этого канала. Аргумент mask - это комбинация, объединенная операцией ИЛИ, из TCL_READABLE, TCL_WRITABLE и TCL_EXCEPTION; это указывает события, которые вызывающий заинтересован заметить на этом канале. Функция должна инициализировать механизмы, специфичные для типа устройства, для обнаружения события интереса на канале. Когда одно или несколько указанных событий происходит на канале, драйвер канала несет ответственность за вызов Tcl_NotifyChannel для информирования общего модуля канала. Драйвер должен позаботиться о том, чтобы не "голодать" другие драйверы каналов или источники обратных вызовов, вызывая Tcl_NotifyChannel слишком часто. Честность можно обеспечить, используя очередь событий Tcl для планирования события канала в последовательности с другими событиями. См. описание Tcl_QueueEvent для деталей о том, как поставить событие в очередь. Это значение можно получить с помощью Tcl_ChannelWatchProc, которое возвращает указатель на функцию. GETHANDLEPROC Поле getHandleProc содержит адрес функции, вызываемой общим уровнем для получения дескриптора, специфичного для устройства, из канала. GetHandleProc должна соответствовать следующему прототипу: typedef int Tcl_DriverGetHandleProc( ClientData instanceData, int direction, ClientData *handlePtr); InstanceData такой же, как значение, переданное Tcl_CreateChannel при создании этого канала. Аргумент direction равен либо TCL_READABLE для получения дескриптора, используемого для ввода, либо TCL_WRITABLE для получения дескриптора, используемого для вывода. Если реализация канала имеет дескрипторы, специфичные для устройства, функция должна получить соответствующий дескриптор, связанный с каналом, в соответствии с аргументом direction. Дескриптор должен быть сохранен в месте, на которое ссылается handlePtr, и должна быть возвращена TCL_OK. Если канал не открыт для указанного направления или если реализация канала не использует дескрипторы устройств, функция должна возвращать TCL_ERROR. Это значение можно получить с помощью Tcl_ChannelGetHandleProc, которое возвращает указатель на функцию. FLUSHPROC Поле flushProc в настоящее время зарезервировано для будущего использования. Оно должно быть установлено в NULL. FlushProc должна соответствовать следующему прототипу: typedef int Tcl_DriverFlushProc( ClientData instanceData); Это значение можно получить с помощью Tcl_ChannelFlushProc, которое возвращает указатель на функцию. HANDLERPROC Поле handlerProc содержит адрес функции, вызываемой общим уровнем для уведомления канала о том, что произошло событие. Оно должно быть определено для стековых драйверов каналов, которые хотят быть уведомленными о событиях, происходящих на базовом (стековом) канале. HandlerProc должна соответствовать следующему прототипу: typedef int Tcl_DriverHandlerProc( ClientData instanceData, int interestMask); InstanceData такой же, как значение, переданное Tcl_CreateChannel при создании этого канала. InterestMask - это комбинация, объединенная операцией ИЛИ, из TCL_READABLE или TCL_WRITABLE; это указывает, какой тип события произошел на этом канале. Это значение можно получить с помощью Tcl_ChannelHandlerProc, которое возвращает указатель на функцию. THREADACTIONPROC Поле threadActionProc содержит адрес функции, вызываемой общим уровнем, когда канал создается, закрывается или собирается перейти в другой поток, т.е. всякий раз, когда состояние драйвера, специфичное для потока, может потребовать инициализации или обновления. Оно может быть NULL. Действие TCL_CHANNEL_THREAD_REMOVE используется для уведомления драйвера о том, что он должен обновить или удалить любые данные, специфичные для потока, которые он может поддерживать для канала. Действие TCL_CHANNEL_THREAD_INSERT используется для уведомления драйвера о том, что он должен обновить или инициализировать любые данные, специфичные для потока, которые он может поддерживать, используя вызывающий поток в качестве ассоциации. См. Tcl_CutChannel и Tcl_SpliceChannel для получения более подробной информации. typedef void Tcl_DriverThreadActionProc( ClientData instanceData, int action); InstanceData такой же, как значение, переданное Tcl_CreateChannel при создании этого канала. Эти значения можно получить с помощью Tcl_ChannelThreadActionProc, которое возвращает указатель на функцию. TRUNCATEPROC Поле truncateProc содержит адрес функции, вызываемой общим уровнем, когда канал усекается до некоторой длины. Оно может быть NULL. typedef int Tcl_DriverTruncateProc( ClientData instanceData, Tcl_WideInt length); InstanceData такой же, как значение, переданное Tcl_CreateChannel при создании этого канала, а length - это новая длина базового файла, которая не должна быть отрицательной. Результат должен быть 0 при успехе или кодом errno (подходящим для использования с Tcl_SetErrno) при неудаче. Эти значения можно получить с помощью Tcl_ChannelTruncateProc, которое возвращает указатель на функцию. TCL_BADCHANNELOPTION Эта процедура генерирует сообщение об ошибке "плохой параметр" в (опциональном) интерпретаторе. Она используется драйверами каналов, когда запрашивается недопустимый параметр Set/Get. Ее цель - объединить список общих параметров со специфичными и факторизовать строку сообщения об ошибке общих параметров. Она всегда возвращает TCL_ERROR Сообщение об ошибке генерируется в значении результата interp, чтобы указать, что команда была вызвана с плохим параметром. Сообщение имеет форму плохой параметр "blah": должен быть одним из <...общие параметры...>+<...специфические параметры...> так вы получаете, например: плохой параметр "-blah": должен быть одним из -blocking, -buffering, -buffersize, -eofchar, -translation, -peername, или -sockname когда вызывается с optionList, равным "peername sockname" "blah" - это аргумент optionName, а "<специфические параметры>" - это список слов специфических параметров, разделенных пробелами. Функция тщательно заботится о вставке знаков минус перед каждым параметром, запятых после и "или" перед последним параметром. OLD CHANNEL TYPES Исходная (8.3.1 и ниже) структура Tcl_ChannelType содержит следующие поля: typedef struct Tcl_ChannelType { const char *typeName; Tcl_DriverBlockModeProc *blockModeProc; Tcl_DriverCloseProc *closeProc; Tcl_DriverInputProc *inputProc; Tcl_DriverOutputProc *outputProc; Tcl_DriverSeekProc *seekProc; Tcl_DriverSetOptionProc *setOptionProc; Tcl_DriverGetOptionProc *getOptionProc; Tcl_DriverWatchProc *watchProc; Tcl_DriverGetHandleProc *getHandleProc; Tcl_DriverClose2Proc *close2Proc; } Tcl_ChannelType; Все еще возможно создать канал с вышеуказанной структурой. Внутренний код канала определит версию. Обязательно используйте новую структуру Tcl_ChannelType, если вы создаете драйвер стекового канала, из-за проблем с предыдущей реализацией стекового канала (в 8.2.0 до 8.3.1). До 8.4.0 (т.е. во время поздних выпусков 8.3 и ранней части цикла разработки 8.4) структура Tcl_ChannelType содержала следующие поля: typedef struct Tcl_ChannelType { const char *typeName; Tcl_ChannelTypeVersion version; Tcl_DriverCloseProc *closeProc; Tcl_DriverInputProc *inputProc; Tcl_DriverOutputProc *outputProc; Tcl_DriverSeekProc *seekProc; Tcl_DriverSetOptionProc *setOptionProc; Tcl_DriverGetOptionProc *getOptionProc; Tcl_DriverWatchProc *watchProc; Tcl_DriverGetHandleProc *getHandleProc; Tcl_DriverClose2Proc *close2Proc; Tcl_DriverBlockModeProc *blockModeProc; Tcl_DriverFlushProc *flushProc; Tcl_DriverHandlerProc *handlerProc; Tcl_DriverTruncateProc *truncateProc; } Tcl_ChannelType; Когда вышеуказанная структура регистрируется как тип канала, поле version всегда должно быть TCL_CHANNEL_VERSION_2. SEE ALSO Tcl_Close(3), Tcl_OpenFileChannel(3), Tcl_SetErrno(3), Tcl_QueueEvent(3), Tcl_StackChannel(3), Tcl_GetStdChannel(3) KEYWORDS blocking, channel driver, channel registration, channel type, nonblocking Tcl 8.4 Tcl_CreateChannel(3)
Tcl_CreateChannel(3) Tcl Library Procedures Tcl_CreateChannel(3) ______________________________________________________________________________ NAME Tcl_CreateChannel, Tcl_GetChannelInstanceData, Tcl_GetChannelType, Tcl_GetChannelName, Tcl_GetChannelHandle, Tcl_GetChannelMode, Tcl_GetChannelBufferSize, Tcl_SetChannelBufferSize, Tcl_NotifyChannel, Tcl_BadChannelOption, Tcl_ChannelName, Tcl_ChannelVersion, Tcl_Channel‐ BlockModeProc, Tcl_ChannelCloseProc, Tcl_ChannelClose2Proc, Tcl_Chan‐ nelInputProc, Tcl_ChannelOutputProc, Tcl_ChannelSeekProc, Tcl_Channel‐ WideSeekProc, Tcl_ChannelTruncateProc, Tcl_ChannelSetOptionProc, Tcl_ChannelGetOptionProc, Tcl_ChannelWatchProc, Tcl_ChannelGetH‐ andleProc, Tcl_ChannelFlushProc, Tcl_ChannelHandlerProc, Tcl_Chan‐ nelThreadActionProc, Tcl_IsChannelShared, Tcl_IsChannelRegistered, Tcl_CutChannel, Tcl_SpliceChannel, Tcl_IsChannelExisting, Tcl_ClearChannelHandlers, Tcl_GetChannelThread, Tcl_ChannelBuffered - procedures for creating and manipulating channels SYNOPSIS #include <tcl.h> Tcl_Channel Tcl_CreateChannel(typePtr, channelName, instanceData, mask) ClientData Tcl_GetChannelInstanceData(channel) const Tcl_ChannelType * Tcl_GetChannelType(channel) const char * Tcl_GetChannelName(channel) int Tcl_GetChannelHandle(channel, direction, handlePtr) Tcl_ThreadId Tcl_GetChannelThread(channel) int Tcl_GetChannelMode(channel) int Tcl_GetChannelBufferSize(channel) Tcl_SetChannelBufferSize(channel, size) Tcl_NotifyChannel(channel, mask) int Tcl_BadChannelOption(interp, optionName, optionList) int Tcl_IsChannelShared(channel) int Tcl_IsChannelRegistered(interp, channel) int Tcl_IsChannelExisting(channelName) void Tcl_CutChannel(channel) void Tcl_SpliceChannel(channel) void Tcl_ClearChannelHandlers(channel) int Tcl_ChannelBuffered(channel) const char * Tcl_ChannelName(typePtr) Tcl_ChannelTypeVersion Tcl_ChannelVersion(typePtr) Tcl_DriverBlockModeProc * Tcl_ChannelBlockModeProc(typePtr) Tcl_DriverCloseProc * Tcl_ChannelCloseProc(typePtr) Tcl_DriverClose2Proc * Tcl_ChannelClose2Proc(typePtr) Tcl_DriverInputProc * Tcl_ChannelInputProc(typePtr) Tcl_DriverOutputProc * Tcl_ChannelOutputProc(typePtr) Tcl_DriverSeekProc * Tcl_ChannelSeekProc(typePtr) Tcl_DriverWideSeekProc * Tcl_ChannelWideSeekProc(typePtr) Tcl_DriverThreadActionProc * Tcl_ChannelThreadActionProc(typePtr) Tcl_DriverTruncateProc * Tcl_ChannelTruncateProc(typePtr) Tcl_DriverSetOptionProc * Tcl_ChannelSetOptionProc(typePtr) Tcl_DriverGetOptionProc * Tcl_ChannelGetOptionProc(typePtr) Tcl_DriverWatchProc * Tcl_ChannelWatchProc(typePtr) Tcl_DriverGetHandleProc * Tcl_ChannelGetHandleProc(typePtr) Tcl_DriverFlushProc * Tcl_ChannelFlushProc(typePtr) Tcl_DriverHandlerProc * Tcl_ChannelHandlerProc(typePtr) ARGUMENTS const Tcl_ChannelType *typePtr (in) Points to a structure containing the ad‐ dresses of procedures that can be called to perform I/O and other functions on the chan‐ nel. const char *channelName (in) The name of this chan‐ nel, such as file3; must not be in use by any other channel. Can be NULL, in which case the channel is created without a name. If the created channel is as‐ signed to one of the standard channels (stdin, stdout or stderr), the assigned channel name will be the name of the stan‐ dard channel. ClientData instanceData (in) Arbitrary one-word value to be associated with this channel. This value is passed to procedures in type‐ Ptr when they are in‐ voked. int mask (in) OR-ed combination of TCL_READABLE and TCL_WRITABLE to indi‐ cate whether a channel is readable and writable. Tcl_Channel channel (in) The channel to operate on. int direction (in) TCL_READABLE means the input handle is wanted; TCL_WRITABLE means the output han‐ dle is wanted. ClientData *handlePtr (out) Points to the location where the desired OS- specific handle should be stored. int size (in) The size, in bytes, of buffers to allocate in this channel. int mask (in) An OR-ed combination of TCL_READABLE, TCL_WRITABLE and TCL_EXCEPTION that in‐ dicates events that have occurred on this channel. Tcl_Interp *interp (in) Current interpreter. (can be NULL) const char *optionName (in) Name of the invalid option. const char *optionList (in) Specific options list (space separated words, without “-”) to append to the standard generic options list. Can be NULL for generic options error message only. ______________________________________________________________________________ DESCRIPTION Tcl uses a two-layered channel architecture. It provides a generic up‐ per layer to enable C and Tcl programs to perform input and output us‐ ing the same APIs for a variety of files, devices, sockets etc. The generic C APIs are described in the manual entry for Tcl_OpenFileChan‐ nel. The lower layer provides type-specific channel drivers for each type of device supported on each platform. This manual entry describes the C APIs used to communicate between the generic layer and the type-spe‐ cific channel drivers. It also explains how new types of channels can be added by providing new channel drivers. Channel drivers consist of a number of components: First, each channel driver provides a Tcl_ChannelType structure containing pointers to functions implementing the various operations used by the generic layer to communicate with the channel driver. The Tcl_ChannelType structure and the functions referenced by it are described in the section TCL_CHANNELTYPE, below. Second, channel drivers usually provide a Tcl command to create in‐ stances of that type of channel. For example, the Tcl open command cre‐ ates channels that use the file and command channel drivers, and the Tcl socket command creates channels that use TCP sockets for network communication. Third, a channel driver optionally provides a C function to open chan‐ nel instances of that type. For example, Tcl_OpenFileChannel opens a channel that uses the file channel driver, and Tcl_OpenTcpClient opens a channel that uses the TCP network protocol. These creation functions typically use Tcl_CreateChannel internally to open the channel. To add a new type of channel you must implement a C API or a Tcl com‐ mand that opens a channel by invoking Tcl_CreateChannel. When your driver calls Tcl_CreateChannel it passes in a Tcl_ChannelType structure describing the driver's I/O procedures. The generic layer will then invoke the functions referenced in that structure to perform operations on the channel. Tcl_CreateChannel opens a new channel and associates the supplied type‐ Ptr and instanceData with it. The channel is opened in the mode indi‐ cated by mask. For a discussion of channel drivers, their operations and the Tcl_ChannelType structure, see the section TCL_CHANNELTYPE, be‐ low. Tcl_CreateChannel interacts with the code managing the standard chan‐ nels. Once a standard channel was initialized either through a call to Tcl_GetStdChannel or a call to Tcl_SetStdChannel closing this standard channel will cause the next call to Tcl_CreateChannel to make the new channel the new standard channel too. See Tcl_StandardChannels for a general treatise about standard channels and the behavior of the Tcl library with regard to them. Tcl_GetChannelInstanceData returns the instance data associated with the channel in channel. This is the same as the instanceData argument in the call to Tcl_CreateChannel that created this channel. Tcl_GetChannelType returns a pointer to the Tcl_ChannelType structure used by the channel in the channel argument. This is the same as the typePtr argument in the call to Tcl_CreateChannel that created this channel. Tcl_GetChannelName returns a string containing the name associated with the channel, or NULL if the channelName argument to Tcl_CreateChannel was NULL. Tcl_GetChannelHandle places the OS-specific device handle associated with channel for the given direction in the location specified by han‐ dlePtr and returns TCL_OK. If the channel does not have a device han‐ dle for the specified direction, then TCL_ERROR is returned instead. Different channel drivers will return different types of handle. Refer to the manual entries for each driver to determine what type of handle is returned. Tcl_GetChannelThread returns the id of the thread currently managing the specified channel. This allows channel drivers to send their file events to the correct event queue even for a multi-threaded core. Tcl_GetChannelMode returns an OR-ed combination of TCL_READABLE and TCL_WRITABLE, indicating whether the channel is open for input and out‐ put. Tcl_GetChannelBufferSize returns the size, in bytes, of buffers allo‐ cated to store input or output in channel. If the value was not set by a previous call to Tcl_SetChannelBufferSize, described below, then the default value of 4096 is returned. Tcl_SetChannelBufferSize sets the size, in bytes, of buffers that will be allocated in subsequent operations on the channel to store input or output. The size argument should be between one and one million, allow‐ ing buffers of one byte to one million bytes. If size is outside this range, Tcl_SetChannelBufferSize sets the buffer size to 4096. Tcl_NotifyChannel is called by a channel driver to indicate to the generic layer that the events specified by mask have occurred on the channel. Channel drivers are responsible for invoking this function whenever the channel handlers need to be called for the channel (or other pending tasks like a write flush should be performed). See WATCHPROC below for more details. Tcl_BadChannelOption is called from driver specific setOptionProc or getOptionProc to generate a complete error message. Tcl_ChannelBuffered returns the number of bytes of input currently buffered in the internal buffer (push back area) of the channel itself. It does not report about the data in the overall buffers for the stack of channels the supplied channel is part of. Tcl_IsChannelShared checks the refcount of the specified channel and returns whether the channel was shared among multiple interpreters (re‐ sult == 1) or not (result == 0). Tcl_IsChannelRegistered checks whether the specified channel is regis‐ tered in the given interpreter (result == 1) or not (result == 0). Tcl_IsChannelExisting checks whether a channel with the specified name is registered in the (thread)-global list of all channels (result == 1) or not (result == 0). Tcl_CutChannel removes the specified channel from the (thread)global list of all channels (of the current thread). Application to a channel still registered in some interpreter is not allowed. Also notifies the driver if the Tcl_ChannelType version is TCL_CHANNEL_VERSION_4 (or higher), and Tcl_DriverThreadActionProc is defined for it. Tcl_SpliceChannel adds the specified channel to the (thread)global list of all channels (of the current thread). Application to a channel reg‐ istered in some interpreter is not allowed. Also notifies the driver if the Tcl_ChannelType version is TCL_CHANNEL_VERSION_4 (or higher), and Tcl_DriverThreadActionProc is defined for it. Tcl_ClearChannelHandlers removes all channel handlers and event scripts associated with the specified channel, thus shutting down all event processing for this channel. TCL_CHANNELTYPE A channel driver provides a Tcl_ChannelType structure that contains pointers to functions that implement the various operations on a chan‐ nel; these operations are invoked as needed by the generic layer. The structure was versioned starting in Tcl 8.3.2/8.4 to correct a problem with stacked channel drivers. See the OLD CHANNEL TYPES section below for details about the old structure. The Tcl_ChannelType structure contains the following fields: typedef struct Tcl_ChannelType { const char *typeName; Tcl_ChannelTypeVersion version; Tcl_DriverCloseProc *closeProc; Tcl_DriverInputProc *inputProc; Tcl_DriverOutputProc *outputProc; Tcl_DriverSeekProc *seekProc; Tcl_DriverSetOptionProc *setOptionProc; Tcl_DriverGetOptionProc *getOptionProc; Tcl_DriverWatchProc *watchProc; Tcl_DriverGetHandleProc *getHandleProc; Tcl_DriverClose2Proc *close2Proc; Tcl_DriverBlockModeProc *blockModeProc; Tcl_DriverFlushProc *flushProc; Tcl_DriverHandlerProc *handlerProc; Tcl_DriverWideSeekProc *wideSeekProc; Tcl_DriverThreadActionProc *threadActionProc; Tcl_DriverTruncateProc *truncateProc; } Tcl_ChannelType; It is not necessary to provide implementations for all channel opera‐ tions. Those which are not necessary may be set to NULL in the struct: blockModeProc, seekProc, setOptionProc, getOptionProc, getHandleProc, and close2Proc, in addition to flushProc, handlerProc, threadAction‐ Proc, and truncateProc. Other functions that cannot be implemented in a meaningful way should return EINVAL when called, to indicate that the operations they represent are not available. Also note that wideSeekProc can be NULL if seekProc is. The user should only use the above structure for Tcl_ChannelType in‐ stantiation. When referencing fields in a Tcl_ChannelType structure, the following functions should be used to obtain the values: Tcl_Chan‐ nelName, Tcl_ChannelVersion, Tcl_ChannelBlockModeProc, Tcl_Channel‐ CloseProc, Tcl_ChannelClose2Proc, Tcl_ChannelInputProc, Tcl_ChannelOut‐ putProc, Tcl_ChannelSeekProc, Tcl_ChannelWideSeekProc, Tcl_Chan‐ nelThreadActionProc, Tcl_ChannelTruncateProc, Tcl_ChannelSetOptionProc, Tcl_ChannelGetOptionProc, Tcl_ChannelWatchProc, Tcl_ChannelGetH‐ andleProc, Tcl_ChannelFlushProc, or Tcl_ChannelHandlerProc. The change to the structures was made in such a way that standard chan‐ nel types are binary compatible. However, channel types that use stacked channels (i.e. TLS, Trf) have new versions to correspond to the above change since the previous code for stacked channels had problems. TYPENAME The typeName field contains a null-terminated string that identifies the type of the device implemented by this driver, e.g. file or socket. This value can be retrieved with Tcl_ChannelName, which returns a pointer to the string. VERSION The version field should be set to the version of the structure that you require. TCL_CHANNEL_VERSION_2 is the minimum recommended. TCL_CHANNEL_VERSION_3 must be set to specify the wideSeekProc member. TCL_CHANNEL_VERSION_4 must be set to specify the threadActionProc mem‐ ber (includes wideSeekProc). TCL_CHANNEL_VERSION_5 must be set to specify the truncateProc members (includes wideSeekProc and threadAc‐ tionProc). If it is not set to any of these, then this Tcl_ChannelType is assumed to have the original structure. See OLD CHANNEL TYPES for more details. While Tcl will recognize and function with either struc‐ tures, stacked channels must be of at least TCL_CHANNEL_VERSION_2 to function correctly. This value can be retrieved with Tcl_ChannelVersion, which returns one of TCL_CHANNEL_VERSION_5, TCL_CHANNEL_VERSION_4, TCL_CHANNEL_VERSION_3, TCL_CHANNEL_VERSION_2 or TCL_CHANNEL_VERSION_1. BLOCKMODEPROC The blockModeProc field contains the address of a function called by the generic layer to set blocking and nonblocking mode on the device. BlockModeProc should match the following prototype: typedef int Tcl_DriverBlockModeProc( ClientData instanceData, int mode); The instanceData is the same as the value passed to Tcl_CreateChannel when this channel was created. The mode argument is either TCL_MODE_BLOCKING or TCL_MODE_NONBLOCKING to set the device into block‐ ing or nonblocking mode. The function should return zero if the opera‐ tion was successful, or a nonzero POSIX error code if the operation failed. If the operation is successful, the function can modify the supplied instanceData to record that the channel entered blocking or nonblocking mode and to implement the blocking or nonblocking behavior. For some device types, the blocking and nonblocking behavior can be implemented by the underlying operating system; for other device types, the behav‐ ior must be emulated in the channel driver. This value can be retrieved with Tcl_ChannelBlockModeProc, which re‐ turns a pointer to the function. A channel driver not supplying a blockModeProc has to be very, very careful. It has to tell the generic layer exactly which blocking mode is acceptable to it, and should this also document for the user so that the blocking mode of the channel is not changed to an unacceptable value. Any confusion here may lead the interpreter into a (spurious and difficult to find) deadlock. CLOSEPROC AND CLOSE2PROC The closeProc field contains the address of a function called by the generic layer to clean up driver-related information when the channel is closed. CloseProc must match the following prototype: typedef int Tcl_DriverCloseProc( ClientData instanceData, Tcl_Interp *interp); The instanceData argument is the same as the value provided to Tcl_Cre‐ ateChannel when the channel was created. The function should release any storage maintained by the channel driver for this channel, and close the input and output devices encapsulated by this channel. All queued output will have been flushed to the device before this function is called, and no further driver operations will be invoked on this in‐ stance after calling the closeProc. If the close operation is success‐ ful, the procedure should return zero; otherwise it should return a nonzero POSIX error code. In addition, if an error occurs and interp is not NULL, the procedure should store an error message in the inter‐ preter's result. Alternatively, channels that support closing the read and write sides independently may set closeProc to TCL_CLOSE2PROC and set close2Proc to the address of a function that matches the following prototype: typedef int Tcl_DriverClose2Proc( ClientData instanceData, Tcl_Interp *interp, int flags); The close2Proc will be called with flags set to an OR'ed combination of TCL_CLOSE_READ or TCL_CLOSE_WRITE to indicate that the driver should close the read and/or write side of the channel. The channel driver may be invoked to perform additional operations on the channel after close2Proc is called to close one or both sides of the channel. If flags is 0 (zero), the driver should close the channel in the manner described above for closeProc. No further operations will be invoked on this instance after close2Proc is called with all flags cleared. In all cases, the close2Proc function should return zero if the close op‐ eration was successful; otherwise it should return a nonzero POSIX er‐ ror code. In addition, if an error occurs and interp is not NULL, the procedure should store an error message in the interpreter's result. The closeProc and close2Proc values can be retrieved with Tcl_Channel‐ CloseProc or Tcl_ChannelClose2Proc, which return a pointer to the re‐ spective function. INPUTPROC The inputProc field contains the address of a function called by the generic layer to read data from the file or device and store it in an internal buffer. InputProc must match the following prototype: typedef int Tcl_DriverInputProc( ClientData instanceData, char *buf, int bufSize, int *errorCodePtr); InstanceData is the same as the value passed to Tcl_CreateChannel when the channel was created. The buf argument points to an array of bytes in which to store input from the device, and the bufSize argument indi‐ cates how many bytes are available at buf. The errorCodePtr argument points to an integer variable provided by the generic layer. If an error occurs, the function should set the variable to a POSIX error code that identifies the error that occurred. The function should read data from the input device encapsulated by the channel and store it at buf. On success, the function should return a nonnegative integer indicating how many bytes were read from the input device and stored at buf. On error, the function should return -1. If an error occurs after some data has been read from the device, that data is lost. If inputProc can determine that the input device has some data avail‐ able but less than requested by the bufSize argument, the function should only attempt to read as much data as is available and return without blocking. If the input device has no data available whatsoever and the channel is in nonblocking mode, the function should return an EAGAIN error. If the input device has no data available whatsoever and the channel is in blocking mode, the function should block for the shortest possible time until at least one byte of data can be read from the device; then, it should return as much data as it can read without blocking. This value can be retrieved with Tcl_ChannelInputProc, which returns a pointer to the function. OUTPUTPROC The outputProc field contains the address of a function called by the generic layer to transfer data from an internal buffer to the output device. OutputProc must match the following prototype: typedef int Tcl_DriverOutputProc( ClientData instanceData, const char *buf, int toWrite, int *errorCodePtr); InstanceData is the same as the value passed to Tcl_CreateChannel when the channel was created. The buf argument contains an array of bytes to be written to the device, and the toWrite argument indicates how many bytes are to be written from the buf argument. The errorCodePtr argument points to an integer variable provided by the generic layer. If an error occurs, the function should set this vari‐ able to a POSIX error code that identifies the error. The function should write the data at buf to the output device encapsu‐ lated by the channel. On success, the function should return a nonnega‐ tive integer indicating how many bytes were written to the output de‐ vice. The return value is normally the same as toWrite, but may be less in some cases such as if the output operation is interrupted by a signal. If an error occurs the function should return -1. In case of error, some data may have been written to the device. If the channel is nonblocking and the output device is unable to absorb any data whatsoever, the function should return -1 with an EAGAIN error without writing any data. This value can be retrieved with Tcl_ChannelOutputProc, which returns a pointer to the function. SEEKPROC AND WIDESEEKPROC The seekProc field contains the address of a function called by the generic layer to move the access point at which subsequent input or output operations will be applied. SeekProc must match the following prototype: typedef int Tcl_DriverSeekProc( ClientData instanceData, long offset, int seekMode, int *errorCodePtr); The instanceData argument is the same as the value given to Tcl_Create‐ Channel when this channel was created. Offset and seekMode have the same meaning as for the Tcl_Seek procedure (described in the manual en‐ try for Tcl_OpenFileChannel). The errorCodePtr argument points to an integer variable provided by the generic layer for returning errno values from the function. The func‐ tion should set this variable to a POSIX error code if an error occurs. The function should store an EINVAL error code if the channel type does not implement seeking. The return value is the new access point or -1 in case of error. If an error occurred, the function should not move the access point. If there is a non-NULL seekProc field, the wideSeekProc field may con‐ tain the address of an alternative function to use which handles wide (i.e. larger than 32-bit) offsets, so allowing seeks within files larger than 2GB. The wideSeekProc will be called in preference to the seekProc, but both must be defined if the wideSeekProc is defined. WideSeekProc must match the following prototype: typedef Tcl_WideInt Tcl_DriverWideSeekProc( ClientData instanceData, Tcl_WideInt offset, int seekMode, int *errorCodePtr); The arguments and return values mean the same thing as with seekProc above, except that the type of offsets and the return type are differ‐ ent. The seekProc value can be retrieved with Tcl_ChannelSeekProc, which re‐ turns a pointer to the function, and similarly the wideSeekProc can be retrieved with Tcl_ChannelWideSeekProc. SETOPTIONPROC The setOptionProc field contains the address of a function called by the generic layer to set a channel type specific option on a channel. setOptionProc must match the following prototype: typedef int Tcl_DriverSetOptionProc( ClientData instanceData, Tcl_Interp *interp, const char *optionName, const char *newValue); optionName is the name of an option to set, and newValue is the new value for that option, as a string. The instanceData is the same as the value given to Tcl_CreateChannel when this channel was created. The function should do whatever channel type specific action is required to implement the new value of the option. Some options are handled by the generic code and this function is never called to set them, e.g. -blockmode. Other options are specific to each channel type and the setOptionProc procedure of the channel driver will get called to implement them. The setOptionProc field can be NULL, which indicates that this channel type supports no type specific op‐ tions. If the option value is successfully modified to the new value, the function returns TCL_OK. It should call Tcl_BadChannelOption which it‐ self returns TCL_ERROR if the optionName is unrecognized. If newValue specifies a value for the option that is not supported or if a system call error occurs, the function should leave an error message in the result of interp if interp is not NULL. The function should also call Tcl_SetErrno to store an appropriate POSIX error code. This value can be retrieved with Tcl_ChannelSetOptionProc, which re‐ turns a pointer to the function. GETOPTIONPROC The getOptionProc field contains the address of a function called by the generic layer to get the value of a channel type specific option on a channel. getOptionProc must match the following prototype: typedef int Tcl_DriverGetOptionProc( ClientData instanceData, Tcl_Interp *interp, const char *optionName, Tcl_DString *optionValue); OptionName is the name of an option supported by this type of channel. If the option name is not NULL, the function stores its current value, as a string, in the Tcl dynamic string optionValue. If optionName is NULL, the function stores in optionValue an alternating list of all supported options and their current values. On success, the function returns TCL_OK. It should call Tcl_BadChannelOption which itself re‐ turns TCL_ERROR if the optionName is unrecognized. If a system call er‐ ror occurs, the function should leave an error message in the result of interp if interp is not NULL. The function should also call Tcl_SetEr‐ rno to store an appropriate POSIX error code. Some options are handled by the generic code and this function is never called to retrieve their value, e.g. -blockmode. Other options are spe‐ cific to each channel type and the getOptionProc procedure of the chan‐ nel driver will get called to implement them. The getOptionProc field can be NULL, which indicates that this channel type supports no type specific options. This value can be retrieved with Tcl_ChannelGetOptionProc, which re‐ turns a pointer to the function. WATCHPROC The watchProc field contains the address of a function called by the generic layer to initialize the event notification mechanism to notice events of interest on this channel. WatchProc should match the follow‐ ing prototype: typedef void Tcl_DriverWatchProc( ClientData instanceData, int mask); The instanceData is the same as the value passed to Tcl_CreateChannel when this channel was created. The mask argument is an OR-ed combina‐ tion of TCL_READABLE, TCL_WRITABLE and TCL_EXCEPTION; it indicates events the caller is interested in noticing on this channel. The function should initialize device type specific mechanisms to no‐ tice when an event of interest is present on the channel. When one or more of the designated events occurs on the channel, the channel driver is responsible for calling Tcl_NotifyChannel to inform the generic channel module. The driver should take care not to starve other chan‐ nel drivers or sources of callbacks by invoking Tcl_NotifyChannel too frequently. Fairness can be insured by using the Tcl event queue to allow the channel event to be scheduled in sequence with other events. See the description of Tcl_QueueEvent for details on how to queue an event. This value can be retrieved with Tcl_ChannelWatchProc, which returns a pointer to the function. GETHANDLEPROC The getHandleProc field contains the address of a function called by the generic layer to retrieve a device-specific handle from the chan‐ nel. GetHandleProc should match the following prototype: typedef int Tcl_DriverGetHandleProc( ClientData instanceData, int direction, ClientData *handlePtr); InstanceData is the same as the value passed to Tcl_CreateChannel when this channel was created. The direction argument is either TCL_READABLE to retrieve the handle used for input, or TCL_WRITABLE to retrieve the handle used for output. If the channel implementation has device-specific handles, the function should retrieve the appropriate handle associated with the channel, ac‐ cording the direction argument. The handle should be stored in the lo‐ cation referred to by handlePtr, and TCL_OK should be returned. If the channel is not open for the specified direction, or if the channel im‐ plementation does not use device handles, the function should return TCL_ERROR. This value can be retrieved with Tcl_ChannelGetHandleProc, which re‐ turns a pointer to the function. FLUSHPROC The flushProc field is currently reserved for future use. It should be set to NULL. FlushProc should match the following prototype: typedef int Tcl_DriverFlushProc( ClientData instanceData); This value can be retrieved with Tcl_ChannelFlushProc, which returns a pointer to the function. HANDLERPROC The handlerProc field contains the address of a function called by the generic layer to notify the channel that an event occurred. It should be defined for stacked channel drivers that wish to be notified of events that occur on the underlying (stacked) channel. HandlerProc should match the following prototype: typedef int Tcl_DriverHandlerProc( ClientData instanceData, int interestMask); InstanceData is the same as the value passed to Tcl_CreateChannel when this channel was created. The interestMask is an OR-ed combination of TCL_READABLE or TCL_WRITABLE; it indicates what type of event occurred on this channel. This value can be retrieved with Tcl_ChannelHandlerProc, which returns a pointer to the function. THREADACTIONPROC The threadActionProc field contains the address of the function called by the generic layer when a channel is created, closed, or going to move to a different thread, i.e. whenever thread-specific driver state might have to initialized or updated. It can be NULL. The action TCL_CHANNEL_THREAD_REMOVE is used to notify the driver that it should update or remove any thread-specific data it might be maintaining for the channel. The action TCL_CHANNEL_THREAD_INSERT is used to notify the driver that it should update or initialize any thread-specific data it might be maintaining using the calling thread as the associate. See Tcl_CutChan‐ nel and Tcl_SpliceChannel for more detail. typedef void Tcl_DriverThreadActionProc( ClientData instanceData, int action); InstanceData is the same as the value passed to Tcl_CreateChannel when this channel was created. These values can be retrieved with Tcl_ChannelThreadActionProc, which returns a pointer to the function. TRUNCATEPROC The truncateProc field contains the address of the function called by the generic layer when a channel is truncated to some length. It can be NULL. typedef int Tcl_DriverTruncateProc( ClientData instanceData, Tcl_WideInt length); InstanceData is the same as the value passed to Tcl_CreateChannel when this channel was created, and length is the new length of the underly‐ ing file, which should not be negative. The result should be 0 on suc‐ cess or an errno code (suitable for use with Tcl_SetErrno) on failure. These values can be retrieved with Tcl_ChannelTruncateProc, which re‐ turns a pointer to the function. TCL_BADCHANNELOPTION This procedure generates a “bad option” error message in an (optional) interpreter. It is used by channel drivers when an invalid Set/Get op‐ tion is requested. Its purpose is to concatenate the generic options list to the specific ones and factorize the generic options error mes‐ sage string. It always returns TCL_ERROR An error message is generated in interp's result value to indicate that a command was invoked with a bad option. The message has the form bad option "blah": should be one of <...generic options...>+<...specific options...> so you get for instance: bad option "-blah": should be one of -blocking, -buffering, -buffersize, -eofchar, -translation, -peername, or -sockname when called with optionList equal to “peername sockname” “blah” is the optionName argument and “<specific options>” is a space separated list of specific option words. The function takes good care of inserting minus signs before each option, commas after, and an “or” before the last option. OLD CHANNEL TYPES The original (8.3.1 and below) Tcl_ChannelType structure contains the following fields: typedef struct Tcl_ChannelType { const char *typeName; Tcl_DriverBlockModeProc *blockModeProc; Tcl_DriverCloseProc *closeProc; Tcl_DriverInputProc *inputProc; Tcl_DriverOutputProc *outputProc; Tcl_DriverSeekProc *seekProc; Tcl_DriverSetOptionProc *setOptionProc; Tcl_DriverGetOptionProc *getOptionProc; Tcl_DriverWatchProc *watchProc; Tcl_DriverGetHandleProc *getHandleProc; Tcl_DriverClose2Proc *close2Proc; } Tcl_ChannelType; It is still possible to create channel with the above structure. The internal channel code will determine the version. It is imperative to use the new Tcl_ChannelType structure if you are creating a stacked channel driver, due to problems with the earlier stacked channel imple‐ mentation (in 8.2.0 to 8.3.1). Prior to 8.4.0 (i.e. during the later releases of 8.3 and early part of the 8.4 development cycle) the Tcl_ChannelType structure contained the following fields: typedef struct Tcl_ChannelType { const char *typeName; Tcl_ChannelTypeVersion version; Tcl_DriverCloseProc *closeProc; Tcl_DriverInputProc *inputProc; Tcl_DriverOutputProc *outputProc; Tcl_DriverSeekProc *seekProc; Tcl_DriverSetOptionProc *setOptionProc; Tcl_DriverGetOptionProc *getOptionProc; Tcl_DriverWatchProc *watchProc; Tcl_DriverGetHandleProc *getHandleProc; Tcl_DriverClose2Proc *close2Proc; Tcl_DriverBlockModeProc *blockModeProc; Tcl_DriverFlushProc *flushProc; Tcl_DriverHandlerProc *handlerProc; Tcl_DriverTruncateProc *truncateProc; } Tcl_ChannelType; When the above structure is registered as a channel type, the version field should always be TCL_CHANNEL_VERSION_2. SEE ALSO Tcl_Close(3), Tcl_OpenFileChannel(3), Tcl_SetErrno(3), Tcl_QueueEvent(3), Tcl_StackChannel(3), Tcl_GetStdChannel(3) KEYWORDS blocking, channel driver, channel registration, channel type, nonblock‐ ing Tcl 8.4 Tcl_CreateChannel(3)
Tcl_CreateFileHandler(3) Процедуры Tcl Library Tcl_CreateFileHandler(3) ______________________________________________________________________________ NAME Tcl_CreateFileHandler, Tcl_DeleteFileHandler - ассоциировать процедуры обратного вызова с файлами или устройствами (только для Unix) SYNOPSIS #include <tcl.h> Tcl_CreateFileHandler(fd, mask, proc, clientData) Tcl_DeleteFileHandler(fd) ARGUMENTS int fd (in) Unix дескриптор файла для открытого файла или устройства. int mask (in) Условия, при которых proc должна вызываться: комбинация из OR (логического ИЛИ) TCL_READABLE, TCL_WRITABLE и TCL_EXCEPTION. Может быть установлен в 0 для временного отключения обработчика. Tcl_FileProc *proc (in) Процедура, которая будет вызвана, когда файл или устройство, указанное в fd, соответствует условиям из mask. ClientData clientData (in) Произвольное значение одного слова, которое передаётся в proc. ______________________________________________________________________________ DESCRIPTION Tcl_CreateFileHandler организует вызов proc в будущем, когда становится возможным ввод-вывод на файле или возникает исключительная ситуация для файла. Файл указывается с помощью fd, а условия интереса - с помощью mask. Например, если mask равен TCL_READABLE, proc будет вызвана, когда файл доступен для чтения. Вызов proc осуществляется через Tcl_DoOneEvent, поэтому Tcl_CreateFileHandler полезен только в программах, которые обрабатывают события через Tcl_DoOneEvent или через команды Tcl, такие как vwait. Процедура proc должна иметь аргументы и результат, соответствующие типу Tcl_FileProc: typedef void Tcl_FileProc( ClientData clientData, int mask); Параметр clientData для proc является копией аргумента clientData, переданного в Tcl_CreateFileHandler при создании обратного вызова. Обычно clientData указывает на структуру данных, содержащую приложение-специфичную информацию о файле. Mask - это целочисленная маска, указывающая, какие из запрошенных условий фактически существуют для файла; она будет содержать подмножество бит из mask, переданного в Tcl_CreateFileHandler. Для данного файла в данный момент может существовать только один обработчик. Если Tcl_CreateFileHandler вызывается, когда обработчик уже существует для fd, новая процедура обратного вызова заменяет ранее записанную информацию. Tcl_DeleteFileHandler может быть вызвана для удаления обработчика файла для fd; если обработчик не существует для файла, указанного в fd, процедура не оказывает никакого эффекта. Цель обработчиков файлов - позволить приложению реагировать на события, пока оно ожидает, когда файлы станут готовыми для ввода-вывода. Чтобы это работало правильно, приложению может потребоваться использовать неблокирующие операции ввода-вывода для файлов, для которых объявлены обработчики. В противном случае приложение может заблокироваться, если оно прочитает или запишет слишком много данных; в это время ожидания завершения ввода-вывода приложение не сможет обслуживать другие события. Используйте Tcl_SetChannelOption с опцией -blocking, чтобы установить канал в блокирующий или неблокирующий режим по необходимости. Обратите внимание, что эти интерфейсы поддерживаются только реализацией Tcl для Unix. SEE ALSO fileevent(n), Tcl_CreateTimerHandler(3), Tcl_DoWhenIdle(3) KEYWORDS callback, file, handler Tcl 8.0 Tcl_CreateFileHandler(3)
Tcl_CreateFileHandler(3) Tcl Library Procedures Tcl_CreateFileHandler(3) ______________________________________________________________________________ NAME Tcl_CreateFileHandler, Tcl_DeleteFileHandler - associate procedure callbacks with files or devices (Unix only) SYNOPSIS #include <tcl.h> Tcl_CreateFileHandler(fd, mask, proc, clientData) Tcl_DeleteFileHandler(fd) ARGUMENTS int fd (in) Unix file descriptor for an open file or device. int mask (in) Conditions under which proc should be called: OR-ed combina‐ tion of TCL_READABLE, TCL_WRITABLE, and TCL_EXCEPTION. May be set to 0 to temporarily disable a handler. Tcl_FileProc *proc (in) Procedure to invoke whenever the file or device indicated by file meets the conditions specified by mask. ClientData clientData (in) Arbitrary one-word value to pass to proc. ______________________________________________________________________________ DESCRIPTION Tcl_CreateFileHandler arranges for proc to be invoked in the future whenever I/O becomes possible on a file or an exceptional condition ex‐ ists for the file. The file is indicated by fd, and the conditions of interest are indicated by mask. For example, if mask is TCL_READABLE, proc will be called when the file is readable. The callback to proc is made by Tcl_DoOneEvent, so Tcl_CreateFileHandler is only useful in pro‐ grams that dispatch events through Tcl_DoOneEvent or through Tcl com‐ mands such as vwait. Proc should have arguments and result that match the type Tcl_FileProc: typedef void Tcl_FileProc( ClientData clientData, int mask); The clientData parameter to proc is a copy of the clientData argument given to Tcl_CreateFileHandler when the callback was created. Typi‐ cally, clientData points to a data structure containing application- specific information about the file. Mask is an integer mask indicat‐ ing which of the requested conditions actually exists for the file; it will contain a subset of the bits in the mask argument to Tcl_Create‐ FileHandler. There may exist only one handler for a given file at a given time. If Tcl_CreateFileHandler is called when a handler already exists for fd, then the new callback replaces the information that was previously recorded. Tcl_DeleteFileHandler may be called to delete the file handler for fd; if no handler exists for the file given by fd then the procedure has no effect. The purpose of file handlers is to enable an application to respond to events while waiting for files to become ready for I/O. For this to work correctly, the application may need to use non-blocking I/O opera‐ tions on the files for which handlers are declared. Otherwise the ap‐ plication may block if it reads or writes too much data; while waiting for the I/O to complete the application will not be able to service other events. Use Tcl_SetChannelOption with -blocking to set the chan‐ nel into blocking or nonblocking mode as required. Note that these interfaces are only supported by the Unix implementa‐ tion of the Tcl notifier. SEE ALSO fileevent(n), Tcl_CreateTimerHandler(3), Tcl_DoWhenIdle(3) KEYWORDS callback, file, handler Tcl 8.0 Tcl_CreateFileHandler(3)
Tcl_SetChannelError(3) Процедуры библиотеки Tcl Tcl_SetChannelError(3) ______________________________________________________________________________ NAME Tcl_SetChannelError, Tcl_SetChannelErrorInterp, Tcl_GetChannelError, Tcl_GetChannelErrorInterp - функции для создания/перехвата ошибок Tcl драйверами каналов. SYNOPSIS #include <tcl.h> void Tcl_SetChannelError(chan, msg) void Tcl_SetChannelErrorInterp(interp, msg) void Tcl_GetChannelError(chan, msgPtr) void Tcl_GetChannelErrorInterp(interp, msgPtr) ARGUMENTS Tcl_Channel chan (in) Указывает на Tcl-канал, область обхода которого доступна. Tcl_Interp* interp (in) Указывает на интерпретатор Tcl, область обхода которого доступна. Tcl_Obj* msg (in) Сообщение об ошибке, помещаемое в область обхода. Список опций возврата и значений, за которым следует строковое сообщение. Как сообщение, так и информация об опциях/значениях являются необязательными. Tcl_Obj** msgPtr (out) Ссылка на место, где будет сохранено сообщение из области обхода. ______________________________________________________________________________ DESCRIPTION Текущее определение драйвера Tcl-канала не позволяет напрямую возвращать произвольные сообщения об ошибках, за исключением установки и получения опций канала. Все остальные функции ограничены кодами ошибок POSIX. Функции, описанные здесь, преодолевают это ограничение. Драйверы каналов могут использовать Tcl_SetChannelError и Tcl_SetChannelErrorInterp для размещения произвольных сообщений об ошибках в областях обхода, определенных для каналов и интерпретаторов. А общий слой ввода/вывод использует Tcl_GetChannelError и Tcl_GetChannelErrorInterp для поиска сообщений в областях обхода и организации их возврата в виде ошибок. Коды ошибок POSIX, установленные драйвером, используются только в том случае, если сообщений нет. Tcl_SetChannelError сохраняет информацию об ошибке в области обхода указанного канала. Количество ссылок на значение msg увеличивается на одну. Предыдущая сохраненная информация будет отброшена путем освобождения ссылки, удерживаемой каналом. Ссылка на канал не должна быть NULL. Tcl_SetChannelErrorInterp сохраняет информацию об ошибке в области обхода указанного интерпретатора. Количество ссылок на значение msg увеличивается на одну. Предыдущая сохраненная информация будет отброшена путем освобождения ссылки, удерживаемой интерпретатором. Ссылка на интерпретатор не должна быть NULL. Tcl_GetChannelError помещает сообщение об ошибке из области обхода указанного канала в msgPtr, либо NULL; и сбрасывает область обхода, то есть после вызова все последующие вызовы будут возвращать NULL, пока не будет вызван Tcl_SetChannelError с ненулевым сообщением. msgPtr не должен быть NULL. Счетчик ссылок на сообщение не изменяется. Ссылка, ранее удерживаемая каналом, теперь удерживается вызывающей функцией, и именно она несет ответственность за освобождение этой ссылки, когда значение больше не используется. Tcl_GetChannelErrorInterp помещает сообщение об ошибке из области обхода указанного интерпретатора в msgPtr, либо NULL; и сбрасывает область обхода, то есть после вызова все последующие вызовы будут возвращать NULL, пока не будет вызван Tcl_SetChannelErrorInterp с ненулевым сообщением. msgPtr не должен быть NULL. Счетчик ссылок на сообщение не изменяется. Ссылка, ранее удерживаемая интерпретатором, теперь удерживается вызывающей функцией, и именно она несет ответственность за освобождение этой ссылки, когда значение больше не используется. Какие функции драйвера канала могут использовать какие функции обхода, перечислены ниже, а также какие функции публичного API канала могут оставлять сообщения в областях обхода. Tcl_DriverCloseProc Может использовать Tcl_SetChannelErrorInterp и только эту функцию. Tcl_DriverInputProc Может использовать Tcl_SetChannelError и только эту функцию. Tcl_DriverOutputProc Может использовать Tcl_SetChannelError и только эту функцию. Tcl_DriverSeekProc Может использовать Tcl_SetChannelError и только эту функцию. Tcl_DriverWideSeekProc Может использовать Tcl_SetChannelError и только эту функцию. Tcl_DriverSetOptionProc Уже имеет возможность передавать произвольные сообщения об ошибках. Не должен использовать никакие новые функции. Tcl_DriverGetOptionProc Уже имеет возможность передавать произвольные сообщения об ошибках. Не должен использовать никакие новые функции. Tcl_DriverWatchProc Не должен использовать никакие новые функции. Вызывается внутренне и не имеет возможности возвращать какой-либо тип ошибки. Tcl_DriverBlockModeProc Может использовать Tcl_SetChannelError и только эту функцию. Tcl_DriverGetHandleProc Не должен использовать никакие новые функции. Это только низкоуровневая функция и не используется командами Tcl. Tcl_DriverHandlerProc Не должен использовать никакие новые функции. Вызывается внутренне и не имеет возможности возвращать какой-либо тип ошибки. На основе вышеуказанной информации следующие публичные функции API Tcl C подвержены этим изменениям; при вызове этих функций канал теперь может содержать сохраненное произвольное сообщение об ошибке, требующее обработки вызывающей стороной. Tcl_Flush Tcl_GetsObj Tcl_Gets Tcl_ReadChars Tcl_ReadRaw Tcl_Read Tcl_Seek Tcl_StackChannel Tcl_Tell Tcl_WriteChars Tcl_WriteObj Tcl_WriteRaw Tcl_Write Все остальные функции API остаются неизменными. В частности, функции ниже оставляют всю информацию об ошибках в результате интерпретатора. Tcl_Close Tcl_UnstackChannel Tcl_UnregisterChannel SEE ALSO Tcl_Close(3), Tcl_OpenFileChannel(3), Tcl_SetErrno(3) KEYWORDS драйвер канала, сообщения об ошибках, тип канала Tcl 8.5 Tcl_SetChannelError(3)
Tcl_SetChannelError(3) Tcl Library Procedures Tcl_SetChannelError(3) ______________________________________________________________________________ NAME Tcl_SetChannelError, Tcl_SetChannelErrorInterp, Tcl_GetChannelError, Tcl_GetChannelErrorInterp - functions to create/intercept Tcl errors by channel drivers. SYNOPSIS #include <tcl.h> void Tcl_SetChannelError(chan, msg) void Tcl_SetChannelErrorInterp(interp, msg) void Tcl_GetChannelError(chan, msgPtr) void Tcl_GetChannelErrorInterp(interp, msgPtr) ARGUMENTS Tcl_Channel chan (in) Refers to the Tcl channel whose bypass area is accessed. Tcl_Interp* interp (in) Refers to the Tcl interpreter whose by‐ pass area is accessed. Tcl_Obj* msg (in) Error message put into a bypass area. A list of return options and values, fol‐ lowed by a string message. Both message and the option/value information are op‐ tional. Tcl_Obj** msgPtr (out) Reference to a place where the message stored in the accessed bypass area can be stored in. ______________________________________________________________________________ DESCRIPTION The current definition of a Tcl channel driver does not permit the di‐ rect return of arbitrary error messages, except for the setting and re‐ trieval of channel options. All other functions are restricted to POSIX error codes. The functions described here overcome this limitation. Channel drivers are allowed to use Tcl_SetChannelError and Tcl_SetChannelErrorInterp to place arbitrary error messages in bypass areas defined for channels and interpreters. And the generic I/O layer uses Tcl_GetChannelError and Tcl_GetChannelErrorInterp to look for messages in the bypass areas and arrange for their return as errors. The POSIX error codes set by a driver are used now if and only if no messages are present. Tcl_SetChannelError stores error information in the bypass area of the specified channel. The number of references to the msg value goes up by one. Previously stored information will be discarded, by releasing the reference held by the channel. The channel reference must not be NULL. Tcl_SetChannelErrorInterp stores error information in the bypass area of the specified interpreter. The number of references to the msg value goes up by one. Previously stored information will be discarded, by re‐ leasing the reference held by the interpreter. The interpreter refer‐ ence must not be NULL. Tcl_GetChannelError places either the error message held in the bypass area of the specified channel into msgPtr, or NULL; and resets the by‐ pass, that is, after an invocation all following invocations will re‐ turn NULL, until an intervening invocation of Tcl_SetChannelError with a non-NULL message. The msgPtr must not be NULL. The reference count of the message is not touched. The reference previously held by the chan‐ nel is now held by the caller of the function and it is its responsi‐ bility to release that reference when it is done with the value. Tcl_GetChannelErrorInterp places either the error message held in the bypass area of the specified interpreter into msgPtr, or NULL; and re‐ sets the bypass, that is, after an invocation all following invocations will return NULL, until an intervening invocation of Tcl_SetChannelEr‐ rorInterp with a non-NULL message. The msgPtr must not be NULL. The reference count of the message is not touched. The reference previ‐ ously held by the interpreter is now held by the caller of the function and it is its responsibility to release that reference when it is done with the value. Which functions of a channel driver are allowed to use which bypass function is listed below, as is which functions of the public channel API may leave a messages in the bypass areas. Tcl_DriverCloseProc May use Tcl_SetChannelErrorInterp, and only this function. Tcl_DriverInputProc May use Tcl_SetChannelError, and only this function. Tcl_DriverOutputProc May use Tcl_SetChannelError, and only this function. Tcl_DriverSeekProc May use Tcl_SetChannelError, and only this function. Tcl_DriverWideSeekProc May use Tcl_SetChannelError, and only this function. Tcl_DriverSetOptionProc Has already the ability to pass arbitrary error messages. Must not use any of the new functions. Tcl_DriverGetOptionProc Has already the ability to pass arbitrary error messages. Must not use any of the new functions. Tcl_DriverWatchProc Must not use any of the new functions. Is internally called and has no ability to return any type of error whatsoever. Tcl_DriverBlockModeProc May use Tcl_SetChannelError, and only this function. Tcl_DriverGetHandleProc Must not use any of the new functions. It is only a low-level function, and not used by Tcl commands. Tcl_DriverHandlerProc Must not use any of the new functions. Is internally called and has no ability to return any type of error whatsoever. Given the information above the following public functions of the Tcl C API are affected by these changes; when these functions are called, the channel may now contain a stored arbitrary error message requiring pro‐ cessing by the caller. Tcl_Flush Tcl_GetsObj Tcl_Gets Tcl_ReadChars Tcl_ReadRaw Tcl_Read Tcl_Seek Tcl_StackChannel Tcl_Tell Tcl_WriteChars Tcl_WriteObj Tcl_WriteRaw Tcl_Write All other API functions are unchanged. In particular, the functions be‐ low leave all their error information in the interpreter result. Tcl_Close Tcl_UnstackChannel Tcl_UnregisterChannel SEE ALSO Tcl_Close(3), Tcl_OpenFileChannel(3), Tcl_SetErrno(3) KEYWORDS channel driver, error messages, channel type Tcl 8.5 Tcl_SetChannelError(3)
Tcl_UniCharIsAlpha(3) Tcl Library Procedures Tcl_UniCharIsAlpha(3) ______________________________________________________________________________ NAME Tcl_UniCharIsAlnum, Tcl_UniCharIsAlpha, Tcl_UniCharIsControl, Tcl_UniCharIsDigit, Tcl_UniCharIsGraph, Tcl_UniCharIsLower, Tcl_UniCharIsPrint, Tcl_UniCharIsPunct, Tcl_UniCharIsSpace, Tcl_UniCharIsUpper, Tcl_UniCharIsWordChar - процедуры для классификации символов Tcl_UniChar SYNOPSIS #include <tcl.h> int Tcl_UniCharIsAlnum(ch) int Tcl_UniCharIsAlpha(ch) int Tcl_UniCharIsControl(ch) int Tcl_UniCharIsDigit(ch) int Tcl_UniCharIsGraph(ch) int Tcl_UniCharIsLower(ch) int Tcl_UniCharIsPrint(ch) int Tcl_UniCharIsPunct(ch) int Tcl_UniCharIsSpace(ch) int Tcl_UniCharIsUpper(ch) int Tcl_UniCharIsWordChar(ch) ARGUMENTS int ch (in) Tcl_UniChar, который нужно проверить. ______________________________________________________________________________ DESCRIPTION Все описанные процедуры проверяют символы Unicode и возвращают логическое значение. Некоторое ненулевое значение означает, что символ действительно принадлежит классу символов, связанному с вызванной процедурой. Остальная часть этого документа просто описывает классы символов, связанные с различными процедурами. КЛАССЫ СИМВОЛОВ Tcl_UniCharIsAlnum проверяет, является ли символ алфавитно-цифровым символом Unicode. Tcl_UniCharIsAlpha проверяет, является ли символ алфавитным символом Unicode. Tcl_UniCharIsControl проверяет, является ли символ управляющим символом Unicode. Tcl_UniCharIsDigit проверяет, является ли символ числовым символом Unicode. Tcl_UniCharIsGraph проверяет, является ли символ любым печатаемым символом Unicode, кроме пробела. Tcl_UniCharIsLower проверяет, является ли символ строчным символом Unicode. Tcl_UniCharIsPrint проверяет, является ли символ печатаемым символом Unicode. Tcl_UniCharIsPunct проверяет, является ли символ знаком препинания Unicode. Tcl_UniCharIsSpace проверяет, является ли символ пробельным символом Unicode. Tcl_UniCharIsUpper проверяет, является ли символ прописным символом Unicode. Tcl_UniCharIsWordChar проверяет, является ли символ алфавитно-цифровым или знаком соединителя. КЛЮЧЕВЫЕ СЛОВА unicode, classification Tcl 8.1 Tcl_UniCharIsAlpha(3)
Tcl_UniCharIsAlpha(3) Tcl Library Procedures Tcl_UniCharIsAlpha(3) ______________________________________________________________________________ NAME Tcl_UniCharIsAlnum, Tcl_UniCharIsAlpha, Tcl_UniCharIsControl, Tcl_UniCharIsDigit, Tcl_UniCharIsGraph, Tcl_UniCharIsLower, Tcl_UniCharIsPrint, Tcl_UniCharIsPunct, Tcl_UniCharIsSpace, Tcl_UniCharIsUpper, Tcl_UniCharIsWordChar - routines for classification of Tcl_UniChar characters SYNOPSIS #include <tcl.h> int Tcl_UniCharIsAlnum(ch) int Tcl_UniCharIsAlpha(ch) int Tcl_UniCharIsControl(ch) int Tcl_UniCharIsDigit(ch) int Tcl_UniCharIsGraph(ch) int Tcl_UniCharIsLower(ch) int Tcl_UniCharIsPrint(ch) int Tcl_UniCharIsPunct(ch) int Tcl_UniCharIsSpace(ch) int Tcl_UniCharIsUpper(ch) int Tcl_UniCharIsWordChar(ch) ARGUMENTS int ch (in) The Tcl_UniChar to be examined. ______________________________________________________________________________ DESCRIPTION All of the routines described examine Unicode characters and return a boolean value. A non-zero return value means that the character does belong to the character class associated with the called routine. The rest of this document just describes the character classes associated with the various routines. CHARACTER CLASSES Tcl_UniCharIsAlnum tests if the character is an alphanumeric Unicode character. Tcl_UniCharIsAlpha tests if the character is an alphabetic Unicode character. Tcl_UniCharIsControl tests if the character is a Unicode control char‐ acter. Tcl_UniCharIsDigit tests if the character is a numeric Unicode charac‐ ter. Tcl_UniCharIsGraph tests if the character is any Unicode print charac‐ ter except space. Tcl_UniCharIsLower tests if the character is a lowercase Unicode char‐ acter. Tcl_UniCharIsPrint tests if the character is a Unicode print character. Tcl_UniCharIsPunct tests if the character is a Unicode punctuation character. Tcl_UniCharIsSpace tests if the character is a whitespace Unicode char‐ acter. Tcl_UniCharIsUpper tests if the character is an uppercase Unicode char‐ acter. Tcl_UniCharIsWordChar tests if the character is alphanumeric or a con‐ nector punctuation mark. KEYWORDS unicode, classification Tcl 8.1 Tcl_UniCharIsAlpha(3)
Tcl_UtfToUpper(3) Tcl Library Procedures Tcl_UtfToUpper(3) ______________________________________________________________________________ NAME Tcl_UniCharToUpper, Tcl_UniCharToLower, Tcl_UniCharToTitle, Tcl_UtfToUpper, Tcl_UtfToLower, Tcl_UtfToTitle - процедуры для манипуляции регистром символов Unicode и строк UTF-8 SYNOPSIS #include <tcl.h> Tcl_UniChar Tcl_UniCharToUpper(ch) Tcl_UniChar Tcl_UniCharToLower(ch) Tcl_UniChar Tcl_UniCharToTitle(ch) int Tcl_UtfToUpper(str) int Tcl_UtfToLower(str) int Tcl_UtfToTitle(str) ARGUMENTS int ch (in) Символ Unicode для преобразования. char *str (in/out) Указатель на строку UTF-8 для преобразования на месте. ______________________________________________________________________________ DESCRIPTION Первые три процедуры преобразуют регистр отдельных символов Unicode: Если ch представляет символ в нижнем регистре, Tcl_UniCharToUpper возвращает соответствующий символ в верхнем регистре. Если символ в верхнем регистре не определён, он возвращает символ без изменений. Если ch представляет символ в верхнем регистре, Tcl_UniCharToLower возвращает соответствующий символ в нижнем регистре. Если символ в нижнем регистре не определён, он возвращает символ без изменений. Если ch представляет символ в нижнем регистре, Tcl_UniCharToTitle возвращает соответствующий символ в титульном регистре. Если символ в титульном регистре не определён, он возвращает соответствующий символ в верхнем регистре. Если символ в верхнем регистре не определён, он возвращает символ без изменений. Титульный регистр определён для небольшого количества символов, которые имеют другой вид, когда они находятся в начале заглавного слова. Следующие три процедуры преобразуют регистр строк UTF-8 на месте в памяти: Tcl_UtfToUpper преобразует каждый символ UTF-8 в str в верхний регистр. Поскольку изменение регистра символа может изменить его размер, байтовое смещение каждого символа в результирующей строке может отличаться от исходного расположения. Tcl_UtfToUpper записывает нулевой байт в конце преобразованной строки. Tcl_UtfToUpper возвращает новую длину строки в байтах. Эта новая длина гарантированно не превышает исходную длину строки. Tcl_UtfToLower работает так же, как Tcl_UtfToUpper, за исключением того, что она преобразует каждый символ в строке в его эквивалент в нижнем регистре. Tcl_UtfToTitle работает так же, как Tcl_UtfToUpper, за исключением того, что она преобразует первый символ в строке в его эквивалент в титульном регистре, а все последующие символы — в их эквиваленты в нижнем регистре. BUGS В настоящее время преобразования регистра определены только для символов плоскости 0 Unicode. Результат для символов Unicode выше 0xFFFF неопределён, но фактически обрабатываются только младшие 16 бит значения символа. KEYWORDS utf, unicode, toupper, tolower, totitle, case Tcl 8.1 Tcl_UtfToUpper(3)
Tcl_UtfToUpper(3) Tcl Library Procedures Tcl_UtfToUpper(3) ______________________________________________________________________________ NAME Tcl_UniCharToUpper, Tcl_UniCharToLower, Tcl_UniCharToTitle, Tcl_UtfToUpper, Tcl_UtfToLower, Tcl_UtfToTitle - routines for manipu‐ lating the case of Unicode characters and UTF-8 strings SYNOPSIS #include <tcl.h> Tcl_UniChar Tcl_UniCharToUpper(ch) Tcl_UniChar Tcl_UniCharToLower(ch) Tcl_UniChar Tcl_UniCharToTitle(ch) int Tcl_UtfToUpper(str) int Tcl_UtfToLower(str) int Tcl_UtfToTitle(str) ARGUMENTS int ch (in) The Unicode character to be converted. char *str (in/out) Pointer to UTF-8 string to be converted in place. ______________________________________________________________________________ DESCRIPTION The first three routines convert the case of individual Unicode charac‐ ters: If ch represents a lower-case character, Tcl_UniCharToUpper returns the corresponding upper-case character. If no upper-case character is de‐ fined, it returns the character unchanged. If ch represents an upper-case character, Tcl_UniCharToLower returns the corresponding lower-case character. If no lower-case character is defined, it returns the character unchanged. If ch represents a lower-case character, Tcl_UniCharToTitle returns the corresponding title-case character. If no title-case character is de‐ fined, it returns the corresponding upper-case character. If no upper- case character is defined, it returns the character unchanged. Title- case is defined for a small number of characters that have a different appearance when they are at the beginning of a capitalized word. The next three routines convert the case of UTF-8 strings in place in memory: Tcl_UtfToUpper changes every UTF-8 character in str to upper-case. Be‐ cause changing the case of a character may change its size, the byte offset of each character in the resulting string may differ from its original location. Tcl_UtfToUpper writes a null byte at the end of the converted string. Tcl_UtfToUpper returns the new length of the string in bytes. This new length is guaranteed to be no longer than the orig‐ inal string length. Tcl_UtfToLower is the same as Tcl_UtfToUpper except it turns each char‐ acter in the string into its lower-case equivalent. Tcl_UtfToTitle is the same as Tcl_UtfToUpper except it turns the first character in the string into its title-case equivalent and all follow‐ ing characters into their lower-case equivalents. BUGS At this time, the case conversions are only defined for the Unicode plane 0 characters. The result for Unicode characters above 0xFFFF is undefined, but - actually - only the lower 16 bits of the character value is handled. KEYWORDS utf, unicode, toupper, tolower, totitle, case Tcl 8.1 Tcl_UtfToUpper(3)
Tcl_GetCwd(3) Процедуры библиотеки Tcl Tcl_GetCwd(3) ______________________________________________________________________________ NAME Tcl_GetCwd, Tcl_Chdir - управлять текущим рабочим каталогом SYNOPSIS #include <tcl.h> char * Tcl_GetCwd(interp, bufferPtr) int Tcl_Chdir(dirName) ARGUMENTS Tcl_Interp *interp (in) Интерпретатор, в котором сообщать об ошибке, если таковая имеется. Tcl_DString *bufferPtr (in/out) Эта динамическая строка используется для хранения текущего рабочего ката‐ лога. На момент вызова она должна быть неинициализирована или освобож‐ дена. Вызывающий должен в конечном итоге вызвать Tcl_DStringFree, что‐ бы освободить всё, что здесь хранит‐ ся. const char *dirName (in) Путь к файлу в формате UTF-8. ______________________________________________________________________________ DESCRIPTION Эти процедуры могут быть использованы для управления текущим рабочим каталогом приложения. Они предоставляют доступ на уровне C к той же функциональности, что и команда Tcl pwd. Tcl_GetCwd возвращает указатель на строку, указывающую на текущий каталог, или NULL, если текущий каталог не удалось определить. Если возвращается NULL, сообщение об ошибке оставляется в результате интер‐ претатора. Память для строки результата выделяется в bufferPtr; вы‐ зывающий должен вызвать Tcl_DStringFree(), когда результат больше не нужен. Формат пути - UTF-8. Tcl_Chdir изменяет текущий рабочий каталог приложения на значение, указанное в dirName. Формат переданной строки должен быть UTF-8. Функция возвращает -1 в случае ошибки или 0 при успешном выполнении. KEYWORDS pwd Tcl 8.1 Tcl_GetCwd(3)
Tcl_GetCwd(3) Tcl Library Procedures Tcl_GetCwd(3) ______________________________________________________________________________ NAME Tcl_GetCwd, Tcl_Chdir - manipulate the current working directory SYNOPSIS #include <tcl.h> char * Tcl_GetCwd(interp, bufferPtr) int Tcl_Chdir(dirName) ARGUMENTS Tcl_Interp *interp (in) Interpreter in which to report an error, if any. Tcl_DString *bufferPtr (in/out) This dynamic string is used to store the current working direc‐ tory. At the time of the call it should be uninitialized or free. The caller must eventually call Tcl_DStringFree to free up any‐ thing stored here. const char *dirName (in) File path in UTF-8 format. ______________________________________________________________________________ DESCRIPTION These procedures may be used to manipulate the current working direc‐ tory for the application. They provide C-level access to the same functionality as the Tcl pwd command. Tcl_GetCwd returns a pointer to a string specifying the current direc‐ tory, or NULL if the current directory could not be determined. If NULL is returned, an error message is left in the interp's result. Storage for the result string is allocated in bufferPtr; the caller must call Tcl_DStringFree() when the result is no longer needed. The format of the path is UTF-8. Tcl_Chdir changes the applications current working directory to the value specified in dirName. The format of the passed in string must be UTF-8. The function returns -1 on error or 0 on success. KEYWORDS pwd Tcl 8.1 Tcl_GetCwd(3)
Tcl_UtfToUpper(3) Tcl Library Procedures Tcl_UtfToUpper(3) ______________________________________________________________________________ NAME Tcl_UniCharToUpper, Tcl_UniCharToLower, Tcl_UniCharToTitle, Tcl_UtfToUpper, Tcl_UtfToLower, Tcl_UtfToTitle - процедуры для манипулирования регистром символов Unicode и строк UTF-8 SYNOPSIS #include <tcl.h> Tcl_UniChar Tcl_UniCharToUpper(ch) Tcl_UniChar Tcl_UniCharToLower(ch) Tcl_UniChar Tcl_UniCharToTitle(ch) int Tcl_UtfToUpper(str) int Tcl_UtfToLower(str) int Tcl_UtfToTitle(str) ARGUMENTS int ch (in) Символ Unicode для преобразования. char *str (in/out) Указатель на строку UTF-8 для преобразования на месте. ______________________________________________________________________________ DESCRIPTION Первые три процедуры преобразовывают регистр отдельных символов Unicode: Если ch представляет собой символ в нижнем регистре, Tcl_UniCharToUpper возвращает соответствующий символ в верхнем регистре. Если соответствующий символ в верхнем регистре не определён, процедура возвращает символ без изменений. Если ch представляет собой символ в верхнем регистре, Tcl_UniCharToLower возвращает соответствующий символ в нижнем регистре. Если соответствующий символ в нижнем регистре не определён, процедура возвращает символ без изменений. Если ch представляет собой символ в нижнем регистре, Tcl_UniCharToTitle возвращает соответствующий символ в регистре заголовка. Если соответствующий символ в регистре заголовка не определён, процедура возвращает соответствующий символ в верхнем регистре. Если соответствующий символ в верхнем регистре не определён, процедура возвращает символ без изменений. Регистр заголовка определён для небольшого количества символов, которые имеют другой вид, когда они находятся в начале заглавного слова. Следующие три процедуры преобразовывают регистр строк UTF-8 на месте в памяти: Tcl_UtfToUpper преобразует каждый символ UTF-8 в str в верхний регистр. Поскольку изменение регистра символа может изменить его размер, байтовое смещение каждого символа в результирующей строке может отличаться от исходного расположения. Tcl_UtfToUpper записывает нулевой байт в конце преобразованной строки. Tcl_UtfToUpper возвращает новую длину строки в байтах. Эта новая длина гарантированно не превышает исходную длину строки. Tcl_UtfToLower работает так же, как Tcl_UtfToUpper, за исключением того, что она преобразует каждый символ в строке в его эквивалент в нижнем регистре. Tcl_UtfToTitle работает так же, как Tcl_UtfToUpper, за исключением того, что она преобразует первый символ в строке в его эквивалент в регистре заголовка, а все последующие символы — в их эквиваленты в нижнем регистре. BUGS В настоящее время преобразования регистра определены только для символов плоскости 0 Unicode. Результат для символов Unicode выше 0xFFFF не определён, но фактически обрабатываются только младшие 16 бит значения символа. KEYWORDS utf, unicode, toupper, tolower, totitle, case Tcl 8.1 Tcl_UtfToUpper(3)
Tcl_UtfToUpper(3) Tcl Library Procedures Tcl_UtfToUpper(3) ______________________________________________________________________________ NAME Tcl_UniCharToUpper, Tcl_UniCharToLower, Tcl_UniCharToTitle, Tcl_UtfToUpper, Tcl_UtfToLower, Tcl_UtfToTitle - routines for manipu‐ lating the case of Unicode characters and UTF-8 strings SYNOPSIS #include <tcl.h> Tcl_UniChar Tcl_UniCharToUpper(ch) Tcl_UniChar Tcl_UniCharToLower(ch) Tcl_UniChar Tcl_UniCharToTitle(ch) int Tcl_UtfToUpper(str) int Tcl_UtfToLower(str) int Tcl_UtfToTitle(str) ARGUMENTS int ch (in) The Unicode character to be converted. char *str (in/out) Pointer to UTF-8 string to be converted in place. ______________________________________________________________________________ DESCRIPTION The first three routines convert the case of individual Unicode charac‐ ters: If ch represents a lower-case character, Tcl_UniCharToUpper returns the corresponding upper-case character. If no upper-case character is de‐ fined, it returns the character unchanged. If ch represents an upper-case character, Tcl_UniCharToLower returns the corresponding lower-case character. If no lower-case character is defined, it returns the character unchanged. If ch represents a lower-case character, Tcl_UniCharToTitle returns the corresponding title-case character. If no title-case character is de‐ fined, it returns the corresponding upper-case character. If no upper- case character is defined, it returns the character unchanged. Title- case is defined for a small number of characters that have a different appearance when they are at the beginning of a capitalized word. The next three routines convert the case of UTF-8 strings in place in memory: Tcl_UtfToUpper changes every UTF-8 character in str to upper-case. Be‐ cause changing the case of a character may change its size, the byte offset of each character in the resulting string may differ from its original location. Tcl_UtfToUpper writes a null byte at the end of the converted string. Tcl_UtfToUpper returns the new length of the string in bytes. This new length is guaranteed to be no longer than the orig‐ inal string length. Tcl_UtfToLower is the same as Tcl_UtfToUpper except it turns each char‐ acter in the string into its lower-case equivalent. Tcl_UtfToTitle is the same as Tcl_UtfToUpper except it turns the first character in the string into its title-case equivalent and all follow‐ ing characters into their lower-case equivalents. BUGS At this time, the case conversions are only defined for the Unicode plane 0 characters. The result for Unicode characters above 0xFFFF is undefined, but - actually - only the lower 16 bits of the character value is handled. KEYWORDS utf, unicode, toupper, tolower, totitle, case Tcl 8.1 Tcl_UtfToUpper(3)
Notifier(3) Процедуры библиотеки Tcl Notifier(3) ______________________________________________________________________________ NAME Tcl_CreateEventSource, Tcl_DeleteEventSource, Tcl_SetMaxBlockTime, Tcl_QueueEvent, Tcl_ThreadQueueEvent, Tcl_ThreadAlert, Tcl_GetCurrent‐ Thread, Tcl_DeleteEvents, Tcl_InitNotifier, Tcl_FinalizeNotifier, Tcl_WaitForEvent, Tcl_AlertNotifier, Tcl_SetTimer, Tcl_ServiceAll, Tcl_ServiceEvent, Tcl_GetServiceMode, Tcl_SetServiceMode, Tcl_Service‐ ModeHook, Tcl_SetNotifier - интерфейсы очереди событий и уведомителя SYNOPSIS #include <tcl.h> void Tcl_CreateEventSource(setupProc, checkProc, clientData) void Tcl_DeleteEventSource(setupProc, checkProc, clientData) void Tcl_SetMaxBlockTime(timePtr) void Tcl_QueueEvent(evPtr, position) void Tcl_ThreadQueueEvent(threadId, evPtr, position) void Tcl_ThreadAlert(threadId) Tcl_ThreadId Tcl_GetCurrentThread() void Tcl_DeleteEvents(deleteProc, clientData) ClientData Tcl_InitNotifier() void Tcl_FinalizeNotifier(clientData) int Tcl_WaitForEvent(timePtr) void Tcl_AlertNotifier(clientData) void Tcl_SetTimer(timePtr) int Tcl_ServiceAll() int Tcl_ServiceEvent(flags) int Tcl_GetServiceMode() int Tcl_SetServiceMode(mode) void Tcl_ServiceModeHook(mode) void Tcl_SetNotifier(notifierProcPtr) ARGUMENTS Tcl_EventSetupProc *setupProc (in) Процедура для вызова для подготовки к ожиданию события в Tcl_DoOneEvent. Tcl_EventCheckProc *checkProc (in) Процедура для вызова Tcl_DoOneEvent после ожидания событий. Проверяет, произошли ли какие-либо события и, если да, добавляет их в очередь. ClientData clientData (in) Произвольное значение размером в одно слово для передачи в setupProc, checkProc или deleteProc. const Tcl_Time *timePtr (in) Указывает максимальное количество времени для ожидания события. Это указано как интервал (сколько ждать), а не абсолютное время (когда проснуться). Если указатель, переданный в Tcl_WaitForEvent, равен NULL, это означает, что нет максимального времени ожидания: ждать вечно, если это необходимо. Tcl_Event *evPtr (in) Событие для добавления в очередь событий. Память для события должна быть выделена вызывающей стороной с помощью Tcl_Al‐ loc или ckalloc. Tcl_QueuePosition position (in) Где добавить новое событие в очередь: TCL_QUEUE_TAIL, TCL_QUEUE_HEAD или TCL_QUEUE_MARK. Tcl_ThreadId threadId (in) Уникальный идентификатор потока. Tcl_EventDeleteProc *deleteProc (in) Процедура для вызова для каждого события в очереди в Tcl_DeleteEvents. int flags (in) Типы событий, которые нужно обработать. Эти флаги те же, что и те, которые передаются в Tcl_DoOneEvent. int mode (in) Указывает, должны ли события обрабатываться Tcl_Ser‐ viceAll. Должен быть одним из TCL_SERVICE_NONE или TCL_SERVICE_ALL. Tcl_NotifierProcs* notifierProcPtr (in) Структура указателей на функции, описывающая процедуры уведомителя, которые должны заменить те, которые установлены в исполняемом файле. Смотрите REPLACING THE NOTIFIER для деталей. ______________________________________________________________________________ INTRODUCTION Интерфейсы, описанные здесь, используются для настройки цикла событий Tcl. Два наиболее распространенных варианта настройки - это добавление новых источников событий и объединение цикла событий Tcl с другим циклом событий, например, предоставленным приложением, в которое встроен Tcl. Каждая из этих задач описана в отдельном разделе ниже. Процедуры в этом руководстве являются строительными блоками, из которых построен уведомитель событий Tcl. Уведомитель событий - это самый нижний слой в механизме событий Tcl. Он состоит из трех частей: [1] Источники событий: они представляют способы, с помощью которых могут генерироваться события. Например, существует источник событий таймера, который реализует процедуру Tcl_CreateTimerHandler и команду after, и источник событий файлов, который реализует процедуру Tcl_CreateFileHandler на системах Unix. Источник событий должен работать с уведомителем, чтобы обнаруживать события в нужное время, записывать их в очередь событий и, в конечном итоге, уведомлять более высокоуровневое программное обеспечение о том, что они произошли. Процедуры Tcl_CreateEventSource, Tcl_DeleteEventSource, и Tcl_Set‐ MaxBlockTime, Tcl_QueueEvent и Tcl_DeleteEvents в основном используются источниками событий. [2] Очередь событий: для приложений без потоков существует одна очередь для всего приложения, содержащая события, которые были обнаружены, но еще не обработаны. Источники событий добавляют события в очередь, чтобы они могли быть обработаны в порядке в подходящее время во время цикла событий. Очередь событий гарантирует справедливую дисциплину обработки событий, чтобы ни один источник событий не мог "голодать" другие. Она также позволяет сохранять события для обработки в будущем. Приложения с потоками работают похожим образом, за исключением того, что для каждого потока, содержащего интерпретатор Tcl, существует отдельная очередь событий. Tcl_QueueEvent используется (в основном источниками событий), чтобы добавить события в очередь событий, а Tcl_DeleteEvents используется для удаления событий из очереди без обработки. В приложении с потоками Tcl_QueueEvent добавляет событие в очередь текущего потока, а Tcl_ThreadQueueEvent добавляет событие в очередь в определенном потоке. [3] Цикл событий: чтобы обнаруживать и обрабатывать события, приложение входит в цикл, который ждет, пока события произойдут, добавляет их в очередь событий и затем обрабатывает их. Большинство приложений будут делать это, вызывая процедуру Tcl_DoOneEvent, которая описана в отдельном руководстве. Большинству приложений Tcl не нужно беспокоиться о внутренних деталях уведомителя Tcl. Однако, уведомитель теперь имеет достаточно гибкости, чтобы быть перенаправленным либо для новой платформы, либо для использования внешнего цикла событий (например, цикла событий Motif, когда Tcl встроен в приложение Motif). Процедуры Tcl_WaitForEvent и Tcl_SetTimer обычно реализуются Tcl, но могут быть заменены новыми версиями для перенаправления уведомителя (процедуры Tcl_InitNotifier, Tcl_AlertNotifier, Tcl_FinalizeNo‐ tifier, Tcl_Sleep, Tcl_CreateFileHandler и Tcl_DeleteFileHandler также должны быть заменены; см. CREATING A NEW NOTIFIER ниже для деталей). Процедуры Tcl_ServiceAll, Tcl_ServiceEvent, Tcl_GetServiceMode и Tcl_SetServiceMode предоставляются для помощи в подключении цикла событий Tcl к внешнему циклу событий, такому как Motif. NOTIFIER BASICS Самый простой способ понять, как работает уведомитель, - это рассмотреть, что происходит, когда вызывается Tcl_DoOneEvent. Tcl_DoOneEvent передается аргумент flags, который указывает, какие виды событий допустимо обрабатывать, и также указывает, блокировать ли, если события не готовы. Tcl_DoOneEvent выполняет следующие действия: [1] Проверяет очередь событий, чтобы увидеть, содержит ли она события, которые можно обработать. Если да, обрабатывает первое возможное событие, удаляет его из очереди и возвращает. Для этого оно вызывает Tcl_Ser‐ viceEvent и передает аргумент flags. [2] Подготавливается к блокировке для события. Для этого Tcl_DoOneEvent вызы‐ вает процедуру настройки в каждом источнике событий. Источник событий выполнит инициализацию, специфичную для источника событий, и, возможно, вызовет Tcl_SetMaxBlockTime, чтобы ограничить, сколько времени Tcl_WaitForEvent будет блокировать, если не произойдет новых событий. [3] Вызывает Tcl_WaitForEvent. Эта процедура реализована по-разному на разных платформах; она ждет, пока произойдет событие, на основе информации, предоставленной источниками событий. Она может заставить приложение заблокироваться, если timePtr указывает интервал, отличный от 0. Tcl_WaitForEvent возвращается, когда что-то произошло, например, файл становится доступным для чтения или истекает указанный интервал timePtr. Если нет событий, для которых Tcl_WaitForEvent может ждать, так что он заблокируется навсегда, то он возвращается немедленно, и Tcl_DoOneEvent возвращает 0. [4] Вызывает процедуру проверки в каждом источнике событий. Процедура проверки определяет, произошли ли события, интересующие этот источник. Если да, события добавляются в очередь событий. [5] Проверяет очередь событий, чтобы увидеть, содержит ли она события, которые можно обработать. Если да, обрабатывает первое возможное событие, удаляет его из очереди и возвращает. [6] Проверяет, есть ли ожидающие вызовы бездействия. Если да, вызывает все из них и возвращает. [7] Либо возвращает 0, чтобы указать, что события не готовы, либо возвращается к шагу [2], если блокировка была запрошена вызывающей стороной. CREATING A NEW EVENT SOURCE Источник событий состоит из трех процедур, вызываемых уведомителем, плюс дополнительных процедур C, которые вызываются более высокоуровневым кодом для организации событийных обратных вызовов. Три процедуры, вызываемые уведомителем, состоят из процедур настройки и проверки, описанных выше, плюс дополнительной процедуры, которая вызывается, когда событие удаляется из очереди событий для обработки. Процедура Tcl_CreateEventSource создает новый источник событий. Ее аргументы указывают процедуру настройки и процедуру проверки для источника событий. SetupProc должна соответствовать следующему прототипу: typedef void Tcl_EventSetupProc( ClientData clientData, int flags); Аргумент clientData будет таким же, как аргумент clientData для Tcl_CreateEventSource; он обычно используется для указания на частную информацию, управляемую источником событий. Аргумент flags будет таким же, как аргумент flags, переданный в Tcl_DoOneEvent, за исключением того, что он никогда не будет 0 (Tcl_DoOneEvent заменяет 0 на TCL_ALL_EVENTS). Flags указывает, какие виды событий следует учитывать; если бит, соответствующий этому источнику событий, не установлен, источник событий должен вернуться немедленно, не делая ничего. Например, источник событий файлов проверяет бит TCL_FILE_EVENTS. Задача SetupProc - убедиться, что приложение проснется, когда произойдут события желаемого типа. Это обычно делается в платформо-зависимом стиле. Например, под Unix источник событий может вызвать Tcl_CreateFileHandler; под Windows он может запросить уведомление с помощью события Windows. Для источников событий, управляемых таймером, таких как события таймера или любые опрошенные события, источник событий может вызвать Tcl_SetMaxBlockTime, чтобы заставить приложение проснуться через указанное время, даже если события не произошли. Если ни один источник событий не вызывает Tcl_SetMaxBlockTime, то Tcl_WaitForEvent будет ждать столько, сколько нужно для события; в противном случае он будет ждать только столько, сколько указано самым коротким интервалом, переданным Tcl_SetMaxBlockTime одним из источников событий. Если источник событий знает, что у него уже есть события, готовые к отчету, он может запросить нулевое максимальное время блокировки. Например, процедура настройки для источника событий X проверяет, есть ли события, уже поставленные в очередь. Если да, она вызывает Tcl_SetMaxBlockTime с нулевым временем блокировки, чтобы Tcl_WaitForEvent не блокировал, если нет новых данных на соединении X. Аргумент timePtr для Tcl_WaitForEvent указывает на структуру, которая описывает интервал времени в секундах и микросекундах: typedef struct Tcl_Time { long sec; long usec; } Tcl_Time; Поле usec должно быть меньше 1000000. Информация, предоставленная Tcl_SetMaxBlockTime, используется только для следующего вызова Tcl_WaitForEvent; она отбрасывается после того, как Tcl_WaitForEvent вернется. В следующий раз, когда будет выполнено ожидание события, будут вызваны процедуры настройки каждого из источников событий, и они смогут указать новую информацию для этого ожидания события. Если приложение использует внешний цикл событий, а не Tcl_DoOneEvent, источники событий могут нуждаться в вызове Tcl_SetMaxBlockTime в другие времена. Например, если зарегистрирован новый обработчик событий, который должен опрашивать события, источник событий может вызвать Tcl_SetMaxBlockTime, чтобы установить время блокировки на ноль, чтобы заставить внешний цикл событий вызвать Tcl. В этом случае Tcl_SetMaxBlockTime вызывает Tcl_SetTimer с самым коротким интервалом, увиденным с момента последнего вызова Tcl_DoOneEvent или Tcl_ServiceAll. Помимо общей процедуры Tcl_SetMaxBlockTime, могут быть доступны другие платформо-специфические процедуры для setupProc, если Tcl_WaitForEvent на этой платформе требует дополнительной информации. Например, на системах Unix интерфейс Tcl_CreateFileHandler может быть использован для ожидания событий файлов. Вторая процедура, предоставляемая каждым источником событий, - это его процедура проверки, указанная аргументом checkProc для Tcl_CreateEventSource. CheckProc должна соответствовать следующему прототипу: typedef void Tcl_EventCheckProc( ClientData clientData, int flags); Аргументы этой процедуры те же, что и для setupProc. CheckProc вызывается Tcl_DoOneEvent после того, как оно подождало событий. Предположительно, по крайней мере один источник событий теперь готов поставить событие в очередь. Tcl_DoOneEvent вызывает каждый из источников событий по очереди, чтобы они все имели возможность поставить в очередь любые готовые события. Процедура проверки делает две вещи. Во-первых, она должна проверить, произошли ли события. Разные источники событий делают это по-разному. Если процедура проверки источника событий обнаруживает интересное событие, она должна добавить событие в очередь событий Tcl. Для этого источник событий вызывает Tcl_QueueEvent. Аргумент evPtr - это указатель на динамически выделенную структуру, содержащую событие (см. ниже для получения дополнительной информации о проблемах управления памятью). Каждый источник событий может определять свою собственную структуру событий с любой релевантной информацией. Однако, первый элемент структуры должен быть структурой типа Tcl_Event, и адрес этой структуры используется при общении между источником событий и остальной частью уведомителя. Tcl_Event имеет следующее определение: typedef struct { Tcl_EventProc *proc; struct Tcl_Event *nextPtr; } Tcl_Event; Источник событий должен заполнить поле proc события перед вызовом Tcl_QueueEvent. NextPtr используется для связывания событий в очереди и не должен изменяться источником событий. Событие может быть добавлено в очередь в одной из трех позиций, в зависимости от аргумента position для Tcl_QueueEvent: TCL_QUEUE_TAIL Добавить событие в конец очереди, так чтобы все другие ожидающие события были обработаны сначала. Это почти всегда правильное место для новых событий. TCL_QUEUE_HEAD Добавить событие в начало очереди, так чтобы оно было обработано перед всеми другими событиями в очереди. TCL_QUEUE_MARK Добавить событие в начало очереди, если нет других событий в начале с позицией TCL_QUEUE_MARK; если да, добавить новое событие сразу после всех других событий TCL_QUEUE_MARK. Это значение position используется для вставки упорядоченной последовательности событий в начало очереди, например, серии событий Enter и Leave, синтезированных во время операции захвата или освобождения в Tk. Когда приходит время обработать событие из очереди (шаги 1 и 4 выше), Tcl_ServiceEvent вызовет proc, указанную в первой структуре Tcl_Event в очереди. Proc должна соответствовать следующему прототипу: typedef int Tcl_EventProc( Tcl_Event *evPtr, int flags); Первый аргумент proc - это указатель на событие, который будет таким же, как первый аргумент вызова Tcl_QueueEvent, который добавил событие в очередь. Второй аргумент proc - это аргумент flags для текущего вызова Tcl_ServiceEvent; он используется источником событий, чтобы вернуться немедленно, если его события не релевантны. Proc должна обработать событие, обычно вызывая одну или несколько команд Tcl или обратных вызовов на уровне C. Как только источник событий закончил обработку события, он возвращает 1, чтобы указать, что событие можно удалить из очереди. Если по какой-то причине источник событий решает, что событие не может быть обработано в это время, он может вернуть 0, чтобы указать, что событие должно быть отложено для обработки позже; в этом случае Tcl_ServiceEvent перейдет к следующему событию в очереди и попытается обработать его. Существует несколько причин, по которым источник событий может отложить событие. Одна возможность - это то, что события этого типа исключены аргументом flags. Например, источник событий файлов всегда вернет 0, если бит TCL_FILE_EVENTS не установлен в flags. Другой пример отсрочки событий происходит в Tk, если Tk_RestrictEvents была вызвана, чтобы отложить определенные виды событий окон. Когда proc возвращает 1, Tcl_ServiceEvent удалит событие из очереди событий и освободит его память. Обратите внимание, что память для события должна быть выделена источником событий (с помощью Tcl_Alloc или макроса Tcl ckalloc) перед вызовом Tcl_QueueEvent, но она будет освобождена Tcl_ServiceEvent, а не источником событий. Приложения с потоками работают похожим образом, за исключением того, что для каждого потока, содержащего интерпретатор Tcl, существует отдельная очередь событий. Вызов Tcl_QueueEvent в многопотоковом приложении добавляет событие в очередь текущего потока. Чтобы добавить событие в очередь другого потока, используйте Tcl_ThreadQueueEvent. Tcl_ThreadQueueEvent принимает аргумент Tcl_ThreadId, который однозначно идентифицирует поток в приложении Tcl. Чтобы получить Tcl_ThreadId для текущего потока, используйте процедуру Tcl_GetCurrentThread. (Поток затем должен передать этот идентификатор другим потокам, чтобы те могли добавлять события в его очередь.) После добавления события в очередь другого потока вы, вероятно, затем должны вызвать Tcl_ThreadAlert, чтобы "разбудить" уведомитель этого потока, чтобы уведомить его о новом событии. Tcl_DeleteEvents можно использовать для явного удаления одного или нескольких событий из очереди событий. Tcl_DeleteEvents вызывает proc для каждого события в очереди, удаляя те, для которых процедура возвращает 1. События, для которых процедура возвращает 0, оставляются в очереди. Proc должна соответствовать следующему прототипу: typedef int Tcl_EventDeleteProc( Tcl_Event *evPtr, ClientData clientData); Аргумент clientData будет таким же, как аргумент clientData для Tcl_DeleteEvents; он обычно используется для указания на частную информацию, управляемую источником событий. EvPtr будет указывать на следующее событие в очереди. Tcl_DeleteEventSource удаляет источник событий. Аргументы setupProc, checkProc и clientData должны точно соответствовать тем, которые были предоставлены Tcl_CreateEventSource для источника событий, который нужно удалить. Если такого источника не существует, Tcl_DeleteEventSource не оказывает никакого эффекта. CREATING A NEW NOTIFIER Уведомитель состоит из всех процедур, описанных в этом руководстве, плюс Tcl_DoOneEvent и Tcl_Sleep, которые доступны на всех платформах, и Tcl_CreateFileHandler и Tcl_DeleteFileHandler, которые специфичны для Unix. Большинство из этих процедур являются общими, то есть они одинаковы для всех уведомителей. Однако, ни одна из процедур не зависит от уведомителя: Tcl_InitNotifier, Tcl_AlertNotifier, Tcl_FinalizeNotifier, Tcl_SetTimer, Tcl_Sleep, Tcl_WaitForEvent, Tcl_CreateFileHandler, Tcl_DeleteFileHandler и Tcl_ServiceModeHook. Чтобы поддерживать новую платформу или интегрировать Tcl с приложением-специфическим циклом событий, вы должны написать новые версии этих процедур. Tcl_InitNotifier инициализирует состояние уведомителя и возвращает дескриптор состояния уведомителя. Tcl вызывает эту процедуру при инициализации интерпретатора Tcl. Аналогично, Tcl_FinalizeNotifier завершает работу уведомителя и вызывается Tcl_Finalize при завершении работы интерпретатора Tcl. Tcl_WaitForEvent - это самая низкоуровневая процедура в уведомителе; она отвечает за ожидание "интересного" события или истечения указанного времени. Перед вызовом Tcl_WaitForEvent каждая из процедур настройки источников событий будет вызвана. Аргумент timePtr для Tcl_WaitForEvent указывает максимальное время для блокировки события, на основе вызовов Tcl_SetMaxBlockTime, сделанных процедурами настройки, и другой информации (например, бита TCL_DONT_WAIT в flags). Идеально, Tcl_WaitForEvent должен только ждать события; он не должен фактически обрабатывать событие каким-либо образом. Позже источники событий обработают необработанные события и создадут Tcl_Events в очереди событий в своих процедурах checkProc. Однако, на некоторых платформах (таких как Windows) это невозможно; события могут обрабатываться в Tcl_WaitForEvent, включая постановку в очередь Tcl_Events и больше (например, обратные вызовы для нативных виджетов могут быть вызваны). Значение возврата из Tcl_WaitForEvent должно быть либо 0, 1, либо -1. На платформах, таких как Windows, где события обрабатываются в Tcl_WaitForEvent, значение возврата 1 означает, что могут быть еще события, ожидающие обработки, которые не были обработаны. Это сигнал вызывающей стороне, что ей нужно вызвать Tcl_WaitForEvent снова, если она хочет обработать все ожидающие события. Значение возврата 0 означает, что вызов Tcl_WaitForEvent снова не окажет никакого эффекта: либо это платформа, где Tcl_WaitForEvent только ждет, не обрабатывая события, либо Tcl_WaitForEvent знает наверняка, что нет дополнительных событий для обработки (например, оно вернулось из-за истечения времени). Наконец, значение возврата -1 означает, что цикл событий больше не работает, и приложение, вероятно, должно размотать и завершить работу. Под Windows это происходит, когда получено сообщение WM_QUIT; под Unix это происходит, когда Tcl_WaitForEvent бы подождал вечно, потому что не было активных источников событий и время ожидания было бесконечным. Tcl_AlertNotifier используется в многопотоковых приложениях, чтобы любой поток мог "разбудить" уведомитель, чтобы уведомить его о новых событиях в его очереди. Tcl_AlertNotifier требует аргументом дескриптор уведомителя, возвращаемый Tcl_InitNotifier. Если уведомитель будет использоваться с внешним циклом событий, то он также должен поддерживать интерфейс Tcl_SetTimer. Tcl_SetTimer вызывается Tcl_SetMaxBlockTime всякий раз, когда максимальное время блокировки было сокращено. Tcl_SetTimer должен организовать, чтобы внешний цикл событий вызвал Tcl_ServiceAll после указанного интервала, даже если события не произошли. Этот интерфейс нужен, потому что Tcl_WaitForEvent не вызывается, когда есть внешний цикл событий. Если уведомитель будет использоваться только из Tcl_DoOneEvent, то Tcl_SetTimer не нужно делать ничего. Tcl_ServiceModeHook вызывается платформо-независимой частью уведомителя, когда клиентский код вызывает Tcl_SetServiceMode. Этот хук предоставляется для поддержки операционных систем, которые требуют специальной обработки событий, когда приложение находится в модальном цикле (уведомитель Windows, например, использует этот хук для создания окна связи). На системах Unix источник событий файлов также нуждается в поддержке от уведомителя. Источник событий файлов состоит из процедур Tcl_CreateFileHandler и Tcl_DeleteFileHandler, которые описаны на странице руководства Tcl_CreateFileHandler. Интерфейсы Tcl_Sleep и Tcl_DoOneEvent описаны в их соответствующих страницах руководства. Самый простой способ создать новый уведомитель - это посмотреть на код существующего уведомителя, например, файлы unix/tclUnixNotfy.c или win/tclWin‐ Notify.c в распределении исходного кода Tcl. REPLACING THE NOTIFIER Уведомитель, написанный в соответствии с вышеуказанными соглашениями, также может быть установлен в работающем процессе вместо стандартного уведомителя. Этот механизм используется, чтобы один исполняемый файл мог использоваться (с стандартным уведомителем) как автономная программа и повторно использоваться (с заменой уведомителя в загружаемом расширении) как расширение для другого приложения, такого как плагин веб-браузера. Для этого расширение вызывает Tcl_SetNotifier, передавая указатель на структуру данных Tcl_NotifierProcs. Структура имеет следующую компоновку: typedef struct Tcl_NotifierProcs { Tcl_SetTimerProc *setTimerProc; Tcl_WaitForEventProc *waitForEventProc; Tcl_CreateFileHandlerProc *createFileHandlerProc; Tcl_DeleteFileHandlerProc *deleteFileHandlerProc; Tcl_InitNotifierProc *initNotifierProc; Tcl_FinalizeNotifierProc *finalizeNotifierProc; Tcl_AlertNotifierProc *alertNotifierProc; Tcl_ServiceModeHookProc *serviceModeHookProc; } Tcl_NotifierProcs; После вызова Tcl_SetNotifier указатели, данные в структуре Tcl_NotifierProcs, заменяют уведомитель, который был установлен в процессе. Это чрезвычайно неразумно заменять работающий уведомитель. Обычно Tcl_SetNotifier следует вызывать в момент инициализации процесса до первого вызова Tcl_InitNotifier. EXTERNAL EVENT LOOPS Интерфейсы уведомителя разработаны так, чтобы Tcl мог быть встроен в приложения, которые имеют свои собственные частные циклы событий. В этом случае приложение не вызывает Tcl_DoOneEvent, кроме случаев рекурсивных циклов событий, таких как вызовы команд Tcl update или vwait. Большую часть времени тратится во внешнем цикле событий приложения. В этом случае уведомитель должен организовать, чтобы внешний цикл событий вызывал обратно в Tcl, когда что-то происходит в различных источниках событий Tcl. Эти обратные вызовы должны организовать постановку соответствующих событий Tcl в очередь событий Tcl. Поскольку внешний цикл событий не вызывает Tcl_DoOneEvent на регулярной основе, уведомитель должен организовать вызов Tcl_ServiceEvent всякий раз, когда события ожидаются в очереди событий Tcl. Самый простой способ сделать это - вызвать Tcl_ServiceAll в конце каждого обратного вызова из внешнего цикла событий. Это обеспечит опрос всех источников событий, обработку всех поставленных в очередь событий и обработку любых ожидающих обработчиков бездействия перед возвратом управления приложению. Кроме того, источники событий, которые должны опрашивать события, могут вызвать Tcl_SetMaxBlockTime, чтобы заставить внешний цикл событий вызвать Tcl, даже если события недоступны в очереди событий системы. Как побочный эффект обработки событий, обнаруженных в основном внешнем цикле событий, Tcl может вызвать Tcl_DoOneEvent для запуска рекурсивного цикла событий в командах, таких как vwait. Tcl_DoOneEvent вызовет внешний цикл событий, что приведет к обратным вызовам, как описано в предыдущем абзаце, что приведет к вызовам Tcl_ServiceAll. Однако, в этих случаях нежелательно, чтобы Tcl_ServiceAll обрабатывало события. Обработка событий там ненужна, потому что управление немедленно вернется во внешний цикл событий и, следовательно, в Tcl_DoOneEvent, который может обработать события сам. Кроме того, Tcl_DoOneEvent должен обрабатывать только одно событие, в то время как Tcl_ServiceAll обычно обрабатывает все ожидающие события. Чтобы обработать эту ситуацию, Tcl_DoOneEvent устанавливает флаг для Tcl_ServiceAll, который заставляет его вернуться немедленно без обработки каких-либо событий. Этот флаг называется режимом обслуживания; Tcl_DoOneEvent восстанавливает его предыдущее значение перед возвратом. В некоторых случаях, однако, может потребоваться, чтобы Tcl_ServiceAll обрабатывало события, даже когда оно было вызвано из Tcl_DoOneEvent. Это происходит, когда есть еще один рекурсивный цикл событий, вызванный через обработчик события, вызванный Tcl_DoOneEvent (например, часть нативного виджета). В этом случае Tcl_DoOneEvent может не иметь возможности обработать события, поэтому Tcl_ServiceAll должно обработать все. Любому рекурсивному циклу событий, который вызывает внешний цикл событий, а не Tcl_DoOneEvent, нужно сбросить режим обслуживания, чтобы все события обрабатывались в Tcl_ServiceAll. Это делается с помощью процедуры Tcl_SetServiceMode. Если Tcl_SetServiceMode передается TCL_SERVICE_NONE, то вызовы Tcl_ServiceAll вернутся немедленно без обработки каких-либо событий. Если Tcl_SetServiceMode передается TCL_SERVICE_ALL, то вызовы Tcl_ServiceAll будут вести себя нормально. Tcl_SetServiceMode возвращает предыдущее значение режима обслуживания, которое должно быть восстановлено при выходе из рекурсивного цикла. Tcl_GetServiceMode возвращает текущее значение режима обслуживания. SEE ALSO Tcl_CreateFileHandler(3), Tcl_DeleteFileHandler(3), Tcl_Sleep(3), Tcl_DoOneEvent(3), Thread(3) KEYWORDS event, notifier, event queue, event sources, file events, timer, idle, service mode, threads Tcl 8.1 Notifier(3)
Notifier(3) Tcl Library Procedures Notifier(3) ______________________________________________________________________________ NAME Tcl_CreateEventSource, Tcl_DeleteEventSource, Tcl_SetMaxBlockTime, Tcl_QueueEvent, Tcl_ThreadQueueEvent, Tcl_ThreadAlert, Tcl_GetCurrent‐ Thread, Tcl_DeleteEvents, Tcl_InitNotifier, Tcl_FinalizeNotifier, Tcl_WaitForEvent, Tcl_AlertNotifier, Tcl_SetTimer, Tcl_ServiceAll, Tcl_ServiceEvent, Tcl_GetServiceMode, Tcl_SetServiceMode, Tcl_Service‐ ModeHook, Tcl_SetNotifier - the event queue and notifier interfaces SYNOPSIS #include <tcl.h> void Tcl_CreateEventSource(setupProc, checkProc, clientData) void Tcl_DeleteEventSource(setupProc, checkProc, clientData) void Tcl_SetMaxBlockTime(timePtr) void Tcl_QueueEvent(evPtr, position) void Tcl_ThreadQueueEvent(threadId, evPtr, position) void Tcl_ThreadAlert(threadId) Tcl_ThreadId Tcl_GetCurrentThread() void Tcl_DeleteEvents(deleteProc, clientData) ClientData Tcl_InitNotifier() void Tcl_FinalizeNotifier(clientData) int Tcl_WaitForEvent(timePtr) void Tcl_AlertNotifier(clientData) void Tcl_SetTimer(timePtr) int Tcl_ServiceAll() int Tcl_ServiceEvent(flags) int Tcl_GetServiceMode() int Tcl_SetServiceMode(mode) void Tcl_ServiceModeHook(mode) void Tcl_SetNotifier(notifierProcPtr) ARGUMENTS Tcl_EventSetupProc *setupProc (in) Procedure to invoke to prepare for event wait in Tcl_DoOneEvent. Tcl_EventCheckProc *checkProc (in) Procedure for Tcl_DoOneEvent to invoke after waiting for events. Checks to see if any events have occurred and, if so, queues them. ClientData clientData (in) Arbitrary one-word value to pass to se‐ tupProc, checkProc, or deleteProc. const Tcl_Time *timePtr (in) Indicates the maxi‐ mum amount of time to wait for an event. This is specified as an in‐ terval (how long to wait), not an abso‐ lute time (when to wakeup). If the pointer passed to Tcl_WaitForEvent is NULL, it means there is no maximum wait time: wait forever if necessary. Tcl_Event *evPtr (in) An event to add to the event queue. The storage for the event must have been allocated by the caller using Tcl_Al‐ loc or ckalloc. Tcl_QueuePosition position (in) Where to add the new event in the queue: TCL_QUEUE_TAIL, TCL_QUEUE_HEAD, or TCL_QUEUE_MARK. Tcl_ThreadId threadId (in) A unique identifier for a thread. Tcl_EventDeleteProc *deleteProc (in) Procedure to invoke for each queued event in Tcl_Dele‐ teEvents. int flags (in) What types of events to service. These flags are the same as those passed to Tcl_DoOneEvent. int mode (in) Indicates whether events should be serviced by Tcl_Ser‐ viceAll. Must be one of TCL_SER‐ VICE_NONE or TCL_SERVICE_ALL. Tcl_NotifierProcs* notifierProcPtr (in) Structure of func‐ tion pointers de‐ scribing notifier procedures that are to replace the ones installed in the ex‐ ecutable. See RE‐ PLACING THE NOTIFIER for details. ______________________________________________________________________________ INTRODUCTION The interfaces described here are used to customize the Tcl event loop. The two most common customizations are to add new sources of events and to merge Tcl's event loop with some other event loop, such as one pro‐ vided by an application in which Tcl is embedded. Each of these tasks is described in a separate section below. The procedures in this manual entry are the building blocks out of which the Tcl event notifier is constructed. The event notifier is the lowest layer in the Tcl event mechanism. It consists of three things: [1] Event sources: these represent the ways in which events can be generated. For example, there is a timer event source that im‐ plements the Tcl_CreateTimerHandler procedure and the after com‐ mand, and there is a file event source that implements the Tcl_CreateFileHandler procedure on Unix systems. An event source must work with the notifier to detect events at the right times, record them on the event queue, and eventually notify higher-level software that they have occurred. The procedures Tcl_CreateEventSource, Tcl_DeleteEventSource, and Tcl_Set‐ MaxBlockTime, Tcl_QueueEvent, and Tcl_DeleteEvents are used pri‐ marily by event sources. [2] The event queue: for non-threaded applications, there is a sin‐ gle queue for the whole application, containing events that have been detected but not yet serviced. Event sources place events onto the queue so that they may be processed in order at appro‐ priate times during the event loop. The event queue guarantees a fair discipline of event handling, so that no event source can starve the others. It also allows events to be saved for ser‐ vicing at a future time. Threaded applications work in a simi‐ lar manner, except that there is a separate event queue for each thread containing a Tcl interpreter. Tcl_QueueEvent is used (primarily by event sources) to add events to the event queue and Tcl_DeleteEvents is used to remove events from the queue without processing them. In a threaded application, Tcl_QueueEvent adds an event to the current thread's queue, and Tcl_ThreadQueueEvent adds an event to a queue in a specific thread. [3] The event loop: in order to detect and process events, the ap‐ plication enters a loop that waits for events to occur, places them on the event queue, and then processes them. Most applica‐ tions will do this by calling the procedure Tcl_DoOneEvent, which is described in a separate manual entry. Most Tcl applications need not worry about any of the internals of the Tcl notifier. However, the notifier now has enough flexibility to be retargeted either for a new platform or to use an external event loop (such as the Motif event loop, when Tcl is embedded in a Motif applica‐ tion). The procedures Tcl_WaitForEvent and Tcl_SetTimer are normally implemented by Tcl, but may be replaced with new versions to retarget the notifier (the Tcl_InitNotifier, Tcl_AlertNotifier, Tcl_FinalizeNo‐ tifier, Tcl_Sleep, Tcl_CreateFileHandler, and Tcl_DeleteFileHandler must also be replaced; see CREATING A NEW NOTIFIER below for details). The procedures Tcl_ServiceAll, Tcl_ServiceEvent, Tcl_GetServiceMode, and Tcl_SetServiceMode are provided to help connect Tcl's event loop to an external event loop such as Motif's. NOTIFIER BASICS The easiest way to understand how the notifier works is to consider what happens when Tcl_DoOneEvent is called. Tcl_DoOneEvent is passed a flags argument that indicates what sort of events it is OK to process and also whether or not to block if no events are ready. Tcl_DoOneEvent does the following things: [1] Check the event queue to see if it contains any events that can be serviced. If so, service the first possible event, remove it from the queue, and return. It does this by calling Tcl_Ser‐ viceEvent and passing in the flags argument. [2] Prepare to block for an event. To do this, Tcl_DoOneEvent in‐ vokes a setup procedure in each event source. The event source will perform event-source specific initialization and possibly call Tcl_SetMaxBlockTime to limit how long Tcl_WaitForEvent will block if no new events occur. [3] Call Tcl_WaitForEvent. This procedure is implemented differ‐ ently on different platforms; it waits for an event to occur, based on the information provided by the event sources. It may cause the application to block if timePtr specifies an interval other than 0. Tcl_WaitForEvent returns when something has hap‐ pened, such as a file becoming readable or the interval given by timePtr expiring. If there are no events for Tcl_WaitForEvent to wait for, so that it would block forever, then it returns im‐ mediately and Tcl_DoOneEvent returns 0. [4] Call a check procedure in each event source. The check proce‐ dure determines whether any events of interest to this source occurred. If so, the events are added to the event queue. [5] Check the event queue to see if it contains any events that can be serviced. If so, service the first possible event, remove it from the queue, and return. [6] See if there are idle callbacks pending. If so, invoke all of them and return. [7] Either return 0 to indicate that no events were ready, or go back to step [2] if blocking was requested by the caller. CREATING A NEW EVENT SOURCE An event source consists of three procedures invoked by the notifier, plus additional C procedures that are invoked by higher-level code to arrange for event-driven callbacks. The three procedures called by the notifier consist of the setup and check procedures described above, plus an additional procedure that is invoked when an event is removed from the event queue for servicing. The procedure Tcl_CreateEventSource creates a new event source. Its arguments specify the setup procedure and check procedure for the event source. SetupProc should match the following prototype: typedef void Tcl_EventSetupProc( ClientData clientData, int flags); The clientData argument will be the same as the clientData argument to Tcl_CreateEventSource; it is typically used to point to private infor‐ mation managed by the event source. The flags argument will be the same as the flags argument passed to Tcl_DoOneEvent except that it will never be 0 (Tcl_DoOneEvent replaces 0 with TCL_ALL_EVENTS). Flags in‐ dicates what kinds of events should be considered; if the bit corre‐ sponding to this event source is not set, the event source should re‐ turn immediately without doing anything. For example, the file event source checks for the TCL_FILE_EVENTS bit. SetupProc's job is to make sure that the application wakes up when events of the desired type occur. This is typically done in a plat‐ form-dependent fashion. For example, under Unix an event source might call Tcl_CreateFileHandler; under Windows it might request notification with a Windows event. For timer-driven event sources such as timer events or any polled event, the event source can call Tcl_SetMaxBlock‐ Time to force the application to wake up after a specified time even if no events have occurred. If no event source calls Tcl_SetMaxBlockTime then Tcl_WaitForEvent will wait as long as necessary for an event to occur; otherwise, it will only wait as long as the shortest interval passed to Tcl_SetMaxBlockTime by one of the event sources. If an event source knows that it already has events ready to report, it can request a zero maximum block time. For example, the setup procedure for the X event source looks to see if there are events already queued. If there are, it calls Tcl_SetMaxBlockTime with a 0 block time so that Tcl_Wait‐ ForEvent does not block if there is no new data on the X connection. The timePtr argument to Tcl_WaitForEvent points to a structure that de‐ scribes a time interval in seconds and microseconds: typedef struct Tcl_Time { long sec; long usec; } Tcl_Time; The usec field should be less than 1000000. Information provided to Tcl_SetMaxBlockTime is only used for the next call to Tcl_WaitForEvent; it is discarded after Tcl_WaitForEvent re‐ turns. The next time an event wait is done each of the event sources' setup procedures will be called again, and they can specify new infor‐ mation for that event wait. If the application uses an external event loop rather than Tcl_DoOneEvent, the event sources may need to call Tcl_SetMaxBlockTime at other times. For example, if a new event handler is registered that needs to poll for events, the event source may call Tcl_SetMaxBlockTime to set the block time to zero to force the external event loop to call Tcl. In this case, Tcl_SetMaxBlockTime invokes Tcl_SetTimer with the shortest interval seen since the last call to Tcl_DoOneEvent or Tcl_ServiceAll. In addition to the generic procedure Tcl_SetMaxBlockTime, other plat‐ form-specific procedures may also be available for setupProc, if there is additional information needed by Tcl_WaitForEvent on that platform. For example, on Unix systems the Tcl_CreateFileHandler interface can be used to wait for file events. The second procedure provided by each event source is its check proce‐ dure, indicated by the checkProc argument to Tcl_CreateEventSource. CheckProc must match the following prototype: typedef void Tcl_EventCheckProc( ClientData clientData, int flags); The arguments to this procedure are the same as those for setupProc. CheckProc is invoked by Tcl_DoOneEvent after it has waited for events. Presumably at least one event source is now prepared to queue an event. Tcl_DoOneEvent calls each of the event sources in turn, so they all have a chance to queue any events that are ready. The check procedure does two things. First, it must see if any events have triggered. Different event sources do this in different ways. If an event source's check procedure detects an interesting event, it must add the event to Tcl's event queue. To do this, the event source calls Tcl_QueueEvent. The evPtr argument is a pointer to a dynamically allocated structure containing the event (see below for more informa‐ tion on memory management issues). Each event source can define its own event structure with whatever information is relevant to that event source. However, the first element of the structure must be a struc‐ ture of type Tcl_Event, and the address of this structure is used when communicating between the event source and the rest of the notifier. A Tcl_Event has the following definition: typedef struct { Tcl_EventProc *proc; struct Tcl_Event *nextPtr; } Tcl_Event; The event source must fill in the proc field of the event before call‐ ing Tcl_QueueEvent. The nextPtr is used to link together the events in the queue and should not be modified by the event source. An event may be added to the queue at any of three positions, depending on the position argument to Tcl_QueueEvent: TCL_QUEUE_TAIL Add the event at the back of the queue, so that all other pending events will be serviced first. This is almost always the right place for new events. TCL_QUEUE_HEAD Add the event at the front of the queue, so that it will be serviced before all other queued events. TCL_QUEUE_MARK Add the event at the front of the queue, unless there are other events at the front whose posi‐ tion is TCL_QUEUE_MARK; if so, add the new event just after all other TCL_QUEUE_MARK events. This value of position is used to in‐ sert an ordered sequence of events at the front of the queue, such as a series of Enter and Leave events synthesized during a grab or un‐ grab operation in Tk. When it is time to handle an event from the queue (steps 1 and 4 above) Tcl_ServiceEvent will invoke the proc specified in the first queued Tcl_Event structure. Proc must match the following prototype: typedef int Tcl_EventProc( Tcl_Event *evPtr, int flags); The first argument to proc is a pointer to the event, which will be the same as the first argument to the Tcl_QueueEvent call that added the event to the queue. The second argument to proc is the flags argument for the current call to Tcl_ServiceEvent; this is used by the event source to return immediately if its events are not relevant. It is up to proc to handle the event, typically by invoking one or more Tcl commands or C-level callbacks. Once the event source has finished handling the event it returns 1 to indicate that the event can be re‐ moved from the queue. If for some reason the event source decides that the event cannot be handled at this time, it may return 0 to indicate that the event should be deferred for processing later; in this case Tcl_ServiceEvent will go on to the next event in the queue and attempt to service it. There are several reasons why an event source might de‐ fer an event. One possibility is that events of this type are excluded by the flags argument. For example, the file event source will always return 0 if the TCL_FILE_EVENTS bit is not set in flags. Another exam‐ ple of deferring events happens in Tk if Tk_RestrictEvents has been in‐ voked to defer certain kinds of window events. When proc returns 1, Tcl_ServiceEvent will remove the event from the event queue and free its storage. Note that the storage for an event must be allocated by the event source (using Tcl_Alloc or the Tcl macro ckalloc) before calling Tcl_QueueEvent, but it will be freed by Tcl_ServiceEvent, not by the event source. Threaded applications work in a similar manner, except that there is a separate event queue for each thread containing a Tcl interpreter. Calling Tcl_QueueEvent in a multithreaded application adds an event to the current thread's queue. To add an event to another thread's queue, use Tcl_ThreadQueueEvent. Tcl_ThreadQueueEvent accepts as an argument a Tcl_ThreadId argument, which uniquely identifies a thread in a Tcl application. To obtain the Tcl_ThreadId for the current thread, use the Tcl_GetCurrentThread procedure. (A thread would then need to pass this identifier to other threads for those threads to be able to add events to its queue.) After adding an event to another thread's queue, you then typically need to call Tcl_ThreadAlert to “wake up” that thread's notifier to alert it to the new event. Tcl_DeleteEvents can be used to explicitly remove one or more events from the event queue. Tcl_DeleteEvents calls proc for each event in the queue, deleting those for with the procedure returns 1. Events for which the procedure returns 0 are left in the queue. Proc should match the following prototype: typedef int Tcl_EventDeleteProc( Tcl_Event *evPtr, ClientData clientData); The clientData argument will be the same as the clientData argument to Tcl_DeleteEvents; it is typically used to point to private information managed by the event source. The evPtr will point to the next event in the queue. Tcl_DeleteEventSource deletes an event source. The setupProc, check‐ Proc, and clientData arguments must exactly match those provided to the Tcl_CreateEventSource for the event source to be deleted. If no such source exists, Tcl_DeleteEventSource has no effect. CREATING A NEW NOTIFIER The notifier consists of all the procedures described in this manual entry, plus Tcl_DoOneEvent and Tcl_Sleep, which are available on all platforms, and Tcl_CreateFileHandler and Tcl_DeleteFileHandler, which are Unix-specific. Most of these procedures are generic, in that they are the same for all notifiers. However, none of the procedures are notifier-dependent: Tcl_InitNotifier, Tcl_AlertNotifier, Tcl_Final‐ izeNotifier, Tcl_SetTimer, Tcl_Sleep, Tcl_WaitForEvent, Tcl_CreateFile‐ Handler, Tcl_DeleteFileHandler and Tcl_ServiceModeHook. To support a new platform or to integrate Tcl with an application-specific event loop, you must write new versions of these procedures. Tcl_InitNotifier initializes the notifier state and returns a handle to the notifier state. Tcl calls this procedure when initializing a Tcl interpreter. Similarly, Tcl_FinalizeNotifier shuts down the notifier, and is called by Tcl_Finalize when shutting down a Tcl interpreter. Tcl_WaitForEvent is the lowest-level procedure in the notifier; it is responsible for waiting for an “interesting” event to occur or for a given time to elapse. Before Tcl_WaitForEvent is invoked, each of the event sources' setup procedure will have been invoked. The timePtr ar‐ gument to Tcl_WaitForEvent gives the maximum time to block for an event, based on calls to Tcl_SetMaxBlockTime made by setup procedures and on other information (such as the TCL_DONT_WAIT bit in flags). Ideally, Tcl_WaitForEvent should only wait for an event to occur; it should not actually process the event in any way. Later on, the event sources will process the raw events and create Tcl_Events on the event queue in their checkProc procedures. However, on some platforms (such as Windows) this is not possible; events may be processed in Tcl_Wait‐ ForEvent, including queuing Tcl_Events and more (for example, callbacks for native widgets may be invoked). The return value from Tcl_Wait‐ ForEvent must be either 0, 1, or -1. On platforms such as Windows where events get processed in Tcl_WaitForEvent, a return value of 1 means that there may be more events still pending that have not been processed. This is a sign to the caller that it must call Tcl_Wait‐ ForEvent again if it wants all pending events to be processed. A 0 re‐ turn value means that calling Tcl_WaitForEvent again will not have any effect: either this is a platform where Tcl_WaitForEvent only waits without doing any event processing, or Tcl_WaitForEvent knows for sure that there are no additional events to process (e.g. it returned be‐ cause the time elapsed). Finally, a return value of -1 means that the event loop is no longer operational and the application should probably unwind and terminate. Under Windows this happens when a WM_QUIT mes‐ sage is received; under Unix it happens when Tcl_WaitForEvent would have waited forever because there were no active event sources and the timeout was infinite. Tcl_AlertNotifier is used in multithreaded applications to allow any thread to “wake up” the notifier to alert it to new events on its queue. Tcl_AlertNotifier requires as an argument the notifier handle returned by Tcl_InitNotifier. If the notifier will be used with an external event loop, then it must also support the Tcl_SetTimer interface. Tcl_SetTimer is invoked by Tcl_SetMaxBlockTime whenever the maximum blocking time has been re‐ duced. Tcl_SetTimer should arrange for the external event loop to in‐ voke Tcl_ServiceAll after the specified interval even if no events have occurred. This interface is needed because Tcl_WaitForEvent is not in‐ voked when there is an external event loop. If the notifier will only be used from Tcl_DoOneEvent, then Tcl_SetTimer need not do anything. Tcl_ServiceModeHook is called by the platform-independent portion of the notifier when client code makes a call to Tcl_SetServiceMode. This hook is provided to support operating systems that require special event handling when the application is in a modal loop (the Windows no‐ tifier, for instance, uses this hook to create a communication window). On Unix systems, the file event source also needs support from the no‐ tifier. The file event source consists of the Tcl_CreateFileHandler and Tcl_DeleteFileHandler procedures, which are described in the Tcl_CreateFileHandler manual page. The Tcl_Sleep and Tcl_DoOneEvent interfaces are described in their re‐ spective manual pages. The easiest way to create a new notifier is to look at the code for an existing notifier, such as the files unix/tclUnixNotfy.c or win/tclWin‐ Notify.c in the Tcl source distribution. REPLACING THE NOTIFIER A notifier that has been written according to the conventions above can also be installed in a running process in place of the standard noti‐ fier. This mechanism is used so that a single executable can be used (with the standard notifier) as a stand-alone program and reused (with a replacement notifier in a loadable extension) as an extension to an‐ other program, such as a Web browser plugin. To do this, the extension makes a call to Tcl_SetNotifier passing a pointer to a Tcl_NotifierProcs data structure. The structure has the following layout: typedef struct Tcl_NotifierProcs { Tcl_SetTimerProc *setTimerProc; Tcl_WaitForEventProc *waitForEventProc; Tcl_CreateFileHandlerProc *createFileHandlerProc; Tcl_DeleteFileHandlerProc *deleteFileHandlerProc; Tcl_InitNotifierProc *initNotifierProc; Tcl_FinalizeNotifierProc *finalizeNotifierProc; Tcl_AlertNotifierProc *alertNotifierProc; Tcl_ServiceModeHookProc *serviceModeHookProc; } Tcl_NotifierProcs; Following the call to Tcl_SetNotifier, the pointers given in the Tcl_NotifierProcs structure replace whatever notifier had been in‐ stalled in the process. It is extraordinarily unwise to replace a running notifier. Normally, Tcl_SetNotifier should be called at process initialization time before the first call to Tcl_InitNotifier. EXTERNAL EVENT LOOPS The notifier interfaces are designed so that Tcl can be embedded into applications that have their own private event loops. In this case, the application does not call Tcl_DoOneEvent except in the case of re‐ cursive event loops such as calls to the Tcl commands update or vwait. Most of the time is spent in the external event loop of the applica‐ tion. In this case the notifier must arrange for the external event loop to call back into Tcl when something happens on the various Tcl event sources. These callbacks should arrange for appropriate Tcl events to be placed on the Tcl event queue. Because the external event loop is not calling Tcl_DoOneEvent on a reg‐ ular basis, it is up to the notifier to arrange for Tcl_ServiceEvent to be called whenever events are pending on the Tcl event queue. The eas‐ iest way to do this is to invoke Tcl_ServiceAll at the end of each callback from the external event loop. This will ensure that all of the event sources are polled, any queued events are serviced, and any pending idle handlers are processed before returning control to the ap‐ plication. In addition, event sources that need to poll for events can call Tcl_SetMaxBlockTime to force the external event loop to call Tcl even if no events are available on the system event queue. As a side effect of processing events detected in the main external event loop, Tcl may invoke Tcl_DoOneEvent to start a recursive event loop in commands like vwait. Tcl_DoOneEvent will invoke the external event loop, which will result in callbacks as described in the preced‐ ing paragraph, which will result in calls to Tcl_ServiceAll. However, in these cases it is undesirable to service events in Tcl_ServiceAll. Servicing events there is unnecessary because control will immediately return to the external event loop and hence to Tcl_DoOneEvent, which can service the events itself. Furthermore, Tcl_DoOneEvent is supposed to service only a single event, whereas Tcl_ServiceAll normally ser‐ vices all pending events. To handle this situation, Tcl_DoOneEvent sets a flag for Tcl_ServiceAll that causes it to return without servic‐ ing any events. This flag is called the service mode; Tcl_DoOneEvent restores it to its previous value before it returns. In some cases, however, it may be necessary for Tcl_ServiceAll to ser‐ vice events even when it has been invoked from Tcl_DoOneEvent. This happens when there is yet another recursive event loop invoked via an event handler called by Tcl_DoOneEvent (such as one that is part of a native widget). In this case, Tcl_DoOneEvent may not have a chance to service events so Tcl_ServiceAll must service them all. Any recursive event loop that calls an external event loop rather than Tcl_DoOneEvent must reset the service mode so that all events get processed in Tcl_ServiceAll. This is done by invoking the Tcl_SetServiceMode proce‐ dure. If Tcl_SetServiceMode is passed TCL_SERVICE_NONE, then calls to Tcl_ServiceAll will return immediately without processing any events. If Tcl_SetServiceMode is passed TCL_SERVICE_ALL, then calls to Tcl_Ser‐ viceAll will behave normally. Tcl_SetServiceMode returns the previous value of the service mode, which should be restored when the recursive loop exits. Tcl_GetServiceMode returns the current value of the ser‐ vice mode. SEE ALSO Tcl_CreateFileHandler(3), Tcl_DeleteFileHandler(3), Tcl_Sleep(3), Tcl_DoOneEvent(3), Thread(3) KEYWORDS event, notifier, event queue, event sources, file events, timer, idle, service mode, threads Tcl 8.1 Notifier(3)
NRE(3) Процедуры библиотеки Tcl NRE(3) ______________________________________________________________________________ NAME Tcl_NRCreateCommand, Tcl_NRCallObjProc, Tcl_NREvalObj, Tcl_NREvalObjv, Tcl_NRCmdSwap, Tcl_NRExprObj, Tcl_NRAddCallback - Некурссивная (без использования стека) оценка Tcl-скриптов. SYNOPSIS #include <tcl.h> Tcl_Command Tcl_NRCreateCommand(interp, cmdName, proc, nreProc, clientData, deleteProc) int Tcl_NRCallObjProc(interp, nreProc, clientData, objc, objv) int Tcl_NREvalObj(interp, objPtr, flags) int Tcl_NREvalObjv(interp, objc, objv, flags) int Tcl_NRCmdSwap(interp, cmd, objc, objv, flags) int Tcl_NRExprObj(interp, objPtr, resultPtr) void Tcl_NRAddCallback(interp, postProcPtr, data0, data1, data2, data3) ARGUMENTS Tcl_Interp *interp (in) Соответствующий интерпретатор. const char *cmdName (in) Имя команды для создания. Tcl_ObjCmdProc *proc (in) Вызывается для оценки команды. Часто является небольшим обёрточным кодом, который использует Tcl_NRCallOb‐ jProc для вызова nreProc с помощью новой трамплины. Поведение такое же, как у аргумента proc в Tcl_CreateObjCommand(3) (см. документацию). Tcl_ObjCmdProc *nreProc (in) Вызывается вместо proc, когда трамплин уже используется. ClientData clientData (in) Произвольное значение одного слова, передаваемое proc, nreProc, deleteProc и objProc. Tcl_CmdDeleteProc *deleteProc (in/out) Вызывается перед удалением cmdName из интерпретатора, позволяя выполнить очистку, специфичную для команды. Может быть NULL. int objc (in) Количество элементов в objv. Tcl_Obj **objv (in) Слова в команде. Tcl_Obj *objPtr (in) Скрипт или выражение для оценки. int flags (in) Как описано для Tcl_EvalObjv. Tcl_Command cmd (in) Токен, который используется вместо токена, полученного из первого слова objv, для оценки команды. Tcl_Obj *resultPtr (out) Указатель на неподелённый объект Tcl_Obj, куда сохраняется результат оценки, если код возврата равен TCL_OK. Tcl_NRPostProc *postProcPtr (in) Функция для добавления в стек. ClientData data0 (in) ClientData data1 (in) ClientData data2 (in) ClientData data3 (in) data0 через data3 — это четыре значения по одному слову, которые будут переданы функции, обозначенной postProcPtr, при её вызове. ______________________________________________________________________________ DESCRIPTION Эти функции предоставляют интерфейс для стека функций, через который интерпретатор проходит для оценки команд. Подпрограмма, реализующая команду, состоит из начальной функции и любых дополнительных функций, которые подпрограмма добавляет в стек по ходу выполнения. Сам интерпретатор добавляет функции в стек для реакции на конец подпрограммы и для реализации других форм контроля, таких как переключение между выполняющимися стеками и оценка других скриптов на дополнительных уровнях без добавления кадров в стек C. Чтобы выполнить подпрограмму, вызывается начальная функция подпрограммы, а затем небольшой код, называемый трамплином, итеративно извлекает функции из стека и вызывает их, используя значение последнего вызова как значение подпрограммы. Tcl_NRCallObjProc вызывает nreProc с помощью новой трамплины. Tcl_NRCreateCommand — это альтернатива Tcl_CreateObjCommand, которая разрешает cmdName (который может содержать квалификаторы пространства имён) относительно текущего пространства имён, создаёт команду с этим именем и возвращает токен для команды, который может быть использован в последующих вызовах Tcl_GetCommandName. За исключением нескольких случаев, указанных ниже, любая существующая команда с таким же именем сначала удаляется. Если interp находится в процессе удаления, Tcl_NRCreateCommand не создаёт никакую команду, не удаляет никакую команду и возвращает NULL. Tcl_NREvalObj добавляет в стек функцию, которая похожа на Tcl_EvalObjEx, но не занимает места в стеке C. Tcl_NREvalObjv добавляет в стек функцию, которая похожа на Tcl_EvalObjv, но не занимает места в стеке C. Tcl_NRCmdSwap похож на Tcl_NREvalObjv, но использует cmd — токен, ранее возвращённый Tcl_CreateObjCommand или Tcl_GetCommandFromObj, вместо разрешения первого слова objv. Tcl_NRExprObj добавляет в стек функцию, которая оценивает objPtr как выражение так же, как Tcl_ExprObj, но без занятия места в стеке C. Все функции возвращают TCL_OK, если оценка скрипта, команды или выражения была успешно запланирована. В противном случае (например, если имя команды не может быть разрешено), они возвращают TCL_ERROR и сохраняют сообщение в результате интерпретатора. Tcl_NRAddCallback добавляет postProcPtr в стек. Подпись для Tcl_NRPostProc выглядит так: typedef int Tcl_NRPostProc( ClientData data[], Tcl_Interp *interp, int result); data — это указатель на массив, содержащий data0 через data3. result — значение, возвращённое предыдущей функцией, реализующей часть подпрограммы. EXAMPLE Следующая команда использует Tcl_EvalObjEx, которая занимает место в стеке C, для оценки скрипта: int TheCmdOldObjProc( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { int result; Tcl_Obj *objPtr; /* Подготовка */ result = Tcl_EvalObjEx(interp, objPtr, 0); /* Постобработка */ return result; } Tcl_CreateObjCommand(interp, "theCommand", TheCmdOldObjProc, clientData, TheCmdDeleteProc); Чтобы избежать занятия места в стеке C, TheCmdOldObjProc переименовывается в TheCmdNRObjProc, а шаг постобработки разделяется на отдельную функцию, TheCmdPostProc, которая добавляется в стек функций. Tcl_EvalObjEx заменяется на Tcl_NREvalObj, который использует трамплин вместо занятия места в стеке C. Новая версия TheCmdOldObjProc — это просто обёртка, которая использует Tcl_NRCallObjProc для вызова TheCmdNRObjProc: int TheCmdOldObjProc( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { return Tcl_NRCallObjProc(interp, TheCmdNRObjProc, clientData, objc, objv); } int TheCmdNRObjProc( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Tcl_Obj *objPtr; /* Подготовка */ Tcl_NRAddCallback(interp, TheCmdPostProc, data0, data1, data2, data3); /* data0 .. data3 — это до четырёх элементов по одному слову для * передачи в процедуру постобработки */ return Tcl_NREvalObj(interp, objPtr, 0); } int TheCmdNRPostProc( ClientData data[], Tcl_Interp *interp, int result) { /* data[0] .. data[3] — это четыре слова данных, * переданных Tcl_NRAddCallback */ /* Постобработка */ return result; } Любая функция, составляющая подпрограмму, может добавлять другие функции, что позволяет реализовать конструкции циклов и последовательностей с помощью стека функций. SEE ALSO Tcl_CreateCommand(3), Tcl_CreateObjCommand(3), Tcl_EvalObjEx(3), Tcl_GetCommandFromObj(3), Tcl_ExprObj(3) KEYWORDS stackless, nonrecursive, execute, command, global, value, result, script COPYRIGHT Copyright © 2008 Kevin B. Kenny. Copyright © 2018 Nathan Coulter. Tcl 8.6 NRE(3)
NRE(3) Tcl Library Procedures NRE(3) ______________________________________________________________________________ NAME Tcl_NRCreateCommand, Tcl_NRCallObjProc, Tcl_NREvalObj, Tcl_NREvalObjv, Tcl_NRCmdSwap, Tcl_NRExprObj, Tcl_NRAddCallback - Non-Recursive (stack‐ less) evaluation of Tcl scripts. SYNOPSIS #include <tcl.h> Tcl_Command Tcl_NRCreateCommand(interp, cmdName, proc, nreProc, clientData, deleteProc) int Tcl_NRCallObjProc(interp, nreProc, clientData, objc, objv) int Tcl_NREvalObj(interp, objPtr, flags) int Tcl_NREvalObjv(interp, objc, objv, flags) int Tcl_NRCmdSwap(interp, cmd, objc, objv, flags) int Tcl_NRExprObj(interp, objPtr, resultPtr) void Tcl_NRAddCallback(interp, postProcPtr, data0, data1, data2, data3) ARGUMENTS Tcl_Interp *interp (in) The relevant Interpreter. const char *cmdName (in) Name of the command to create. Tcl_ObjCmdProc *proc (in) Called in order to evaluate a command. Is often just a small wrapper that uses Tcl_NRCallOb‐ jProc to call nreProc using a new trampoline. Behaves in the same way as the proc argument to Tcl_CreateObjCommand(3) (q.v.). Tcl_ObjCmdProc *nreProc (in) Called instead of proc when a trampoline is already in use. ClientData clientData (in) Arbitrary one-word value passed to proc, nreProc, deleteProc and objProc. Tcl_CmdDeleteProc *deleteProc (in/out) Called before cmdName is deleted from the interpreter, allowing for command-specific cleanup. May be NULL. int objc (in) Number of items in objv. Tcl_Obj **objv (in) Words in the command. Tcl_Obj *objPtr (in) A script or expression to eval‐ uate. int flags (in) As described for Tcl_EvalObjv. Tcl_Command cmd (in) Token to use instead of one de‐ rived from the first word of objv in order to evaluate a command. Tcl_Obj *resultPtr (out) Pointer to an unshared Tcl_Obj where the result of the evalua‐ tion is stored if the return code is TCL_OK. Tcl_NRPostProc *postProcPtr (in) A function to push. ClientData data0 (in) ClientData data1 (in) ClientData data2 (in) ClientData data3 (in) data0 through data3 are four one-word values that will be passed to the function desig‐ nated by postProcPtr when it is invoked. ______________________________________________________________________________ DESCRIPTION These functions provide an interface to the function stack that an in‐ terpreter iterates through to evaluate commands. The routine behind a command is implemented by an initial function and any additional func‐ tions that the routine pushes onto the stack as it progresses. The in‐ terpreter itself pushes functions onto the stack to react to the end of a routine and to exercise other forms of control such as switching be‐ tween in-progress stacks and the evaluation of other scripts at addi‐ tional levels without adding frames to the C stack. To execute a rou‐ tine, the initial function for the routine is called and then a small bit of code called a trampoline iteratively takes functions off the stack and calls them, using the value of the last call as the value of the routine. Tcl_NRCallObjProc calls nreProc using a new trampoline. Tcl_NRCreateCommand, an alternative to Tcl_CreateObjCommand, resolves cmdName, which may contain namespace qualifiers, relative to the cur‐ rent namespace, creates a command by that name, and returns a token for the command which may be used in subsequent calls to Tcl_GetCommand‐ Name. Except for a few cases noted below any existing command by the same name is first deleted. If interp is in the process of being deleted Tcl_NRCreateCommand does not create any command, does not delete any command, and returns NULL. Tcl_NREvalObj pushes a function that is like Tcl_EvalObjEx but consumes no space on the C stack. Tcl_NREvalObjv pushes a function that is like Tcl_EvalObjv but consumes no space on the C stack. Tcl_NRCmdSwap is like Tcl_NREvalObjv, but uses cmd, a token previously returned by Tcl_CreateObjCommand or Tcl_GetCommandFromObj, instead of resolving the first word of objv. Tcl_NRExprObj pushes a function that evaluates objPtr as an expression in the same manner as Tcl_ExprObj but without consuming space on the C stack. All of the functions return TCL_OK if the evaluation of the script, command, or expression has been scheduled successfully. Otherwise (for example if the command name cannot be resolved), they return TCL_ERROR and store a message as the interpreter's result. Tcl_NRAddCallback pushes postProcPtr. The signature for Tcl_NRPostProc is: typedef int Tcl_NRPostProc( ClientData data[], Tcl_Interp *interp, int result); data is a pointer to an array containing data0 through data3. result is the value returned by the previous function implementing part the routine. EXAMPLE The following command uses Tcl_EvalObjEx, which consumes space on the C stack, to evalute a script: int TheCmdOldObjProc( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { int result; Tcl_Obj *objPtr; ... preparation ... result = Tcl_EvalObjEx(interp, objPtr, 0); ... postprocessing ... return result; } Tcl_CreateObjCommand(interp, "theCommand", TheCmdOldObjProc, clientData, TheCmdDeleteProc); To avoid consuming space on the C stack, TheCmdOldObjProc is renamed to TheCmdNRObjProc and the postprocessing step is split into a separate function, TheCmdPostProc, which is pushed onto the function stack. Tcl_EvalObjEx is replaced with Tcl_NREvalObj, which uses a trampoline instead of consuming space on the C stack. A new version of TheCm‐ dOldObjProc is just a a wrapper that uses Tcl_NRCallObjProc to call TheCmdNRObjProc: int TheCmdOldObjProc( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { return Tcl_NRCallObjProc(interp, TheCmdNRObjProc, clientData, objc, objv); } int TheCmdNRObjProc ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Tcl_Obj *objPtr; ... preparation ... Tcl_NRAddCallback(interp, TheCmdPostProc, data0, data1, data2, data3); /* data0 .. data3 are up to four one-word items to * pass to the postprocessing procedure */ return Tcl_NREvalObj(interp, objPtr, 0); } int TheCmdNRPostProc( ClientData data[], Tcl_Interp *interp, int result) { /* data[0] .. data[3] are the four words of data * passed to Tcl_NRAddCallback */ ... postprocessing ... return result; } Any function comprising a routine can push other functions, making it possible implement looping and sequencing constructs using the function stack. SEE ALSO Tcl_CreateCommand(3), Tcl_CreateObjCommand(3), Tcl_EvalObjEx(3), Tcl_GetCommandFromObj(3), Tcl_ExprObj(3) KEYWORDS stackless, nonrecursive, execute, command, global, value, result, script COPYRIGHT Copyright © 2008 Kevin B. Kenny. Copyright © 2018 Nathan Coulter. Tcl 8.6 NRE(3)
Tcl_CreateObjCommand(3) Процедуры библиотеки Tcl Tcl_CreateObjCommand(3) ______________________________________________________________________________ NAME Tcl_CreateObjCommand, Tcl_DeleteCommand, Tcl_DeleteCommandFromToken, Tcl_GetCommandInfo, Tcl_GetCommandInfoFromToken, Tcl_SetCommandInfo, Tcl_SetCommandInfoFromToken, Tcl_GetCommandName, Tcl_GetCommandFull‐ Name, Tcl_GetCommandFromObj - реализовать новые команды на C SYNOPSIS #include <tcl.h> Tcl_Command Tcl_CreateObjCommand(interp, cmdName, proc, clientData, deleteProc) int Tcl_DeleteCommand(interp, cmdName) int Tcl_DeleteCommandFromToken(interp, token) int Tcl_GetCommandInfo(interp, cmdName, infoPtr) int Tcl_SetCommandInfo(interp, cmdName, infoPtr) int Tcl_GetCommandInfoFromToken(token, infoPtr) int Tcl_SetCommandInfoFromToken(token, infoPtr) const char * Tcl_GetCommandName(interp, token) void Tcl_GetCommandFullName(interp, token, objPtr) Tcl_Command Tcl_GetCommandFromObj(interp, objPtr) ARGUMENTS Tcl_Interp *interp (in) Интерпретатор, в котором создать новую команду или который содержит команду. const char *cmdName (in) Имя команды. Tcl_ObjCmdProc *proc (in) Реализация новой команды: proc будет вызвана всякий раз, когда cmdName вызывается как команда. ClientData clientData (in) Произвольное значение одного слова для передачи в proc и deleteProc. Tcl_CmdDeleteProc *deleteProc (in) Процедура, которая будет вызвана перед удалением cmdName из интерпретатора; позволяет выполнить очистку, специфичную для команды. Если NULL, то процедура не вызывается перед удалением команды. Tcl_Command token (in) Токен для команды, возвращаемый предыдущим вызовом Tcl_CreateObjCommand. Команда не должна быть удалена. Tcl_CmdInfo *infoPtr (in/out) Указатель на структуру, содержащую различную информацию о Tcl-команде. Tcl_Obj *objPtr (in) Значение, содержащее имя Tcl-команды. ______________________________________________________________________________ DESCRIPTION Tcl_CreateObjCommand определяет новую команду в interp и ассоциирует ее с процедурой proc, так что всякий раз, когда имя вызывается как Tcl-команда (например, через вызов Tcl_EvalObjEx), интерпретатор Tcl вызовет proc для обработки команды. Tcl_CreateObjCommand удаляет любое существующее имя команды, уже ассоциированное с интерпретатором (однако см. ниже исключение, где существующая команда не удаляется). Она возвращает токен, который может использоваться для ссылки на команду в последующих вызовах Tcl_GetCommandName. Если имя содержит какие-либо квалификаторы пространства имен ::, то команда добавляется в указанное пространство имен; в противном случае команда добавляется в глобальное пространство имен. Если Tcl_CreateObjCommand вызывается для интерпретатора, который в процессе удаления, то она не создает новую команду и возвращает NULL. Процедура proc должна иметь аргументы и результат, соответствующие типу Tcl_ObjCmdProc: typedef int Tcl_ObjCmdProc( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); При вызове proc параметры clientData и interp будут копиями аргументов clientData и interp, переданных Tcl_CreateObjCommand. Обычно clientData указывает на структуру данных, специфичную для приложения, которая описывает, что делать при вызове процедуры команды. Objc и objv описывают аргументы команды, objc задает количество значений аргументов (включая имя команды), а objv задает значения аргументов. Массив objv будет содержать objc значений, указывающих на значения аргументов. В отличие от argv[argv], используемого в процедуре команды на основе строк, objv[objc] не будет содержать NULL. Кроме того, при вызове proc она не должна изменять содержимое массива objv путем присвоения новых значений указателям элементам массива (например, objv[2] = NULL), поскольку это приведет к потере памяти и повреждению стека выполнения. Ключевое слово const в объявлении objv заставит компиляторы, соответствующие ANSI, сообщать о любой такой попытке присвоения как об ошибке. Однако допустимо изменить внутреннее представление любого индивидуального аргумента значения. Например, пользователь может вызвать Tcl_GetIntFromObj для objv[2], чтобы получить целочисленное представление этого значения; этот вызов может изменить тип значения, на которое указывает objv[2], но не изменит, на что указывает objv[2]. proc должна возвращать целочисленный код, который является либо TCL_OK, TCL_ERROR, TCL_RETURN, TCL_BREAK или TCL_CONTINUE. См. обзорную страницу Tcl для деталей о том, что означают эти коды. Большинство нормальных команд будут возвращать только TCL_OK или TCL_ERROR. Кроме того, если proc нужно вернуть непустой результат, она может вызвать Tcl_SetObjResult для установки результата интерпретатора. В случае кода возврата TCL_OK это дает результат команды, а в случае TCL_ERROR это дает сообщение об ошибке. Перед вызовом процедуры команды Tcl_EvalObjEx устанавливает результат интерпретатора на указатель на значение, представляющее пустую строку, так что простые команды могут вернуть пустой результат, ничего не делая. Содержимое массива objv принадлежит Tcl и не гарантируется, что оно сохранится после возврата proc: proc не должна изменять их. Вызовите Tcl_SetObjResult, если вы хотите вернуть что-то из массива objv. Обыкновенно Tcl_CreateObjCommand удаляет любое существующее имя команды, уже ассоциированное с интерпретатором. Однако, если существующая команда была создана предыдущим вызовом Tcl_CreateCommand, Tcl_CreateOb‐ jCommand не удаляет команду, а вместо этого организует для интерпретатора Tcl вызвать Tcl_ObjCmdProc proc в будущем. Старая процедура команды на основе строк Tcl_CmdProc, ассоциированная с командой, сохраняется, и ее адрес можно получить последующими вызовами Tcl_GetCommandInfo. Это делается для обратной совместимости. DeleteProc будет вызвана, когда (если) имя будет удалено. Это может произойти через вызов Tcl_DeleteCommand, Tcl_DeleteCommandFromToken или Tcl_DeleteInterp, или путем замены имени в другом вызове Tcl_CreateOb‐ jCommand. DeleteProc вызывается перед удалением команды и дает приложению возможность освободить любые структуры, ассоциированные с командой. DeleteProc должна иметь аргументы и результат, соответствующие типу Tcl_CmdDeleteProc: typedef void Tcl_CmdDeleteProc( ClientData clientData); Аргумент clientData будет таким же, как аргумент clientData, переданный Tcl_CreateObjCommand. Tcl_DeleteCommand удаляет команду из интерпретатора команд. После завершения вызова попытки вызвать cmdName в interp приведут к ошибкам. Если cmdName не связано как команда в interp, то Tcl_DeleteCommand не делает ничего и возвращает -1; в противном случае возвращает 0. Нет ограничений на cmdName: она может ссылаться на встроенную команду, команду, специфичную для приложения, или процедуру Tcl. Если имя содержит какие-либо квалификаторы пространства имен ::, команда удаляется из указанного пространства имен. Для токена, возвращенного Tcl_CreateObjCommand, Tcl_DeleteCommandFrom‐ Token удаляет команду из интерпретатора команд. Она удалит команду даже если та была переименована. После завершения вызова попытки вызвать команду в interp приведут к ошибкам. Если команда, соответствующая token, уже была удалена из interp, то Tcl_DeleteCommand ничего не делает и возвращает -1; в противном случае возвращает 0. Tcl_GetCommandInfo проверяет, существует ли аргумент cmdName как команда в interp. cmdName может включать квалификаторы пространства имен :: для идентификации команды в определенном пространстве имен. Если команда не найдена, то возвращается 0. В противном случае размещает информацию о команде в структуре Tcl_CmdInfo, на которую указывает infoPtr, и возвращает 1. Структура Tcl_CmdInfo имеет следующие поля: typedef struct Tcl_CmdInfo { int isNativeObjectProc; Tcl_ObjCmdProc *objProc; ClientData objClientData; Tcl_CmdProc *proc; ClientData clientData; Tcl_CmdDeleteProc *deleteProc; ClientData deleteData; Tcl_Namespace *namespacePtr; } Tcl_CmdInfo; Поле isNativeObjectProc имеет значение 1, если Tcl_CreateObjCommand была вызвана для регистрации команды; оно равно 0, если вызывалась только Tcl_CreateCommand. Это позволяет программе определить, быстрее вызвать objProc или proc: objProc обычно быстрее, если isNativeObjectProc имеет значение 1. Поля objProc и objClientData имеют то же значение, что и аргументы proc и clientData для Tcl_CreateObjCommand; они содержат информацию о процедуре команды на основе значений, которую интерпретатор Tcl вызывает для реализации команды. Поля proc и clientData содержат информацию о процедуре команды на основе строк, которая реализует команду. Если Tcl_CreateCommand была вызвана для этой команды, это процедура, переданная ей; в противном случае это процедура совместимости, зарегистрированная Tcl_CreateObjCommand, которая просто вызывает процедуру команды на основе значений после преобразования ее строковых аргументов в значения Tcl. Поле deleteData - это значение ClientData для передачи deleteProc; обычно оно такое же, как clientData, но может быть установлено независимо с помощью процедуры Tcl_SetCommandInfo. Поле namespacePtr содержит указатель на Tcl_Namespace, который содержит команду. Tcl_GetCommandInfoFromToken идентична Tcl_GetCommandInfo, за исключением того, что она использует токен команды, возвращаемый из Tcl_CreateObjCommand, вместо имени команды. Если параметр token равен NULL, возвращается 0; в противном случае возвращается 1 и заполняется структура, обозначенная infoPtr. Tcl_SetCommandInfo используется для изменения процедур и значений ClientData, ассоциированных с командой. Ее аргумент cmdName - имя команды в interp. cmdName может включать квалификаторы пространства имен :: для идентификации команды в определенном пространстве имен. Если эта команда не существует, Tcl_SetCommandInfo возвращает 0. В противном случае копирует информацию из *infoPtr во внутреннюю структуру Tcl для команды и возвращает 1. Tcl_SetCommandInfoFromToken идентична Tcl_SetCommandInfo, за исключением того, что она принимает токен команды, возвращаемый Tcl_CreateObjCommand, вместо имени команды. Если параметр token равен NULL, возвращается 0. В противном случае копирует информацию из *infoPtr во внутреннюю структуру Tcl для команды и возвращает 1. Обратите внимание, что как Tcl_SetCommandInfo, так и Tcl_SetCommandInfoFromToken позволяют задать значение ClientData для процедуры удаления команды, отличное от ClientData для ее процедуры команды. Обратите внимание, что ни Tcl_SetCommandInfo, ни Tcl_SetCommandInfoFromToken не изменят пространство имен команды. Используйте Tcl_Eval для вызова команды rename, чтобы сделать это. Tcl_GetCommandName предоставляет механизм для отслеживания команд, которые были переименованы. Для токена, возвращенного Tcl_CreateObjCommand при создании команды, Tcl_GetCommandName возвращает строковое имя команды. Если команда была переименована с момента создания, то Tcl_GetCommandName возвращает текущее имя. Это имя не включает какие-либо квалификаторы пространства имен ::. Команда, соответствующая token, не должна быть удалена. Строка, возвращенная Tcl_GetCommandName, находится в динамической памяти, принадлежащей Tcl, и гарантируется, что она сохранит свое значение только до тех пор, пока команда не будет удалена или переименована; вызывающие должны скопировать строку, если им нужно сохранить ее надолго. Tcl_GetCommandFullName производит полностью квалифицированное имя команды из токена команды. Имя, включая все префиксы пространства имен, добавляется к значению, указанному objPtr. Tcl_GetCommandFromObj возвращает токен для команды, указанной именем в Tcl_Obj. Имя команды разрешается относительно текущего пространства имен. Возвращает NULL, если команда не найдена. SEE ALSO Tcl_CreateCommand(3), Tcl_ResetResult(3), Tcl_SetObjResult(3) KEYWORDS bind, command, create, delete, namespace, value Tcl 8.0 Tcl_CreateObjCommand(3)
Tcl_CreateObjCommand(3) Tcl Library Procedures Tcl_CreateObjCommand(3) ______________________________________________________________________________ NAME Tcl_CreateObjCommand, Tcl_DeleteCommand, Tcl_DeleteCommandFromToken, Tcl_GetCommandInfo, Tcl_GetCommandInfoFromToken, Tcl_SetCommandInfo, Tcl_SetCommandInfoFromToken, Tcl_GetCommandName, Tcl_GetCommandFull‐ Name, Tcl_GetCommandFromObj - implement new commands in C SYNOPSIS #include <tcl.h> Tcl_Command Tcl_CreateObjCommand(interp, cmdName, proc, clientData, deleteProc) int Tcl_DeleteCommand(interp, cmdName) int Tcl_DeleteCommandFromToken(interp, token) int Tcl_GetCommandInfo(interp, cmdName, infoPtr) int Tcl_SetCommandInfo(interp, cmdName, infoPtr) int Tcl_GetCommandInfoFromToken(token, infoPtr) int Tcl_SetCommandInfoFromToken(token, infoPtr) const char * Tcl_GetCommandName(interp, token) void Tcl_GetCommandFullName(interp, token, objPtr) Tcl_Command Tcl_GetCommandFromObj(interp, objPtr) ARGUMENTS Tcl_Interp *interp (in) Interpreter in which to create a new command or that contains a command. const char *cmdName (in) Name of command. Tcl_ObjCmdProc *proc (in) Implementation of the new command: proc will be called whenever cmdName is invoked as a command. ClientData clientData (in) Arbitrary one-word value to pass to proc and deleteProc. Tcl_CmdDeleteProc *deleteProc (in) Procedure to call before cmdName is deleted from the interpreter; allows for command-specific cleanup. If NULL, then no procedure is called before the com‐ mand is deleted. Tcl_Command token (in) Token for command, returned by previous call to Tcl_CreateObjCommand. The command must not have been deleted. Tcl_CmdInfo *infoPtr (in/out) Pointer to structure con‐ taining various information about a Tcl command. Tcl_Obj *objPtr (in) Value containing the name of a Tcl command. ______________________________________________________________________________ DESCRIPTION Tcl_CreateObjCommand defines a new command in interp and associates it with procedure proc such that whenever name is invoked as a Tcl command (e.g., via a call to Tcl_EvalObjEx) the Tcl interpreter will call proc to process the command. Tcl_CreateObjCommand deletes any existing command name already associ‐ ated with the interpreter (however see below for an exception where the existing command is not deleted). It returns a token that may be used to refer to the command in subsequent calls to Tcl_GetCommandName. If name contains any :: namespace qualifiers, then the command is added to the specified namespace; otherwise the command is added to the global namespace. If Tcl_CreateObjCommand is called for an interpreter that is in the process of being deleted, then it does not create a new com‐ mand and it returns NULL. proc should have arguments and result that match the type Tcl_ObjCmdProc: typedef int Tcl_ObjCmdProc( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); When proc is invoked, the clientData and interp parameters will be copies of the clientData and interp arguments given to Tcl_CreateObj‐ Command. Typically, clientData points to an application-specific data structure that describes what to do when the command procedure is in‐ voked. Objc and objv describe the arguments to the command, objc giving the number of argument values (including the command name) and objv giving the values of the arguments. The objv array will contain objc values, pointing to the argument values. Unlike argv[argv] used in a string-based command procedure, objv[objc] will not contain NULL. Additionally, when proc is invoked, it must not modify the contents of the objv array by assigning new pointer values to any element of the array (for example, objv[2] = NULL) because this will cause memory to be lost and the runtime stack to be corrupted. The const in the decla‐ ration of objv will cause ANSI-compliant compilers to report any such attempted assignment as an error. However, it is acceptable to modify the internal representation of any individual value argument. For in‐ stance, the user may call Tcl_GetIntFromObj on objv[2] to obtain the integer representation of that value; that call may change the type of the value that objv[2] points at, but will not change where objv[2] points. proc must return an integer code that is either TCL_OK, TCL_ERROR, TCL_RETURN, TCL_BREAK, or TCL_CONTINUE. See the Tcl overview man page for details on what these codes mean. Most normal commands will only return TCL_OK or TCL_ERROR. In addition, if proc needs to return a non-empty result, it can call Tcl_SetObjResult to set the interpreter's result. In the case of a TCL_OK return code this gives the result of the command, and in the case of TCL_ERROR this gives an error message. Before invoking a command procedure, Tcl_EvalObjEx sets interpreter's result to point to a value representing an empty string, so simple com‐ mands can return an empty result by doing nothing at all. The contents of the objv array belong to Tcl and are not guaranteed to persist once proc returns: proc should not modify them. Call Tcl_SetO‐ bjResult if you want to return something from the objv array. Ordinarily, Tcl_CreateObjCommand deletes any existing command name al‐ ready associated with the interpreter. However, if the existing com‐ mand was created by a previous call to Tcl_CreateCommand, Tcl_CreateOb‐ jCommand does not delete the command but instead arranges for the Tcl interpreter to call the Tcl_ObjCmdProc proc in the future. The old string-based Tcl_CmdProc associated with the command is retained and its address can be obtained by subsequent Tcl_GetCommandInfo calls. This is done for backwards compatibility. DeleteProc will be invoked when (if) name is deleted. This can occur through a call to Tcl_DeleteCommand, Tcl_DeleteCommandFromToken, or Tcl_DeleteInterp, or by replacing name in another call to Tcl_CreateOb‐ jCommand. DeleteProc is invoked before the command is deleted, and gives the application an opportunity to release any structures associ‐ ated with the command. DeleteProc should have arguments and result that match the type Tcl_CmdDeleteProc: typedef void Tcl_CmdDeleteProc( ClientData clientData); The clientData argument will be the same as the clientData argument passed to Tcl_CreateObjCommand. Tcl_DeleteCommand deletes a command from a command interpreter. Once the call completes, attempts to invoke cmdName in interp will result in errors. If cmdName is not bound as a command in interp then Tcl_DeleteCommand does nothing and returns -1; otherwise it returns 0. There are no restrictions on cmdName: it may refer to a built-in com‐ mand, an application-specific command, or a Tcl procedure. If name contains any :: namespace qualifiers, the command is deleted from the specified namespace. Given a token returned by Tcl_CreateObjCommand, Tcl_DeleteCommandFrom‐ Token deletes the command from a command interpreter. It will delete a command even if that command has been renamed. Once the call com‐ pletes, attempts to invoke the command in interp will result in errors. If the command corresponding to token has already been deleted from in‐ terp then Tcl_DeleteCommand does nothing and returns -1; otherwise it returns 0. Tcl_GetCommandInfo checks to see whether its cmdName argument exists as a command in interp. cmdName may include :: namespace qualifiers to identify a command in a particular namespace. If the command is not found, then it returns 0. Otherwise it places information about the command in the Tcl_CmdInfo structure pointed to by infoPtr and returns 1. A Tcl_CmdInfo structure has the following fields: typedef struct Tcl_CmdInfo { int isNativeObjectProc; Tcl_ObjCmdProc *objProc; ClientData objClientData; Tcl_CmdProc *proc; ClientData clientData; Tcl_CmdDeleteProc *deleteProc; ClientData deleteData; Tcl_Namespace *namespacePtr; } Tcl_CmdInfo; The isNativeObjectProc field has the value 1 if Tcl_CreateObjCommand was called to register the command; it is 0 if only Tcl_CreateCommand was called. It allows a program to determine whether it is faster to call objProc or proc: objProc is normally faster if isNativeObjectProc has the value 1. The fields objProc and objClientData have the same meaning as the proc and clientData arguments to Tcl_CreateObjCommand; they hold information about the value-based command procedure that the Tcl interpreter calls to implement the command. The fields proc and clientData hold information about the string-based command procedure that implements the command. If Tcl_CreateCommand was called for this command, this is the procedure passed to it; otherwise, this is a com‐ patibility procedure registered by Tcl_CreateObjCommand that simply calls the command's value-based procedure after converting its string arguments to Tcl values. The field deleteData is the ClientData value to pass to deleteProc; it is normally the same as clientData but may be set independently using the Tcl_SetCommandInfo procedure. The field namespacePtr holds a pointer to the Tcl_Namespace that contains the command. Tcl_GetCommandInfoFromToken is identical to Tcl_GetCommandInfo except that it uses a command token returned from Tcl_CreateObjCommand in place of the command name. If the token parameter is NULL, it returns 0; otherwise, it returns 1 and fills in the structure designated by in‐ foPtr. Tcl_SetCommandInfo is used to modify the procedures and ClientData val‐ ues associated with a command. Its cmdName argument is the name of a command in interp. cmdName may include :: namespace qualifiers to identify a command in a particular namespace. If this command does not exist then Tcl_SetCommandInfo returns 0. Otherwise, it copies the in‐ formation from *infoPtr to Tcl's internal structure for the command and returns 1. Tcl_SetCommandInfoFromToken is identical to Tcl_SetCommandInfo except that it takes a command token as returned by Tcl_CreateObjCommand in‐ stead of the command name. If the token parameter is NULL, it returns 0. Otherwise, it copies the information from *infoPtr to Tcl's inter‐ nal structure for the command and returns 1. Note that Tcl_SetCommandInfo and Tcl_SetCommandInfoFromToken both allow the ClientData for a command's deletion procedure to be given a differ‐ ent value than the ClientData for its command procedure. Note that neither Tcl_SetCommandInfo nor Tcl_SetCommandInfoFromToken will change a command's namespace. Use Tcl_Eval to call the rename command to do that. Tcl_GetCommandName provides a mechanism for tracking commands that have been renamed. Given a token returned by Tcl_CreateObjCommand when the command was created, Tcl_GetCommandName returns the string name of the command. If the command has been renamed since it was created, then Tcl_GetCommandName returns the current name. This name does not in‐ clude any :: namespace qualifiers. The command corresponding to token must not have been deleted. The string returned by Tcl_GetCommandName is in dynamic memory owned by Tcl and is only guaranteed to retain its value as long as the command is not deleted or renamed; callers should copy the string if they need to keep it for a long time. Tcl_GetCommandFullName produces the fully qualified name of a command from a command token. The name, including all namespace prefixes, is appended to the value specified by objPtr. Tcl_GetCommandFromObj returns a token for the command specified by the name in a Tcl_Obj. The command name is resolved relative to the cur‐ rent namespace. Returns NULL if the command is not found. SEE ALSO Tcl_CreateCommand(3), Tcl_ResetResult(3), Tcl_SetObjResult(3) KEYWORDS bind, command, create, delete, namespace, value Tcl 8.0 Tcl_CreateObjCommand(3)
Tcl_Ensemble(3) Процедуры Tcl библиотеки Tcl_Ensemble(3) ______________________________________________________________________________ НАЗВАНИЕ Tcl_CreateEnsemble, Tcl_FindEnsemble, Tcl_GetEnsembleFlags, Tcl_GetEnsembleMappingDict, Tcl_GetEnsembleNamespace, Tcl_GetEnsem‐ bleParameterList, Tcl_GetEnsembleUnknownHandler, Tcl_GetEnsembleSubcom‐ mandList, Tcl_IsEnsemble, Tcl_SetEnsembleFlags, Tcl_SetEnsembleMapping‐ Dict, Tcl_SetEnsembleParameterList, Tcl_SetEnsembleSubcommandList, Tcl_SetEnsembleUnknownHandler - манипулировать командами ансамблей СИНОПСИС #include <tcl.h> Tcl_Command Tcl_CreateEnsemble(interp, name, namespacePtr, ensFlags) Tcl_Command Tcl_FindEnsemble(interp, cmdNameObj, flags) int Tcl_IsEnsemble(token) int Tcl_GetEnsembleFlags(interp, token, ensFlagsPtr) int Tcl_SetEnsembleFlags(interp, token, ensFlags) int Tcl_GetEnsembleMappingDict(interp, token, dictObjPtr) int Tcl_SetEnsembleMappingDict(interp, token, dictObj) int │ Tcl_GetEnsembleParameterList(interp, token, listObjPtr) │ int │ Tcl_SetEnsembleParameterList(interp, token, listObj) │ int Tcl_GetEnsembleSubcommandList(interp, token, listObjPtr) int Tcl_SetEnsembleSubcommandList(interp, token, listObj) int Tcl_GetEnsembleUnknownHandler(interp, token, listObjPtr) int Tcl_SetEnsembleUnknownHandler(interp, token, listObj) int Tcl_GetEnsembleNamespace(interp, token, namespacePtrPtr) АРГУМЕНТЫ Tcl_Interp *interp (in/out) Интерпретатор, в котором ансамбль будет создан или найден. Также место, где записываются сообщения об ошибках. Функции, чьи имена начинаются с Tcl_GetEnsemble, могут иметь значение NULL для interp, но все остальные функции не должны. const char *name (in) Имя команды ансамбля, которая будет создана. Tcl_Namespace *namespacePtr (in) Пространство имён, к которому будет привязана команда ансамбля, или NULL для текущего пространства имён. int ensFlags (in) Набор флагов, объединённых с помощью OR, описывающих базовую конфигурацию ансамбля. В настоящее время только один бит имеет значение, TCL_ENSEMBLE_PREFIX, который присутствует, если команда ансамбля должна также совпадать с недвусмысленными префиксами подкоманд. Tcl_Obj *cmdNameObj (in) Значение, содержащее имя команды ансамбля для поиска. int flags (in) Набор флагов, объединённых с помощью OR, управляющих поведением Tcl_FindEnsemble. В настоящее время поддерживается только TCL_LEAVE_ERR_MSG. Tcl_Command token (in) Обычный токен команды, который относится к команде ансамбля, или который вы хотите использовать для проверки как команды ансамбля в Tcl_IsEnsemble. int *ensFlagsPtr (out) Указатель на переменную, в которую будет записан текущий набор флагов ансамбля; в настоящее время определён только бит TCL_ENSEMBLE_PREFIX. Tcl_Obj *dictObj (in) Значение словаря для использования в качестве словаря сопоставления подкоманд с префиксами команд реализации в ансамбле. Может быть NULL, если словарь сопоставления нужно удалить. Tcl_Obj **dictObjPtr (out) Указатель на переменную, в которую будет записан текущий словарь сопоставления ансамбля. Tcl_Obj *listObj (in) Значение списка для использования в качестве списка формальных параметров перед подкомандой, списка определённых подкоманд в словаре или префикса команды обработчика неизвестной подкоманды. Может быть NULL, если список подкоманд или обработчик неизвестных подкоманд нужно удалить. Tcl_Obj **listObjPtr (out) Указатель на переменную, в которую будет записан текущий список формальных параметров перед подкомандой, список определённых подкоманд или текущий префикс обработчика неизвестных подкоманд. Tcl_Namespace **namespacePtrPtr (out) Указатель на переменную, в которую будет записан дескриптор пространства имён, к которому привязан ансамбль. ______________________________________________________________________________ ОПИСАНИЕ Ансамбль - это команда, привязанная к какому-то пространству имён, которая состоит из коллекции подкоманд, реализуемых другими командами Tcl. Первый аргумент команды ансамбля всегда интерпретируется как селектор, указывающий, какую подкоманду выполнить. Ансамбли создаются с помощью Tcl_CreateEnsemble, которая принимает четыре аргумента: интерпретатор, в котором нужно работать, имя ансамбля для создания, пространство имён в интерпретаторе, к которому привязывается ансамбль, и набор флагов ансамбля по умолчанию. Результат функции - токен команды ансамбля, который можно использовать для дальнейшей настройки ансамбля с помощью API, описанного ниже в разделе СВОЙСТВА АНСАМБЛЯ. По имени команды ансамбля токен этой команды можно получить с помощью Tcl_FindEnsemble. Если указанное имя команды (в cmdNameObj) не относится к команде ансамбля, результат функции - NULL, и (если бит TCL_LEAVE_ERR_MSG установлен в flags) в результате интерпретатора оставляется сообщение об ошибке. Токен команды можно проверить на то, относится ли он к ансамблю, с помощью Tcl_IsEnsemble. Это возвращает 1, если токен относится к ансамблю, или 0 в противном случае. СВОЙСТВА АНСАМБЛЯ Каждый ансамбль имеет четыре свойства для чтения и записи, а также одно свойство только для чтения. Свойства такие: flags (чтение и запись) Набор флагов для ансамбля, выраженный как битовая маска. В настоящее время единственный публичный флаг - TCL_ENSEMBLE_PREFIX, который устанавливается, когда разрешены недвусмысленные префиксы подкоманд для разрешения на реализации, а также точные совпадения. Флаги можно читать и записывать с помощью Tcl_GetEnsembleFlags и Tcl_SetEnsembleFlags соответственно. Результат обеих функций - код результата Tcl (TCL_OK или TCL_ERROR, если токен не относится к ансамблю). словарь сопоставления (чтение и запись) Словарь, содержащий сопоставление имён подкоманд со списками слов для использования в качестве префикса команды (заменяя первые два слова команды, которые являются самой командой ансамбля и именем подкоманды), или NULL, если каждая подкоманда должна быть сопоставлена с командой с тем же неполным именем в пространстве имён ансамбля. По умолчанию - NULL. Можно читать и записывать с помощью Tcl_GetEnsembleMappingDict и Tcl_SetEnsembleMappingDict соответственно. Результат обеих функций - код результата Tcl (TCL_OK или TCL_ERROR, если токен не относится к ансамблю), и словарь, полученный из Tcl_GetEnsembleMappingDict, всегда следует считать неизменяемым, даже если он не является общим. Все имена команд в префиксах, установленных через Tcl_SetEnsembleMappingDict, должны быть полностью квалифицированными. список формальных параметров перед подкомандой (чтение и запись) Список имён формальных параметров (имена используются только │ при генерации сообщений об ошибках), которые передаются при │ вызове ансамбля между именем ансамбля и аргументом │ подкоманды. NULL (по умолчанию) эквивалентно пустому списку. │ Можно читать и записывать с помощью │ Tcl_GetEnsembleParameterList и │ Tcl_SetEnsembleParameterList соответственно. Результат обеих │ функций - код результата Tcl (TCL_OK или TCL_ERROR, если │ токен не относится к ансамблю), и список, полученный из │ Tcl_GetEnsembleParameterList, всегда следует считать │ неизменяемым, даже если он не является общим. список подкоманд (чтение и запись) Список всех имён подкоманд для ансамбля, или NULL, если это должно быть получено из ключей словаря сопоставления (см. выше) или (если это также NULL) из набора команд, экспортируемых привязанным пространством имён. Можно читать и записывать с помощью Tcl_GetEnsembleSubcommandList и Tcl_SetEnsembleSubcommandList соответственно. Результат обеих функций - код результата Tcl (TCL_OK или TCL_ERROR, если токен не относится к ансамблю), и список, полученный из Tcl_GetEnsembleSubcommandList, всегда следует считать неизменяемым, даже если он не является общим. префикс команды обработчика неизвестной подкоманды (чтение и запись) Список слов, которые добавляются в начало любой подкоманды, когда подкоманда неизвестна ансамблю (в соответствии с текущим правилом обработки префиксов); см. команду namespace ensemble для получения дополнительных деталей. Если NULL, будет использоваться поведение по умолчанию - генерация подходящего сообщения об ошибке - при встрече неизвестной подкоманды. Можно читать и записывать с помощью Tcl_GetEnsembleUnknownHandler и Tcl_SetEnsembleUnknownHandler соответственно. Результат обеих функций - код результата Tcl (TCL_OK или TCL_ERROR, если токен не относится к ансамблю), и список, полученный из Tcl_GetEnsembleUnknownHandler, всегда следует считать неизменяемым, даже если он не является общим. привязанное пространство имён (только чтение) Пространство имён, к которому привязан ансамбль; когда пространство имён удаляется, ансамбль тоже удаляется, и это пространство имён также используется для списка экспортируемых команд, если и словарь сопоставления, и свойство списка подкоманд равны NULL. Можно читать с помощью Tcl_GetEnsembleNamespace, которая возвращает код результата Tcl (TCL_OK или TCL_ERROR, если токен не относится к ансамблю). СМ. ТАКЖЕ namespace(n), Tcl_DeleteCommandFromToken(3) КЛЮЧЕВЫЕ СЛОВА command, ensemble Tcl 8.5 Tcl_Ensemble(3)
Tcl_Ensemble(3) Tcl Library Procedures Tcl_Ensemble(3) ______________________________________________________________________________ NAME Tcl_CreateEnsemble, Tcl_FindEnsemble, Tcl_GetEnsembleFlags, Tcl_GetEnsembleMappingDict, Tcl_GetEnsembleNamespace, Tcl_GetEnsem‐ bleParameterList, Tcl_GetEnsembleUnknownHandler, Tcl_GetEnsembleSubcom‐ mandList, Tcl_IsEnsemble, Tcl_SetEnsembleFlags, Tcl_SetEnsembleMapping‐ Dict, Tcl_SetEnsembleParameterList, Tcl_SetEnsembleSubcommandList, Tcl_SetEnsembleUnknownHandler - manipulate ensemble commands SYNOPSIS #include <tcl.h> Tcl_Command Tcl_CreateEnsemble(interp, name, namespacePtr, ensFlags) Tcl_Command Tcl_FindEnsemble(interp, cmdNameObj, flags) int Tcl_IsEnsemble(token) int Tcl_GetEnsembleFlags(interp, token, ensFlagsPtr) int Tcl_SetEnsembleFlags(interp, token, ensFlags) int Tcl_GetEnsembleMappingDict(interp, token, dictObjPtr) int Tcl_SetEnsembleMappingDict(interp, token, dictObj) int │ Tcl_GetEnsembleParameterList(interp, token, listObjPtr) │ int │ Tcl_SetEnsembleParameterList(interp, token, listObj) │ int Tcl_GetEnsembleSubcommandList(interp, token, listObjPtr) int Tcl_SetEnsembleSubcommandList(interp, token, listObj) int Tcl_GetEnsembleUnknownHandler(interp, token, listObjPtr) int Tcl_SetEnsembleUnknownHandler(interp, token, listObj) int Tcl_GetEnsembleNamespace(interp, token, namespacePtrPtr) ARGUMENTS Tcl_Interp *interp (in/out) The interpreter in which the ensemble is to be created or found. Also where error result mes‐ sages are written. The functions whose names start with Tcl_GetEnsem‐ ble may have a NULL for the interp, but all other functions must not. const char *name (in) The name of the ensemble command to be created. Tcl_Namespace *namespacePtr (in) The namespace to which the ensemble command is to be bound, or NULL for the current namespace. int ensFlags (in) An OR'ed set of flag bits describing the basic con‐ figuration of the ensem‐ ble. Currently only one bit has meaning, TCL_EN‐ SEMBLE_PREFIX, which is present when the ensemble command should also match unambiguous prefixes of subcommands. Tcl_Obj *cmdNameObj (in) A value holding the name of the ensemble command to look up. int flags (in) An OR'ed set of flag bits controlling the behavior of Tcl_FindEnsemble. Cur‐ rently only TCL_LEAVE_ERR_MSG is sup‐ ported. Tcl_Command token (in) A normal command token that refers to an ensem‐ ble command, or which you wish to use for testing as an ensemble command in Tcl_IsEnsemble. int *ensFlagsPtr (out) Pointer to a variable into which to write the current ensemble flag bits; currently only the bit TCL_ENSEMBLE_PREFIX is defined. Tcl_Obj *dictObj (in) A dictionary value to use for the subcommand to im‐ plementation command pre‐ fix mapping dictionary in the ensemble. May be NULL if the mapping dictionary is to be removed. Tcl_Obj **dictObjPtr (out) Pointer to a variable into which to write the current ensemble mapping dictionary. Tcl_Obj *listObj (in) A list value to use for the list of formal pre- subcommand parameters, the defined list of sub‐ commands in the dictio‐ nary or the unknown sub‐ command handler command prefix. May be NULL if the subcommand list or unknown handler are to be removed. Tcl_Obj **listObjPtr (out) Pointer to a variable into which to write the current list of formal pre-subcommand parame‐ ters, the defined list of subcommands or the cur‐ rent unknown handler pre‐ fix. Tcl_Namespace **namespacePtrPtr (out) Pointer to a variable into which to write the handle of the namespace to which the ensemble is bound. ______________________________________________________________________________ DESCRIPTION An ensemble is a command, bound to some namespace, which consists of a collection of subcommands implemented by other Tcl commands. The first argument to the ensemble command is always interpreted as a selector that states what subcommand to execute. Ensembles are created using Tcl_CreateEnsemble, which takes four argu‐ ments: the interpreter to work within, the name of the ensemble to cre‐ ate, the namespace within the interpreter to bind the ensemble to, and the default set of ensemble flags. The result of the function is the command token for the ensemble, which may be used to further configure the ensemble using the API described below in ENSEMBLE PROPERTIES. Given the name of an ensemble command, the token for that command may be retrieved using Tcl_FindEnsemble. If the given command name (in cmd‐ NameObj) does not refer to an ensemble command, the result of the func‐ tion is NULL and (if the TCL_LEAVE_ERR_MSG bit is set in flags) an er‐ ror message is left in the interpreter result. A command token may be checked to see if it refers to an ensemble using Tcl_IsEnsemble. This returns 1 if the token refers to an ensemble, or 0 otherwise. ENSEMBLE PROPERTIES Every ensemble has four read-write properties and a read-only property. The properties are: flags (read-write) The set of flags for the ensemble, expressed as a bit-field. Currently, the only public flag is TCL_ENSEMBLE_PREFIX which is set when unambiguous prefixes of subcommands are permitted to be resolved to implementations as well as exact matches. The flags may be read and written using Tcl_GetEnsembleFlags and Tcl_SetEnsembleFlags respectively. The result of both of those functions is a Tcl result code (TCL_OK, or TCL_ERROR if the to‐ ken does not refer to an ensemble). mapping dictionary (read-write) A dictionary containing a mapping from subcommand names to lists of words to use as a command prefix (replacing the first two words of the command which are the ensemble command itself and the subcommand name), or NULL if every subcommand is to be mapped to the command with the same unqualified name in the en‐ semble's bound namespace. Defaults to NULL. May be read and written using Tcl_GetEnsembleMappingDict and Tcl_SetEnsembleMap‐ pingDict respectively. The result of both of those functions is a Tcl result code (TCL_OK, or TCL_ERROR if the token does not refer to an ensemble) and the dictionary obtained from Tcl_GetEnsembleMappingDict should always be treated as immutable even if it is unshared. All command names in prefixes set via Tcl_SetEnsembleMappingDict must be fully qualified. formal pre-subcommand parameter list (read-write) A list of formal parameter names (the names only being used when │ generating error messages) that come at invocation of the ensem‐ │ ble between the name of the ensemble and the subcommand argu‐ │ ment. NULL (the default) is equivalent to the empty list. May be │ read and written using Tcl_GetEnsembleParameterList and │ Tcl_SetEnsembleParameterList respectively. The result of both of │ those functions is a Tcl result code (TCL_OK, or TCL_ERROR if │ the token does not refer to an ensemble) and the dictionary ob‐ │ tained from Tcl_GetEnsembleParameterList should always be │ treated as immutable even if it is unshared. subcommand list (read-write) A list of all the subcommand names for the ensemble, or NULL if this is to be derived from either the keys of the mapping dic‐ tionary (see above) or (if that is also NULL) from the set of commands exported by the bound namespace. May be read and writ‐ ten using Tcl_GetEnsembleSubcommandList and Tcl_SetEnsembleSub‐ commandList respectively. The result of both of those functions is a Tcl result code (TCL_OK, or TCL_ERROR if the token does not refer to an ensemble) and the list obtained from Tcl_GetEnsem‐ bleSubcommandList should always be treated as immutable even if it is unshared. unknown subcommand handler command prefix (read-write) A list of words to prepend on the front of any subcommand when the subcommand is unknown to the ensemble (according to the cur‐ rent prefix handling rule); see the namespace ensemble command for more details. If NULL, the default behavior - generate a suitable error message - will be used when an unknown subcommand is encountered. May be read and written using Tcl_GetEnsembleUn‐ knownHandler and Tcl_SetEnsembleUnknownHandler respectively. The result of both functions is a Tcl result code (TCL_OK, or TCL_ERROR if the token does not refer to an ensemble) and the list obtained from Tcl_GetEnsembleUnknownHandler should always be treated as immutable even if it is unshared. bound namespace (read-only) The namespace to which the ensemble is bound; when the namespace is deleted, so too will the ensemble, and this namespace is also the namespace whose list of exported commands is used if both the mapping dictionary and the subcommand list properties are NULL. May be read using Tcl_GetEnsembleNamespace which returns a Tcl result code (TCL_OK, or TCL_ERROR if the token does not re‐ fer to an ensemble). SEE ALSO namespace(n), Tcl_DeleteCommandFromToken(3) KEYWORDS command, ensemble Tcl 8.5 Tcl_Ensemble(3)
Tcl_Ensemble(3) Процедуры библиотеки Tcl Tcl_Ensemble(3) ______________________________________________________________________________ NAME Tcl_CreateEnsemble, Tcl_FindEnsemble, Tcl_GetEnsembleFlags, Tcl_GetEnsembleMappingDict, Tcl_GetEnsembleNamespace, Tcl_GetEnsem‐ bleParameterList, Tcl_GetEnsembleUnknownHandler, Tcl_GetEnsembleSubcom‐ mandList, Tcl_IsEnsemble, Tcl_SetEnsembleFlags, Tcl_SetEnsembleMapping‐ Dict, Tcl_SetEnsembleParameterList, Tcl_SetEnsembleSubcommandList, Tcl_SetEnsembleUnknownHandler - манипулировать командами ансамблей SYNOPSIS #include <tcl.h> Tcl_Command Tcl_CreateEnsemble(interp, name, namespacePtr, ensFlags) Tcl_Command Tcl_FindEnsemble(interp, cmdNameObj, flags) int Tcl_IsEnsemble(token) int Tcl_GetEnsembleFlags(interp, token, ensFlagsPtr) int Tcl_SetEnsembleFlags(interp, token, ensFlags) int Tcl_GetEnsembleMappingDict(interp, token, dictObjPtr) int Tcl_SetEnsembleMappingDict(interp, token, dictObj) int │ Tcl_GetEnsembleParameterList(interp, token, listObjPtr) │ int │ Tcl_SetEnsembleParameterList(interp, token, listObj) │ int Tcl_GetEnsembleSubcommandList(interp, token, listObjPtr) int Tcl_SetEnsembleSubcommandList(interp, token, listObj) int Tcl_GetEnsembleUnknownHandler(interp, token, listObjPtr) int Tcl_SetEnsembleUnknownHandler(interp, token, listObj) int Tcl_GetEnsembleNamespace(interp, token, namespacePtrPtr) ARGUMENTS Tcl_Interp *interp (in/out) Интерпретатор, в котором ансамбль будет создан или найден. Также здесь записываются сообщения об ошибках. Функции, чьи имена начинаются с Tcl_GetEnsem‐ ble, могут принимать NULL для interp, но все другие функции не должны. const char *name (in) Имя команды ансамбля, которая будет создана. Tcl_Namespace *namespacePtr (in) Пространство имён, к которому будет привязано команда ансамбля, или NULL для текущего пространства имён. int ensFlags (in) Набор флагов, объединённых с помощью OR, описывающий базовую конфигурацию ансамбля. В настоящее время только один бит имеет значение: TCL_EN‐ SEMBLE_PREFIX, который присутствует, когда команда ансамбля должна также соответствовать однозначным префиксам подкоманд. Tcl_Obj *cmdNameObj (in) Значение, содержащее имя команды ансамбля для поиска. int flags (in) Набор флагов, объединённых с помощью OR, управляющий поведением Tcl_FindEnsemble. В настоящее время поддерживается только TCL_LEAVE_ERR_MSG. Tcl_Command token (in) Обычный токен команды, который относится к команде ансамбля, или который вы хотите использовать для проверки как команду ансамбля в Tcl_IsEnsemble. int *ensFlagsPtr (out) Указатель на переменную, в которую будет записан текущий набор флагов ансамбля; в настоящее время определён только бит TCL_ENSEMBLE_PREFIX. Tcl_Obj *dictObj (in) Значение словаря для использования в качестве словаря сопоставления подкоманд с префиксами команд реализации в ансамбле. Может быть NULL, если словарь сопоставления нужно удалить. Tcl_Obj **dictObjPtr (out) Указатель на переменную, в которую будет записан текущий словарь сопоставления ансамбля. Tcl_Obj *listObj (in) Значение списка для использования в качестве списка формальных параметров перед подкомандой, списка определённых подкоманд в словаре или префикса команды обработчика неизвестной подкоманды. Может быть NULL, если список подкоманд или обработчик неизвестного элемента нужно удалить. Tcl_Obj **listObjPtr (out) Указатель на переменную, в которую будет записан текущий список формальных параметров перед подкомандой, список определённых подкоманд или текущий префикс обработчика неизвестного элемента. Tcl_Namespace **namespacePtrPtr (out) Указатель на переменную, в которую будет записан дескриптор пространства имён, к которому привязано ансамбль. ______________________________________________________________________________ DESCRIPTION Ансамбль - это команда, привязанная к какому-то пространству имён, которая состоит из коллекции подкоманд, реализуемых другими командами Tcl. Первый аргумент команды ансамбля всегда интерпретируется как селектор, указывающий, какую подкоманду выполнить. Ансамбли создаются с помощью Tcl_CreateEnsemble, которая принимает четыре аргумента: интерпретатор, в котором нужно работать, имя ансамбля для создания, пространство имён в интерпретаторе, к которому ансамбль будет привязан, и набор флагов ансамбля по умолчанию. Результат функции - токен команды ансамбля, который можно использовать для дальнейшей настройки ансамбля с помощью API, описанного ниже в разделе ENSEMBLE PROPERTIES. Для получения токена команды ансамбля по её имени можно использовать Tcl_FindEnsemble. Если указанное имя команды (в cmdNameObj) не относится к команде ансамбля, результат функции будет NULL, и (если бит TCL_LEAVE_ERR_MSG установлен в flags) в результате интерпретатора будет оставлено сообщение об ошибке. Токен команды можно проверить на то, относится ли он к ансамблю, с помощью Tcl_IsEnsemble. Это возвращает 1, если токен относится к ансамблю, или 0 в противном случае. ENSEMBLE PROPERTIES Каждый ансамбль имеет четыре свойства для чтения и записи, а также одно свойство только для чтения. Свойства такие: flags (чтение и запись) Набор флагов для ансамбля, выраженный как битовая маска. В настоящее время единственный публичный флаг - TCL_ENSEMBLE_PREFIX, который устанавливается, когда разрешены однозначные префиксы подкоманд для разрешения на реализации, а также точные совпадения. Флаги можно читать и записывать с помощью Tcl_GetEnsembleFlags и Tcl_SetEnsembleFlags соответственно. Результат обеих функций - код результата Tcl (TCL_OK или TCL_ERROR, если токен не относится к ансамблю). mapping dictionary (чтение и запись) Словарь, содержащий сопоставление имён подкоманд спискам слов, которые используются в качестве префикса команды (заменяя первые два слова команды, которые являются самой командой ансамбля и именем подкоманды), или NULL, если каждая подкоманда должна быть сопоставлена команде с тем же неполным именем в привязанном пространстве имён ансамбля. По умолчанию - NULL. Можно читать и записывать с помощью Tcl_GetEnsembleMappingDict и Tcl_SetEnsembleMap‐ pingDict соответственно. Результат обеих функций - код результата Tcl (TCL_OK или TCL_ERROR, если токен не относится к ансамблю), и словарь, полученный из Tcl_GetEnsembleMappingDict, всегда следует считать неизменяемым, даже если он неразделяемый. Все имена команд в префиксах, установленных через Tcl_SetEnsembleMappingDict, должны быть полностью квалифицированы. formal pre-subcommand parameter list (чтение и запись) Список имён формальных параметров (имена используются только при генерации сообщений об ошибках), которые передаются при вызове ансамбля между именем ансамбля и аргументом подкоманды. NULL (по умолчанию) эквивалентен пустому списку. Можно читать и записывать с помощью Tcl_GetEnsembleParameterList и Tcl_SetEnsembleParameterList соответственно. Результат обеих функций - код результата Tcl (TCL_OK или TCL_ERROR, если токен не относится к ансамблю), и список, полученный из Tcl_GetEnsembleParameterList, всегда следует считать неизменяемым, даже если он неразделяемый. subcommand list (чтение и запись) Список всех имён подкоманд для ансамбля, или NULL, если он должен быть получен из ключей словаря сопоставления (см. выше) или (если это тоже NULL) из набора команд, экспортируемых привязанным пространством имён. Можно читать и записывать с помощью Tcl_GetEnsembleSubcommandList и Tcl_SetEnsembleSubcommandList соответственно. Результат обеих функций - код результата Tcl (TCL_OK или TCL_ERROR, если токен не относится к ансамблю), и список, полученный из Tcl_GetEnsembleSub‐ commandList, всегда следует считать неизменяемым, даже если он неразделяемый. unknown subcommand handler command prefix (чтение и запись) Список слов, которые добавляются в начало любой подкоманды, когда подкоманда неизвестна ансамблю (согласно текущему правилу обработки префиксов); см. команду namespace ensemble для более подробной информации. Если NULL, будет использоваться поведение по умолчанию - генерировать подходящее сообщение об ошибке - при встрече неизвестной подкоманды. Можно читать и записывать с помощью Tcl_GetEnsembleUn‐ knownHandler и Tcl_SetEnsembleUnknownHandler соответственно. Результат обеих функций - код результата Tcl (TCL_OK или TCL_ERROR, если токен не относится к ансамблю), и список, полученный из Tcl_GetEnsembleUn‐ knownHandler, всегда следует считать неизменяемым, даже если он неразделяемый. bound namespace (только чтение) Пространство имён, к которому привязан ансамбль; когда пространство имён удаляется, ансамбль тоже удаляется, и это пространство имён также используется для списка экспортируемых команд, если и словарь сопоставления, и свойство списка подкоманд равны NULL. Можно читать с помощью Tcl_GetEnsembleNamespace, которая возвращает код результата Tcl (TCL_OK или TCL_ERROR, если токен не относится к ансамблю). SEE ALSO namespace(n), Tcl_DeleteCommandFromToken(3) KEYWORDS command, ensemble Tcl 8.5 Tcl_Ensemble(3)
Tcl_Ensemble(3) Tcl Library Procedures Tcl_Ensemble(3) ______________________________________________________________________________ NAME Tcl_CreateEnsemble, Tcl_FindEnsemble, Tcl_GetEnsembleFlags, Tcl_GetEnsembleMappingDict, Tcl_GetEnsembleNamespace, Tcl_GetEnsem‐ bleParameterList, Tcl_GetEnsembleUnknownHandler, Tcl_GetEnsembleSubcom‐ mandList, Tcl_IsEnsemble, Tcl_SetEnsembleFlags, Tcl_SetEnsembleMapping‐ Dict, Tcl_SetEnsembleParameterList, Tcl_SetEnsembleSubcommandList, Tcl_SetEnsembleUnknownHandler - manipulate ensemble commands SYNOPSIS #include <tcl.h> Tcl_Command Tcl_CreateEnsemble(interp, name, namespacePtr, ensFlags) Tcl_Command Tcl_FindEnsemble(interp, cmdNameObj, flags) int Tcl_IsEnsemble(token) int Tcl_GetEnsembleFlags(interp, token, ensFlagsPtr) int Tcl_SetEnsembleFlags(interp, token, ensFlags) int Tcl_GetEnsembleMappingDict(interp, token, dictObjPtr) int Tcl_SetEnsembleMappingDict(interp, token, dictObj) int │ Tcl_GetEnsembleParameterList(interp, token, listObjPtr) │ int │ Tcl_SetEnsembleParameterList(interp, token, listObj) │ int Tcl_GetEnsembleSubcommandList(interp, token, listObjPtr) int Tcl_SetEnsembleSubcommandList(interp, token, listObj) int Tcl_GetEnsembleUnknownHandler(interp, token, listObjPtr) int Tcl_SetEnsembleUnknownHandler(interp, token, listObj) int Tcl_GetEnsembleNamespace(interp, token, namespacePtrPtr) ARGUMENTS Tcl_Interp *interp (in/out) The interpreter in which the ensemble is to be created or found. Also where error result mes‐ sages are written. The functions whose names start with Tcl_GetEnsem‐ ble may have a NULL for the interp, but all other functions must not. const char *name (in) The name of the ensemble command to be created. Tcl_Namespace *namespacePtr (in) The namespace to which the ensemble command is to be bound, or NULL for the current namespace. int ensFlags (in) An OR'ed set of flag bits describing the basic con‐ figuration of the ensem‐ ble. Currently only one bit has meaning, TCL_EN‐ SEMBLE_PREFIX, which is present when the ensemble command should also match unambiguous prefixes of subcommands. Tcl_Obj *cmdNameObj (in) A value holding the name of the ensemble command to look up. int flags (in) An OR'ed set of flag bits controlling the behavior of Tcl_FindEnsemble. Cur‐ rently only TCL_LEAVE_ERR_MSG is sup‐ ported. Tcl_Command token (in) A normal command token that refers to an ensem‐ ble command, or which you wish to use for testing as an ensemble command in Tcl_IsEnsemble. int *ensFlagsPtr (out) Pointer to a variable into which to write the current ensemble flag bits; currently only the bit TCL_ENSEMBLE_PREFIX is defined. Tcl_Obj *dictObj (in) A dictionary value to use for the subcommand to im‐ plementation command pre‐ fix mapping dictionary in the ensemble. May be NULL if the mapping dictionary is to be removed. Tcl_Obj **dictObjPtr (out) Pointer to a variable into which to write the current ensemble mapping dictionary. Tcl_Obj *listObj (in) A list value to use for the list of formal pre- subcommand parameters, the defined list of sub‐ commands in the dictio‐ nary or the unknown sub‐ command handler command prefix. May be NULL if the subcommand list or unknown handler are to be removed. Tcl_Obj **listObjPtr (out) Pointer to a variable into which to write the current list of formal pre-subcommand parame‐ ters, the defined list of subcommands or the cur‐ rent unknown handler pre‐ fix. Tcl_Namespace **namespacePtrPtr (out) Pointer to a variable into which to write the handle of the namespace to which the ensemble is bound. ______________________________________________________________________________ DESCRIPTION An ensemble is a command, bound to some namespace, which consists of a collection of subcommands implemented by other Tcl commands. The first argument to the ensemble command is always interpreted as a selector that states what subcommand to execute. Ensembles are created using Tcl_CreateEnsemble, which takes four argu‐ ments: the interpreter to work within, the name of the ensemble to cre‐ ate, the namespace within the interpreter to bind the ensemble to, and the default set of ensemble flags. The result of the function is the command token for the ensemble, which may be used to further configure the ensemble using the API described below in ENSEMBLE PROPERTIES. Given the name of an ensemble command, the token for that command may be retrieved using Tcl_FindEnsemble. If the given command name (in cmd‐ NameObj) does not refer to an ensemble command, the result of the func‐ tion is NULL and (if the TCL_LEAVE_ERR_MSG bit is set in flags) an er‐ ror message is left in the interpreter result. A command token may be checked to see if it refers to an ensemble using Tcl_IsEnsemble. This returns 1 if the token refers to an ensemble, or 0 otherwise. ENSEMBLE PROPERTIES Every ensemble has four read-write properties and a read-only property. The properties are: flags (read-write) The set of flags for the ensemble, expressed as a bit-field. Currently, the only public flag is TCL_ENSEMBLE_PREFIX which is set when unambiguous prefixes of subcommands are permitted to be resolved to implementations as well as exact matches. The flags may be read and written using Tcl_GetEnsembleFlags and Tcl_SetEnsembleFlags respectively. The result of both of those functions is a Tcl result code (TCL_OK, or TCL_ERROR if the to‐ ken does not refer to an ensemble). mapping dictionary (read-write) A dictionary containing a mapping from subcommand names to lists of words to use as a command prefix (replacing the first two words of the command which are the ensemble command itself and the subcommand name), or NULL if every subcommand is to be mapped to the command with the same unqualified name in the en‐ semble's bound namespace. Defaults to NULL. May be read and written using Tcl_GetEnsembleMappingDict and Tcl_SetEnsembleMap‐ pingDict respectively. The result of both of those functions is a Tcl result code (TCL_OK, or TCL_ERROR if the token does not refer to an ensemble) and the dictionary obtained from Tcl_GetEnsembleMappingDict should always be treated as immutable even if it is unshared. All command names in prefixes set via Tcl_SetEnsembleMappingDict must be fully qualified. formal pre-subcommand parameter list (read-write) A list of formal parameter names (the names only being used when │ generating error messages) that come at invocation of the ensem‐ │ ble between the name of the ensemble and the subcommand argu‐ │ ment. NULL (the default) is equivalent to the empty list. May be │ read and written using Tcl_GetEnsembleParameterList and │ Tcl_SetEnsembleParameterList respectively. The result of both of │ those functions is a Tcl result code (TCL_OK, or TCL_ERROR if │ the token does not refer to an ensemble) and the dictionary ob‐ │ tained from Tcl_GetEnsembleParameterList should always be │ treated as immutable even if it is unshared. subcommand list (read-write) A list of all the subcommand names for the ensemble, or NULL if this is to be derived from either the keys of the mapping dic‐ tionary (see above) or (if that is also NULL) from the set of commands exported by the bound namespace. May be read and writ‐ ten using Tcl_GetEnsembleSubcommandList and Tcl_SetEnsembleSub‐ commandList respectively. The result of both of those functions is a Tcl result code (TCL_OK, or TCL_ERROR if the token does not refer to an ensemble) and the list obtained from Tcl_GetEnsem‐ bleSubcommandList should always be treated as immutable even if it is unshared. unknown subcommand handler command prefix (read-write) A list of words to prepend on the front of any subcommand when the subcommand is unknown to the ensemble (according to the cur‐ rent prefix handling rule); see the namespace ensemble command for more details. If NULL, the default behavior - generate a suitable error message - will be used when an unknown subcommand is encountered. May be read and written using Tcl_GetEnsembleUn‐ knownHandler and Tcl_SetEnsembleUnknownHandler respectively. The result of both functions is a Tcl result code (TCL_OK, or TCL_ERROR if the token does not refer to an ensemble) and the list obtained from Tcl_GetEnsembleUnknownHandler should always be treated as immutable even if it is unshared. bound namespace (read-only) The namespace to which the ensemble is bound; when the namespace is deleted, so too will the ensemble, and this namespace is also the namespace whose list of exported commands is used if both the mapping dictionary and the subcommand list properties are NULL. May be read using Tcl_GetEnsembleNamespace which returns a Tcl result code (TCL_OK, or TCL_ERROR if the token does not re‐ fer to an ensemble). SEE ALSO namespace(n), Tcl_DeleteCommandFromToken(3) KEYWORDS command, ensemble Tcl 8.5 Tcl_Ensemble(3)
Filesystem(3) Tcl Library Procedures Filesystem(3) ______________________________________________________________________________ NAME Tcl_FSRegister, Tcl_FSUnregister, Tcl_FSData, Tcl_FSMountsChanged, Tcl_FSGetFileSystemForPath, Tcl_FSGetPathType, Tcl_FSCopyFile, Tcl_FS‐ CopyDirectory, Tcl_FSCreateDirectory, Tcl_FSDeleteFile, Tcl_FSRemoveDi‐ rectory, Tcl_FSRenameFile, Tcl_FSListVolumes, Tcl_FSEvalFile, Tcl_FSE‐ valFileEx, Tcl_FSLoadFile, Tcl_FSUnloadFile, Tcl_FSMatchInDirectory, Tcl_FSLink, Tcl_FSLstat, Tcl_FSUtime, Tcl_FSFileAttrsGet, Tcl_FSFileAt‐ trsSet, Tcl_FSFileAttrStrings, Tcl_FSStat, Tcl_FSAccess, Tcl_FSOpen‐ FileChannel, Tcl_FSGetCwd, Tcl_FSChdir, Tcl_FSPathSeparator, Tcl_FSJoinPath, Tcl_FSSplitPath, Tcl_FSEqualPaths, Tcl_FSGetNormalized‐ Path, Tcl_FSJoinToPath, Tcl_FSConvertToPathType, Tcl_FSGetInternalRep, Tcl_FSGetTranslatedPath, Tcl_FSGetTranslatedStringPath, Tcl_FSNewNa‐ tivePath, Tcl_FSGetNativePath, Tcl_FSFileSystemInfo, Tcl_GetAccessTime‐ FromStat, Tcl_GetBlockSizeFromStat, Tcl_GetBlocksFromStat, Tcl_GetChangeTimeFromStat, Tcl_GetDeviceTypeFromStat, Tcl_GetFSDevice‐ FromStat, Tcl_GetFSInodeFromStat, Tcl_GetGroupIdFromStat, Tcl_GetLinkCountFromStat, Tcl_GetModeFromStat, Tcl_GetModificationTime‐ FromStat, Tcl_GetSizeFromStat, Tcl_GetUserIdFromStat, Tcl_AllocStatBuf - procedures to interact with any filesystem SYNOPSIS #include <tcl.h> int Tcl_FSRegister(clientData, fsPtr) int Tcl_FSUnregister(fsPtr) void * Tcl_FSData(fsPtr) Tcl_FSMountsChanged(fsPtr) const Tcl_Filesystem * Tcl_FSGetFileSystemForPath(pathPtr) Tcl_PathType Tcl_FSGetPathType(pathPtr) int Tcl_FSCopyFile(srcPathPtr, destPathPtr) int Tcl_FSCopyDirectory(srcPathPtr, destPathPtr, errorPtr) int Tcl_FSCreateDirectory(pathPtr) int Tcl_FSDeleteFile(pathPtr) int Tcl_FSRemoveDirectory(pathPtr, recursive, errorPtr) int Tcl_FSRenameFile(srcPathPtr, destPathPtr) Tcl_Obj * Tcl_FSListVolumes(void) int Tcl_FSEvalFileEx(interp, pathPtr, encodingName) int Tcl_FSEvalFile(interp, pathPtr) int Tcl_FSLoadFile(interp, pathPtr, sym1, sym2, proc1Ptr, proc2Ptr, loadHandlePtr, unloadProcPtr) int │ Tcl_FSUnloadFile(interp, loadHandle) │ int Tcl_FSMatchInDirectory(interp, resultPtr, pathPtr, pattern, types) Tcl_Obj * Tcl_FSLink(linkNamePtr, toPtr, linkAction) int Tcl_FSLstat(pathPtr, statPtr) int Tcl_FSUtime(pathPtr, tval) int Tcl_FSFileAttrsGet(interp, index, pathPtr, objPtrRef) int Tcl_FSFileAttrsSet(interp, index, pathPtr, objPtr) const char *const * Tcl_FSFileAttrStrings(pathPtr, objPtrRef) int Tcl_FSStat(pathPtr, statPtr) int Tcl_FSAccess(pathPtr, mode) Tcl_Channel Tcl_FSOpenFileChannel(interp, pathPtr, modeString, permissions) Tcl_Obj * Tcl_FSGetCwd(interp) int Tcl_FSChdir(pathPtr) Tcl_Obj * Tcl_FSPathSeparator(pathPtr) Tcl_Obj * Tcl_FSJoinPath(listObj, elements) Tcl_Obj * Tcl_FSSplitPath(pathPtr, lenPtr) int Tcl_FSEqualPaths(firstPtr, secondPtr) Tcl_Obj * Tcl_FSGetNormalizedPath(interp, pathPtr) Tcl_Obj * Tcl_FSJoinToPath(basePtr, objc, objv) int Tcl_FSConvertToPathType(interp, pathPtr) void * Tcl_FSGetInternalRep(pathPtr, fsPtr) Tcl_Obj * Tcl_FSGetTranslatedPath(interp, pathPtr) const char * Tcl_FSGetTranslatedStringPath(interp, pathPtr) Tcl_Obj * Tcl_FSNewNativePath(fsPtr, clientData) const void * Tcl_FSGetNativePath(pathPtr) Tcl_Obj * Tcl_FSFileSystemInfo(pathPtr) Tcl_StatBuf * Tcl_AllocStatBuf() Tcl_WideInt │ Tcl_GetAccessTimeFromStat(statPtr) │ unsigned │ Tcl_GetBlockSizeFromStat(statPtr) │ Tcl_WideUInt │ Tcl_GetBlocksFromStat(statPtr) │ Tcl_WideInt │ Tcl_GetChangeTimeFromStat(statPtr) │ int │ Tcl_GetDeviceTypeFromStat(statPtr) │ unsigned │ Tcl_GetFSDeviceFromStat(statPtr) │ unsigned │ Tcl_GetFSInodeFromStat(statPtr) │ int │ Tcl_GetGroupIdFromStat(statPtr) │ int │ Tcl_GetLinkCountFromStat(statPtr) │ unsigned │ Tcl_GetModeFromStat(statPtr) │ Tcl_WideInt │ Tcl_GetModificationTimeFromStat(statPtr) │ Tcl_WideUInt │ Tcl_GetSizeFromStat(statPtr) │ int │ Tcl_GetUserIdFromStat(statPtr) │ ARGUMENTS const Tcl_Filesystem *fsPtr (in) Points to a structure con‐ taining the addresses of procedures that can be called to perform the vari‐ ous filesystem operations. Tcl_Obj *pathPtr (in) The path represented by this value is used for the operation in question. If the value does not already have an internal path rep‐ resentation, it will be converted to have one. Tcl_Obj *srcPathPtr (in) As for pathPtr, but used for the source file for a copy or rename operation. Tcl_Obj *destPathPtr (in) As for pathPtr, but used for the destination file‐ name for a copy or rename operation. int recursive (in) Whether to remove subdirec‐ tories and their contents as well. const char *encodingName (in) The encoding of the data stored in the file identi‐ fied by pathPtr and to be evaluated. const char *pattern (in) Only files or directories matching this pattern will be returned. Tcl_GlobTypeData *types (in) Only files or directories matching the type descrip‐ tions contained in this structure will be returned. This parameter may be NULL. Tcl_Interp *interp (in) Interpreter to use either for results, evaluation, or reporting error messages. void *clientData (in) The native description of the path value to create. Tcl_Obj *firstPtr (in) The first of two path val‐ ues to compare. The value may be converted to path type. Tcl_Obj *secondPtr (in) The second of two path val‐ ues to compare. The value may be converted to path type. Tcl_Obj *listObj (in) The list of path elements to operate on with a join operation. int elements (in) The number of elements in the listObj which should be joined together. If nega‐ tive, then all elements are joined. Tcl_Obj **errorPtr (out) In the case of an error, filled with a value con‐ taining the name of the file which caused an error in the various copy/rename operations. int index (in) The index of the attribute in question. Tcl_Obj *objPtr (in) The value to set in the op‐ eration. Tcl_Obj **objPtrRef (out) Filled with a value con‐ taining the result of the operation. Tcl_Obj *resultPtr (out) Preallocated value in which to store (using Tcl_ListOb‐ jAppendElement) the list of files or directories which are successfully matched. int mode (in) Mask consisting of one or more of R_OK, W_OK, X_OK and F_OK. R_OK, W_OK and X_OK request checking whether the file exists and has read, write and exe‐ cute permissions, respec‐ tively. F_OK just requests checking for the existence of the file. Tcl_StatBuf *statPtr (out) The structure that contains the result of a stat or lstat operation. const char *sym1 (in) Name of a procedure to look up in the file's symbol ta‐ ble const char *sym2 (in) Name of a procedure to look up in the file's symbol ta‐ ble Tcl_PackageInitProc **proc1Ptr (out) Filled with the init func‐ tion for this code. Tcl_PackageInitProc **proc2Ptr (out) Filled with the safe-init function for this code. void **clientDataPtr (out) Filled with the clientData value to pass to this code's unload function when it is called. Tcl_LoadHandle *loadHandlePtr (out) Filled with an abstract to‐ ken representing the loaded file. Tcl_FSUnloadFileProc **unloadProcPtr (out) Filled with the function to use to unload this piece of code. Tcl_LoadHandle loadHandle (in) Handle to the loaded li‐ brary to be unloaded. utimbuf *tval (in) The access and modification times in this structure are read and used to set those values for a given file. const char *modeString (in) Specifies how the file is to be accessed. May have any of the values allowed for the mode argument to the Tcl open command. int permissions (in) POSIX-style permission flags such as 0644. If a new file is created, these permissions will be set on the created file. int *lenPtr (out) If non-NULL, filled with the number of elements in the split path. Tcl_Obj *basePtr (in) The base path on to which to join the given elements. May be NULL. int objc (in) The number of elements in objv. Tcl_Obj *const objv[] (in) The elements to join to the given base path. Tcl_Obj *linkNamePtr (in) The name of the link to be created or read. Tcl_Obj *toPtr (in) What the link called linkNamePtr should be linked to, or NULL if the symbolic link specified by linkNamePtr is to be read. int linkAction (in) OR-ed combination of flags indicating what kind of link should be created (will be ignored if toPtr is NULL). Valid bits to set are TCL_CREATE_SYM‐ BOLIC_LINK and TCL_CRE‐ ATE_HARD_LINK. When both flags are set and the un‐ derlying filesystem can do either, symbolic links are preferred. ______________________________________________________________________________ DESCRIPTION There are several reasons for calling the Tcl_FS API functions (e.g. Tcl_FSAccess and Tcl_FSStat) rather than calling system level functions like access and stat directly. First, they will work cross- platform, so an extension which calls them should work unmodified on Unix and Windows. Second, the Windows implementation of some of these functions fixes some bugs in the system level calls. Third, these func‐ tion calls deal with any “Utf to platform-native” path conversions which may be required (and may cache the results of such conversions for greater efficiency on subsequent calls). Fourth, and perhaps most importantly, all of these functions are “virtual filesystem aware”. Any virtual filesystem (VFS for short) which has been registered (through Tcl_FSRegister) may reroute file access to alternative media or access methods. This means that all of these functions (and there‐ fore the corresponding file, glob, pwd, cd, open, etc. Tcl commands) may be operate on “files” which are not native files in the native filesystem. This also means that any Tcl extension which accesses the filesystem (FS for short) through this API is automatically “virtual filesystem aware”. Of course, if an extension accesses the native filesystem directly (through platform-specific APIs, for example), then Tcl cannot intercept such calls. If appropriate VFSes have been registered, the “files” may, to give two examples, be remote (e.g. situated on a remote ftp server) or archived (e.g. lying inside a .zip archive). Such registered filesystems provide a lookup table of functions to implement all or some of the functional‐ ity listed here. Finally, the Tcl_FSStat and Tcl_FSLstat calls abstract away from what the “struct stat” buffer is actually declared to be, al‐ lowing the same code to be used both on systems with and systems with‐ out support for files larger than 2GB in size. The Tcl_FS API is Tcl_Obj-ified and may cache internal representations and other path-related strings (e.g. the current working directory). One side-effect of this is that one must not pass in values with a ref‐ erence count of zero to any of these functions. If such calls were han‐ dled, they might result in memory leaks (under some circumstances, the filesystem code may wish to retain a reference to the passed in value, and so one must not assume that after any of these calls return, the value still has a reference count of zero - it may have been incre‐ mented) or in a direct segmentation fault (or other memory access er‐ ror) due to the value being freed part way through the complex value manipulation required to ensure that the path is fully normalized and absolute for filesystem determination. The practical lesson to learn from this is that Tcl_Obj *path = Tcl_NewStringObj(...); Tcl_FSWhatever(path); Tcl_DecrRefCount(path); is wrong, and may cause memory errors. The path must have its reference count incremented before passing it in, or decrementing it. For this reason, values with a reference count of zero are considered not to be valid filesystem paths and calling any Tcl_FS API function with such a value will result in no action being taken. FS API FUNCTIONS Tcl_FSCopyFile attempts to copy the file given by srcPathPtr to the path name given by destPathPtr. If the two paths given lie in the same filesystem (according to Tcl_FSGetFileSystemForPath) then that filesys‐ tem's “copy file” function is called (if it is non-NULL). Otherwise the function returns -1 and sets the errno global C variable to the “EXDEV” POSIX error code (which signifies a “cross-domain link”). Tcl_FSCopyDirectory attempts to copy the directory given by srcPathPtr to the path name given by destPathPtr. If the two paths given lie in the same filesystem (according to Tcl_FSGetFileSystemForPath) then that filesystem's “copy file” function is called (if it is non-NULL). Oth‐ erwise the function returns -1 and sets the errno global C variable to the “EXDEV” POSIX error code (which signifies a “cross-domain link”). Tcl_FSCreateDirectory attempts to create the directory given by pathPtr by calling the owning filesystem's “create directory” function. Tcl_FSDeleteFile attempts to delete the file given by pathPtr by call‐ ing the owning filesystem's “delete file” function. Tcl_FSRemoveDirectory attempts to remove the directory given by pathPtr by calling the owning filesystem's “remove directory” function. Tcl_FSRenameFile attempts to rename the file or directory given by src‐ PathPtr to the path name given by destPathPtr. If the two paths given lie in the same filesystem (according to Tcl_FSGetFileSystemForPath) then that filesystem's “rename file” function is called (if it is non- NULL). Otherwise the function returns -1 and sets the errno global C variable to the “EXDEV” POSIX error code (which signifies a “cross-do‐ main link”). Tcl_FSListVolumes calls each filesystem which has a non-NULL “list vol‐ umes” function and asks them to return their list of root volumes. It accumulates the return values in a list which is returned to the caller (with a reference count of 0). Tcl_FSEvalFileEx reads the file given by pathPtr using the encoding identified by encodingName and evaluates its contents as a Tcl script. It returns the same information as Tcl_EvalObjEx. If encodingName is NULL, the system encoding is used for reading the file contents. If the file could not be read then a Tcl error is returned to describe why the file could not be read. The eofchar for files is “\x1A” (^Z) for all platforms. If you require a “^Z” in code for string comparison, you can use “\x1A”, which will be safely substituted by the Tcl inter‐ preter into “^Z”. Tcl_FSEvalFile is a simpler version of Tcl_FSEval‐ FileEx that always uses the system encoding when reading the file. Tcl_FSLoadFile dynamically loads a binary code file into memory and re‐ turns the addresses of two procedures within that file, if they are de‐ fined. The appropriate function for the filesystem to which pathPtr be‐ longs will be called. If that filesystem does not implement this func‐ tion (most virtual filesystems will not, because of OS limitations in dynamically loading binary code), Tcl will attempt to copy the file to a temporary directory and load that temporary file. Tcl_FSUnloadFile │ reverses the operation, asking for the library indicated by the load‐ │ Handle to be removed from the process. Note that, unlike with the un‐ │ load command, this does not give the library any opportunity to clean │ up. Both the above functions return a standard Tcl completion code. If an error occurs, an error message is left in the interp's result. The token provided via the variable indicated by loadHandlePtr may be │ used with Tcl_FindSymbol. Tcl_FSMatchInDirectory is used by the globbing code to search a direc‐ tory for all files which match a given pattern. The appropriate func‐ tion for the filesystem to which pathPtr belongs will be called. The return value is a standard Tcl result indicating whether an error occurred in globbing. Error messages are placed in interp (unless in‐ terp is NULL, which is allowed), but good results are placed in the re‐ sultPtr given. Note that the glob code implements recursive patterns internally, so this function will only ever be passed simple patterns, which can be matched using the logic of string match. To handle recursion, Tcl will call this function frequently asking only for directories to be re‐ turned. A special case of being called with a NULL pattern indicates that the path needs to be checked only for the correct type. Tcl_FSLink replaces the library version of readlink, and extends it to support the creation of links. The appropriate function for the filesystem to which linkNamePtr belongs will be called. If the toPtr is NULL, a “read link” action is performed. The result is a Tcl_Obj specifying the contents of the symbolic link given by linkNamePtr, or NULL if the link could not be read. The result is owned by the caller, which should call Tcl_DecrRefCount when the result is no longer needed. If the toPtr is not NULL, Tcl should create a link of one of the types passed in in the linkAction flag. This flag is an OR'ed combination of TCL_CREATE_SYMBOLIC_LINK and TCL_CREATE_HARD_LINK. Where a choice exists (i.e. more than one flag is passed in), the Tcl convention is to prefer symbolic links. When a link is successfully created, the return value should be toPtr (which is therefore already owned by the caller). If unsuccessful, NULL is returned. Tcl_FSLstat fills the Tcl_StatBuf structure statPtr with information about the specified file. You do not need any access rights to the file to get this information but you need search rights to all directories named in the path leading to the file. The Tcl_StatBuf structure in‐ cludes info regarding device, inode (always 0 on Windows), privilege mode, nlink (always 1 on Windows), user id (always 0 on Windows), group id (always 0 on Windows), rdev (same as device on Windows), size, last access time, last modification time, and last metadata change time. See PORTABLE STAT RESULT API for a description of how to write portable code to allocate and access the Tcl_StatBuf structure. If path exists, Tcl_FSLstat returns 0 and the stat structure is filled with data. Otherwise, -1 is returned, and no stat info is given. Tcl_FSUtime replaces the library version of utime. This returns 0 on success and -1 on error (as per the utime documenta‐ tion). If successful, the function will update the “atime” and “mtime” values of the file given. Tcl_FSFileAttrsGet implements read access for the hookable file at‐ tributes subcommand. The appropriate function for the filesystem to which pathPtr belongs will be called. If the result is TCL_OK, then a value was placed in objPtrRef, which will only be temporarily valid (unless Tcl_IncrRefCount is called). Tcl_FSFileAttrsSet implements write access for the hookable file at‐ tributes subcommand. The appropriate function for the filesystem to which pathPtr belongs will be called. Tcl_FSFileAttrStrings implements part of the hookable file attributes subcommand. The appropriate function for the filesystem to which path‐ Ptr belongs will be called. The called procedure may either return an array of strings, or may in‐ stead return NULL and place a Tcl list into the given objPtrRef. Tcl will take that list and first increment its reference count before us‐ ing it. On completion of that use, Tcl will decrement its reference count. Hence if the list should be disposed of by Tcl when done, it should have a reference count of zero, and if the list should not be disposed of, the filesystem should ensure it retains a reference count to the value. Tcl_FSAccess checks whether the process would be allowed to read, write or test for existence of the file (or other filesystem object) whose name is pathname. If pathname is a symbolic link on Unix, then permis‐ sions of the file referred by this symbolic link are tested. On success (all requested permissions granted), zero is returned. On error (at least one bit in mode asked for a permission that is denied, or some other error occurred), -1 is returned. Tcl_FSStat fills the Tcl_StatBuf structure statPtr with information about the specified file. You do not need any access rights to the file to get this information but you need search rights to all directories named in the path leading to the file. The Tcl_StatBuf structure in‐ cludes info regarding device, inode (always 0 on Windows), privilege mode, nlink (always 1 on Windows), user id (always 0 on Windows), group id (always 0 on Windows), rdev (same as device on Windows), size, last access time, last modification time, and last metadata change time. See PORTABLE STAT RESULT API for a description of how to write portable code to allocate and access the Tcl_StatBuf structure. If path exists, Tcl_FSStat returns 0 and the stat structure is filled with data. Otherwise, -1 is returned, and no stat info is given. Tcl_FSOpenFileChannel opens a file specified by pathPtr and returns a channel handle that can be used to perform input and output on the file. This API is modeled after the fopen procedure of the Unix stan‐ dard I/O library. The syntax and meaning of all arguments is similar to those given in the Tcl open command when opening a file. If an er‐ ror occurs while opening the channel, Tcl_FSOpenFileChannel returns NULL and records a POSIX error code that can be retrieved with Tcl_GetErrno. In addition, if interp is non-NULL, Tcl_FSOpenFileChan‐ nel leaves an error message in interp's result after any error. The newly created channel is not registered in the supplied inter‐ preter; to register it, use Tcl_RegisterChannel. If one of the stan‐ dard channels, stdin, stdout or stderr was previously closed, the act of creating the new channel also assigns it as a replacement for the standard channel. Tcl_FSGetCwd replaces the library version of getcwd. It returns the Tcl library's current working directory. This may be different to the native platform's working directory, which happens when the current working directory is not in the native filesystem. The result is a pointer to a Tcl_Obj specifying the current directory, or NULL if the current directory could not be determined. If NULL is returned, an error message is left in the interp's result. The result already has its reference count incremented for the caller. When it is no longer needed, that reference count should be decre‐ mented. This is needed for thread-safety purposes, to allow multiple threads to access this and related functions, while ensuring the re‐ sults are always valid. Tcl_FSChdir replaces the library version of chdir. The path is normal‐ ized and then passed to the filesystem which claims it. If that filesystem does not implement this function, Tcl will fallback to a combination of stat and access to check whether the directory exists and has appropriate permissions. For results, see chdir documentation. If successful, we keep a record of the successful path in cwdPathPtr for subsequent calls to Tcl_FS‐ GetCwd. Tcl_FSPathSeparator returns the separator character to be used for most specific element of the path specified by pathPtr (i.e. the last part of the path). The separator is returned as a Tcl_Obj containing a string of length 1. If the path is invalid, NULL is returned. Tcl_FSJoinPath takes the given Tcl_Obj, which must be a valid list (which is allowed to have a reference count of zero), and returns the path value given by considering the first elements elements as valid path segments (each path segment may be a complete path, a partial path or just a single possible directory or file name). If any path segment is actually an absolute path, then all prior path segments are dis‐ carded. If elements is less than 0, we use the entire list. It is possible that the returned value is actually an element of the given list, so the caller should be careful to increment the reference count of the result before freeing the list. The returned value, typically with a reference count of zero (but it could be shared under some conditions), contains the joined path. The caller must add a reference count to the value before using it. In par‐ ticular, the returned value could be an element of the given list, so freeing the list might free the value prematurely if no reference count has been taken. If the number of elements is zero, then the returned value will be an empty-string Tcl_Obj. Tcl_FSSplitPath takes the given Tcl_Obj, which should be a valid path, and returns a Tcl list value containing each segment of that path as an element. It returns a list value with a reference count of zero. If the passed in lenPtr is non-NULL, the variable it points to will be up‐ dated to contain the number of elements in the returned list. Tcl_FSEqualPaths tests whether the two paths given represent the same filesystem object. It returns 1 if the paths are equal, and 0 if they are different. If either path is NULL, 0 is always returned. Tcl_FSGetNormalizedPath attempts to extract from the given Tcl_Obj a unique normalized path representation, whose string value can be used as a unique identifier for the file. It returns the normalized path value, owned by Tcl, or NULL if the path was invalid or could otherwise not be successfully converted. Extrac‐ tion of absolute, normalized paths is very efficient (because the filesystem operates on these representations internally), although the result when the filesystem contains numerous symbolic links may not be the most user-friendly version of a path. The return value is owned by Tcl and has a lifetime equivalent to that of the pathPtr passed in (un‐ less that is a relative path, in which case the normalized path value may be freed any time the cwd changes) - the caller can of course in‐ crement the reference count if it wishes to maintain a copy for longer. Tcl_FSJoinToPath takes the given value, which should usually be a valid path or NULL, and joins onto it the array of paths segments given. Returns a value, typically with reference count of zero (but it could be shared under some conditions), containing the joined path. The caller must add a reference count to the value before using it. If any of the values passed into this function (pathPtr or path elements) have a reference count of zero, they will be freed when this function re‐ turns. Tcl_FSConvertToPathType tries to convert the given Tcl_Obj to a valid Tcl path type, taking account of the fact that the cwd may have changed even if this value is already supposedly of the correct type. The filename may begin with “~” (to indicate current user's home directory) or “~<user>” (to indicate any user's home directory). If the conversion succeeds (i.e. the value is a valid path in one of the current filesystems), then TCL_OK is returned. Otherwise TCL_ERROR is returned, and an error message may be left in the interpreter. Tcl_FSGetInternalRep extracts the internal representation of a given path value, in the given filesystem. If the path value belongs to a different filesystem, we return NULL. If the internal representation is currently NULL, we attempt to generate it, by calling the filesystem's Tcl_FSCreateInternalRepProc. Returns NULL or a valid internal path representation. This internal representation is cached, so that repeated calls to this function will not require additional conversions. Tcl_FSGetTranslatedPath attempts to extract the translated path from the given Tcl_Obj. If the translation succeeds (i.e. the value is a valid path), then it is returned. Otherwise NULL will be returned, and an error message may be left in the interpreter. A “translated” path is one which contains no “~” or “~user” sequences (these have been expanded to their current representation in the filesystem). The value returned is owned by the caller, which must store it or call Tcl_DecrRefCount to ensure memory is freed. This function is of little practical use, and Tcl_FSGetNor‐ malizedPath or Tcl_FSGetNativePath are usually better functions to use for most purposes. Tcl_FSGetTranslatedStringPath does the same as Tcl_FSGetTranslatedPath, but returns a character string or NULL. The string returned is dynami‐ cally allocated and owned by the caller, which must store it or call ckfree to ensure it is freed. Again, Tcl_FSGetNormalizedPath or Tcl_FS‐ GetNativePath are usually better functions to use for most purposes. Tcl_FSNewNativePath performs something like the reverse of the usual obj->path->nativerep conversions. If some code retrieves a path in na‐ tive form (from, e.g. readlink or a native dialog), and that path is to be used at the Tcl level, then calling this function is an efficient way of creating the appropriate path value type. The resulting value is a pure “path” value, which will only receive a UTF-8 string representation if that is required by some Tcl code. Tcl_FSGetNativePath is for use by the Win/Unix native filesystems, so that they can easily retrieve the native (char* or TCHAR*) representa‐ tion of a path. This function is a convenience wrapper around Tcl_FS‐ GetInternalRep. It may be desirable in the future to have non-string- based native representations (for example, on macOS, a representation using a fileSpec of FSRef structure would probably be more efficient). On Windows a full Unicode representation would allow for paths of un‐ limited length. Currently the representation is simply a character string which may contain either the relative path or a complete, abso‐ lute normalized path in the native encoding (complex conditions dictate which of these will be provided, so neither can be relied upon, unless the path is known to be absolute). If you need a native path which must be absolute, then you should ask for the native version of a normalized path. If for some reason a non-absolute, non-normalized version of the path is needed, that must be constructed separately (e.g. using Tcl_FS‐ GetTranslatedPath). The native representation is cached so that repeated calls to this function will not require additional conversions. The return value is owned by Tcl and has a lifetime equivalent to that of the pathPtr passed in (unless that is a relative path, in which case the native representation may be freed any time the cwd changes). Tcl_FSFileSystemInfo returns a list of two elements. The first element is the name of the filesystem (e.g. “native”, “vfs”, “zip”, or “prowrap”, perhaps), and the second is the particular type of the given path within that filesystem (which is filesystem dependent). The second element may be empty if the filesystem does not provide a further cate‐ gorization of files. A valid list value is returned, unless the path value is not recog‐ nized, when NULL will be returned. Tcl_FSGetFileSystemForPath returns a pointer to the Tcl_Filesystem which accepts this path as valid. If no filesystem will accept the path, NULL is returned. Tcl_FSGetPathType determines whether the given path is relative to the current directory, relative to the current volume, or absolute. It returns one of TCL_PATH_ABSOLUTE, TCL_PATH_RELATIVE, or TCL_PATH_VOLUME_RELATIVE PORTABLE STAT RESULT API Tcl_AllocStatBuf allocates a Tcl_StatBuf on the system heap (which may be deallocated by being passed to ckfree). This allows extensions to invoke Tcl_FSStat and Tcl_FSLstat without being dependent on the size of the buffer. That in turn depends on the flags used to build Tcl. The portable fields of a Tcl_StatBuf may be read using the following │ functions, each of which returns the value of the corresponding field │ listed in the table below. Note that on some platforms there may be │ other fields in the Tcl_StatBuf as it is an alias for a suitable system │ structure, but only the portable ones are made available here. See your │ system documentation for a full description of these fields. │ Access Function Field │ Tcl_GetFSDeviceFromStat st_dev │ Tcl_GetFSInodeFromStat st_ino │ Tcl_GetModeFromStat st_mode │ Tcl_GetLinkCountFromStat st_nlink │ Tcl_GetUserIdFromStat st_uid │ Tcl_GetGroupIdFromStat st_gid │ Tcl_GetDeviceTypeFromStat st_rdev │ Tcl_GetAccessTimeFromStat st_atime │ Tcl_GetModificationTimeFromStat st_mtime │ Tcl_GetChangeTimeFromStat st_ctime │ Tcl_GetSizeFromStat st_size │ Tcl_GetBlocksFromStat st_blocks │ Tcl_GetBlockSizeFromStat st_blksize │ THE VIRTUAL FILESYSTEM API A filesystem provides a Tcl_Filesystem structure that contains pointers to functions that implement the various operations on a filesystem; these operations are invoked as needed by the generic layer, which gen‐ erally occurs through the functions listed above. The Tcl_Filesystem structures are manipulated using the following meth‐ ods. Tcl_FSRegister takes a pointer to a filesystem structure and an op‐ tional piece of data to associated with that filesystem. On calling this function, Tcl will attach the filesystem to the list of known filesystems, and it will become fully functional immediately. Tcl does not check if the same filesystem is registered multiple times (and in general that is not a good thing to do). TCL_OK will be returned. Tcl_FSUnregister removes the given filesystem structure from the list of known filesystems, if it is known, and returns TCL_OK. If the filesystem is not currently registered, TCL_ERROR is returned. Tcl_FSData will return the clientData associated with the given filesystem, if that filesystem is registered. Otherwise it will return NULL. Tcl_FSMountsChanged is used to inform the Tcl's core that the set of mount points for the given (already registered) filesystem have changed, and that cached file representations may therefore no longer be correct. THE TCL_FILESYSTEM STRUCTURE The Tcl_Filesystem structure contains the following fields: typedef struct Tcl_Filesystem { const char *typeName; int structureLength; Tcl_FSVersion version; Tcl_FSPathInFilesystemProc *pathInFilesystemProc; Tcl_FSDupInternalRepProc *dupInternalRepProc; Tcl_FSFreeInternalRepProc *freeInternalRepProc; Tcl_FSInternalToNormalizedProc *internalToNormalizedProc; Tcl_FSCreateInternalRepProc *createInternalRepProc; Tcl_FSNormalizePathProc *normalizePathProc; Tcl_FSFilesystemPathTypeProc *filesystemPathTypeProc; Tcl_FSFilesystemSeparatorProc *filesystemSeparatorProc; Tcl_FSStatProc *statProc; Tcl_FSAccessProc *accessProc; Tcl_FSOpenFileChannelProc *openFileChannelProc; Tcl_FSMatchInDirectoryProc *matchInDirectoryProc; Tcl_FSUtimeProc *utimeProc; Tcl_FSLinkProc *linkProc; Tcl_FSListVolumesProc *listVolumesProc; Tcl_FSFileAttrStringsProc *fileAttrStringsProc; Tcl_FSFileAttrsGetProc *fileAttrsGetProc; Tcl_FSFileAttrsSetProc *fileAttrsSetProc; Tcl_FSCreateDirectoryProc *createDirectoryProc; Tcl_FSRemoveDirectoryProc *removeDirectoryProc; Tcl_FSDeleteFileProc *deleteFileProc; Tcl_FSCopyFileProc *copyFileProc; Tcl_FSRenameFileProc *renameFileProc; Tcl_FSCopyDirectoryProc *copyDirectoryProc; Tcl_FSLstatProc *lstatProc; Tcl_FSLoadFileProc *loadFileProc; Tcl_FSGetCwdProc *getCwdProc; Tcl_FSChdirProc *chdirProc; } Tcl_Filesystem; Except for the first three fields in this structure which contain sim‐ ple data elements, all entries contain addresses of functions called by the generic filesystem layer to perform the complete range of filesys‐ tem related actions. The many functions in this structure are broken down into three cate‐ gories: infrastructure functions (almost all of which must be imple‐ mented), operational functions (which must be implemented if a complete filesystem is provided), and efficiency functions (which need only be implemented if they can be done so efficiently, or if they have side- effects which are required by the filesystem; Tcl has less efficient emulations it can fall back on). It is important to note that, in the current version of Tcl, most of these fallbacks are only used to handle commands initiated in Tcl, not in C. What this means is, that if a file rename command is issued in Tcl, and the relevant filesystem(s) do not implement their Tcl_FSRenameFileProc, Tcl's core will instead fallback on a combination of other filesystem functions (it will use Tcl_FSCopy‐ FileProc followed by Tcl_FSDeleteFileProc, and if Tcl_FSCopyFileProc is not implemented there is a further fallback). However, if a Tcl_FSRe‐ nameFileProc command is issued at the C level, no such fallbacks occur. This is true except for the last four entries in the filesystem table (lstat, load, getcwd and chdir) for which fallbacks do in fact occur at the C level. Any functions which take path names in Tcl_Obj form take those names in UTF-8 form. The filesystem infrastructure API is designed to support efficient, cached conversion of these UTF-8 paths to other native rep‐ resentations. EXAMPLE FILESYSTEM DEFINITION Here is the filesystem lookup table used by the “vfs” extension which allows filesystem actions to be implemented in Tcl. static Tcl_Filesystem vfsFilesystem = { "tclvfs", sizeof(Tcl_Filesystem), TCL_FILESYSTEM_VERSION_1, &VfsPathInFilesystem, &VfsDupInternalRep, &VfsFreeInternalRep, /* No internal to normalized, since we don't create * any pure 'internal' Tcl_Obj path representations */ NULL, /* No create native rep function, since we don't use * it and don't choose to support uses of * Tcl_FSNewNativePath */ NULL, /* Normalize path isn't needed - we assume paths only * have one representation */ NULL, &VfsFilesystemPathType, &VfsFilesystemSeparator, &VfsStat, &VfsAccess, &VfsOpenFileChannel, &VfsMatchInDirectory, &VfsUtime, /* We choose not to support symbolic links inside our * VFS's */ NULL, &VfsListVolumes, &VfsFileAttrStrings, &VfsFileAttrsGet, &VfsFileAttrsSet, &VfsCreateDirectory, &VfsRemoveDirectory, &VfsDeleteFile, /* No copy file; use the core fallback mechanism */ NULL, /* No rename file; use the core fallback mechanism */ NULL, /* No copy directory; use the core fallback mechanism */ NULL, /* Core will use stat for lstat */ NULL, /* No load; use the core fallback mechanism */ NULL, /* We don't need a getcwd or chdir; the core's own * internal value is suitable */ NULL, NULL }; FILESYSTEM INFRASTRUCTURE These fields contain basic information about the filesystem structure and addresses of functions which are used to associate a particular filesystem with a file path, and deal with the internal handling of path representations, for example copying and freeing such representa‐ tions. TYPENAME The typeName field contains a null-terminated string that identifies the type of the filesystem implemented, e.g. “native”, “zip” or “vfs”. STRUCTURE LENGTH The structureLength field is generally implemented as sizeof(Tcl_Filesystem), and is there to allow easier binary backwards compatibility if the size of the structure changes in a future Tcl re‐ lease. VERSION The version field should be set to TCL_FILESYSTEM_VERSION_1. PATHINFILESYSTEMPROC The pathInFilesystemProc field contains the address of a function which is called to determine whether a given path value belongs to this filesystem or not. Tcl will only call the rest of the filesystem func‐ tions with a path for which this function has returned TCL_OK. If the path does not belong, -1 should be returned (the behavior of Tcl for any other return value is not defined). If TCL_OK is returned, then the optional clientDataPtr output parameter can be used to return an inter‐ nal (filesystem specific) representation of the path, which will be cached inside the path value, and may be retrieved efficiently by the other filesystem functions. Tcl will simultaneously cache the fact that this path belongs to this filesystem. Such caches are invalidated when filesystem structures are added or removed from Tcl's internal list of known filesystems. typedef int Tcl_FSPathInFilesystemProc( Tcl_Obj *pathPtr, ClientData *clientDataPtr); DUPINTERNALREPPROC This function makes a copy of a path's internal representation, and is called when Tcl needs to duplicate a path value. If NULL, Tcl will sim‐ ply not copy the internal representation, which may then need to be re‐ generated later. typedef ClientData Tcl_FSDupInternalRepProc( ClientData clientData); FREEINTERNALREPPROC Free the internal representation. This must be implemented if internal representations need freeing (i.e. if some memory is allocated when an internal representation is generated), but may otherwise be NULL. typedef void Tcl_FSFreeInternalRepProc( ClientData clientData); INTERNALTONORMALIZEDPROC Function to convert internal representation to a normalized path. Only required if the filesystem creates pure path values with no string/path representation. The return value is a Tcl value whose string represen‐ tation is the normalized path. typedef Tcl_Obj *Tcl_FSInternalToNormalizedProc( ClientData clientData); CREATEINTERNALREPPROC Function to take a path value, and calculate an internal representation for it, and store that native representation in the value. May be NULL if paths have no internal representation, or if the Tcl_FSPathIn‐ FilesystemProc for this filesystem always immediately creates an inter‐ nal representation for paths it accepts. typedef ClientData Tcl_FSCreateInternalRepProc( Tcl_Obj *pathPtr); NORMALIZEPATHPROC Function to normalize a path. Should be implemented for all filesystems which can have multiple string representations for the same path value. In Tcl, every “path” must have a single unique “normalized” string rep‐ resentation. Depending on the filesystem, there may be more than one unnormalized string representation which refers to that path (e.g. a relative path, a path with different character case if the filesystem is case insensitive, a path contain a reference to a home directory such as “~”, a path containing symbolic links, etc). If the very last component in the path is a symbolic link, it should not be converted into the value it points to (but its case or other aspects should be made unique). All other path components should be converted from sym‐ bolic links. This one exception is required to agree with Tcl's seman‐ tics with file delete, file rename, file copy operating on symbolic links. This function may be called with nextCheckpoint either at the beginning of the path (i.e. zero), at the end of the path, or at any intermediate file separator in the path. It will never point to any other arbitrary position in the path. In the last of the three valid cases, the implementation can assume that the path up to and including the file separator is known and normalized. typedef int Tcl_FSNormalizePathProc( Tcl_Interp *interp, Tcl_Obj *pathPtr, int nextCheckpoint); FILESYSTEM OPERATIONS The fields in this section of the structure contain addresses of func‐ tions which are called to carry out the basic filesystem operations. A filesystem which expects to be used with the complete standard Tcl com‐ mand set must implement all of these. If some of them are not imple‐ mented, then certain Tcl commands may fail when operating on paths within that filesystem. However, in some instances this may be desir‐ able (for example, a read-only filesystem should not implement the last four functions, and a filesystem which does not support symbolic links need not implement the readlink function, etc. The Tcl core expects filesystems to behave in this way). FILESYSTEMPATHTYPEPROC Function to determine the type of a path in this filesystem. May be NULL, in which case no type information will be available to users of the filesystem. The “type” is used only for informational purposes, and should be returned as the string representation of the Tcl_Obj which is returned. A typical return value might be “networked”, “zip” or “ftp”. The Tcl_Obj result is owned by the filesystem and so Tcl will increment the reference count of that value if it wishes to retain a reference to it. typedef Tcl_Obj *Tcl_FSFilesystemPathTypeProc( Tcl_Obj *pathPtr); FILESYSTEMSEPARATORPROC Function to return the separator character(s) for this filesystem. This need only be implemented if the filesystem wishes to use a differ‐ ent separator than the standard string “/”. Amongst other uses, it is returned by the file separator command. The return value should be a value with reference count of zero. typedef Tcl_Obj *Tcl_FSFilesystemSeparatorProc( Tcl_Obj *pathPtr); STATPROC Function to process a Tcl_FSStat call. Must be implemented for any rea‐ sonable filesystem, since many Tcl level commands depend crucially upon it (e.g. file atime, file isdirectory, file size, glob). typedef int Tcl_FSStatProc( Tcl_Obj *pathPtr, Tcl_StatBuf *statPtr); The Tcl_FSStatProc fills the stat structure statPtr with information about the specified file. You do not need any access rights to the file to get this information but you need search rights to all directories named in the path leading to the file. The stat structure includes info regarding device, inode (always 0 on Windows), privilege mode, nlink (always 1 on Windows), user id (always 0 on Windows), group id (always 0 on Windows), rdev (same as device on Windows), size, last access time, last modification time, and last metadata change time. If the file represented by pathPtr exists, the Tcl_FSStatProc returns 0 and the stat structure is filled with data. Otherwise, -1 is returned, and no stat info is given. ACCESSPROC Function to process a Tcl_FSAccess call. Must be implemented for any reasonable filesystem, since many Tcl level commands depend crucially upon it (e.g. file exists, file readable). typedef int Tcl_FSAccessProc( Tcl_Obj *pathPtr, int mode); The Tcl_FSAccessProc checks whether the process would be allowed to read, write or test for existence of the file (or other filesystem ob‐ ject) whose name is in pathPtr. If the pathname refers to a symbolic link, then the permissions of the file referred by this symbolic link should be tested. On success (all requested permissions granted), zero is returned. On error (at least one bit in mode asked for a permission that is denied, or some other error occurred), -1 is returned. OPENFILECHANNELPROC Function to process a Tcl_FSOpenFileChannel call. Must be implemented for any reasonable filesystem, since any operations which require open or accessing a file's contents will use it (e.g. open, encoding, and many Tk commands). typedef Tcl_Channel Tcl_FSOpenFileChannelProc( Tcl_Interp *interp, Tcl_Obj *pathPtr, int mode, int permissions); The Tcl_FSOpenFileChannelProc opens a file specified by pathPtr and re‐ turns a channel handle that can be used to perform input and output on the file. This API is modeled after the fopen procedure of the Unix standard I/O library. The syntax and meaning of all arguments is simi‐ lar to those given in the Tcl open command when opening a file, where the mode argument is a combination of the POSIX flags O_RDONLY, O_WRONLY, etc. If an error occurs while opening the channel, the Tcl_FSOpenFileChannelProc returns NULL and records a POSIX error code that can be retrieved with Tcl_GetErrno. In addition, if interp is non-NULL, the Tcl_FSOpenFileChannelProc leaves an error message in in‐ terp's result after any error. The newly created channel must not be registered in the supplied inter‐ preter by a Tcl_FSOpenFileChannelProc; that task is up to the caller of Tcl_FSOpenFileChannel (if necessary). If one of the standard channels, stdin, stdout or stderr was previously closed, the act of creating the new channel also assigns it as a replacement for the standard channel. MATCHINDIRECTORYPROC Function to process a Tcl_FSMatchInDirectory call. If not implemented, then glob and recursive copy functionality will be lacking in the filesystem (and this may impact commands like encoding names which use glob functionality internally). typedef int Tcl_FSMatchInDirectoryProc( Tcl_Interp *interp, Tcl_Obj *resultPtr, Tcl_Obj *pathPtr, const char *pattern, Tcl_GlobTypeData *types); The function should return all files or directories (or other filesys‐ tem objects) which match the given pattern and accord with the types specification given. There are two ways in which this function may be called. If pattern is NULL, then pathPtr is a full path specification of a single file or directory which should be checked for existence and correct type. Otherwise, pathPtr is a directory, the contents of which the function should search for files or directories which have the cor‐ rect type. In either case, pathPtr can be assumed to be both non-NULL and non-empty. It is not currently documented whether pathPtr will have a file separator at its end of not, so code should be flexible to both possibilities. The return value is a standard Tcl result indicating whether an error occurred in the matching process. Error messages are placed in interp, unless interp in NULL in which case no error message need be generated; on a TCL_OK result, results should be added to the resultPtr value given (which can be assumed to be a valid unshared Tcl list). The matches added to resultPtr should include any path prefix given in pathPtr (this usually means they will be absolute path specifications). Note that if no matches are found, that simply leads to an empty re‐ sult; errors are only signaled for actual file or filesystem problems which may occur during the matching process. The Tcl_GlobTypeData structure passed in the types parameter contains the following fields: typedef struct Tcl_GlobTypeData { /* Corresponds to bcdpfls as in 'find -t' */ int type; /* Corresponds to file permissions */ int perm; /* Acceptable mac type */ Tcl_Obj *macType; /* Acceptable mac creator */ Tcl_Obj *macCreator; } Tcl_GlobTypeData; There are two specific cases which it is important to handle correctly, both when types is non-NULL. The two cases are when types->types & TCL_GLOB_TYPE_DIR or types->types & TCL_GLOB_TYPE_MOUNT are true (and in particular when the other flags are false). In the first of these cases, the function must list the contained directories. Tcl uses this to implement recursive globbing, so it is critical that filesystems im‐ plement directory matching correctly. In the second of these cases, with TCL_GLOB_TYPE_MOUNT, the filesystem must list the mount points which lie within the given pathPtr (and in this case, pathPtr need not lie within the same filesystem - different to all other cases in which this function is called). Support for this is critical if Tcl is to have seamless transitions between from one filesystem to another. UTIMEPROC Function to process a Tcl_FSUtime call. Required to allow setting (not reading) of times with file mtime, file atime and the open-r/open- w/fcopy implementation of file copy. typedef int Tcl_FSUtimeProc( Tcl_Obj *pathPtr, struct utimbuf *tval); The access and modification times of the file specified by pathPtr should be changed to the values given in the tval structure. The return value should be 0 on success and -1 on an error, as with the system utime. LINKPROC Function to process a Tcl_FSLink call. Should be implemented only if the filesystem supports links, and may otherwise be NULL. typedef Tcl_Obj *Tcl_FSLinkProc( Tcl_Obj *linkNamePtr, Tcl_Obj *toPtr, int linkAction); If toPtr is NULL, the function is being asked to read the contents of a link. The result is a Tcl_Obj specifying the contents of the link given by linkNamePtr, or NULL if the link could not be read. The result is owned by the caller (and should therefore have its ref count incre‐ mented before being returned). Any callers should call Tcl_DecrRefCount on this result when it is no longer needed. If toPtr is not NULL, the function should attempt to create a link. The result in this case should be toPtr if the link was successful and NULL otherwise. In this case the result is not owned by the caller (i.e. no reference count ma‐ nipulations on either end are needed). See the documentation for Tcl_FSLink for the correct interpretation of the linkAction flags. LISTVOLUMESPROC Function to list any filesystem volumes added by this filesystem. Should be implemented only if the filesystem adds volumes at the head of the filesystem, so that they can be returned by file volumes. typedef Tcl_Obj *Tcl_FSListVolumesProc(void); The result should be a list of volumes added by this filesystem, or NULL (or an empty list) if no volumes are provided. The result value is considered to be owned by the filesystem (not by Tcl's core), but should be given a reference count for Tcl. Tcl will use the contents of the list and then decrement that reference count. This allows filesys‐ tems to choose whether they actually want to retain a “global list” of volumes or not (if not, they generate the list on the fly and pass it to Tcl with a reference count of 1 and then forget about the list, if yes, then they simply increment the reference count of their global list and pass it to Tcl which will copy the contents and then decrement the count back to where it was). Therefore, Tcl considers return values from this proc to be read-only. FILEATTRSTRINGSPROC Function to list all attribute strings which are valid for this filesystem. If not implemented the filesystem will not support the file attributes command. This allows arbitrary additional information to be attached to files in the filesystem. If it is not implemented, there is no need to implement the get and set methods. typedef const char *const *Tcl_FSFileAttrStringsProc( Tcl_Obj *pathPtr, Tcl_Obj **objPtrRef); The called function may either return an array of strings, or may in‐ stead return NULL and place a Tcl list into the given objPtrRef. Tcl will take that list and first increment its reference count before us‐ ing it. On completion of that use, Tcl will decrement its reference count. Hence if the list should be disposed of by Tcl when done, it should have a reference count of zero, and if the list should not be disposed of, the filesystem should ensure it returns a value with a reference count of at least one. FILEATTRSGETPROC Function to process a Tcl_FSFileAttrsGet call, used by file attributes. typedef int Tcl_FSFileAttrsGetProc( Tcl_Interp *interp, int index, Tcl_Obj *pathPtr, Tcl_Obj **objPtrRef); Returns a standard Tcl return code. The attribute value retrieved, which corresponds to the index'th element in the list returned by the Tcl_FSFileAttrStringsProc, is a Tcl_Obj placed in objPtrRef (if TCL_OK was returned) and is likely to have a reference count of zero. Either way we must either store it somewhere (e.g. the Tcl result), or Incr/Decr its reference count to ensure it is properly freed. FILEATTRSSETPROC Function to process a Tcl_FSFileAttrsSet call, used by file attributes. If the filesystem is read-only, there is no need to implement this. typedef int Tcl_FSFileAttrsSetProc( Tcl_Interp *interp, int index, Tcl_Obj *pathPtr, Tcl_Obj *objPtr); The attribute value of the index'th element in the list returned by the Tcl_FSFileAttrStringsProc should be set to the objPtr given. CREATEDIRECTORYPROC Function to process a Tcl_FSCreateDirectory call. Should be implemented unless the FS is read-only. typedef int Tcl_FSCreateDirectoryProc( Tcl_Obj *pathPtr); The return value is a standard Tcl result indicating whether an error occurred in the process. If successful, a new directory should have been added to the filesystem in the location specified by pathPtr. REMOVEDIRECTORYPROC Function to process a Tcl_FSRemoveDirectory call. Should be implemented unless the FS is read-only. typedef int Tcl_FSRemoveDirectoryProc( Tcl_Obj *pathPtr, int recursive, Tcl_Obj **errorPtr); The return value is a standard Tcl result indicating whether an error occurred in the process. If successful, the directory specified by pathPtr should have been removed from the filesystem. If the recursive flag is given, then a non-empty directory should be deleted without er‐ ror. If this flag is not given, then and the directory is non-empty a POSIX “EEXIST” error should be signaled. If an error does occur, the name of the file or directory which caused the error should be placed in errorPtr. DELETEFILEPROC Function to process a Tcl_FSDeleteFile call. Should be implemented un‐ less the FS is read-only. typedef int Tcl_FSDeleteFileProc( Tcl_Obj *pathPtr); The return value is a standard Tcl result indicating whether an error occurred in the process. If successful, the file specified by pathPtr should have been removed from the filesystem. Note that, if the filesystem supports symbolic links, Tcl will always call this function and not Tcl_FSRemoveDirectoryProc when needed to delete them (even if they are symbolic links to directories). FILESYSTEM EFFICIENCY These functions need not be implemented for a particular filesystem be‐ cause the core has a fallback implementation available. See each indi‐ vidual description for the consequences of leaving the field NULL. LSTATPROC Function to process a Tcl_FSLstat call. If not implemented, Tcl will attempt to use the statProc defined above instead. Therefore it need only be implemented if a filesystem can differentiate between stat and lstat calls. typedef int Tcl_FSLstatProc( Tcl_Obj *pathPtr, Tcl_StatBuf *statPtr); The behavior of this function is very similar to that of the Tcl_FSStatProc defined above, except that if it is applied to a sym‐ bolic link, it returns information about the link, not about the target file. COPYFILEPROC Function to process a Tcl_FSCopyFile call. If not implemented Tcl will fall back on open-r, open-w and fcopy as a copying mechanism. There‐ fore it need only be implemented if the filesystem can perform that ac‐ tion more efficiently. typedef int Tcl_FSCopyFileProc( Tcl_Obj *srcPathPtr, Tcl_Obj *destPathPtr); The return value is a standard Tcl result indicating whether an error occurred in the copying process. Note that, destPathPtr is the name of the file which should become the copy of srcPathPtr. It is never the name of a directory into which srcPathPtr could be copied (i.e. the function is much simpler than the Tcl level file copy subcommand). Note that, if the filesystem supports symbolic links, Tcl will always call this function and not copyDirectoryProc when needed to copy them (even if they are symbolic links to directories). Finally, if the filesystem determines it cannot support the file copy action, calling Tcl_SetEr‐ rno(EXDEV) and returning a non-TCL_OK result will tell Tcl to use its standard fallback mechanisms. RENAMEFILEPROC Function to process a Tcl_FSRenameFile call. If not implemented, Tcl will fall back on a copy and delete mechanism. Therefore it need only be implemented if the filesystem can perform that action more effi‐ ciently. typedef int Tcl_FSRenameFileProc( Tcl_Obj *srcPathPtr, Tcl_Obj *destPathPtr); The return value is a standard Tcl result indicating whether an error occurred in the renaming process. If the filesystem determines it can‐ not support the file rename action, calling Tcl_SetErrno(EXDEV) and re‐ turning a non-TCL_OK result will tell Tcl to use its standard fallback mechanisms. COPYDIRECTORYPROC Function to process a Tcl_FSCopyDirectory call. If not implemented, Tcl will fall back on a recursive file mkdir, file copy mechanism. There‐ fore it need only be implemented if the filesystem can perform that ac‐ tion more efficiently. typedef int Tcl_FSCopyDirectoryProc( Tcl_Obj *srcPathPtr, Tcl_Obj *destPathPtr, Tcl_Obj **errorPtr); The return value is a standard Tcl result indicating whether an error occurred in the copying process. If an error does occur, the name of the file or directory which caused the error should be placed in er‐ rorPtr. Note that, destPathPtr is the name of the directory-name which should become the mirror-image of srcPathPtr. It is not the name of a directory into which srcPathPtr should be copied (i.e. the function is much simpler than the Tcl level file copy subcommand). Finally, if the filesystem determines it cannot support the directory copy action, calling Tcl_SetErrno(EXDEV) and returning a non-TCL_OK result will tell Tcl to use its standard fallback mechanisms. LOADFILEPROC Function to process a Tcl_FSLoadFile call. If not implemented, Tcl will fall back on a copy to native-temp followed by a Tcl_FSLoadFile on that temporary copy. Therefore it need only be implemented if the filesystem can load code directly, or it can be implemented simply to return TCL_ERROR to disable load functionality in this filesystem entirely. typedef int Tcl_FSLoadFileProc( Tcl_Interp *interp, Tcl_Obj *pathPtr, Tcl_LoadHandle *handlePtr, Tcl_FSUnloadFileProc *unloadProcPtr); Returns a standard Tcl completion code. If an error occurs, an error message is left in the interp's result. The function dynamically loads a binary code file into memory. On a successful load, the handlePtr should be filled with a token for the dynamically loaded file, and the unloadProcPtr should be filled in with the address of a procedure. The unload procedure will be called with the given Tcl_LoadHandle as its only parameter when Tcl needs to unload the file. For example, for the native filesystem, the Tcl_LoadHandle returned is currently a token which can be used in the private TclpFindSymbol to access functions in the new code. Each filesystem is free to define the Tcl_LoadHandle as it requires. Finally, if the filesystem determines it cannot support the file load action, calling Tcl_SetErrno(EXDEV) and returning a non- TCL_OK result will tell Tcl to use its standard fallback mechanisms. UNLOADFILEPROC Function to unload a previously successfully loaded file. If load was implemented, then this should also be implemented, if there is any cleanup action required. typedef void Tcl_FSUnloadFileProc( Tcl_LoadHandle loadHandle); GETCWDPROC Function to process a Tcl_FSGetCwd call. Most filesystems need not im‐ plement this. It will usually only be called once, if getcwd is called before chdir. May be NULL. typedef Tcl_Obj *Tcl_FSGetCwdProc( Tcl_Interp *interp); If the filesystem supports a native notion of a current working direc‐ tory (which might perhaps change independent of Tcl), this function should return that cwd as the result, or NULL if the current directory could not be determined (e.g. the user does not have appropriate per‐ missions on the cwd directory). If NULL is returned, an error message is left in the interp's result. CHDIRPROC Function to process a Tcl_FSChdir call. If filesystems do not implement this, it will be emulated by a series of directory access checks. Oth‐ erwise, virtual filesystems which do implement it need only respond with a positive return result if the pathPtr is a valid, accessible di‐ rectory in their filesystem. They need not remember the result, since that will be automatically remembered for use by Tcl_FSGetCwd. Real filesystems should carry out the correct action (i.e. call the correct system chdir API). typedef int Tcl_FSChdirProc( Tcl_Obj *pathPtr); The Tcl_FSChdirProc changes the applications current working directory to the value specified in pathPtr. The function returns -1 on error or 0 on success. SEE ALSO cd(n), file(n), filename(n), load(n), open(n), pwd(n), source(n), un‐ load(n) KEYWORDS stat, access, filesystem, vfs, virtual filesystem Tcl 8.4 Filesystem(3)
Filesystem(3) Процедуры библиотеки Tcl Filesystem(3) ______________________________________________________________________________ НАЗВАНИЕ Tcl_FSRegister, Tcl_FSUnregister, Tcl_FSData, Tcl_FSMountsChanged, Tcl_FSGetFileSystemForPath, Tcl_FSGetPathType, Tcl_FSCopyFile, Tcl_FS‐ CopyDirectory, Tcl_FSCreateDirectory, Tcl_FSDeleteFile, Tcl_FSRemoveDi‐ rectory, Tcl_FSRenameFile, Tcl_FSListVolumes, Tcl_FSEvalFile, Tcl_FSE‐ valFileEx, Tcl_FSLoadFile, Tcl_FSUnloadFile, Tcl_FSMatchInDirectory, Tcl_FSLink, Tcl_FSLstat, Tcl_FSUtime, Tcl_FSFileAttrsGet, Tcl_FSFileAt‐ trsSet, Tcl_FSFileAttrStrings, Tcl_FSStat, Tcl_FSAccess, Tcl_FSOpen‐ FileChannel, Tcl_FSGetCwd, Tcl_FSChdir, Tcl_FSPathSeparator, Tcl_FSJoinPath, Tcl_FSSplitPath, Tcl_FSEqualPaths, Tcl_FSGetNormalized‐ Path, Tcl_FSJoinToPath, Tcl_FSConvertToPathType, Tcl_FSGetInternalRep, Tcl_FSGetTranslatedPath, Tcl_FSGetTranslatedStringPath, Tcl_FSNewNa‐ tivePath, Tcl_FSGetNativePath, Tcl_FSFileSystemInfo, Tcl_GetAccessTime‐ FromStat, Tcl_GetBlockSizeFromStat, Tcl_GetBlocksFromStat, Tcl_GetChangeTimeFromStat, Tcl_GetDeviceTypeFromStat, Tcl_GetFSDevice‐ FromStat, Tcl_GetFSInodeFromStat, Tcl_GetGroupIdFromStat, Tcl_GetLinkCountFromStat, Tcl_GetModeFromStat, Tcl_GetModificationTime‐ FromStat, Tcl_GetSizeFromStat, Tcl_GetUserIdFromStat, Tcl_AllocStatBuf - процедуры для взаимодействия с любой файловой системой СИНОПСИС #include <tcl.h> int Tcl_FSRegister(clientData, fsPtr) int Tcl_FSUnregister(fsPtr) void * Tcl_FSData(fsPtr) Tcl_FSMountsChanged(fsPtr) const Tcl_Filesystem * Tcl_FSGetFileSystemForPath(pathPtr) Tcl_PathType Tcl_FSGetPathType(pathPtr) int Tcl_FSCopyFile(srcPathPtr, destPathPtr) int Tcl_FSCopyDirectory(srcPathPtr, destPathPtr, errorPtr) int Tcl_FSCreateDirectory(pathPtr) int Tcl_FSDeleteFile(pathPtr) int Tcl_FSRemoveDirectory(pathPtr, recursive, errorPtr) int Tcl_FSRenameFile(srcPathPtr, destPathPtr) Tcl_Obj * Tcl_FSListVolumes(void) int Tcl_FSEvalFileEx(interp, pathPtr, encodingName) int Tcl_FSEvalFile(interp, pathPtr) int Tcl_FSLoadFile(interp, pathPtr, sym1, sym2, proc1Ptr, proc2Ptr, loadHandlePtr, unloadProcPtr) int │ Tcl_FSUnloadFile(interp, loadHandle) │ int Tcl_FSMatchInDirectory(interp, resultPtr, pathPtr, pattern, types) Tcl_Obj * Tcl_FSLink(linkNamePtr, toPtr, linkAction) int Tcl_FSLstat(pathPtr, statPtr) int Tcl_FSUtime(pathPtr, tval) int Tcl_FSFileAttrsGet(interp, index, pathPtr, objPtrRef) int Tcl_FSFileAttrsSet(interp, index, pathPtr, objPtr) const char *const * Tcl_FSFileAttrStrings(pathPtr, objPtrRef) int Tcl_FSStat(pathPtr, statPtr) int Tcl_FSAccess(pathPtr, mode) Tcl_Channel Tcl_FSOpenFileChannel(interp, pathPtr, modeString, permissions) Tcl_Obj * Tcl_FSGetCwd(interp) int Tcl_FSChdir(pathPtr) Tcl_Obj * Tcl_FSPathSeparator(pathPtr) Tcl_Obj * Tcl_FSJoinPath(listObj, elements) Tcl_Obj * Tcl_FSSplitPath(pathPtr, lenPtr) int Tcl_FSEqualPaths(firstPtr, secondPtr) Tcl_Obj * Tcl_FSGetNormalizedPath(interp, pathPtr) Tcl_Obj * Tcl_FSJoinToPath(basePtr, objc, objv) int Tcl_FSConvertToPathType(interp, pathPtr) void * Tcl_FSGetInternalRep(pathPtr, fsPtr) Tcl_Obj * Tcl_FSGetTranslatedPath(interp, pathPtr) const char * Tcl_FSGetTranslatedStringPath(interp, pathPtr) Tcl_Obj * Tcl_FSNewNativePath(fsPtr, clientData) const void * Tcl_FSGetNativePath(pathPtr) Tcl_Obj * Tcl_FSFileSystemInfo(pathPtr) Tcl_StatBuf * Tcl_AllocStatBuf() Tcl_WideInt │ Tcl_GetAccessTimeFromStat(statPtr) │ unsigned │ Tcl_GetBlockSizeFromStat(statPtr) │ Tcl_WideUInt │ Tcl_GetBlocksFromStat(statPtr) │ Tcl_WideInt │ Tcl_GetChangeTimeFromStat(statPtr) │ int │ Tcl_GetDeviceTypeFromStat(statPtr) │ unsigned │ Tcl_GetFSDeviceFromStat(statPtr) │ unsigned │ Tcl_GetFSInodeFromStat(statPtr) │ int │ Tcl_GetGroupIdFromStat(statPtr) │ int │ Tcl_GetLinkCountFromStat(statPtr) │ unsigned │ Tcl_GetModeFromStat(statPtr) │ Tcl_WideInt │ Tcl_GetModificationTimeFromStat(statPtr) │ Tcl_WideUInt │ Tcl_GetSizeFromStat(statPtr) │ int │ Tcl_GetUserIdFromStat(statPtr) │ АРГУМЕНТЫ const Tcl_Filesystem *fsPtr (in) Указатель на структуру, содер‐ жащую адреса процедур, которые могут быть вызваны для выпол‐ нения различных операций над файловой системой. Tcl_Obj *pathPtr (in) Путь, представленный этим зна‐ чением, используется для опе‐ рации в вопросе. Если значение не имеет внутренней представ‐ ления пути, оно будет преоб‐ разовано в него. Tcl_Obj *srcPathPtr (in) Как для pathPtr, но использую‐ щееся для исходного файла для операции копирования или пе‐ реименования. Tcl_Obj *destPathPtr (in) Как для pathPtr, но использую‐ щееся для имени файла назна‐ чения для операции копирова‐ ния или переименования. int recursive (in) Указывает, следует ли удалять поддиректории и их содержимое тоже. const char *encodingName (in) Кодировка данных, хранящихся в файле, идентифицируемом по pa‐ thPtr, и подлежащих оценке. const char *pattern (in) Будут возвращены только файлы или директории, соответствующие этому шаблону. Tcl_GlobTypeData *types (in) Будут возвращены только файлы или директории, соответствующие описаниям типов, содержащимся в этой структуре. Этот параметр может быть NULL. Tcl_Interp *interp (in) Интерпретатор, используемый для результатов, оценки или сооб‐ щения об ошибках. void *clientData (in) Родное описание значения пути для создания. Tcl_Obj *firstPtr (in) Первый из двух путей для срав‐ нения. Значение может быть пре‐ образовано в тип пути. Tcl_Obj *secondPtr (in) Второй из двух путей для срав‐ нения. Значение может быть пре‐ образовано в тип пути. Tcl_Obj *listObj (in) Список элементов пути для опе‐ рации объединения. int elements (in) Количество элементов в listObj, которые должны быть объединены. Если отрицательное, то все эле‐ менты объединены. Tcl_Obj **errorPtr (out) В случае ошибки заполняется зна‐ чением, содержащим имя файла, который вызвал ошибку в раз‐ личных операциях копирования/ переименования. int index (in) Индекс атрибута в вопросе. Tcl_Obj *objPtr (in) Значение для установки в опе‐ рации. Tcl_Obj **objPtrRef (out) Заполняется значением, содержа‐ щим результат операции. Tcl_Obj *resultPtr (out) Предварительно выделенное зна‐ чение, в котором хранится (с по‐ мощью Tcl_ListObjAppendElement) список файлов или директорий, которые успешно совпали. int mode (in) Маска, состоящая из одного или более из R_OK, W_OK, X_OK и F_OK. R_OK, W_OK и X_OK запрашивают проверку, существует ли файл и имеет ли он права на чтение, запись и выполнение соответст‐ венно. F_OK запрашивает только проверку существования файла. Tcl_StatBuf *statPtr (out) Структура, содержащая результат операции stat или lstat. const char *sym1 (in) Имя процедуры для поиска в сим‐ вольной таблице файла. const char *sym2 (in) Имя процедуры для поиска в сим‐ вольной таблице файла. Tcl_PackageInitProc **proc1Ptr (out) Заполняется функцией инициали‐ зации для этого кода. Tcl_PackageInitProc **proc2Ptr (out) Заполняется функцией безопасной инициализации для этого кода. void **clientDataPtr (out) Заполняется значением clientData, которое будет передано функ‐ ции выгрузки этого кода, когда она будет вызвана. Tcl_LoadHandle *loadHandlePtr (out) Заполняется абстрактным токеном, представляющим загруженный файл. Tcl_FSUnloadFileProc **unloadProcPtr (out) Заполняется функцией для вы‐ грузки этого кода. Tcl_LoadHandle loadHandle (in) Дескриптор загруженной библио‐ теки для выгрузки. utimbuf *tval (in) В этой структуре содержатся вре‐ мя доступа и изменения, которые читаются и используются для установки этих значений для данного файла. const char *modeString (in) Указывает, как файл должен быть открыт. Может иметь любые зна‐ чения, допустимые для аргумента mode в команде Tcl open. int permissions (in) Флаги разрешений в стиле POSIX, такие как 0644. Если создается новый файл, эти разрешения бу‐ дут установлены на созданном файле. int *lenPtr (out) Если не NULL, заполняется коли‐ чеством элементов в разбитом пути. Tcl_Obj *basePtr (in) Базовый путь, к которому сле‐ дует присоединить указанные элементы. Может быть NULL. int objc (in) Количество элементов в objv. Tcl_Obj *const objv[] (in) Элементы для присоединения к указанному базовому пути. Tcl_Obj *linkNamePtr (in) Имя ссылки, которую нужно со‐ здать или прочитать. Tcl_Obj *toPtr (in) То, на что должна ссылаться ссылка с именем linkNamePtr, или NULL, если символическая ссылка, указанная в linkNamePtr, должна быть прочитана. int linkAction (in) Комбинация флагов OR, указываю‐ щая, какой тип ссылки следует создать (будет игнорироваться, если toPtr равно NULL). Допус‐ тимые биты для установки: TCL_CRE‐ ATE_SYMBOLIC_LINK и TCL_CREATE_‐ HARD_LINK. Когда оба флага ус‐ тановлены, и базовая файловая система может делать либо, пред‐ почитаются символические ссылки. ______________________________________________________________________________ ОПИСАНИЕ Существует несколько причин для вызова функций API Tcl_FS (например, Tcl_FSAccess и Tcl_FSStat), а не прямого вызова системных функций, таких как access и stat. Во-первых, они работают кросс-платформенно, поэтому расширение, которое их вызывает, должно работать без изменений на Unix и Windows. Во-вторых, реализация Windows некоторых из этих функций исправляет ошибки в системных вызовах. В-третьих, эти вызовы функций обрабатывают любые необходимые преобразования "Utf в платформо-специфичное" пути (и могут кэшировать результаты таких преобразований для большей эффективности при последующих вызовах). В-четвертых, и, возможно, наиболее важно, все эти функции "осведомлены о виртуальной файловой системе". Любая виртуальная файловая система (VFS в сокращении), зарегистрированная через Tcl_FSRegister, может перенаправлять доступ к файлам на альтернативные носители или методы доступа. Это означает, что все эти функции (а следовательно, и соответствующие команды Tcl, такие как file, glob, pwd, cd, open и т.д.) могут работать с "файлами", которые не являются родными файлами в родной файловой системе. Это также означает, что любое расширение Tcl, которое обращается к файловой системе (FS в сокращении) через этот API, автоматически "осведомлено о виртуальной файловой системе". Конечно, если расширение обращается напрямую к родной файловой системе (через платформо-специфичные API, например), Tcl не может перехватить такие вызовы. Если соответствующие VFS зарегистрированы, "файлы" могут, к примеру, быть удаленными (например, расположенными на удаленном сервере FTP) или архивированными (например, лежащими внутри архива .zip). Такие зарегистрированные файловые системы предоставляют таблицу поиска функций для реализации всего или части функциональности, перечисленной здесь. Наконец, вызовы Tcl_FSStat и Tcl_FSLstat абстрагируют от того, что буфер "struct stat" фактически объявлен, позволяя использовать один и тот же код на системах с поддержкой и без поддержки файлов больше 2ГБ. API Tcl_FS использует Tcl_Obj и может кэшировать внутренние представления и другие связанные с путем строки (например, текущую рабочую директорию). Один из побочных эффектов этого заключается в том, что значения с нулевым счетчиком ссылок нельзя передавать в никакие из этих функций. Если такие вызовы обрабатывались, они могли бы привести к утечкам памяти (в некоторых обстоятельствах код файловой системы может захотеть сохранить ссылку на переданное значение, поэтому нельзя предполагать, что после любого из этих вызовов значение все еще имеет счетчик ссылок равным нулю) или к прямому ошибке сегментации (или другой ошибке доступа к памяти) из-за освобождения значения на полпути через сложную манипуляцию значениями, необходимую для обеспечения того, чтобы путь был полностью нормализован и абсолютен для определения файловой системы. Практический урок из этого заключается в том, что Tcl_Obj *path = Tcl_NewStringObj(...); Tcl_FSWhatever(path); Tcl_DecrRefCount(path); неверно и может вызвать ошибки памяти. Счетчик ссылок пути должен быть увеличен перед передачей его в, или уменьшен после. По этой причине значения с нулевым счетчиком ссылок считаются недействительными путями файловой системы, и вызов любой функции API Tcl_FS с таким значением приведет к тому, что никаких действий не будет предпринято. ФУНКЦИИ API FS Tcl_FSCopyFile пытается скопировать файл, указанный в srcPathPtr, в имя пути, указанное в destPathPtr. Если два указанных пути лежат в той же файловой системе (согласно Tcl_FSGetFileSystemForPath), то вызывается функция "копирования файла" этой файловой системы (если она не NULL). В противном случае функция возвращает -1 и устанавливает глобальную переменную C errno в код POSIX-ошибки "EXDEV" (что обозначает "ссылку между доменами"). Tcl_FSCopyDirectory пытается скопировать директорию, указанную в srcPathPtr, в имя пути, указанное в destPathPtr. Если два указанных пути лежат в той же файловой системе (согласно Tcl_FSGetFileSystemForPa‐ th), то вызывается функция "копирования файла" этой файловой системы (если она не NULL). В противном случае функция возвращает -1 и устанавливает глобальную переменную C errno в код POSIX-ошибки "EXDEV" (что обозначает "ссылку между доменами"). Tcl_FSCreateDirectory пытается создать директорию, указанную в pathPtr, вызывая функцию "создания директории" владельца. Tcl_FSDeleteFile пытается удалить файл, указанный в pathPtr, вызывая функцию "удаления файла" владельца. Tcl_FSRemoveDirectory пытается удалить директорию, указанную в pathPtr, вызывая функцию "удаления директории" владельца. Tcl_FSRenameFile пытается переименовать файл или директорию, указанную в srcPathPtr, в имя пути, указанное в destPathPtr. Если два указанных пути лежат в той же файловой системе (согласно Tcl_FSGetFileSystemForPa‐ th), то вызывается функция "переименования файла" этой файловой системы (если она не NULL). В противном случае функция возвращает -1 и устанавливает глобальную переменную C errno в код POSIX-ошибки "EXDEV" (что обозначает "ссылку между доменами"). Tcl_FSListVolumes вызывает каждую файловую систему, у которой функция "списка томов" не NULL, и запрашивает у них список их корневых томов. Он накапливает возвращаемые значения в списке, который возвращается вызывающему (со счетчиком ссылок 0). Tcl_FSEvalFileEx читает файл, указанный в pathPtr, используя кодировку, идентифицированную как encodingName, и оценивает его содержимое как скрипт Tcl. Он возвращает ту же информацию, что и Tcl_EvalObjEx. Если encodingName равно NULL, используется системная кодировка для чтения содержимого файла. Если файл не удалось прочитать, возвращается ошибка Tcl, описывающая, почему файл не удалось прочитать. Символ конца файла (eofchar) для файлов - "\x1A" (^Z) для всех платформ. Если требуется "^Z" в коде для строкового сравнения, можно использовать "\x1A", который будет безопасно заменен интерпретатором Tcl на "^Z". Tcl_FSEvalFile - это упрощенная версия Tcl_FSEvalFileEx, которая всегда использует системную кодировку при чтении файла. Tcl_FSLoadFile динамически загружает файл бинарного кода в память и возвращает адреса двух процедур внутри этого файла, если они определены. Будет вызвана подходящая функция для файловой системы, к которой принадлежит pathPtr. Если эта файловая система не реализует эту функцию (большинство виртуальных файловых систем не будут, из-за ограничений ОС в динамической загрузке бинарного кода), Tcl попытается скопировать файл во временный каталог и загрузить этот временный файл. │ Tcl_FSUnloadFile │ отменяет операцию, запрашивая удаление библиотеки, │ указанной в loadHandle, из процесса. Обратите внимание, что, в отличие │ от команды unload, это не дает библиотеке возможности очистки. │ Оба перечисленных выше функции возвращают стандартный код завершения Tcl. Если возникает ошибка, сообщение об ошибке оставляется в результате интерпретатора. Токен, предоставленный через переменную, указанную в loadHandlePtr, │ может быть использован с Tcl_FindSymbol. Tcl_FSMatchInDirectory используется кодом glob для поиска в директории всех файлов, которые соответствуют заданному шаблону. Будет вызвана подходящая функция для файловой системы, к которой принадлежит pathPtr. Возвращаемое значение - стандартный результат Tcl, указывающий, возникла ли ошибка в процессе glob. Сообщения об ошибках размещаются в interp (если interp не NULL, что допустимо), но хорошие результаты размещаются в указанном resultPtr. Обратите внимание, что код glob реализует рекурсивные шаблоны внутренне, так что эта функция будет передавать только простые шаблоны. Для обработки рекурсии Tcl будет часто вызывать эту функцию, запрашивая только возвращение директорий. Специальный случай вызова с NULL-шаблоном указывает, что путь нужно проверить только на правильный тип. Tcl_FSLink заменяет библиотечную версию readlink и расширяет ее для поддержки создания ссылок. Будет вызвана подходящая функция для файловой системы, к которой принадлежит linkNamePtr. Если toPtr равно NULL, выполняется действие "чтение ссылки". Результат - Tcl_Obj, указывающий содержимое символической ссылки, данной в linkNamePtr, или NULL, если ссылку нельзя прочитать. Результат принадлежит вызывающему, который должен вызвать Tcl_DecrRefCount, когда результат больше не нужен. Если toPtr не NULL, Tcl должна создать ссылку одного из типов, переданных в флаге linkAction. Этот флаг - комбинация OR из TCL_CREATE_SYMBOLIC_LINK и TCL_CREATE_HARD_LINK. Где есть выбор (т.е. более одного флага передано), соглашение Tcl - предпочитать символические ссылки. Когда ссылка успешно создана, возвращаемое значение должно быть toPtr (которое поэтому уже принадлежит вызывающему). Если неудачно, возвращается NULL. Tcl_FSLstat заполняет структуру Tcl_StatBuf statPtr информацией об указанном файле. Вам не нужны права доступа к файлу, чтобы получить эту информацию, но вам нужны права поиска во всех директориях, указанных в пути, ведущем к файлу. Структура Tcl_StatBuf включает информацию о устройстве, inode (всегда 0 на Windows), привилегированном режиме, nlink (всегда 1 на Windows), идентификаторе пользователя (всегда 0 на Windows), идентификаторе группы (всегда 0 на Windows), rdev (то же, что и устройство на Windows), размере, времени последнего доступа, времени последнего изменения и времени последнего изменения метаданных. См. PORTABLE STAT RESULT API для описания, как писать переносимый код для выделения и доступа к структуре Tcl_StatBuf. Если путь существует, Tcl_FSLstat возвращает 0, и структура stat заполняется данными. В противном случае возвращается -1, и информация stat не предоставляется. Tcl_FSUtime заменяет библиотечную версию utime. Это возвращает 0 при успехе и -1 при ошибке (как в документации utime). При успешном выполнении функция обновит значения "atime" и "mtime" указанного файла. Tcl_FSFileAttrsGet реализует доступ на чтение для подкоманды атрибутов файлов, которые можно настраивать. Будет вызвана подходящая функция для файловой системы, к которой принадлежит pathPtr. Если результат TCL_OK, то значение размещено в objPtrRef, которое будет действительным только временно (если не вызвать Tcl_IncrRefCount). Tcl_FSFileAttrsSet реализует доступ на запись для подкоманды атрибутов файлов, которые можно настраивать. Будет вызвана подходящая функция для файловой системы, к которой принадлежит pathPtr. Tcl_FSFileAttrStrings реализует часть подкоманды атрибутов файлов, которые можно настраивать. Будет вызвана подходящая функция для файловой системы, к которой принадлежит pathPtr. Вызванная процедура может либо вернуть массив строк, либо вместо этого вернуть NULL и поместить список Tcl в данный objPtrRef. Tcl возьмет этот список и сначала увеличит его счетчик ссылок перед использованием. По завершении этого использования Tcl уменьшит его счетчик ссылок. Следовательно, если список должен быть удален Tcl по завершении, он должен иметь счетчик ссылок равный нулю, а если список не должен быть удален, файловая система должна убедиться, что возвращает значение со счетчиком ссылок не менее одного. Tcl_FSAccess проверяет, будет ли процессу разрешено читать, писать или проверять существование файла (или другого объекта файловой системы), имя которого указано в pathname. Если pathname - символическая ссылка на Unix, то проверяются разрешения файла, на который ссылается эта символическая ссылка. При успехе (все запрошенные разрешения предоставлены) возвращается ноль. При ошибке (хотя бы один бит в mode запрашивал разрешение, которое отказано, или возникла другая ошибка) возвращается -1. Tcl_FSStat заполняет структуру Tcl_StatBuf statPtr информацией об указанном файле. Вам не нужны права доступа к файлу, чтобы получить эту информацию, но вам нужны права поиска во всех директориях, указанных в пути, ведущем к файлу. Структура Tcl_StatBuf включает информацию о устройстве, inode (всегда 0 на Windows), привилегированном режиме, nlink (всегда 1 на Windows), идентификаторе пользователя (всегда 0 на Windows), идентификаторе группы (всегда 0 на Windows), rdev (то же, что и устройство на Windows), размере, времени последнего доступа, времени последнего изменения и времени последнего изменения метаданных. См. PORTABLE STAT RESULT API для описания, как писать переносимый код для выделения и доступа к структуре Tcl_StatBuf. Если путь существует, Tcl_FSStat возвращает 0, и структура stat заполняется данными. В противном случае возвращается -1, и информация stat не предоставляется. Tcl_FSOpenFileChannel открывает файл, указанный в pathPtr, и возвращает дескриптор канала, который можно использовать для ввода и вывода в файл. Этот API моделируется по процедуре fopen стандартной библиотеки ввода/вывода Unix. Синтаксис и значение всех аргументов аналогичны тем, которые даны в команде Tcl open при открытии файла. Если возникает ошибка при открытии канала, Tcl_FSOpenFileChannel возвращает NULL и фиксирует код POSIX-ошибки, который можно получить с помощью Tcl_GetErrno. Кроме того, если interp не NULL, Tcl_FSOpenFileChannel оставляет сообщение об ошибке в результате interp после любой ошибки. Новый созданный канал не регистрируется в предоставленном интерпретаторе; для регистрации используйте Tcl_RegisterChannel. Если один из стандартных каналов, stdin, stdout или stderr, был ранее закрыт, акт создания нового канала также назначает его в качестве замены для стандартного канала. Tcl_FSGetCwd заменяет библиотечную версию getcwd. Она возвращает текущую рабочую директорию библиотеки Tcl. Это может отличаться от рабочей директории родной платформы, что происходит, когда текущая рабочая директория не в родной файловой системе. Результат - указатель на Tcl_Obj, указывающий текущую директорию, или NULL, если текущую директорию нельзя определить. Если возвращается NULL, сообщение об ошибке оставляется в результате интерпретатора. Результат уже имеет увеличенный счетчик ссылок для вызывающего. Когда он больше не нужен, этот счетчик ссылок должен быть уменьшен. Это требуется для обеспечения безопасности потоков, чтобы позволить нескольким потокам получать доступ к этому и связанным функциям, в то время как обеспечение того, что результаты всегда действительны. Tcl_FSChdir заменяет библиотечную версию chdir. Путь нормализуется, а затем передается файловой системе, которая заявляет на него права. Если эта файловая система не реализует эту функцию, Tcl вернется к комбинации stat и access для проверки, существует ли директория и имеет ли она соответствующие разрешения. Для результатов см. документацию chdir. При успешном выполнении мы сохраняем запись успешного пути в cwdPathPtr для последующих вызовов Tcl_FSGetCwd. Tcl_FSPathSeparator возвращает символ(ы) разделителя для наиболее конкретного элемента пути, указанного в pathPtr (т.е. последней части пути). Разделитель возвращается как Tcl_Obj, содержащий строку длиной 1. Если путь недействителен, возвращается NULL. Tcl_FSJoinPath берет данный Tcl_Obj, который должен быть допустимым списком (который может иметь счетчик ссылок 0), и возвращает значение пути, полученное за счет рассмотрения первых elements элементов как допустимых сегментов пути (каждый сегмент пути может быть полным путем, частичным путем или просто одним возможным именем директории или файла). Если какой-либо сегмент пути является фактическим абсолютным путем, то все предыдущие сегменты пути отбрасываются. Если elements меньше 0, мы используем весь список. Возможным является то, что возвращаемое значение является элементом данного списка, поэтому вызывающий должен увеличить счетчик ссылок результата перед освобождением списка. Возвращаемое значение, обычно со счетчиком ссылок 0 (но оно может быть общим в некоторых условиях), содержит объединенный путь. Вызывающий должен добавить счетчик ссылок к значению перед его использованием. В частности, возвращаемое значение может быть элементом данного списка, поэтому освобождение списка может освободить значение преждевременно, если счетчик ссылок не был взят. Если количество элементов равно нулю, то возвращаемое значение будет Tcl_Obj с пустой строкой. Tcl_FSSplitPath берет данный Tcl_Obj, который должен быть допустимым путем, и возвращает значение списка Tcl, содержащее каждый сегмент этого пути в качестве элемента. Он возвращает значение списка со счетчиком ссылок 0. Если переданный lenPtr не NULL, переменная, на которую он указывает, будет обновлена для содержащего количества элементов в возвращенном списке. Tcl_FSEqualPaths проверяет, представляют ли два пути один и тот же объект файловой системы. Возвращает 1, если пути равны, и 0, если они различаются. Если любой путь равен NULL, всегда возвращается 0. Tcl_FSGetNormalizedPath пытается извлечь из данного Tcl_Obj уникальное нормализованное представление пути, строковое значение которого может быть использовано как уникальный идентификатор для файла. Он возвращает нормализованное значение пути, принадлежащее Tcl, или NULL, если путь недействителен или его невозможно успешно преобразовать. Извлечение абсолютных, нормализованных путей очень эффективно (потому что файловая система работает с этими представлениями внутренне), хотя результат, когда файловая система содержит множество символических ссылок, может не быть наиболее удобным для пользователя версией пути. Возвращаемое значение принадлежит Tcl и имеет срок действия, эквивалентный pathPtr, переданному (если это относительный путь, то нормализованное значение пути может быть освобождено в любое время при изменении cwd) - вызывающий, конечно, может увеличить счетчик ссылок, если желает сохранить копию на более длительный срок. Tcl_FSJoinToPath берет данное значение, которое обычно должно быть допустимым путем или NULL, и присоединяет к нему массив сегментов путей, указанных. Возвращает значение, обычно со счетчиком ссылок 0 (но оно может быть общим в некоторых условиях), содержащее объединенный путь. Вызывающий должен добавить счетчик ссылок к значению перед его использованием. Если какое-либо из значений, переданных в эту функцию (pathPtr или элементы пути), имеют счетчик ссылок 0, они будут освобождены, когда функция вернется. Tcl_FSConvertToPathType пытается преобразовать данный Tcl_Obj в допустимый тип пути Tcl, учитывая тот факт, что cwd может измениться, даже если это значение уже якобы правильного типа. Имя файла может начинаться с "~" (для обозначения домашней директории текущего пользователя) или "~<user>" (для обозначения домашней директории любого пользователя). Если преобразование удается (т.е. значение является допустимым путем в одной из текущих файловых систем), возвращается TCL_OK. В противном случае возвращается TCL_ERROR, и сообщение об ошибке может быть оставлено в интерпретаторе. Tcl_FSGetInternalRep извлекает внутреннее представление данного значения пути в данной файловой системе. Если значение пути принадлежит другой файловой системе, возвращается NULL. Если внутреннее представление в настоящее время NULL, мы пытаемся сгенерировать его, вызывая процедуру Tcl_FSCreateInternalRepProc файловой системы. Возвращает NULL или допустимое внутреннее представление пути. Это внутреннее представление кэшируется, так что повторные вызовы этой функции не потребуют дополнительных преобразований. Tcl_FSGetTranslatedPath пытается извлечь переведенный путь из данного Tcl_Obj. Если перевод успешен (т.е. значение является допустимым путем), то он возвращается. В противном случае возвращается NULL, и сообщение об ошибке может быть оставлено в интерпретаторе. "Переведенный" путь - это тот, который не содержит последовательностей "~" или "~user" (они были расширены до их текущего представления в файловой системе). Возвращаемое значение принадлежит вызывающему, который должен сохранить его или вызвать Tcl_DecrRefCount, чтобы обеспечить освобождение памяти. Эта функция мало практического использования, и Tcl_FSGetNormalizedPath или Tcl_FSGetNativePath обычно являются лучшими функциями для использования в большинстве случаев. Tcl_FSGetTranslatedStringPath выполняет то же, что и Tcl_FSGetTranslatedPath, но возвращает строку символов или NULL. Возвращаемая строка динамически выделяется и принадлежит вызывающему, который должен сохранить ее или вызвать ckfree, чтобы обеспечить ее освобождение. Опять же, Tcl_FSGetNormalizedPath или Tcl_FSGetNativePath обычно являются лучшими функциями для использования в большинстве случаев. Tcl_FSNewNativePath выполняет что-то вроде обратного обычных преобразований obj->path->nativerep. Если некоторый код извлекает путь в родной форме (из, например, readlink или родного диалога) и этот путь должен быть использован на уровне Tcl, то вызов этой функции - эффективный способ создания соответствующего типа значения пути. Полученное значение - чистое "значение пути", которое получит строковое представление UTF-8 только в том случае, если это требуется некоторым кодом Tcl. Tcl_FSGetNativePath предназначен для использования Win/Unix родными файловыми системами, так чтобы они могли легко получить родное (char* или TCHAR*) представление пути. Эта функция - удобная обертка вокруг Tcl_FSGetInternalRep. В будущем может быть желательно иметь родные представления, не основанные на строках (например, на macOS, представление с использованием структуры fileSpec или FSRef было бы более эффективным). На Windows полное представление Unicode позволит использовать пути неограниченной длины. В настоящее время представление просто строка символов, которая может содержать либо относительный путь, либо полный, абсолютный нормализованный путь в родной кодировке (сложные условия диктуют, какое из них будет предоставлено, так что ни одно из них нельзя полагаться, если путь известен как абсолютный). Если нужен родной путь, который должен быть абсолютным, то следует запросить родную версию нормализованного пути. Если по какой-то причине нужна неабсолютная, ненормализованная версия пути, ее нужно построить отдельно (например, с помощью Tcl_FSGetTranslatedPath). Родное представление кэшируется, так что повторные вызовы этой функции не потребуют дополнительных преобразований. Возвращаемое значение принадлежит Tcl и имеет срок действия, эквивалентный pathPtr, переданному (если это относительный путь, то родное представление может быть освобождено в любое время при изменении cwd). Tcl_FSFileSystemInfo возвращает список из двух элементов. Первый элемент - имя файловой системы (например, "native", "vfs", "zip" или "prowrap", возможно), а второй - конкретный тип данного пути в этой файловой системе (что зависит от файловой системы). Второй элемент может быть пустым, если файловая система не предоставляет дальнейшую категоризацию файлов. Возвращается допустимое значение списка, если значение пути распознано; в противном случае возвращается NULL. Tcl_FSGetFileSystemForPath возвращает указатель на Tcl_Filesystem, которая принимает этот путь как допустимый. Если ни одна файловая система не примет путь, возвращается NULL. Tcl_FSGetPathType определяет, является ли данный путь относительным по отношению к текущей директории, относительным по отношению к текущему тому или абсолютным. Он возвращает один из TCL_PATH_ABSOLUTE, TCL_PATH_RELATIVE или TCL_PATH_VOLUME_RELATIVE. PORTABLE STAT RESULT API Tcl_AllocStatBuf выделяет Tcl_StatBuf в куче системы (которая может быть освобождена путем передачи в ckfree). Это позволяет расширениям вызывать Tcl_FSStat и Tcl_FSLstat без зависимости от размера буфера. │ Это, в свою очередь, зависит от флагов, используемых для сборки Tcl. │ Портативные поля Tcl_StatBuf можно читать с помощью следующих │ функций, каждая из которых возвращает значение соответствующего поля, │ перечисленного в таблице ниже. Обратите внимание, что на некоторых │ платформах может быть другие поля в Tcl_StatBuf, поскольку это псевдоним │ для подходящей системной структуры, но только портативные доступны │ здесь. См. документацию вашей системы для полного описания этих полей. │ Access Function Field │ Tcl_GetFSDeviceFromStat st_dev │ Tcl_GetFSInodeFromStat st_ino │ Tcl_GetModeFromStat st_mode │ Tcl_GetLinkCountFromStat st_nlink │ Tcl_GetUserIdFromStat st_uid │ Tcl_GetGroupIdFromStat st_gid │ Tcl_GetDeviceTypeFromStat st_rdev │ Tcl_GetAccessTimeFromStat st_atime │ Tcl_GetModificationTimeFromStat st_mtime │ Tcl_GetChangeTimeFromStat st_ctime │ Tcl_GetSizeFromStat st_size │ Tcl_GetBlocksFromStat st_blocks │ Tcl_GetBlockSizeFromStat st_blksize │ ВИРТУАЛЬНАЯ ФАЙЛОВАЯ СИСТЕМА API Файловая система предоставляет структуру Tcl_Filesystem, содержащую указатели на функции, которые реализуют различные операции над файловой системой; эти операции вызываются по необходимости универсальным уровнем, что обычно происходит через функции, перечисленные выше. Структуры Tcl_Filesystem манипулируются с помощью следующих методов. Tcl_FSRegister принимает указатель на структуру файловой системы и необязательный блок данных для ассоциации с этой файловой системой. При вызове этой функции Tcl прикрепит файловую систему к списку известных файловых систем, и она немедленно станет полностью функциональной. Tcl не проверяет, регистрируется ли одна и та же файловая система несколько раз (и в общем это нехорошо). Будет возвращено TCL_OK. Tcl_FSUnregister удаляет указанную структуру файловой системы из списка известных файловых систем, если она известна, и возвращает TCL_OK. Если файловая система в настоящее время не зарегистрирована, возвращается TCL_ERROR. Tcl_FSData вернет clientData, связанный с данной файловой системой, если эта файловая система зарегистрирована. В противном случае вернется NULL. Tcl_FSMountsChanged используется для информирования ядра Tcl о том, что набор точек монтирования для данной (уже зарегистрированной) файловой системы изменился, и что кэшированные представления файлов, возможно, больше не верны. СТРУКТУРА TCL_FILESYSTEM Структура Tcl_Filesystem содержит следующие поля: typedef struct Tcl_Filesystem { const char *typeName; int structureLength; Tcl_FSVersion version; Tcl_FSPathInFilesystemProc *pathInFilesystemProc; Tcl_FSDupInternalRepProc *dupInternalRepProc; Tcl_FSFreeInternalRepProc *freeInternalRepProc; Tcl_FSInternalToNormalizedProc *internalToNormalizedProc; Tcl_FSCreateInternalRepProc *createInternalRepProc; Tcl_FSNormalizePathProc *normalizePathProc; Tcl_FSFilesystemPathTypeProc *filesystemPathTypeProc; Tcl_FSFilesystemSeparatorProc *filesystemSeparatorProc; Tcl_FSStatProc *statProc; Tcl_FSAccessProc *accessProc; Tcl_FSOpenFileChannelProc *openFileChannelProc; Tcl_FSMatchInDirectoryProc *matchInDirectoryProc; Tcl_FSUtimeProc *utimeProc; Tcl_FSLinkProc *linkProc; Tcl_FSListVolumesProc *listVolumesProc; Tcl_FSFileAttrStringsProc *fileAttrStringsProc; Tcl_FSFileAttrsGetProc *fileAttrsGetProc; Tcl_FSFileAttrsSetProc *fileAttrsSetProc; Tcl_FSCreateDirectoryProc *createDirectoryProc; Tcl_FSRemoveDirectoryProc *removeDirectoryProc; Tcl_FSDeleteFileProc *deleteFileProc; Tcl_FSCopyFileProc *copyFileProc; Tcl_FSRenameFileProc *renameFileProc; Tcl_FSCopyDirectoryProc *copyDirectoryProc; Tcl_FSLstatProc *lstatProc; Tcl_FSLoadFileProc *loadFileProc; Tcl_FSGetCwdProc *getCwdProc; Tcl_FSChdirProc *chdirProc; } Tcl_Filesystem; За исключением первых трех полей в этой структуре, содержащих простые элементы данных, все записи содержат адреса функций, вызываемых универсальным уровнем файловой системы для выполнения полного диапазона действий, связанных с файловой системой. Многие функции в этой структуре разделены на три категории: функции инфраструктуры (почти все из которых должны быть реализованы), операционные функции (которые должны быть реализованы, если предоставляется полная файловая система) и функции эффективности (которые нужно реализовать только если они могут быть реализованы эффективно или если у них есть побочные эффекты, требуемые файловой системой; Tcl имеет менее эффективные эмуляции, на которые он может вернуться). Важно отметить, что в текущей версии Tcl большинство из этих резервных копий используются только для обработки команд, инициированных в Tcl, а не в C. Это означает, что если команда переименования файла выдается в Tcl, и соответствующие файловая(ые) система(ы) не реализуют свою Tcl_FSRenameFileProc, ядро Tcl вместо этого вернется к комбинации других функций файловой системы (оно использует Tcl_FSCopyFileProc, за которой следует Tcl_FSDeleteFileProc, а если Tcl_FSCopyFileProc не реализовано, есть дальнейший резерв). Однако, если команда Tcl_FSRenameFileProc выдается на уровне C, такие резервные копии не происходят. Это верно, кроме четырех последних записей в таблице файловой системы (lstat, load, getcwd и chdir), для которых резервные копии действительно происходят на уровне C. Любые функции, которые принимают имена путей в форме Tcl_Obj, принимают эти имена в форме UTF-8. API инфраструктуры файловой системы предназначено для поддержки эффективного, кэшированного преобразования этих путей UTF-8 в другие родные представления. ПРИМЕР ОПРЕДЕЛЕНИЯ ФАЙЛОВОЙ СИСТЕМЫ Вот таблица поиска файловой системы, используемая расширением "vfs", которое позволяет реализовывать действия файловой системы в Tcl. static Tcl_Filesystem vfsFilesystem = { "tclvfs", sizeof(Tcl_Filesystem), TCL_FILESYSTEM_VERSION_1, &VfsPathInFilesystem, &VfsDupInternalRep, &VfsFreeInternalRep, /* Нет internal to normalized, поскольку мы не создаем * никаких чистых 'internal' представлений Tcl_Obj пути */ NULL, /* Нет функции создания родного представления, поскольку мы не * используем его и не выбираем поддержку использования * Tcl_FSNewNativePath */ NULL, /* Нормализация пути не нужна - мы предполагаем, что пути имеют * только одно представление */ NULL, &VfsFilesystemPathType, &VfsFilesystemSeparator, &VfsStat, &VfsAccess, &VfsOpenFileChannel, &VfsMatchInDirectory, &VfsUtime, /* Мы выбираем не поддерживать символические ссылки внутри наших * VFS */ NULL, &VfsListVolumes, &VfsFileAttrStrings, &VfsFileAttrsGet, &VfsFileAttrsSet, &VfsCreateDirectory, &VfsRemoveDirectory, &VfsDeleteFile, /* Нет копирования файла; используем механизм резервного копирования * ядра */ NULL, /* Нет переименования файла; используем механизм резервного * копирования ядра */ NULL, /* Нет копирования директории; используем механизм резервного * копирования ядра */ NULL, /* Ядро будет использовать stat для lstat */ NULL, /* Нет загрузки; используем механизм резервного копирования ядра */ NULL, /* Нам не нужна getcwd или chdir; внутреннее значение ядра * подходит */ NULL, NULL }; ИНФРАСТРУКТУРА ФАЙЛОВОЙ СИСТЕМЫ Эти поля содержат базовую информацию о структуре файловой системы и адреса функций, которые используются для ассоциации конкретной файловой системы с путем файла и обработки внутренних представлений пути, например копирования и освобождения таких представлений. TYPENAME Поле typeName содержит завершенную нулем строку, которая идентифицирует тип реализованной файловой системы, например "native", "zip" или "vfs". STRUCTURE LENGTH Поле structureLength обычно реализуется как sizeof(Tcl_Filesystem) и предназначено для облегчения бинарной обратной совместимости, если размер структуры изменится в будущем выпуске Tcl. VERSION Поле version должно быть установлено в TCL_FILESYSTEM_VERSION_1. PATHINFILESYSTEMPROC Поле pathInFilesystemProc содержит адрес функции, которая вызывается для определения, принадлежит ли данное значение пути этой файловой системе или нет. Tcl будет вызывать остальные функции файловой системы с путем, для которого эта функция вернула TCL_OK. Если путь не принадлежит, следует вернуть -1 (поведение Tcl для любого другого возвращаемого значения не определено). Если возвращается TCL_OK, то необязательный выходной параметр clientDataPtr можно использовать для возврата внутреннего (специфичного для файловой системы) представления пути, которое будет кэшироваться внутри значения пути и может быть эффективно извлечено другими функциями файловой системы. Tcl одновременно кэширует тот факт, что этот путь принадлежит этой файловой системе. Такие кэши инвалидируются при добавлении или удалении структур файловой системы из внутреннего списка известных файловых систем Tcl. typedef int Tcl_FSPathInFilesystemProc( Tcl_Obj *pathPtr, ClientData *clientDataPtr); DUPINTERNALREPPROC Эта функция создает копию внутреннего представления пути и вызывается, когда Tcl нужно дублировать значение пути. Если NULL, Tcl просто не скопирует внутреннее представление, которое затем может потребовать повторной генерации позже. typedef ClientData Tcl_FSDupInternalRepProc( ClientData clientData); FREEINTERNALREPPROC Освободить внутреннее представление. Это должно быть реализовано, если внутренние представления требуют освобождения (т.е. если некоторое место выделяется при генерации внутреннего представления), но в противном случае может быть NULL. typedef void Tcl_FSFreeInternalRepProc( ClientData clientData); INTERNALTONORMALIZEDPROC Функция для преобразования внутреннего представления в нормализованный путь. Требуется только если файловая система создает чистые значения пути без строкового/путевого представления. Возвращаемое значение - значение Tcl, строковое представление которого является нормализованным путем. typedef Tcl_Obj *Tcl_FSInternalToNormalizedProc( ClientData clientData); CREATEINTERNALREPPROC Функция для взятия значения пути и расчета внутреннего представления для него и хранения этого родного представления в значении. Может быть NULL, если пути не имеют внутреннего представления или если Tcl_FSPathInFilesystemProc для этой файловой системы всегда немедленно создает внутреннее представление для путей, которые она принимает. typedef ClientData Tcl_FSCreateInternalRepProc( Tcl_Obj *pathPtr); NORMALIZEPATHPROC Функция для нормализации пути. Должна быть реализована для всех файловых систем, которые могут иметь несколько строковых представлений для одного и того же значения пути. В Tcl каждый "путь" должен иметь одно уникальное "нормализованное" строковое представление. В зависимости от файловой системы может быть более одного ненормализованного строкового представления, которое относится к этому пути (например, относительный путь, путь с другим регистром символов, если файловая система нечувствительна к регистру, путь, содержащий ссылку на домашнюю директорию, такую как "~", путь, содержащий символические ссылки и т.д.). Если самый последний компонент в пути - символическая ссылка, она не должна быть преобразована в значение, на которое она указывает (но ее регистр или другие аспекты должны быть сделаны уникальными). Все остальные компоненты пути должны быть преобразованы из символических ссылок. Это одно исключение требуется для согласия с семантикой Tcl для file delete, file rename, file copy, действующих на символические ссылки. Эта функция может быть вызвана с nextCheckpoint либо в начале пути (т.е. ноль), в конце пути или в любой промежуточной точке разделителя файла в пути. Она никогда не укажет на любую другую произвольную позицию в пути. В последнем из трех допустимых случаев реализация может предположить, что путь до и включая разделитель файла известен и нормализован. typedef int Tcl_FSNormalizePathProc( Tcl_Interp *interp, Tcl_Obj *pathPtr, int nextCheckpoint); ОПЕРАЦИИ ФАЙЛОВОЙ СИСТЕМЫ Поля в этом разделе структуры содержат адреса функций, которые вызываются для выполнения базовых операций файловой системы. Для файловой системы, которая ожидает использования с полным стандартным набором команд Tcl, все из них должны быть реализованы. Если некоторые из них не реализованы, то определенные команды Tcl могут не работать, когда они действуют на пути внутри этой файловой системы. Однако, в некоторых случаях это может быть желательно (например, файловая система только для чтения не должна реализовывать последние четыре функции, а файловая система, которая не поддерживает символические ссылки, не нуждается в реализации функции readlink и т.д. Ядро Tcl ожидает, что файловые системы будут вести себя так). FILESYSTEMPATHTYPEPROC Функция для определения типа пути в этой файловой системе. Может быть NULL, в таком случае информация о типе не будет доступна пользователям файловой системы. "Тип" используется только в информационных целях и должен быть возвращен как строковое представление Tcl_Obj, которое возвращается. Типичное возвращаемое значение может быть "networked", "zip" или "ftp". Результат Tcl_Obj принадлежит файловой системе, так что Tcl увеличит счетчик ссылок этого значения, если желает сохранить ссылку на него. typedef Tcl_Obj *Tcl_FSFilesystemPathTypeProc( Tcl_Obj *pathPtr); FILESYSTEMSEPARATORPROC Функция для возврата символа(ов) разделителя для этой файловой системы. Это нужно реализовать только если файловая система желает использовать другой разделитель, чем стандартную строку "/". Среди прочего, он возвращается командой file separator. Возвращаемое значение должно быть значением со счетчиком ссылок 0. typedef Tcl_Obj *Tcl_FSFilesystemSeparatorProc( Tcl_Obj *pathPtr); STATPROC Функция для обработки вызова Tcl_FSStat. Должна быть реализована для любой разумной файловой системы, поскольку многие команды на уровне Tcl критически зависят от нее (например, file atime, file isdirectory, file size, glob). typedef int Tcl_FSStatProc( Tcl_Obj *pathPtr, Tcl_StatBuf *statPtr); Tcl_FSStatProc заполняет структуру stat информацией об указанном файле. Вам не нужны права доступа к файлу, чтобы получить эту информацию, но вам нужны права поиска во всех директориях, указанных в пути, ведущем к файлу. Структура stat включает информацию о устройстве, inode (всегда 0 на Windows), привилегированном режиме, nlink (всегда 1 на Windows), идентификаторе пользователя (всегда 0 на Windows), идентификаторе группы (всегда 0 на Windows), rdev (то же, что и устройство на Windows), размере, времени последнего доступа, времени последнего изменения и времени последнего изменения метаданных. Если файл, представленный pathPtr, существует, Tcl_FSStatProc возвращает 0, и структура stat заполняется данными. В противном случае возвращается -1, и информация stat не предоставляется. ACCESSPROC Функция для обработки вызова Tcl_FSAccess. Должна быть реализована для любой разумной файловой системы, поскольку многие команды на уровне Tcl критически зависят от нее (например, file exists, file readable). typedef int Tcl_FSAccessProc( Tcl_Obj *pathPtr, int mode); Tcl_FSAccessProc проверяет, будет ли процессу разрешено читать, писать или проверять существование файла (или другого объекта файловой системы), имя которого указано в pathPtr. Если pathname ссылается на символическую ссылку, то проверяются разрешения файла, на который ссылается эта символическая ссылка. При успехе (все запрошенные разрешения предоставлены) возвращается ноль. При ошибке (хотя бы один бит в mode запрашивал разрешение, которое отказано, или возникла другая ошибка) возвращается -1. OPENFILECHANNELPROC Функция для обработки вызова Tcl_FSOpenFileChannel. Должна быть реализована для любой разумной файловой системы, поскольку любые операции, требующие открытия или доступа к содержимому файла, будут использовать ее (например, open, encoding и многие команды Tk). typedef Tcl_Channel Tcl_FSOpenFileChannelProc( Tcl_Interp *interp, Tcl_Obj *pathPtr, int mode, int permissions); Tcl_FSOpenFileChannelProc открывает файл, указанный в pathPtr, и возвращает дескриптор канала, который можно использовать для ввода и вывода в файл. Этот API моделируется по процедуре fopen стандартной библиотеки ввода/вывода Unix. Синтаксис и значение всех аргументов аналогичны тем, которые даны в команде Tcl open при открытии файла, где аргумент mode - комбинация флагов POSIX O_RDONLY, O_WRONLY и т.д. Если возникает ошибка при открытии канала, Tcl_FSOpenFileChannelProc возвращает NULL и фиксирует код POSIX-ошибки, который можно получить с помощью Tcl_GetErrno. Кроме того, если interp не NULL, Tcl_FSOpenFileChannelProc оставляет сообщение об ошибке в результате interp после любой ошибки. Новый созданный канал не должен быть зарегистрирован в предоставленном интерпретаторе Tcl_FSOpenFileChannelProc; это задача вызывающего (если необходимо). Если один из стандартных каналов, stdin, stdout или stderr, был ранее закрыт, акт создания нового канала также назначает его в качестве замены для стандартного канала. MATCHINDIRECTORYPROC Функция для обработки вызова Tcl_FSMatchInDirectory. Если не реализована, то функциональность glob и рекурсивного копирования будет отсутствовать в файловой системе (и это может повлиять на команды, такие как encoding names, которые используют функциональность glob внутренне). typedef int Tcl_FSMatchInDirectoryProc( Tcl_Interp *interp, Tcl_Obj *resultPtr, Tcl_Obj *pathPtr, const char *pattern, Tcl_GlobTypeData *types); Функция должна возвращать все файлы или директории (или другие объекты файловой системы), которые соответствуют данному шаблону и соответствуют указанной спецификации типов. Существуют два способа вызова этой функции. Если pattern равно NULL, то pathPtr - полная спецификация пути одного файла или директории, который должен быть проверен на существование и правильный тип. В противном случае pathPtr - директория, содержимое которой функция должна искать файлы или директории, которые имеют правильный тип. В любом случае, pathPtr можно считать и не NULL, и непустым. В настоящее время не задокументировано, будет ли в pathPtr разделитель файла в конце или нет, так что код должен быть гибким для обоих возможностей. Возвращаемое значение - стандартный результат Tcl, указывающий, возникла ли ошибка в процессе сопоставления. Сообщения об ошибках размещаются в interp, если interp не NULL (что допустимо), в противном случае сообщение об ошибке не нужно генерировать; при результате TCL_OK результаты должны быть добавлены к указанному resultPtr (которое можно считать допустимым неподеленным списком Tcl). Совпадения, добавленные к resultPtr, должны включать любой префикс пути, данный в pathPtr (это обычно означает, что они будут абсолютными спецификациями пути). Обратите внимание, что если совпадения не найдены, это просто приводит к пустому результату; ошибки сигнализируются только для фактических проблем с файлами или файловой системой, которые могут возникнуть во время процесса сопоставления. Структура Tcl_GlobTypeData, переданная в параметре types, содержит следующие поля: typedef struct Tcl_GlobTypeData { /* Соответствует bcdpfls как в 'find -t' */ int type; /* Соответствует разрешениям файла */ int perm; /* Допустимый тип mac */ Tcl_Obj *macType; /* Допустимый создатель mac */ Tcl_Obj *macCreator; } Tcl_GlobTypeData; Существуют два конкретных случая, которые важно правильно обработать, оба когда types не NULL. Два случая - когда types->types & TCL_GLOB_TYPE_DIR или types->types & TCL_GLOB_TYPE_MOUNT истинны (и в частности когда другие флаги ложны). В первом из этих случаев функция должна перечислить содержащиеся директории. Tcl использует это для реализации рекурсивного globbing, так что критически важно, чтобы файловые системы правильно реализовывали сопоставление директорий. Во втором из этих случаев, с TCL_GLOB_TYPE_MOUNT, файловая система должна перечислить точки монтирования, которые лежат внутри данного pathPtr (и в этом случае pathPtr не обязательно лежит внутри той же файловой системы - в отличие от всех других случаев, в которых эта функция вызывается). Поддержка этого критически важна, если Tcl хочет иметь плавные переходы между одной файловой системой и другой. UTIMEPROC Функция для обработки вызова Tcl_FSUtime. Требуется для разрешения установки (но не чтения) времен с помощью file mtime, file atime и реализации open-r/open-w/fcopy команды file copy. typedef int Tcl_FSUtimeProc( Tcl_Obj *pathPtr, struct utimbuf *tval); Время доступа и изменения файла, указанного в pathPtr, должно быть изменено на значения, данные в структуре tval. Возвращаемое значение должно быть 0 при успехе и -1 при ошибке, как в системном utime. LINKPROC Функция для обработки вызова Tcl_FSLink. Должна быть реализована только если файловая система поддерживает ссылки, в противном случае может быть NULL. typedef Tcl_Obj *Tcl_FSLinkProc( Tcl_Obj *linkNamePtr, Tcl_Obj *toPtr, int linkAction); Если toPtr равно NULL, функция запрашивается для чтения содержимого ссылки. Результат - Tcl_Obj, указывающий содержимое символической ссылки, данной в linkNamePtr, или NULL, если ссылку нельзя прочитать. Результат принадлежит вызывающему, который должен вызвать Tcl_DecrRefCount, когда результат больше не нужен. Если toPtr не NULL, функция должна попытаться создать ссылку. В этом случае результат должен быть toPtr, если ссылка была успешной, и NULL в противном случае. В этом случае результат не принадлежит вызывающему (т.е. манипуляции счетчиком ссылок на обоих концах не нужны). См. документацию для Tcl_FSLink для правильной интерпретации флагов linkAction. LISTVOLUMESPROC Функция для перечисления любых томов файловой системы, добавленных этой файловой системой. Должна быть реализована только если файловая система добавляет тома в начале файловой системы, так чтобы их можно было вернуть командой file volumes. typedef Tcl_Obj *Tcl_FSListVolumesProc(void); Результат должен быть списком томов, добавленных этой файловой системой, или NULL (или пустым списком), если томов не предоставляется. Значение результата считается принадлежащим файловой системе (не ядру Tcl), но должно быть дано счетчик ссылок для Tcl. Tcl использует содержимое списка, а затем уменьшает этот счетчик ссылок. Это позволяет файловым системам выбирать, хотят ли они фактически сохранить "глобальный список" томов или нет (если нет, они генерируют список на лету и передают его Tcl со счетчиком ссылок 1, а затем забывают о списке; если да, то они просто увеличивают счетчик ссылок своего глобального списка и передают его Tcl, который скопирует содержимое, а затем уменьшит счетчик обратно до того, чем он был). Следовательно, Tcl считает возвращаемые значения из этой процедуры только для чтения. FILEATTRSTRINGSPROC Функция для перечисления всех строк атрибутов, которые действительны для этой файловой системы. Если не реализовано, файловая система не будет поддерживать команду file attributes. Это позволяет прикреплять произвольную дополнительную информацию к файлам в файловой системе. Если это не реализовано, нет необходимости реализовывать методы get и set. typedef const char *const *Tcl_FSFileAttrStringsProc( Tcl_Obj *pathPtr, Tcl_Obj **objPtrRef); Вызванная функция может либо вернуть массив строк, либо вместо этого вернуть NULL и поместить список Tcl в данный objPtrRef. Tcl возьмет этот список и сначала увеличит его счетчик ссылок перед использованием. По завершении этого использования Tcl уменьшит его счетчик ссылок. Следовательно, если список должен быть удален Tcl по завершении, он должен иметь счетчик ссылок равный нулю, а если список не должен быть удален, файловая система должна убедиться, что возвращает значение со счетчиком ссылок не менее одного. FILEATTRSGETPROC Функция для обработки вызова Tcl_FSFileAttrsGet, используемая командой file attributes. typedef int Tcl_FSFileAttrsGetProc( Tcl_Interp *interp, int index, Tcl_Obj *pathPtr, Tcl_Obj **objPtrRef); Возвращает стандартный код возврата Tcl. Полученное значение атрибута, которое соответствует index'ному элементу в списке, возвращенном Tcl_FSFileAttrStringsProc, - Tcl_Obj, размещенное в objPtrRef (если возвращено TCL_OK) и, вероятно, имеет счетчик ссылок 0. В любом случае мы должны либо сохранить его где-то (например, в результате Tcl), либо Incr/Decr его счетчик ссылок, чтобы обеспечить правильное освобождение. FILEATTRSSETPROC Функция для обработки вызова Tcl_FSFileAttrsSet, используемая командой file attributes. Если файловая система только для чтения, нет необходимости реализовывать это. typedef int Tcl_FSFileAttrsSetProc( Tcl_Interp *interp, int index, Tcl_Obj *pathPtr, Tcl_Obj *objPtr); Значение атрибута, которое соответствует index'ному элементу в списке, возвращенном Tcl_FSFileAttrStringsProc, должно быть установлено в данное objPtr. CREATEDIRECTORYPROC Функция для обработки вызова Tcl_FSCreateDirectory. Должна быть реализована, если FS только для чтения. typedef int Tcl_FSCreateDirectoryProc( Tcl_Obj *pathPtr); Возвращаемое значение - стандартный результат Tcl, указывающий, возникла ли ошибка в процессе. При успешном выполнении новая директория должна быть добавлена в файловую систему в месте, указанном в pathPtr. REMOVEDIRECTORYPROC Функция для обработки вызова Tcl_FSRemoveDirectory. Должна быть реализована, если FS только для чтения. typedef int Tcl_FSRemoveDirectoryProc( Tcl_Obj *pathPtr, int recursive, Tcl_Obj **errorPtr); Возвращаемое значение - стандартный результат Tcl, указывающий, возникла ли ошибка в процессе. При успешном выполнении директория, указанная в pathPtr, должна быть удалена из файловой системы. Если флаг recursive задан, то непустая директория должна быть удалена без ошибки. Если этот флаг не задан, то и директория непустая, должна сигнализироваться ошибка POSIX "EEXIST". Если возникает ошибка, имя файла или директории, которая вызвала ошибку, должно быть размещено в errorPtr. DELETEFILEPROC Функция для обработки вызова Tcl_FSDeleteFile. Должна быть реализована, если FS только для чтения. typedef int Tcl_FSDeleteFileProc( Tcl_Obj *pathPtr); Возвращаемое значение - стандартный результат Tcl, указывающий, возникла ли ошибка в процессе. При успешном выполнении файл, указанный в pathPtr, должен быть удален из файловой системы. Обратите внимание, что, если файловая система поддерживает символические ссылки, Tcl всегда будет вызывать эту функцию, а не Tcl_FSRemoveDirectoryProc, когда нужно удалить их (даже если они являются символическими ссылками на директории). ЭФФЕКТИВНОСТЬ ФАЙЛОВОЙ СИСТЕМЫ Эти функции необязательны для реализации для конкретной файловой системы, потому что в ядре есть резервная реализация. См. каждое индивидуальное описание для последствий оставления поля NULL. LSTATPROC Функция для обработки вызова Tcl_FSLstat. Если не реализовано, Tcl попытается использовать statProc, определенную выше. Следовательно, ее нужно реализовать только если файловая система может различать вызовы stat и lstat. typedef int Tcl_FSLstatProc( Tcl_Obj *pathPtr, Tcl_StatBuf *statPtr); Поведение этой функции очень похоже на Tcl_FSStatProc, определенную выше, за исключением того, что если она применяется к символической ссылке, она возвращает информацию о ссылке, а не о целевом файле. COPYFILEPROC Функция для обработки вызова Tcl_FSCopyFile. Если не реализовано, Tcl вернется к open-r, open-w и fcopy как механизму копирования. Следовательно, ее нужно реализовать только если файловая система может выполнить это действие более эффективно. typedef int Tcl_FSCopyFileProc( Tcl_Obj *srcPathPtr, Tcl_Obj *destPathPtr); Возвращаемое значение - стандартный результат Tcl, указывающий, возникла ли ошибка в процессе копирования. Обратите внимание, что destPathPtr - имя файла, который должен стать копией srcPathPtr. Это никогда не имя директории, в которую srcPathPtr мог быть скопирован (т.е. функция гораздо проще, чем подкоманда file copy на уровне Tcl). Обратите внимание, что, если файловая система поддерживает символические ссылки, Tcl всегда будет вызывать эту функцию, а не copyDirectoryProc, когда нужно скопировать их (даже если они являются символическими ссылками на директории). Наконец, если файловая система определяет, что не может поддерживать действие копирования файла, вызов Tcl_SetErrno(EXDEV) и возврат ненулевого результата сообщит Tcl использовать его стандартные механизмы резервного копирования. RENAMEFILEPROC Функция для обработки вызова Tcl_FSRenameFile. Если не реализовано, Tcl вернется к механизму копирования и удаления. Следовательно, ее нужно реализовать только если файловая система может выполнить это действие более эффективно. typedef int Tcl_FSRenameFileProc( Tcl_Obj *srcPathPtr, Tcl_Obj *destPathPtr); Возвращаемое значение - стандартный результат Tcl, указывающий, возникла ли ошибка в процессе переименования. Если файловая система определяет, что не может поддерживать действие переименования файла, вызов Tcl_SetErrno(EXDEV) и возврат ненулевого результата сообщит Tcl использовать его стандартные механизмы резервного копирования. COPYDIRECTORYPROC Функция для обработки вызова Tcl_FSCopyDirectory. Если не реализовано, Tcl вернется к рекурсивному механизму file mkdir, file copy. Следовательно, ее нужно реализовать только если файловая система может выполнить это действие более эффективно. typedef int Tcl_FSCopyDirectoryProc( Tcl_Obj *srcPathPtr, Tcl_Obj *destPathPtr, Tcl_Obj **errorPtr); Возвращаемое значение - стандартный результат Tcl, указывающий, возникла ли ошибка в процессе копирования. Если возникает ошибка, имя файла или директории, которая вызвала ошибку, должно быть размещено в errorPtr. Обратите внимание, что destPathPtr - имя директории, которая должна стать зеркальным отображением srcPathPtr. Это не имя директории, в которую srcPathPtr должен быть скопирован (т.е. функция гораздо проще, чем подкоманда file copy на уровне Tcl). Наконец, если файловая система определяет, что не может поддерживать действие копирования директории, вызов Tcl_SetErrno(EXDEV) и возврат ненулевого результата сообщит Tcl использовать его стандартные механизмы резервного копирования. LOADFILEPROC Функция для обработки вызова Tcl_FSLoadFile. Если не реализовано, Tcl вернется к копированию в родной-temp, за которым следует Tcl_FSLoadFile на этой временной копии. Следовательно, ее нужно реализовать только если файловая система может загружать код напрямую или если она может быть реализована просто для возврата TCL_ERROR, чтобы отключить функциональность загрузки в этой файловой системе полностью. typedef int Tcl_FSLoadFileProc( Tcl_Interp *interp, Tcl_Obj *pathPtr, Tcl_LoadHandle *handlePtr, Tcl_FSUnloadFileProc *unloadProcPtr); Возвращает стандартный код завершения Tcl. Если возникает ошибка, сообщение об ошибке оставляется в результате интерпретатора. Функция динамически загружает файл бинарного кода в память. При успешной загрузке handlePtr должно быть заполнено токеном для динамически загруженного файла, а unloadProcPtr должно быть заполнено адресом процедуры. Процедура выгрузки будет вызвана с данным Tcl_LoadHandle как ее единственным параметром, когда Tcl нужно выгрузить файл. Например, для родной файловой системы, Tcl_LoadHandle, возвращаемый в настоящее время, является токеном, который можно использовать в частном TclpFindSymbol для доступа к функциям в новом коде. Каждая файловая система свободна определять Tcl_LoadHandle так, как ей требуется. Наконец, если файловая система определяет, что не может поддерживать действие загрузки файла, вызов Tcl_SetErrno(EXDEV) и возврат ненулевого результата сообщит Tcl использовать его стандартные механизмы резервного копирования. UNLOADFILEPROC Функция для выгрузки ранее успешно загруженного файла. Если load реализовано, то это также должно быть реализовано, если требуется какое-либо действие очистки. typedef void Tcl_FSUnloadFileProc( Tcl_LoadHandle loadHandle); GETCWDPROC Функция для обработки вызова Tcl_FSGetCwd. Большинству файловых систем не нужно реализовывать это. Она обычно будет вызываться только один раз, если getcwd вызывается перед chdir. Может быть NULL. typedef Tcl_Obj *Tcl_FSGetCwdProc( Tcl_Interp *interp); Если файловая система поддерживает родное понятие текущей рабочей директории (которая может, возможно, изменяться независимо от Tcl), эта функция должна возвращать эту cwd как результат или NULL, если текущую директорию нельзя определить (например, у пользователя нет соответствующих разрешений на директорию cwd). Если возвращается NULL, сообщение об ошибке оставляется в результате интерпретатора. CHDIRPROC Функция для обработки вызова Tcl_FSChdir. Если файловые системы не реализуют это, оно будет эмулироваться серией проверок доступа к директориям. В противном случае виртуальные файловые системы, которые реализуют это, должны только ответить положительным результатом, если pathPtr - допустимая, доступная директория в их файловой системе. Им не нужно помнить результат, поскольку это будет автоматически запомнено для использования Tcl_FSGetCwd. Реальные файловые системы должны выполнять правильное действие (т.е. вызывать правильный системный API chdir). typedef int Tcl_FSChdirProc( Tcl_Obj *pathPtr); Tcl_FSChdirProc изменяет текущую рабочую директорию приложения на значение, указанное в pathPtr. Функция возвращает -1 при ошибке или 0 при успехе. СМОТРИТЕ ТАКЖЕ cd(n), file(n), filename(n), load(n), open(n), pwd(n), source(n), un‐ load(n) КЛЮЧЕВЫЕ СЛОВА stat, access, filesystem, vfs, virtual filesystem
Filesystem(3) Tcl Library Procedures Filesystem(3) ______________________________________________________________________________ NAME Tcl_FSRegister, Tcl_FSUnregister, Tcl_FSData, Tcl_FSMountsChanged, Tcl_FSGetFileSystemForPath, Tcl_FSGetPathType, Tcl_FSCopyFile, Tcl_FS‐ CopyDirectory, Tcl_FSCreateDirectory, Tcl_FSDeleteFile, Tcl_FSRemoveDi‐ rectory, Tcl_FSRenameFile, Tcl_FSListVolumes, Tcl_FSEvalFile, Tcl_FSE‐ valFileEx, Tcl_FSLoadFile, Tcl_FSUnloadFile, Tcl_FSMatchInDirectory, Tcl_FSLink, Tcl_FSLstat, Tcl_FSUtime, Tcl_FSFileAttrsGet, Tcl_FSFileAt‐ trsSet, Tcl_FSFileAttrStrings, Tcl_FSStat, Tcl_FSAccess, Tcl_FSOpen‐ FileChannel, Tcl_FSGetCwd, Tcl_FSChdir, Tcl_FSPathSeparator, Tcl_FSJoinPath, Tcl_FSSplitPath, Tcl_FSEqualPaths, Tcl_FSGetNormalized‐ Path, Tcl_FSJoinToPath, Tcl_FSConvertToPathType, Tcl_FSGetInternalRep, Tcl_FSGetTranslatedPath, Tcl_FSGetTranslatedStringPath, Tcl_FSNewNa‐ tivePath, Tcl_FSGetNativePath, Tcl_FSFileSystemInfo, Tcl_GetAccessTime‐ FromStat, Tcl_GetBlockSizeFromStat, Tcl_GetBlocksFromStat, Tcl_GetChangeTimeFromStat, Tcl_GetDeviceTypeFromStat, Tcl_GetFSDevice‐ FromStat, Tcl_GetFSInodeFromStat, Tcl_GetGroupIdFromStat, Tcl_GetLinkCountFromStat, Tcl_GetModeFromStat, Tcl_GetModificationTime‐ FromStat, Tcl_GetSizeFromStat, Tcl_GetUserIdFromStat, Tcl_AllocStatBuf - procedures to interact with any filesystem SYNOPSIS #include <tcl.h> int Tcl_FSRegister(clientData, fsPtr) int Tcl_FSUnregister(fsPtr) void * Tcl_FSData(fsPtr) Tcl_FSMountsChanged(fsPtr) const Tcl_Filesystem * Tcl_FSGetFileSystemForPath(pathPtr) Tcl_PathType Tcl_FSGetPathType(pathPtr) int Tcl_FSCopyFile(srcPathPtr, destPathPtr) int Tcl_FSCopyDirectory(srcPathPtr, destPathPtr, errorPtr) int Tcl_FSCreateDirectory(pathPtr) int Tcl_FSDeleteFile(pathPtr) int Tcl_FSRemoveDirectory(pathPtr, recursive, errorPtr) int Tcl_FSRenameFile(srcPathPtr, destPathPtr) Tcl_Obj * Tcl_FSListVolumes(void) int Tcl_FSEvalFileEx(interp, pathPtr, encodingName) int Tcl_FSEvalFile(interp, pathPtr) int Tcl_FSLoadFile(interp, pathPtr, sym1, sym2, proc1Ptr, proc2Ptr, loadHandlePtr, unloadProcPtr) int │ Tcl_FSUnloadFile(interp, loadHandle) │ int Tcl_FSMatchInDirectory(interp, resultPtr, pathPtr, pattern, types) Tcl_Obj * Tcl_FSLink(linkNamePtr, toPtr, linkAction) int Tcl_FSLstat(pathPtr, statPtr) int Tcl_FSUtime(pathPtr, tval) int Tcl_FSFileAttrsGet(interp, index, pathPtr, objPtrRef) int Tcl_FSFileAttrsSet(interp, index, pathPtr, objPtr) const char *const * Tcl_FSFileAttrStrings(pathPtr, objPtrRef) int Tcl_FSStat(pathPtr, statPtr) int Tcl_FSAccess(pathPtr, mode) Tcl_Channel Tcl_FSOpenFileChannel(interp, pathPtr, modeString, permissions) Tcl_Obj * Tcl_FSGetCwd(interp) int Tcl_FSChdir(pathPtr) Tcl_Obj * Tcl_FSPathSeparator(pathPtr) Tcl_Obj * Tcl_FSJoinPath(listObj, elements) Tcl_Obj * Tcl_FSSplitPath(pathPtr, lenPtr) int Tcl_FSEqualPaths(firstPtr, secondPtr) Tcl_Obj * Tcl_FSGetNormalizedPath(interp, pathPtr) Tcl_Obj * Tcl_FSJoinToPath(basePtr, objc, objv) int Tcl_FSConvertToPathType(interp, pathPtr) void * Tcl_FSGetInternalRep(pathPtr, fsPtr) Tcl_Obj * Tcl_FSGetTranslatedPath(interp, pathPtr) const char * Tcl_FSGetTranslatedStringPath(interp, pathPtr) Tcl_Obj * Tcl_FSNewNativePath(fsPtr, clientData) const void * Tcl_FSGetNativePath(pathPtr) Tcl_Obj * Tcl_FSFileSystemInfo(pathPtr) Tcl_StatBuf * Tcl_AllocStatBuf() Tcl_WideInt │ Tcl_GetAccessTimeFromStat(statPtr) │ unsigned │ Tcl_GetBlockSizeFromStat(statPtr) │ Tcl_WideUInt │ Tcl_GetBlocksFromStat(statPtr) │ Tcl_WideInt │ Tcl_GetChangeTimeFromStat(statPtr) │ int │ Tcl_GetDeviceTypeFromStat(statPtr) │ unsigned │ Tcl_GetFSDeviceFromStat(statPtr) │ unsigned │ Tcl_GetFSInodeFromStat(statPtr) │ int │ Tcl_GetGroupIdFromStat(statPtr) │ int │ Tcl_GetLinkCountFromStat(statPtr) │ unsigned │ Tcl_GetModeFromStat(statPtr) │ Tcl_WideInt │ Tcl_GetModificationTimeFromStat(statPtr) │ Tcl_WideUInt │ Tcl_GetSizeFromStat(statPtr) │ int │ Tcl_GetUserIdFromStat(statPtr) │ ARGUMENTS const Tcl_Filesystem *fsPtr (in) Points to a structure con‐ taining the addresses of procedures that can be called to perform the vari‐ ous filesystem operations. Tcl_Obj *pathPtr (in) The path represented by this value is used for the operation in question. If the value does not already have an internal path rep‐ resentation, it will be converted to have one. Tcl_Obj *srcPathPtr (in) As for pathPtr, but used for the source file for a copy or rename operation. Tcl_Obj *destPathPtr (in) As for pathPtr, but used for the destination file‐ name for a copy or rename operation. int recursive (in) Whether to remove subdirec‐ tories and their contents as well. const char *encodingName (in) The encoding of the data stored in the file identi‐ fied by pathPtr and to be evaluated. const char *pattern (in) Only files or directories matching this pattern will be returned. Tcl_GlobTypeData *types (in) Only files or directories matching the type descrip‐ tions contained in this structure will be returned. This parameter may be NULL. Tcl_Interp *interp (in) Interpreter to use either for results, evaluation, or reporting error messages. void *clientData (in) The native description of the path value to create. Tcl_Obj *firstPtr (in) The first of two path val‐ ues to compare. The value may be converted to path type. Tcl_Obj *secondPtr (in) The second of two path val‐ ues to compare. The value may be converted to path type. Tcl_Obj *listObj (in) The list of path elements to operate on with a join operation. int elements (in) The number of elements in the listObj which should be joined together. If nega‐ tive, then all elements are joined. Tcl_Obj **errorPtr (out) In the case of an error, filled with a value con‐ taining the name of the file which caused an error in the various copy/rename operations. int index (in) The index of the attribute in question. Tcl_Obj *objPtr (in) The value to set in the op‐ eration. Tcl_Obj **objPtrRef (out) Filled with a value con‐ taining the result of the operation. Tcl_Obj *resultPtr (out) Preallocated value in which to store (using Tcl_ListOb‐ jAppendElement) the list of files or directories which are successfully matched. int mode (in) Mask consisting of one or more of R_OK, W_OK, X_OK and F_OK. R_OK, W_OK and X_OK request checking whether the file exists and has read, write and exe‐ cute permissions, respec‐ tively. F_OK just requests checking for the existence of the file. Tcl_StatBuf *statPtr (out) The structure that contains the result of a stat or lstat operation. const char *sym1 (in) Name of a procedure to look up in the file's symbol ta‐ ble const char *sym2 (in) Name of a procedure to look up in the file's symbol ta‐ ble Tcl_PackageInitProc **proc1Ptr (out) Filled with the init func‐ tion for this code. Tcl_PackageInitProc **proc2Ptr (out) Filled with the safe-init function for this code. void **clientDataPtr (out) Filled with the clientData value to pass to this code's unload function when it is called. Tcl_LoadHandle *loadHandlePtr (out) Filled with an abstract to‐ ken representing the loaded file. Tcl_FSUnloadFileProc **unloadProcPtr (out) Filled with the function to use to unload this piece of code. Tcl_LoadHandle loadHandle (in) Handle to the loaded li‐ brary to be unloaded. utimbuf *tval (in) The access and modification times in this structure are read and used to set those values for a given file. const char *modeString (in) Specifies how the file is to be accessed. May have any of the values allowed for the mode argument to the Tcl open command. int permissions (in) POSIX-style permission flags such as 0644. If a new file is created, these permissions will be set on the created file. int *lenPtr (out) If non-NULL, filled with the number of elements in the split path. Tcl_Obj *basePtr (in) The base path on to which to join the given elements. May be NULL. int objc (in) The number of elements in objv. Tcl_Obj *const objv[] (in) The elements to join to the given base path. Tcl_Obj *linkNamePtr (in) The name of the link to be created or read. Tcl_Obj *toPtr (in) What the link called linkNamePtr should be linked to, or NULL if the symbolic link specified by linkNamePtr is to be read. int linkAction (in) OR-ed combination of flags indicating what kind of link should be created (will be ignored if toPtr is NULL). Valid bits to set are TCL_CREATE_SYM‐ BOLIC_LINK and TCL_CRE‐ ATE_HARD_LINK. When both flags are set and the un‐ derlying filesystem can do either, symbolic links are preferred. ______________________________________________________________________________ DESCRIPTION There are several reasons for calling the Tcl_FS API functions (e.g. Tcl_FSAccess and Tcl_FSStat) rather than calling system level functions like access and stat directly. First, they will work cross- platform, so an extension which calls them should work unmodified on Unix and Windows. Second, the Windows implementation of some of these functions fixes some bugs in the system level calls. Third, these func‐ tion calls deal with any “Utf to platform-native” path conversions which may be required (and may cache the results of such conversions for greater efficiency on subsequent calls). Fourth, and perhaps most importantly, all of these functions are “virtual filesystem aware”. Any virtual filesystem (VFS for short) which has been registered (through Tcl_FSRegister) may reroute file access to alternative media or access methods. This means that all of these functions (and there‐ fore the corresponding file, glob, pwd, cd, open, etc. Tcl commands) may be operate on “files” which are not native files in the native filesystem. This also means that any Tcl extension which accesses the filesystem (FS for short) through this API is automatically “virtual filesystem aware”. Of course, if an extension accesses the native filesystem directly (through platform-specific APIs, for example), then Tcl cannot intercept such calls. If appropriate VFSes have been registered, the “files” may, to give two examples, be remote (e.g. situated on a remote ftp server) or archived (e.g. lying inside a .zip archive). Such registered filesystems provide a lookup table of functions to implement all or some of the functional‐ ity listed here. Finally, the Tcl_FSStat and Tcl_FSLstat calls abstract away from what the “struct stat” buffer is actually declared to be, al‐ lowing the same code to be used both on systems with and systems with‐ out support for files larger than 2GB in size. The Tcl_FS API is Tcl_Obj-ified and may cache internal representations and other path-related strings (e.g. the current working directory). One side-effect of this is that one must not pass in values with a ref‐ erence count of zero to any of these functions. If such calls were han‐ dled, they might result in memory leaks (under some circumstances, the filesystem code may wish to retain a reference to the passed in value, and so one must not assume that after any of these calls return, the value still has a reference count of zero - it may have been incre‐ mented) or in a direct segmentation fault (or other memory access er‐ ror) due to the value being freed part way through the complex value manipulation required to ensure that the path is fully normalized and absolute for filesystem determination. The practical lesson to learn from this is that Tcl_Obj *path = Tcl_NewStringObj(...); Tcl_FSWhatever(path); Tcl_DecrRefCount(path); is wrong, and may cause memory errors. The path must have its reference count incremented before passing it in, or decrementing it. For this reason, values with a reference count of zero are considered not to be valid filesystem paths and calling any Tcl_FS API function with such a value will result in no action being taken. FS API FUNCTIONS Tcl_FSCopyFile attempts to copy the file given by srcPathPtr to the path name given by destPathPtr. If the two paths given lie in the same filesystem (according to Tcl_FSGetFileSystemForPath) then that filesys‐ tem's “copy file” function is called (if it is non-NULL). Otherwise the function returns -1 and sets the errno global C variable to the “EXDEV” POSIX error code (which signifies a “cross-domain link”). Tcl_FSCopyDirectory attempts to copy the directory given by srcPathPtr to the path name given by destPathPtr. If the two paths given lie in the same filesystem (according to Tcl_FSGetFileSystemForPath) then that filesystem's “copy file” function is called (if it is non-NULL). Oth‐ erwise the function returns -1 and sets the errno global C variable to the “EXDEV” POSIX error code (which signifies a “cross-domain link”). Tcl_FSCreateDirectory attempts to create the directory given by pathPtr by calling the owning filesystem's “create directory” function. Tcl_FSDeleteFile attempts to delete the file given by pathPtr by call‐ ing the owning filesystem's “delete file” function. Tcl_FSRemoveDirectory attempts to remove the directory given by pathPtr by calling the owning filesystem's “remove directory” function. Tcl_FSRenameFile attempts to rename the file or directory given by src‐ PathPtr to the path name given by destPathPtr. If the two paths given lie in the same filesystem (according to Tcl_FSGetFileSystemForPath) then that filesystem's “rename file” function is called (if it is non- NULL). Otherwise the function returns -1 and sets the errno global C variable to the “EXDEV” POSIX error code (which signifies a “cross-do‐ main link”). Tcl_FSListVolumes calls each filesystem which has a non-NULL “list vol‐ umes” function and asks them to return their list of root volumes. It accumulates the return values in a list which is returned to the caller (with a reference count of 0). Tcl_FSEvalFileEx reads the file given by pathPtr using the encoding identified by encodingName and evaluates its contents as a Tcl script. It returns the same information as Tcl_EvalObjEx. If encodingName is NULL, the system encoding is used for reading the file contents. If the file could not be read then a Tcl error is returned to describe why the file could not be read. The eofchar for files is “\x1A” (^Z) for all platforms. If you require a “^Z” in code for string comparison, you can use “\x1A”, which will be safely substituted by the Tcl inter‐ preter into “^Z”. Tcl_FSEvalFile is a simpler version of Tcl_FSEval‐ FileEx that always uses the system encoding when reading the file. Tcl_FSLoadFile dynamically loads a binary code file into memory and re‐ turns the addresses of two procedures within that file, if they are de‐ fined. The appropriate function for the filesystem to which pathPtr be‐ longs will be called. If that filesystem does not implement this func‐ tion (most virtual filesystems will not, because of OS limitations in dynamically loading binary code), Tcl will attempt to copy the file to a temporary directory and load that temporary file. Tcl_FSUnloadFile │ reverses the operation, asking for the library indicated by the load‐ │ Handle to be removed from the process. Note that, unlike with the un‐ │ load command, this does not give the library any opportunity to clean │ up. Both the above functions return a standard Tcl completion code. If an error occurs, an error message is left in the interp's result. The token provided via the variable indicated by loadHandlePtr may be │ used with Tcl_FindSymbol. Tcl_FSMatchInDirectory is used by the globbing code to search a direc‐ tory for all files which match a given pattern. The appropriate func‐ tion for the filesystem to which pathPtr belongs will be called. The return value is a standard Tcl result indicating whether an error occurred in globbing. Error messages are placed in interp (unless in‐ terp is NULL, which is allowed), but good results are placed in the re‐ sultPtr given. Note that the glob code implements recursive patterns internally, so this function will only ever be passed simple patterns, which can be matched using the logic of string match. To handle recursion, Tcl will call this function frequently asking only for directories to be re‐ turned. A special case of being called with a NULL pattern indicates that the path needs to be checked only for the correct type. Tcl_FSLink replaces the library version of readlink, and extends it to support the creation of links. The appropriate function for the filesystem to which linkNamePtr belongs will be called. If the toPtr is NULL, a “read link” action is performed. The result is a Tcl_Obj specifying the contents of the symbolic link given by linkNamePtr, or NULL if the link could not be read. The result is owned by the caller, which should call Tcl_DecrRefCount when the result is no longer needed. If the toPtr is not NULL, Tcl should create a link of one of the types passed in in the linkAction flag. This flag is an OR'ed combination of TCL_CREATE_SYMBOLIC_LINK and TCL_CREATE_HARD_LINK. Where a choice exists (i.e. more than one flag is passed in), the Tcl convention is to prefer symbolic links. When a link is successfully created, the return value should be toPtr (which is therefore already owned by the caller). If unsuccessful, NULL is returned. Tcl_FSLstat fills the Tcl_StatBuf structure statPtr with information about the specified file. You do not need any access rights to the file to get this information but you need search rights to all directories named in the path leading to the file. The Tcl_StatBuf structure in‐ cludes info regarding device, inode (always 0 on Windows), privilege mode, nlink (always 1 on Windows), user id (always 0 on Windows), group id (always 0 on Windows), rdev (same as device on Windows), size, last access time, last modification time, and last metadata change time. See PORTABLE STAT RESULT API for a description of how to write portable code to allocate and access the Tcl_StatBuf structure. If path exists, Tcl_FSLstat returns 0 and the stat structure is filled with data. Otherwise, -1 is returned, and no stat info is given. Tcl_FSUtime replaces the library version of utime. This returns 0 on success and -1 on error (as per the utime documenta‐ tion). If successful, the function will update the “atime” and “mtime” values of the file given. Tcl_FSFileAttrsGet implements read access for the hookable file at‐ tributes subcommand. The appropriate function for the filesystem to which pathPtr belongs will be called. If the result is TCL_OK, then a value was placed in objPtrRef, which will only be temporarily valid (unless Tcl_IncrRefCount is called). Tcl_FSFileAttrsSet implements write access for the hookable file at‐ tributes subcommand. The appropriate function for the filesystem to which pathPtr belongs will be called. Tcl_FSFileAttrStrings implements part of the hookable file attributes subcommand. The appropriate function for the filesystem to which path‐ Ptr belongs will be called. The called procedure may either return an array of strings, or may in‐ stead return NULL and place a Tcl list into the given objPtrRef. Tcl will take that list and first increment its reference count before us‐ ing it. On completion of that use, Tcl will decrement its reference count. Hence if the list should be disposed of by Tcl when done, it should have a reference count of zero, and if the list should not be disposed of, the filesystem should ensure it retains a reference count to the value. Tcl_FSAccess checks whether the process would be allowed to read, write or test for existence of the file (or other filesystem object) whose name is pathname. If pathname is a symbolic link on Unix, then permis‐ sions of the file referred by this symbolic link are tested. On success (all requested permissions granted), zero is returned. On error (at least one bit in mode asked for a permission that is denied, or some other error occurred), -1 is returned. Tcl_FSStat fills the Tcl_StatBuf structure statPtr with information about the specified file. You do not need any access rights to the file to get this information but you need search rights to all directories named in the path leading to the file. The Tcl_StatBuf structure in‐ cludes info regarding device, inode (always 0 on Windows), privilege mode, nlink (always 1 on Windows), user id (always 0 on Windows), group id (always 0 on Windows), rdev (same as device on Windows), size, last access time, last modification time, and last metadata change time. See PORTABLE STAT RESULT API for a description of how to write portable code to allocate and access the Tcl_StatBuf structure. If path exists, Tcl_FSStat returns 0 and the stat structure is filled with data. Otherwise, -1 is returned, and no stat info is given. Tcl_FSOpenFileChannel opens a file specified by pathPtr and returns a channel handle that can be used to perform input and output on the file. This API is modeled after the fopen procedure of the Unix stan‐ dard I/O library. The syntax and meaning of all arguments is similar to those given in the Tcl open command when opening a file. If an er‐ ror occurs while opening the channel, Tcl_FSOpenFileChannel returns NULL and records a POSIX error code that can be retrieved with Tcl_GetErrno. In addition, if interp is non-NULL, Tcl_FSOpenFileChan‐ nel leaves an error message in interp's result after any error. The newly created channel is not registered in the supplied inter‐ preter; to register it, use Tcl_RegisterChannel. If one of the stan‐ dard channels, stdin, stdout or stderr was previously closed, the act of creating the new channel also assigns it as a replacement for the standard channel. Tcl_FSGetCwd replaces the library version of getcwd. It returns the Tcl library's current working directory. This may be different to the native platform's working directory, which happens when the current working directory is not in the native filesystem. The result is a pointer to a Tcl_Obj specifying the current directory, or NULL if the current directory could not be determined. If NULL is returned, an error message is left in the interp's result. The result already has its reference count incremented for the caller. When it is no longer needed, that reference count should be decre‐ mented. This is needed for thread-safety purposes, to allow multiple threads to access this and related functions, while ensuring the re‐ sults are always valid. Tcl_FSChdir replaces the library version of chdir. The path is normal‐ ized and then passed to the filesystem which claims it. If that filesystem does not implement this function, Tcl will fallback to a combination of stat and access to check whether the directory exists and has appropriate permissions. For results, see chdir documentation. If successful, we keep a record of the successful path in cwdPathPtr for subsequent calls to Tcl_FS‐ GetCwd. Tcl_FSPathSeparator returns the separator character to be used for most specific element of the path specified by pathPtr (i.e. the last part of the path). The separator is returned as a Tcl_Obj containing a string of length 1. If the path is invalid, NULL is returned. Tcl_FSJoinPath takes the given Tcl_Obj, which must be a valid list (which is allowed to have a reference count of zero), and returns the path value given by considering the first elements elements as valid path segments (each path segment may be a complete path, a partial path or just a single possible directory or file name). If any path segment is actually an absolute path, then all prior path segments are dis‐ carded. If elements is less than 0, we use the entire list. It is possible that the returned value is actually an element of the given list, so the caller should be careful to increment the reference count of the result before freeing the list. The returned value, typically with a reference count of zero (but it could be shared under some conditions), contains the joined path. The caller must add a reference count to the value before using it. In par‐ ticular, the returned value could be an element of the given list, so freeing the list might free the value prematurely if no reference count has been taken. If the number of elements is zero, then the returned value will be an empty-string Tcl_Obj. Tcl_FSSplitPath takes the given Tcl_Obj, which should be a valid path, and returns a Tcl list value containing each segment of that path as an element. It returns a list value with a reference count of zero. If the passed in lenPtr is non-NULL, the variable it points to will be up‐ dated to contain the number of elements in the returned list. Tcl_FSEqualPaths tests whether the two paths given represent the same filesystem object. It returns 1 if the paths are equal, and 0 if they are different. If either path is NULL, 0 is always returned. Tcl_FSGetNormalizedPath attempts to extract from the given Tcl_Obj a unique normalized path representation, whose string value can be used as a unique identifier for the file. It returns the normalized path value, owned by Tcl, or NULL if the path was invalid or could otherwise not be successfully converted. Extrac‐ tion of absolute, normalized paths is very efficient (because the filesystem operates on these representations internally), although the result when the filesystem contains numerous symbolic links may not be the most user-friendly version of a path. The return value is owned by Tcl and has a lifetime equivalent to that of the pathPtr passed in (un‐ less that is a relative path, in which case the normalized path value may be freed any time the cwd changes) - the caller can of course in‐ crement the reference count if it wishes to maintain a copy for longer. Tcl_FSJoinToPath takes the given value, which should usually be a valid path or NULL, and joins onto it the array of paths segments given. Returns a value, typically with reference count of zero (but it could be shared under some conditions), containing the joined path. The caller must add a reference count to the value before using it. If any of the values passed into this function (pathPtr or path elements) have a reference count of zero, they will be freed when this function re‐ turns. Tcl_FSConvertToPathType tries to convert the given Tcl_Obj to a valid Tcl path type, taking account of the fact that the cwd may have changed even if this value is already supposedly of the correct type. The filename may begin with “~” (to indicate current user's home directory) or “~<user>” (to indicate any user's home directory). If the conversion succeeds (i.e. the value is a valid path in one of the current filesystems), then TCL_OK is returned. Otherwise TCL_ERROR is returned, and an error message may be left in the interpreter. Tcl_FSGetInternalRep extracts the internal representation of a given path value, in the given filesystem. If the path value belongs to a different filesystem, we return NULL. If the internal representation is currently NULL, we attempt to generate it, by calling the filesystem's Tcl_FSCreateInternalRepProc. Returns NULL or a valid internal path representation. This internal representation is cached, so that repeated calls to this function will not require additional conversions. Tcl_FSGetTranslatedPath attempts to extract the translated path from the given Tcl_Obj. If the translation succeeds (i.e. the value is a valid path), then it is returned. Otherwise NULL will be returned, and an error message may be left in the interpreter. A “translated” path is one which contains no “~” or “~user” sequences (these have been expanded to their current representation in the filesystem). The value returned is owned by the caller, which must store it or call Tcl_DecrRefCount to ensure memory is freed. This function is of little practical use, and Tcl_FSGetNor‐ malizedPath or Tcl_FSGetNativePath are usually better functions to use for most purposes. Tcl_FSGetTranslatedStringPath does the same as Tcl_FSGetTranslatedPath, but returns a character string or NULL. The string returned is dynami‐ cally allocated and owned by the caller, which must store it or call ckfree to ensure it is freed. Again, Tcl_FSGetNormalizedPath or Tcl_FS‐ GetNativePath are usually better functions to use for most purposes. Tcl_FSNewNativePath performs something like the reverse of the usual obj->path->nativerep conversions. If some code retrieves a path in na‐ tive form (from, e.g. readlink or a native dialog), and that path is to be used at the Tcl level, then calling this function is an efficient way of creating the appropriate path value type. The resulting value is a pure “path” value, which will only receive a UTF-8 string representation if that is required by some Tcl code. Tcl_FSGetNativePath is for use by the Win/Unix native filesystems, so that they can easily retrieve the native (char* or TCHAR*) representa‐ tion of a path. This function is a convenience wrapper around Tcl_FS‐ GetInternalRep. It may be desirable in the future to have non-string- based native representations (for example, on macOS, a representation using a fileSpec of FSRef structure would probably be more efficient). On Windows a full Unicode representation would allow for paths of un‐ limited length. Currently the representation is simply a character string which may contain either the relative path or a complete, abso‐ lute normalized path in the native encoding (complex conditions dictate which of these will be provided, so neither can be relied upon, unless the path is known to be absolute). If you need a native path which must be absolute, then you should ask for the native version of a normalized path. If for some reason a non-absolute, non-normalized version of the path is needed, that must be constructed separately (e.g. using Tcl_FS‐ GetTranslatedPath). The native representation is cached so that repeated calls to this function will not require additional conversions. The return value is owned by Tcl and has a lifetime equivalent to that of the pathPtr passed in (unless that is a relative path, in which case the native representation may be freed any time the cwd changes). Tcl_FSFileSystemInfo returns a list of two elements. The first element is the name of the filesystem (e.g. “native”, “vfs”, “zip”, or “prowrap”, perhaps), and the second is the particular type of the given path within that filesystem (which is filesystem dependent). The second element may be empty if the filesystem does not provide a further cate‐ gorization of files. A valid list value is returned, unless the path value is not recog‐ nized, when NULL will be returned. Tcl_FSGetFileSystemForPath returns a pointer to the Tcl_Filesystem which accepts this path as valid. If no filesystem will accept the path, NULL is returned. Tcl_FSGetPathType determines whether the given path is relative to the current directory, relative to the current volume, or absolute. It returns one of TCL_PATH_ABSOLUTE, TCL_PATH_RELATIVE, or TCL_PATH_VOLUME_RELATIVE PORTABLE STAT RESULT API Tcl_AllocStatBuf allocates a Tcl_StatBuf on the system heap (which may be deallocated by being passed to ckfree). This allows extensions to invoke Tcl_FSStat and Tcl_FSLstat without being dependent on the size of the buffer. That in turn depends on the flags used to build Tcl. The portable fields of a Tcl_StatBuf may be read using the following │ functions, each of which returns the value of the corresponding field │ listed in the table below. Note that on some platforms there may be │ other fields in the Tcl_StatBuf as it is an alias for a suitable system │ structure, but only the portable ones are made available here. See your │ system documentation for a full description of these fields. │ Access Function Field │ Tcl_GetFSDeviceFromStat st_dev │ Tcl_GetFSInodeFromStat st_ino │ Tcl_GetModeFromStat st_mode │ Tcl_GetLinkCountFromStat st_nlink │ Tcl_GetUserIdFromStat st_uid │ Tcl_GetGroupIdFromStat st_gid │ Tcl_GetDeviceTypeFromStat st_rdev │ Tcl_GetAccessTimeFromStat st_atime │ Tcl_GetModificationTimeFromStat st_mtime │ Tcl_GetChangeTimeFromStat st_ctime │ Tcl_GetSizeFromStat st_size │ Tcl_GetBlocksFromStat st_blocks │ Tcl_GetBlockSizeFromStat st_blksize │ THE VIRTUAL FILESYSTEM API A filesystem provides a Tcl_Filesystem structure that contains pointers to functions that implement the various operations on a filesystem; these operations are invoked as needed by the generic layer, which gen‐ erally occurs through the functions listed above. The Tcl_Filesystem structures are manipulated using the following meth‐ ods. Tcl_FSRegister takes a pointer to a filesystem structure and an op‐ tional piece of data to associated with that filesystem. On calling this function, Tcl will attach the filesystem to the list of known filesystems, and it will become fully functional immediately. Tcl does not check if the same filesystem is registered multiple times (and in general that is not a good thing to do). TCL_OK will be returned. Tcl_FSUnregister removes the given filesystem structure from the list of known filesystems, if it is known, and returns TCL_OK. If the filesystem is not currently registered, TCL_ERROR is returned. Tcl_FSData will return the clientData associated with the given filesystem, if that filesystem is registered. Otherwise it will return NULL. Tcl_FSMountsChanged is used to inform the Tcl's core that the set of mount points for the given (already registered) filesystem have changed, and that cached file representations may therefore no longer be correct. THE TCL_FILESYSTEM STRUCTURE The Tcl_Filesystem structure contains the following fields: typedef struct Tcl_Filesystem { const char *typeName; int structureLength; Tcl_FSVersion version; Tcl_FSPathInFilesystemProc *pathInFilesystemProc; Tcl_FSDupInternalRepProc *dupInternalRepProc; Tcl_FSFreeInternalRepProc *freeInternalRepProc; Tcl_FSInternalToNormalizedProc *internalToNormalizedProc; Tcl_FSCreateInternalRepProc *createInternalRepProc; Tcl_FSNormalizePathProc *normalizePathProc; Tcl_FSFilesystemPathTypeProc *filesystemPathTypeProc; Tcl_FSFilesystemSeparatorProc *filesystemSeparatorProc; Tcl_FSStatProc *statProc; Tcl_FSAccessProc *accessProc; Tcl_FSOpenFileChannelProc *openFileChannelProc; Tcl_FSMatchInDirectoryProc *matchInDirectoryProc; Tcl_FSUtimeProc *utimeProc; Tcl_FSLinkProc *linkProc; Tcl_FSListVolumesProc *listVolumesProc; Tcl_FSFileAttrStringsProc *fileAttrStringsProc; Tcl_FSFileAttrsGetProc *fileAttrsGetProc; Tcl_FSFileAttrsSetProc *fileAttrsSetProc; Tcl_FSCreateDirectoryProc *createDirectoryProc; Tcl_FSRemoveDirectoryProc *removeDirectoryProc; Tcl_FSDeleteFileProc *deleteFileProc; Tcl_FSCopyFileProc *copyFileProc; Tcl_FSRenameFileProc *renameFileProc; Tcl_FSCopyDirectoryProc *copyDirectoryProc; Tcl_FSLstatProc *lstatProc; Tcl_FSLoadFileProc *loadFileProc; Tcl_FSGetCwdProc *getCwdProc; Tcl_FSChdirProc *chdirProc; } Tcl_Filesystem; Except for the first three fields in this structure which contain sim‐ ple data elements, all entries contain addresses of functions called by the generic filesystem layer to perform the complete range of filesys‐ tem related actions. The many functions in this structure are broken down into three cate‐ gories: infrastructure functions (almost all of which must be imple‐ mented), operational functions (which must be implemented if a complete filesystem is provided), and efficiency functions (which need only be implemented if they can be done so efficiently, or if they have side- effects which are required by the filesystem; Tcl has less efficient emulations it can fall back on). It is important to note that, in the current version of Tcl, most of these fallbacks are only used to handle commands initiated in Tcl, not in C. What this means is, that if a file rename command is issued in Tcl, and the relevant filesystem(s) do not implement their Tcl_FSRenameFileProc, Tcl's core will instead fallback on a combination of other filesystem functions (it will use Tcl_FSCopy‐ FileProc followed by Tcl_FSDeleteFileProc, and if Tcl_FSCopyFileProc is not implemented there is a further fallback). However, if a Tcl_FSRe‐ nameFileProc command is issued at the C level, no such fallbacks occur. This is true except for the last four entries in the filesystem table (lstat, load, getcwd and chdir) for which fallbacks do in fact occur at the C level. Any functions which take path names in Tcl_Obj form take those names in UTF-8 form. The filesystem infrastructure API is designed to support efficient, cached conversion of these UTF-8 paths to other native rep‐ resentations. EXAMPLE FILESYSTEM DEFINITION Here is the filesystem lookup table used by the “vfs” extension which allows filesystem actions to be implemented in Tcl. static Tcl_Filesystem vfsFilesystem = { "tclvfs", sizeof(Tcl_Filesystem), TCL_FILESYSTEM_VERSION_1, &VfsPathInFilesystem, &VfsDupInternalRep, &VfsFreeInternalRep, /* No internal to normalized, since we don't create * any pure 'internal' Tcl_Obj path representations */ NULL, /* No create native rep function, since we don't use * it and don't choose to support uses of * Tcl_FSNewNativePath */ NULL, /* Normalize path isn't needed - we assume paths only * have one representation */ NULL, &VfsFilesystemPathType, &VfsFilesystemSeparator, &VfsStat, &VfsAccess, &VfsOpenFileChannel, &VfsMatchInDirectory, &VfsUtime, /* We choose not to support symbolic links inside our * VFS's */ NULL, &VfsListVolumes, &VfsFileAttrStrings, &VfsFileAttrsGet, &VfsFileAttrsSet, &VfsCreateDirectory, &VfsRemoveDirectory, &VfsDeleteFile, /* No copy file; use the core fallback mechanism */ NULL, /* No rename file; use the core fallback mechanism */ NULL, /* No copy directory; use the core fallback mechanism */ NULL, /* Core will use stat for lstat */ NULL, /* No load; use the core fallback mechanism */ NULL, /* We don't need a getcwd or chdir; the core's own * internal value is suitable */ NULL, NULL }; FILESYSTEM INFRASTRUCTURE These fields contain basic information about the filesystem structure and addresses of functions which are used to associate a particular filesystem with a file path, and deal with the internal handling of path representations, for example copying and freeing such representa‐ tions. TYPENAME The typeName field contains a null-terminated string that identifies the type of the filesystem implemented, e.g. “native”, “zip” or “vfs”. STRUCTURE LENGTH The structureLength field is generally implemented as sizeof(Tcl_Filesystem), and is there to allow easier binary backwards compatibility if the size of the structure changes in a future Tcl re‐ lease. VERSION The version field should be set to TCL_FILESYSTEM_VERSION_1. PATHINFILESYSTEMPROC The pathInFilesystemProc field contains the address of a function which is called to determine whether a given path value belongs to this filesystem or not. Tcl will only call the rest of the filesystem func‐ tions with a path for which this function has returned TCL_OK. If the path does not belong, -1 should be returned (the behavior of Tcl for any other return value is not defined). If TCL_OK is returned, then the optional clientDataPtr output parameter can be used to return an inter‐ nal (filesystem specific) representation of the path, which will be cached inside the path value, and may be retrieved efficiently by the other filesystem functions. Tcl will simultaneously cache the fact that this path belongs to this filesystem. Such caches are invalidated when filesystem structures are added or removed from Tcl's internal list of known filesystems. typedef int Tcl_FSPathInFilesystemProc( Tcl_Obj *pathPtr, ClientData *clientDataPtr); DUPINTERNALREPPROC This function makes a copy of a path's internal representation, and is called when Tcl needs to duplicate a path value. If NULL, Tcl will sim‐ ply not copy the internal representation, which may then need to be re‐ generated later. typedef ClientData Tcl_FSDupInternalRepProc( ClientData clientData); FREEINTERNALREPPROC Free the internal representation. This must be implemented if internal representations need freeing (i.e. if some memory is allocated when an internal representation is generated), but may otherwise be NULL. typedef void Tcl_FSFreeInternalRepProc( ClientData clientData); INTERNALTONORMALIZEDPROC Function to convert internal representation to a normalized path. Only required if the filesystem creates pure path values with no string/path representation. The return value is a Tcl value whose string represen‐ tation is the normalized path. typedef Tcl_Obj *Tcl_FSInternalToNormalizedProc( ClientData clientData); CREATEINTERNALREPPROC Function to take a path value, and calculate an internal representation for it, and store that native representation in the value. May be NULL if paths have no internal representation, or if the Tcl_FSPathIn‐ FilesystemProc for this filesystem always immediately creates an inter‐ nal representation for paths it accepts. typedef ClientData Tcl_FSCreateInternalRepProc( Tcl_Obj *pathPtr); NORMALIZEPATHPROC Function to normalize a path. Should be implemented for all filesystems which can have multiple string representations for the same path value. In Tcl, every “path” must have a single unique “normalized” string rep‐ resentation. Depending on the filesystem, there may be more than one unnormalized string representation which refers to that path (e.g. a relative path, a path with different character case if the filesystem is case insensitive, a path contain a reference to a home directory such as “~”, a path containing symbolic links, etc). If the very last component in the path is a symbolic link, it should not be converted into the value it points to (but its case or other aspects should be made unique). All other path components should be converted from sym‐ bolic links. This one exception is required to agree with Tcl's seman‐ tics with file delete, file rename, file copy operating on symbolic links. This function may be called with nextCheckpoint either at the beginning of the path (i.e. zero), at the end of the path, or at any intermediate file separator in the path. It will never point to any other arbitrary position in the path. In the last of the three valid cases, the implementation can assume that the path up to and including the file separator is known and normalized. typedef int Tcl_FSNormalizePathProc( Tcl_Interp *interp, Tcl_Obj *pathPtr, int nextCheckpoint); FILESYSTEM OPERATIONS The fields in this section of the structure contain addresses of func‐ tions which are called to carry out the basic filesystem operations. A filesystem which expects to be used with the complete standard Tcl com‐ mand set must implement all of these. If some of them are not imple‐ mented, then certain Tcl commands may fail when operating on paths within that filesystem. However, in some instances this may be desir‐ able (for example, a read-only filesystem should not implement the last four functions, and a filesystem which does not support symbolic links need not implement the readlink function, etc. The Tcl core expects filesystems to behave in this way). FILESYSTEMPATHTYPEPROC Function to determine the type of a path in this filesystem. May be NULL, in which case no type information will be available to users of the filesystem. The “type” is used only for informational purposes, and should be returned as the string representation of the Tcl_Obj which is returned. A typical return value might be “networked”, “zip” or “ftp”. The Tcl_Obj result is owned by the filesystem and so Tcl will increment the reference count of that value if it wishes to retain a reference to it. typedef Tcl_Obj *Tcl_FSFilesystemPathTypeProc( Tcl_Obj *pathPtr); FILESYSTEMSEPARATORPROC Function to return the separator character(s) for this filesystem. This need only be implemented if the filesystem wishes to use a differ‐ ent separator than the standard string “/”. Amongst other uses, it is returned by the file separator command. The return value should be a value with reference count of zero. typedef Tcl_Obj *Tcl_FSFilesystemSeparatorProc( Tcl_Obj *pathPtr); STATPROC Function to process a Tcl_FSStat call. Must be implemented for any rea‐ sonable filesystem, since many Tcl level commands depend crucially upon it (e.g. file atime, file isdirectory, file size, glob). typedef int Tcl_FSStatProc( Tcl_Obj *pathPtr, Tcl_StatBuf *statPtr); The Tcl_FSStatProc fills the stat structure statPtr with information about the specified file. You do not need any access rights to the file to get this information but you need search rights to all directories named in the path leading to the file. The stat structure includes info regarding device, inode (always 0 on Windows), privilege mode, nlink (always 1 on Windows), user id (always 0 on Windows), group id (always 0 on Windows), rdev (same as device on Windows), size, last access time, last modification time, and last metadata change time. If the file represented by pathPtr exists, the Tcl_FSStatProc returns 0 and the stat structure is filled with data. Otherwise, -1 is returned, and no stat info is given. ACCESSPROC Function to process a Tcl_FSAccess call. Must be implemented for any reasonable filesystem, since many Tcl level commands depend crucially upon it (e.g. file exists, file readable). typedef int Tcl_FSAccessProc( Tcl_Obj *pathPtr, int mode); The Tcl_FSAccessProc checks whether the process would be allowed to read, write or test for existence of the file (or other filesystem ob‐ ject) whose name is in pathPtr. If the pathname refers to a symbolic link, then the permissions of the file referred by this symbolic link should be tested. On success (all requested permissions granted), zero is returned. On error (at least one bit in mode asked for a permission that is denied, or some other error occurred), -1 is returned. OPENFILECHANNELPROC Function to process a Tcl_FSOpenFileChannel call. Must be implemented for any reasonable filesystem, since any operations which require open or accessing a file's contents will use it (e.g. open, encoding, and many Tk commands). typedef Tcl_Channel Tcl_FSOpenFileChannelProc( Tcl_Interp *interp, Tcl_Obj *pathPtr, int mode, int permissions); The Tcl_FSOpenFileChannelProc opens a file specified by pathPtr and re‐ turns a channel handle that can be used to perform input and output on the file. This API is modeled after the fopen procedure of the Unix standard I/O library. The syntax and meaning of all arguments is simi‐ lar to those given in the Tcl open command when opening a file, where the mode argument is a combination of the POSIX flags O_RDONLY, O_WRONLY, etc. If an error occurs while opening the channel, the Tcl_FSOpenFileChannelProc returns NULL and records a POSIX error code that can be retrieved with Tcl_GetErrno. In addition, if interp is non-NULL, the Tcl_FSOpenFileChannelProc leaves an error message in in‐ terp's result after any error. The newly created channel must not be registered in the supplied inter‐ preter by a Tcl_FSOpenFileChannelProc; that task is up to the caller of Tcl_FSOpenFileChannel (if necessary). If one of the standard channels, stdin, stdout or stderr was previously closed, the act of creating the new channel also assigns it as a replacement for the standard channel. MATCHINDIRECTORYPROC Function to process a Tcl_FSMatchInDirectory call. If not implemented, then glob and recursive copy functionality will be lacking in the filesystem (and this may impact commands like encoding names which use glob functionality internally). typedef int Tcl_FSMatchInDirectoryProc( Tcl_Interp *interp, Tcl_Obj *resultPtr, Tcl_Obj *pathPtr, const char *pattern, Tcl_GlobTypeData *types); The function should return all files or directories (or other filesys‐ tem objects) which match the given pattern and accord with the types specification given. There are two ways in which this function may be called. If pattern is NULL, then pathPtr is a full path specification of a single file or directory which should be checked for existence and correct type. Otherwise, pathPtr is a directory, the contents of which the function should search for files or directories which have the cor‐ rect type. In either case, pathPtr can be assumed to be both non-NULL and non-empty. It is not currently documented whether pathPtr will have a file separator at its end of not, so code should be flexible to both possibilities. The return value is a standard Tcl result indicating whether an error occurred in the matching process. Error messages are placed in interp, unless interp in NULL in which case no error message need be generated; on a TCL_OK result, results should be added to the resultPtr value given (which can be assumed to be a valid unshared Tcl list). The matches added to resultPtr should include any path prefix given in pathPtr (this usually means they will be absolute path specifications). Note that if no matches are found, that simply leads to an empty re‐ sult; errors are only signaled for actual file or filesystem problems which may occur during the matching process. The Tcl_GlobTypeData structure passed in the types parameter contains the following fields: typedef struct Tcl_GlobTypeData { /* Corresponds to bcdpfls as in 'find -t' */ int type; /* Corresponds to file permissions */ int perm; /* Acceptable mac type */ Tcl_Obj *macType; /* Acceptable mac creator */ Tcl_Obj *macCreator; } Tcl_GlobTypeData; There are two specific cases which it is important to handle correctly, both when types is non-NULL. The two cases are when types->types & TCL_GLOB_TYPE_DIR or types->types & TCL_GLOB_TYPE_MOUNT are true (and in particular when the other flags are false). In the first of these cases, the function must list the contained directories. Tcl uses this to implement recursive globbing, so it is critical that filesystems im‐ plement directory matching correctly. In the second of these cases, with TCL_GLOB_TYPE_MOUNT, the filesystem must list the mount points which lie within the given pathPtr (and in this case, pathPtr need not lie within the same filesystem - different to all other cases in which this function is called). Support for this is critical if Tcl is to have seamless transitions between from one filesystem to another. UTIMEPROC Function to process a Tcl_FSUtime call. Required to allow setting (not reading) of times with file mtime, file atime and the open-r/open- w/fcopy implementation of file copy. typedef int Tcl_FSUtimeProc( Tcl_Obj *pathPtr, struct utimbuf *tval); The access and modification times of the file specified by pathPtr should be changed to the values given in the tval structure. The return value should be 0 on success and -1 on an error, as with the system utime. LINKPROC Function to process a Tcl_FSLink call. Should be implemented only if the filesystem supports links, and may otherwise be NULL. typedef Tcl_Obj *Tcl_FSLinkProc( Tcl_Obj *linkNamePtr, Tcl_Obj *toPtr, int linkAction); If toPtr is NULL, the function is being asked to read the contents of a link. The result is a Tcl_Obj specifying the contents of the link given by linkNamePtr, or NULL if the link could not be read. The result is owned by the caller (and should therefore have its ref count incre‐ mented before being returned). Any callers should call Tcl_DecrRefCount on this result when it is no longer needed. If toPtr is not NULL, the function should attempt to create a link. The result in this case should be toPtr if the link was successful and NULL otherwise. In this case the result is not owned by the caller (i.e. no reference count ma‐ nipulations on either end are needed). See the documentation for Tcl_FSLink for the correct interpretation of the linkAction flags. LISTVOLUMESPROC Function to list any filesystem volumes added by this filesystem. Should be implemented only if the filesystem adds volumes at the head of the filesystem, so that they can be returned by file volumes. typedef Tcl_Obj *Tcl_FSListVolumesProc(void); The result should be a list of volumes added by this filesystem, or NULL (or an empty list) if no volumes are provided. The result value is considered to be owned by the filesystem (not by Tcl's core), but should be given a reference count for Tcl. Tcl will use the contents of the list and then decrement that reference count. This allows filesys‐ tems to choose whether they actually want to retain a “global list” of volumes or not (if not, they generate the list on the fly and pass it to Tcl with a reference count of 1 and then forget about the list, if yes, then they simply increment the reference count of their global list and pass it to Tcl which will copy the contents and then decrement the count back to where it was). Therefore, Tcl considers return values from this proc to be read-only. FILEATTRSTRINGSPROC Function to list all attribute strings which are valid for this filesystem. If not implemented the filesystem will not support the file attributes command. This allows arbitrary additional information to be attached to files in the filesystem. If it is not implemented, there is no need to implement the get and set methods. typedef const char *const *Tcl_FSFileAttrStringsProc( Tcl_Obj *pathPtr, Tcl_Obj **objPtrRef); The called function may either return an array of strings, or may in‐ stead return NULL and place a Tcl list into the given objPtrRef. Tcl will take that list and first increment its reference count before us‐ ing it. On completion of that use, Tcl will decrement its reference count. Hence if the list should be disposed of by Tcl when done, it should have a reference count of zero, and if the list should not be disposed of, the filesystem should ensure it returns a value with a reference count of at least one. FILEATTRSGETPROC Function to process a Tcl_FSFileAttrsGet call, used by file attributes. typedef int Tcl_FSFileAttrsGetProc( Tcl_Interp *interp, int index, Tcl_Obj *pathPtr, Tcl_Obj **objPtrRef); Returns a standard Tcl return code. The attribute value retrieved, which corresponds to the index'th element in the list returned by the Tcl_FSFileAttrStringsProc, is a Tcl_Obj placed in objPtrRef (if TCL_OK was returned) and is likely to have a reference count of zero. Either way we must either store it somewhere (e.g. the Tcl result), or Incr/Decr its reference count to ensure it is properly freed. FILEATTRSSETPROC Function to process a Tcl_FSFileAttrsSet call, used by file attributes. If the filesystem is read-only, there is no need to implement this. typedef int Tcl_FSFileAttrsSetProc( Tcl_Interp *interp, int index, Tcl_Obj *pathPtr, Tcl_Obj *objPtr); The attribute value of the index'th element in the list returned by the Tcl_FSFileAttrStringsProc should be set to the objPtr given. CREATEDIRECTORYPROC Function to process a Tcl_FSCreateDirectory call. Should be implemented unless the FS is read-only. typedef int Tcl_FSCreateDirectoryProc( Tcl_Obj *pathPtr); The return value is a standard Tcl result indicating whether an error occurred in the process. If successful, a new directory should have been added to the filesystem in the location specified by pathPtr. REMOVEDIRECTORYPROC Function to process a Tcl_FSRemoveDirectory call. Should be implemented unless the FS is read-only. typedef int Tcl_FSRemoveDirectoryProc( Tcl_Obj *pathPtr, int recursive, Tcl_Obj **errorPtr); The return value is a standard Tcl result indicating whether an error occurred in the process. If successful, the directory specified by pathPtr should have been removed from the filesystem. If the recursive flag is given, then a non-empty directory should be deleted without er‐ ror. If this flag is not given, then and the directory is non-empty a POSIX “EEXIST” error should be signaled. If an error does occur, the name of the file or directory which caused the error should be placed in errorPtr. DELETEFILEPROC Function to process a Tcl_FSDeleteFile call. Should be implemented un‐ less the FS is read-only. typedef int Tcl_FSDeleteFileProc( Tcl_Obj *pathPtr); The return value is a standard Tcl result indicating whether an error occurred in the process. If successful, the file specified by pathPtr should have been removed from the filesystem. Note that, if the filesystem supports symbolic links, Tcl will always call this function and not Tcl_FSRemoveDirectoryProc when needed to delete them (even if they are symbolic links to directories). FILESYSTEM EFFICIENCY These functions need not be implemented for a particular filesystem be‐ cause the core has a fallback implementation available. See each indi‐ vidual description for the consequences of leaving the field NULL. LSTATPROC Function to process a Tcl_FSLstat call. If not implemented, Tcl will attempt to use the statProc defined above instead. Therefore it need only be implemented if a filesystem can differentiate between stat and lstat calls. typedef int Tcl_FSLstatProc( Tcl_Obj *pathPtr, Tcl_StatBuf *statPtr); The behavior of this function is very similar to that of the Tcl_FSStatProc defined above, except that if it is applied to a sym‐ bolic link, it returns information about the link, not about the target file. COPYFILEPROC Function to process a Tcl_FSCopyFile call. If not implemented Tcl will fall back on open-r, open-w and fcopy as a copying mechanism. There‐ fore it need only be implemented if the filesystem can perform that ac‐ tion more efficiently. typedef int Tcl_FSCopyFileProc( Tcl_Obj *srcPathPtr, Tcl_Obj *destPathPtr); The return value is a standard Tcl result indicating whether an error occurred in the copying process. Note that, destPathPtr is the name of the file which should become the copy of srcPathPtr. It is never the name of a directory into which srcPathPtr could be copied (i.e. the function is much simpler than the Tcl level file copy subcommand). Note that, if the filesystem supports symbolic links, Tcl will always call this function and not copyDirectoryProc when needed to copy them (even if they are symbolic links to directories). Finally, if the filesystem determines it cannot support the file copy action, calling Tcl_SetEr‐ rno(EXDEV) and returning a non-TCL_OK result will tell Tcl to use its standard fallback mechanisms. RENAMEFILEPROC Function to process a Tcl_FSRenameFile call. If not implemented, Tcl will fall back on a copy and delete mechanism. Therefore it need only be implemented if the filesystem can perform that action more effi‐ ciently. typedef int Tcl_FSRenameFileProc( Tcl_Obj *srcPathPtr, Tcl_Obj *destPathPtr); The return value is a standard Tcl result indicating whether an error occurred in the renaming process. If the filesystem determines it can‐ not support the file rename action, calling Tcl_SetErrno(EXDEV) and re‐ turning a non-TCL_OK result will tell Tcl to use its standard fallback mechanisms. COPYDIRECTORYPROC Function to process a Tcl_FSCopyDirectory call. If not implemented, Tcl will fall back on a recursive file mkdir, file copy mechanism. There‐ fore it need only be implemented if the filesystem can perform that ac‐ tion more efficiently. typedef int Tcl_FSCopyDirectoryProc( Tcl_Obj *srcPathPtr, Tcl_Obj *destPathPtr, Tcl_Obj **errorPtr); The return value is a standard Tcl result indicating whether an error occurred in the copying process. If an error does occur, the name of the file or directory which caused the error should be placed in er‐ rorPtr. Note that, destPathPtr is the name of the directory-name which should become the mirror-image of srcPathPtr. It is not the name of a directory into which srcPathPtr should be copied (i.e. the function is much simpler than the Tcl level file copy subcommand). Finally, if the filesystem determines it cannot support the directory copy action, calling Tcl_SetErrno(EXDEV) and returning a non-TCL_OK result will tell Tcl to use its standard fallback mechanisms. LOADFILEPROC Function to process a Tcl_FSLoadFile call. If not implemented, Tcl will fall back on a copy to native-temp followed by a Tcl_FSLoadFile on that temporary copy. Therefore it need only be implemented if the filesystem can load code directly, or it can be implemented simply to return TCL_ERROR to disable load functionality in this filesystem entirely. typedef int Tcl_FSLoadFileProc( Tcl_Interp *interp, Tcl_Obj *pathPtr, Tcl_LoadHandle *handlePtr, Tcl_FSUnloadFileProc *unloadProcPtr); Returns a standard Tcl completion code. If an error occurs, an error message is left in the interp's result. The function dynamically loads a binary code file into memory. On a successful load, the handlePtr should be filled with a token for the dynamically loaded file, and the unloadProcPtr should be filled in with the address of a procedure. The unload procedure will be called with the given Tcl_LoadHandle as its only parameter when Tcl needs to unload the file. For example, for the native filesystem, the Tcl_LoadHandle returned is currently a token which can be used in the private TclpFindSymbol to access functions in the new code. Each filesystem is free to define the Tcl_LoadHandle as it requires. Finally, if the filesystem determines it cannot support the file load action, calling Tcl_SetErrno(EXDEV) and returning a non- TCL_OK result will tell Tcl to use its standard fallback mechanisms. UNLOADFILEPROC Function to unload a previously successfully loaded file. If load was implemented, then this should also be implemented, if there is any cleanup action required. typedef void Tcl_FSUnloadFileProc( Tcl_LoadHandle loadHandle); GETCWDPROC Function to process a Tcl_FSGetCwd call. Most filesystems need not im‐ plement this. It will usually only be called once, if getcwd is called before chdir. May be NULL. typedef Tcl_Obj *Tcl_FSGetCwdProc( Tcl_Interp *interp); If the filesystem supports a native notion of a current working direc‐ tory (which might perhaps change independent of Tcl), this function should return that cwd as the result, or NULL if the current directory could not be determined (e.g. the user does not have appropriate per‐ missions on the cwd directory). If NULL is returned, an error message is left in the interp's result. CHDIRPROC Function to process a Tcl_FSChdir call. If filesystems do not implement this, it will be emulated by a series of directory access checks. Oth‐ erwise, virtual filesystems which do implement it need only respond with a positive return result if the pathPtr is a valid, accessible di‐ rectory in their filesystem. They need not remember the result, since that will be automatically remembered for use by Tcl_FSGetCwd. Real filesystems should carry out the correct action (i.e. call the correct system chdir API). typedef int Tcl_FSChdirProc( Tcl_Obj *pathPtr); The Tcl_FSChdirProc changes the applications current working directory to the value specified in pathPtr. The function returns -1 on error or 0 on success. SEE ALSO cd(n), file(n), filename(n), load(n), open(n), pwd(n), source(n), un‐ load(n) KEYWORDS stat, access, filesystem, vfs, virtual filesystem Tcl 8.4 Filesystem(3)
Tcl_GetEncoding(3) Процедуры библиотеки Tcl Tcl_GetEncoding(3) ______________________________________________________________________________ NAME Tcl_GetEncoding, Tcl_FreeEncoding, Tcl_GetEncodingFromObj, Tcl_Ex‐ ternalToUtfDString, Tcl_ExternalToUtf, Tcl_UtfToExternalDString, Tcl_UtfToExternal, Tcl_WinTCharToUtf, Tcl_WinUtfToTChar, Tcl_GetEncod‐ ingName, Tcl_SetSystemEncoding, Tcl_GetEncodingNameFromEnvironment, Tcl_GetEncodingNames, Tcl_CreateEncoding, Tcl_GetEncodingSearchPath, Tcl_SetEncodingSearchPath, Tcl_GetDefaultEncodingDir, Tcl_SetDefault‐ EncodingDir - процедуры для создания и использования кодировок SYNOPSIS #include <tcl.h> Tcl_Encoding Tcl_GetEncoding(interp, name) void Tcl_FreeEncoding(encoding) int Tcl_GetEncodingFromObj(interp, objPtr, encodingPtr) char * Tcl_ExternalToUtfDString(encoding, src, srcLen, dstPtr) char * Tcl_UtfToExternalDString(encoding, src, srcLen, dstPtr) int Tcl_ExternalToUtf(interp, encoding, src, srcLen, flags, statePtr, dst, dstLen, srcReadPtr, dstWrotePtr, dstCharsPtr) int Tcl_UtfToExternal(interp, encoding, src, srcLen, flags, statePtr, dst, dstLen, srcReadPtr, dstWrotePtr, dstCharsPtr) char * Tcl_WinTCharToUtf(tsrc, srcLen, dstPtr) TCHAR * Tcl_WinUtfToTChar(src, srcLen, dstPtr) const char * Tcl_GetEncodingName(encoding) int Tcl_SetSystemEncoding(interp, name) const char * Tcl_GetEncodingNameFromEnvironment(bufPtr) void Tcl_GetEncodingNames(interp) Tcl_Encoding Tcl_CreateEncoding(typePtr) Tcl_Obj * Tcl_GetEncodingSearchPath() int Tcl_SetEncodingSearchPath(searchPath) const char * Tcl_GetDefaultEncodingDir(void) void Tcl_SetDefaultEncodingDir(path) ARGUMENTS Tcl_Interp *interp (in) Интерпретатор для использова‐ ния в отчётах об ошибках или NULL, если отчёты об ошибках не нужны. const char *name (in) Имя кодировки для загрузки. Tcl_Encoding encoding (in) Кодировка для запроса, освобож‐ дения или использования для пре‐ образования текста. Если encoding равен NULL, используется текущая системная кодировка. Tcl_Obj *objPtr (in) Имя кодировки для получения то‐ кена. Tcl_Encoding *encodingPtr (out) Указатель на хранилище, куда бу‐ дет записан токен кодировки. const char *src (in) Для функций Tcl_ExternalToUtf, массив байтов в указанной коди‐ ровке, которые нужно преобразо‐ вать в UTF-8. Для функций Tcl_UtfToExternal и Tcl_WinUtfToTChar, массив сим‐ волов UTF-8 для преобразования в указанную кодировку. const TCHAR *tsrc (in) Массив символов TCHAR Windows для преобразования в UTF-8. int srcLen (in) Длина src или tsrc в байтах. Если длина отрицательная, ис‐ пользуется длина строки, специ‐ фичная для кодировки. Tcl_DString *dstPtr (out) Указатель на неинициализирован‐ ный или освобождённый Tcl_DString, в котором будет храниться преоб‐ разованный результат. int flags (in) Различные биты флагов, объе‐ динённые с помощью OR. TCL_EN‐ CODING_START указывает, что ис‐ точный буфер является первым блоком в (потенциально многоблочном) по‐ тооке ввода, что сообщает проце‐ дуре преобразования сбросить со‐ стояние в исходное и выполнить любую необходимую инициализацию перед преобразованием первого бай‐ та. TCL_ENCODING_END указывает, что исходный буфер является по‐ следним блоком в (потенциально многоблочном) потоке ввода, что сообщает процедуре преобразования выполнить любую финализацию, ко‐ торая нужна после преобразования последнего байта, а затем сбро‐ сить состояние в исходное. TCL_ENCODING_STOPONERROR ука‐ зывает, что процедура преобразо‐ вания должна немедленно верну‐ ться при чтении символа исходно‐ го буфера, который не существует в целевой кодировке; в противном случае будет автоматически под‐ ставлен символ замены по умол‐ чанию. Tcl_EncodingState *statePtr (in/out) Используется при преобразовании (обычно длинного или неопреде‐ лённого) потока байтов по частям. Процедура преобразования хранит своё текущее состояние в *statePtr после преобразования src (буфер, содержащий текущую часть), и это состояние должно быть переда‐ но при преобразовании следующей части потока, чтобы процедура преобразования знала, в каком состоянии она была в конце преды‐ дущей части. Может быть NULL, в этом случае значение флага иг‐ норируется, и предполагается, что исходный буфер содержит по‐ лную строку для преобразования. char *dst (out) Буфер, в котором будет хранить‐ ся преобразованный результат. В dst не будет храниться более dstLen байтов. int dstLen (in) Максимальная длина выходного буфера dst в байтах. int *srcReadPtr (out) Заполняется количеством байтов из src, которые были фактичес‐ ки преобразованы. Это может быть меньше исходной длины исходного буфера, если возникли проблемы с преобразованием некоторых сим‐ волов. Может быть NULL. int *dstWrotePtr (out) Заполняется количеством байтов, которые были фактически записа‐ ны в выходной буфер в результате преобразования. Может быть NULL. int *dstCharsPtr (out) Заполняется количеством симво‐ лов, соответствующих количеству байтов, записанных в выходной бу‐ фер. Может быть NULL. Tcl_DString *bufPtr (out) Хранилище для имени системной кодировки. const Tcl_EncodingType *typePtr (in) Структура, которая определяет новый тип кодировки. Tcl_Obj *searchPath (in) Список каталогов файловой сис‐ темы, в которых нужно искать фай‐ лы данных кодировок. const char *path (in) Путь к расположению файла ко‐ дировки. ______________________________________________________________________________ INTRODUCTION Эти процедуры преобразовывают между внутренним представлением символов Tcl, UTF-8, и представлениями символов, используемыми различными опе‐ рационными системами или файловыми системами, такими как Unicode, ASCII или Shift-JIS. При работе со строками, такими как получение имён фа‐ йлов или отображение символов с использованием международных шрифтов, строки должны быть переведены в один или несколько форматов, которые мо‐ гут использовать различные системные вызовы. Например, на японской ра‐ бочей станции Unix пользователь может получить имя файла в кодировке EUC-JP и затем перевести символы в кодировку шрифта jisx0208 для отоб‐ ражения имени файла в виджете Tk. Цель пакета кодировок - помочь пре‐ мостить разрыв перевода. UTF-8 предоставляет промежуточную основу для всех различных кодировок. В приведённом выше примере текст будет пе‐ реведён в UTF-8 из той кодировки файлов, которую использует операци‐ онная система. Затем он будет переведён из UTF-8 в ту кодировку шрифта, которую требуют процедуры отображения. Некоторые базовые кодировки компилируются в Tcl. Другие могут быть оп‐ ределены пользователем или динамически загружены из файлов кодировок спо‐ собом, независимым от платформы. DESCRIPTION Tcl_GetEncoding находит кодировку по её имени. Имя может ссылаться на встроенную кодировку Tcl, пользовательскую кодировку, зарегистрирован‐ ную с помощью вызова Tcl_CreateEncoding, или динамически загружаемый файл кодировки. Возвращаемое значение - токен, который представляет ко‐ дировку и может использоваться в последующих вызовах процедур, таких как Tcl_GetEncodingName, Tcl_FreeEncoding и Tcl_UtfToExternal. Если имя не ссылается на известную или загружаемую кодировку, возвращается NULL, и сообщение об ошибке возвращается в interp. Пакет кодировок поддерживает базу данных всех кодировок, которые сейчас используются. В первый раз, когда имя встречается, Tcl_GetEncoding воз‐ вращает кодировку с счётчиком ссылок 1. Если то же самое имя запрашива‐ ется в дальнейшем, счётчик ссылок для этой кодировки увеличивается без накладных расходов на выделение новой кодировки и всех связанных с ней структур данных. Когда кодировка больше не нужна, следует вызвать Tcl_FreeEncoding для её освобождения. Когда кодировка больше нигде не используется (т.е. она была освобождена столько раз, сколько раз была получена), Tcl_FreeEnco‐ ding освободит всю память, которую использовала кодировка, и удалит её из базы данных. Tcl_GetEncodingFromObj рассматривает строковое представление objPtr как имя кодировки и находит кодировку с этим именем, как и Tcl_GetEncoding. Когда кодировка найдена, она кэшируется в значении objPtr для будущих ссылок, токен Tcl_Encoding записывается в хранилище, на которое указа‐ тель encodingPtr, и возвращается значение TCL_OK. Если такая кодировка не найдена, возвращается значение TCL_ERROR, и запись в *encodingPtr не происходит. Как и в случае с Tcl_GetEncoding, вызывающий должен вызвать Tcl_FreeEncoding для полученного токена кодировки, когда этот токен бо‐ лее не будет использоваться. Tcl_ExternalToUtfDString преобразует исходный буфер src из указанной ко‐ дировки в UTF-8. Преобразованные байты хранятся в dstPtr, который за‐ тем завершается нулевым символом. Вызывающий в конечном итоге должен вызвать Tcl_DStringFree для освобождения информации, хранящейся в dstPtr. При преобразовании, если любой из символов в исходном буфере не может быть представлен в целевой кодировке, будет использован символ замены по умолчанию. Возвращаемое значение - указатель на значение, хранящееся в DString. Tcl_ExternalToUtf преобразует исходный буфер src из указанной кодировки в UTF-8. Преобразуется до srcLen байтов из исходного буфера, и до dstLen преобразованных байтов хранится в dst. Во всех случаях, *srcReadPtr за‐ полняется количеством байтов из src, которые были успешно преобразова‐ ны, и *dstWrotePtr заполняется соответствующим количеством байтов, ко‐ торые были сохранены в dst. Возвращаемое значение - одно из следующих: TCL_OK Все байты src были преобразова‐ ны. TCL_CONVERT_NOSPACE Выходной буфер был недостаточ‐ но большим для всех преобразо‐ ванных данных; были преобразова‐ ны столько символов, сколько поместились. TCL_CONVERT_MULTIBYTE Последние несколько байтов в ис‐ ходном буфере были началом по‐ следовательности нескольких бай‐ тов, но для завершения этой по‐ следовательности требовалось бо‐ лее байтов. Последующий вызов процедуры преобразования должен передать буфер, содержащий не‐ преобразованные байты, оставав‐ шиеся в src, плюс некоторые до‐ полнительные байты из потока ис‐ точника, чтобы правильно преоб‐ разовать ранее разделённую по‐ следовательность нескольких бай‐ тов. TCL_CONVERT_SYNTAX Исходный буфер содержал недей‐ ствительную последовательность символов. Это может произойти, если поток ввода был повреждён или если метод кодировки ввода был неправильно идентифицирован. TCL_CONVERT_UNKNOWN Исходный буфер содержал символ, который не может быть представ‐ лен в целевой кодировке, и ука‐ зано TCL_ENCODING_STOPONERROR. Tcl_UtfToExternalDString преобразует исходный буфер src из UTF-8 в ука‐ занную кодировку. Преобразованные байты хранятся в dstPtr, который за‐ тем завершается соответствующим нулевым символом кодировки. Вызываю‐ щий в конечном итоге должен вызвать Tcl_DStringFree для освобождения ин‐ формации, хранящейся в dstPtr. При преобразовании, если любой из симво‐ лов в исходном буфере не может быть представлен в целевой кодировке, бу‐ дет использован символ замены по умолчанию. Возвращаемое значение - ук азатель на значение, хранящееся в DString. Tcl_UtfToExternal преобразует исходный буфер src из UTF-8 в указанную кодировку. Преобразуется до srcLen байтов из исходного буфера, и до dstLen преобразованных байтов хранится в dst. Во всех случаях, *srcReadPtr заполняется количеством байтов из src, которые были успешно преобразу‐ емы, и *dstWrotePtr заполняется соответствующим количеством байтов, ко‐ торые были сохранены в dst. Возвращаемые значения такие же, как и для Tcl_ExternalToUtf. Tcl_WinUtfToTChar и Tcl_WinTCharToUtf - это функции удобства только для Windows для преобразования между UTF-8 и строками Windows на основе ти‐ па TCHAR, который по конвенции является символом Unicode в Windows NT. Tcl_GetEncodingName примерно является обратным Tcl_GetEncoding. Для заданной кодировки возвращаемое значение - аргумент name, который был использован для создания кодировки. Строка, возвращаемая Tcl_GetEncodingName, гарантированно существует только до тех пор, пока кодировка не будет удалена. Вызывающий не должен изменять эту строку. Tcl_SetSystemEncoding устанавливает кодировку по умолчанию, которая дол‐ жна использоваться всякий раз, когда пользователь передаёт значение NULL для аргумента encoding в любой из других функций кодировки. Если name равно NULL, системная кодировка сбрасывается в кодировку по умолчанию, binary. Если имя не ссылается на известную или загружаемую кодировку, возвращается TCL_ERROR, и сообщение об ошибке оставляется в interp. В противном случае эта процедура увеличивает счётчик ссылок новой систем‐ ной кодировки, уменьшает счётчик ссылок старой системной кодировки и возвращает TCL_OK. Tcl_GetEncodingNameFromEnvironment предоставляет средство для библиоте‐ ки Tcl сообщить имя кодировки, которое, по её мнению, является правиль‐ ным для использования в качестве системной кодировки, на основе систем‐ ных вызовов и осмотра среды, подходящей для платформы. Она принимает bufPtr, указатель на неинициализированный или освобождённый Tcl_DString, и записывает имя кодировки в него. Возвращается Tcl_DStringValue. Tcl_GetEncodingNames устанавливает результат interp в список, состоящий из имён всех кодировок, которые в настоящее время определены или могут быть динамически загружены, с поиском по пути кодировки, указанному Tcl_SetDefaultEncodingDir. Эта процедура не гарантирует, что динамичес‐ ки загружаемые файлы кодировок содержат действительные данные, а всего лишь то, что они существуют. Tcl_CreateEncoding определяет новую кодировку и регистрирует С-процеду‐ ры, которые будут вызываться для преобразования между кодировкой и UTF-8. Кодировки, созданные Tcl_CreateEncoding, затем видны в базе данных, используемой Tcl_GetEncoding. Как и в случае с процедурой Tcl_GetEncoding, возвращаемое значение - токен, который представляет кодировку и может использоваться в последующих вызовах других функций кодировки. Tcl_CreateEncoding возвращает кодировку со счётчиком ссылок 1. Если кодировка с указанным именем уже существует, её запись в базе данных заменяется новой кодиров‐ кой; токен для старой кодировки останется действительным и будет вести себя как раньше, но пользователи нового токена теперь будут вызывать новые процедуры кодировки. Аргумент typePtr в Tcl_CreateEncoding содержит информацию об имени ко‐ дировки и процедурах, которые будут вызываться для преобразования между этой кодировкой и UTF-8. Он определяется следующим образом: typedef struct Tcl_EncodingType { const char *encodingName; Tcl_EncodingConvertProc *toUtfProc; Tcl_EncodingConvertProc *fromUtfProc; Tcl_EncodingFreeProc *freeProc; ClientData clientData; int nullSize; } Tcl_EncodingType; Поле encodingName предоставляет строковое имя для кодировки, по которо‐ му она может быть указана в других процедурах, таких как Tcl_GetEncoding. Поле toUtfProc ссылается на процедуру обратного вызова для вызова для преобразования текста из этой кодировки в UTF-8. Поле fromUtfProc ссыла‐ ется на процедуру обратного вызова для вызова для преобразования текста из UTF-8 в эту кодировку. Поле freeProc ссылается на процедуру обратного вызова для вызова при удалении этой кодировки. Поле freeProc может быть NULL. Поле clientData содержит произвольное значение одного слова, пе‐ редаваемое toUtfProc, fromUtfProc и freeProc при их вызове. Обычно это указатель на структуру данных, содержащую информацию, специфичную для кодировки, которую могут использовать процедуры обратного вызова. На пример, две очень похожие кодировки, такие как ascii и macRoman, могут использовать одну и ту же процедуру обратного вызова, но использовать разные значения clientData для управления своим поведением. Поле nullSize указывает количество нулевых байтов, которые обозначают конец строки в этой кодировке. Оно должно быть 1 (для кодировок с одним байтом или не‐ сколькими байтами, таких как ASCII или Shift-JIS) или 2 (для кодировок с двумя байтами, таких как Unicode). Кодировки с постоянным размером и 3 или более байтами на символ (такие как CNS11643) не принимаются. Процедуры обратного вызова toUtfProc и fromUtfProc должны соответство‐ вать типу Tcl_EncodingConvertProc: typedef int Tcl_EncodingConvertProc( ClientData clientData, const char *src, int srcLen, int flags, Tcl_EncodingState *statePtr, char *dst, int dstLen, int *srcReadPtr, int *dstWrotePtr, int *dstCharsPtr); Процедуры toUtfProc и fromUtfProc вызываются функциями Tcl_ExternalToUtf или Tcl_UtfToExternal для выполнения фактического преобразования. Пара‐ метр clientData этих процедур такой же, как поле clientData, указанное в Tcl_CreateEncoding при создании кодировки. Остальные аргументы проце‐ ссуры обратного вызова те же, что и аргументы, задокументированные вы‐ ше, для Tcl_ExternalToUtf или Tcl_UtfToExternal, с следующими исключе‐ ниями. Если аргумент srcLen одной из этих высокоуровневых функций от‐ рицательный, значение, переданное процедуре обратного вызова, будет соответствующей длиной строки, специфичной для кодировки, src. Если любой из аргументов srcReadPtr, dstWrotePtr или dstCharsPtr одной из высокоуровневых функций равен NULL, соответствующее значение, передан‐ ное процедуре обратного вызова, будет ненулевым местом. Процедура обратного вызова freeProc, если она ненулевая, должна совпа‐ дать с типом Tcl_EncodingFreeProc: typedef void Tcl_EncodingFreeProc( ClientData clientData); Эта функция freeProc вызывается при удалении кодировки. Параметр cli‐ entData такой же, как поле clientData, указанное в Tcl_CreateEncoding при создании кодировки. Tcl_GetEncodingSearchPath и Tcl_SetEncodingSearchPath вызываются для доступа и установки списка каталогов файловой системы, в которых ищем файлы данных кодировок. Значение, возвращаемое Tcl_GetEncodingSearchPath, является значением, хранящимся последним успешным вызовом Tcl_SetEncodingSearchPath. Если вызовов Tcl_SetEncodingSearchPath не было, Tcl вычислит начальное зна‐ чение на основе среды. Существует один путь поиска кодировок для всего процесса, общий для всех потоков в процессе. Tcl_SetEncodingSearchPath сохраняет searchPath и возвращает TCL_OK, ес‐ ли searchPath является допустимым списком Tcl, в противном случае воз‐ вращается TCL_ERROR. Элементы searchPath не проверяются как существующие читаемые каталоги файловой системы. При поиске файлов данных кодировок несуществующие или нечитаемые каталоги файловой системы в searchPath игнорируются. Tcl_GetDefaultEncodingDir и Tcl_SetDefaultEncodingDir являются устарев‐ шими интерфейсами, лучше заменяемыми вызовами Tcl_GetEncodingSearchPath и Tcl_SetEncodingSearchPath. Они вызываются для доступа и установки пер‐ вого элемента списка searchPath. Поскольку Tcl ищет файлы данных коди‐ ровок в searchPath в порядке списка, эти процедуры устанавливают "по умолчанию" каталог, в котором искать файлы данных кодировок. ENCODING FILES Пространство не позволяет предварительно компилировать в Tcl каждый воз‐ можный алгоритм кодировки, поэтому многие кодировки хранятся на диске как динамически загружаемые файлы кодировок. Это поведение также поз‐ воляет пользователю создавать дополнительные файлы кодировок, которые могут быть загружены с помощью того же механизма. Эти файлы кодировок содержат информацию о таблицах и/или последовательностях экранирования, используемых для сопоставления между внешней кодировкой и Unicode. Внеш‐ няя кодировка может состоять из символов с одним байтом, несколькими байтами или двумя байтами. Каждая динамически загружаемая кодировка представлена как текстовый файл. Первая строка файла, начинающаяся с символа "#", является коммен‐ тарием, предоставляющим человекочитаемое описание файла. Следующая строка идентифицирует тип файла кодировки. Это может быть одна из следующих букв: [1] S Кодировка с одним байтом, где один символ всегда имеет длину один байт в кодировке. Пример - iso8859-1, используемая во мно‐ гих европейских языках. [2] D Кодировка с двумя байтами, где один символ всегда имеет длину два байта в кодировке. Пример - big5, используемая для китайско‐ го текста. [3] M Кодировка с несколькими байтами, где один символ может иметь длину один или два байта. Некоторые байты являются начальными, указывающими, что должен следовать другой байт, и вместе эти два байта представляют один символ. Другие байты не являются на‐ чальными и представляют себя. Пример - shiftjis, используемая на многих японских компьютерах. [4] E Кодировка с последовательностями экранирования, указывающая, что определённые последовательности байтов не представляют сим‐ волы, а команды, описывающие, как должны интерпретироваться сле‐ дующие байты. Остальные строки в файле зависят от типа. Случаи [1], [2] и [3] коллективно называются файлами кодировок на осно‐ ве таблиц. Строки в файле кодировки на основе таблиц имеют тот же фор‐ мат, что и этот пример, взятый из кодировки shiftjis (это не полный файл): # Encoding file: shiftjis, multi-byte M 003F 0 40 00 0000000100020003000400050006000700080009000A000B000C000D000E000F 0010001100120013001400150016001700180019001A001B001C001D001E001F 0020002100220023002400250026002700280029002A002B002C002D002E002F 0030003100320033003400350036003700380039003A003B003C003D003E003F 0040004100420043004400450046004700480049004A004B004C004D004E004F 0050005100520053005400550056005700580059005A005B005C005D005E005F 0060006100620063006400650066006700680069006A006B006C006D006E006F 0070007100720073007400750076007700780079007A007B007C007D203E007F 0080000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000FF61FF62FF63FF64FF65FF66FF67FF68FF69FF6AFF6BFF6CFF6DFF6EFF6F FF70FF71FF72FF73FF74FF75FF76FF77FF78FF79FF7AFF7BFF7CFF7DFF7EFF7F FF80FF81FF82FF83FF84FF85FF86FF87FF88FF89FF8AFF8BFF8CFF8DFF8EFF8F FF90FF91FF92FF93FF94FF95FF96FF97FF98FF99FF9AFF9BFF9CFF9DFF9EFF9F 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 81 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 300030013002FF0CFF0E30FBFF1AFF1BFF1FFF01309B309C00B4FF4000A8FF3E FFE3FF3F30FD30FE309D309E30034EDD30053006300730FC20152010FF0F005C 301C2016FF5C2026202520182019201C201DFF08FF0930143015FF3BFF3DFF5B FF5D30083009300A300B300C300D300E300F30103011FF0B221200B100D70000 00F7FF1D2260FF1CFF1E22662267221E22342642264000B0203220332103FFE5 FF0400A200A3FF05FF03FF06FF0AFF2000A72606260525CB25CF25CE25C725C6 25A125A025B325B225BD25BC203B301221922190219121933013000000000000 000000000000000000000000000000002208220B2286228722822283222A2229 000000000000000000000000000000002227222800AC21D221D4220022030000 0000000000000000000000000000000000000000222022A52312220222072261 2252226A226B221A223D221D2235222B222C0000000000000000000000000000 212B2030266F266D266A2020202100B6000000000000000025EF000000000000 Третья строка файла - три числа. Первое число - символ замены (в ша‐ рифке 16) для использования при преобразовании из UTF-8 в эту кодиров‐ ку. Второе число - 1, если этот файл представляет кодировку для шрифта символов, или 0 в противном случае. Последнее число (в десятичной сис‐ теме) - количество страниц данных, которые следуют. Последующие строки в примере выше - страницы, описывающие, как сопос‐ тавить из кодировки в 2-байтовый Unicode. Первая строка в странице ука‐ зывает номер страницы. За ней следуют 256 двухбайтных чисел, размещён‐ ных в 16 строках по 16 чисел. Для заданного символа в кодировке стар‐ ший байт этого символа используется для выбора страницы, а младший байт - как индекс для выбора одного из двухбайтных чисел на этой странице - полученное значение является соответствующим символом Unicode. Из об‐ зора примера выше видно, что символы 0x7E и 0x8163 в shiftjis соответ‐ ствуют 203E и 2026 в Unicode соответственно. За первой страницей следуют все остальные страницы, каждая в том же формате: одно число, идентифицирующее страницу, за которым следуют 256 двухбайтных символов Unicode. Если символ в кодировке сопоставляется символу Unicode 0000, это означает, что символ не существует. Если все символы на странице будут сопоставлены 0000, эту страницу можно пропус‐ тить. Случай [4] - файл кодировки с последовательностями экранирования. Стро‐ ки в этом типе файла имеют тот же формат, что и этот пример, взятый из кодировки iso2022-jp: # Encoding file: iso2022-jp, escape-driven E init {} final {} iso8859-1 \x1b(B jis0201 \x1b(J jis0208 \x1b$@ jis0208 \x1b$B jis0212 \x1b$(D gb2312 \x1b$A ksc5601 \x1b$(C В файле первый столбец представляет опцию, а второй столбец - связанное значение. init - строка для вывода или ожидания перед преобразованием первого символа, в то время как final - строка для вывода или ожидания после последнего символа. Все остальные опции - имена кодировок на ос‐ нове таблиц; связанное значение - последовательность экранирования, ко‐ торая отмечает эту кодировку. Используется синтаксис Tcl для значений; в приведённом выше примере, например, "{}" представляет пустую строку, а "\x1b" - символ 27. Когда Tcl_GetEncoding встречает имя кодировки, которое ещё не загруже‐ но, оно пытается загрузить файл кодировки с именем name.enc из подка‐ талога encoding каждого каталога, в котором Tcl ищет свою библиотеку сценариев. Если файл кодировки существует, но имеет неверный формат, сообщение об ошибке будет оставлено в interp. KEYWORDS utf, кодировка, преобразование Tcl 8.1 Tcl_GetEncoding(3)
Tcl_GetEncoding(3) Tcl Library Procedures Tcl_GetEncoding(3) ______________________________________________________________________________ NAME Tcl_GetEncoding, Tcl_FreeEncoding, Tcl_GetEncodingFromObj, Tcl_Ex‐ ternalToUtfDString, Tcl_ExternalToUtf, Tcl_UtfToExternalDString, Tcl_UtfToExternal, Tcl_WinTCharToUtf, Tcl_WinUtfToTChar, Tcl_GetEncod‐ ingName, Tcl_SetSystemEncoding, Tcl_GetEncodingNameFromEnvironment, Tcl_GetEncodingNames, Tcl_CreateEncoding, Tcl_GetEncodingSearchPath, Tcl_SetEncodingSearchPath, Tcl_GetDefaultEncodingDir, Tcl_SetDefault‐ EncodingDir - procedures for creating and using encodings SYNOPSIS #include <tcl.h> Tcl_Encoding Tcl_GetEncoding(interp, name) void Tcl_FreeEncoding(encoding) int Tcl_GetEncodingFromObj(interp, objPtr, encodingPtr) char * Tcl_ExternalToUtfDString(encoding, src, srcLen, dstPtr) char * Tcl_UtfToExternalDString(encoding, src, srcLen, dstPtr) int Tcl_ExternalToUtf(interp, encoding, src, srcLen, flags, statePtr, dst, dstLen, srcReadPtr, dstWrotePtr, dstCharsPtr) int Tcl_UtfToExternal(interp, encoding, src, srcLen, flags, statePtr, dst, dstLen, srcReadPtr, dstWrotePtr, dstCharsPtr) char * Tcl_WinTCharToUtf(tsrc, srcLen, dstPtr) TCHAR * Tcl_WinUtfToTChar(src, srcLen, dstPtr) const char * Tcl_GetEncodingName(encoding) int Tcl_SetSystemEncoding(interp, name) const char * Tcl_GetEncodingNameFromEnvironment(bufPtr) void Tcl_GetEncodingNames(interp) Tcl_Encoding Tcl_CreateEncoding(typePtr) Tcl_Obj * Tcl_GetEncodingSearchPath() int Tcl_SetEncodingSearchPath(searchPath) const char * Tcl_GetDefaultEncodingDir(void) void Tcl_SetDefaultEncodingDir(path) ARGUMENTS Tcl_Interp *interp (in) Interpreter to use for error reporting, or NULL if no error reporting is desired. const char *name (in) Name of encoding to load. Tcl_Encoding encoding (in) The encoding to query, free, or use for converting text. If encoding is NULL, the current system encoding is used. Tcl_Obj *objPtr (in) Name of encoding to get token for. Tcl_Encoding *encodingPtr (out) Points to storage where encoding token is to be written. const char *src (in) For the Tcl_Ex‐ ternalToUtf func‐ tions, an array of bytes in the speci‐ fied encoding that are to be converted to UTF-8. For the Tcl_UtfToExternal and Tcl_WinUtfToTChar functions, an array of UTF-8 characters to be converted to the specified encod‐ ing. const TCHAR *tsrc (in) An array of Windows TCHAR characters to convert to UTF-8. int srcLen (in) Length of src or tsrc in bytes. If the length is negative, the encoding-specific length of the string is used. Tcl_DString *dstPtr (out) Pointer to an unini‐ tialized or free Tcl_DString in which the converted result will be stored. int flags (in) Various flag bits OR- ed together. TCL_EN‐ CODING_START signi‐ fies that the source buffer is the first block in a (poten‐ tially multi-block) input stream, telling the conversion rou‐ tine to reset to an initial state and perform any initial‐ ization that needs to occur before the first byte is con‐ verted. TCL_ENCOD‐ ING_END signifies that the source buf‐ fer is the last block in a (potentially multi-block) input stream, telling the conversion routine to perform any finaliza‐ tion that needs to occur after the last byte is converted and then to reset to an initial state. TCL_ENCODING_STOPON‐ ERROR signifies that the conversion rou‐ tine should return immediately upon reading a source character that does not exist in the tar‐ get encoding; other‐ wise a default fall‐ back character will automatically be sub‐ stituted. Tcl_EncodingState *statePtr (in/out) Used when converting a (generally long or indefinite length) byte stream in a piece-by-piece fash‐ ion. The conversion routine stores its current state in *statePtr after src (the buffer contain‐ ing the current piece) has been con‐ verted; that state information must be passed back when con‐ verting the next piece of the stream so the conversion routine knows what state it was in when it left off at the end of the last piece. May be NULL, in which case the value specified for flags is ignored and the source buffer is assumed to contain the complete string to convert. char *dst (out) Buffer in which the converted result will be stored. No more than dstLen bytes will be stored in dst. int dstLen (in) The maximum length of the output buffer dst in bytes. int *srcReadPtr (out) Filled with the num‐ ber of bytes from src that were actually converted. This may be less than the original source length if there was a problem converting some source charac‐ ters. May be NULL. int *dstWrotePtr (out) Filled with the num‐ ber of bytes that were actually stored in the output buffer as a result of the conversion. May be NULL. int *dstCharsPtr (out) Filled with the num‐ ber of characters that correspond to the number of bytes stored in the output buffer. May be NULL. Tcl_DString *bufPtr (out) Storage for the pre‐ scribed system encod‐ ing name. const Tcl_EncodingType *typePtr (in) Structure that de‐ fines a new type of encoding. Tcl_Obj *searchPath (in) List of filesystem directories in which to search for encod‐ ing data files. const char *path (in) A path to the loca‐ tion of the encoding file. ______________________________________________________________________________ INTRODUCTION These routines convert between Tcl's internal character representation, UTF-8, and character representations used by various operating systems or file systems, such as Unicode, ASCII, or Shift-JIS. When operating on strings, such as such as obtaining the names of files or displaying characters using international fonts, the strings must be translated into one or possibly multiple formats that the various system calls can use. For instance, on a Japanese Unix workstation, a user might obtain a filename represented in the EUC-JP file encoding and then translate the characters to the jisx0208 font encoding in order to display the filename in a Tk widget. The purpose of the encoding package is to help bridge the translation gap. UTF-8 provides an intermediate stag‐ ing ground for all the various encodings. In the example above, text would be translated into UTF-8 from whatever file encoding the operat‐ ing system is using. Then it would be translated from UTF-8 into what‐ ever font encoding the display routines require. Some basic encodings are compiled into Tcl. Others can be defined by the user or dynamically loaded from encoding files in a platform-inde‐ pendent manner. DESCRIPTION Tcl_GetEncoding finds an encoding given its name. The name may refer to a built-in Tcl encoding, a user-defined encoding registered by call‐ ing Tcl_CreateEncoding, or a dynamically-loadable encoding file. The return value is a token that represents the encoding and can be used in subsequent calls to procedures such as Tcl_GetEncodingName, Tcl_FreeEn‐ coding, and Tcl_UtfToExternal. If the name did not refer to any known or loadable encoding, NULL is returned and an error message is returned in interp. The encoding package maintains a database of all encodings currently in use. The first time name is seen, Tcl_GetEncoding returns an encoding with a reference count of 1. If the same name is requested further times, then the reference count for that encoding is incremented with‐ out the overhead of allocating a new encoding and all its associated data structures. When an encoding is no longer needed, Tcl_FreeEncoding should be called to release it. When an encoding is no longer in use anywhere (i.e., it has been freed as many times as it has been gotten) Tcl_FreeEncoding will release all storage the encoding was using and delete it from the database. Tcl_GetEncodingFromObj treats the string representation of objPtr as an encoding name, and finds an encoding with that name, just as Tcl_GetEn‐ coding does. When an encoding is found, it is cached within the objPtr value for future reference, the Tcl_Encoding token is written to the storage pointed to by encodingPtr, and the value TCL_OK is returned. If no such encoding is found, the value TCL_ERROR is returned, and no writing to *encodingPtr takes place. Just as with Tcl_GetEncoding, the caller should call Tcl_FreeEncoding on the resulting encoding token when that token will no longer be used. Tcl_ExternalToUtfDString converts a source buffer src from the speci‐ fied encoding into UTF-8. The converted bytes are stored in dstPtr, which is then null-terminated. The caller should eventually call Tcl_DStringFree to free any information stored in dstPtr. When con‐ verting, if any of the characters in the source buffer cannot be repre‐ sented in the target encoding, a default fallback character will be used. The return value is a pointer to the value stored in the DString. Tcl_ExternalToUtf converts a source buffer src from the specified en‐ coding into UTF-8. Up to srcLen bytes are converted from the source buffer and up to dstLen converted bytes are stored in dst. In all cases, *srcReadPtr is filled with the number of bytes that were suc‐ cessfully converted from src and *dstWrotePtr is filled with the corre‐ sponding number of bytes that were stored in dst. The return value is one of the following: TCL_OK All bytes of src were converted. TCL_CONVERT_NOSPACE The destination buffer was not large enough for all of the con‐ verted data; as many characters as could fit were converted though. TCL_CONVERT_MULTIBYTE The last few bytes in the source buffer were the beginning of a multibyte sequence, but more bytes were needed to complete this se‐ quence. A subsequent call to the conversion routine should pass a buffer containing the unconverted bytes that remained in src plus some further bytes from the source stream to properly convert the for‐ merly split-up multibyte sequence. TCL_CONVERT_SYNTAX The source buffer contained an in‐ valid character sequence. This may occur if the input stream has been damaged or if the input encoding method was misidentified. TCL_CONVERT_UNKNOWN The source buffer contained a char‐ acter that could not be represented in the target encoding and TCL_EN‐ CODING_STOPONERROR was specified. Tcl_UtfToExternalDString converts a source buffer src from UTF-8 into the specified encoding. The converted bytes are stored in dstPtr, which is then terminated with the appropriate encoding-specific null. The caller should eventually call Tcl_DStringFree to free any informa‐ tion stored in dstPtr. When converting, if any of the characters in the source buffer cannot be represented in the target encoding, a de‐ fault fallback character will be used. The return value is a pointer to the value stored in the DString. Tcl_UtfToExternal converts a source buffer src from UTF-8 into the specified encoding. Up to srcLen bytes are converted from the source buffer and up to dstLen converted bytes are stored in dst. In all cases, *srcReadPtr is filled with the number of bytes that were suc‐ cessfully converted from src and *dstWrotePtr is filled with the corre‐ sponding number of bytes that were stored in dst. The return values are the same as the return values for Tcl_ExternalToUtf. Tcl_WinUtfToTChar and Tcl_WinTCharToUtf are Windows-only convenience functions for converting between UTF-8 and Windows strings based on the TCHAR type which is by convention a Unicode character on Windows NT. Tcl_GetEncodingName is roughly the inverse of Tcl_GetEncoding. Given an encoding, the return value is the name argument that was used to create the encoding. The string returned by Tcl_GetEncodingName is only guaranteed to persist until the encoding is deleted. The caller must not modify this string. Tcl_SetSystemEncoding sets the default encoding that should be used whenever the user passes a NULL value for the encoding argument to any of the other encoding functions. If name is NULL, the system encoding is reset to the default system encoding, binary. If the name did not refer to any known or loadable encoding, TCL_ERROR is returned and an error message is left in interp. Otherwise, this procedure increments the reference count of the new system encoding, decrements the refer‐ ence count of the old system encoding, and returns TCL_OK. Tcl_GetEncodingNameFromEnvironment provides a means for the Tcl library to report the encoding name it believes to be the correct one to use as the system encoding, based on system calls and examination of the envi‐ ronment suitable for the platform. It accepts bufPtr, a pointer to an uninitialized or freed Tcl_DString and writes the encoding name to it. The Tcl_DStringValue is returned. Tcl_GetEncodingNames sets the interp result to a list consisting of the names of all the encodings that are currently defined or can be dynami‐ cally loaded, searching the encoding path specified by Tcl_SetDefault‐ EncodingDir. This procedure does not ensure that the dynamically-load‐ able encoding files contain valid data, but merely that they exist. Tcl_CreateEncoding defines a new encoding and registers the C proce‐ dures that are called back to convert between the encoding and UTF-8. Encodings created by Tcl_CreateEncoding are thereafter visible in the database used by Tcl_GetEncoding. Just as with the Tcl_GetEncoding procedure, the return value is a token that represents the encoding and can be used in subsequent calls to other encoding functions. Tcl_Cre‐ ateEncoding returns an encoding with a reference count of 1. If an en‐ coding with the specified name already exists, then its entry in the database is replaced with the new encoding; the token for the old en‐ coding will remain valid and continue to behave as before, but users of the new token will now call the new encoding procedures. The typePtr argument to Tcl_CreateEncoding contains information about the name of the encoding and the procedures that will be called to con‐ vert between this encoding and UTF-8. It is defined as follows: typedef struct Tcl_EncodingType { const char *encodingName; Tcl_EncodingConvertProc *toUtfProc; Tcl_EncodingConvertProc *fromUtfProc; Tcl_EncodingFreeProc *freeProc; ClientData clientData; int nullSize; } Tcl_EncodingType; The encodingName provides a string name for the encoding, by which it can be referred in other procedures such as Tcl_GetEncoding. The toUtfProc refers to a callback procedure to invoke to convert text from this encoding into UTF-8. The fromUtfProc refers to a callback proce‐ dure to invoke to convert text from UTF-8 into this encoding. The freeProc refers to a callback procedure to invoke when this encoding is deleted. The freeProc field may be NULL. The clientData contains an arbitrary one-word value passed to toUtfProc, fromUtfProc, and freeProc whenever they are called. Typically, this is a pointer to a data structure containing encoding-specific information that can be used by the callback procedures. For instance, two very similar encodings such as ascii and macRoman may use the same callback procedure, but use dif‐ ferent values of clientData to control its behavior. The nullSize specifies the number of zero bytes that signify end-of-string in this encoding. It must be 1 (for single-byte or multi-byte encodings like ASCII or Shift-JIS) or 2 (for double-byte encodings like Unicode). Constant-sized encodings with 3 or more bytes per character (such as CNS11643) are not accepted. The callback procedures toUtfProc and fromUtfProc should match the type Tcl_EncodingConvertProc: typedef int Tcl_EncodingConvertProc( ClientData clientData, const char *src, int srcLen, int flags, Tcl_EncodingState *statePtr, char *dst, int dstLen, int *srcReadPtr, int *dstWrotePtr, int *dstCharsPtr); The toUtfProc and fromUtfProc procedures are called by the Tcl_Ex‐ ternalToUtf or Tcl_UtfToExternal family of functions to perform the ac‐ tual conversion. The clientData parameter to these procedures is the same as the clientData field specified to Tcl_CreateEncoding when the encoding was created. The remaining arguments to the callback proce‐ dures are the same as the arguments, documented at the top, to Tcl_Ex‐ ternalToUtf or Tcl_UtfToExternal, with the following exceptions. If the srcLen argument to one of those high-level functions is negative, the value passed to the callback procedure will be the appropriate en‐ coding-specific string length of src. If any of the srcReadPtr, dst‐ WrotePtr, or dstCharsPtr arguments to one of the high-level functions is NULL, the corresponding value passed to the callback procedure will be a non-NULL location. The callback procedure freeProc, if non-NULL, should match the type Tcl_EncodingFreeProc: typedef void Tcl_EncodingFreeProc( ClientData clientData); This freeProc function is called when the encoding is deleted. The clientData parameter is the same as the clientData field specified to Tcl_CreateEncoding when the encoding was created. Tcl_GetEncodingSearchPath and Tcl_SetEncodingSearchPath are called to access and set the list of filesystem directories searched for encoding data files. The value returned by Tcl_GetEncodingSearchPath is the value stored by the last successful call to Tcl_SetEncodingSearchPath. If no calls to Tcl_SetEncodingSearchPath have occurred, Tcl will compute an initial value based on the environment. There is one encoding search path for the entire process, shared by all threads in the process. Tcl_SetEncodingSearchPath stores searchPath and returns TCL_OK, unless searchPath is not a valid Tcl list, which causes TCL_ERROR to be re‐ turned. The elements of searchPath are not verified as existing read‐ able filesystem directories. When searching for encoding data files takes place, and non-existent or non-readable filesystem directories on the searchPath are silently ignored. Tcl_GetDefaultEncodingDir and Tcl_SetDefaultEncodingDir are obsolete interfaces best replaced with calls to Tcl_GetEncodingSearchPath and Tcl_SetEncodingSearchPath. They are called to access and set the first element of the searchPath list. Since Tcl searches searchPath for en‐ coding data files in list order, these routines establish the “default” directory in which to find encoding data files. ENCODING FILES Space would prohibit precompiling into Tcl every possible encoding al‐ gorithm, so many encodings are stored on disk as dynamically-loadable encoding files. This behavior also allows the user to create addi‐ tional encoding files that can be loaded using the same mechanism. These encoding files contain information about the tables and/or escape sequences used to map between an external encoding and Unicode. The external encoding may consist of single-byte, multi-byte, or double- byte characters. Each dynamically-loadable encoding is represented as a text file. The initial line of the file, beginning with a “#” symbol, is a comment that provides a human-readable description of the file. The next line identifies the type of encoding file. It can be one of the following letters: [1] S A single-byte encoding, where one character is always one byte long in the encoding. An example is iso8859-1, used by many Eu‐ ropean languages. [2] D A double-byte encoding, where one character is always two bytes long in the encoding. An example is big5, used for Chinese text. [3] M A multi-byte encoding, where one character may be either one or two bytes long. Certain bytes are lead bytes, indicating that another byte must follow and that together the two bytes repre‐ sent one character. Other bytes are not lead bytes and repre‐ sent themselves. An example is shiftjis, used by many Japanese computers. [4] E An escape-sequence encoding, specifying that certain sequences of bytes do not represent characters, but commands that describe how following bytes should be interpreted. The rest of the lines in the file depend on the type. Cases [1], [2], and [3] are collectively referred to as table-based en‐ coding files. The lines in a table-based encoding file are in the same format as this example taken from the shiftjis encoding (this is not the complete file): # Encoding file: shiftjis, multi-byte M 003F 0 40 00 0000000100020003000400050006000700080009000A000B000C000D000E000F 0010001100120013001400150016001700180019001A001B001C001D001E001F 0020002100220023002400250026002700280029002A002B002C002D002E002F 0030003100320033003400350036003700380039003A003B003C003D003E003F 0040004100420043004400450046004700480049004A004B004C004D004E004F 0050005100520053005400550056005700580059005A005B005C005D005E005F 0060006100620063006400650066006700680069006A006B006C006D006E006F 0070007100720073007400750076007700780079007A007B007C007D203E007F 0080000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000FF61FF62FF63FF64FF65FF66FF67FF68FF69FF6AFF6BFF6CFF6DFF6EFF6F FF70FF71FF72FF73FF74FF75FF76FF77FF78FF79FF7AFF7BFF7CFF7DFF7EFF7F FF80FF81FF82FF83FF84FF85FF86FF87FF88FF89FF8AFF8BFF8CFF8DFF8EFF8F FF90FF91FF92FF93FF94FF95FF96FF97FF98FF99FF9AFF9BFF9CFF9DFF9EFF9F 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 81 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 300030013002FF0CFF0E30FBFF1AFF1BFF1FFF01309B309C00B4FF4000A8FF3E FFE3FF3F30FD30FE309D309E30034EDD30053006300730FC20152010FF0F005C 301C2016FF5C2026202520182019201C201DFF08FF0930143015FF3BFF3DFF5B FF5D30083009300A300B300C300D300E300F30103011FF0B221200B100D70000 00F7FF1D2260FF1CFF1E22662267221E22342642264000B0203220332103FFE5 FF0400A200A3FF05FF03FF06FF0AFF2000A72606260525CB25CF25CE25C725C6 25A125A025B325B225BD25BC203B301221922190219121933013000000000000 000000000000000000000000000000002208220B2286228722822283222A2229 000000000000000000000000000000002227222800AC21D221D4220022030000 0000000000000000000000000000000000000000222022A52312220222072261 2252226A226B221A223D221D2235222B222C0000000000000000000000000000 212B2030266F266D266A2020202100B6000000000000000025EF000000000000 The third line of the file is three numbers. The first number is the fallback character (in base 16) to use when converting from UTF-8 to this encoding. The second number is a 1 if this file represents the encoding for a symbol font, or 0 otherwise. The last number (in base 10) is how many pages of data follow. Subsequent lines in the example above are pages that describe how to map from the encoding into 2-byte Unicode. The first line in a page identifies the page number. Following it are 256 double-byte numbers, arranged as 16 rows of 16 numbers. Given a character in the encoding, the high byte of that character is used to select which page, and the low byte of that character is used as an index to select one of the double-byte numbers in that page - the value obtained being the corre‐ sponding Unicode character. By examination of the example above, one can see that the characters 0x7E and 0x8163 in shiftjis map to 203E and 2026 in Unicode, respectively. Following the first page will be all the other pages, each in the same format as the first: one number identifying the page followed by 256 double-byte Unicode characters. If a character in the encoding maps to the Unicode character 0000, it means that the character does not actu‐ ally exist. If all characters on a page would map to 0000, that page can be omitted. Case [4] is the escape-sequence encoding file. The lines in an this type of file are in the same format as this example taken from the iso2022-jp encoding: # Encoding file: iso2022-jp, escape-driven E init {} final {} iso8859-1 \x1b(B jis0201 \x1b(J jis0208 \x1b$@ jis0208 \x1b$B jis0212 \x1b$(D gb2312 \x1b$A ksc5601 \x1b$(C In the file, the first column represents an option and the second col‐ umn is the associated value. init is a string to emit or expect before the first character is converted, while final is a string to emit or expect after the last character. All other options are names of table- based encodings; the associated value is the escape-sequence that marks that encoding. Tcl syntax is used for the values; in the above exam‐ ple, for instance, “{}” represents the empty string and “\x1b” repre‐ sents character 27. When Tcl_GetEncoding encounters an encoding name that has not been loaded, it attempts to load an encoding file called name.enc from the encoding subdirectory of each directory that Tcl searches for its script library. If the encoding file exists, but is malformed, an er‐ ror message will be left in interp. KEYWORDS utf, encoding, convert Tcl 8.1 Tcl_GetEncoding(3)
Tcl_BooleanObj(3) Процедуры библиотеки Tcl Tcl_BooleanObj(3) ______________________________________________________________________________ NAME Tcl_NewBooleanObj, Tcl_SetBooleanObj, Tcl_GetBooleanFromObj - хранение/извлечение логического значения в Tcl_Obj SYNOPSIS #include <tcl.h> Tcl_Obj * Tcl_NewBooleanObj(intValue) Tcl_SetBooleanObj(objPtr, intValue) int Tcl_GetBooleanFromObj(interp, objPtr, intPtr) ARGUMENTS int intValue (in) Целочисленное значение для хранения как логического значения в Tcl_Obj. Tcl_Obj *objPtr (in/out) Указатель на Tcl_Obj, в котором нужно хранить или из которого извлекать логическое значение. Tcl_Interp *interp (in/out) Если логическое значение не может быть извлечено, сообщение об ошибке оставляется в результате интерпретатора, если interp не равно NULL. int *intPtr (out) Указатель на место, где Tcl_GetBoolean‐ FromObj хранит логическое значение (0 или 1), полученное из objPtr. ______________________________________________________________________________ DESCRIPTION Эти процедуры используются для передачи логических значений в Tcl и из Tcl в виде Tcl_Obj. При хранении логического значения в Tcl_Obj любое ненулевое целочисленное значение в intValue считается логическим значением 1, а целочисленное значение 0 считается логическим значением 0. Tcl_NewBooleanObj создаёт новый Tcl_Obj, хранит в нём логическое значение intValue и возвращает указатель на новый Tcl_Obj. Новый Tcl_Obj имеет счётчик ссылок, равный нулю. Tcl_SetBooleanObj принимает objPtr, указатель на существующий Tcl_Obj, и хранит в Tcl_Obj *objPtr логическое значение intValue. Это операция записи в *objPtr, поэтому objPtr должен быть несвязанным. Попытки записи в связанный Tcl_Obj вызовут панику. Успешная запись intValue в *objPtr подразумевает освобождение любого предыдущего значения, хранившегося в *objPtr. Tcl_GetBooleanFromObj пытается извлечь логическое значение из значения, хранящегося в *objPtr. Если objPtr содержит строковое значение, распознаваемое Tcl_GetBoolean, то распознанное логическое значение записывается по адресу, указанному intPtr. Если objPtr содержит любое значение, распознаваемое как число Tcl, то если это значение равно нулю, записывается 0 по адресу, указанному intPtr, а если значение ненулевое, записывается 1 по адресу, указанному intPtr. Во всех случаях, когда значение записывается по адресу, указанному intPtr, Tcl_GetBooleanFromObj возвращает TCL_OK. Если значение objPtr не соответствует ни одному из указанных условий, возвращается TCL_ERROR, и сообщение об ошибке оставляется в результате интерпретатора, если interp не равно NULL. Tcl_GetBooleanFromObj также может изменить внутренние поля *objPtr, чтобы будущие вызовы Tcl_GetBooleanFromObj для того же objPtr выполнялись более эффективно. Обратите внимание, что процедуры Tcl_GetBooleanFromObj и Tcl_GetBoolean не являются функциональными эквивалентами. Множество значений, для которых Tcl_GetBooleanFromObj возвращает TCL_OK, строго больше, чем множество значений, для которых Tcl_GetBoolean делает то же самое. Например, значение "5", переданное Tcl_GetBooleanFromObj, приведёт к возврату TCL_OK (и логическому значению 1), в то время как то же значение, переданное Tcl_GetBoolean, приведёт к возврату TCL_ERROR. SEE ALSO Tcl_NewObj, Tcl_IsShared, Tcl_GetBoolean KEYWORDS boolean, value Tcl 8.5 Tcl_BooleanObj(3)
Tcl_BooleanObj(3) Tcl Library Procedures Tcl_BooleanObj(3) ______________________________________________________________________________ NAME Tcl_NewBooleanObj, Tcl_SetBooleanObj, Tcl_GetBooleanFromObj - store/re‐ trieve boolean value in a Tcl_Obj SYNOPSIS #include <tcl.h> Tcl_Obj * Tcl_NewBooleanObj(intValue) Tcl_SetBooleanObj(objPtr, intValue) int Tcl_GetBooleanFromObj(interp, objPtr, intPtr) ARGUMENTS int intValue (in) Integer value to be stored as a bool‐ ean value in a Tcl_Obj. Tcl_Obj *objPtr (in/out) Points to the Tcl_Obj in which to store, or from which to retrieve a boolean value. Tcl_Interp *interp (in/out) If a boolean value cannot be re‐ trieved, an error message is left in the interpreter's result value unless interp is NULL. int *intPtr (out) Points to place where Tcl_GetBoolean‐ FromObj stores the boolean value (0 or 1) obtained from objPtr. ______________________________________________________________________________ DESCRIPTION These procedures are used to pass boolean values to and from Tcl as Tcl_Obj's. When storing a boolean value into a Tcl_Obj, any non-zero integer value in intValue is taken to be the boolean value 1, and the integer value 0 is taken to be the boolean value 0. Tcl_NewBooleanObj creates a new Tcl_Obj, stores the boolean value int‐ Value in it, and returns a pointer to the new Tcl_Obj. The new Tcl_Obj has reference count of zero. Tcl_SetBooleanObj accepts objPtr, a pointer to an existing Tcl_Obj, and stores in the Tcl_Obj *objPtr the boolean value intValue. This is a write operation on *objPtr, so objPtr must be unshared. Attempts to write to a shared Tcl_Obj will panic. A successful write of intValue into *objPtr implies the freeing of any former value stored in *objPtr. Tcl_GetBooleanFromObj attempts to retrieve a boolean value from the value stored in *objPtr. If objPtr holds a string value recognized by Tcl_GetBoolean, then the recognized boolean value is written at the ad‐ dress given by intPtr. If objPtr holds any value recognized as a num‐ ber by Tcl, then if that value is zero a 0 is written at the address given by intPtr and if that value is non-zero a 1 is written at the ad‐ dress given by intPtr. In all cases where a value is written at the address given by intPtr, Tcl_GetBooleanFromObj returns TCL_OK. If the value of objPtr does not meet any of the conditions above, then TCL_ER‐ ROR is returned and an error message is left in the interpreter's re‐ sult unless interp is NULL. Tcl_GetBooleanFromObj may also make changes to the internal fields of *objPtr so that future calls to Tcl_GetBooleanFromObj on the same objPtr can be performed more effi‐ ciently. Note that the routines Tcl_GetBooleanFromObj and Tcl_GetBoolean are not functional equivalents. The set of values for which Tcl_GetBooleanFro‐ mObj will return TCL_OK is strictly larger than the set of values for which Tcl_GetBoolean will do the same. For example, the value “5” passed to Tcl_GetBooleanFromObj will lead to a TCL_OK return (and the boolean value 1), while the same value passed to Tcl_GetBoolean will lead to a TCL_ERROR return. SEE ALSO Tcl_NewObj, Tcl_IsShared, Tcl_GetBoolean KEYWORDS boolean, value Tcl 8.5 Tcl_BooleanObj(3)
Tcl_TraceVar(3) Процедуры Tcl Библиотеки Tcl_TraceVar(3) ______________________________________________________________________________ ИМЯ Tcl_TraceVar, Tcl_TraceVar2, Tcl_UntraceVar, Tcl_UntraceVar2, Tcl_Var‐ TraceInfo, Tcl_VarTraceInfo2 - мониторинг доступа к переменной СИНОПСИС #include <tcl.h> int Tcl_TraceVar(interp, varName, flags, proc, clientData) int Tcl_TraceVar2(interp, name1, name2, flags, proc, clientData) Tcl_UntraceVar(interp, varName, flags, proc, clientData) Tcl_UntraceVar2(interp, name1, name2, flags, proc, clientData) ClientData Tcl_VarTraceInfo(interp, varName, flags, proc, prevClientData) ClientData Tcl_VarTraceInfo2(interp, name1, name2, flags, proc, prevClientData) АРГУМЕНТЫ Tcl_Interp *interp (in) Интерпретатор, содержащий переменную. const char *varName (in) Имя переменной. Может ссылаться на скалярную переменную, на массивную переменную без индекса или на массивную переменную с индексом в скобках. int flags (in) Комбинация значений, объединённых через OR: TCL_TRACE_READS, TCL_TRACE_WRITES, TCL_TRACE_UNSETS, TCL_TRACE_ARRAY, TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY, TCL_TRACE_RESULT_DYNAMIC и TCL_TRACE_RESULT_OB‐ JECT. Не все флаги используются во всех процедурах. См. ниже для дополнительной информации. Tcl_VarTraceProc *proc (in) Процедура, которая будет вызвана при каждом из отслеживаемых операций. ClientData clientData (in) Произвольное значение одного слова для передачи в proc. const char *name1 (in) Имя скалярной или массивной переменной (без индекса массива). const char *name2 (in) Для трейса элемента массива указывает индекс элемента. Для трейсов скалярных переменных или всего массива равно NULL. ClientData prevClientData (in) Если не NULL, содержит последнее значение, возвращенное Tcl_VarTraceInfo или Tcl_VarTraceInfo2, чтобы этот вызов возвращал информацию о следующем трейсе. Если NULL, этот вызов возвращает информацию о первом трейсе. ______________________________________________________________________________ ОПИСАНИЕ Tcl_TraceVar позволяет процедуре C мониторить и контролировать доступ к переменной Tcl, так что процедура C вызывается всякий раз, когда переменная читается, записывается или отменяется. Если трейс создан успешно, Tcl_TraceVar возвращает TCL_OK. Если произошла ошибка (например, varName указывает на элемент массива, но фактическая переменная не является массивом), то возвращается TCL_ERROR, и сообщение об ошибке оставляется в результате интерпретатора. Аргумент flags в Tcl_TraceVar указывает, когда должна вызываться процедура трейса, и предоставляет информацию для настройки трейса. Он состоит из комбинации значений, объединённых через OR, из следующих: TCL_GLOBAL_ONLY Обычно переменная ищется на текущем уровне вызова процедуры; если этот бит установлен, переменная будет искаться на глобальном уровне, игнорируя любые активные процедуры. TCL_NAMESPACE_ONLY Обычно переменная ищется на текущем уровне вызова процедуры; если этот бит установлен, переменная будет искаться в текущем пространстве имён, игнорируя любые активные процедуры. TCL_TRACE_READS Вызывать proc всякий раз, когда предпринимается попытка прочитать переменную. TCL_TRACE_WRITES Вызывать proc всякий раз, когда предпринимается попытка изменить переменную. TCL_TRACE_UNSETS Вызывать proc всякий раз, когда переменная отменяется. Переменная может быть отменена явно с помощью команды unset, или неявно, когда процедура возвращается (её локальные переменные автоматически отменяются) или когда интерпретатор удаляется (все переменные автоматически отменяются). TCL_TRACE_ARRAY Вызывать proc всякий раз, когда вызывается команда array. Это даёт процедуре трейса возможность обновить массив перед вызовом array names или array get. Обратите внимание, что это вызывается перед array set, но это запустит трейсы записи. TCL_TRACE_RESULT_DYNAMIC Результат вызова proc — это динамически выделенная строка, которая будет освобождена библиотекой Tcl с помощью вызова ckfree. Не может быть указан одновременно с TCL_TRACE_RESULT_OBJECT. TCL_TRACE_RESULT_OBJECT Результат вызова proc — это Tcl_Obj* (приведённый к char*), с счётчиком ссылок не менее одного. Владение этой ссылкой будет передано ядру Tcl для освобождения (когда ядро закончит с ней) с помощью вызова Tcl_DecrRefCount. Не может быть указан одновременно с TCL_TRACE_RESULT_DYNAMIC. Всякий раз, когда одна из указанных операций выполняется с переменной, proc будет вызвана. Она должна иметь аргументы и результат, соответствующие типу Tcl_VarTraceProc: typedef char *Tcl_VarTraceProc( ClientData clientData, Tcl_Interp *interp, const char *name1, const char *name2, int flags); Параметры clientData и interp будут иметь те же значения, что и те, которые были переданы в Tcl_TraceVar при создании трейса. ClientData обычно указывает на структуру данных, специфичную для приложения, которая описывает, что делать при вызове proc. Name1 и name2 дают имя отслеживаемой переменной в обычной форме из двух частей (см. описание Tcl_TraceVar2 ниже для деталей). Flags — это комбинация битов, объединённых через OR, предоставляющая несколько частей информации. Один из битов TCL_TRACE_READS, TCL_TRACE_WRITES, TCL_TRACE_ARRAY или TCL_TRACE_UNSETS будет установлен в flags, чтобы указать, какая операция выполняется с переменной. Бит TCL_GLOBAL_ONLY будет установлен, когда доступная переменная — глобальная и недоступная с текущего уровня вызова процедуры: процедура трейса должна передать этот флаг обратно в процедуры, связанные с переменными, такие как Tcl_GetVar, если она пытается получить доступ к переменной. Бит TCL_NAMESPACE_ONLY будет установлен, когда доступная переменная — в пространстве имён и недоступная с текущего уровня вызова процедуры: процедура трейса должна передать этот флаг обратно в процедуры, связанные с переменными, такие как Tcl_GetVar, если она пытается получить доступ к переменной. Бит TCL_TRACE_DESTROYED будет установлен в flags, если трейс готовится к уничтожению; эта информация может быть полезной для proc, чтобы она могла очистить свои собственные внутренние структуры данных (см. раздел TCL_TRACE_DESTROYED ниже для дополнительных деталей). Наконец, бит TCL_INTERP_DESTROYED будет установлен, если весь интерпретатор уничтожается. Когда этот бит установлен, proc должна быть особенно осторожной в том, что она делает (см. раздел TCL_INTERP_DESTROYED ниже). Возвращаемое значение процедуры трейса обычно должно быть NULL; см. ВОЗВРАТ ОШИБОК ниже для информации о других возможностях. Tcl_UntraceVar может быть использована для удаления трейса. Если переменная, указанная интерпретатором, varName и flags, имеет трейс, установленный с flags, proc и clientData, то соответствующий трейс удаляется. Если такого трейса не существует, то вызов Tcl_UntraceVar не имеет эффекта. Те же биты действительны для flags, как и для вызовов Tcl_TraceVar. Tcl_VarTraceInfo может быть использована для получения информации о трейсах, установленных на данной переменной. Возвращаемое значение из Tcl_VarTraceInfo — это clientData, связанное с определённым трейсом. Трейс должен быть на переменной, указанной аргументами interp, varName и flags (используются только биты TCL_GLOBAL_ONLY и TCL_NAMESPACE_ONLY из flags; другие биты игнорируются), и его процедура трейса должна быть той же, что и proc. Если аргумент prevClientData равен NULL, то возвращаемое значение соответствует первому (самому недавно созданному) совпадающему трейсу или NULL, если совпадающих трейсов нет. Если аргумент prevClientData не равен NULL, то он должен быть возвращаемым значением из предыдущего вызова Tcl_VarTraceInfo. В этом случае новое возвращаемое значение будет соответствовать следующему совпадающему трейсу после того, чей clientData совпадает с prevClientData, или NULL, если ни один трейс не совпадает с prevClientData или если нет больше совпадающих трейсов после него. Этот механизм позволяет перебирать все трейсы для данной переменной, которые имеют одинаковую proc. ИМЕНА С ДВУМЯ ЧАСТЯМИ Процедуры Tcl_TraceVar2, Tcl_UntraceVar2 и Tcl_VarTraceInfo2 идентичны Tcl_TraceVar, Tcl_UntraceVar и Tcl_VarTraceInfo соответственно, за исключением того, что имя переменной состоит из двух частей. Name1 указывает имя скалярной переменной или массива, а name2 указывает имя элемента внутри массива. Когда name2 равен NULL, name1 может содержать как имя массива, так и имя элемента: если имя содержит открывающую скобку и заканчивается закрывающей скобкой, то значение между скобками трактуется как имя элемента (которое может иметь любое строковое значение), а символы перед первой открывающей скобкой трактуются как имя массивной переменной. Если name2 равен NULL и name1 не ссылается на элемент массива, это означает, что переменная является скалярной или трейс устанавливается на весь массив, а не на отдельный элемент (см. ТРЕЙСЫ ВСЕГО МАССИВА ниже для дополнительной информации). ДОСТУП К ПЕРЕМЕННЫМ ВО ВРЕМЯ ТРЕЙСОВ Во время трейсов чтения, записи и массива процедура трейса может читать, записывать или отменять отслеживаемую переменную с помощью Tcl_GetVar2, Tcl_SetVar2 и других процедур. Пока proc выполняется, трейсы временно отключены для переменной, так что вызовы Tcl_GetVar2 и Tcl_SetVar2 не вызовут proc или другие процедуры трейса снова. Отключение происходит только для переменной, чья процедура трейса активна; доступы к другим переменным всё ещё будут отслеживаться. Однако, если переменная отменяется во время трейса чтения или записи, то трейсы отмены будут вызваны. Во время трейсов отмены переменная уже полностью удалена. Процедура трейса может читать или записывать переменную, но это будет новая версия переменной. Трейсы не отключены во время трейсов отмены, как в случае с трейсами чтения и записи, но существующие трейсы были удалены из переменной перед вызовом любых процедур трейса. Если новые трейсы устанавливаются процедурами трейса отмены, эти трейсы будут вызваны при доступах к переменной процедурами трейса. ВРЕМЯ ВЫЗОВА ОБРАТНОГО ВЫЗОВА Когда указан трейс чтения для переменной, процедура трейса будет вызвана всякий раз, когда значение переменной читается. Это включает команды set Tcl, $-нотацию в командах Tcl и вызовы процедур Tcl_GetVar и Tcl_GetVar2. Proc вызывается непосредственно перед возвратом значения переменной. Она может изменить значение переменной, чтобы повлиять на то, что возвращается при отслеживаемом доступе. Если она отменяет переменную, то доступ вернёт ошибку, как будто переменная никогда не существовала. Когда указан трейс записи для переменной, процедура трейса будет вызвана всякий раз, когда значение переменной модифицируется. Это включает команды set, команды, которые модифицируют переменные как побочный эффект (такие как catch и scan), и вызовы процедур Tcl_SetVar и Tcl_SetVar2. Proc будет вызвана после модификации значения переменной, но перед возвратом нового значения переменной. Она может изменить значение переменной, чтобы переопределить изменение и определить значение, которое фактически возвращается при отслеживаемом доступе. Если она удаляет переменную, то отслеживаемый доступ вернёт пустую строку. Когда указан трейс массива, процедура трейса будет вызвана в начале реализации команды array, перед тем, как будут вызваны операции, такие как get, set или names. Процедура трейса может модифицировать элементы массива с помощью Tcl_SetVar и Tcl_SetVar2. Когда указан трейс отмены, процедура трейса будет вызвана всякий раз, когда переменная уничтожается. Трейсы будут вызваны после того, как переменная была полностью отменена. ТРЕЙСЫ ВСЕГО МАССИВА Если вызов Tcl_TraceVar или Tcl_TraceVar2 указывает имя массивной переменной без индекса массива, то трейс устанавливается на весь массив. Это означает, что proc будет вызвана всякий раз, когда любой элемент массива доступен способами, указанными в flags. Когда массив отменяется, трейс всего массива будет вызван только один раз, с name1, равным имени массива, и name2 равным NULL; он не будет вызван один раз для каждого элемента. НЕСКОЛЬКО ТРЕЙСОВ Возможна ситуация, когда несколько трейсов существуют на одной переменной. В этом случае все процедуры трейса будут вызваны при каждом доступе, в порядке от самого недавно созданного к наименее недавно созданному. Когда существуют трейсы всего массива для массива, а также трейсы на отдельных элементах, трейсы всего массива вызываются перед трейсами отдельных элементов. Если трейс чтения или записи отменяет переменную, то все трейсы отмены будут вызваны, но оставшаяся часть трейсов чтения и записи будет пропущена. ВОЗВРАТ ОШИБОК В нормальных условиях процедуры трейса должны возвращать NULL, указывая на успешное завершение. Если proc возвращает ненулевое значение, это означает, что произошла ошибка. Возвращаемое значение должно быть указателем на статическую строку, содержащую сообщение об ошибке, если (ровно один из) флагов TCL_TRACE_RESULT_DYNAMIC и TCL_TRACE_RESULT_OBJECT установлен, что указывает, что результат — это либо динамическая строка (для освобождения с помощью ckfree), либо Tcl_Obj* (приведённый к char* и для освобождения с помощью Tcl_DecrRefCount), содержащая сообщение об ошибке. Если процедура трейса возвращает ошибку, дальнейшие трейсы для доступа не вызываются, и отслеживаемый доступ прерывается с данным сообщением. Процедуры трейса могут использовать эту возможность, чтобы сделать переменные только для чтения, например (но обратите внимание, что значение переменной уже будет изменено перед вызовом процедуры трейса, так что процедура трейса должна будет восстановить правильное значение). Возвращаемое значение из proc используется только во время трейсов чтения и записи. Во время трейсов отмены возвращаемое значение игнорируется, и все релевантные процедуры трейса всегда будут вызваны. ОГРАНИЧЕНИЯ Процедура трейса может быть вызвана в любое время, даже когда в интерпретаторе хранятся частично сформированные результаты. Если процедура трейса делает что-либо, что может повредить этот результат (например, вызывает Tcl_Eval), то она должна использовать процедуры Tcl_SaveInterpState и связанные с ними, чтобы сохранить и восстановить исходное состояние интерпретатора перед возвратом. НЕОПРЕДЕЛЕННЫЕ ПЕРЕМЕННЫЕ Допустимо установить трейс на неопределённую переменную. Переменная будет всё ещё выглядеть неопределённой до первого раза, когда её значение устанавливается. Если неопределённая переменная трейсируется и затем отменяется, отменение завершится ошибкой ("нет такой переменной"), но процедура трейса всё равно будет вызвана. ФЛАГ TCL_TRACE_DESTROYED В обратном вызове отмены в proc бит TCL_TRACE_DESTROYED установлен в flags, если трейс удаляется в рамках удаления. Трейсы на переменной всегда удаляются, когда переменная удаляется; единственный случай, когда TCL_TRACE_DESTROYED не установлен, — это для трейса всего массива, вызванного, когда только один элемент массива отменяется. TCL_INTERP_DESTROYED Когда интерпретатор уничтожается, трейсы отмены вызываются для всех его переменных. Бит TCL_INTERP_DESTROYED будет установлен в аргументе flags, передаваемом процедурам трейса. Процедуры трейса должны быть крайне осторожны в том, что они делают, если бит TCL_INTERP_DESTROYED установлен. Небезопасно вызывать любые процедуры Tcl в интерпретаторе, поскольку его состояние частично удалено. Всё, что должны делать процедуры трейса в этих обстоятельствах, — это очистить и освободить свои собственные внутренние структуры данных. ОШИБКИ Tcl не выполняет никакой проверки ошибок, чтобы предотвратить неправильное использование интерпретатора процедурами трейса при установленном TCL_INTERP_DESTROYED. Трейсы массивов ещё не интегрированы с командой Tcl info exists, и нет доступа на уровне Tcl к трейсам массивов. СМ. ТАКЖЕ trace(n) КЛЮЧЕВЫЕ СЛОВА clientData, trace, variable Tcl 7.4 Tcl_TraceVar(3)
Tcl_TraceVar(3) Tcl Library Procedures Tcl_TraceVar(3) ______________________________________________________________________________ NAME Tcl_TraceVar, Tcl_TraceVar2, Tcl_UntraceVar, Tcl_UntraceVar2, Tcl_Var‐ TraceInfo, Tcl_VarTraceInfo2 - monitor accesses to a variable SYNOPSIS #include <tcl.h> int Tcl_TraceVar(interp, varName, flags, proc, clientData) int Tcl_TraceVar2(interp, name1, name2, flags, proc, clientData) Tcl_UntraceVar(interp, varName, flags, proc, clientData) Tcl_UntraceVar2(interp, name1, name2, flags, proc, clientData) ClientData Tcl_VarTraceInfo(interp, varName, flags, proc, prevClientData) ClientData Tcl_VarTraceInfo2(interp, name1, name2, flags, proc, prevClientData) ARGUMENTS Tcl_Interp *interp (in) Interpreter containing variable. const char *varName (in) Name of variable. May refer to a scalar vari‐ able, to an array vari‐ able with no index, or to an array variable with a parenthesized index. int flags (in) OR-ed combination of the values TCL_TRACE_READS, TCL_TRACE_WRITES, TCL_TRACE_UNSETS, TCL_TRACE_ARRAY, TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY, TCL_TRACE_RESULT_DYNAMIC and TCL_TRACE_RESULT_OB‐ JECT. Not all flags are used by all procedures. See below for more infor‐ mation. Tcl_VarTraceProc *proc (in) Procedure to invoke when‐ ever one of the traced operations occurs. ClientData clientData (in) Arbitrary one-word value to pass to proc. const char *name1 (in) Name of scalar or array variable (without array index). const char *name2 (in) For a trace on an element of an array, gives the index of the element. For traces on scalar variables or on whole ar‐ rays, is NULL. ClientData prevClientData (in) If non-NULL, gives last value returned by Tcl_VarTraceInfo or Tcl_VarTraceInfo2, so this call will return in‐ formation about next trace. If NULL, this call will return informa‐ tion about first trace. ______________________________________________________________________________ DESCRIPTION Tcl_TraceVar allows a C procedure to monitor and control access to a Tcl variable, so that the C procedure is invoked whenever the variable is read or written or unset. If the trace is created successfully then Tcl_TraceVar returns TCL_OK. If an error occurred (e.g. varName speci‐ fies an element of an array, but the actual variable is not an array) then TCL_ERROR is returned and an error message is left in the inter‐ preter's result. The flags argument to Tcl_TraceVar indicates when the trace procedure is to be invoked and provides information for setting up the trace. It consists of an OR-ed combination of any of the following values: TCL_GLOBAL_ONLY Normally, the variable will be looked up at the current level of procedure call; if this bit is set then the variable will be looked up at global level, ignoring any active procedures. TCL_NAMESPACE_ONLY Normally, the variable will be looked up at the current level of procedure call; if this bit is set then the variable will be looked up in the current namespace, ignoring any active proce‐ dures. TCL_TRACE_READS Invoke proc whenever an attempt is made to read the variable. TCL_TRACE_WRITES Invoke proc whenever an attempt is made to modify the variable. TCL_TRACE_UNSETS Invoke proc whenever the variable is unset. A variable may be unset either explicitly by an unset command, or implicitly when a procedure returns (its local variables are automatically un‐ set) or when the interpreter is deleted (all variables are auto‐ matically unset). TCL_TRACE_ARRAY Invoke proc whenever the array command is invoked. This gives the trace procedure a chance to update the array before array names or array get is called. Note that this is called before an array set, but that will trigger write traces. TCL_TRACE_RESULT_DYNAMIC The result of invoking the proc is a dynamically allocated string that will be released by the Tcl library via a call to ckfree. Must not be specified at the same time as TCL_TRACE_RE‐ SULT_OBJECT. TCL_TRACE_RESULT_OBJECT The result of invoking the proc is a Tcl_Obj* (cast to a char*) with a reference count of at least one. The ownership of that reference will be transferred to the Tcl core for release (when the core has finished with it) via a call to Tcl_DecrRefCount. Must not be specified at the same time as TCL_TRACE_RESULT_DY‐ NAMIC. Whenever one of the specified operations occurs on the variable, proc will be invoked. It should have arguments and result that match the type Tcl_VarTraceProc: typedef char *Tcl_VarTraceProc( ClientData clientData, Tcl_Interp *interp, const char *name1, const char *name2, int flags); The clientData and interp parameters will have the same values as those passed to Tcl_TraceVar when the trace was created. ClientData typi‐ cally points to an application-specific data structure that describes what to do when proc is invoked. Name1 and name2 give the name of the traced variable in the normal two-part form (see the description of Tcl_TraceVar2 below for details). Flags is an OR-ed combination of bits providing several pieces of information. One of the bits TCL_TRACE_READS, TCL_TRACE_WRITES, TCL_TRACE_ARRAY, or TCL_TRACE_UNSETS will be set in flags to indicate which operation is being performed on the variable. The bit TCL_GLOBAL_ONLY will be set whenever the vari‐ able being accessed is a global one not accessible from the current level of procedure call: the trace procedure will need to pass this flag back to variable-related procedures like Tcl_GetVar if it attempts to access the variable. The bit TCL_NAMESPACE_ONLY will be set when‐ ever the variable being accessed is a namespace one not accessible from the current level of procedure call: the trace procedure will need to pass this flag back to variable-related procedures like Tcl_GetVar if it attempts to access the variable. The bit TCL_TRACE_DESTROYED will be set in flags if the trace is about to be destroyed; this informa‐ tion may be useful to proc so that it can clean up its own internal data structures (see the section TCL_TRACE_DESTROYED below for more de‐ tails). Lastly, the bit TCL_INTERP_DESTROYED will be set if the entire interpreter is being destroyed. When this bit is set, proc must be es‐ pecially careful in the things it does (see the section TCL_INTERP_DE‐ STROYED below). The trace procedure's return value should normally be NULL; see ERROR RETURNS below for information on other possibilities. Tcl_UntraceVar may be used to remove a trace. If the variable speci‐ fied by interp, varName, and flags has a trace set with flags, proc, and clientData, then the corresponding trace is removed. If no such trace exists, then the call to Tcl_UntraceVar has no effect. The same bits are valid for flags as for calls to Tcl_TraceVar. Tcl_VarTraceInfo may be used to retrieve information about traces set on a given variable. The return value from Tcl_VarTraceInfo is the clientData associated with a particular trace. The trace must be on the variable specified by the interp, varName, and flags arguments (only the TCL_GLOBAL_ONLY and TCL_NAMESPACE_ONLY bits from flags is used; other bits are ignored) and its trace procedure must the same as the proc argument. If the prevClientData argument is NULL then the re‐ turn value corresponds to the first (most recently created) matching trace, or NULL if there are no matching traces. If the prevClientData argument is not NULL, then it should be the return value from a previ‐ ous call to Tcl_VarTraceInfo. In this case, the new return value will correspond to the next matching trace after the one whose clientData matches prevClientData, or NULL if no trace matches prevClientData or if there are no more matching traces after it. This mechanism makes it possible to step through all of the traces for a given variable that have the same proc. TWO-PART NAMES The procedures Tcl_TraceVar2, Tcl_UntraceVar2, and Tcl_VarTraceInfo2 are identical to Tcl_TraceVar, Tcl_UntraceVar, and Tcl_VarTraceInfo, respectively, except that the name of the variable consists of two parts. Name1 gives the name of a scalar variable or array, and name2 gives the name of an element within an array. When name2 is NULL, name1 may contain both an array and an element name: if the name con‐ tains an open parenthesis and ends with a close parenthesis, then the value between the parentheses is treated as an element name (which can have any string value) and the characters before the first open paren‐ thesis are treated as the name of an array variable. If name2 is NULL and name1 does not refer to an array element it means that either the variable is a scalar or the trace is to be set on the entire array rather than an individual element (see WHOLE-ARRAY TRACES below for more information). ACCESSING VARIABLES DURING TRACES During read, write, and array traces, the trace procedure can read, write, or unset the traced variable using Tcl_GetVar2, Tcl_SetVar2, and other procedures. While proc is executing, traces are temporarily dis‐ abled for the variable, so that calls to Tcl_GetVar2 and Tcl_SetVar2 will not cause proc or other trace procedures to be invoked again. Disabling only occurs for the variable whose trace procedure is active; accesses to other variables will still be traced. However, if a vari‐ able is unset during a read or write trace then unset traces will be invoked. During unset traces the variable has already been completely expunged. It is possible for the trace procedure to read or write the variable, but this will be a new version of the variable. Traces are not dis‐ abled during unset traces as they are for read and write traces, but existing traces have been removed from the variable before any trace procedures are invoked. If new traces are set by unset trace proce‐ dures, these traces will be invoked on accesses to the variable by the trace procedures. CALLBACK TIMING When read tracing has been specified for a variable, the trace proce‐ dure will be invoked whenever the variable's value is read. This in‐ cludes set Tcl commands, $-notation in Tcl commands, and invocations of the Tcl_GetVar and Tcl_GetVar2 procedures. Proc is invoked just before the variable's value is returned. It may modify the value of the vari‐ able to affect what is returned by the traced access. If it unsets the variable then the access will return an error just as if the variable never existed. When write tracing has been specified for a variable, the trace proce‐ dure will be invoked whenever the variable's value is modified. This includes set commands, commands that modify variables as side effects (such as catch and scan), and calls to the Tcl_SetVar and Tcl_SetVar2 procedures). Proc will be invoked after the variable's value has been modified, but before the new value of the variable has been returned. It may modify the value of the variable to override the change and to determine the value actually returned by the traced access. If it deletes the variable then the traced access will return an empty string. When array tracing has been specified, the trace procedure will be in‐ voked at the beginning of the array command implementation, before any of the operations like get, set, or names have been invoked. The trace procedure can modify the array elements with Tcl_SetVar and Tcl_Set‐ Var2. When unset tracing has been specified, the trace procedure will be in‐ voked whenever the variable is destroyed. The traces will be called after the variable has been completely unset. WHOLE-ARRAY TRACES If a call to Tcl_TraceVar or Tcl_TraceVar2 specifies the name of an ar‐ ray variable without an index into the array, then the trace will be set on the array as a whole. This means that proc will be invoked whenever any element of the array is accessed in the ways specified by flags. When an array is unset, a whole-array trace will be invoked just once, with name1 equal to the name of the array and name2 NULL; it will not be invoked once for each element. MULTIPLE TRACES It is possible for multiple traces to exist on the same variable. When this happens, all of the trace procedures will be invoked on each ac‐ cess, in order from most-recently-created to least-recently-created. When there exist whole-array traces for an array as well as traces on individual elements, the whole-array traces are invoked before the in‐ dividual-element traces. If a read or write trace unsets the variable then all of the unset traces will be invoked but the remainder of the read and write traces will be skipped. ERROR RETURNS Under normal conditions trace procedures should return NULL, indicating successful completion. If proc returns a non-NULL value it signifies that an error occurred. The return value must be a pointer to a static character string containing an error message, unless (exactly one of) the TCL_TRACE_RESULT_DYNAMIC and TCL_TRACE_RESULT_OBJECT flags is set, which specify that the result is either a dynamic string (to be re‐ leased with ckfree) or a Tcl_Obj* (cast to char* and to be released with Tcl_DecrRefCount) containing the error message. If a trace proce‐ dure returns an error, no further traces are invoked for the access and the traced access aborts with the given message. Trace procedures can use this facility to make variables read-only, for example (but note that the value of the variable will already have been modified before the trace procedure is called, so the trace procedure will have to re‐ store the correct value). The return value from proc is only used during read and write tracing. During unset traces, the return value is ignored and all relevant trace procedures will always be invoked. RESTRICTIONS A trace procedure can be called at any time, even when there are par‐ tially formed results stored in the interpreter. If the trace proce‐ dure does anything that could damage this result (such as calling Tcl_Eval) then it must use the Tcl_SaveInterpState and related routines to save and restore the original state of the interpreter before it re‐ turns. UNDEFINED VARIABLES It is legal to set a trace on an undefined variable. The variable will still appear to be undefined until the first time its value is set. If an undefined variable is traced and then unset, the unset will fail with an error (“no such variable”), but the trace procedure will still be invoked. TCL_TRACE_DESTROYED FLAG In an unset callback to proc, the TCL_TRACE_DESTROYED bit is set in flags if the trace is being removed as part of the deletion. Traces on a variable are always removed whenever the variable is deleted; the only time TCL_TRACE_DESTROYED is not set is for a whole-array trace in‐ voked when only a single element of an array is unset. TCL_INTERP_DESTROYED When an interpreter is destroyed, unset traces are called for all of its variables. The TCL_INTERP_DESTROYED bit will be set in the flags argument passed to the trace procedures. Trace procedures must be ex‐ tremely careful in what they do if the TCL_INTERP_DESTROYED bit is set. It is not safe for the procedures to invoke any Tcl procedures on the interpreter, since its state is partially deleted. All that trace pro‐ cedures should do under these circumstances is to clean up and free their own internal data structures. BUGS Tcl does not do any error checking to prevent trace procedures from misusing the interpreter during traces with TCL_INTERP_DESTROYED set. Array traces are not yet integrated with the Tcl info exists command, nor is there Tcl-level access to array traces. SEE ALSO trace(n) KEYWORDS clientData, trace, variable Tcl 7.4 Tcl_TraceVar(3)
Notifier(3) Процедуры библиотеки Tcl Notifier(3) ______________________________________________________________________________ NAME Tcl_CreateEventSource, Tcl_DeleteEventSource, Tcl_SetMaxBlockTime, Tcl_QueueEvent, Tcl_ThreadQueueEvent, Tcl_ThreadAlert, Tcl_GetCurrent‐ Thread, Tcl_DeleteEvents, Tcl_InitNotifier, Tcl_FinalizeNotifier, Tcl_WaitForEvent, Tcl_AlertNotifier, Tcl_SetTimer, Tcl_ServiceAll, Tcl_ServiceEvent, Tcl_GetServiceMode, Tcl_SetServiceMode, Tcl_Service‐ ModeHook, Tcl_SetNotifier - интерфейсы очереди событий и уведомителя SYNOPSIS #include <tcl.h> void Tcl_CreateEventSource(setupProc, checkProc, clientData) void Tcl_DeleteEventSource(setupProc, checkProc, clientData) void Tcl_SetMaxBlockTime(timePtr) void Tcl_QueueEvent(evPtr, position) void Tcl_ThreadQueueEvent(threadId, evPtr, position) void Tcl_ThreadAlert(threadId) Tcl_ThreadId Tcl_GetCurrentThread() void Tcl_DeleteEvents(deleteProc, clientData) ClientData Tcl_InitNotifier() void Tcl_FinalizeNotifier(clientData) int Tcl_WaitForEvent(timePtr) void Tcl_AlertNotifier(clientData) void Tcl_SetTimer(timePtr) int Tcl_ServiceAll() int Tcl_ServiceEvent(flags) int Tcl_GetServiceMode() int Tcl_SetServiceMode(mode) void Tcl_ServiceModeHook(mode) void Tcl_SetNotifier(notifierProcPtr) ARGUMENTS Tcl_EventSetupProc *setupProc (in) Процедура для вызова для подготовки к ожиданию событий в Tcl_DoOneEvent. Tcl_EventCheckProc *checkProc (in) Процедура для вызова Tcl_DoOneEvent после ожидания событий. Проверяет, произошли ли какие-либо события и, если да, добавляет их в очередь. ClientData clientData (in) Произвольное значение одного слова для передачи в se‐ tupProc, checkProc или deleteProc. const Tcl_Time *timePtr (in) Указывает максимальное время ожидания события. Это задается как интервал (сколько ждать), а не абсолютное время (когда проснуться). Если указатель, передаваемый Tcl_WaitForEvent, равен NULL, это означает, что нет максимального времени ожидания: ждать вечно, если необходимо. Tcl_Event *evPtr (in) Событие для добавления в очередь событий. Память для события должна быть выделена вызывающей стороной с помощью Tcl_Al‐ loc или ckalloc. Tcl_QueuePosition position (in) Где добавить новое событие в очередь: TCL_QUEUE_TAIL, TCL_QUEUE_HEAD или TCL_QUEUE_MARK. Tcl_ThreadId threadId (in) Уникальный идентификатор потока. Tcl_EventDeleteProc *deleteProc (in) Процедура для вызова для каждого события в очереди в Tcl_DeleteEvents. int flags (in) Типы событий, которые нужно обслуживать. Эти флаги те же, что и те, которые передаются Tcl_DoOneEvent. int mode (in) Указывает, должны ли события обслуживаться Tcl_Ser‐ viceAll. Должно быть одно из TCL_SERVICE_NONE или TCL_SERVICE_ALL. Tcl_NotifierProcs* notifierProcPtr (in) Структура указателей на функции, описывающая процедуры уведомителя, которые должны заменить те, которые установлены в исполняемом файле. См. REPLACING THE NOTIFIER для деталей. ______________________________________________________________________________ INTRODUCTION Интерфейсы, описанные здесь, используются для настройки цикла событий Tcl. Два наиболее распространенных варианта настройки - это добавление новых источников событий и объединение цикла событий Tcl с другим циклом событий, таким как тот, который предоставляется приложением, в которое встроен Tcl. Каждое из этих задач описано в отдельном разделе ниже. Процедуры в этом руководстве являются строительными блоками, из которых построен уведомитель событий Tcl. Уведомитель событий - это самый нижний слой в механизме событий Tcl. Он состоит из трех компонентов: [1] Источники событий: они представляют способы генерации событий. Например, есть источник событий таймера, который реализует процедуру Tcl_CreateTimerHandler и команду after, и источник событий файла, который реализует процедуру Tcl_CreateFileHandler на системах Unix. Источник событий должен работать с уведомителем, чтобы обнаруживать события в нужное время, записывать их в очередь событий и в конечном итоге уведомлять более высокоуровневое программное обеспечение о том, что они произошли. Процедуры Tcl_CreateEventSource, Tcl_DeleteEventSource, Tcl_SetMaxBlockTime, Tcl_QueueEvent и Tcl_DeleteEvents в основном используются источниками событий. [2] Очередь событий: для приложений без потоков есть одна очередь для всего приложения, содержащая события, которые были обнаружены, но еще не обслужены. Источники событий размещают события в очереди, чтобы они могли обрабатываться в порядке в подходящее время во время цикла событий. Очередь событий гарантирует дисциплину обработки событий, так что ни один источник событий не может "голодать" другие. Она также позволяет сохранять события для обслуживания в будущем. Приложения с потоками работают аналогично, за исключением того, что для каждого потока, содержащего интерпретатор Tcl, есть отдельная очередь событий. Tcl_QueueEvent используется (в основном источниками событий) для добавления событий в очередь событий, а Tcl_DeleteEvents используется для удаления событий из очереди без их обработки. В приложении с потоками Tcl_QueueEvent добавляет событие в очередь текущего потока, а Tcl_ThreadQueueEvent добавляет событие в очередь в определенном потоке. [3] Цикл событий: чтобы обнаруживать и обрабатывать события, приложение входит в цикл, который ждет, пока события произойдут, размещает их в очереди событий и затем обрабатывает. Большинство приложений будут делать это, вызывая процедуру Tcl_DoOneEvent, которая описана в отдельном руководстве. Большинству приложений Tcl не нужно беспокоиться о внутренних деталях уведомителя Tcl. Однако уведомитель теперь имеет достаточно гибкости, чтобы быть перенаправленным либо для новой платформы, либо для использования внешнего цикла событий (например, цикла событий Motif, когда Tcl встроен в приложение Motif). Процедуры Tcl_WaitForEvent и Tcl_SetTimer обычно реализуются Tcl, но могут быть заменены новыми версиями для перенаправления уведомителя (также Tcl_InitNotifier, Tcl_AlertNotifier, Tcl_FinalizeNo‐ tifier, Tcl_Sleep, Tcl_CreateFileHandler и Tcl_DeleteFileHandler должны быть заменены; см. CREATING A NEW NOTIFIER ниже для деталей). Процедуры Tcl_ServiceAll, Tcl_ServiceEvent, Tcl_GetServiceMode и Tcl_SetServiceMode предоставляются для помощи в подключении цикла событий Tcl к внешнему циклу событий, такому как Motif. NOTIFIER BASICS Самый простой способ понять, как работает уведомитель, - это рассмотреть, что происходит при вызове Tcl_DoOneEvent. Tcl_DoOneEvent получает аргумент flags, который указывает, какие типы событий можно обработать, и также указывает, блокировать ли, если события не готовы. Tcl_DoOneEvent выполняет следующее: [1] Проверяет очередь событий, чтобы увидеть, содержит ли она события, которые можно обслужить. Если да, обслуживает первое возможное событие, удаляет его из очереди и возвращает. Для этого вызывается Tcl_ServiceEvent с передачей аргумента flags. [2] Подготавливается к блокировке для события. Для этого Tcl_DoOneEvent вызывает процедуру настройки в каждом источнике событий. Источник событий выполнит инициализацию, специфичную для источника событий, и, возможно, вызовет Tcl_SetMaxBlockTime, чтобы ограничить, как долго Tcl_WaitForEvent будет блокировать, если новые события не произойдут. [3] Вызывает Tcl_WaitForEvent. Эта процедура реализуется по-разному на разных платформах; она ждет, пока произойдет событие, на основе информации, предоставленной источниками событий. Она может вызвать блокировку приложения, если timePtr указывает интервал, отличный от 0. Tcl_WaitForEvent возвращает, когда что-то произошло, например, файл стал доступным для чтения или истек интервал, указанный timePtr. Если нет событий, для которых Tcl_WaitForEvent может ждать, так что он заблокирует навсегда, то он возвращает немедленно, и Tcl_DoOneEvent возвращает 0. [4] Вызывает процедуру проверки в каждом источнике событий. Процедура проверки определяет, произошли ли события, интересующие этот источник. Если да, события добавляются в очередь событий. [5] Проверяет очередь событий, чтобы увидеть, содержит ли она события, которые можно обслужить. Если да, обслуживает первое возможное событие, удаляет его из очереди и возвращает. [6] Проверяет, есть ли ожидающие обратные вызовы в простое. Если да, вызывает все из них и возвращает. [7] Либо возвращает 0, чтобы указать, что события не готовы, либо возвращается к шагу [2], если блокировка была запрошена вызывающей стороной. CREATING A NEW EVENT SOURCE Источник событий состоит из трех процедур, вызываемых уведомителем, плюс дополнительных процедур C, которые вызываются более высокоуровневым кодом для организации событийных обратных вызовов. Три процедуры, вызываемые уведомителем, включают процедуры настройки и проверки, описанные выше, плюс дополнительную процедуру, которая вызывается, когда событие удаляется из очереди событий для обслуживания. Процедура Tcl_CreateEventSource создает новый источник событий. Ее аргументы указывают процедуру настройки и процедуру проверки для источника событий. SetupProc должна соответствовать следующему прототипу: typedef void Tcl_EventSetupProc( ClientData clientData, int flags); Аргумент clientData будет таким же, как аргумент clientData для Tcl_CreateEventSource; он обычно используется для указания на частную информацию, управляемую источником событий. Аргумент flags будет таким же, как аргумент flags, передаваемый Tcl_DoOneEvent, за исключением того, что он никогда не будет равен 0 (Tcl_DoOneEvent заменяет 0 на TCL_ALL_EVENTS). Flags указывает, какие виды событий следует учитывать; если бит, соответствующий этому источнику событий, не установлен, источник событий должен вернуться немедленно, не делая ничего. Например, источник событий файла проверяет бит TCL_FILE_EVENTS. Задача SetupProc - убедиться, что приложение проснется, когда события желаемого типа произойдут. Это обычно делается в зависимости от платформы. Например, под Unix источник событий может вызвать Tcl_CreateFileHandler; под Windows он может запросить уведомление с помощью события Windows. Для источников событий, управляемых таймером, таких как события таймера или любые опрошенные события, источник событий может вызвать Tcl_SetMaxBlockTime, чтобы заставить приложение проснуться через указанное время, даже если события не произошли. Если ни один источник событий не вызывает Tcl_SetMaxBlockTime, то Tcl_WaitForEvent будет ждать столько, сколько нужно для события; в противном случае он будет ждать только столько, сколько указан самый короткий интервал, переданный Tcl_SetMaxBlockTime одним из источников событий. Если источник событий знает, что у него уже есть события, готовые к отчету, он может запросить нулевое максимальное время блокировки. Например, процедура настройки для источника событий X проверяет, есть ли события, уже поставленные в очередь. Если да, она вызывает Tcl_SetMaxBlockTime с нулевым временем блокировки, чтобы Tcl_WaitForEvent не блокировал, если нет новых данных на соединении X. Аргумент timePtr для Tcl_WaitForEvent указывает на структуру, описывающую интервал времени в секундах и микросекундах: typedef struct Tcl_Time { long sec; long usec; } Tcl_Time; Поле usec должно быть меньше 1000000. Информация, предоставленная Tcl_SetMaxBlockTime, используется только для следующего вызова Tcl_WaitForEvent; она отбрасывается после возврата Tcl_WaitForEvent. В следующий раз, когда будет выполнено ожидание событий, процедуры настройки каждого из источников событий будут вызваны снова, и они могут указать новую информацию для этого ожидания событий. Если приложение использует внешний цикл событий, а не Tcl_DoOneEvent, источники событий могут нуждаться в вызове Tcl_SetMaxBlockTime в другие времена. Например, если зарегистрирован новый обработчик событий, который нуждается в опросе событий, источник событий может вызвать Tcl_SetMaxBlockTime, чтобы установить время блокировки в ноль, чтобы заставить внешний цикл событий вызвать Tcl. В этом случае Tcl_SetMaxBlockTime вызывает Tcl_SetTimer с самым коротким интервалом, видимым с момента последнего вызова Tcl_DoOneEvent или Tcl_ServiceAll. Помимо общей процедуры Tcl_SetMaxBlockTime, могут быть доступны другие процедуры, специфичные для платформы, для setupProc, если для Tcl_WaitForEvent на этой платформе требуется дополнительная информация. Например, на системах Unix можно использовать интерфейс Tcl_CreateFileHandler для ожидания событий файлов. Вторая процедура, предоставляемая каждым источником событий, - это его процедура проверки, указанная аргументом checkProc для Tcl_CreateEventSource. CheckProc должна соответствовать следующему прототипу: typedef void Tcl_EventCheckProc( ClientData clientData, int flags); Аргументы этой процедуры те же, что и для setupProc. CheckProc вызывается Tcl_DoOneEvent после того, как оно подождало событий. Предположительно, по крайней мере один источник событий теперь готов поставить в очередь событие. Tcl_DoOneEvent вызывает каждый из источников событий по очереди, так что они все имеют шанс поставить в очередь любые готовые события. Процедура проверки делает две вещи. Во-первых, она должна увидеть, произошли ли какие-либо события. Разные источники событий делают это по-разному. Если процедура проверки источника событий обнаруживает интересное событие, она должна добавить событие в очередь событий Tcl. Для этого источник событий вызывает Tcl_QueueEvent. Аргумент evPtr - это указатель на динамически выделенную структуру, содержащую событие (см. ниже для дополнительной информации о проблемах управления памятью). Каждый источник событий может определять свою собственную структуру событий с любой релевантной информацией. Однако первый элемент структуры должен быть структурой типа Tcl_Event, и адрес этой структуры используется при общении между источником событий и остальной частью уведомителя. Tcl_Event имеет следующее определение: typedef struct { Tcl_EventProc *proc; struct Tcl_Event *nextPtr; } Tcl_Event; Источник событий должен заполнить поле proc события перед вызовом Tcl_QueueEvent. NextPtr используется для связи событий в очереди и не должен изменяться источником событий. Событие может быть добавлено в очередь в одном из трех позиций, в зависимости от аргумента position для Tcl_QueueEvent: TCL_QUEUE_TAIL Добавить событие в конец очереди, так что все другие ожидающие события будут обслужены сначала. Это почти всегда правильное место для новых событий. TCL_QUEUE_HEAD Добавить событие в начало очереди, так что оно будет обслужено перед всеми другими событиями в очереди. TCL_QUEUE_MARK Добавить событие в начало очереди, если нет других событий в начале с позицией TCL_QUEUE_MARK; в противном случае добавить новое событие сразу после всех других событий TCL_QUEUE_MARK. Это значение position используется для вставки упорядоченной последовательности событий в начало очереди, такой как серия событий Enter и Leave, синтезированных во время операции захвата или освобождения в Tk. Когда придет время обработать событие из очереди (шаги 1 и 4 выше), Tcl_ServiceEvent вызовет proc, указанный в первой структуре Tcl_Event в очереди. Proc должна соответствовать следующему прототипу: typedef int Tcl_EventProc( Tcl_Event *evPtr, int flags); Первый аргумент для proc - это указатель на событие, который будет таким же, как первый аргумент вызова Tcl_QueueEvent, который добавил событие в очередь. Второй аргумент для proc - это аргумент flags для текущего вызова Tcl_ServiceEvent; это используется источником событий, чтобы вернуться немедленно, если его события не актуальны. Задача proc - обработать событие, обычно вызывая одну или несколько команд Tcl или обратных вызовов на уровне C. Как только источник событий завершит обработку события, он возвращает 1, чтобы указать, что событие можно удалить из очереди. Если по какой-то причине источник событий решает, что событие не может быть обработано в это время, оно может вернуть 0, чтобы указать, что событие должно быть отложено для обработки позже; в этом случае Tcl_ServiceEvent перейдет к следующему событию в очереди и попытается обслужить его. Существует несколько причин, по которым источник событий может отложить событие. Одна возможность - это то, что события этого типа исключены аргументом flags. Например, источник событий файла всегда вернет 0, если бит TCL_FILE_EVENTS не установлен в flags. Другой пример отложения событий происходит в Tk, если Tk_RestrictEvents был вызван для отложения определенных видов событий окон. Когда proc возвращает 1, Tcl_ServiceEvent удалит событие из очереди событий и освободит его память. Обратите внимание, что память для события должна быть выделена источником событий (с помощью Tcl_Alloc или макроса Tcl ckalloc) перед вызовом Tcl_QueueEvent, но она будет освобождена Tcl_ServiceEvent, а не источником событий. Приложения с потоками работают аналогично, за исключением того, что для каждого потока, содержащего интерпретатор Tcl, есть отдельная очередь событий. Вызов Tcl_QueueEvent в многопотоковом приложении добавляет событие в очередь текущего потока. Чтобы добавить событие в очередь другого потока, используйте Tcl_ThreadQueueEvent. Tcl_ThreadQueueEvent принимает аргумент Tcl_ThreadId, который однозначно идентифицирует поток в приложении Tcl. Чтобы получить Tcl_ThreadId для текущего потока, используйте процедуру Tcl_GetCurrentThread. (Поток затем должен передать этот идентификатор другим потокам, чтобы те могли добавлять события в его очередь.) После добавления события в очередь другого потока вы обычно затем должны вызвать Tcl_ThreadAlert, чтобы "разбудить" уведомитель этого потока, чтобы уведомить его о новом событии. Tcl_DeleteEvents можно использовать для явного удаления одного или нескольких событий из очереди событий. Tcl_DeleteEvents вызывает proc для каждого события в очереди, удаляя те, для которых процедура возвращает 1. События, для которых процедура возвращает 0, оставляются в очереди. Proc должна соответствовать следующему прототипу: typedef int Tcl_EventDeleteProc( Tcl_Event *evPtr, ClientData clientData); Аргумент clientData будет таким же, как аргумент clientData для Tcl_DeleteEvents; он обычно используется для указания на частную информацию, управляемую источником событий. EvPtr будет указывать на следующее событие в очереди. Tcl_DeleteEventSource удаляет источник событий. Аргументы setupProc, checkProc и clientData должны точно соответствовать тем, которые предоставлены для Tcl_CreateEventSource для удаляемого источника событий. Если такого источника не существует, Tcl_DeleteEventSource не имеет эффекта. CREATING A NEW NOTIFIER Уведомитель состоит из всех процедур, описанных в этом руководстве, плюс Tcl_DoOneEvent и Tcl_Sleep, которые доступны на всех платформах, и Tcl_CreateFileHandler и Tcl_DeleteFileHandler, которые специфичны для Unix. Большинство из этих процедур являются общими, то есть они одинаковы для всех уведомителей. Однако ни одна из процедур не зависит от уведомителя: Tcl_InitNotifier, Tcl_AlertNotifier, Tcl_FinalizeNotifier, Tcl_SetTimer, Tcl_Sleep, Tcl_WaitForEvent, Tcl_CreateFileHandler, Tcl_DeleteFileHandler и Tcl_ServiceModeHook. Чтобы поддерживать новую платформу или интегрировать Tcl с циклом событий, специфичным для приложения, вы должны написать новые версии этих процедур. Tcl_InitNotifier инициализирует состояние уведомителя и возвращает дескриптор состояния уведомителя. Tcl вызывает эту процедуру при инициализации интерпретатора Tcl. Аналогично, Tcl_FinalizeNotifier завершает работу уведомителя и вызывается Tcl_Finalize при завершении работы интерпретатора Tcl. Tcl_WaitForEvent - это процедура самого низкого уровня в уведомителе; она отвечает за ожидание "интересного" события или истечения указанного времени. Перед вызовом Tcl_WaitForEvent каждая из процедур настройки источников событий будет вызвана. Аргумент timePtr для Tcl_WaitForEvent дает максимальное время блокировки для события, на основе вызовов Tcl_SetMaxBlockTime, сделанных процедурами настройки, и другой информации (например, бита TCL_DONT_WAIT в flags). Идеально Tcl_WaitForEvent должно только ждать события; оно не должно фактически обрабатывать событие каким-либо образом. Позже источники событий обработают необработанные события и создадут Tcl_Events в очереди событий в своих процедурах checkProc. Однако на некоторых платформах (таких как Windows) это невозможно; события могут обрабатываться в Tcl_WaitForEvent, включая постановку в очередь Tcl_Events и больше (например, обратные вызовы для нативных виджетов могут быть вызваны). Значение возврата из Tcl_WaitForEvent должно быть либо 0, либо 1, либо -1. На платформах, таких как Windows, где события обрабатываются в Tcl_WaitForEvent, значение возврата 1 означает, что могут быть еще события, ожидающие обработки. Это сигнал вызывающей стороне, что ей нужно вызвать Tcl_WaitForEvent снова, если она хочет обработать все ожидающие события. Значение возврата 0 означает, что вызов Tcl_WaitForEvent снова не окажет никакого эффекта: либо это платформа, где Tcl_WaitForEvent только ждет, не обрабатывая события, либо Tcl_WaitForEvent знает наверняка, что нет дополнительных событий для обработки (например, оно вернулось, потому что истекло время). Наконец, значение возврата -1 означает, что цикл событий больше не работает, и приложение, вероятно, должно развернуться и завершиться. Под Windows это происходит, когда получено сообщение WM_QUIT; под Unix это происходит, когда Tcl_WaitForEvent подождал бы вечно, потому что не было активных источников событий и время ожидания было бесконечным. Tcl_AlertNotifier используется в многопотоковых приложениях, чтобы любой поток мог "разбудить" уведомитель, чтобы уведомить его о новых событиях в его очереди. Tcl_AlertNotifier требует аргумент дескриптора уведомителя, возвращаемого Tcl_InitNotifier. Если уведомитель будет использоваться с внешним циклом событий, то он также должен поддерживать интерфейс Tcl_SetTimer. Tcl_SetTimer вызывается Tcl_SetMaxBlockTime всякий раз, когда максимальное время блокировки уменьшается. Tcl_SetTimer должен организовать для внешнего цикла событий вызвать Tcl_ServiceAll после указанного интервала, даже если события не произошли. Этот интерфейс необходим, потому что Tcl_WaitForEvent не вызывается, когда есть внешний цикл событий. Если уведомитель будет использоваться только из Tcl_DoOneEvent, то Tcl_SetTimer не нужно ничего делать. Tcl_ServiceModeHook вызывается платформо-независимой частью уведомителя, когда клиентский код вызывает Tcl_SetServiceMode. Этот хук предоставляется для поддержки операционных систем, которые требуют специальной обработки событий, когда приложение находится в модальном цикле (уведомитель Windows, например, использует этот хук для создания окна связи). На системах Unix источник событий файла также нуждается в поддержке от уведомителя. Источник событий файла состоит из процедур Tcl_CreateFileHandler и Tcl_DeleteFileHandler, которые описаны на странице руководства Tcl_CreateFileHandler. Интерфейсы Tcl_Sleep и Tcl_DoOneEvent описаны в их соответствующих страницах руководства. Самый простой способ создать новый уведомитель - посмотреть код существующего уведомителя, например файлы unix/tclUnixNotfy.c или win/tclWinNotify.c в дистрибутиве исходного кода Tcl. REPLACING THE NOTIFIER Уведомитель, написанный в соответствии с вышеуказанными соглашениями, также может быть установлен в работающем процессе вместо стандартного уведомителя. Этот механизм используется, чтобы один исполняемый файл мог использоваться (с стандартным уведомителем) как автономная программа и повторно использоваться (с заменой уведомителя в загружаемом расширении) как расширение для другой программы, такой как плагин веб-браузера. Чтобы сделать это, расширение вызывает Tcl_SetNotifier, передавая указатель на структуру данных Tcl_NotifierProcs. Структура имеет следующую компоновку: typedef struct Tcl_NotifierProcs { Tcl_SetTimerProc *setTimerProc; Tcl_WaitForEventProc *waitForEventProc; Tcl_CreateFileHandlerProc *createFileHandlerProc; Tcl_DeleteFileHandlerProc *deleteFileHandlerProc; Tcl_InitNotifierProc *initNotifierProc; Tcl_FinalizeNotifierProc *finalizeNotifierProc; Tcl_AlertNotifierProc *alertNotifierProc; Tcl_ServiceModeHookProc *serviceModeHookProc; } Tcl_NotifierProcs; После вызова Tcl_SetNotifier указатели, данные в структуре Tcl_NotifierProcs, заменяют уведомитель, который был установлен в процессе. Это чрезвычайно неразумно заменять работающий уведомитель. Обычно Tcl_SetNotifier следует вызывать на этапе инициализации процесса до первого вызова Tcl_InitNotifier. EXTERNAL EVENT LOOPS Интерфейсы уведомителя предназначены для того, чтобы Tcl мог быть встроен в приложения, которые имеют свои собственные частные циклы событий. В этом случае приложение не вызывает Tcl_DoOneEvent, кроме случаев рекурсивных циклов событий, таких как вызовы команд Tcl update или vwait. Большую часть времени тратится во внешнем цикле событий приложения. В этом случае уведомитель должен организовать для внешнего цикла событий обратный вызов в Tcl, когда что-то происходит в различных источниках событий Tcl. Эти обратные вызовы должны организовать соответствующее размещение событий Tcl в очереди событий Tcl. Поскольку внешний цикл событий не вызывает Tcl_DoOneEvent на регулярной основе, уведомитель должен организовать вызов Tcl_ServiceEvent всякий раз, когда события ожидаются в очереди событий Tcl. Самый простой способ сделать это - вызвать Tcl_ServiceAll в конце каждого обратного вызова из внешнего цикла событий. Это обеспечит опрос всех источников событий, обслуживание всех поставленных в очередь событий и обработку любых ожидающих обработчиков простоя перед возвратом контроля приложению. Кроме того, источники событий, которым нужно опрашивать события, могут вызвать Tcl_SetMaxBlockTime, чтобы заставить внешний цикл событий вызвать Tcl, даже если события не доступны в очереди системных событий. Как побочный эффект обработки событий, обнаруженных в основном внешнем цикле событий, Tcl может вызвать Tcl_DoOneEvent для запуска рекурсивного цикла событий в командах, таких как vwait. Tcl_DoOneEvent вызовет внешний цикл событий, что приведет к обратным вызовам, как описано в предыдущем абзаце, что приведет к вызовам Tcl_ServiceAll. Однако в этих случаях нежелательно обслуживать события в Tcl_ServiceAll. Обслуживание событий там излишне, потому что контроль немедленно вернется во внешний цикл событий и, следовательно, в Tcl_DoOneEvent, который может обслуживать события сам. Кроме того, Tcl_DoOneEvent должен обслуживать только одно событие, в то время как Tcl_ServiceAll обычно обслуживает все ожидающие события. Чтобы обработать эту ситуацию, Tcl_DoOneEvent устанавливает флаг для Tcl_ServiceAll, который заставляет его возвращать без обслуживания каких-либо событий. Этот флаг называется режимом обслуживания; Tcl_DoOneEvent восстанавливает его предыдущее значение перед возвратом. В некоторых случаях, однако, может потребоваться, чтобы Tcl_ServiceAll обслуживал события, даже когда оно было вызвано из Tcl_DoOneEvent. Это происходит, когда есть еще один рекурсивный цикл событий, вызванный через обработчик события, вызванный Tcl_DoOneEvent (например, часть нативного виджета). В этом случае Tcl_DoOneEvent может не иметь возможности обслуживать события, так что Tcl_ServiceAll должно обслуживать их все. Любому рекурсивному циклу событий, который вызывает внешний цикл событий, а не Tcl_DoOneEvent, нужно сбросить режим обслуживания, чтобы все события обрабатывались в Tcl_ServiceAll. Это делается путем вызова процедуры Tcl_SetServiceMode. Если Tcl_SetServiceMode передается TCL_SERVICE_NONE, то вызовы Tcl_ServiceAll вернутся немедленно без обработки каких-либо событий. Если Tcl_SetServiceMode передается TCL_SERVICE_ALL, то вызовы Tcl_ServiceAll будут вести себя нормально. Tcl_SetServiceMode возвращает предыдущее значение режима обслуживания, которое должно быть восстановлено при выходе из рекурсивного цикла. Tcl_GetServiceMode возвращает текущее значение режима обслуживания. SEE ALSO Tcl_CreateFileHandler(3), Tcl_DeleteFileHandler(3), Tcl_Sleep(3), Tcl_DoOneEvent(3), Thread(3) KEYWORDS event, notifier, event queue, event sources, file events, timer, idle, service mode, threads Tcl 8.1 Notifier(3)
Notifier(3) Tcl Library Procedures Notifier(3) ______________________________________________________________________________ NAME Tcl_CreateEventSource, Tcl_DeleteEventSource, Tcl_SetMaxBlockTime, Tcl_QueueEvent, Tcl_ThreadQueueEvent, Tcl_ThreadAlert, Tcl_GetCurrent‐ Thread, Tcl_DeleteEvents, Tcl_InitNotifier, Tcl_FinalizeNotifier, Tcl_WaitForEvent, Tcl_AlertNotifier, Tcl_SetTimer, Tcl_ServiceAll, Tcl_ServiceEvent, Tcl_GetServiceMode, Tcl_SetServiceMode, Tcl_Service‐ ModeHook, Tcl_SetNotifier - the event queue and notifier interfaces SYNOPSIS #include <tcl.h> void Tcl_CreateEventSource(setupProc, checkProc, clientData) void Tcl_DeleteEventSource(setupProc, checkProc, clientData) void Tcl_SetMaxBlockTime(timePtr) void Tcl_QueueEvent(evPtr, position) void Tcl_ThreadQueueEvent(threadId, evPtr, position) void Tcl_ThreadAlert(threadId) Tcl_ThreadId Tcl_GetCurrentThread() void Tcl_DeleteEvents(deleteProc, clientData) ClientData Tcl_InitNotifier() void Tcl_FinalizeNotifier(clientData) int Tcl_WaitForEvent(timePtr) void Tcl_AlertNotifier(clientData) void Tcl_SetTimer(timePtr) int Tcl_ServiceAll() int Tcl_ServiceEvent(flags) int Tcl_GetServiceMode() int Tcl_SetServiceMode(mode) void Tcl_ServiceModeHook(mode) void Tcl_SetNotifier(notifierProcPtr) ARGUMENTS Tcl_EventSetupProc *setupProc (in) Procedure to invoke to prepare for event wait in Tcl_DoOneEvent. Tcl_EventCheckProc *checkProc (in) Procedure for Tcl_DoOneEvent to invoke after waiting for events. Checks to see if any events have occurred and, if so, queues them. ClientData clientData (in) Arbitrary one-word value to pass to se‐ tupProc, checkProc, or deleteProc. const Tcl_Time *timePtr (in) Indicates the maxi‐ mum amount of time to wait for an event. This is specified as an in‐ terval (how long to wait), not an abso‐ lute time (when to wakeup). If the pointer passed to Tcl_WaitForEvent is NULL, it means there is no maximum wait time: wait forever if necessary. Tcl_Event *evPtr (in) An event to add to the event queue. The storage for the event must have been allocated by the caller using Tcl_Al‐ loc or ckalloc. Tcl_QueuePosition position (in) Where to add the new event in the queue: TCL_QUEUE_TAIL, TCL_QUEUE_HEAD, or TCL_QUEUE_MARK. Tcl_ThreadId threadId (in) A unique identifier for a thread. Tcl_EventDeleteProc *deleteProc (in) Procedure to invoke for each queued event in Tcl_Dele‐ teEvents. int flags (in) What types of events to service. These flags are the same as those passed to Tcl_DoOneEvent. int mode (in) Indicates whether events should be serviced by Tcl_Ser‐ viceAll. Must be one of TCL_SER‐ VICE_NONE or TCL_SERVICE_ALL. Tcl_NotifierProcs* notifierProcPtr (in) Structure of func‐ tion pointers de‐ scribing notifier procedures that are to replace the ones installed in the ex‐ ecutable. See RE‐ PLACING THE NOTIFIER for details. ______________________________________________________________________________ INTRODUCTION The interfaces described here are used to customize the Tcl event loop. The two most common customizations are to add new sources of events and to merge Tcl's event loop with some other event loop, such as one pro‐ vided by an application in which Tcl is embedded. Each of these tasks is described in a separate section below. The procedures in this manual entry are the building blocks out of which the Tcl event notifier is constructed. The event notifier is the lowest layer in the Tcl event mechanism. It consists of three things: [1] Event sources: these represent the ways in which events can be generated. For example, there is a timer event source that im‐ plements the Tcl_CreateTimerHandler procedure and the after com‐ mand, and there is a file event source that implements the Tcl_CreateFileHandler procedure on Unix systems. An event source must work with the notifier to detect events at the right times, record them on the event queue, and eventually notify higher-level software that they have occurred. The procedures Tcl_CreateEventSource, Tcl_DeleteEventSource, and Tcl_Set‐ MaxBlockTime, Tcl_QueueEvent, and Tcl_DeleteEvents are used pri‐ marily by event sources. [2] The event queue: for non-threaded applications, there is a sin‐ gle queue for the whole application, containing events that have been detected but not yet serviced. Event sources place events onto the queue so that they may be processed in order at appro‐ priate times during the event loop. The event queue guarantees a fair discipline of event handling, so that no event source can starve the others. It also allows events to be saved for ser‐ vicing at a future time. Threaded applications work in a simi‐ lar manner, except that there is a separate event queue for each thread containing a Tcl interpreter. Tcl_QueueEvent is used (primarily by event sources) to add events to the event queue and Tcl_DeleteEvents is used to remove events from the queue without processing them. In a threaded application, Tcl_QueueEvent adds an event to the current thread's queue, and Tcl_ThreadQueueEvent adds an event to a queue in a specific thread. [3] The event loop: in order to detect and process events, the ap‐ plication enters a loop that waits for events to occur, places them on the event queue, and then processes them. Most applica‐ tions will do this by calling the procedure Tcl_DoOneEvent, which is described in a separate manual entry. Most Tcl applications need not worry about any of the internals of the Tcl notifier. However, the notifier now has enough flexibility to be retargeted either for a new platform or to use an external event loop (such as the Motif event loop, when Tcl is embedded in a Motif applica‐ tion). The procedures Tcl_WaitForEvent and Tcl_SetTimer are normally implemented by Tcl, but may be replaced with new versions to retarget the notifier (the Tcl_InitNotifier, Tcl_AlertNotifier, Tcl_FinalizeNo‐ tifier, Tcl_Sleep, Tcl_CreateFileHandler, and Tcl_DeleteFileHandler must also be replaced; see CREATING A NEW NOTIFIER below for details). The procedures Tcl_ServiceAll, Tcl_ServiceEvent, Tcl_GetServiceMode, and Tcl_SetServiceMode are provided to help connect Tcl's event loop to an external event loop such as Motif's. NOTIFIER BASICS The easiest way to understand how the notifier works is to consider what happens when Tcl_DoOneEvent is called. Tcl_DoOneEvent is passed a flags argument that indicates what sort of events it is OK to process and also whether or not to block if no events are ready. Tcl_DoOneEvent does the following things: [1] Check the event queue to see if it contains any events that can be serviced. If so, service the first possible event, remove it from the queue, and return. It does this by calling Tcl_Ser‐ viceEvent and passing in the flags argument. [2] Prepare to block for an event. To do this, Tcl_DoOneEvent in‐ vokes a setup procedure in each event source. The event source will perform event-source specific initialization and possibly call Tcl_SetMaxBlockTime to limit how long Tcl_WaitForEvent will block if no new events occur. [3] Call Tcl_WaitForEvent. This procedure is implemented differ‐ ently on different platforms; it waits for an event to occur, based on the information provided by the event sources. It may cause the application to block if timePtr specifies an interval other than 0. Tcl_WaitForEvent returns when something has hap‐ pened, such as a file becoming readable or the interval given by timePtr expiring. If there are no events for Tcl_WaitForEvent to wait for, so that it would block forever, then it returns im‐ mediately and Tcl_DoOneEvent returns 0. [4] Call a check procedure in each event source. The check proce‐ dure determines whether any events of interest to this source occurred. If so, the events are added to the event queue. [5] Check the event queue to see if it contains any events that can be serviced. If so, service the first possible event, remove it from the queue, and return. [6] See if there are idle callbacks pending. If so, invoke all of them and return. [7] Either return 0 to indicate that no events were ready, or go back to step [2] if blocking was requested by the caller. CREATING A NEW EVENT SOURCE An event source consists of three procedures invoked by the notifier, plus additional C procedures that are invoked by higher-level code to arrange for event-driven callbacks. The three procedures called by the notifier consist of the setup and check procedures described above, plus an additional procedure that is invoked when an event is removed from the event queue for servicing. The procedure Tcl_CreateEventSource creates a new event source. Its arguments specify the setup procedure and check procedure for the event source. SetupProc should match the following prototype: typedef void Tcl_EventSetupProc( ClientData clientData, int flags); The clientData argument will be the same as the clientData argument to Tcl_CreateEventSource; it is typically used to point to private infor‐ mation managed by the event source. The flags argument will be the same as the flags argument passed to Tcl_DoOneEvent except that it will never be 0 (Tcl_DoOneEvent replaces 0 with TCL_ALL_EVENTS). Flags in‐ dicates what kinds of events should be considered; if the bit corre‐ sponding to this event source is not set, the event source should re‐ turn immediately without doing anything. For example, the file event source checks for the TCL_FILE_EVENTS bit. SetupProc's job is to make sure that the application wakes up when events of the desired type occur. This is typically done in a plat‐ form-dependent fashion. For example, under Unix an event source might call Tcl_CreateFileHandler; under Windows it might request notification with a Windows event. For timer-driven event sources such as timer events or any polled event, the event source can call Tcl_SetMaxBlock‐ Time to force the application to wake up after a specified time even if no events have occurred. If no event source calls Tcl_SetMaxBlockTime then Tcl_WaitForEvent will wait as long as necessary for an event to occur; otherwise, it will only wait as long as the shortest interval passed to Tcl_SetMaxBlockTime by one of the event sources. If an event source knows that it already has events ready to report, it can request a zero maximum block time. For example, the setup procedure for the X event source looks to see if there are events already queued. If there are, it calls Tcl_SetMaxBlockTime with a 0 block time so that Tcl_Wait‐ ForEvent does not block if there is no new data on the X connection. The timePtr argument to Tcl_WaitForEvent points to a structure that de‐ scribes a time interval in seconds and microseconds: typedef struct Tcl_Time { long sec; long usec; } Tcl_Time; The usec field should be less than 1000000. Information provided to Tcl_SetMaxBlockTime is only used for the next call to Tcl_WaitForEvent; it is discarded after Tcl_WaitForEvent re‐ turns. The next time an event wait is done each of the event sources' setup procedures will be called again, and they can specify new infor‐ mation for that event wait. If the application uses an external event loop rather than Tcl_DoOneEvent, the event sources may need to call Tcl_SetMaxBlockTime at other times. For example, if a new event handler is registered that needs to poll for events, the event source may call Tcl_SetMaxBlockTime to set the block time to zero to force the external event loop to call Tcl. In this case, Tcl_SetMaxBlockTime invokes Tcl_SetTimer with the shortest interval seen since the last call to Tcl_DoOneEvent or Tcl_ServiceAll. In addition to the generic procedure Tcl_SetMaxBlockTime, other plat‐ form-specific procedures may also be available for setupProc, if there is additional information needed by Tcl_WaitForEvent on that platform. For example, on Unix systems the Tcl_CreateFileHandler interface can be used to wait for file events. The second procedure provided by each event source is its check proce‐ dure, indicated by the checkProc argument to Tcl_CreateEventSource. CheckProc must match the following prototype: typedef void Tcl_EventCheckProc( ClientData clientData, int flags); The arguments to this procedure are the same as those for setupProc. CheckProc is invoked by Tcl_DoOneEvent after it has waited for events. Presumably at least one event source is now prepared to queue an event. Tcl_DoOneEvent calls each of the event sources in turn, so they all have a chance to queue any events that are ready. The check procedure does two things. First, it must see if any events have triggered. Different event sources do this in different ways. If an event source's check procedure detects an interesting event, it must add the event to Tcl's event queue. To do this, the event source calls Tcl_QueueEvent. The evPtr argument is a pointer to a dynamically allocated structure containing the event (see below for more informa‐ tion on memory management issues). Each event source can define its own event structure with whatever information is relevant to that event source. However, the first element of the structure must be a struc‐ ture of type Tcl_Event, and the address of this structure is used when communicating between the event source and the rest of the notifier. A Tcl_Event has the following definition: typedef struct { Tcl_EventProc *proc; struct Tcl_Event *nextPtr; } Tcl_Event; The event source must fill in the proc field of the event before call‐ ing Tcl_QueueEvent. The nextPtr is used to link together the events in the queue and should not be modified by the event source. An event may be added to the queue at any of three positions, depending on the position argument to Tcl_QueueEvent: TCL_QUEUE_TAIL Add the event at the back of the queue, so that all other pending events will be serviced first. This is almost always the right place for new events. TCL_QUEUE_HEAD Add the event at the front of the queue, so that it will be serviced before all other queued events. TCL_QUEUE_MARK Add the event at the front of the queue, unless there are other events at the front whose posi‐ tion is TCL_QUEUE_MARK; if so, add the new event just after all other TCL_QUEUE_MARK events. This value of position is used to in‐ sert an ordered sequence of events at the front of the queue, such as a series of Enter and Leave events synthesized during a grab or un‐ grab operation in Tk. When it is time to handle an event from the queue (steps 1 and 4 above) Tcl_ServiceEvent will invoke the proc specified in the first queued Tcl_Event structure. Proc must match the following prototype: typedef int Tcl_EventProc( Tcl_Event *evPtr, int flags); The first argument to proc is a pointer to the event, which will be the same as the first argument to the Tcl_QueueEvent call that added the event to the queue. The second argument to proc is the flags argument for the current call to Tcl_ServiceEvent; this is used by the event source to return immediately if its events are not relevant. It is up to proc to handle the event, typically by invoking one or more Tcl commands or C-level callbacks. Once the event source has finished handling the event it returns 1 to indicate that the event can be re‐ moved from the queue. If for some reason the event source decides that the event cannot be handled at this time, it may return 0 to indicate that the event should be deferred for processing later; in this case Tcl_ServiceEvent will go on to the next event in the queue and attempt to service it. There are several reasons why an event source might de‐ fer an event. One possibility is that events of this type are excluded by the flags argument. For example, the file event source will always return 0 if the TCL_FILE_EVENTS bit is not set in flags. Another exam‐ ple of deferring events happens in Tk if Tk_RestrictEvents has been in‐ voked to defer certain kinds of window events. When proc returns 1, Tcl_ServiceEvent will remove the event from the event queue and free its storage. Note that the storage for an event must be allocated by the event source (using Tcl_Alloc or the Tcl macro ckalloc) before calling Tcl_QueueEvent, but it will be freed by Tcl_ServiceEvent, not by the event source. Threaded applications work in a similar manner, except that there is a separate event queue for each thread containing a Tcl interpreter. Calling Tcl_QueueEvent in a multithreaded application adds an event to the current thread's queue. To add an event to another thread's queue, use Tcl_ThreadQueueEvent. Tcl_ThreadQueueEvent accepts as an argument a Tcl_ThreadId argument, which uniquely identifies a thread in a Tcl application. To obtain the Tcl_ThreadId for the current thread, use the Tcl_GetCurrentThread procedure. (A thread would then need to pass this identifier to other threads for those threads to be able to add events to its queue.) After adding an event to another thread's queue, you then typically need to call Tcl_ThreadAlert to “wake up” that thread's notifier to alert it to the new event. Tcl_DeleteEvents can be used to explicitly remove one or more events from the event queue. Tcl_DeleteEvents calls proc for each event in the queue, deleting those for with the procedure returns 1. Events for which the procedure returns 0 are left in the queue. Proc should match the following prototype: typedef int Tcl_EventDeleteProc( Tcl_Event *evPtr, ClientData clientData); The clientData argument will be the same as the clientData argument to Tcl_DeleteEvents; it is typically used to point to private information managed by the event source. The evPtr will point to the next event in the queue. Tcl_DeleteEventSource deletes an event source. The setupProc, check‐ Proc, and clientData arguments must exactly match those provided to the Tcl_CreateEventSource for the event source to be deleted. If no such source exists, Tcl_DeleteEventSource has no effect. CREATING A NEW NOTIFIER The notifier consists of all the procedures described in this manual entry, plus Tcl_DoOneEvent and Tcl_Sleep, which are available on all platforms, and Tcl_CreateFileHandler and Tcl_DeleteFileHandler, which are Unix-specific. Most of these procedures are generic, in that they are the same for all notifiers. However, none of the procedures are notifier-dependent: Tcl_InitNotifier, Tcl_AlertNotifier, Tcl_Final‐ izeNotifier, Tcl_SetTimer, Tcl_Sleep, Tcl_WaitForEvent, Tcl_CreateFile‐ Handler, Tcl_DeleteFileHandler and Tcl_ServiceModeHook. To support a new platform or to integrate Tcl with an application-specific event loop, you must write new versions of these procedures. Tcl_InitNotifier initializes the notifier state and returns a handle to the notifier state. Tcl calls this procedure when initializing a Tcl interpreter. Similarly, Tcl_FinalizeNotifier shuts down the notifier, and is called by Tcl_Finalize when shutting down a Tcl interpreter. Tcl_WaitForEvent is the lowest-level procedure in the notifier; it is responsible for waiting for an “interesting” event to occur or for a given time to elapse. Before Tcl_WaitForEvent is invoked, each of the event sources' setup procedure will have been invoked. The timePtr ar‐ gument to Tcl_WaitForEvent gives the maximum time to block for an event, based on calls to Tcl_SetMaxBlockTime made by setup procedures and on other information (such as the TCL_DONT_WAIT bit in flags). Ideally, Tcl_WaitForEvent should only wait for an event to occur; it should not actually process the event in any way. Later on, the event sources will process the raw events and create Tcl_Events on the event queue in their checkProc procedures. However, on some platforms (such as Windows) this is not possible; events may be processed in Tcl_Wait‐ ForEvent, including queuing Tcl_Events and more (for example, callbacks for native widgets may be invoked). The return value from Tcl_Wait‐ ForEvent must be either 0, 1, or -1. On platforms such as Windows where events get processed in Tcl_WaitForEvent, a return value of 1 means that there may be more events still pending that have not been processed. This is a sign to the caller that it must call Tcl_Wait‐ ForEvent again if it wants all pending events to be processed. A 0 re‐ turn value means that calling Tcl_WaitForEvent again will not have any effect: either this is a platform where Tcl_WaitForEvent only waits without doing any event processing, or Tcl_WaitForEvent knows for sure that there are no additional events to process (e.g. it returned be‐ cause the time elapsed). Finally, a return value of -1 means that the event loop is no longer operational and the application should probably unwind and terminate. Under Windows this happens when a WM_QUIT mes‐ sage is received; under Unix it happens when Tcl_WaitForEvent would have waited forever because there were no active event sources and the timeout was infinite. Tcl_AlertNotifier is used in multithreaded applications to allow any thread to “wake up” the notifier to alert it to new events on its queue. Tcl_AlertNotifier requires as an argument the notifier handle returned by Tcl_InitNotifier. If the notifier will be used with an external event loop, then it must also support the Tcl_SetTimer interface. Tcl_SetTimer is invoked by Tcl_SetMaxBlockTime whenever the maximum blocking time has been re‐ duced. Tcl_SetTimer should arrange for the external event loop to in‐ voke Tcl_ServiceAll after the specified interval even if no events have occurred. This interface is needed because Tcl_WaitForEvent is not in‐ voked when there is an external event loop. If the notifier will only be used from Tcl_DoOneEvent, then Tcl_SetTimer need not do anything. Tcl_ServiceModeHook is called by the platform-independent portion of the notifier when client code makes a call to Tcl_SetServiceMode. This hook is provided to support operating systems that require special event handling when the application is in a modal loop (the Windows no‐ tifier, for instance, uses this hook to create a communication window). On Unix systems, the file event source also needs support from the no‐ tifier. The file event source consists of the Tcl_CreateFileHandler and Tcl_DeleteFileHandler procedures, which are described in the Tcl_CreateFileHandler manual page. The Tcl_Sleep and Tcl_DoOneEvent interfaces are described in their re‐ spective manual pages. The easiest way to create a new notifier is to look at the code for an existing notifier, such as the files unix/tclUnixNotfy.c or win/tclWin‐ Notify.c in the Tcl source distribution. REPLACING THE NOTIFIER A notifier that has been written according to the conventions above can also be installed in a running process in place of the standard noti‐ fier. This mechanism is used so that a single executable can be used (with the standard notifier) as a stand-alone program and reused (with a replacement notifier in a loadable extension) as an extension to an‐ other program, such as a Web browser plugin. To do this, the extension makes a call to Tcl_SetNotifier passing a pointer to a Tcl_NotifierProcs data structure. The structure has the following layout: typedef struct Tcl_NotifierProcs { Tcl_SetTimerProc *setTimerProc; Tcl_WaitForEventProc *waitForEventProc; Tcl_CreateFileHandlerProc *createFileHandlerProc; Tcl_DeleteFileHandlerProc *deleteFileHandlerProc; Tcl_InitNotifierProc *initNotifierProc; Tcl_FinalizeNotifierProc *finalizeNotifierProc; Tcl_AlertNotifierProc *alertNotifierProc; Tcl_ServiceModeHookProc *serviceModeHookProc; } Tcl_NotifierProcs; Following the call to Tcl_SetNotifier, the pointers given in the Tcl_NotifierProcs structure replace whatever notifier had been in‐ stalled in the process. It is extraordinarily unwise to replace a running notifier. Normally, Tcl_SetNotifier should be called at process initialization time before the first call to Tcl_InitNotifier. EXTERNAL EVENT LOOPS The notifier interfaces are designed so that Tcl can be embedded into applications that have their own private event loops. In this case, the application does not call Tcl_DoOneEvent except in the case of re‐ cursive event loops such as calls to the Tcl commands update or vwait. Most of the time is spent in the external event loop of the applica‐ tion. In this case the notifier must arrange for the external event loop to call back into Tcl when something happens on the various Tcl event sources. These callbacks should arrange for appropriate Tcl events to be placed on the Tcl event queue. Because the external event loop is not calling Tcl_DoOneEvent on a reg‐ ular basis, it is up to the notifier to arrange for Tcl_ServiceEvent to be called whenever events are pending on the Tcl event queue. The eas‐ iest way to do this is to invoke Tcl_ServiceAll at the end of each callback from the external event loop. This will ensure that all of the event sources are polled, any queued events are serviced, and any pending idle handlers are processed before returning control to the ap‐ plication. In addition, event sources that need to poll for events can call Tcl_SetMaxBlockTime to force the external event loop to call Tcl even if no events are available on the system event queue. As a side effect of processing events detected in the main external event loop, Tcl may invoke Tcl_DoOneEvent to start a recursive event loop in commands like vwait. Tcl_DoOneEvent will invoke the external event loop, which will result in callbacks as described in the preced‐ ing paragraph, which will result in calls to Tcl_ServiceAll. However, in these cases it is undesirable to service events in Tcl_ServiceAll. Servicing events there is unnecessary because control will immediately return to the external event loop and hence to Tcl_DoOneEvent, which can service the events itself. Furthermore, Tcl_DoOneEvent is supposed to service only a single event, whereas Tcl_ServiceAll normally ser‐ vices all pending events. To handle this situation, Tcl_DoOneEvent sets a flag for Tcl_ServiceAll that causes it to return without servic‐ ing any events. This flag is called the service mode; Tcl_DoOneEvent restores it to its previous value before it returns. In some cases, however, it may be necessary for Tcl_ServiceAll to ser‐ vice events even when it has been invoked from Tcl_DoOneEvent. This happens when there is yet another recursive event loop invoked via an event handler called by Tcl_DoOneEvent (such as one that is part of a native widget). In this case, Tcl_DoOneEvent may not have a chance to service events so Tcl_ServiceAll must service them all. Any recursive event loop that calls an external event loop rather than Tcl_DoOneEvent must reset the service mode so that all events get processed in Tcl_ServiceAll. This is done by invoking the Tcl_SetServiceMode proce‐ dure. If Tcl_SetServiceMode is passed TCL_SERVICE_NONE, then calls to Tcl_ServiceAll will return immediately without processing any events. If Tcl_SetServiceMode is passed TCL_SERVICE_ALL, then calls to Tcl_Ser‐ viceAll will behave normally. Tcl_SetServiceMode returns the previous value of the service mode, which should be restored when the recursive loop exits. Tcl_GetServiceMode returns the current value of the ser‐ vice mode. SEE ALSO Tcl_CreateFileHandler(3), Tcl_DeleteFileHandler(3), Tcl_Sleep(3), Tcl_DoOneEvent(3), Thread(3) KEYWORDS event, notifier, event queue, event sources, file events, timer, idle, service mode, threads Tcl 8.1 Notifier(3)
Tcl_Preserve(3) Процедуры библиотеки Tcl Tcl_Preserve(3) ______________________________________________________________________________ NAME Tcl_Preserve, Tcl_Release, Tcl_EventuallyFree - избегать освобождения хранилища во время его использования SYNOPSIS #include <tcl.h> Tcl_Preserve(ClientData clientData) Tcl_Release(ClientData clientData) Tcl_EventuallyFree(ClientData clientData, Tcl_FreeProc *freeProc) ARGUMENTS ClientData clientData (in) Токен, описывающий структуру, которую нужно освободить или перераспределить. Обычно указатель на память для структуры. Tcl_FreeProc *freeProc (in) Процедура, которую нужно вызвать для освобождения clientData. ______________________________________________________________________________ DESCRIPTION Эти три процедуры помогают реализовать простой механизм подсчета ссылок для управления хранилищем. Они предназначены для решения проблемы, связанной с удалением виджетов, но также полезны в многих других ситуациях. Когда виджет удаляется, его запись виджета (структура, содержащая информацию, специфичную для виджета) должна быть возвращена в распределитель хранилища. Однако возможно, что запись виджета активно используется одной из процедур в стеке на момент удаления. Это может произойти, например, если команда, связанная с виджетом кнопки, вызывает удаление кнопки: событие X вызывает вызов процедуры обработки событий C в кнопке, что в свою очередь вызывает выполнение связанной с кнопкой команды Tcl, что в свою очередь приводит к удалению кнопки, что в свою очередь приводит к освобождению записи виджета кнопки. К сожалению, когда команда Tcl возвращается, процедура обработки событий кнопки потребуется обратиться к записи виджета кнопки. Из-за этого запись виджета не должна освобождаться в рамках удаления, а должна быть сохранена до тех пор, пока процедура обработки событий не завершит работу с ней. В других ситуациях, когда виджет удаляется, возможно немедленно освободить запись виджета. Tcl_Preserve и Tcl_Release реализуют короткосрочные счетчики ссылок для своего аргумента clientData. Аргумент clientData идентифицирует объект и обычно состоит из адреса структуры. Счетчики ссылок гарантируют, что объект не будет освобожден, пока каждый вызов Tcl_Preserve для объекта не будет сопоставлен с вызовами Tcl_Release. Может быть любое количество несопоставленных вызовов Tcl_Preserve одновременно. Tcl_EventuallyFree вызывается для освобождения своего аргумента clientData. Она проверяет, есть ли несопоставленные вызовы Tcl_Preserve для объекта. Если нет, то Tcl_EventuallyFree вызывает freeProc немедленно. В противном случае Tcl_EventuallyFree фиксирует факт, что clientData в конечном итоге нужно освободить. Когда все вызовы Tcl_Preserve будут сопоставлены с вызовами Tcl_Release, то freeProc будет вызвана Tcl_Release для выполнения очистки. Вся работа по освобождению объекта выполняется freeProc. FreeProc должна иметь аргументы и результат, соответствующие типу Tcl_FreeProc: typedef void Tcl_FreeProc( char *blockPtr); Аргумент blockPtr для freeProc будет таким же, как аргумент clientData для Tcl_EventuallyFree. Тип blockPtr (char *) отличается от типа аргумента clientData для Tcl_EventuallyFree по историческим причинам, но значение одинаково. Когда аргумент clientData для Tcl_EventuallyFree относится к хранилищу, выделенному и возвращенному предыдущим вызовом Tcl_Alloc, ckalloc или другой функции библиотеки Tcl, то аргумент freeProc должен иметь специальное значение TCL_DYNAMIC. Этот механизм можно использовать для решения описанной выше проблемы, разместив вызовы Tcl_Preserve и Tcl_Release вокруг действий, которые могут вызвать нежелательное перераспределение хранилища. Механизм предназначен только для краткосрочного использования (т. е. пока процедуры находятся в стеке); он не будет работать эффективно как механизм для долгосрочных счетчиков ссылок. Реализация не зависит каким-либо образом от внутренней структуры освобождаемых объектов; она хранит счетчики ссылок в отдельной структуре. SEE ALSO Tcl_Interp, Tcl_Alloc KEYWORDS free, reference count, storage Tcl 7.5 Tcl_Preserve(3)
Tcl_Preserve(3) Tcl Library Procedures Tcl_Preserve(3) ______________________________________________________________________________ NAME Tcl_Preserve, Tcl_Release, Tcl_EventuallyFree - avoid freeing storage while it is being used SYNOPSIS #include <tcl.h> Tcl_Preserve(clientData) Tcl_Release(clientData) Tcl_EventuallyFree(clientData, freeProc) ARGUMENTS ClientData clientData (in) Token describing structure to be freed or reallocated. Usually a pointer to memory for structure. Tcl_FreeProc *freeProc (in) Procedure to invoke to free clientData. ______________________________________________________________________________ DESCRIPTION These three procedures help implement a simple reference count mecha‐ nism for managing storage. They are designed to solve a problem having to do with widget deletion, but are also useful in many other situa‐ tions. When a widget is deleted, its widget record (the structure holding information specific to the widget) must be returned to the storage allocator. However, it is possible that the widget record is in active use by one of the procedures on the stack at the time of the deletion. This can happen, for example, if the command associated with a button widget causes the button to be destroyed: an X event causes an event-handling C procedure in the button to be invoked, which in turn causes the button's associated Tcl command to be executed, which in turn causes the button to be deleted, which in turn causes the but‐ ton's widget record to be de-allocated. Unfortunately, when the Tcl command returns, the button's event-handling procedure will need to reference the button's widget record. Because of this, the widget record must not be freed as part of the deletion, but must be retained until the event-handling procedure has finished with it. In other sit‐ uations where the widget is deleted, it may be possible to free the widget record immediately. Tcl_Preserve and Tcl_Release implement short-term reference counts for their clientData argument. The clientData argument identifies an ob‐ ject and usually consists of the address of a structure. The reference counts guarantee that an object will not be freed until each call to Tcl_Preserve for the object has been matched by calls to Tcl_Release. There may be any number of unmatched Tcl_Preserve calls in effect at once. Tcl_EventuallyFree is invoked to free up its clientData argument. It checks to see if there are unmatched Tcl_Preserve calls for the object. If not, then Tcl_EventuallyFree calls freeProc immediately. Otherwise Tcl_EventuallyFree records the fact that clientData needs eventually to be freed. When all calls to Tcl_Preserve have been matched with calls to Tcl_Release then freeProc will be called by Tcl_Release to do the cleanup. All the work of freeing the object is carried out by freeProc. FreeP‐ roc must have arguments and result that match the type Tcl_FreeProc: typedef void Tcl_FreeProc( char *blockPtr); The blockPtr argument to freeProc will be the same as the clientData argument to Tcl_EventuallyFree. The type of blockPtr (char *) is dif‐ ferent than the type of the clientData argument to Tcl_EventuallyFree for historical reasons, but the value is the same. When the clientData argument to Tcl_EventuallyFree refers to storage allocated and returned by a prior call to Tcl_Alloc, ckalloc, or an‐ other function of the Tcl library, then the freeProc argument should be given the special value of TCL_DYNAMIC. This mechanism can be used to solve the problem described above by placing Tcl_Preserve and Tcl_Release calls around actions that may cause undesired storage re-allocation. The mechanism is intended only for short-term use (i.e. while procedures are pending on the stack); it will not work efficiently as a mechanism for long-term reference counts. The implementation does not depend in any way on the internal structure of the objects being freed; it keeps the reference counts in a separate structure. SEE ALSO Tcl_Interp, Tcl_Alloc KEYWORDS free, reference count, storage Tcl 7.5 Tcl_Preserve(3)
Tcl_SplitList(3) Процедуры библиотеки Tcl Tcl_SplitList(3) ______________________________________________________________________________ NAME Tcl_SplitList, Tcl_Merge, Tcl_ScanElement, Tcl_ConvertElement, Tcl_ScanCountedElement, Tcl_ConvertCountedElement - манипулировать списками Tcl SYNOPSIS #include <tcl.h> int Tcl_SplitList(interp, list, argcPtr, argvPtr) char * Tcl_Merge(argc, argv) int Tcl_ScanElement(src, flagsPtr) int Tcl_ScanCountedElement(src, length, flagsPtr) int Tcl_ConvertElement(src, dst, flags) int Tcl_ConvertCountedElement(src, length, dst, flags) ARGUMENTS Tcl_Interp *interp (out) Интерпретатор для отчета об ошибках. Если значение NULL, сообщение об ошибке не оставляется. const char *list (in) Указатель на строку с правильной структурой списка. int *argcPtr (out) Заполняется количеством элементов в списке. const char ***argvPtr (out) *argvPtr будет заполнен адресом массива указателей на строки, которые являются извлеченными элементами списка. В массиве будет *argcPtr действительных записей, за которыми следует запись NULL. int argc (in) Количество элементов в argv. const char *const *argv (in) Массив строк для объединения в один список. Каждая строка станет отдельным элементом списка. const char *src (in) Строка, которая должна стать элементом списка. int *flagsPtr (in) Указатель на слово для заполнения информацией о src. Значение *flagsPtr должно быть передано в Tcl_ConvertElement. int length (in) Количество байтов в строке src. char *dst (in) Место для копирования преобразованного элемента списка. Должно содержать достаточно символов для хранения преобразованной строки. int flags (in) Информация о src. Должно быть значением, возвращенным предыдущим вызовом Tcl_ScanElement, возможно, объединенным с TCL_DONT_USE_BRACES с помощью операции OR. ______________________________________________________________________________ DESCRIPTION Эти процедуры могут быть использованы для разборa и сборки списков Tcl. Tcl_SplitList разбивает список на его составные элементы, возвращая массив указателей на элементы с помощью argcPtr и argvPtr. При извлечении аргументов Tcl_SplitList соблюдает обычные правила для подстановок обратных слэшей и фигурных скобок. Область памяти, на которую указывает *argvPtr, динамически выделяется; в дополнение к массиву указателей, она также содержит копии всех элементов списка. Ответственность за освобождение этой памяти лежит на вызывающей стороне. Например, предположим, что вы вызвали Tcl_SplitList с помощью следующего кода: int argc, code; char *string; char **argv; ... code = Tcl_SplitList(interp, string, &argc, &argv); Затем вы должны в конечном итоге освободить память с помощью вызова, подобного следующему: Tcl_Free((char *) argv); Tcl_SplitList обычно возвращает TCL_OK, что означает, что список был успешно разобраен. Если в списке была синтаксическая ошибка, то возвращается TCL_ERROR, и результат интерпретатора будет указывать на сообщение об ошибке, описывающее проблему (если interp не был NULL). Если возвращается TCL_ERROR, то память не выделяется, и *argvPtr не изменяется. Tcl_Merge является обратной операцией к Tcl_SplitList: она принимает коллекцию строк, заданных argc и argv, и генерирует результирующую строку с правильной структурой списка. Это означает, что команды, такие как index, могут быть использованы для извлечения исходных элементов снова. Кроме того, если результат Tcl_Merge передан в Tcl_Eval, он будет разобран на argc слов, значения которых будут такими же, как строки argv, переданные в Tcl_Merge. Tcl_Merge модифицирует элементы списка с помощью фигурных скобок и/или обратных слэшей для создания правильной структуры списка Tcl. Результирующая строка динамически выделяется с помощью Tcl_Alloc; вызывающая сторона должна в конечном итоге освободить пространство с помощью Tcl_Free. Если результат Tcl_Merge передан в Tcl_SplitList, элементы, возвращенные Tcl_SplitList, будут идентичны тем, которые были переданы в Tcl_Merge. Однако обратное неверно: если Tcl_SplitList передана заданная строка, и полученные argc и argv переданы в Tcl_Merge, результирующая строка может не быть той же, что и исходная строка, переданная в Tcl_SplitList. Это потому, что Tcl_Merge может использовать обратные слэши и фигурные скобки по-другому, чем исходная строка. Tcl_ScanElement и Tcl_ConvertElement являются процедурами, которые выполняют всю реальную работу Tcl_Merge. Tcl_ScanElement сканирует свой аргумент src и определяет, как использовать обратные слэши и фигурные скобки при преобразовании в элемент списка. Она возвращает завышенную оценку количества символов, необходимых для представления src в качестве элемента списка, и хранит информацию в *flagsPtr, которая необходима Tcl_ConvertElement. Tcl_ConvertElement является дополнительной процедурой к Tcl_ScanElement. Она выполняет фактическую работу по преобразованию строки в элемент списка. Ее аргумент flags должен быть таким же, как значение, возвращенное Tcl_ScanElement. Tcl_ConvertElement записывает правильный элемент списка в память, начиная с *dst, и возвращает счетчик общего количества записанных символов, который не превысит результат, возвращенный Tcl_ScanElement. Tcl_ConvertElement записывает только фактический элемент списка без каких-либо начальных или конечных пробелов: это зависит от вызывающей стороны, чтобы включить пробелы между соседними элементами списка. Tcl_ConvertElement использует один из двух разных подходов для обработки специальных символов в src. Везде, где возможно, она обрабатывает специальные символы, окружающие строку фигурными скобками. Это производит чистый вид вывода, но не может быть использовано в некоторых ситуациях, таких как когда src содержит несбалансированные фигурные скобки. В этих ситуациях Tcl_ConvertElement обрабатывает специальные символы, генерируя последовательности обратных слэшей для них. Вызывающая сторона может настаивать на втором подходе, объединив значение флага, возвращенное Tcl_ScanElement, с TCL_DONT_USE_BRACES с помощью операции OR. Хотя это произведет менее красивый результат, оно полезно в некоторых специальных ситуациях, таких как когда Tcl_ConvertElement используется для генерации части аргумента для команды Tcl. В этом случае, окружение src фигурными скобками приведет к тому, что команда не будет разобрана правильно. По умолчанию, Tcl_ConvertElement будет использовать кавычки в своем выводе, чтобы убедиться, что первый символ элемента не является символом хэша (“#”). Это для того, чтобы убедиться, что первый элемент любого списка, переданного в eval, не будет неправильно разобран как начало комментария. Когда элемент списка не является первым элементом списка, такие кавычки не нужны. Когда вызывающая сторона может быть уверена, что элемент не является первым элементом списка, она может отключить кавычки для начального символа хэша, объединив значение флага, возвращенное Tcl_ScanElement, с TCL_DONT_QUOTE_HASH. Tcl_ScanCountedElement и Tcl_ConvertCountedElement такие же, как Tcl_ScanElement и Tcl_ConvertElement, за исключением того, что длина строки src указывается аргументом length, и строка может содержать встроенные нулевые символы. SEE ALSO Tcl_ListObjGetElements(3) KEYWORDS backslash, convert, element, list, merge, split, strings Tcl 8.0 Tcl_SplitList(3)
Tcl_SplitList(3) Tcl Library Procedures Tcl_SplitList(3) ______________________________________________________________________________ NAME Tcl_SplitList, Tcl_Merge, Tcl_ScanElement, Tcl_ConvertElement, Tcl_ScanCountedElement, Tcl_ConvertCountedElement - manipulate Tcl lists SYNOPSIS #include <tcl.h> int Tcl_SplitList(interp, list, argcPtr, argvPtr) char * Tcl_Merge(argc, argv) int Tcl_ScanElement(src, flagsPtr) int Tcl_ScanCountedElement(src, length, flagsPtr) int Tcl_ConvertElement(src, dst, flags) int Tcl_ConvertCountedElement(src, length, dst, flags) ARGUMENTS Tcl_Interp *interp (out) Interpreter to use for error reporting. If NULL, then no error message is left. const char *list (in) Pointer to a string with proper list structure. int *argcPtr (out) Filled in with number of el‐ ements in list. const char ***argvPtr (out) *argvPtr will be filled in with the address of an array of pointers to the strings that are the extracted ele‐ ments of list. There will be *argcPtr valid entries in the array, followed by a NULL entry. int argc (in) Number of elements in argv. const char *const *argv (in) Array of strings to merge together into a single list. Each string will become a separate element of the list. const char *src (in) String that is to become an element of a list. int *flagsPtr (in) Pointer to word to fill in with information about src. The value of *flagsPtr must be passed to Tcl_ConvertEle‐ ment. int length (in) Number of bytes in string src. char *dst (in) Place to copy converted list element. Must contain enough characters to hold converted string. int flags (in) Information about src. Must be value returned by previ‐ ous call to Tcl_ScanElement, possibly OR-ed with TCL_DONT_USE_BRACES. ______________________________________________________________________________ DESCRIPTION These procedures may be used to disassemble and reassemble Tcl lists. Tcl_SplitList breaks a list up into its constituent elements, returning an array of pointers to the elements using argcPtr and argvPtr. While extracting the arguments, Tcl_SplitList obeys the usual rules for back‐ slash substitutions and braces. The area of memory pointed to by *argvPtr is dynamically allocated; in addition to the array of point‐ ers, it also holds copies of all the list elements. It is the caller's responsibility to free up all of this storage. For example, suppose that you have called Tcl_SplitList with the following code: int argc, code; char *string; char **argv; ... code = Tcl_SplitList(interp, string, &argc, &argv); Then you should eventually free the storage with a call like the fol‐ lowing: Tcl_Free((char *) argv); Tcl_SplitList normally returns TCL_OK, which means the list was suc‐ cessfully parsed. If there was a syntax error in list, then TCL_ERROR is returned and the interpreter's result will point to an error message describing the problem (if interp was not NULL). If TCL_ERROR is re‐ turned then no memory is allocated and *argvPtr is not modified. Tcl_Merge is the inverse of Tcl_SplitList: it takes a collection of strings given by argc and argv and generates a result string that has proper list structure. This means that commands like index may be used to extract the original elements again. In addition, if the result of Tcl_Merge is passed to Tcl_Eval, it will be parsed into argc words whose values will be the same as the argv strings passed to Tcl_Merge. Tcl_Merge will modify the list elements with braces and/or backslashes in order to produce proper Tcl list structure. The result string is dynamically allocated using Tcl_Alloc; the caller must eventually re‐ lease the space using Tcl_Free. If the result of Tcl_Merge is passed to Tcl_SplitList, the elements re‐ turned by Tcl_SplitList will be identical to those passed into Tcl_Merge. However, the converse is not true: if Tcl_SplitList is passed a given string, and the resulting argc and argv are passed to Tcl_Merge, the resulting string may not be the same as the original string passed to Tcl_SplitList. This is because Tcl_Merge may use backslashes and braces differently than the original string. Tcl_ScanElement and Tcl_ConvertElement are the procedures that do all of the real work of Tcl_Merge. Tcl_ScanElement scans its src argument and determines how to use backslashes and braces when converting it to a list element. It returns an overestimate of the number of characters required to represent src as a list element, and it stores information in *flagsPtr that is needed by Tcl_ConvertElement. Tcl_ConvertElement is a companion procedure to Tcl_ScanElement. It does the actual work of converting a string to a list element. Its flags argument must be the same as the value returned by Tcl_ScanEle‐ ment. Tcl_ConvertElement writes a proper list element to memory start‐ ing at *dst and returns a count of the total number of characters writ‐ ten, which will be no more than the result returned by Tcl_ScanElement. Tcl_ConvertElement writes out only the actual list element without any leading or trailing spaces: it is up to the caller to include spaces between adjacent list elements. Tcl_ConvertElement uses one of two different approaches to handle the special characters in src. Wherever possible, it handles special char‐ acters by surrounding the string with braces. This produces clean- looking output, but cannot be used in some situations, such as when src contains unmatched braces. In these situations, Tcl_ConvertElement handles special characters by generating backslash sequences for them. The caller may insist on the second approach by OR-ing the flag value returned by Tcl_ScanElement with TCL_DONT_USE_BRACES. Although this will produce an uglier result, it is useful in some special situations, such as when Tcl_ConvertElement is being used to generate a portion of an argument for a Tcl command. In this case, surrounding src with curly braces would cause the command not to be parsed correctly. By default, Tcl_ConvertElement will use quoting in its output to be sure the first character of an element is not the hash character (“#”.) This is to be sure the first element of any list passed to eval is not mis-parsed as the beginning of a comment. When a list element is not the first element of a list, this quoting is not necessary. When the caller can be sure that the element is not the first element of a list, it can disable quoting of the leading hash character by OR-ing the flag value returned by Tcl_ScanElement with TCL_DONT_QUOTE_HASH. Tcl_ScanCountedElement and Tcl_ConvertCountedElement are the same as Tcl_ScanElement and Tcl_ConvertElement, except the length of string src is specified by the length argument, and the string may contain embed‐ ded nulls. SEE ALSO Tcl_ListObjGetElements(3) KEYWORDS backslash, convert, element, list, merge, split, strings Tcl 8.0 Tcl_SplitList(3)
Tcl_CreateChannel(3) Процедуры библиотеки Tcl Tcl_CreateChannel(3) ______________________________________________________________________________ NAME Tcl_CreateChannel, Tcl_GetChannelInstanceData, Tcl_GetChannelType, Tcl_GetChannelName, Tcl_GetChannelHandle, Tcl_GetChannelMode, Tcl_GetChannelBufferSize, Tcl_SetChannelBufferSize, Tcl_NotifyChannel, Tcl_BadChannelOption, Tcl_ChannelName, Tcl_ChannelVersion, Tcl_Channel‐ BlockModeProc, Tcl_ChannelCloseProc, Tcl_ChannelClose2Proc, Tcl_Chan‐ nelInputProc, Tcl_ChannelOutputProc, Tcl_ChannelSeekProc, Tcl_Channel‐ WideSeekProc, Tcl_ChannelTruncateProc, Tcl_ChannelSetOptionProc, Tcl_ChannelGetOptionProc, Tcl_ChannelWatchProc, Tcl_ChannelGetH‐ andleProc, Tcl_ChannelFlushProc, Tcl_ChannelHandlerProc, Tcl_Chan‐ nelThreadActionProc, Tcl_IsChannelShared, Tcl_IsChannelRegistered, Tcl_CutChannel, Tcl_SpliceChannel, Tcl_IsChannelExisting, Tcl_ClearChannelHandlers, Tcl_GetChannelThread, Tcl_ChannelBuffered - процедуры для создания и манипулирования каналами SYNOPSIS #include <tcl.h> Tcl_Channel Tcl_CreateChannel(typePtr, channelName, instanceData, mask) ClientData Tcl_GetChannelInstanceData(channel) const Tcl_ChannelType * Tcl_GetChannelType(channel) const char * Tcl_GetChannelName(channel) int Tcl_GetChannelHandle(channel, direction, handlePtr) Tcl_ThreadId Tcl_GetChannelThread(channel) int Tcl_GetChannelMode(channel) int Tcl_GetChannelBufferSize(channel) Tcl_SetChannelBufferSize(channel, size) Tcl_NotifyChannel(channel, mask) int Tcl_BadChannelOption(interp, optionName, optionList) int Tcl_IsChannelShared(channel) int Tcl_IsChannelRegistered(interp, channel) int Tcl_IsChannelExisting(channelName) void Tcl_CutChannel(channel) void Tcl_SpliceChannel(channel) void Tcl_ClearChannelHandlers(channel) int Tcl_ChannelBuffered(channel) const char * Tcl_ChannelName(typePtr) Tcl_ChannelTypeVersion Tcl_ChannelVersion(typePtr) Tcl_DriverBlockModeProc * Tcl_ChannelBlockModeProc(typePtr) Tcl_DriverCloseProc * Tcl_ChannelCloseProc(typePtr) Tcl_DriverClose2Proc * Tcl_ChannelClose2Proc(typePtr) Tcl_DriverInputProc * Tcl_ChannelInputProc(typePtr) Tcl_DriverOutputProc * Tcl_ChannelOutputProc(typePtr) Tcl_DriverSeekProc * Tcl_ChannelSeekProc(typePtr) Tcl_DriverWideSeekProc * Tcl_ChannelWideSeekProc(typePtr) Tcl_DriverThreadActionProc * Tcl_ChannelThreadActionProc(typePtr) Tcl_DriverTruncateProc * Tcl_ChannelTruncateProc(typePtr) Tcl_DriverSetOptionProc * Tcl_ChannelSetOptionProc(typePtr) Tcl_DriverGetOptionProc * Tcl_ChannelGetOptionProc(typePtr) Tcl_DriverWatchProc * Tcl_ChannelWatchProc(typePtr) Tcl_DriverGetHandleProc * Tcl_ChannelGetHandleProc(typePtr) Tcl_DriverFlushProc * Tcl_ChannelFlushProc(typePtr) Tcl_DriverHandlerProc * Tcl_ChannelHandlerProc(typePtr) ARGUMENTS const Tcl_ChannelType *typePtr (in) Указывает на структуру, содержащую адреса процедур, которые могут быть вызваны для выполнения операций ввода-вывода и других функций для канала. const char *channelName (in) Имя этого канала, такое как file3; не должно использоваться никаким другим каналом. Может быть NULL, в таком случае канал создается без имени. Если созданный канал присваивается одному из стандартных каналов (stdin, stdout или stderr), то присвоенное имя канала будет именем стандартного канала. ClientData instanceData (in) Произвольное значение одного слова, которое ассоциируется с этим каналом. Это значение передается процедурам в typePtr при их вызове. int mask (in) Сочетание через OR из TCL_READABLE и TCL_WRITABLE, указывающее, открыт ли канал для чтения и записи. Tcl_Channel channel (in) Канал, на котором нужно выполнить операции. int direction (in) TCL_READABLE означает, что нужен дескриптор ввода; TCL_WRITABLE означает, что нужен дескриптор вывода. ClientData *handlePtr (out) Указывает на место, где следует хранить требуемый специфический для ОС дескриптор. int size (in) Размер, в байтах, буферов, которые будут выделены для этого канала. int mask (in) Сочетание через OR из TCL_READABLE, TCL_WRITABLE и TCL_EXCEPTION, которое указывает на события, произошедшие на этом канале. Tcl_Interp *interp (in) Текущий интерпретатор. (может быть NULL) const char *optionName (in) Имя недопустимой опции. const char *optionList (in) Специфический список опций (слова, разделенные пробелами, без "-"), который нужно добавить к стандартному списку общих опций. Может быть NULL для сообщения об ошибке только общих опций. ______________________________________________________________________________ DESCRIPTION Tcl использует двухуровневую архитектуру каналов. Она предоставляет общий верхний уровень, чтобы позволить программам на C и Tcl выполнять ввод и вывод с использованием одних и тех же API для различных файлов, устройств, сокетов и т.д. Общие API на C описаны в руководстве по Tcl_OpenFileChannel. Нижний уровень предоставляет специфические для типа драйверы каналов для каждого типа устройства, поддерживаемого на каждой платформе. Это руководство описывает API на C, используемые для связи между общим уровнем и специфическими для типа драйверами каналов. Оно также объясняет, как добавить новые типы каналов, предоставив новые драйверы каналов. Драйверы каналов состоят из нескольких компонентов: Во-первых, каждый драйвер канала предоставляет структуру Tcl_ChannelType, содержащую указатели на функции, реализующие различные операции, используемые общим уровнем для связи с драйвером канала. Структура Tcl_ChannelType и функции, на которые она ссылается, описаны в разделе TCL_CHANNELTYPE ниже. Во-вторых, драйверы каналов обычно предоставляют команду Tcl для создания экземпляров этого типа канала. Например, команда Tcl open создает каналы, использующие драйверы файлов и команд, а команда Tcl socket создает каналы, использующие TCP-сокеты для сетевой связи. В-третьих, драйвер канала по желанию предоставляет функцию C для открытия экземпляров этого типа канала. Например, Tcl_OpenFileChannel открывает канал, использующий драйвер файлов, а Tcl_OpenTcpClient открывает канал, использующий протокол TCP-сети. Эти функции создания обычно используют Tcl_CreateChannel внутренне для открытия канала. Чтобы добавить новый тип канала, вам нужно реализовать API на C или команду Tcl, которая открывает канал, вызывая Tcl_CreateChannel. Когда ваш драйвер вызывает Tcl_CreateChannel, он передает структуру Tcl_ChannelType, описывающую процедуры ввода-вывода драйвера. Общий уровень затем вызовет функции, на которые ссылается в этой структуре, для выполнения операций на канале. Tcl_CreateChannel открывает новый канал и ассоциирует с ним предоставленный typePtr и instanceData. Канал открывается в режиме, указанном в mask. Для обсуждения драйверов каналов, их операций и структуры Tcl_ChannelType см. раздел TCL_CHANNELTYPE ниже. Tcl_CreateChannel взаимодействует с кодом, управляющим стандартными каналами. После инициализации стандартного канала либо через вызов Tcl_GetStdChannel, либо через вызов Tcl_SetStdChannel, закрытие этого стандартного канала приведет к тому, что следующий вызов Tcl_CreateChannel сделает новый канал новым стандартным каналом. См. Tcl_StandardChannels для общего описания стандартных каналов и поведения библиотеки Tcl по отношению к ним. Tcl_GetChannelInstanceData возвращает данные экземпляра, ассоциированные с каналом в channel. Это то же самое, что и аргумент instanceData в вызове Tcl_CreateChannel, который создал этот канал. Tcl_GetChannelType возвращает указатель на структуру Tcl_ChannelType, используемую каналом в аргументе channel. Это то же самое, что и аргумент typePtr в вызове Tcl_CreateChannel, который создал этот канал. Tcl_GetChannelName возвращает строку, содержащую имя, ассоциированное с каналом, или NULL, если аргумент channelName в Tcl_CreateChannel был NULL. Tcl_GetChannelHandle размещает специфический для ОС дескриптор устройства, ассоциированный с каналом для заданного направления, в месте, указанном handlePtr, и возвращает TCL_OK. Если канал не имеет дескриптора устройства для указанного направления, то возвращается TCL_ERROR. Разные драйверы каналов вернут разные типы дескрипторов. Смотрите руководства для каждого драйвера, чтобы определить, какой тип дескриптора возвращается. Tcl_GetChannelThread возвращает идентификатор потока, который в данный момент управляет указанным каналом. Это позволяет драйверам каналов отправлять свои события файлов в правильную очередь событий, даже для многопоточного ядра. Tcl_GetChannelMode возвращает сочетание через OR из TCL_READABLE и TCL_WRITABLE, указывающее, открыт ли канал для ввода и вывода. Tcl_GetChannelBufferSize возвращает размер, в байтах, буферов, выделенных для хранения ввода или вывода в канале. Если значение не было установлено предыдущим вызовом Tcl_SetChannelBufferSize, описанным ниже, то возвращается значение по умолчанию 4096. Tcl_SetChannelBufferSize устанавливает размер, в байтах, буферов, которые будут выделены в последующих операциях на канале для хранения ввода или вывода. Аргумент size должен быть между одним и одним миллионом, позволяя буферам от одного байта до одного миллиона байтов. Если size выходит за этот диапазон, Tcl_SetChannelBufferSize устанавливает размер буфера в 4096. Tcl_NotifyChannel вызывается драйвером канала, чтобы указать общему уровню, что события, указанные в mask, произошли на канале. Драйверы каналов несут ответственность за вызов этой функции, когда обработчики каналов должны быть вызваны для канала (или должны быть выполнены другие ожидающие задачи, такие как сброс записи). См. WATCHPROC ниже для более подробной информации. Tcl_BadChannelOption вызывается из специфических для драйвера setOptionProc или getOptionProc, чтобы сгенерировать полное сообщение об ошибке. Tcl_ChannelBuffered возвращает количество байтов ввода, в данный момент буферизованных во внутреннем буфере (области возврата) самого канала. Он не сообщает о данных в общих буферах для стека каналов, частью которого является предоставленный канал. Tcl_IsChannelShared проверяет счетчик ссылок указанного канала и возвращает, делится ли канал между несколькими интерпретаторами (результат == 1) или нет (результат == 0). Tcl_IsChannelRegistered проверяет, зарегистрирован ли указанный канал в данном интерпретаторе (результат == 1) или нет (результат == 0). Tcl_IsChannelExisting проверяет, существует ли канал с указанным именем в глобальном списке всех каналов (результат == 1) или нет (результат == 0). Tcl_CutChannel удаляет указанный канал из глобального списка всех каналов (текущего потока). Применение к каналу, все еще зарегистрированному в каком-то интерпретаторе, не допускается. Также уведомляет драйвер, если версия Tcl_ChannelType равна TCL_CHANNEL_VERSION_4 (или выше), и Tcl_DriverThreadActionProc определен для него. Tcl_SpliceChannel добавляет указанный канал в глобальный список всех каналов (текущего потока). Применение к каналу, зарегистрированному в каком-то интерпретаторе, не допускается. Также уведомляет драйвер, если версия Tcl_ChannelType равна TCL_CHANNEL_VERSION_4 (или выше), и Tcl_DriverThreadActionProc определен для него. Tcl_ClearChannelHandlers удаляет все обработчики каналов и сценарии событий, ассоциированные с указанным каналом, тем самым отключая всю обработку событий для этого канала. TCL_CHANNELTYPE Драйвер канала предоставляет структуру Tcl_ChannelType, содержащую указатели на функции, реализующие различные операции на канале; эти операции вызываются по необходимости общим уровнем. Структура была версионирована, начиная с Tcl 8.3.2/8.4, чтобы исправить проблему с драйверами стекированных каналов. См. раздел OLD CHANNEL TYPES ниже для деталей о старой структуре. Структура Tcl_ChannelType содержит следующие поля: typedef struct Tcl_ChannelType { const char *typeName; Tcl_ChannelTypeVersion version; Tcl_DriverCloseProc *closeProc; Tcl_DriverInputProc *inputProc; Tcl_DriverOutputProc *outputProc; Tcl_DriverSeekProc *seekProc; Tcl_DriverSetOptionProc *setOptionProc; Tcl_DriverGetOptionProc *getOptionProc; Tcl_DriverWatchProc *watchProc; Tcl_DriverGetHandleProc *getHandleProc; Tcl_DriverClose2Proc *close2Proc; Tcl_DriverBlockModeProc *blockModeProc; Tcl_DriverFlushProc *flushProc; Tcl_DriverHandlerProc *handlerProc; Tcl_DriverWideSeekProc *wideSeekProc; Tcl_DriverThreadActionProc *threadActionProc; Tcl_DriverTruncateProc *truncateProc; } Tcl_ChannelType; Не обязательно предоставлять реализации для всех операций канала. Те, которые не нужны, могут быть установлены в NULL в структуре: blockModeProc, seekProc, setOptionProc, getOptionProc, getHandleProc, и close2Proc, кроме flushProc, handlerProc, threadActionProc и truncateProc. Другие функции, которые не могут быть реализованы осмысленным образом, должны возвращать EINVAL при вызове, чтобы указать, что операции, которые они представляют, недоступны. Также отметьте, что wideSeekProc может быть NULL, если seekProc есть. Пользователь должен использовать только вышеуказанную структуру для инстанцирования Tcl_ChannelType. При ссылке на поля в структуре Tcl_ChannelType следует использовать следующие функции для получения значений: Tcl_ChannelName, Tcl_ChannelVersion, Tcl_ChannelBlockModeProc, Tcl_ChannelCloseProc, Tcl_ChannelClose2Proc, Tcl_ChannelInputProc, Tcl_ChannelOutputProc, Tcl_ChannelSeekProc, Tcl_ChannelWideSeekProc, Tcl_ChannelThreadActionProc, Tcl_ChannelTruncateProc, Tcl_ChannelSetOptionProc, Tcl_ChannelGetOptionProc, Tcl_ChannelWatchProc, Tcl_ChannelGetHandleProc, Tcl_ChannelFlushProc или Tcl_ChannelHandlerProc. Изменение структуры было сделано так, чтобы стандартные типы каналов были бинарно совместимы. Однако, типы каналов, которые используют стекированные каналы (т.е. TLS, Trf), имеют новые версии для соответствия вышеуказанному изменению, поскольку предыдущий код для стекированных каналов имел проблемы. TYPENAME Поле typeName содержит завершенную нулем строку, которая идентифицирует тип устройства, реализованного этим драйвером, например file или socket. Это значение можно получить с помощью Tcl_ChannelName, которая возвращает указатель на строку. VERSION Поле version должно быть установлено на версию структуры, которую вы требуете. TCL_CHANNEL_VERSION_2 - это минимально рекомендуемая. TCL_CHANNEL_VERSION_3 должно быть установлено для указания члена wideSeekProc. TCL_CHANNEL_VERSION_4 должно быть установлено для указания члена threadActionProc (включая wideSeekProc). TCL_CHANNEL_VERSION_5 должно быть установлено для указания членов truncateProc (включая wideSeekProc и threadActionProc). Если оно не установлено ни в одно из этих, то предполагается, что эта Tcl_ChannelType имеет исходную структуру. См. OLD CHANNEL TYPES для более подробной информации. Хотя Tcl будет распознавать и работать с любой из структур, стекированные каналы должны быть как минимум TCL_CHANNEL_VERSION_2, чтобы работать правильно. Это значение можно получить с помощью Tcl_ChannelVersion, которая возвращает одно из TCL_CHANNEL_VERSION_5, TCL_CHANNEL_VERSION_4, TCL_CHANNEL_VERSION_3, TCL_CHANNEL_VERSION_2 или TCL_CHANNEL_VERSION_1. BLOCKMODEPROC Поле blockModeProc содержит адрес функции, вызываемой общим уровнем для установки режима блокировки и неблокировки на устройстве. BlockModeProc должна соответствовать следующему прототипу: typedef int Tcl_DriverBlockModeProc( ClientData instanceData, int mode); Аргумент instanceData - то же самое, что и значение, переданное Tcl_CreateChannel при создании этого канала. Аргумент mode - это либо TCL_MODE_BLOCKING, либо TCL_MODE_NONBLOCKING для установки устройства в режим блокировки или неблокировки. Функция должна возвращать ноль, если операция прошла успешно, или ненулевой код ошибки POSIX, если операция завершилась неудачей. Если операция успешна, функция может изменить предоставленный instanceData для записи того, что канал вошел в режим блокировки или неблокировки, и для реализации поведения блокировки или неблокировки. Для некоторых типов устройств поведение блокировки и неблокировки может быть реализовано базовой операционной системой; для других типов устройств поведение должно быть эмулировано в драйвере канала. Это значение можно получить с помощью Tcl_ChannelBlockModeProc, которая возвращает указатель на функцию. Драйвер канала, не предоставляющий blockModeProc, должен быть очень осторожным. Он должен точно указать общему уровню, какой режим блокировки приемлем для него, и также задокументировать это для пользователя, чтобы режим блокировки канала не изменился на неприемлемое значение. Любая путаница здесь может привести интерпретатор в (ложный и трудно обнаруживаемый) тупик. CLOSEPROC AND CLOSE2PROC Поле closeProc содержит адрес функции, вызываемой общим уровнем для очистки информации, связанной с драйвером, при закрытии канала. CloseProc должна соответствовать следующему прототипу: typedef int Tcl_DriverCloseProc( ClientData instanceData, Tcl_Interp *interp); Аргумент instanceData - то же самое, что и значение, предоставленное Tcl_CreateChannel при создании канала. Функция должна освободить любое хранилище, поддерживаемое драйвером канала для этого канала, и закрыть устройства ввода и вывода, инкапсулированные этим каналом. Все очередированный вывод будет сброшен в устройство перед вызовом этой функции, и никакие дальнейшие операции драйвера не будут вызваны для этого экземпляра после вызова closeProc. Если операция закрытия успешна, процедура должна возвращать ноль; в противном случае она должна возвращать ненулевой код ошибки POSIX. Кроме того, если возникает ошибка и interp не NULL, процедура должна хранить сообщение об ошибке в результате интерпретатора. В качестве альтернативы, каналы, которые поддерживают закрытие сторон чтения и записи независимо, могут установить closeProc в TCL_CLOSE2PROC и close2Proc в адрес функции, которая соответствует следующему прототипу: typedef int Tcl_DriverClose2Proc( ClientData instanceData, Tcl_Interp *interp, int flags); Close2Proc будет вызвана с flags, установленным в сочетание через OR из TCL_CLOSE_READ или TCL_CLOSE_WRITE, чтобы указать, что драйвер должен закрыть сторону чтения и/или записи канала. Драйвер канала может быть вызван для выполнения дополнительных операций на канале после вызова close2Proc для закрытия одной или обеих сторон канала. Если flags равно 0 (ноль), драйвер должен закрыть канал так, как описано выше для closeProc. Ни одна дальнейшая операция не будет вызвана для этого экземпляра после вызова close2Proc со всеми флагами, очищенными. В всех случаях функция close2Proc должна возвращать ноль, если операция закрытия прошла успешно; в противном случае она должна возвращать ненулевой код ошибки POSIX. Кроме того, если возникает ошибка и interp не NULL, процедура должна хранить сообщение об ошибке в результате интерпретатора. Значения closeProc и close2Proc можно получить с помощью Tcl_ChannelCloseProc или Tcl_ChannelClose2Proc, которые возвращают указатель на соответствующую функцию. INPUTPROC Поле inputProc содержит адрес функции, вызываемой общим уровнем для чтения данных из файла или устройства и хранения их во внутреннем буфере. InputProc должна соответствовать следующему прототипу: typedef int Tcl_DriverInputProc( ClientData instanceData, char *buf, int bufSize, int *errorCodePtr); InstanceData - то же самое, что и значение, переданное Tcl_CreateChannel при создании канала. Аргумент buf указывает на массив байтов, в котором следует хранить ввод из устройства, а аргумент bufSize указывает, сколько байтов доступно в buf. Аргумент errorCodePtr указывает на переменную целого числа, предоставленную общим уровнем. Если возникает ошибка, функция должна установить эту переменную в код ошибки POSIX, который идентифицирует возникшую ошибку. Функция должна читать данные из устройства ввода, инкапсулированного каналом, и хранить их в buf. При успешном выполнении функция должна возвращать неотрицательное целое число, указывающее, сколько байтов было прочитано из устройства ввода и сохранено в buf. При ошибке функция должна возвращать -1. Если ошибка возникает после того, как некоторые данные были прочитаны из устройства, эти данные потеряны. Если inputProc может определить, что устройство ввода имеет некоторые доступные данные, но меньше, чем запрошено аргументом bufSize, функция должна попытаться прочитать только столько данных, сколько доступно, и вернуться без блокировки. Если устройство ввода не имеет доступных данных и канал находится в неблокирующем режиме, функция должна возвращать ошибку EAGAIN. Если устройство ввода не имеет доступных данных и канал находится в блокирующем режиме, функция должна блокироваться на как можно более короткое время, пока не сможет прочитать хотя бы один байт данных из устройства; затем она должна вернуть столько данных, сколько может прочитать без блокировки. Это значение можно получить с помощью Tcl_ChannelInputProc, которая возвращает указатель на функцию. OUTPUTPROC Поле outputProc содержит адрес функции, вызываемой общим уровнем для передачи данных из внутреннего буфера в устройство вывода. OutputProc должна соответствовать следующему прототипу: typedef int Tcl_DriverOutputProc( ClientData instanceData, const char *buf, int toWrite, int *errorCodePtr); InstanceData - то же самое, что и значение, переданное Tcl_CreateChannel при создании канала. Аргумент buf содержит массив байтов, которые нужно записать в устройство, а аргумент toWrite указывает, сколько байтов нужно записать из buf. Аргумент errorCodePtr указывает на переменную целого числа, предоставленную общим уровнем. Если возникает ошибка, функция должна установить эту переменную в код ошибки POSIX, который идентифицирует ошибку. Функция должна записать данные в buf в устройство вывода, инкапсулированное каналом. При успешном выполнении функция должна возвращать неотрицательное целое число, указывающее, сколько байтов было записано в устройство вывода. Возвращаемое значение обычно равно toWrite, но может быть меньше в некоторых случаях, таких как если операция вывода прерывается сигналом. Если возникает ошибка, функция должна возвращать -1. В случае ошибки некоторые данные могли быть записаны в устройство. Если канал неблокирующий и устройство вывода не может поглотить никаких данных, функция должна возвращать -1 с ошибкой EAGAIN, не записывая никаких данных. Это значение можно получить с помощью Tcl_ChannelOutputProc, которая возвращает указатель на функцию. SEEKPROC AND WIDESEEKPROC Поле seekProc содержит адрес функции, вызываемой общим уровнем для перемещения точки доступа, к которой будут применяться последующие операции ввода или вывода. SeekProc должна соответствовать следующему прототипу: typedef int Tcl_DriverSeekProc( ClientData instanceData, long offset, int seekMode, int *errorCodePtr); Аргумент instanceData - то же самое, что и значение, данное Tcl_CreateChannel при создании этого канала. Offset и seekMode имеют то же значение, что и для процедуры Tcl_Seek (описанной в руководстве по Tcl_OpenFileChannel). Аргумент errorCodePtr указывает на переменную целого числа, предоставленную общим уровнем для возврата значений errno из функции. Функция должна установить эту переменную в код ошибки POSIX, если возникает ошибка. Функция должна хранить код ошибки EINVAL, если тип канала не реализует поиск. Возвращаемое значение - новая точка доступа или -1 в случае ошибки. Если возникла ошибка, функция не должна перемещать точку доступа. Если есть ненулевое поле seekProc, поле wideSeekProc может содержать адрес альтернативной функции для использования, которая обрабатывает широкие (т.е. больше 32-битные) смещения, что позволяет выполнять поиск в файлах больше 2 ГБ. WideSeekProc будет вызвана в предпочтении перед seekProc, но оба должны быть определены, если wideSeekProc определена. WideSeekProc должна соответствовать следующему прототипу: typedef Tcl_WideInt Tcl_DriverWideSeekProc( ClientData instanceData, Tcl_WideInt offset, int seekMode, int *errorCodePtr); Аргументы и возвращаемое значение имеют то же значение, что и в seekProc выше, за исключением того, что тип смещений и тип возвращаемого значения отличаются. Значение seekProc можно получить с помощью Tcl_ChannelSeekProc, которая возвращает указатель на функцию, и аналогично wideSeekProc можно получить с помощью Tcl_ChannelWideSeekProc. SETOPTIONPROC Поле setOptionProc содержит адрес функции, вызываемой общим уровнем для установки опции, специфичной для типа канала, на канале. SetOptionProc должна соответствовать следующему прототипу: typedef int Tcl_DriverSetOptionProc( ClientData instanceData, Tcl_Interp *interp, const char *optionName, const char *newValue); OptionName - имя опции для установки, а newValue - новое значение для этой опции в виде строки. InstanceData - то же самое, что и значение, данное Tcl_CreateChannel при создании этого канала. Функция должна выполнять любые действия, специфичные для типа канала, которые требуются для реализации нового значения опции. Некоторые опции обрабатываются общим кодом, и эта функция никогда не вызывается для их установки, например -blockmode. Другие опции специфичны для каждого типа канала, и процедура setOptionProc драйвера канала будет вызвана для их реализации. Поле setOptionProc может быть NULL, что указывает, что этот тип канала не поддерживает специфических для типа опций. Если значение опции успешно изменено на новое значение, функция возвращает TCL_OK. Она должна вызывать Tcl_BadChannelOption, которая сама возвращает TCL_ERROR, если optionName не распознано. Если newValue указывает значение для опции, которое не поддерживается, или если возникает системная ошибка, функция должна оставить сообщение об ошибке в результате interp, если interp не NULL. Функция также должна вызывать Tcl_SetErrno для хранения подходящего кода ошибки POSIX. Это значение можно получить с помощью Tcl_ChannelSetOptionProc, которая возвращает указатель на функцию. GETOPTIONPROC Поле getOptionProc содержит адрес функции, вызываемой общим уровнем для получения значения опции, специфичной для типа канала, на канале. GetOptionProc должна соответствовать следующему прототипу: typedef int Tcl_DriverGetOptionProc( ClientData instanceData, Tcl_Interp *interp, const char *optionName, Tcl_DString *optionValue); OptionName - имя опции, поддерживаемой этим типом канала. Если имя опции не NULL, функция хранит ее текущее значение, в виде строки, в динамической строке Tcl optionValue. Если optionName равно NULL, функция хранит в optionValue чередующийся список всех поддерживаемых опций и их текущих значений. При успешном выполнении функция возвращает TCL_OK. Она должна вызывать Tcl_BadChannelOption, которая сама возвращает TCL_ERROR, если optionName не распознано. Если возникает системная ошибка, функция должна оставить сообщение об ошибке в результате interp, если interp не NULL. Функция также должна вызывать Tcl_SetErrno для хранения подходящего кода ошибки POSIX. Некоторые опции обрабатываются общим кодом, и эта функция никогда не вызывается для получения их значения, например -blockmode. Другие опции специфичны для каждого типа канала, и процедура getOptionProc драйвера канала будет вызвана для их реализации. Поле getOptionProc может быть NULL, что указывает, что этот тип канала не поддерживает специфических для типа опций. Это значение можно получить с помощью Tcl_ChannelGetOptionProc, которая возвращает указатель на функцию. WATCHPROC Поле watchProc содержит адрес функции, вызываемой общим уровнем для инициализации механизма уведомления о событиях, чтобы заметить события интереса на этом канале. WatchProc должна соответствовать следующему прототипу: typedef void Tcl_DriverWatchProc( ClientData instanceData, int mask); Аргумент instanceData - то же самое, что и значение, переданное Tcl_CreateChannel при создании этого канала. Аргумент mask - это сочетание через OR из TCL_READABLE, TCL_WRITABLE и TCL_EXCEPTION; оно указывает события, которыми заинтересован вызывающий на этом канале. Функция должна инициализировать механизмы, специфичные для типа устройства, для обнаружения, когда событие интереса присутствует на канале. Когда одно или несколько указанных событий происходит на канале, драйвер канала несет ответственность за вызов Tcl_NotifyChannel для информирования модуля общего канала. Драйвер должен позаботиться о том, чтобы не "голодать" другие драйверы каналов или источники обратных вызовов, вызывая Tcl_NotifyChannel слишком часто. Честность можно обеспечить, используя очередь событий Tcl для планирования события канала в последовательности с другими событиями. См. описание Tcl_QueueEvent для деталей о том, как поставить событие в очередь. Это значение можно получить с помощью Tcl_ChannelWatchProc, которая возвращает указатель на функцию. GETHANDLEPROC Поле getHandleProc содержит адрес функции, вызываемой общим уровнем для получения дескриптора, специфичного для устройства, из канала. GetHandleProc должна соответствовать следующему прототипу: typedef int Tcl_DriverGetHandleProc( ClientData instanceData, int direction, ClientData *handlePtr); InstanceData - то же самое, что и значение, переданное Tcl_CreateChannel при создании этого канала. Аргумент direction - это либо TCL_READABLE для получения дескриптора, используемого для ввода, либо TCL_WRITABLE для получения дескриптора, используемого для вывода. Если реализация канала имеет дескрипторы, специфичные для устройства, функция должна получить подходящий дескриптор, ассоциированный с каналом, в соответствии с аргументом direction. Дескриптор должен быть сохранен в месте, на которое ссылается handlePtr, и должна возвращаться TCL_OK. Если канал не открыт для указанного направления или если реализация канала не использует дескрипторы устройств, функция должна возвращать TCL_ERROR. Это значение можно получить с помощью Tcl_ChannelGetHandleProc, которая возвращает указатель на функцию. FLUSHPROC Поле flushProc в настоящее время зарезервировано для будущего использования. Оно должно быть установлено в NULL. FlushProc должна соответствовать следующему прототипу: typedef int Tcl_DriverFlushProc( ClientData instanceData); Это значение можно получить с помощью Tcl_ChannelFlushProc, которая возвращает указатель на функцию. HANDLERPROC Поле handlerProc содержит адрес функции, вызываемой общим уровнем для уведомления канала о том, что произошло событие. Оно должно быть определено для драйверов стекированных каналов, которые хотят быть уведомленными о событиях, происходящих на базовом (стекированном) канале. HandlerProc должна соответствовать следующему прототипу: typedef int Tcl_DriverHandlerProc( ClientData instanceData, int interestMask); InstanceData - то же самое, что и значение, переданное Tcl_CreateChannel при создании этого канала. Аргумент interestMask - это сочетание через OR из TCL_READABLE или TCL_WRITABLE; оно указывает, какой тип события произошел на этом канале. Это значение можно получить с помощью Tcl_ChannelHandlerProc, которая возвращает указатель на функцию. THREADACTIONPROC Поле threadActionProc содержит адрес функции, вызываемой общим уровнем, когда канал создается, закрывается или собирается перейти в другой поток, т.е. когда специфическое для потока состояние драйвера может потребоваться инициализировать или обновить. Оно может быть NULL. Действие TCL_CHANNEL_THREAD_REMOVE используется для уведомления драйвера о том, что он должен обновить или удалить любые специфические для потока данные, которые он может поддерживать для канала. Действие TCL_CHANNEL_THREAD_INSERT используется для уведомления драйвера о том, что он должен обновить или инициализировать любые специфические для потока данные, которые он может поддерживать, используя вызывающий поток в качестве ассоциированного. См. Tcl_CutChannel и Tcl_SpliceChannel для более подробной информации. typedef void Tcl_DriverThreadActionProc( ClientData instanceData, int action); InstanceData - то же самое, что и значение, переданное Tcl_CreateChannel при создании этого канала. Эти значения можно получить с помощью Tcl_ChannelThreadActionProc, которая возвращает указатель на функцию. TRUNCATEPROC Поле truncateProc содержит адрес функции, вызываемой общим уровнем, когда канал усекается до некоторой длины. Оно может быть NULL. typedef int Tcl_DriverTruncateProc( ClientData instanceData, Tcl_WideInt length); InstanceData - то же самое, что и значение, переданное Tcl_CreateChannel при создании этого канала, а length - новая длина базового файла, которая не должна быть отрицательной. Результат должен быть 0 при успешном выполнении или код errno (подходящий для использования с Tcl_SetErrno) при неудаче. Эти значения можно получить с помощью Tcl_ChannelTruncateProc, которая возвращает указатель на функцию. TCL_BADCHANNELOPTION Эта процедура генерирует сообщение об ошибке "недопустимая опция" в (опциональном) интерпретаторе. Она используется драйверами каналов, когда запрашивается недопустимая опция Set/Get. Ее цель - объединить список общих опций со специфическими и факторизовать строку сообщения об ошибке общих опций. Она всегда возвращает TCL_ERROR Сообщение об ошибке генерируется в значении результата interp, чтобы указать, что команда была вызвана с недопустимой опцией. Сообщение имеет форму bad option "blah": should be one of <...общие опции...>+<...специфические опции...> так что вы получаете, например: bad option "-blah": should be one of -blocking, -buffering, -buffersize, -eofchar, -translation, -peername, or -sockname когда вызывается с optionList равным “peername sockname” "blah" - это аргумент optionName, а "<специфические опции>" - это список слов специфических опций, разделенных пробелами. Функция тщательно заботится о вставке минусов перед каждой опцией, запятых после и "or" перед последней опцией. OLD CHANNEL TYPES Исходная (8.3.1 и ниже) структура Tcl_ChannelType содержит следующие поля: typedef struct Tcl_ChannelType { const char *typeName; Tcl_DriverBlockModeProc *blockModeProc; Tcl_DriverCloseProc *closeProc; Tcl_DriverInputProc *inputProc; Tcl_DriverOutputProc *outputProc; Tcl_DriverSeekProc *seekProc; Tcl_DriverSetOptionProc *setOptionProc; Tcl_DriverGetOptionProc *getOptionProc; Tcl_DriverWatchProc *watchProc; Tcl_DriverGetHandleProc *getHandleProc; Tcl_DriverClose2Proc *close2Proc; } Tcl_ChannelType; Все еще возможно создавать канал с вышеуказанной структурой. Внутренний код канала определит версию. Обязательно используйте новую структуру Tcl_ChannelType, если вы создаете драйвер стекированного канала, из-за проблем с предыдущей реализацией стекированных каналов (в 8.2.0 до 8.3.1). До 8.4.0 (т.е. во время поздних выпусков 8.3 и ранней части цикла разработки 8.4) структура Tcl_ChannelType содержала следующие поля: typedef struct Tcl_ChannelType { const char *typeName; Tcl_ChannelTypeVersion version; Tcl_DriverCloseProc *closeProc; Tcl_DriverInputProc *inputProc; Tcl_DriverOutputProc *outputProc; Tcl_DriverSeekProc *seekProc; Tcl_DriverSetOptionProc *setOptionProc; Tcl_DriverGetOptionProc *getOptionProc; Tcl_DriverWatchProc *watchProc; Tcl_DriverGetHandleProc *getHandleProc; Tcl_DriverClose2Proc *close2Proc; Tcl_DriverBlockModeProc *blockModeProc; Tcl_DriverFlushProc *flushProc; Tcl_DriverHandlerProc *handlerProc; Tcl_DriverTruncateProc *truncateProc; } Tcl_ChannelType; Когда вышеуказанная структура регистрируется как тип канала, поле version всегда должно быть TCL_CHANNEL_VERSION_2. SEE ALSO Tcl_Close(3), Tcl_OpenFileChannel(3), Tcl_SetErrno(3), Tcl_QueueEvent(3), Tcl_StackChannel(3), Tcl_GetStdChannel(3) KEYWORDS blocking, channel driver, channel registration, channel type, nonblocking Tcl 8.4 Tcl_CreateChannel(3)
Tcl_CreateChannel(3) Tcl Library Procedures Tcl_CreateChannel(3) ______________________________________________________________________________ NAME Tcl_CreateChannel, Tcl_GetChannelInstanceData, Tcl_GetChannelType, Tcl_GetChannelName, Tcl_GetChannelHandle, Tcl_GetChannelMode, Tcl_GetChannelBufferSize, Tcl_SetChannelBufferSize, Tcl_NotifyChannel, Tcl_BadChannelOption, Tcl_ChannelName, Tcl_ChannelVersion, Tcl_Channel‐ BlockModeProc, Tcl_ChannelCloseProc, Tcl_ChannelClose2Proc, Tcl_Chan‐ nelInputProc, Tcl_ChannelOutputProc, Tcl_ChannelSeekProc, Tcl_Channel‐ WideSeekProc, Tcl_ChannelTruncateProc, Tcl_ChannelSetOptionProc, Tcl_ChannelGetOptionProc, Tcl_ChannelWatchProc, Tcl_ChannelGetH‐ andleProc, Tcl_ChannelFlushProc, Tcl_ChannelHandlerProc, Tcl_Chan‐ nelThreadActionProc, Tcl_IsChannelShared, Tcl_IsChannelRegistered, Tcl_CutChannel, Tcl_SpliceChannel, Tcl_IsChannelExisting, Tcl_ClearChannelHandlers, Tcl_GetChannelThread, Tcl_ChannelBuffered - procedures for creating and manipulating channels SYNOPSIS #include <tcl.h> Tcl_Channel Tcl_CreateChannel(typePtr, channelName, instanceData, mask) ClientData Tcl_GetChannelInstanceData(channel) const Tcl_ChannelType * Tcl_GetChannelType(channel) const char * Tcl_GetChannelName(channel) int Tcl_GetChannelHandle(channel, direction, handlePtr) Tcl_ThreadId Tcl_GetChannelThread(channel) int Tcl_GetChannelMode(channel) int Tcl_GetChannelBufferSize(channel) Tcl_SetChannelBufferSize(channel, size) Tcl_NotifyChannel(channel, mask) int Tcl_BadChannelOption(interp, optionName, optionList) int Tcl_IsChannelShared(channel) int Tcl_IsChannelRegistered(interp, channel) int Tcl_IsChannelExisting(channelName) void Tcl_CutChannel(channel) void Tcl_SpliceChannel(channel) void Tcl_ClearChannelHandlers(channel) int Tcl_ChannelBuffered(channel) const char * Tcl_ChannelName(typePtr) Tcl_ChannelTypeVersion Tcl_ChannelVersion(typePtr) Tcl_DriverBlockModeProc * Tcl_ChannelBlockModeProc(typePtr) Tcl_DriverCloseProc * Tcl_ChannelCloseProc(typePtr) Tcl_DriverClose2Proc * Tcl_ChannelClose2Proc(typePtr) Tcl_DriverInputProc * Tcl_ChannelInputProc(typePtr) Tcl_DriverOutputProc * Tcl_ChannelOutputProc(typePtr) Tcl_DriverSeekProc * Tcl_ChannelSeekProc(typePtr) Tcl_DriverWideSeekProc * Tcl_ChannelWideSeekProc(typePtr) Tcl_DriverThreadActionProc * Tcl_ChannelThreadActionProc(typePtr) Tcl_DriverTruncateProc * Tcl_ChannelTruncateProc(typePtr) Tcl_DriverSetOptionProc * Tcl_ChannelSetOptionProc(typePtr) Tcl_DriverGetOptionProc * Tcl_ChannelGetOptionProc(typePtr) Tcl_DriverWatchProc * Tcl_ChannelWatchProc(typePtr) Tcl_DriverGetHandleProc * Tcl_ChannelGetHandleProc(typePtr) Tcl_DriverFlushProc * Tcl_ChannelFlushProc(typePtr) Tcl_DriverHandlerProc * Tcl_ChannelHandlerProc(typePtr) ARGUMENTS const Tcl_ChannelType *typePtr (in) Points to a structure containing the ad‐ dresses of procedures that can be called to perform I/O and other functions on the chan‐ nel. const char *channelName (in) The name of this chan‐ nel, such as file3; must not be in use by any other channel. Can be NULL, in which case the channel is created without a name. If the created channel is as‐ signed to one of the standard channels (stdin, stdout or stderr), the assigned channel name will be the name of the stan‐ dard channel. ClientData instanceData (in) Arbitrary one-word value to be associated with this channel. This value is passed to procedures in type‐ Ptr when they are in‐ voked. int mask (in) OR-ed combination of TCL_READABLE and TCL_WRITABLE to indi‐ cate whether a channel is readable and writable. Tcl_Channel channel (in) The channel to operate on. int direction (in) TCL_READABLE means the input handle is wanted; TCL_WRITABLE means the output han‐ dle is wanted. ClientData *handlePtr (out) Points to the location where the desired OS- specific handle should be stored. int size (in) The size, in bytes, of buffers to allocate in this channel. int mask (in) An OR-ed combination of TCL_READABLE, TCL_WRITABLE and TCL_EXCEPTION that in‐ dicates events that have occurred on this channel. Tcl_Interp *interp (in) Current interpreter. (can be NULL) const char *optionName (in) Name of the invalid option. const char *optionList (in) Specific options list (space separated words, without “-”) to append to the standard generic options list. Can be NULL for generic options error message only. ______________________________________________________________________________ DESCRIPTION Tcl uses a two-layered channel architecture. It provides a generic up‐ per layer to enable C and Tcl programs to perform input and output us‐ ing the same APIs for a variety of files, devices, sockets etc. The generic C APIs are described in the manual entry for Tcl_OpenFileChan‐ nel. The lower layer provides type-specific channel drivers for each type of device supported on each platform. This manual entry describes the C APIs used to communicate between the generic layer and the type-spe‐ cific channel drivers. It also explains how new types of channels can be added by providing new channel drivers. Channel drivers consist of a number of components: First, each channel driver provides a Tcl_ChannelType structure containing pointers to functions implementing the various operations used by the generic layer to communicate with the channel driver. The Tcl_ChannelType structure and the functions referenced by it are described in the section TCL_CHANNELTYPE, below. Second, channel drivers usually provide a Tcl command to create in‐ stances of that type of channel. For example, the Tcl open command cre‐ ates channels that use the file and command channel drivers, and the Tcl socket command creates channels that use TCP sockets for network communication. Third, a channel driver optionally provides a C function to open chan‐ nel instances of that type. For example, Tcl_OpenFileChannel opens a channel that uses the file channel driver, and Tcl_OpenTcpClient opens a channel that uses the TCP network protocol. These creation functions typically use Tcl_CreateChannel internally to open the channel. To add a new type of channel you must implement a C API or a Tcl com‐ mand that opens a channel by invoking Tcl_CreateChannel. When your driver calls Tcl_CreateChannel it passes in a Tcl_ChannelType structure describing the driver's I/O procedures. The generic layer will then invoke the functions referenced in that structure to perform operations on the channel. Tcl_CreateChannel opens a new channel and associates the supplied type‐ Ptr and instanceData with it. The channel is opened in the mode indi‐ cated by mask. For a discussion of channel drivers, their operations and the Tcl_ChannelType structure, see the section TCL_CHANNELTYPE, be‐ low. Tcl_CreateChannel interacts with the code managing the standard chan‐ nels. Once a standard channel was initialized either through a call to Tcl_GetStdChannel or a call to Tcl_SetStdChannel closing this standard channel will cause the next call to Tcl_CreateChannel to make the new channel the new standard channel too. See Tcl_StandardChannels for a general treatise about standard channels and the behavior of the Tcl library with regard to them. Tcl_GetChannelInstanceData returns the instance data associated with the channel in channel. This is the same as the instanceData argument in the call to Tcl_CreateChannel that created this channel. Tcl_GetChannelType returns a pointer to the Tcl_ChannelType structure used by the channel in the channel argument. This is the same as the typePtr argument in the call to Tcl_CreateChannel that created this channel. Tcl_GetChannelName returns a string containing the name associated with the channel, or NULL if the channelName argument to Tcl_CreateChannel was NULL. Tcl_GetChannelHandle places the OS-specific device handle associated with channel for the given direction in the location specified by han‐ dlePtr and returns TCL_OK. If the channel does not have a device han‐ dle for the specified direction, then TCL_ERROR is returned instead. Different channel drivers will return different types of handle. Refer to the manual entries for each driver to determine what type of handle is returned. Tcl_GetChannelThread returns the id of the thread currently managing the specified channel. This allows channel drivers to send their file events to the correct event queue even for a multi-threaded core. Tcl_GetChannelMode returns an OR-ed combination of TCL_READABLE and TCL_WRITABLE, indicating whether the channel is open for input and out‐ put. Tcl_GetChannelBufferSize returns the size, in bytes, of buffers allo‐ cated to store input or output in channel. If the value was not set by a previous call to Tcl_SetChannelBufferSize, described below, then the default value of 4096 is returned. Tcl_SetChannelBufferSize sets the size, in bytes, of buffers that will be allocated in subsequent operations on the channel to store input or output. The size argument should be between one and one million, allow‐ ing buffers of one byte to one million bytes. If size is outside this range, Tcl_SetChannelBufferSize sets the buffer size to 4096. Tcl_NotifyChannel is called by a channel driver to indicate to the generic layer that the events specified by mask have occurred on the channel. Channel drivers are responsible for invoking this function whenever the channel handlers need to be called for the channel (or other pending tasks like a write flush should be performed). See WATCHPROC below for more details. Tcl_BadChannelOption is called from driver specific setOptionProc or getOptionProc to generate a complete error message. Tcl_ChannelBuffered returns the number of bytes of input currently buffered in the internal buffer (push back area) of the channel itself. It does not report about the data in the overall buffers for the stack of channels the supplied channel is part of. Tcl_IsChannelShared checks the refcount of the specified channel and returns whether the channel was shared among multiple interpreters (re‐ sult == 1) or not (result == 0). Tcl_IsChannelRegistered checks whether the specified channel is regis‐ tered in the given interpreter (result == 1) or not (result == 0). Tcl_IsChannelExisting checks whether a channel with the specified name is registered in the (thread)-global list of all channels (result == 1) or not (result == 0). Tcl_CutChannel removes the specified channel from the (thread)global list of all channels (of the current thread). Application to a channel still registered in some interpreter is not allowed. Also notifies the driver if the Tcl_ChannelType version is TCL_CHANNEL_VERSION_4 (or higher), and Tcl_DriverThreadActionProc is defined for it. Tcl_SpliceChannel adds the specified channel to the (thread)global list of all channels (of the current thread). Application to a channel reg‐ istered in some interpreter is not allowed. Also notifies the driver if the Tcl_ChannelType version is TCL_CHANNEL_VERSION_4 (or higher), and Tcl_DriverThreadActionProc is defined for it. Tcl_ClearChannelHandlers removes all channel handlers and event scripts associated with the specified channel, thus shutting down all event processing for this channel. TCL_CHANNELTYPE A channel driver provides a Tcl_ChannelType structure that contains pointers to functions that implement the various operations on a chan‐ nel; these operations are invoked as needed by the generic layer. The structure was versioned starting in Tcl 8.3.2/8.4 to correct a problem with stacked channel drivers. See the OLD CHANNEL TYPES section below for details about the old structure. The Tcl_ChannelType structure contains the following fields: typedef struct Tcl_ChannelType { const char *typeName; Tcl_ChannelTypeVersion version; Tcl_DriverCloseProc *closeProc; Tcl_DriverInputProc *inputProc; Tcl_DriverOutputProc *outputProc; Tcl_DriverSeekProc *seekProc; Tcl_DriverSetOptionProc *setOptionProc; Tcl_DriverGetOptionProc *getOptionProc; Tcl_DriverWatchProc *watchProc; Tcl_DriverGetHandleProc *getHandleProc; Tcl_DriverClose2Proc *close2Proc; Tcl_DriverBlockModeProc *blockModeProc; Tcl_DriverFlushProc *flushProc; Tcl_DriverHandlerProc *handlerProc; Tcl_DriverWideSeekProc *wideSeekProc; Tcl_DriverThreadActionProc *threadActionProc; Tcl_DriverTruncateProc *truncateProc; } Tcl_ChannelType; It is not necessary to provide implementations for all channel opera‐ tions. Those which are not necessary may be set to NULL in the struct: blockModeProc, seekProc, setOptionProc, getOptionProc, getHandleProc, and close2Proc, in addition to flushProc, handlerProc, threadAction‐ Proc, and truncateProc. Other functions that cannot be implemented in a meaningful way should return EINVAL when called, to indicate that the operations they represent are not available. Also note that wideSeekProc can be NULL if seekProc is. The user should only use the above structure for Tcl_ChannelType in‐ stantiation. When referencing fields in a Tcl_ChannelType structure, the following functions should be used to obtain the values: Tcl_Chan‐ nelName, Tcl_ChannelVersion, Tcl_ChannelBlockModeProc, Tcl_Channel‐ CloseProc, Tcl_ChannelClose2Proc, Tcl_ChannelInputProc, Tcl_ChannelOut‐ putProc, Tcl_ChannelSeekProc, Tcl_ChannelWideSeekProc, Tcl_Chan‐ nelThreadActionProc, Tcl_ChannelTruncateProc, Tcl_ChannelSetOptionProc, Tcl_ChannelGetOptionProc, Tcl_ChannelWatchProc, Tcl_ChannelGetH‐ andleProc, Tcl_ChannelFlushProc, or Tcl_ChannelHandlerProc. The change to the structures was made in such a way that standard chan‐ nel types are binary compatible. However, channel types that use stacked channels (i.e. TLS, Trf) have new versions to correspond to the above change since the previous code for stacked channels had problems. TYPENAME The typeName field contains a null-terminated string that identifies the type of the device implemented by this driver, e.g. file or socket. This value can be retrieved with Tcl_ChannelName, which returns a pointer to the string. VERSION The version field should be set to the version of the structure that you require. TCL_CHANNEL_VERSION_2 is the minimum recommended. TCL_CHANNEL_VERSION_3 must be set to specify the wideSeekProc member. TCL_CHANNEL_VERSION_4 must be set to specify the threadActionProc mem‐ ber (includes wideSeekProc). TCL_CHANNEL_VERSION_5 must be set to specify the truncateProc members (includes wideSeekProc and threadAc‐ tionProc). If it is not set to any of these, then this Tcl_ChannelType is assumed to have the original structure. See OLD CHANNEL TYPES for more details. While Tcl will recognize and function with either struc‐ tures, stacked channels must be of at least TCL_CHANNEL_VERSION_2 to function correctly. This value can be retrieved with Tcl_ChannelVersion, which returns one of TCL_CHANNEL_VERSION_5, TCL_CHANNEL_VERSION_4, TCL_CHANNEL_VERSION_3, TCL_CHANNEL_VERSION_2 or TCL_CHANNEL_VERSION_1. BLOCKMODEPROC The blockModeProc field contains the address of a function called by the generic layer to set blocking and nonblocking mode on the device. BlockModeProc should match the following prototype: typedef int Tcl_DriverBlockModeProc( ClientData instanceData, int mode); The instanceData is the same as the value passed to Tcl_CreateChannel when this channel was created. The mode argument is either TCL_MODE_BLOCKING or TCL_MODE_NONBLOCKING to set the device into block‐ ing or nonblocking mode. The function should return zero if the opera‐ tion was successful, or a nonzero POSIX error code if the operation failed. If the operation is successful, the function can modify the supplied instanceData to record that the channel entered blocking or nonblocking mode and to implement the blocking or nonblocking behavior. For some device types, the blocking and nonblocking behavior can be implemented by the underlying operating system; for other device types, the behav‐ ior must be emulated in the channel driver. This value can be retrieved with Tcl_ChannelBlockModeProc, which re‐ turns a pointer to the function. A channel driver not supplying a blockModeProc has to be very, very careful. It has to tell the generic layer exactly which blocking mode is acceptable to it, and should this also document for the user so that the blocking mode of the channel is not changed to an unacceptable value. Any confusion here may lead the interpreter into a (spurious and difficult to find) deadlock. CLOSEPROC AND CLOSE2PROC The closeProc field contains the address of a function called by the generic layer to clean up driver-related information when the channel is closed. CloseProc must match the following prototype: typedef int Tcl_DriverCloseProc( ClientData instanceData, Tcl_Interp *interp); The instanceData argument is the same as the value provided to Tcl_Cre‐ ateChannel when the channel was created. The function should release any storage maintained by the channel driver for this channel, and close the input and output devices encapsulated by this channel. All queued output will have been flushed to the device before this function is called, and no further driver operations will be invoked on this in‐ stance after calling the closeProc. If the close operation is success‐ ful, the procedure should return zero; otherwise it should return a nonzero POSIX error code. In addition, if an error occurs and interp is not NULL, the procedure should store an error message in the inter‐ preter's result. Alternatively, channels that support closing the read and write sides independently may set closeProc to TCL_CLOSE2PROC and set close2Proc to the address of a function that matches the following prototype: typedef int Tcl_DriverClose2Proc( ClientData instanceData, Tcl_Interp *interp, int flags); The close2Proc will be called with flags set to an OR'ed combination of TCL_CLOSE_READ or TCL_CLOSE_WRITE to indicate that the driver should close the read and/or write side of the channel. The channel driver may be invoked to perform additional operations on the channel after close2Proc is called to close one or both sides of the channel. If flags is 0 (zero), the driver should close the channel in the manner described above for closeProc. No further operations will be invoked on this instance after close2Proc is called with all flags cleared. In all cases, the close2Proc function should return zero if the close op‐ eration was successful; otherwise it should return a nonzero POSIX er‐ ror code. In addition, if an error occurs and interp is not NULL, the procedure should store an error message in the interpreter's result. The closeProc and close2Proc values can be retrieved with Tcl_Channel‐ CloseProc or Tcl_ChannelClose2Proc, which return a pointer to the re‐ spective function. INPUTPROC The inputProc field contains the address of a function called by the generic layer to read data from the file or device and store it in an internal buffer. InputProc must match the following prototype: typedef int Tcl_DriverInputProc( ClientData instanceData, char *buf, int bufSize, int *errorCodePtr); InstanceData is the same as the value passed to Tcl_CreateChannel when the channel was created. The buf argument points to an array of bytes in which to store input from the device, and the bufSize argument indi‐ cates how many bytes are available at buf. The errorCodePtr argument points to an integer variable provided by the generic layer. If an error occurs, the function should set the variable to a POSIX error code that identifies the error that occurred. The function should read data from the input device encapsulated by the channel and store it at buf. On success, the function should return a nonnegative integer indicating how many bytes were read from the input device and stored at buf. On error, the function should return -1. If an error occurs after some data has been read from the device, that data is lost. If inputProc can determine that the input device has some data avail‐ able but less than requested by the bufSize argument, the function should only attempt to read as much data as is available and return without blocking. If the input device has no data available whatsoever and the channel is in nonblocking mode, the function should return an EAGAIN error. If the input device has no data available whatsoever and the channel is in blocking mode, the function should block for the shortest possible time until at least one byte of data can be read from the device; then, it should return as much data as it can read without blocking. This value can be retrieved with Tcl_ChannelInputProc, which returns a pointer to the function. OUTPUTPROC The outputProc field contains the address of a function called by the generic layer to transfer data from an internal buffer to the output device. OutputProc must match the following prototype: typedef int Tcl_DriverOutputProc( ClientData instanceData, const char *buf, int toWrite, int *errorCodePtr); InstanceData is the same as the value passed to Tcl_CreateChannel when the channel was created. The buf argument contains an array of bytes to be written to the device, and the toWrite argument indicates how many bytes are to be written from the buf argument. The errorCodePtr argument points to an integer variable provided by the generic layer. If an error occurs, the function should set this vari‐ able to a POSIX error code that identifies the error. The function should write the data at buf to the output device encapsu‐ lated by the channel. On success, the function should return a nonnega‐ tive integer indicating how many bytes were written to the output de‐ vice. The return value is normally the same as toWrite, but may be less in some cases such as if the output operation is interrupted by a signal. If an error occurs the function should return -1. In case of error, some data may have been written to the device. If the channel is nonblocking and the output device is unable to absorb any data whatsoever, the function should return -1 with an EAGAIN error without writing any data. This value can be retrieved with Tcl_ChannelOutputProc, which returns a pointer to the function. SEEKPROC AND WIDESEEKPROC The seekProc field contains the address of a function called by the generic layer to move the access point at which subsequent input or output operations will be applied. SeekProc must match the following prototype: typedef int Tcl_DriverSeekProc( ClientData instanceData, long offset, int seekMode, int *errorCodePtr); The instanceData argument is the same as the value given to Tcl_Create‐ Channel when this channel was created. Offset and seekMode have the same meaning as for the Tcl_Seek procedure (described in the manual en‐ try for Tcl_OpenFileChannel). The errorCodePtr argument points to an integer variable provided by the generic layer for returning errno values from the function. The func‐ tion should set this variable to a POSIX error code if an error occurs. The function should store an EINVAL error code if the channel type does not implement seeking. The return value is the new access point or -1 in case of error. If an error occurred, the function should not move the access point. If there is a non-NULL seekProc field, the wideSeekProc field may con‐ tain the address of an alternative function to use which handles wide (i.e. larger than 32-bit) offsets, so allowing seeks within files larger than 2GB. The wideSeekProc will be called in preference to the seekProc, but both must be defined if the wideSeekProc is defined. WideSeekProc must match the following prototype: typedef Tcl_WideInt Tcl_DriverWideSeekProc( ClientData instanceData, Tcl_WideInt offset, int seekMode, int *errorCodePtr); The arguments and return values mean the same thing as with seekProc above, except that the type of offsets and the return type are differ‐ ent. The seekProc value can be retrieved with Tcl_ChannelSeekProc, which re‐ turns a pointer to the function, and similarly the wideSeekProc can be retrieved with Tcl_ChannelWideSeekProc. SETOPTIONPROC The setOptionProc field contains the address of a function called by the generic layer to set a channel type specific option on a channel. setOptionProc must match the following prototype: typedef int Tcl_DriverSetOptionProc( ClientData instanceData, Tcl_Interp *interp, const char *optionName, const char *newValue); optionName is the name of an option to set, and newValue is the new value for that option, as a string. The instanceData is the same as the value given to Tcl_CreateChannel when this channel was created. The function should do whatever channel type specific action is required to implement the new value of the option. Some options are handled by the generic code and this function is never called to set them, e.g. -blockmode. Other options are specific to each channel type and the setOptionProc procedure of the channel driver will get called to implement them. The setOptionProc field can be NULL, which indicates that this channel type supports no type specific op‐ tions. If the option value is successfully modified to the new value, the function returns TCL_OK. It should call Tcl_BadChannelOption which it‐ self returns TCL_ERROR if the optionName is unrecognized. If newValue specifies a value for the option that is not supported or if a system call error occurs, the function should leave an error message in the result of interp if interp is not NULL. The function should also call Tcl_SetErrno to store an appropriate POSIX error code. This value can be retrieved with Tcl_ChannelSetOptionProc, which re‐ turns a pointer to the function. GETOPTIONPROC The getOptionProc field contains the address of a function called by the generic layer to get the value of a channel type specific option on a channel. getOptionProc must match the following prototype: typedef int Tcl_DriverGetOptionProc( ClientData instanceData, Tcl_Interp *interp, const char *optionName, Tcl_DString *optionValue); OptionName is the name of an option supported by this type of channel. If the option name is not NULL, the function stores its current value, as a string, in the Tcl dynamic string optionValue. If optionName is NULL, the function stores in optionValue an alternating list of all supported options and their current values. On success, the function returns TCL_OK. It should call Tcl_BadChannelOption which itself re‐ turns TCL_ERROR if the optionName is unrecognized. If a system call er‐ ror occurs, the function should leave an error message in the result of interp if interp is not NULL. The function should also call Tcl_SetEr‐ rno to store an appropriate POSIX error code. Some options are handled by the generic code and this function is never called to retrieve their value, e.g. -blockmode. Other options are spe‐ cific to each channel type and the getOptionProc procedure of the chan‐ nel driver will get called to implement them. The getOptionProc field can be NULL, which indicates that this channel type supports no type specific options. This value can be retrieved with Tcl_ChannelGetOptionProc, which re‐ turns a pointer to the function. WATCHPROC The watchProc field contains the address of a function called by the generic layer to initialize the event notification mechanism to notice events of interest on this channel. WatchProc should match the follow‐ ing prototype: typedef void Tcl_DriverWatchProc( ClientData instanceData, int mask); The instanceData is the same as the value passed to Tcl_CreateChannel when this channel was created. The mask argument is an OR-ed combina‐ tion of TCL_READABLE, TCL_WRITABLE and TCL_EXCEPTION; it indicates events the caller is interested in noticing on this channel. The function should initialize device type specific mechanisms to no‐ tice when an event of interest is present on the channel. When one or more of the designated events occurs on the channel, the channel driver is responsible for calling Tcl_NotifyChannel to inform the generic channel module. The driver should take care not to starve other chan‐ nel drivers or sources of callbacks by invoking Tcl_NotifyChannel too frequently. Fairness can be insured by using the Tcl event queue to allow the channel event to be scheduled in sequence with other events. See the description of Tcl_QueueEvent for details on how to queue an event. This value can be retrieved with Tcl_ChannelWatchProc, which returns a pointer to the function. GETHANDLEPROC The getHandleProc field contains the address of a function called by the generic layer to retrieve a device-specific handle from the chan‐ nel. GetHandleProc should match the following prototype: typedef int Tcl_DriverGetHandleProc( ClientData instanceData, int direction, ClientData *handlePtr); InstanceData is the same as the value passed to Tcl_CreateChannel when this channel was created. The direction argument is either TCL_READABLE to retrieve the handle used for input, or TCL_WRITABLE to retrieve the handle used for output. If the channel implementation has device-specific handles, the function should retrieve the appropriate handle associated with the channel, ac‐ cording the direction argument. The handle should be stored in the lo‐ cation referred to by handlePtr, and TCL_OK should be returned. If the channel is not open for the specified direction, or if the channel im‐ plementation does not use device handles, the function should return TCL_ERROR. This value can be retrieved with Tcl_ChannelGetHandleProc, which re‐ turns a pointer to the function. FLUSHPROC The flushProc field is currently reserved for future use. It should be set to NULL. FlushProc should match the following prototype: typedef int Tcl_DriverFlushProc( ClientData instanceData); This value can be retrieved with Tcl_ChannelFlushProc, which returns a pointer to the function. HANDLERPROC The handlerProc field contains the address of a function called by the generic layer to notify the channel that an event occurred. It should be defined for stacked channel drivers that wish to be notified of events that occur on the underlying (stacked) channel. HandlerProc should match the following prototype: typedef int Tcl_DriverHandlerProc( ClientData instanceData, int interestMask); InstanceData is the same as the value passed to Tcl_CreateChannel when this channel was created. The interestMask is an OR-ed combination of TCL_READABLE or TCL_WRITABLE; it indicates what type of event occurred on this channel. This value can be retrieved with Tcl_ChannelHandlerProc, which returns a pointer to the function. THREADACTIONPROC The threadActionProc field contains the address of the function called by the generic layer when a channel is created, closed, or going to move to a different thread, i.e. whenever thread-specific driver state might have to initialized or updated. It can be NULL. The action TCL_CHANNEL_THREAD_REMOVE is used to notify the driver that it should update or remove any thread-specific data it might be maintaining for the channel. The action TCL_CHANNEL_THREAD_INSERT is used to notify the driver that it should update or initialize any thread-specific data it might be maintaining using the calling thread as the associate. See Tcl_CutChan‐ nel and Tcl_SpliceChannel for more detail. typedef void Tcl_DriverThreadActionProc( ClientData instanceData, int action); InstanceData is the same as the value passed to Tcl_CreateChannel when this channel was created. These values can be retrieved with Tcl_ChannelThreadActionProc, which returns a pointer to the function. TRUNCATEPROC The truncateProc field contains the address of the function called by the generic layer when a channel is truncated to some length. It can be NULL. typedef int Tcl_DriverTruncateProc( ClientData instanceData, Tcl_WideInt length); InstanceData is the same as the value passed to Tcl_CreateChannel when this channel was created, and length is the new length of the underly‐ ing file, which should not be negative. The result should be 0 on suc‐ cess or an errno code (suitable for use with Tcl_SetErrno) on failure. These values can be retrieved with Tcl_ChannelTruncateProc, which re‐ turns a pointer to the function. TCL_BADCHANNELOPTION This procedure generates a “bad option” error message in an (optional) interpreter. It is used by channel drivers when an invalid Set/Get op‐ tion is requested. Its purpose is to concatenate the generic options list to the specific ones and factorize the generic options error mes‐ sage string. It always returns TCL_ERROR An error message is generated in interp's result value to indicate that a command was invoked with a bad option. The message has the form bad option "blah": should be one of <...generic options...>+<...specific options...> so you get for instance: bad option "-blah": should be one of -blocking, -buffering, -buffersize, -eofchar, -translation, -peername, or -sockname when called with optionList equal to “peername sockname” “blah” is the optionName argument and “<specific options>” is a space separated list of specific option words. The function takes good care of inserting minus signs before each option, commas after, and an “or” before the last option. OLD CHANNEL TYPES The original (8.3.1 and below) Tcl_ChannelType structure contains the following fields: typedef struct Tcl_ChannelType { const char *typeName; Tcl_DriverBlockModeProc *blockModeProc; Tcl_DriverCloseProc *closeProc; Tcl_DriverInputProc *inputProc; Tcl_DriverOutputProc *outputProc; Tcl_DriverSeekProc *seekProc; Tcl_DriverSetOptionProc *setOptionProc; Tcl_DriverGetOptionProc *getOptionProc; Tcl_DriverWatchProc *watchProc; Tcl_DriverGetHandleProc *getHandleProc; Tcl_DriverClose2Proc *close2Proc; } Tcl_ChannelType; It is still possible to create channel with the above structure. The internal channel code will determine the version. It is imperative to use the new Tcl_ChannelType structure if you are creating a stacked channel driver, due to problems with the earlier stacked channel imple‐ mentation (in 8.2.0 to 8.3.1). Prior to 8.4.0 (i.e. during the later releases of 8.3 and early part of the 8.4 development cycle) the Tcl_ChannelType structure contained the following fields: typedef struct Tcl_ChannelType { const char *typeName; Tcl_ChannelTypeVersion version; Tcl_DriverCloseProc *closeProc; Tcl_DriverInputProc *inputProc; Tcl_DriverOutputProc *outputProc; Tcl_DriverSeekProc *seekProc; Tcl_DriverSetOptionProc *setOptionProc; Tcl_DriverGetOptionProc *getOptionProc; Tcl_DriverWatchProc *watchProc; Tcl_DriverGetHandleProc *getHandleProc; Tcl_DriverClose2Proc *close2Proc; Tcl_DriverBlockModeProc *blockModeProc; Tcl_DriverFlushProc *flushProc; Tcl_DriverHandlerProc *handlerProc; Tcl_DriverTruncateProc *truncateProc; } Tcl_ChannelType; When the above structure is registered as a channel type, the version field should always be TCL_CHANNEL_VERSION_2. SEE ALSO Tcl_Close(3), Tcl_OpenFileChannel(3), Tcl_SetErrno(3), Tcl_QueueEvent(3), Tcl_StackChannel(3), Tcl_GetStdChannel(3) KEYWORDS blocking, channel driver, channel registration, channel type, nonblock‐ ing Tcl 8.4 Tcl_CreateChannel(3)
Tcl_ObjType(3) Tcl Library Procedures Tcl_ObjType(3) ______________________________________________________________________________ NAME Tcl_RegisterObjType, Tcl_GetObjType, Tcl_AppendAllObjTypes, Tcl_Con‐ vertToType - манипулировать типами значений Tcl SYNOPSIS #include <tcl.h> Tcl_RegisterObjType(typePtr) const Tcl_ObjType * Tcl_GetObjType(typeName) int Tcl_AppendAllObjTypes(interp, objPtr) int Tcl_ConvertToType(interp, objPtr, typePtr) ARGUMENTS const Tcl_ObjType *typePtr (in) Указывает на структуру, содержащую информацию о типе значения Tcl. Это хранилище должно существовать всегда, обычно путём статического выделения. const char *typeName (in) Имя типа значения Tcl, которое Tcl_GetObjType должен искать. Tcl_Interp *interp (in) Интерпретатор для отчёта об ошибках. Tcl_Obj *objPtr (in) Для Tcl_AppendAllObjTypes, это указывает на значение, к которому добавляются имена каждого типа значения в качестве элемента списка. Для Tcl_ConvertToType, это указывает на значение, которое должно быть результатом предыдущего вызова Tcl_NewObj. ______________________________________________________________________________ DESCRIPTION Процедуры в этом руководстве управляют типами значений Tcl (иногда называемыми типами объектов или Tcl_ObjTypes по историческим причинам). Они используются для регистрации новых типов значений, поиска типов и принудительной конверсии из одного типа в другой. Tcl_RegisterObjType регистрирует новый тип значения Tcl в таблице всех типов значений, которые Tcl_GetObjType может искать по имени. Существуют и другие поддерживаемые Tcl типы значений, которые Tcl не регистрирует. Расширения могут аналогично решать, регистрировать ли типы значений, которые они создают, или нет. Аргумент typePtr указывает на структуру Tcl_ObjType, которая описывает новый тип, указывая его имя и предоставляя указатели на четыре процедуры, реализующие тип. Если таблица типов уже содержит тип с таким же именем, как в typePtr, он заменяется новым типом. Структура Tcl_ObjType описана в разделе THE TCL_OBJTYPE STRUCTURE ниже. Tcl_GetObjType возвращает указатель на зарегистрированный Tcl_ObjType с именем typeName. Возвращает NULL, если тип с таким именем не зарегистрирован. Tcl_AppendAllObjTypes добавляет имя каждого зарегистрированного типа значения в качестве элемента списка к значению, на которое ссылается objPtr. Возвращаемое значение — TCL_OK, если не было ошибок при конверсии objPtr в значение списка; в противном случае возвращается TCL_ERROR. Tcl_ConvertToType конвертирует значение из одного типа в другой, если это возможно. Он создаёт новое внутреннее представление для objPtr, подходящее для целевого типа typePtr, и устанавливает его член typePtr, вызывая процедуру typePtr->setFromAnyProc. Любое внутреннее представление для старого типа objPtr освобождается. Если во время конверсии возникает ошибка, возвращается TCL_ERROR, и сообщение об ошибке оставляется в значении результата для interp, если interp не равно NULL. В противном случае возвращается TCL_OK. Передача NULL в interp позволяет использовать эту процедуру для проверки, возможна ли конверсия (и была ли она выполнена). В многих случаях процедура typePtr->setFromAnyProc установит objPtr->typePtr на значение аргумента typePtr, но это больше не гарантируется. Процедура setFromAnyProc может установить внутреннее представление для objPtr для использования другого связанного Tcl_ObjType, если сочтёт это подходящим. THE TCL_OBJTYPE STRUCTURE Авторы расширений могут определять новые типы значений, определяя четыре процедуры и инициализируя структуру Tcl_ObjType для описания типа. Авторы расширений также могут передавать указатель на свою структуру Tcl_ObjType в Tcl_RegisterObjType, если они хотят разрешить другим расширениям искать их Tcl_ObjType по имени с помощью процедуры Tcl_GetObjType. Структура Tcl_ObjType определяется следующим образом: typedef struct Tcl_ObjType { const char *name; Tcl_FreeInternalRepProc *freeIntRepProc; Tcl_DupInternalRepProc *dupIntRepProc; Tcl_UpdateStringProc *updateStringProc; Tcl_SetFromAnyProc *setFromAnyProc; } Tcl_ObjType; THE NAME FIELD Член name описывает имя типа, например, int. При регистрации типа это имя используется вызывающими Tcl_GetObjType для поиска типа. Для незарегистрированных типов поле name в основном полезно для отладки. Оставшиеся четыре члена — указатели на процедуры, вызываемые общим кодом значений Tcl: THE SETFROMANYPROC FIELD Член setFromAnyProc содержит адрес функции, вызываемой для создания корректного внутреннего представления из строкового представления значения. typedef int Tcl_SetFromAnyProc( Tcl_Interp *interp, Tcl_Obj *objPtr); Если внутреннее представление не может быть создано из строки, возвращается TCL_ERROR, и сообщение об ошибке помещается в значение результата для interp, если interp не равно NULL. Если setFromAnyProc успешна, она сохраняет новое внутреннее представление, устанавливает член objPtr's typePtr для указания на структуру Tcl_ObjType, соответствующую новому внутреннему представлению, и возвращает TCL_OK. Перед установкой нового внутреннего представления setFromAnyProc должна освободить любое внутреннее представление старого типа objPtr; для этого она вызывает freeIntRepProc старого типа, если оно не равно NULL. Например, setFromAnyProc для встроенного типа списка Tcl получает актуальное строковое представление для objPtr, вызывая Tcl_GetStringFromObj. Он анализирует строку, чтобы убедиться, что она в правильном формате списка и получить каждое значение элемента списка, и, если это удаётся, сохраняет элементы списка во внутреннем представлении objPtr и устанавливает член objPtr's typePtr для указания на структуру Tcl_ObjType типа списка. Не освобождайте старое внутреннее представление objPtr, если не замените его новым или не сбросите член typePtr на NULL. Член setFromAnyProc может быть установлен в NULL, если процедуры, использующие внутреннее представление, не нуждаются в его получении из произвольного строкового значения. Однако, в этом случае, передача указателя на тип в Tcl_ConvertToType приведёт к панике, поэтому, чтобы избежать этой возможности, тип не должен быть зарегистрирован. THE UPDATESTRINGPROC FIELD Член updateStringProc содержит адрес функции, вызываемой для создания корректного строкового представления из внутреннего представления значения. typedef void Tcl_UpdateStringProc( Tcl_Obj *objPtr); Член bytes objPtr всегда равен NULL при вызове. Он должен всегда установить bytes в ненулевое значение перед возвратом. Мы требуем, чтобы байтовый массив строкового представления имел нулевой символ после последнего байта, в смещении length, и не имел нулевых байтов перед этим; это позволяет относиться к строковым представлениям как к обычным строкам C, оканчивающимся нулевым символом. Эти ограничения легко соблюдать, используя внутреннюю кодировку UTF Tcl для строкового представления, как для других процедур Tcl, принимающих строковые значения в качестве аргументов. Хранилище для байтового массива должно быть выделено в куче с помощью Tcl_Alloc или ckalloc. Обратите внимание, что updateStringProcs должны выделить достаточно хранилища для байтов строки и завершающего нулевого байта. Например, updateStringProc для встроенного типа double Tcl вызывает Tcl_PrintDouble для записи в буфер размера TCL_DOUBLE_SPACE, затем выделяет и копирует строковое представление в пространство, достаточное для его хранения. Указатель на выделенное пространство сохраняется в члене bytes. Член updateStringProc может быть установлен в NULL, если процедуры, использующие внутреннее представление, написаны так, что строковое представление никогда не устаревает. Невыполнение этого обязательства приведёт к паникам или сбоям при вызове Tcl_GetStringFromObj или других похожих процедур. THE DUPINTREPPROC FIELD Член dupIntRepProc содержит адрес функции, вызываемой для копирования внутреннего представления из одного значения в другое. typedef void Tcl_DupInternalRepProc( Tcl_Obj *srcPtr, Tcl_Obj *dupPtr); Внутреннее представление dupPtr становится копией внутреннего представления srcPtr. Перед вызовом внутреннее представление srcPtr корректно, а dupPtr — нет. Тип значения srcPtr определяет, что значит копирование его внутреннего представления. Например, dupIntRepProc для типа Tcl integer просто копирует целое число. DupIntRepProc встроенного типа списка использует более сложную схему для максимального совместного использования хранилища. THE FREEINTREPPROC FIELD Член freeIntRepProc содержит адрес функции, которая вызывается при освобождении значения. typedef void Tcl_FreeInternalRepProc( Tcl_Obj *objPtr); Функция freeIntRepProc может освобождать хранилище для внутреннего представления значения и выполнять другую обработку, специфичную для типа, необходимую при освобождении значения. Например, freeIntRepProc типа списка уважает схему совместного использования хранилища, установленную dupIntRepProc, так что освобождает хранилище только при освобождении последнего значения, использующего его. Член freeIntRepProc может быть установлен в NULL, чтобы указать, что внутреннее представление не требует освобождения. Реализация freeIntRepProc не должна обращаться к члену bytes значения, поскольку Tcl использует это поле внутренне во время удаления значения. Определённые задачи для freeIntRepProc не нуждаются в обращении к члену bytes. SEE ALSO Tcl_NewObj(3), Tcl_DecrRefCount(3), Tcl_IncrRefCount(3) KEYWORDS internal representation, value, value type, string representation, type conversion Tcl 8.0 Tcl_ObjType(3)
Tcl_ObjType(3) Tcl Library Procedures Tcl_ObjType(3) ______________________________________________________________________________ NAME Tcl_RegisterObjType, Tcl_GetObjType, Tcl_AppendAllObjTypes, Tcl_Con‐ vertToType - manipulate Tcl value types SYNOPSIS #include <tcl.h> Tcl_RegisterObjType(typePtr) const Tcl_ObjType * Tcl_GetObjType(typeName) int Tcl_AppendAllObjTypes(interp, objPtr) int Tcl_ConvertToType(interp, objPtr, typePtr) ARGUMENTS const Tcl_ObjType *typePtr (in) Points to the structure containing information about the Tcl value type. This storage must live for‐ ever, typically by being statically allocated. const char *typeName (in) The name of a Tcl value type that Tcl_GetObjType should look up. Tcl_Interp *interp (in) Interpreter to use for error report‐ ing. Tcl_Obj *objPtr (in) For Tcl_AppendAllObjTypes, this points to the value onto which it appends the name of each value type as a list element. For Tcl_Convert‐ ToType, this points to a value that must have been the result of a pre‐ vious call to Tcl_NewObj. ______________________________________________________________________________ DESCRIPTION The procedures in this man page manage Tcl value types (sometimes re‐ ferred to as object types or Tcl_ObjTypes for historical reasons). They are used to register new value types, look up types, and force conversions from one type to another. Tcl_RegisterObjType registers a new Tcl value type in the table of all value types that Tcl_GetObjType can look up by name. There are other value types supported by Tcl as well, which Tcl chooses not to regis‐ ter. Extensions can likewise choose to register the value types they create or not. The argument typePtr points to a Tcl_ObjType structure that describes the new type by giving its name and by supplying point‐ ers to four procedures that implement the type. If the type table al‐ ready contains a type with the same name as in typePtr, it is replaced with the new type. The Tcl_ObjType structure is described in the sec‐ tion THE TCL_OBJTYPE STRUCTURE below. Tcl_GetObjType returns a pointer to the registered Tcl_ObjType with name typeName. It returns NULL if no type with that name is regis‐ tered. Tcl_AppendAllObjTypes appends the name of each registered value type as a list element onto the Tcl value referenced by objPtr. The return value is TCL_OK unless there was an error converting objPtr to a list value; in that case TCL_ERROR is returned. Tcl_ConvertToType converts a value from one type to another if possi‐ ble. It creates a new internal representation for objPtr appropriate for the target type typePtr and sets its typePtr member as determined by calling the typePtr->setFromAnyProc routine. Any internal represen‐ tation for objPtr's old type is freed. If an error occurs during con‐ version, it returns TCL_ERROR and leaves an error message in the result value for interp unless interp is NULL. Otherwise, it returns TCL_OK. Passing a NULL interp allows this procedure to be used as a test whether the conversion can be done (and in fact was done). In many cases, the typePtr->setFromAnyProc routine will set ob‐ jPtr->typePtr to the argument value typePtr, but that is no longer guaranteed. The setFromAnyProc is free to set the internal representa‐ tion for objPtr to make use of another related Tcl_ObjType, if it sees fit. THE TCL_OBJTYPE STRUCTURE Extension writers can define new value types by defining four proce‐ dures and initializing a Tcl_ObjType structure to describe the type. Extension writers may also pass a pointer to their Tcl_ObjType struc‐ ture to Tcl_RegisterObjType if they wish to permit other extensions to look up their Tcl_ObjType by name with the Tcl_GetObjType routine. The Tcl_ObjType structure is defined as follows: typedef struct Tcl_ObjType { const char *name; Tcl_FreeInternalRepProc *freeIntRepProc; Tcl_DupInternalRepProc *dupIntRepProc; Tcl_UpdateStringProc *updateStringProc; Tcl_SetFromAnyProc *setFromAnyProc; } Tcl_ObjType; THE NAME FIELD The name member describes the name of the type, e.g. int. When a type is registered, this is the name used by callers of Tcl_GetObjType to lookup the type. For unregistered types, the name field is primarily of value for debugging. The remaining four members are pointers to procedures called by the generic Tcl value code: THE SETFROMANYPROC FIELD The setFromAnyProc member contains the address of a function called to create a valid internal representation from a value's string represen‐ tation. typedef int Tcl_SetFromAnyProc( Tcl_Interp *interp, Tcl_Obj *objPtr); If an internal representation cannot be created from the string, it re‐ turns TCL_ERROR and puts a message describing the error in the result value for interp unless interp is NULL. If setFromAnyProc is success‐ ful, it stores the new internal representation, sets objPtr's typePtr member to point to the Tcl_ObjType struct corresponding to the new in‐ ternal representation, and returns TCL_OK. Before setting the new in‐ ternal representation, the setFromAnyProc must free any internal repre‐ sentation of objPtr's old type; it does this by calling the old type's freeIntRepProc if it is not NULL. As an example, the setFromAnyProc for the built-in Tcl list type gets an up-to-date string representation for objPtr by calling Tcl_Get‐ StringFromObj. It parses the string to verify it is in a valid list format and to obtain each element value in the list, and, if this suc‐ ceeds, stores the list elements in objPtr's internal representation and sets objPtr's typePtr member to point to the list type's Tcl_ObjType structure. Do not release objPtr's old internal representation unless you replace it with a new one or reset the typePtr member to NULL. The setFromAnyProc member may be set to NULL, if the routines making use of the internal representation have no need to derive that internal representation from an arbitrary string value. However, in this case, passing a pointer to the type to Tcl_ConvertToType will lead to a panic, so to avoid this possibility, the type should not be registered. THE UPDATESTRINGPROC FIELD The updateStringProc member contains the address of a function called to create a valid string representation from a value's internal repre‐ sentation. typedef void Tcl_UpdateStringProc( Tcl_Obj *objPtr); objPtr's bytes member is always NULL when it is called. It must always set bytes non-NULL before returning. We require the string representa‐ tion's byte array to have a null after the last byte, at offset length, and to have no null bytes before that; this allows string representa‐ tions to be treated as conventional null character-terminated C strings. These restrictions are easily met by using Tcl's internal UTF encoding for the string representation, same as one would do for other Tcl routines accepting string values as arguments. Storage for the byte array must be allocated in the heap by Tcl_Alloc or ckalloc. Note that updateStringProcs must allocate enough storage for the string's bytes and the terminating null byte. The updateStringProc for Tcl's built-in double type, for example, calls Tcl_PrintDouble to write to a buffer of size TCL_DOUBLE_SPACE, then al‐ locates and copies the string representation to just enough space to hold it. A pointer to the allocated space is stored in the bytes mem‐ ber. The updateStringProc member may be set to NULL, if the routines making use of the internal representation are written so that the string rep‐ resentation is never invalidated. Failure to meet this obligation will lead to panics or crashes when Tcl_GetStringFromObj or other similar routines ask for the string representation. THE DUPINTREPPROC FIELD The dupIntRepProc member contains the address of a function called to copy an internal representation from one value to another. typedef void Tcl_DupInternalRepProc( Tcl_Obj *srcPtr, Tcl_Obj *dupPtr); dupPtr's internal representation is made a copy of srcPtr's internal representation. Before the call, srcPtr's internal representation is valid and dupPtr's is not. srcPtr's value type determines what copying its internal representation means. For example, the dupIntRepProc for the Tcl integer type simply copies an integer. The built-in list type's dupIntRepProc uses a far more so‐ phisticated scheme to continue sharing storage as much as it reasonably can. THE FREEINTREPPROC FIELD The freeIntRepProc member contains the address of a function that is called when a value is freed. typedef void Tcl_FreeInternalRepProc( Tcl_Obj *objPtr); The freeIntRepProc function can deallocate the storage for the value's internal representation and do other type-specific processing necessary when a value is freed. For example, the list type's freeIntRepProc respects the storage shar‐ ing scheme established by the dupIntRepProc so that it only frees stor‐ age when the last value sharing it is being freed. The freeIntRepProc member can be set to NULL to indicate that the in‐ ternal representation does not require freeing. The freeIntRepProc im‐ plementation must not access the bytes member of the value, since Tcl makes its own internal uses of that field during value deletion. The defined tasks for the freeIntRepProc have no need to consult the bytes member. SEE ALSO Tcl_NewObj(3), Tcl_DecrRefCount(3), Tcl_IncrRefCount(3) KEYWORDS internal representation, value, value type, string representation, type conversion Tcl 8.0 Tcl_ObjType(3)
Tcl_SetErrno(3) Процедуры библиотеки Tcl Tcl_SetErrno(3) ______________________________________________________________________________ NAME Tcl_SetErrno, Tcl_GetErrno, Tcl_ErrnoId, Tcl_ErrnoMsg - манипулировать errno для хранения и извлечения кодов ошибок SYNOPSIS #include <tcl.h> void Tcl_SetErrno(errorCode) int Tcl_GetErrno() const char * Tcl_ErrnoId() const char * Tcl_ErrnoMsg(errorCode) ARGUMENTS int errorCode (in) POSIX-код ошибки, такой как ENOENT. ______________________________________________________________________________ DESCRIPTION Tcl_SetErrno и Tcl_GetErrno предоставляют переносимый доступ к перемен‐ ной errno, которая используется для записи кода POSIX-ошибки после сис‐ темных вызовов и других операций, таких как Tcl_Gets. Эти процедуры необходимы, потому что доступ к глобальным переменным не может быть вы‐ полнен через границы модулей на некоторых платформах. Tcl_SetErrno устанавливает переменную errno в значение аргумента erro‐ rCode. Процедуры C, которые хотят возвращать информацию об ошибках сво‐ им вызывающим через errno, должны вызывать Tcl_SetErrno вместо прямой установки errno. Tcl_GetErrno возвращает текущее значение errno. Процедуры, желающие получить доступ к errno, должны вызывать эту процедуру вместо прямого доступа к errno. Tcl_ErrnoId и Tcl_ErrnoMsg возвращают строковые представления значений errno. Tcl_ErrnoId возвращает машиночитаемый текстовый идентификатор, такой как “EACCES”, соответствующий текущему значению errno. Tcl_Er‐ rnoMsg возвращает удобочитаемую строку, такую как “permission denied”, соответствующую значению аргумента errorCode. Аргумент errorCode типич‐ но является значением, возвращенным Tcl_GetErrno. Строки, возвращае‐ мые этими функциями, статически выделены, и вызывающий не должен освобо‐ ждать или изменять их. KEYWORDS errno, error code, глобальные переменные Tcl 8.3 Tcl_SetErrno(3)
Tcl_SetErrno(3) Tcl Library Procedures Tcl_SetErrno(3) ______________________________________________________________________________ NAME Tcl_SetErrno, Tcl_GetErrno, Tcl_ErrnoId, Tcl_ErrnoMsg - manipulate er‐ rno to store and retrieve error codes SYNOPSIS #include <tcl.h> void Tcl_SetErrno(errorCode) int Tcl_GetErrno() const char * Tcl_ErrnoId() const char * Tcl_ErrnoMsg(errorCode) ARGUMENTS int errorCode (in) A POSIX error code such as ENOENT. ______________________________________________________________________________ DESCRIPTION Tcl_SetErrno and Tcl_GetErrno provide portable access to the errno variable, which is used to record a POSIX error code after system calls and other operations such as Tcl_Gets. These procedures are necessary because global variable accesses cannot be made across module bound‐ aries on some platforms. Tcl_SetErrno sets the errno variable to the value of the errorCode ar‐ gument C procedures that wish to return error information to their callers via errno should call Tcl_SetErrno rather than setting errno directly. Tcl_GetErrno returns the current value of errno. Procedures wishing to access errno should call this procedure instead of accessing errno di‐ rectly. Tcl_ErrnoId and Tcl_ErrnoMsg return string representations of errno values. Tcl_ErrnoId returns a machine-readable textual identifier such as “EACCES” that corresponds to the current value of errno. Tcl_Er‐ rnoMsg returns a human-readable string such as “permission denied” that corresponds to the value of its errorCode argument. The errorCode ar‐ gument is typically the value returned by Tcl_GetErrno. The strings returned by these functions are statically allocated and the caller must not free or modify them. KEYWORDS errno, error code, global variables Tcl 8.3 Tcl_SetErrno(3)
Tcl_CreateChannel(3) Процедуры библиотеки Tcl Tcl_CreateChannel(3) ______________________________________________________________________________ NAME Tcl_CreateChannel, Tcl_GetChannelInstanceData, Tcl_GetChannelType, Tcl_GetChannelName, Tcl_GetChannelHandle, Tcl_GetChannelMode, Tcl_GetChannelBufferSize, Tcl_SetChannelBufferSize, Tcl_NotifyChannel, Tcl_BadChannelOption, Tcl_ChannelName, Tcl_ChannelVersion, Tcl_Channel‐ BlockModeProc, Tcl_ChannelCloseProc, Tcl_ChannelClose2Proc, Tcl_Chan‐ nelInputProc, Tcl_ChannelOutputProc, Tcl_ChannelSeekProc, Tcl_Channel‐ WideSeekProc, Tcl_ChannelTruncateProc, Tcl_ChannelSetOptionProc, Tcl_ChannelGetOptionProc, Tcl_ChannelWatchProc, Tcl_ChannelGetH‐ andleProc, Tcl_ChannelFlushProc, Tcl_ChannelHandlerProc, Tcl_Chan‐ nelThreadActionProc, Tcl_IsChannelShared, Tcl_IsChannelRegistered, Tcl_CutChannel, Tcl_SpliceChannel, Tcl_IsChannelExisting, Tcl_ClearChannelHandlers, Tcl_GetChannelThread, Tcl_ChannelBuffered - процедуры для создания и манипулирования каналами SYNOPSIS #include <tcl.h> Tcl_Channel Tcl_CreateChannel(typePtr, channelName, instanceData, mask) ClientData Tcl_GetChannelInstanceData(channel) const Tcl_ChannelType * Tcl_GetChannelType(channel) const char * Tcl_GetChannelName(channel) int Tcl_GetChannelHandle(channel, direction, handlePtr) Tcl_ThreadId Tcl_GetChannelThread(channel) int Tcl_GetChannelMode(channel) int Tcl_GetChannelBufferSize(channel) Tcl_SetChannelBufferSize(channel, size) Tcl_NotifyChannel(channel, mask) int Tcl_BadChannelOption(interp, optionName, optionList) int Tcl_IsChannelShared(channel) int Tcl_IsChannelRegistered(interp, channel) int Tcl_IsChannelExisting(channelName) void Tcl_CutChannel(channel) void Tcl_SpliceChannel(channel) void Tcl_ClearChannelHandlers(channel) int Tcl_ChannelBuffered(channel) const char * Tcl_ChannelName(typePtr) Tcl_ChannelTypeVersion Tcl_ChannelVersion(typePtr) Tcl_DriverBlockModeProc * Tcl_ChannelBlockModeProc(typePtr) Tcl_DriverCloseProc * Tcl_ChannelCloseProc(typePtr) Tcl_DriverClose2Proc * Tcl_ChannelClose2Proc(typePtr) Tcl_DriverInputProc * Tcl_ChannelInputProc(typePtr) Tcl_DriverOutputProc * Tcl_ChannelOutputProc(typePtr) Tcl_DriverSeekProc * Tcl_ChannelSeekProc(typePtr) Tcl_DriverWideSeekProc * Tcl_ChannelWideSeekProc(typePtr) Tcl_DriverThreadActionProc * Tcl_ChannelThreadActionProc(typePtr) Tcl_DriverTruncateProc * Tcl_ChannelTruncateProc(typePtr) Tcl_DriverSetOptionProc * Tcl_ChannelSetOptionProc(typePtr) Tcl_DriverGetOptionProc * Tcl_ChannelGetOptionProc(typePtr) Tcl_DriverWatchProc * Tcl_ChannelWatchProc(typePtr) Tcl_DriverGetHandleProc * Tcl_ChannelGetHandleProc(typePtr) Tcl_DriverFlushProc * Tcl_ChannelFlushProc(typePtr) Tcl_DriverHandlerProc * Tcl_ChannelHandlerProc(typePtr) ARGUMENTS const Tcl_ChannelType *typePtr (in) Указывает на структуру, содержащую адреса процедур, которые могут быть вызваны для выполнения операций ввода-вывода и других функций для канала. const char *channelName (in) Имя этого канала, такое как file3; не должно использоваться другим каналом. Может быть NULL, в этом случае канал создается без имени. Если созданный канал присваивается одному из стандартных каналов (stdin, stdout или stderr), то присвоенное имя канала будет именем стандартного канала. ClientData instanceData (in) Произвольное значение одного слова, связанное с этим каналом. Это значение передается процедурам в typePtr при их вызове. int mask (in) Комбинация через OR из TCL_READABLE и TCL_WRITABLE, указывающая, является ли канал читаемым и/или записываемым. Tcl_Channel channel (in) Канал, на котором выполняется операция. int direction (in) TCL_READABLE означает, что требуется дескриптор ввода; TCL_WRITABLE означает, что требуется дескриптор вывода. ClientData *handlePtr (out) Указывает на место, где должен храниться требуемый специфический для ОС дескриптор. int size (in) Размер, в байтах, буферов, которые будут выделены для этого канала. int mask (in) Комбинация через OR из TCL_READABLE, TCL_WRITABLE и TCL_EXCEPTION, указывающая, какие события произошли на этом канале. Tcl_Interp *interp (in) Текущий интерпретатор. (может быть NULL) const char *optionName (in) Имя недопустимого параметра. const char *optionList (in) Специфический список параметров (слова, разделенные пробелами, без "-"), который должен быть добавлен к стандартному списку общих параметров. Может быть NULL для сообщения об ошибке только общих параметров. ______________________________________________________________________________ DESCRIPTION Tcl использует двухуровневую архитектуру каналов. Она предоставляет общий верхний слой, позволяющий программам на C и Tcl выполнять ввод и вывод с использованием одних и тех же API для различных файлов, устройств, сокетов и т.д. Общие API на C описаны в руководстве по Tcl_OpenFileChannel. Нижний слой предоставляет специфические для типа драйверы каналов для каждого типа поддерживаемых устройств на каждой платформе. Это руководство описывает API на C, используемые для связи между общим слоем и специфическими для типа драйверами каналов. Оно также объясняет, как добавить новые типы каналов, предоставив новые драйверы каналов. Драйверы каналов состоят из нескольких компонентов: Во-первых, каждый драйвер каналов предоставляет структуру Tcl_ChannelType, содержащую указатели на функции, реализующие различные операции, используемые общим слоем для связи с драйвером каналов. Структура Tcl_ChannelType и функции, на которые она ссылается, описаны в разделе TCL_CHANNELTYPE ниже. Во-вторых, драйверы каналов обычно предоставляют команду Tcl для создания экземпляров этого типа канала. Например, команда Tcl open создает каналы, использующие драйверы файлов и команд, а команда Tcl socket создает каналы, использующие TCP-сокеты для сетевой связи. В-третьих, драйвер канала опционально предоставляет функцию C для открытия экземпляров канала этого типа. Например, Tcl_OpenFileChannel открывает канал, использующий драйвер файлов, а Tcl_OpenTcpClient открывает канал, использующий протокол TCP. Эти функции создания обычно используют Tcl_CreateChannel внутренне для открытия канала. Чтобы добавить новый тип канала, вам нужно реализовать API на C или команду Tcl, которая открывает канал, вызывая Tcl_CreateChannel. Когда ваш драйвер вызывает Tcl_CreateChannel, он передает структуру Tcl_ChannelType, описывающую процедуры ввода-вывода драйвера. Общий слой затем вызовет функции, на которые ссылается эта структура, для выполнения операций на канале. Tcl_CreateChannel открывает новый канал и связывает с ним предоставленный typePtr и instanceData. Канал открывается в режиме, указанном в mask. Для обсуждения драйверов каналов, их операций и структуры Tcl_ChannelType см. раздел TCL_CHANNELTYPE ниже. Tcl_CreateChannel взаимодействует с кодом, управляющим стандартными каналами. После инициализации стандартного канала либо через вызов Tcl_GetStdChannel, либо через вызов Tcl_SetStdChannel, закрытие этого стандартного канала приведет к тому, что следующий вызов Tcl_CreateChannel сделает новый канал новым стандартным каналом. См. Tcl_StandardChannels для общего описания стандартных каналов и поведения библиотеки Tcl по отношению к ним. Tcl_GetChannelInstanceData возвращает данные экземпляра, связанные с каналом в channel. Это то же самое, что и аргумент instanceData в вызове Tcl_CreateChannel, который создал этот канал. Tcl_GetChannelType возвращает указатель на структуру Tcl_ChannelType, используемую каналом в аргументе channel. Это то же самое, что и аргумент typePtr в вызове Tcl_CreateChannel, который создал этот канал. Tcl_GetChannelName возвращает строку, содержащую имя, связанное с каналом, или NULL, если аргумент channelName в Tcl_CreateChannel был NULL. Tcl_GetChannelHandle размещает специфический для ОС дескриптор устройства, связанный с каналом для заданного направления, в местоположении, указанном handlePtr, и возвращает TCL_OK. Если канал не имеет дескриптора устройства для указанного направления, возвращается TCL_ERROR. Разные драйверы каналов будут возвращать разные типы дескрипторов. Ссылка на руководства для каждого драйвера для определения типа возвращаемого дескриптора. Tcl_GetChannelThread возвращает идентификатор потока, который в настоящее время управляет указанным каналом. Это позволяет драйверам каналов отправлять свои события файлов в правильную очередь событий даже для многопоточного ядра. Tcl_GetChannelMode возвращает комбинацию через OR из TCL_READABLE и TCL_WRITABLE, указывающую, открыт ли канал для ввода и вывода. Tcl_GetChannelBufferSize возвращает размер, в байтах, буферов, выделенных для хранения ввода или вывода в канале. Если значение не было установлено предыдущим вызовом Tcl_SetChannelBufferSize, описанным ниже, то возвращается значение по умолчанию 4096. Tcl_SetChannelBufferSize устанавливает размер, в байтах, буферов, которые будут выделены в последующих операциях на канале для хранения ввода или вывода. Аргумент size должен быть между одним и одним миллионом, позволяя буферам от одного байта до одного миллиона байтов. Если size находится вне этого диапазона, Tcl_SetChannelBufferSize устанавливает размер буфера в 4096. Tcl_NotifyChannel вызывается драйвером канала, чтобы указать общему слою, что события, указанные в mask, произошли на канале. Драйверы каналов несут ответственность за вызов этой функции всякий раз, когда обработчики каналов должны быть вызваны для канала (или должны быть выполнены другие ожидающие задачи, такие как сброс записи). См. WATCHPROC ниже для получения дополнительных деталей. Tcl_BadChannelOption вызывается из специфической для драйвера setOptionProc или getOptionProc для генерации полного сообщения об ошибке. Tcl_ChannelBuffered возвращает количество байтов ввода, в настоящее время буферизованных во внутреннем буфере (области возврата) самого канала. Он не сообщает о данных в общих буферах для стека каналов, частью которого является поставленный канал. Tcl_IsChannelShared проверяет счетчик ссылок указанного канала и возвращает, разделен ли канал между несколькими интерпретаторами (результат == 1) или нет (результат == 0). Tcl_IsChannelRegistered проверяет, зарегистрирован ли указанный канал в данном интерпретаторе (результат == 1) или нет (результат == 0). Tcl_IsChannelExisting проверяет, существует ли канал с указанным именем в (потоково)-глобальном списке всех каналов (результат == 1) или нет (результат == 0). Tcl_CutChannel удаляет указанный канал из (потоково)-глобального списка всех каналов (текущего потока). Применение к каналу, все еще зарегистрированному в каком-то интерпретаторе, не допускается. Также уведомляет драйвер, если версия Tcl_ChannelType является TCL_CHANNEL_VERSION_4 (или выше), и Tcl_DriverThreadActionProc определен для него. Tcl_SpliceChannel добавляет указанный канал в (потоково)-глобальный список всех каналов (текущего потока). Применение к каналу, зарегистрированному в каком-то интерпретаторе, не допускается. Также уведомляет драйвер, если версия Tcl_ChannelType является TCL_CHANNEL_VERSION_4 (или выше), и Tcl_DriverThreadActionProc определен для него. Tcl_ClearChannelHandlers удаляет все обработчики каналов и скрипты событий, связанные с указанным каналом, тем самым отключая всю обработку событий для этого канала. TCL_CHANNELTYPE Драйвер канала предоставляет структуру Tcl_ChannelType, содержащую указатели на функции, реализующие различные операции на канале; эти операции вызываются по необходимости общим слоем. Структура была версионирована начиная с Tcl 8.3.2/8.4 для исправления проблемы со стековыми драйверами каналов. См. раздел OLD CHANNEL TYPES ниже для деталей о старой структуре. Структура Tcl_ChannelType содержит следующие поля: typedef struct Tcl_ChannelType { const char *typeName; Tcl_ChannelTypeVersion version; Tcl_DriverCloseProc *closeProc; Tcl_DriverInputProc *inputProc; Tcl_DriverOutputProc *outputProc; Tcl_DriverSeekProc *seekProc; Tcl_DriverSetOptionProc *setOptionProc; Tcl_DriverGetOptionProc *getOptionProc; Tcl_DriverWatchProc *watchProc; Tcl_DriverGetHandleProc *getHandleProc; Tcl_DriverClose2Proc *close2Proc; Tcl_DriverBlockModeProc *blockModeProc; Tcl_DriverFlushProc *flushProc; Tcl_DriverHandlerProc *handlerProc; Tcl_DriverWideSeekProc *wideSeekProc; Tcl_DriverThreadActionProc *threadActionProc; Tcl_DriverTruncateProc *truncateProc; } Tcl_ChannelType; Не обязательно предоставлять реализации для всех операций канала. Те, которые не нужны, могут быть установлены в NULL в структуре: blockModeProc, seekProc, setOptionProc, getOptionProc, getHandleProc, и close2Proc, в дополнение к flushProc, handlerProc, threadActionProc и truncateProc. Другие функции, которые не могут быть реализованы осмысленным образом, должны возвращать EINVAL при вызове, чтобы указать, что операции, которые они представляют, недоступны. Также обратите внимание, что wideSeekProc может быть NULL, если seekProc таковым является. Пользователь должен использовать только вышеуказанную структуру для инстанцирования Tcl_ChannelType. При обращении к полям в структуре Tcl_ChannelType следует использовать следующие функции для получения значений: Tcl_ChannelName, Tcl_ChannelVersion, Tcl_ChannelBlockModeProc, Tcl_ChannelCloseProc, Tcl_ChannelClose2Proc, Tcl_ChannelInputProc, Tcl_ChannelOutputProc, Tcl_ChannelSeekProc, Tcl_ChannelWideSeekProc, Tcl_ChannelThreadActionProc, Tcl_ChannelTruncateProc, Tcl_ChannelSetOptionProc, Tcl_ChannelGetOptionProc, Tcl_ChannelWatchProc, Tcl_ChannelGetHandleProc, Tcl_ChannelFlushProc или Tcl_ChannelHandlerProc. Изменение структуры было сделано так, чтобы стандартные типы каналов были бинарно совместимы. Однако, типы каналов, которые используют стековые каналы (т.е. TLS, Trf), имеют новые версии, соответствующие вышеуказанному изменению, поскольку предыдущий код для стековых каналов имел проблемы. TYPENAME Поле typeName содержит нулем завершаемую строку, которая идентифицирует тип устройства, реализованного этим драйвером, например, file или socket. Это значение можно получить с помощью Tcl_ChannelName, которое возвращает указатель на строку. VERSION Поле version должно быть установлено в версию структуры, которую вы требуете. TCL_CHANNEL_VERSION_2 является минимально рекомендуемой. TCL_CHANNEL_VERSION_3 должно быть установлено для указания члена wideSeekProc. TCL_CHANNEL_VERSION_4 должно быть установлено для указания члена threadActionProc (включая wideSeekProc). TCL_CHANNEL_VERSION_5 должно быть установлено для указания членов truncateProc (включая wideSeekProc и threadActionProc). Если оно не установлено ни в одно из этих, то предполагается, что Tcl_ChannelType имеет оригинальную структуру. См. OLD CHANNEL TYPES для получения дополнительных деталей. Хотя Tcl будет распознавать и работать с любой структурой, стековые каналы должны быть как минимум TCL_CHANNEL_VERSION_2, чтобы работать правильно. Это значение можно получить с помощью Tcl_ChannelVersion, которое возвращает одно из TCL_CHANNEL_VERSION_5, TCL_CHANNEL_VERSION_4, TCL_CHANNEL_VERSION_3, TCL_CHANNEL_VERSION_2 или TCL_CHANNEL_VERSION_1. BLOCKMODEPROC Поле blockModeProc содержит адрес функции, вызываемой общим слоем для установки режима блокировки и неблокировки на устройстве. BlockModeProc должна соответствовать следующему прототипу: typedef int Tcl_DriverBlockModeProc( ClientData instanceData, int mode); Аргумент instanceData такой же, как значение, переданное Tcl_CreateChannel при создании этого канала. Аргумент mode является либо TCL_MODE_BLOCKING, либо TCL_MODE_NONBLOCKING для установки устройства в режим блокировки или неблокировки. Функция должна возвращать ноль, если операция прошла успешно, или ненулевой код ошибки POSIX, если операция завершилась неудачей. Если операция успешна, функция может изменить предоставленные instanceData для записи того, что канал вошел в режим блокировки или неблокировки, и для реализации поведения блокировки или неблокировки. Для некоторых типов устройств поведение блокировки и неблокировки может быть реализовано базовой операционной системой; для других типов устройств поведение должно быть эмулировано в драйвере канала. Это значение можно получить с помощью Tcl_ChannelBlockModeProc, которая возвращает указатель на функцию. Драйвер канала, не предоставляющий blockModeProc, должен быть очень, очень осторожным. Он должен точно указывать общему слою, какой режим блокировки приемлем для него, и также документировать это для пользователя, чтобы режим блокировки канала не был изменен на неприемлемое значение. Любая путаница здесь может привести интерпретатор в (ложный и трудно обнаруживаемый) тупик. CLOSEPROC AND CLOSE2PROC Поле closeProc содержит адрес функции, вызываемой общим слоем для очистки информации, связанной с драйвером, при закрытии канала. CloseProc должна соответствовать следующему прототипу: typedef int Tcl_DriverCloseProc( ClientData instanceData, Tcl_Interp *interp); Аргумент instanceData такой же, как значение, предоставленное Tcl_CreateChannel при создании канала. Функция должна освободить любое хранилище, поддерживаемое драйвером канала для этого канала, и закрыть устройства ввода и вывода, инкапсулированные этим каналом. Все очередь вывода будет сброшена в устройство перед вызовом этой функции, и никакие дополнительные операции драйвера не будут вызваны для этого экземпляра после вызова closeProc. Если операция закрытия успешна, процедура должна возвращать ноль; в противном случае она должна возвращать ненулевой код ошибки POSIX. Кроме того, если возникает ошибка и interp не NULL, процедура должна хранить сообщение об ошибке в результате интерпретатора. В качестве альтернативы, каналы, которые поддерживают закрытие сторон чтения и записи независимо, могут установить closeProc в TCL_CLOSE2PROC и установить close2Proc в адрес функции, которая соответствует следующему прототипу: typedef int Tcl_DriverClose2Proc( ClientData instanceData, Tcl_Interp *interp, int flags); Close2Proc будет вызвана с flags, установленным в комбинацию через OR из TCL_CLOSE_READ или TCL_CLOSE_WRITE, чтобы указать, что драйвер должен закрыть сторону чтения и/или записи канала. Драйвер канала может быть вызван для выполнения дополнительных операций на канале после вызова close2Proc для закрытия одной или обеих сторон канала. Если flags равно 0 (нулю), драйвер должен закрыть канал так, как описано выше для closeProc. Ниже никаких операций не будет вызвано для этого экземпляра после вызова close2Proc со всеми флагами, очищенными. Во всех случаях функция close2Proc должна возвращать ноль, если операция закрытия прошла успешно; в противном случае она должна возвращать ненулевой код ошибки POSIX. Кроме того, если возникает ошибка и interp не NULL, процедура должна хранить сообщение об ошибке в результате интерпретатора. Значения closeProc и close2Proc можно получить с помощью Tcl_ChannelCloseProc или Tcl_ChannelClose2Proc, которые возвращают указатель на соответствующую функцию. INPUTPROC Поле inputProc содержит адрес функции, вызываемой общим слоем для чтения данных из файла или устройства и хранения их во внутреннем буфере. InputProc должна соответствовать следующему прототипу: typedef int Tcl_DriverInputProc( ClientData instanceData, char *buf, int bufSize, int *errorCodePtr); InstanceData такой же, как значение, переданное Tcl_CreateChannel при создании канала. Аргумент buf указывает на массив байтов, в котором следует хранить ввод из устройства, а аргумент bufSize указывает, сколько байтов доступно в buf. Аргумент errorCodePtr указывает на переменную целого числа, предоставленную общим слоем. Если возникает ошибка, функция должна установить эту переменную в код ошибки POSIX, который идентифицирует возникшую ошибку. Функция должна читать данные из устройства ввода, инкапсулированного каналом, и хранить их в buf. При успешном выполнении функция должна возвращать неотрицательное целое число, указывающее, сколько байтов было прочитано из устройства ввода и сохранено в buf. При ошибке функция должна возвращать -1. Если ошибка возникает после того, как некоторые данные были прочитаны из устройства, эти данные утеряны. Если inputProc может определить, что устройство ввода имеет некоторые доступные данные, но меньше, чем запрошено аргументом bufSize, функция должна попытаться прочитать только столько данных, сколько доступно, и вернуться без блокировки. Если устройство ввода не имеет доступных данных и канал находится в неблокирующем режиме, функция должна возвращать ошибку EAGAIN. Если устройство ввода не имеет доступных данных и канал находится в блокирующем режиме, функция должна блокировать на самое короткое возможное время, пока не сможет прочитать хотя бы один байт данных из устройства; затем она должна вернуться с таким количеством данных, сколько может прочитать без блокировки. Это значение можно получить с помощью Tcl_ChannelInputProc, которая возвращает указатель на функцию. OUTPUTPROC Поле outputProc содержит адрес функции, вызываемой общим слоем для передачи данных из внутреннего буфера в устройство вывода. OutputProc должна соответствовать следующему прототипу: typedef int Tcl_DriverOutputProc( ClientData instanceData, const char *buf, int toWrite, int *errorCodePtr); InstanceData такой же, как значение, переданное Tcl_CreateChannel при создании канала. Аргумент buf содержит массив байтов, которые должны быть записаны в устройство, а аргумент toWrite указывает, сколько байтов следует записать из buf. Аргумент errorCodePtr указывает на переменную целого числа, предоставленную общим слоем. Если возникает ошибка, функция должна установить эту переменную в код ошибки POSIX, который идентифицирует ошибку. Функция должна записывать данные в buf в устройство вывода, инкапсулированное каналом. При успешном выполнении функция должна возвращать неотрицательное целое число, указывающее, сколько байтов было записано в устройство вывода. Значение возврата обычно такое же, как toWrite, но может быть меньше в некоторых случаях, например, если операция вывода прерывается сигналом. Если возникает ошибка, функция должна возвращать -1. В случае ошибки некоторые данные могли быть записаны в устройство. Если канал неблокирующий и устройство вывода не может поглотить никаких данных, функция должна возвращать -1 с ошибкой EAGAIN, не записывая никаких данных. Это значение можно получить с помощью Tcl_ChannelOutputProc, которая возвращает указатель на функцию. SEEKPROC AND WIDESEEKPROC Поле seekProc содержит адрес функции, вызываемой общим слоем для перемещения точки доступа, к которой будут применены последующие операции ввода или вывода. SeekProc должна соответствовать следующему прототипу: typedef int Tcl_DriverSeekProc( ClientData instanceData, long offset, int seekMode, int *errorCodePtr); Аргумент instanceData такой же, как значение, данное Tcl_CreateChannel при создании этого канала. Offset и seekMode имеют то же значение, что и для процедуры Tcl_Seek (описанной в руководстве по Tcl_OpenFileChannel). Аргумент errorCodePtr указывает на переменную целого числа, предоставленную общим слоем для возврата значений errno из функции. Функция должна установить эту переменную в код ошибки POSIX, если возникает ошибка. Функция должна хранить код ошибки EINVAL, если тип канала не реализует поиск. Возвращаемое значение - это новая точка доступа или -1 в случае ошибки. Если возникла ошибка, функция не должна перемещать точку доступа. Если есть ненулевое поле seekProc, поле wideSeekProc может содержать адрес альтернативной функции для использования, которая обрабатывает широкие (т.е. большие, чем 32-битные) смещения, позволяя искать в файлах больше 2 ГБ. WideSeekProc будет вызвана в предпочтении seekProc, но оба должны быть определены, если wideSeekProc определен. WideSeekProc должна соответствовать следующему прототипу: typedef Tcl_WideInt Tcl_DriverWideSeekProc( ClientData instanceData, Tcl_WideInt offset, int seekMode, int *errorCodePtr); Аргументы и возвращаемые значения имеют то же значение, что и с seekProc выше, за исключением того, что тип смещений и тип возвращаемого значения отличаются. Значение seekProc можно получить с помощью Tcl_ChannelSeekProc, которая возвращает указатель на функцию, и аналогично wideSeekProc можно получить с помощью Tcl_ChannelWideSeekProc. SETOPTIONPROC Поле setOptionProc содержит адрес функции, вызываемой общим слоем для установки параметра, специфичного для типа канала, на канале. SetOptionProc должна соответствовать следующему прототипу: typedef int Tcl_DriverSetOptionProc( ClientData instanceData, Tcl_Interp *interp, const char *optionName, const char *newValue); OptionName - имя параметра для установки, а newValue - новое значение для этого параметра в виде строки. InstanceData такое же, как значение, данное Tcl_CreateChannel при создании этого канала. Функция должна выполнить любые специфичные для типа канала действия, требуемые для реализации нового значения параметра. Некоторые параметры обрабатываются общим кодом, и эта функция никогда не вызывается для их установки, например, -blockmode. Другие параметры специфичны для каждого типа канала, и процедура setOptionProc драйвера канала будет вызвана для их реализации. Поле setOptionProc может быть NULL, что указывает, что этот тип канала не поддерживает специфичные для типа параметры. Если значение параметра успешно изменено на новое значение, функция возвращает TCL_OK. Она должна вызвать Tcl_BadChannelOption, которая сама возвращает TCL_ERROR, если optionName не распознано. Если newValue указывает значение для параметра, которое не поддерживается, или если возникает системная ошибка, функция должна оставить сообщение об ошибке в результате interp, если interp не NULL. Функция также должна вызвать Tcl_SetErrno для хранения подходящего кода ошибки POSIX. Это значение можно получить с помощью Tcl_ChannelSetOptionProc, которая возвращает указатель на функцию. GETOPTIONPROC Поле getOptionProc содержит адрес функции, вызываемой общим слоем для получения значения параметра, специфичного для типа канала, на канале. GetOptionProc должна соответствовать следующему прототипу: typedef int Tcl_DriverGetOptionProc( ClientData instanceData, Tcl_Interp *interp, const char *optionName, Tcl_DString *optionValue); OptionName - имя параметра, поддерживаемого этим типом канала. Если имя параметра не NULL, функция хранит его текущее значение, как строку, в динамической строке Tcl optionValue. Если optionName равно NULL, функция хранит в optionValue чередующийся список всех поддерживаемых параметров и их текущих значений. При успешном выполнении функция возвращает TCL_OK. Она должна вызвать Tcl_BadChannelOption, которая сама возвращает TCL_ERROR, если optionName не распознано. Если возникает системная ошибка, функция должна оставить сообщение об ошибке в результате interp, если interp не NULL. Функция также должна вызвать Tcl_SetErrno для хранения подходящего кода ошибки POSIX. Некоторые параметры обрабатываются общим кодом, и эта функция никогда не вызывается для получения их значения, например, -blockmode. Другие параметры специфичны для каждого типа канала, и процедура getOptionProc драйвера канала будет вызвана для их реализации. Поле getOptionProc может быть NULL, что указывает, что этот тип канала не поддерживает специфичные для типа параметры. Это значение можно получить с помощью Tcl_ChannelGetOptionProc, которая возвращает указатель на функцию. WATCHPROC Поле watchProc содержит адрес функции, вызываемой общим слоем для инициализации механизма уведомления событий для обнаружения событий интереса на этом канале. WatchProc должна соответствовать следующему прототипу: typedef void Tcl_DriverWatchProc( ClientData instanceData, int mask); InstanceData такое же, как значение, переданное Tcl_CreateChannel при создании этого канала. Аргумент mask - комбинация через OR из TCL_READABLE, TCL_WRITABLE и TCL_EXCEPTION; он указывает события, которые вызывающий заинтересован в обнаружении на этом канале. Функция должна инициализировать специфичные для типа устройства механизмы для обнаружения, когда событие интереса присутствует на канале. Когда одно или несколько указанных событий происходит на канале, драйвер канала несет ответственность за вызов Tcl_NotifyChannel для информирования общего модуля канала. Драйвер должен позаботиться о том, чтобы не загружать другие драйверы каналов или источники обратных вызовов, вызывая Tcl_NotifyChannel слишком часто. Честность можно обеспечить, используя очередь событий Tcl для планирования события канала в последовательности с другими событиями. См. описание Tcl_QueueEvent для деталей о том, как поставить событие в очередь. Это значение можно получить с помощью Tcl_ChannelWatchProc, которая возвращает указатель на функцию. GETHANDLEPROC Поле getHandleProc содержит адрес функции, вызываемой общим слоем для получения дескриптора, специфичного для устройства, из канала. GetHandleProc должна соответствовать следующему прототипу: typedef int Tcl_DriverGetHandleProc( ClientData instanceData, int direction, ClientData *handlePtr); InstanceData такое же, как значение, переданное Tcl_CreateChannel при создании этого канала. Аргумент direction - либо TCL_READABLE для получения дескриптора, используемого для ввода, либо TCL_WRITABLE для получения дескриптора, используемого для вывода. Если реализация канала имеет дескрипторы, специфичные для устройства, функция должна получить подходящий дескриптор, связанный с каналом, в соответствии с аргументом direction. Дескриптор должен быть сохранен в местоположении, на которое ссылается handlePtr, и возвращено TCL_OK. Если канал не открыт для указанного направления или если реализация канала не использует дескрипторы устройства, функция должна возвращать TCL_ERROR. Это значение можно получить с помощью Tcl_ChannelGetHandleProc, которая возвращает указатель на функцию. FLUSHPROC Поле flushProc в настоящее время зарезервировано для будущего использования. Оно должно быть установлено в NULL. FlushProc должна соответствовать следующему прототипу: typedef int Tcl_DriverFlushProc( ClientData instanceData); Это значение можно получить с помощью Tcl_ChannelFlushProc, которая возвращает указатель на функцию. HANDLERPROC Поле handlerProc содержит адрес функции, вызываемой общим слоем для уведомления канала о том, что произошло событие. Оно должно быть определено для стековых драйверов каналов, которые хотят быть уведомленными о событиях, происходящих на базовом (стековом) канале. HandlerProc должна соответствовать следующему прототипу: typedef int Tcl_DriverHandlerProc( ClientData instanceData, int interestMask); InstanceData такое же, как значение, переданное Tcl_CreateChannel при создании этого канала. InterestMask - комбинация через OR из TCL_READABLE или TCL_WRITABLE; она указывает, какой тип события произошел на этом канале. Это значение можно получить с помощью Tcl_ChannelHandlerProc, которая возвращает указатель на функцию. THREADACTIONPROC Поле threadActionProc содержит адрес функции, вызываемой общим слоем, когда канал создается, закрывается или собирается перейти в другой поток, т.е. всякий раз, когда специфичное для потока состояние драйвера может потребовать инициализации или обновления. Оно может быть NULL. Действие TCL_CHANNEL_THREAD_REMOVE используется для уведомления драйвера о том, что он должен обновить или удалить любые специфичные для потока данные, которые он может поддерживать для канала. Действие TCL_CHANNEL_THREAD_INSERT используется для уведомления драйвера о том, что он должен обновить или инициализировать любые специфичные для потока данные, которые он может поддерживать, используя вызывающий поток как ассоциированный. См. Tcl_CutChannel и Tcl_SpliceChannel для получения дополнительных деталей. typedef void Tcl_DriverThreadActionProc( ClientData instanceData, int action); InstanceData такое же, как значение, переданное Tcl_CreateChannel при создании этого канала. Эти значения можно получить с помощью Tcl_ChannelThreadActionProc, которая возвращает указатель на функцию. TRUNCATEPROC Поле truncateProc содержит адрес функции, вызываемой общим слоем, когда канал усекается до некоторой длины. Оно может быть NULL. typedef int Tcl_DriverTruncateProc( ClientData instanceData, Tcl_WideInt length); InstanceData такое же, как значение, переданное Tcl_CreateChannel при создании этого канала, а length - новая длина базового файла, которая не должна быть отрицательной. Результат должен быть 0 при успешном выполнении или кодом errno (подходящим для использования с Tcl_SetErrno) при ошибке. Эти значения можно получить с помощью Tcl_ChannelTruncateProc, которая возвращает указатель на функцию. TCL_BADCHANNELOPTION Эта процедура генерирует сообщение об ошибке "плохой параметр" в (опциональном) интерпретаторе. Она используется драйверами каналов, когда запрошен недопустимый параметр Set/Get. Ее цель - объединить список общих параметров со специфическими и факторизовать строку сообщения об ошибке общих параметров. Она всегда возвращает TCL_ERROR Сообщение об ошибке генерируется в значении результата interp, чтобы указать, что команда была вызвана с плохим параметром. Сообщение имеет форму плохой параметр "blah": должен быть одним из <...общие параметры...>+<...специфические параметры...> так что вы получаете, например: плохой параметр "-blah": должен быть одним из -blocking, -buffering, -buffersize, -eofchar, -translation, -peername или -sockname когда вызывается с optionList равным “peername sockname” "blah" - это аргумент optionName, а "<специфические параметры>" - список слов специфических параметров, разделенных пробелами. Функция тщательно вставляет знаки минуса перед каждым параметром, запятые после и "или" перед последним параметром. OLD CHANNEL TYPES Исходная (8.3.1 и ниже) структура Tcl_ChannelType содержит следующие поля: typedef struct Tcl_ChannelType { const char *typeName; Tcl_DriverBlockModeProc *blockModeProc; Tcl_DriverCloseProc *closeProc; Tcl_DriverInputProc *inputProc; Tcl_DriverOutputProc *outputProc; Tcl_DriverSeekProc *seekProc; Tcl_DriverSetOptionProc *setOptionProc; Tcl_DriverGetOptionProc *getOptionProc; Tcl_DriverWatchProc *watchProc; Tcl_DriverGetHandleProc *getHandleProc; Tcl_DriverClose2Proc *close2Proc; } Tcl_ChannelType; Все еще возможно создать канал с вышеуказанной структурой. Внутренний код канала определит версию. Необходимо использовать новую структуру Tcl_ChannelType, если вы создаете стековый драйвер канала, из-за проблем с предыдущей реализацией стековых каналов (в 8.2.0 до 8.3.1). До 8.4.0 (т.е. во время поздних выпусков 8.3 и ранней части цикла разработки 8.4) структура Tcl_ChannelType содержала следующие поля: typedef struct Tcl_ChannelType { const char *typeName; Tcl_ChannelTypeVersion version; Tcl_DriverCloseProc *closeProc; Tcl_DriverInputProc *inputProc; Tcl_DriverOutputProc *outputProc; Tcl_DriverSeekProc *seekProc; Tcl_DriverSetOptionProc *setOptionProc; Tcl_DriverGetOptionProc *getOptionProc; Tcl_DriverWatchProc *watchProc; Tcl_DriverGetHandleProc *getHandleProc; Tcl_DriverClose2Proc *close2Proc; Tcl_DriverBlockModeProc *blockModeProc; Tcl_DriverFlushProc *flushProc; Tcl_DriverHandlerProc *handlerProc; Tcl_DriverTruncateProc *truncateProc; } Tcl_ChannelType; Когда вышеуказанная структура регистрируется как тип канала, поле version всегда должно быть TCL_CHANNEL_VERSION_2. SEE ALSO Tcl_Close(3), Tcl_OpenFileChannel(3), Tcl_SetErrno(3), Tcl_QueueEvent(3), Tcl_StackChannel(3), Tcl_GetStdChannel(3) KEYWORDS blocking, channel driver, channel registration, channel type, nonblocking Tcl 8.4 Tcl_CreateChannel(3)
Tcl_CreateChannel(3) Tcl Library Procedures Tcl_CreateChannel(3) ______________________________________________________________________________ NAME Tcl_CreateChannel, Tcl_GetChannelInstanceData, Tcl_GetChannelType, Tcl_GetChannelName, Tcl_GetChannelHandle, Tcl_GetChannelMode, Tcl_GetChannelBufferSize, Tcl_SetChannelBufferSize, Tcl_NotifyChannel, Tcl_BadChannelOption, Tcl_ChannelName, Tcl_ChannelVersion, Tcl_Channel‐ BlockModeProc, Tcl_ChannelCloseProc, Tcl_ChannelClose2Proc, Tcl_Chan‐ nelInputProc, Tcl_ChannelOutputProc, Tcl_ChannelSeekProc, Tcl_Channel‐ WideSeekProc, Tcl_ChannelTruncateProc, Tcl_ChannelSetOptionProc, Tcl_ChannelGetOptionProc, Tcl_ChannelWatchProc, Tcl_ChannelGetH‐ andleProc, Tcl_ChannelFlushProc, Tcl_ChannelHandlerProc, Tcl_Chan‐ nelThreadActionProc, Tcl_IsChannelShared, Tcl_IsChannelRegistered, Tcl_CutChannel, Tcl_SpliceChannel, Tcl_IsChannelExisting, Tcl_ClearChannelHandlers, Tcl_GetChannelThread, Tcl_ChannelBuffered - procedures for creating and manipulating channels SYNOPSIS #include <tcl.h> Tcl_Channel Tcl_CreateChannel(typePtr, channelName, instanceData, mask) ClientData Tcl_GetChannelInstanceData(channel) const Tcl_ChannelType * Tcl_GetChannelType(channel) const char * Tcl_GetChannelName(channel) int Tcl_GetChannelHandle(channel, direction, handlePtr) Tcl_ThreadId Tcl_GetChannelThread(channel) int Tcl_GetChannelMode(channel) int Tcl_GetChannelBufferSize(channel) Tcl_SetChannelBufferSize(channel, size) Tcl_NotifyChannel(channel, mask) int Tcl_BadChannelOption(interp, optionName, optionList) int Tcl_IsChannelShared(channel) int Tcl_IsChannelRegistered(interp, channel) int Tcl_IsChannelExisting(channelName) void Tcl_CutChannel(channel) void Tcl_SpliceChannel(channel) void Tcl_ClearChannelHandlers(channel) int Tcl_ChannelBuffered(channel) const char * Tcl_ChannelName(typePtr) Tcl_ChannelTypeVersion Tcl_ChannelVersion(typePtr) Tcl_DriverBlockModeProc * Tcl_ChannelBlockModeProc(typePtr) Tcl_DriverCloseProc * Tcl_ChannelCloseProc(typePtr) Tcl_DriverClose2Proc * Tcl_ChannelClose2Proc(typePtr) Tcl_DriverInputProc * Tcl_ChannelInputProc(typePtr) Tcl_DriverOutputProc * Tcl_ChannelOutputProc(typePtr) Tcl_DriverSeekProc * Tcl_ChannelSeekProc(typePtr) Tcl_DriverWideSeekProc * Tcl_ChannelWideSeekProc(typePtr) Tcl_DriverThreadActionProc * Tcl_ChannelThreadActionProc(typePtr) Tcl_DriverTruncateProc * Tcl_ChannelTruncateProc(typePtr) Tcl_DriverSetOptionProc * Tcl_ChannelSetOptionProc(typePtr) Tcl_DriverGetOptionProc * Tcl_ChannelGetOptionProc(typePtr) Tcl_DriverWatchProc * Tcl_ChannelWatchProc(typePtr) Tcl_DriverGetHandleProc * Tcl_ChannelGetHandleProc(typePtr) Tcl_DriverFlushProc * Tcl_ChannelFlushProc(typePtr) Tcl_DriverHandlerProc * Tcl_ChannelHandlerProc(typePtr) ARGUMENTS const Tcl_ChannelType *typePtr (in) Points to a structure containing the ad‐ dresses of procedures that can be called to perform I/O and other functions on the chan‐ nel. const char *channelName (in) The name of this chan‐ nel, such as file3; must not be in use by any other channel. Can be NULL, in which case the channel is created without a name. If the created channel is as‐ signed to one of the standard channels (stdin, stdout or stderr), the assigned channel name will be the name of the stan‐ dard channel. ClientData instanceData (in) Arbitrary one-word value to be associated with this channel. This value is passed to procedures in type‐ Ptr when they are in‐ voked. int mask (in) OR-ed combination of TCL_READABLE and TCL_WRITABLE to indi‐ cate whether a channel is readable and writable. Tcl_Channel channel (in) The channel to operate on. int direction (in) TCL_READABLE means the input handle is wanted; TCL_WRITABLE means the output han‐ dle is wanted. ClientData *handlePtr (out) Points to the location where the desired OS- specific handle should be stored. int size (in) The size, in bytes, of buffers to allocate in this channel. int mask (in) An OR-ed combination of TCL_READABLE, TCL_WRITABLE and TCL_EXCEPTION that in‐ dicates events that have occurred on this channel. Tcl_Interp *interp (in) Current interpreter. (can be NULL) const char *optionName (in) Name of the invalid option. const char *optionList (in) Specific options list (space separated words, without “-”) to append to the standard generic options list. Can be NULL for generic options error message only. ______________________________________________________________________________ DESCRIPTION Tcl uses a two-layered channel architecture. It provides a generic up‐ per layer to enable C and Tcl programs to perform input and output us‐ ing the same APIs for a variety of files, devices, sockets etc. The generic C APIs are described in the manual entry for Tcl_OpenFileChan‐ nel. The lower layer provides type-specific channel drivers for each type of device supported on each platform. This manual entry describes the C APIs used to communicate between the generic layer and the type-spe‐ cific channel drivers. It also explains how new types of channels can be added by providing new channel drivers. Channel drivers consist of a number of components: First, each channel driver provides a Tcl_ChannelType structure containing pointers to functions implementing the various operations used by the generic layer to communicate with the channel driver. The Tcl_ChannelType structure and the functions referenced by it are described in the section TCL_CHANNELTYPE, below. Second, channel drivers usually provide a Tcl command to create in‐ stances of that type of channel. For example, the Tcl open command cre‐ ates channels that use the file and command channel drivers, and the Tcl socket command creates channels that use TCP sockets for network communication. Third, a channel driver optionally provides a C function to open chan‐ nel instances of that type. For example, Tcl_OpenFileChannel opens a channel that uses the file channel driver, and Tcl_OpenTcpClient opens a channel that uses the TCP network protocol. These creation functions typically use Tcl_CreateChannel internally to open the channel. To add a new type of channel you must implement a C API or a Tcl com‐ mand that opens a channel by invoking Tcl_CreateChannel. When your driver calls Tcl_CreateChannel it passes in a Tcl_ChannelType structure describing the driver's I/O procedures. The generic layer will then invoke the functions referenced in that structure to perform operations on the channel. Tcl_CreateChannel opens a new channel and associates the supplied type‐ Ptr and instanceData with it. The channel is opened in the mode indi‐ cated by mask. For a discussion of channel drivers, their operations and the Tcl_ChannelType structure, see the section TCL_CHANNELTYPE, be‐ low. Tcl_CreateChannel interacts with the code managing the standard chan‐ nels. Once a standard channel was initialized either through a call to Tcl_GetStdChannel or a call to Tcl_SetStdChannel closing this standard channel will cause the next call to Tcl_CreateChannel to make the new channel the new standard channel too. See Tcl_StandardChannels for a general treatise about standard channels and the behavior of the Tcl library with regard to them. Tcl_GetChannelInstanceData returns the instance data associated with the channel in channel. This is the same as the instanceData argument in the call to Tcl_CreateChannel that created this channel. Tcl_GetChannelType returns a pointer to the Tcl_ChannelType structure used by the channel in the channel argument. This is the same as the typePtr argument in the call to Tcl_CreateChannel that created this channel. Tcl_GetChannelName returns a string containing the name associated with the channel, or NULL if the channelName argument to Tcl_CreateChannel was NULL. Tcl_GetChannelHandle places the OS-specific device handle associated with channel for the given direction in the location specified by han‐ dlePtr and returns TCL_OK. If the channel does not have a device han‐ dle for the specified direction, then TCL_ERROR is returned instead. Different channel drivers will return different types of handle. Refer to the manual entries for each driver to determine what type of handle is returned. Tcl_GetChannelThread returns the id of the thread currently managing the specified channel. This allows channel drivers to send their file events to the correct event queue even for a multi-threaded core. Tcl_GetChannelMode returns an OR-ed combination of TCL_READABLE and TCL_WRITABLE, indicating whether the channel is open for input and out‐ put. Tcl_GetChannelBufferSize returns the size, in bytes, of buffers allo‐ cated to store input or output in channel. If the value was not set by a previous call to Tcl_SetChannelBufferSize, described below, then the default value of 4096 is returned. Tcl_SetChannelBufferSize sets the size, in bytes, of buffers that will be allocated in subsequent operations on the channel to store input or output. The size argument should be between one and one million, allow‐ ing buffers of one byte to one million bytes. If size is outside this range, Tcl_SetChannelBufferSize sets the buffer size to 4096. Tcl_NotifyChannel is called by a channel driver to indicate to the generic layer that the events specified by mask have occurred on the channel. Channel drivers are responsible for invoking this function whenever the channel handlers need to be called for the channel (or other pending tasks like a write flush should be performed). See WATCHPROC below for more details. Tcl_BadChannelOption is called from driver specific setOptionProc or getOptionProc to generate a complete error message. Tcl_ChannelBuffered returns the number of bytes of input currently buffered in the internal buffer (push back area) of the channel itself. It does not report about the data in the overall buffers for the stack of channels the supplied channel is part of. Tcl_IsChannelShared checks the refcount of the specified channel and returns whether the channel was shared among multiple interpreters (re‐ sult == 1) or not (result == 0). Tcl_IsChannelRegistered checks whether the specified channel is regis‐ tered in the given interpreter (result == 1) or not (result == 0). Tcl_IsChannelExisting checks whether a channel with the specified name is registered in the (thread)-global list of all channels (result == 1) or not (result == 0). Tcl_CutChannel removes the specified channel from the (thread)global list of all channels (of the current thread). Application to a channel still registered in some interpreter is not allowed. Also notifies the driver if the Tcl_ChannelType version is TCL_CHANNEL_VERSION_4 (or higher), and Tcl_DriverThreadActionProc is defined for it. Tcl_SpliceChannel adds the specified channel to the (thread)global list of all channels (of the current thread). Application to a channel reg‐ istered in some interpreter is not allowed. Also notifies the driver if the Tcl_ChannelType version is TCL_CHANNEL_VERSION_4 (or higher), and Tcl_DriverThreadActionProc is defined for it. Tcl_ClearChannelHandlers removes all channel handlers and event scripts associated with the specified channel, thus shutting down all event processing for this channel. TCL_CHANNELTYPE A channel driver provides a Tcl_ChannelType structure that contains pointers to functions that implement the various operations on a chan‐ nel; these operations are invoked as needed by the generic layer. The structure was versioned starting in Tcl 8.3.2/8.4 to correct a problem with stacked channel drivers. See the OLD CHANNEL TYPES section below for details about the old structure. The Tcl_ChannelType structure contains the following fields: typedef struct Tcl_ChannelType { const char *typeName; Tcl_ChannelTypeVersion version; Tcl_DriverCloseProc *closeProc; Tcl_DriverInputProc *inputProc; Tcl_DriverOutputProc *outputProc; Tcl_DriverSeekProc *seekProc; Tcl_DriverSetOptionProc *setOptionProc; Tcl_DriverGetOptionProc *getOptionProc; Tcl_DriverWatchProc *watchProc; Tcl_DriverGetHandleProc *getHandleProc; Tcl_DriverClose2Proc *close2Proc; Tcl_DriverBlockModeProc *blockModeProc; Tcl_DriverFlushProc *flushProc; Tcl_DriverHandlerProc *handlerProc; Tcl_DriverWideSeekProc *wideSeekProc; Tcl_DriverThreadActionProc *threadActionProc; Tcl_DriverTruncateProc *truncateProc; } Tcl_ChannelType; It is not necessary to provide implementations for all channel opera‐ tions. Those which are not necessary may be set to NULL in the struct: blockModeProc, seekProc, setOptionProc, getOptionProc, getHandleProc, and close2Proc, in addition to flushProc, handlerProc, threadAction‐ Proc, and truncateProc. Other functions that cannot be implemented in a meaningful way should return EINVAL when called, to indicate that the operations they represent are not available. Also note that wideSeekProc can be NULL if seekProc is. The user should only use the above structure for Tcl_ChannelType in‐ stantiation. When referencing fields in a Tcl_ChannelType structure, the following functions should be used to obtain the values: Tcl_Chan‐ nelName, Tcl_ChannelVersion, Tcl_ChannelBlockModeProc, Tcl_Channel‐ CloseProc, Tcl_ChannelClose2Proc, Tcl_ChannelInputProc, Tcl_ChannelOut‐ putProc, Tcl_ChannelSeekProc, Tcl_ChannelWideSeekProc, Tcl_Chan‐ nelThreadActionProc, Tcl_ChannelTruncateProc, Tcl_ChannelSetOptionProc, Tcl_ChannelGetOptionProc, Tcl_ChannelWatchProc, Tcl_ChannelGetH‐ andleProc, Tcl_ChannelFlushProc, or Tcl_ChannelHandlerProc. The change to the structures was made in such a way that standard chan‐ nel types are binary compatible. However, channel types that use stacked channels (i.e. TLS, Trf) have new versions to correspond to the above change since the previous code for stacked channels had problems. TYPENAME The typeName field contains a null-terminated string that identifies the type of the device implemented by this driver, e.g. file or socket. This value can be retrieved with Tcl_ChannelName, which returns a pointer to the string. VERSION The version field should be set to the version of the structure that you require. TCL_CHANNEL_VERSION_2 is the minimum recommended. TCL_CHANNEL_VERSION_3 must be set to specify the wideSeekProc member. TCL_CHANNEL_VERSION_4 must be set to specify the threadActionProc mem‐ ber (includes wideSeekProc). TCL_CHANNEL_VERSION_5 must be set to specify the truncateProc members (includes wideSeekProc and threadAc‐ tionProc). If it is not set to any of these, then this Tcl_ChannelType is assumed to have the original structure. See OLD CHANNEL TYPES for more details. While Tcl will recognize and function with either struc‐ tures, stacked channels must be of at least TCL_CHANNEL_VERSION_2 to function correctly. This value can be retrieved with Tcl_ChannelVersion, which returns one of TCL_CHANNEL_VERSION_5, TCL_CHANNEL_VERSION_4, TCL_CHANNEL_VERSION_3, TCL_CHANNEL_VERSION_2 or TCL_CHANNEL_VERSION_1. BLOCKMODEPROC The blockModeProc field contains the address of a function called by the generic layer to set blocking and nonblocking mode on the device. BlockModeProc should match the following prototype: typedef int Tcl_DriverBlockModeProc( ClientData instanceData, int mode); The instanceData is the same as the value passed to Tcl_CreateChannel when this channel was created. The mode argument is either TCL_MODE_BLOCKING or TCL_MODE_NONBLOCKING to set the device into block‐ ing or nonblocking mode. The function should return zero if the opera‐ tion was successful, or a nonzero POSIX error code if the operation failed. If the operation is successful, the function can modify the supplied instanceData to record that the channel entered blocking or nonblocking mode and to implement the blocking or nonblocking behavior. For some device types, the blocking and nonblocking behavior can be implemented by the underlying operating system; for other device types, the behav‐ ior must be emulated in the channel driver. This value can be retrieved with Tcl_ChannelBlockModeProc, which re‐ turns a pointer to the function. A channel driver not supplying a blockModeProc has to be very, very careful. It has to tell the generic layer exactly which blocking mode is acceptable to it, and should this also document for the user so that the blocking mode of the channel is not changed to an unacceptable value. Any confusion here may lead the interpreter into a (spurious and difficult to find) deadlock. CLOSEPROC AND CLOSE2PROC The closeProc field contains the address of a function called by the generic layer to clean up driver-related information when the channel is closed. CloseProc must match the following prototype: typedef int Tcl_DriverCloseProc( ClientData instanceData, Tcl_Interp *interp); The instanceData argument is the same as the value provided to Tcl_Cre‐ ateChannel when the channel was created. The function should release any storage maintained by the channel driver for this channel, and close the input and output devices encapsulated by this channel. All queued output will have been flushed to the device before this function is called, and no further driver operations will be invoked on this in‐ stance after calling the closeProc. If the close operation is success‐ ful, the procedure should return zero; otherwise it should return a nonzero POSIX error code. In addition, if an error occurs and interp is not NULL, the procedure should store an error message in the inter‐ preter's result. Alternatively, channels that support closing the read and write sides independently may set closeProc to TCL_CLOSE2PROC and set close2Proc to the address of a function that matches the following prototype: typedef int Tcl_DriverClose2Proc( ClientData instanceData, Tcl_Interp *interp, int flags); The close2Proc will be called with flags set to an OR'ed combination of TCL_CLOSE_READ or TCL_CLOSE_WRITE to indicate that the driver should close the read and/or write side of the channel. The channel driver may be invoked to perform additional operations on the channel after close2Proc is called to close one or both sides of the channel. If flags is 0 (zero), the driver should close the channel in the manner described above for closeProc. No further operations will be invoked on this instance after close2Proc is called with all flags cleared. In all cases, the close2Proc function should return zero if the close op‐ eration was successful; otherwise it should return a nonzero POSIX er‐ ror code. In addition, if an error occurs and interp is not NULL, the procedure should store an error message in the interpreter's result. The closeProc and close2Proc values can be retrieved with Tcl_Channel‐ CloseProc or Tcl_ChannelClose2Proc, which return a pointer to the re‐ spective function. INPUTPROC The inputProc field contains the address of a function called by the generic layer to read data from the file or device and store it in an internal buffer. InputProc must match the following prototype: typedef int Tcl_DriverInputProc( ClientData instanceData, char *buf, int bufSize, int *errorCodePtr); InstanceData is the same as the value passed to Tcl_CreateChannel when the channel was created. The buf argument points to an array of bytes in which to store input from the device, and the bufSize argument indi‐ cates how many bytes are available at buf. The errorCodePtr argument points to an integer variable provided by the generic layer. If an error occurs, the function should set the variable to a POSIX error code that identifies the error that occurred. The function should read data from the input device encapsulated by the channel and store it at buf. On success, the function should return a nonnegative integer indicating how many bytes were read from the input device and stored at buf. On error, the function should return -1. If an error occurs after some data has been read from the device, that data is lost. If inputProc can determine that the input device has some data avail‐ able but less than requested by the bufSize argument, the function should only attempt to read as much data as is available and return without blocking. If the input device has no data available whatsoever and the channel is in nonblocking mode, the function should return an EAGAIN error. If the input device has no data available whatsoever and the channel is in blocking mode, the function should block for the shortest possible time until at least one byte of data can be read from the device; then, it should return as much data as it can read without blocking. This value can be retrieved with Tcl_ChannelInputProc, which returns a pointer to the function. OUTPUTPROC The outputProc field contains the address of a function called by the generic layer to transfer data from an internal buffer to the output device. OutputProc must match the following prototype: typedef int Tcl_DriverOutputProc( ClientData instanceData, const char *buf, int toWrite, int *errorCodePtr); InstanceData is the same as the value passed to Tcl_CreateChannel when the channel was created. The buf argument contains an array of bytes to be written to the device, and the toWrite argument indicates how many bytes are to be written from the buf argument. The errorCodePtr argument points to an integer variable provided by the generic layer. If an error occurs, the function should set this vari‐ able to a POSIX error code that identifies the error. The function should write the data at buf to the output device encapsu‐ lated by the channel. On success, the function should return a nonnega‐ tive integer indicating how many bytes were written to the output de‐ vice. The return value is normally the same as toWrite, but may be less in some cases such as if the output operation is interrupted by a signal. If an error occurs the function should return -1. In case of error, some data may have been written to the device. If the channel is nonblocking and the output device is unable to absorb any data whatsoever, the function should return -1 with an EAGAIN error without writing any data. This value can be retrieved with Tcl_ChannelOutputProc, which returns a pointer to the function. SEEKPROC AND WIDESEEKPROC The seekProc field contains the address of a function called by the generic layer to move the access point at which subsequent input or output operations will be applied. SeekProc must match the following prototype: typedef int Tcl_DriverSeekProc( ClientData instanceData, long offset, int seekMode, int *errorCodePtr); The instanceData argument is the same as the value given to Tcl_Create‐ Channel when this channel was created. Offset and seekMode have the same meaning as for the Tcl_Seek procedure (described in the manual en‐ try for Tcl_OpenFileChannel). The errorCodePtr argument points to an integer variable provided by the generic layer for returning errno values from the function. The func‐ tion should set this variable to a POSIX error code if an error occurs. The function should store an EINVAL error code if the channel type does not implement seeking. The return value is the new access point or -1 in case of error. If an error occurred, the function should not move the access point. If there is a non-NULL seekProc field, the wideSeekProc field may con‐ tain the address of an alternative function to use which handles wide (i.e. larger than 32-bit) offsets, so allowing seeks within files larger than 2GB. The wideSeekProc will be called in preference to the seekProc, but both must be defined if the wideSeekProc is defined. WideSeekProc must match the following prototype: typedef Tcl_WideInt Tcl_DriverWideSeekProc( ClientData instanceData, Tcl_WideInt offset, int seekMode, int *errorCodePtr); The arguments and return values mean the same thing as with seekProc above, except that the type of offsets and the return type are differ‐ ent. The seekProc value can be retrieved with Tcl_ChannelSeekProc, which re‐ turns a pointer to the function, and similarly the wideSeekProc can be retrieved with Tcl_ChannelWideSeekProc. SETOPTIONPROC The setOptionProc field contains the address of a function called by the generic layer to set a channel type specific option on a channel. setOptionProc must match the following prototype: typedef int Tcl_DriverSetOptionProc( ClientData instanceData, Tcl_Interp *interp, const char *optionName, const char *newValue); optionName is the name of an option to set, and newValue is the new value for that option, as a string. The instanceData is the same as the value given to Tcl_CreateChannel when this channel was created. The function should do whatever channel type specific action is required to implement the new value of the option. Some options are handled by the generic code and this function is never called to set them, e.g. -blockmode. Other options are specific to each channel type and the setOptionProc procedure of the channel driver will get called to implement them. The setOptionProc field can be NULL, which indicates that this channel type supports no type specific op‐ tions. If the option value is successfully modified to the new value, the function returns TCL_OK. It should call Tcl_BadChannelOption which it‐ self returns TCL_ERROR if the optionName is unrecognized. If newValue specifies a value for the option that is not supported or if a system call error occurs, the function should leave an error message in the result of interp if interp is not NULL. The function should also call Tcl_SetErrno to store an appropriate POSIX error code. This value can be retrieved with Tcl_ChannelSetOptionProc, which re‐ turns a pointer to the function. GETOPTIONPROC The getOptionProc field contains the address of a function called by the generic layer to get the value of a channel type specific option on a channel. getOptionProc must match the following prototype: typedef int Tcl_DriverGetOptionProc( ClientData instanceData, Tcl_Interp *interp, const char *optionName, Tcl_DString *optionValue); OptionName is the name of an option supported by this type of channel. If the option name is not NULL, the function stores its current value, as a string, in the Tcl dynamic string optionValue. If optionName is NULL, the function stores in optionValue an alternating list of all supported options and their current values. On success, the function returns TCL_OK. It should call Tcl_BadChannelOption which itself re‐ turns TCL_ERROR if the optionName is unrecognized. If a system call er‐ ror occurs, the function should leave an error message in the result of interp if interp is not NULL. The function should also call Tcl_SetEr‐ rno to store an appropriate POSIX error code. Some options are handled by the generic code and this function is never called to retrieve their value, e.g. -blockmode. Other options are spe‐ cific to each channel type and the getOptionProc procedure of the chan‐ nel driver will get called to implement them. The getOptionProc field can be NULL, which indicates that this channel type supports no type specific options. This value can be retrieved with Tcl_ChannelGetOptionProc, which re‐ turns a pointer to the function. WATCHPROC The watchProc field contains the address of a function called by the generic layer to initialize the event notification mechanism to notice events of interest on this channel. WatchProc should match the follow‐ ing prototype: typedef void Tcl_DriverWatchProc( ClientData instanceData, int mask); The instanceData is the same as the value passed to Tcl_CreateChannel when this channel was created. The mask argument is an OR-ed combina‐ tion of TCL_READABLE, TCL_WRITABLE and TCL_EXCEPTION; it indicates events the caller is interested in noticing on this channel. The function should initialize device type specific mechanisms to no‐ tice when an event of interest is present on the channel. When one or more of the designated events occurs on the channel, the channel driver is responsible for calling Tcl_NotifyChannel to inform the generic channel module. The driver should take care not to starve other chan‐ nel drivers or sources of callbacks by invoking Tcl_NotifyChannel too frequently. Fairness can be insured by using the Tcl event queue to allow the channel event to be scheduled in sequence with other events. See the description of Tcl_QueueEvent for details on how to queue an event. This value can be retrieved with Tcl_ChannelWatchProc, which returns a pointer to the function. GETHANDLEPROC The getHandleProc field contains the address of a function called by the generic layer to retrieve a device-specific handle from the chan‐ nel. GetHandleProc should match the following prototype: typedef int Tcl_DriverGetHandleProc( ClientData instanceData, int direction, ClientData *handlePtr); InstanceData is the same as the value passed to Tcl_CreateChannel when this channel was created. The direction argument is either TCL_READABLE to retrieve the handle used for input, or TCL_WRITABLE to retrieve the handle used for output. If the channel implementation has device-specific handles, the function should retrieve the appropriate handle associated with the channel, ac‐ cording the direction argument. The handle should be stored in the lo‐ cation referred to by handlePtr, and TCL_OK should be returned. If the channel is not open for the specified direction, or if the channel im‐ plementation does not use device handles, the function should return TCL_ERROR. This value can be retrieved with Tcl_ChannelGetHandleProc, which re‐ turns a pointer to the function. FLUSHPROC The flushProc field is currently reserved for future use. It should be set to NULL. FlushProc should match the following prototype: typedef int Tcl_DriverFlushProc( ClientData instanceData); This value can be retrieved with Tcl_ChannelFlushProc, which returns a pointer to the function. HANDLERPROC The handlerProc field contains the address of a function called by the generic layer to notify the channel that an event occurred. It should be defined for stacked channel drivers that wish to be notified of events that occur on the underlying (stacked) channel. HandlerProc should match the following prototype: typedef int Tcl_DriverHandlerProc( ClientData instanceData, int interestMask); InstanceData is the same as the value passed to Tcl_CreateChannel when this channel was created. The interestMask is an OR-ed combination of TCL_READABLE or TCL_WRITABLE; it indicates what type of event occurred on this channel. This value can be retrieved with Tcl_ChannelHandlerProc, which returns a pointer to the function. THREADACTIONPROC The threadActionProc field contains the address of the function called by the generic layer when a channel is created, closed, or going to move to a different thread, i.e. whenever thread-specific driver state might have to initialized or updated. It can be NULL. The action TCL_CHANNEL_THREAD_REMOVE is used to notify the driver that it should update or remove any thread-specific data it might be maintaining for the channel. The action TCL_CHANNEL_THREAD_INSERT is used to notify the driver that it should update or initialize any thread-specific data it might be maintaining using the calling thread as the associate. See Tcl_CutChan‐ nel and Tcl_SpliceChannel for more detail. typedef void Tcl_DriverThreadActionProc( ClientData instanceData, int action); InstanceData is the same as the value passed to Tcl_CreateChannel when this channel was created. These values can be retrieved with Tcl_ChannelThreadActionProc, which returns a pointer to the function. TRUNCATEPROC The truncateProc field contains the address of the function called by the generic layer when a channel is truncated to some length. It can be NULL. typedef int Tcl_DriverTruncateProc( ClientData instanceData, Tcl_WideInt length); InstanceData is the same as the value passed to Tcl_CreateChannel when this channel was created, and length is the new length of the underly‐ ing file, which should not be negative. The result should be 0 on suc‐ cess or an errno code (suitable for use with Tcl_SetErrno) on failure. These values can be retrieved with Tcl_ChannelTruncateProc, which re‐ turns a pointer to the function. TCL_BADCHANNELOPTION This procedure generates a “bad option” error message in an (optional) interpreter. It is used by channel drivers when an invalid Set/Get op‐ tion is requested. Its purpose is to concatenate the generic options list to the specific ones and factorize the generic options error mes‐ sage string. It always returns TCL_ERROR An error message is generated in interp's result value to indicate that a command was invoked with a bad option. The message has the form bad option "blah": should be one of <...generic options...>+<...specific options...> so you get for instance: bad option "-blah": should be one of -blocking, -buffering, -buffersize, -eofchar, -translation, -peername, or -sockname when called with optionList equal to “peername sockname” “blah” is the optionName argument and “<specific options>” is a space separated list of specific option words. The function takes good care of inserting minus signs before each option, commas after, and an “or” before the last option. OLD CHANNEL TYPES The original (8.3.1 and below) Tcl_ChannelType structure contains the following fields: typedef struct Tcl_ChannelType { const char *typeName; Tcl_DriverBlockModeProc *blockModeProc; Tcl_DriverCloseProc *closeProc; Tcl_DriverInputProc *inputProc; Tcl_DriverOutputProc *outputProc; Tcl_DriverSeekProc *seekProc; Tcl_DriverSetOptionProc *setOptionProc; Tcl_DriverGetOptionProc *getOptionProc; Tcl_DriverWatchProc *watchProc; Tcl_DriverGetHandleProc *getHandleProc; Tcl_DriverClose2Proc *close2Proc; } Tcl_ChannelType; It is still possible to create channel with the above structure. The internal channel code will determine the version. It is imperative to use the new Tcl_ChannelType structure if you are creating a stacked channel driver, due to problems with the earlier stacked channel imple‐ mentation (in 8.2.0 to 8.3.1). Prior to 8.4.0 (i.e. during the later releases of 8.3 and early part of the 8.4 development cycle) the Tcl_ChannelType structure contained the following fields: typedef struct Tcl_ChannelType { const char *typeName; Tcl_ChannelTypeVersion version; Tcl_DriverCloseProc *closeProc; Tcl_DriverInputProc *inputProc; Tcl_DriverOutputProc *outputProc; Tcl_DriverSeekProc *seekProc; Tcl_DriverSetOptionProc *setOptionProc; Tcl_DriverGetOptionProc *getOptionProc; Tcl_DriverWatchProc *watchProc; Tcl_DriverGetHandleProc *getHandleProc; Tcl_DriverClose2Proc *close2Proc; Tcl_DriverBlockModeProc *blockModeProc; Tcl_DriverFlushProc *flushProc; Tcl_DriverHandlerProc *handlerProc; Tcl_DriverTruncateProc *truncateProc; } Tcl_ChannelType; When the above structure is registered as a channel type, the version field should always be TCL_CHANNEL_VERSION_2. SEE ALSO Tcl_Close(3), Tcl_OpenFileChannel(3), Tcl_SetErrno(3), Tcl_QueueEvent(3), Tcl_StackChannel(3), Tcl_GetStdChannel(3) KEYWORDS blocking, channel driver, channel registration, channel type, nonblock‐ ing Tcl 8.4 Tcl_CreateChannel(3)
Tcl_TraceCommand(3) Процедуры библиотеки Tcl Tcl_TraceCommand(3) ______________________________________________________________________________ NAME Tcl_CommandTraceInfo, Tcl_TraceCommand, Tcl_UntraceCommand - мониторинг переименований и удалений команды SYNOPSIS #include <tcl.h> ClientData Tcl_CommandTraceInfo(interp, cmdName, flags, proc, prevClientData) int Tcl_TraceCommand(interp, cmdName, flags, proc, clientData) void Tcl_UntraceCommand(interp, cmdName, flags, proc, clientData) ARGUMENTS Tcl_Interp *interp (in) Интерпретатор, содержащий команду. const char *cmdName (in) Имя команды. int flags (in) Сочетание значений, объединенных побитовым ИЛИ, TCL_TRACE_RENAME и TCL_TRACE_DELETE. Tcl_CommandTraceProc *proc (in) Процедура, которую нужно вызвать, когда указанные операции происходят с cmdName. ClientData clientData (in) Произвольный аргумент для передачи в proc. ClientData prevClientData (in) Если не NULL, содержит последнее значение, возвращенное Tcl_CommandTraceInfo, поэтому этот вызов вернет информацию о следующей трассировке. Если NULL, этот вызов вернет информацию о первой трассировке. ______________________________________________________________________________ DESCRIPTION Tcl_TraceCommand позволяет процедуре на языке C мониторить операции, выполняемые над командой Tcl, так что процедура C вызывается всякий раз, когда команда переименовывается или удаляется. Если трассировка создана успешно, Tcl_TraceCommand возвращает TCL_OK. Если произошла ошибка (например, cmdName указывает на несуществующую команду), то возвращается TCL_ERROR, и сообщение об ошибке оставляется в результате интерпретатора. Аргумент flags в Tcl_TraceCommand указывает, когда должна вызываться процедура трассировки. Он состоит из сочетания значений, объединенных побитовым ИЛИ, из следующих: TCL_TRACE_RENAME Вызывать proc всякий раз, когда команда переименовывается. TCL_TRACE_DELETE Вызывать proc, когда команда удаляется. Всякий раз, когда одна из указанных операций происходит с командой, proc будет вызвана. Она должна иметь аргументы и результат, соответствующие типу Tcl_CommandTraceProc: typedef void Tcl_CommandTraceProc( ClientData clientData, Tcl_Interp *interp, const char *oldName, const char *newName, int flags); Параметры clientData и interp будут иметь те же значения, что и те, которые были переданы в Tcl_TraceCommand при создании трассировки. ClientData обычно указывает на структуру данных, специфичную для приложения, которая описывает, что делать при вызове proc. OldName дает имя команды, которая переименовывается, а newName дает имя, в которое команда переименовывается (или NULL, когда команда удаляется). Flags является сочетанием битов, потенциально предоставляющим несколько частей информации. Один из битов TCL_TRACE_RENAME или TCL_TRACE_DELETE будет установлен в flags, чтобы указать, какая операция выполняется над командой. Бит TCL_TRACE_DESTROYED будет установлен в flags, если трассировка 即将 будет уничтожена; эта информация может быть полезной для proc, чтобы она могла очистить свои собственные внутренние структуры данных (см. раздел TCL_TRACE_DESTROYED ниже для получения дополнительных деталей). Поскольку удаление команд может происходить в процессе удаления интерпретатора, который их содержит, proc должна быть осторожной при проверке того, что переданный interp может быть использован. Функция Tcl_InterpDeleted является важным инструментом для этого. Когда Tcl_InterpDeleted возвращает 1, proc не сможет вызвать никакие скрипты в interp. Функция proc в этой ситуации ограничена очисткой своих собственных структур данных. Tcl_UntraceCommand может использоваться для удаления трассировки. Если команда, указанная интерпретатором interp, cmdName и flags, имеет трассировку, установленную с flags, proc и clientData, то соответствующая трассировка удаляется. Если такой трассировки не существует, вызов Tcl_UntraceCommand не оказывает эффекта. Для flags допустимы те же биты, что и для вызовов Tcl_TraceCommand. Tcl_CommandTraceInfo может использоваться для получения информации о трассировках, установленных на данной команде. Возвращаемое значение от Tcl_CommandTraceInfo является clientData, связанным с определенной трассировкой. Трассировка должна быть на команде, указанной аргументами interp, cmdName и flags (обратите внимание, что в настоящее время flags игнорируются; flags следует установить в 0 для обеспечения будущей совместимости), и ее процедура трассировки должна быть той же, что и proc. Если аргумент prevClientData равен NULL, то возвращаемое значение соответствует первой (самой недавно созданной) подходящей трассировке или NULL, если подходящих трассировок нет. Если prevClientData не равен NULL, то он должен быть значением, возвращенным из предыдущего вызова Tcl_CommandTraceInfo. В этом случае новое возвращаемое значение будет соответствовать следующей подходящей трассировке после той, чей clientData совпадает с prevClientData, или NULL, если трассировка, совпадающая с prevClientData, не найдена или если больше нет подходящих трассировок. Этот механизм позволяет последовательно просматривать все трассировки для данной команды, имеющие одинаковую proc. CALLING COMMANDS DURING TRACES Во время трассировок переименования команда, которая переименовывается, видна одновременно под обоими именами, и команда все еще существует во время трассировок удаления, если интерпретатор, содержащий ее, не удаляется. Однако, нет механизма для сигнализации об ошибке, произошедшей в процедуре трассировки, поэтому нужно быть очень осторожным, чтобы ошибки не потерялись бесследно. MULTIPLE TRACES Возможна ситуация, когда несколько трассировок существует на одной и той же команде. В этом случае все процедуры трассировок будут вызваны при каждом доступе, в порядке от самой недавно созданной до наименее недавно созданной. Попытки удалить команду во время трассировки удаления не удатся бесшумно, поскольку команда уже запланирована на удаление. Если команда, которая переименовывается, переименовывается одной из своих трассировок переименования, это переименование имеет приоритет над тем, которое вызвало трассировку, и коллекция трассировок не будет перевыполнена; если несколько трассировок переименовывают команду, последнее переименование имеет приоритет. TCL_TRACE_DESTROYED FLAG В обратном вызове удаления для proc бит TCL_TRACE_DESTROYED установлен в flags. KEYWORDS clientData, trace, command Tcl 7.4 Tcl_TraceCommand(3)
Tcl_TraceCommand(3) Tcl Library Procedures Tcl_TraceCommand(3) ______________________________________________________________________________ NAME Tcl_CommandTraceInfo, Tcl_TraceCommand, Tcl_UntraceCommand - monitor renames and deletes of a command SYNOPSIS #include <tcl.h> ClientData Tcl_CommandTraceInfo(interp, cmdName, flags, proc, prevClientData) int Tcl_TraceCommand(interp, cmdName, flags, proc, clientData) void Tcl_UntraceCommand(interp, cmdName, flags, proc, clientData) ARGUMENTS Tcl_Interp *interp (in) Interpreter contain‐ ing the command. const char *cmdName (in) Name of command. int flags (in) OR'ed collection of the values TCL_TRACE_RENAME and TCL_TRACE_DELETE. Tcl_CommandTraceProc *proc (in) Procedure to call when specified opera‐ tions occur to cmd‐ Name. ClientData clientData (in) Arbitrary argument to pass to proc. ClientData prevClientData (in) If non-NULL, gives last value returned by Tcl_CommandTrace‐ Info, so this call will return informa‐ tion about next trace. If NULL, this call will return in‐ formation about first trace. ______________________________________________________________________________ DESCRIPTION Tcl_TraceCommand allows a C procedure to monitor operations performed on a Tcl command, so that the C procedure is invoked whenever the com‐ mand is renamed or deleted. If the trace is created successfully then Tcl_TraceCommand returns TCL_OK. If an error occurred (e.g. cmdName specifies a non-existent command) then TCL_ERROR is returned and an er‐ ror message is left in the interpreter's result. The flags argument to Tcl_TraceCommand indicates when the trace proce‐ dure is to be invoked. It consists of an OR'ed combination of any of the following values: TCL_TRACE_RENAME Invoke proc whenever the command is renamed. TCL_TRACE_DELETE Invoke proc when the command is deleted. Whenever one of the specified operations occurs to the command, proc will be invoked. It should have arguments and result that match the type Tcl_CommandTraceProc: typedef void Tcl_CommandTraceProc( ClientData clientData, Tcl_Interp *interp, const char *oldName, const char *newName, int flags); The clientData and interp parameters will have the same values as those passed to Tcl_TraceCommand when the trace was created. ClientData typ‐ ically points to an application-specific data structure that describes what to do when proc is invoked. OldName gives the name of the command being renamed, and newName gives the name that the command is being re‐ named to (or NULL when the command is being deleted.) Flags is an OR'ed combination of bits potentially providing several pieces of in‐ formation. One of the bits TCL_TRACE_RENAME and TCL_TRACE_DELETE will be set in flags to indicate which operation is being performed on the command. The bit TCL_TRACE_DESTROYED will be set in flags if the trace is about to be destroyed; this information may be useful to proc so that it can clean up its own internal data structures (see the section TCL_TRACE_DESTROYED below for more details). Because the deletion of commands can take place as part of the deletion of the interp that con‐ tains them, proc must be careful about checking what the passed in in‐ terp value can be called upon to do. The routine Tcl_InterpDeleted is an important tool for this. When Tcl_InterpDeleted returns 1, proc will not be able to invoke any scripts in interp. The function of proc in that circumstance is limited to the cleanup of its own data struc‐ tures. Tcl_UntraceCommand may be used to remove a trace. If the command spec‐ ified by interp, cmdName, and flags has a trace set with flags, proc, and clientData, then the corresponding trace is removed. If no such trace exists, then the call to Tcl_UntraceCommand has no effect. The same bits are valid for flags as for calls to Tcl_TraceCommand. Tcl_CommandTraceInfo may be used to retrieve information about traces set on a given command. The return value from Tcl_CommandTraceInfo is the clientData associated with a particular trace. The trace must be on the command specified by the interp, cmdName, and flags arguments (note that currently the flags are ignored; flags should be set to 0 for future compatibility) and its trace procedure must the same as the proc argument. If the prevClientData argument is NULL then the return value corresponds to the first (most recently created) matching trace, or NULL if there are no matching traces. If the prevClientData argu‐ ment is not NULL, then it should be the return value from a previous call to Tcl_CommandTraceInfo. In this case, the new return value will correspond to the next matching trace after the one whose clientData matches prevClientData, or NULL if no trace matches prevClientData or if there are no more matching traces after it. This mechanism makes it possible to step through all of the traces for a given command that have the same proc. CALLING COMMANDS DURING TRACES During rename traces, the command being renamed is visible with both names simultaneously, and the command still exists during delete traces, unless the interp that contains it is being deleted. However, there is no mechanism for signaling that an error occurred in a trace procedure, so great care should be taken that errors do not get silently lost. MULTIPLE TRACES It is possible for multiple traces to exist on the same command. When this happens, all of the trace procedures will be invoked on each ac‐ cess, in order from most-recently-created to least-recently-created. Attempts to delete the command during a delete trace will fail silently, since the command is already scheduled for deletion anyway. If the command being renamed is renamed by one of its rename traces, that renaming takes precedence over the one that triggered the trace and the collection of traces will not be reexecuted; if several traces rename the command, the last renaming takes precedence. TCL_TRACE_DESTROYED FLAG In a delete callback to proc, the TCL_TRACE_DESTROYED bit is set in flags. KEYWORDS clientData, trace, command Tcl 7.4 Tcl_TraceCommand(3)
Threads(3) Процедуры библиотеки Tcl Threads(3) ______________________________________________________________________________ ИМЯ Tcl_ConditionNotify, Tcl_ConditionWait, Tcl_ConditionFinalize, Tcl_Get‐ ThreadData, Tcl_MutexLock, Tcl_MutexUnlock, Tcl_MutexFinalize, Tcl_Cre‐ ateThread, Tcl_JoinThread - Поддержка потоков Tcl СИНОПСИС #include <tcl.h> void Tcl_ConditionNotify(condPtr) void Tcl_ConditionWait(condPtr, mutexPtr, timePtr) void Tcl_ConditionFinalize(condPtr) Void * Tcl_GetThreadData(keyPtr, size) void Tcl_MutexLock(mutexPtr) void Tcl_MutexUnlock(mutexPtr) void Tcl_MutexFinalize(mutexPtr) int Tcl_CreateThread(idPtr, proc, clientData, stackSize, flags) int Tcl_JoinThread(id, result) АРГУМЕНТЫ Tcl_Condition *condPtr (in) Условная переменная, которая должна быть связана с мьютексом. Tcl_Mutex *mutexPtr (in) Мьютекс. const Tcl_Time *timePtr (in) Ограничение по времени для ожидания условия. NULL для ожидания навсегда. Обратите внимание, что значение опроса 0 секунд не имеет особого смысла. Tcl_ThreadDataKey *keyPtr (in) Это идентифицирует блок локального хранения потока. Ключ должен быть статическим и общим для всего процесса, но каждый поток будет связывать с этим ключом разный блок хранения. int *size (in) Размер блока локального хранения потока. Это количество данных выделяется и инициализируется нулями в первый раз, когда каждый поток вызывает Tcl_Get‐ ThreadData. Tcl_ThreadId *idPtr (out) Указанный хранение будет содержать идентификатор newly созданного потока, возвращаемый операционной системой. Tcl_ThreadId id (in) Идентификатор потока, для которого ожидается. Tcl_ThreadCreateProc *proc (in) Эта процедура будет действовать как main() newly созданного потока. Указанный client‐ Data будет его единственным аргументом. ClientData clientData (in) Произвольная информация. Передается как единственный аргумент для proc. int stackSize (in) Размер стека, выделенного для нового потока. int flags (in) Битовая маска, содержащая флаги, позволяющие вызывающему изменить поведение нового потока. int *result (out) Указанное хранение используется для размещения кода выхода потока, для которого ожидается. ______________________________________________________________________________ ВВЕДЕНИЕ Начиная с выпуска 8.1, ядро Tcl является потокобезопасным, что позволяет интегрировать Tcl в многопоточные приложения без настройки ядра Tcl. Начиная с выпуска 8.6, поддержка многопоточности Tcl включена по умолчанию. Чтобы отключить поддержку многопоточности Tcl, вы должны включить опцию --disable-threads в configure при настройке и компиляции ядра Tcl. Важным ограничением реализации потоков Tcl является то, что только поток, который создал интерпретатор Tcl, может использовать этот интерпретатор. Другими словами, несколько потоков не могут обращаться к одному и тому же интерпретатору Tcl. (Однако, один поток может безопасно создавать и использовать несколько интер‐ претаторов.) ОПИСАНИЕ Tcl предоставляет Tcl_CreateThread для создания потоков. Вызывающий может опре‐ делить размер стека, выделенного для нового потока, и изменить поведение с помощью предоставленных флагов. Значение TCL_THREAD_STACK_DEFAULT для stackSize указывает, что должен использоваться размер по умолчанию, указанный операционной системой, для нового потока. Что касается флагов, в настоящее время определены только значения TCL_THREAD_NOFLAGS и TCL_THREAD_JOINABLE. Первое из них вызывает поведение по умолчанию без специальных настроек. Использование второго значения отмечает новый поток как присоединяемый. Это означает, что другой поток может ждать, пока такой отмеченный поток не завершится и присоединится к нему. Ограничения: На некоторых UNIX-системах библиотека pthread не содержит функциональности для указания размера стека потока. Указанное значение для размера стека игнорируется на этих системах. Windows в настоящее время не поддерживает присоединяемые потоки. Это значение флага поэтому игнорируется на этой платформе. Tcl предоставляет функции Tcl_ExitThread и Tcl_FinalizeThread для завершения потоков и вызова необязательных обработчиков выхода на поток. См. страницу Tcl_Exit для получения дополнительной информации о этих процедурах. Функция Tcl_JoinThread предоставляется для того, чтобы потоки могли ждать выхода другого потока, который должен быть отмечен как присоединяемый с помощью флага TCL_THREAD_JOINABLE во время его создания через Tcl_CreateThread. Попытка дождаться выхода непоединяемого потока или потока, который уже ожидается, приведет к ошибке. Ожидание присоединяемого потока, который уже завершился, возможно, система сохранит необходимую информацию до вызова Tcl_JoinThread. Это означает, что невызов Tcl_JoinThread для присоединяемого потока приведет к утечке памяти. Вызов Tcl_GetThreadData возвращает указатель на блок потоко‐ частных данных. Его аргументами являются ключ, который общий для всех потоков, и размер для блока хранения. Хранение автоматически выделяется и инициализируется нулями в первый раз, когда каждый поток запрашивает его. Хранение автоматически освобождается Tcl_FinalizeThread. СИНХРОНИЗАЦИЯ И ОБЩЕНИЕ Tcl предоставляет Tcl_ThreadQueueEvent и Tcl_ThreadAlert для обработки очереди событий в многопоточных приложениях. См. страницу Notifier для получения дополнительной информации о этих процедурах. Мьютекс - это блокировка, которая используется для последовательной обработки всех потоков через кусок кода с помощью вызова Tcl_MutexLock и Tcl_MutexUnlock. Если один поток удерживает мьютекс, любой другой поток, вызывающий Tcl_MutexLock, заблокируется, пока не будет вызван Tcl_MutexUnlock. Мьютекс может быть уничтожен после его использования с помощью вызова Tcl_MutexFinalize. Результат блокировки мьютекса дважды из одного и того же потока не определен. На некоторых платформах это приведет к взаимной блокировке. Процедуры Tcl_MutexLock, Tcl_MutexUnlock и Tcl_MutexFinalize определяются как пустые макросы, если не компилируется с включенными потоками. Для объявления мьютексов должна использоваться макрос TCL_DECLARE_MUTEX. Эта макрос гарантирует правильную обработку мьютекса даже когда ядро компилируется без включенных потоков. Условная переменная используется как механизм сигнализации: поток может заблокировать мьютекс и затем ждать условной переменной с Tcl_Condition‐ Wait. Это атомно освобождает блокировку мьютекса и блокирует ожидающий поток, пока другой поток не вызовет Tcl_ConditionNotify. Вызывающий Tcl_ConditionNotify должен иметь связанный мьютекс, удерживаемый ранее с помощью вызова Tcl_MutexLock, но это не принуждается. Уведомление условной переменной разблокирует все потоки, ожидающие условной переменной, но они не продолжают, пока мьютекс не будет освобожден с Tcl_MutexUn‐ lock. Реализация Tcl_ConditionWait автоматически блокирует мьютекс перед возвратом. Вызывающий Tcl_ConditionWait должен быть готов к ложным уведомлениям, вызывая Tcl_ConditionWait внутри цикла while, который тестирует некоторый инвариант. Условная переменная может быть уничтожена после ее использования с помощью вызова Tcl_Con‐ ditionFinalize. Процедуры Tcl_ConditionNotify, Tcl_ConditionWait и Tcl_ConditionFinalize определяются как пустые макросы, если не компилируется с включенными потоками. ИНИЦИАЛИЗАЦИЯ Все эти объекты синхронизации являются самоинициализирующимися. Они реализованы как непрозрачные указатели, которые должны быть NULL при первом использовании. Мьютексы и условные переменные очищаются либо обработчиками выхода процесса (если они существуют так долго), либо явно с помощью вызовов Tcl_MutexFi‐ nalize или Tcl_ConditionFinalize. Локальное хранение потока восстанавливается во время Tcl_FinalizeThread. ДОСТУП К ПОТОКАМ НА УРОВНЕ СЦЕНАРИЕВ Tcl не предоставляет встроенных команд для сценариев для создания, управления или присоединения потоков, ни какого-либо доступа на уровне сценария к мьютексу или условным переменным. Он предоставляет такие возможности только через интерфейсы C и оставляет это на усмотрение пакетов раскрывать эти вопросы на уровне сценария. Один из таких пакетов - пакет Thread. ПРИМЕР Чтобы создать поток с переносимым кодом, его функция реализации должна быть объявлена следующим образом: static Tcl_ThreadCreateProc MyThreadImplFunc; Она затем должна быть определена как в этом примере, который просто подсчитывает до заданного значения и затем завершается. static Tcl_ThreadCreateType MyThreadImplFunc( ClientData clientData) { int i, limit = (int) clientData; for (i=0 ; i<limit ; i++) { /* ничего не делаем здесь */ } TCL_THREAD_CREATE_RETURN; } Чтобы создать вышеуказанный поток, заставить его выполниться и дождаться его завершения, мы бы сделали это: int limit = 1000000000; ClientData limitData = (void*)((intptr_t) limit); Tcl_ThreadId id; /* содержит идентификатор созданного потока */ int result; if (Tcl_CreateThread(&id, MyThreadImplFunc, limitData, TCL_THREAD_STACK_DEFAULT, TCL_THREAD_JOINABLE) != TCL_OK) { /* Поток не создан правильно */ return; } /* Сделайте что-то еще на некоторое время здесь */ if (Tcl_JoinThread(id, &result) != TCL_OK) { /* Поток не завершился правильно */ return; } /* Всё очищено аккуратно */ СМ. ТАКЖЕ Tcl_GetCurrentThread(3), Tcl_ThreadQueueEvent(3), Tcl_ThreadAlert(3), Tcl_ExitThread(3), Tcl_FinalizeThread(3), Tcl_CreateThreadEx‐ itHandler(3), Tcl_DeleteThreadExitHandler(3), Thread КЛЮЧЕВЫЕ СЛОВА thread, mutex, condition variable, thread local storage Tcl 8.1 Threads(3)
Threads(3) Tcl Library Procedures Threads(3) ______________________________________________________________________________ NAME Tcl_ConditionNotify, Tcl_ConditionWait, Tcl_ConditionFinalize, Tcl_Get‐ ThreadData, Tcl_MutexLock, Tcl_MutexUnlock, Tcl_MutexFinalize, Tcl_Cre‐ ateThread, Tcl_JoinThread - Tcl thread support SYNOPSIS #include <tcl.h> void Tcl_ConditionNotify(condPtr) void Tcl_ConditionWait(condPtr, mutexPtr, timePtr) void Tcl_ConditionFinalize(condPtr) Void * Tcl_GetThreadData(keyPtr, size) void Tcl_MutexLock(mutexPtr) void Tcl_MutexUnlock(mutexPtr) void Tcl_MutexFinalize(mutexPtr) int Tcl_CreateThread(idPtr, proc, clientData, stackSize, flags) int Tcl_JoinThread(id, result) ARGUMENTS Tcl_Condition *condPtr (in) A condition variable, which must be associated with a mutex lock. Tcl_Mutex *mutexPtr (in) A mutex lock. const Tcl_Time *timePtr (in) A time limit on the condition wait. NULL to wait forever. Note that a polling value of 0 seconds does not make much sense. Tcl_ThreadDataKey *keyPtr (in) This identifies a block of thread local storage. The key should be static and process- wide, yet each thread will end up associating a different block of storage with this key. int *size (in) The size of the thread local storage block. This amount of data is allocated and initial‐ ized to zero the first time each thread calls Tcl_Get‐ ThreadData. Tcl_ThreadId *idPtr (out) The referred storage will con‐ tain the id of the newly cre‐ ated thread as returned by the operating system. Tcl_ThreadId id (in) Id of the thread waited upon. Tcl_ThreadCreateProc *proc (in) This procedure will act as the main() of the newly created thread. The specified client‐ Data will be its sole argument. ClientData clientData (in) Arbitrary information. Passed as sole argument to the proc. int stackSize (in) The size of the stack given to the new thread. int flags (in) Bitmask containing flags allow‐ ing the caller to modify behav‐ ior of the new thread. int *result (out) The referred storage is used to place the exit code of the thread waited upon into it. ______________________________________________________________________________ INTRODUCTION Beginning with the 8.1 release, the Tcl core is thread safe, which al‐ lows you to incorporate Tcl into multithreaded applications without customizing the Tcl core. Starting with the 8.6 release, Tcl multi‐ threading support is on by default. To disable Tcl multithreading sup‐ port, you must include the --disable-threads option to configure when you configure and compile your Tcl core. An important constraint of the Tcl threads implementation is that only the thread that created a Tcl interpreter can use that interpreter. In other words, multiple threads can not access the same Tcl interpreter. (However, a single thread can safely create and use multiple inter‐ preters.) DESCRIPTION Tcl provides Tcl_CreateThread for creating threads. The caller can de‐ termine the size of the stack given to the new thread and modify the behavior through the supplied flags. The value TCL_THREAD_STACK_DEFAULT for the stackSize indicates that the default size as specified by the operating system is to be used for the new thread. As for the flags, currently only the values TCL_THREAD_NOFLAGS and TCL_THREAD_JOINABLE are defined. The first of them invokes the default behavior with no special settings. Using the second value marks the new thread as join‐ able. This means that another thread can wait for the such marked thread to exit and join it. Restrictions: On some UNIX systems the pthread-library does not contain the functionality to specify the stack size of a thread. The specified value for the stack size is ignored on these systems. Windows cur‐ rently does not support joinable threads. This flag value is therefore ignored on this platform. Tcl provides the Tcl_ExitThread and Tcl_FinalizeThread functions for terminating threads and invoking optional per-thread exit handlers. See the Tcl_Exit page for more information on these procedures. The Tcl_JoinThread function is provided to allow threads to wait upon the exit of another thread, which must have been marked as joinable through usage of the TCL_THREAD_JOINABLE-flag during its creation via Tcl_CreateThread. Trying to wait for the exit of a non-joinable thread or a thread which is already waited upon will result in an error. Waiting for a joinable thread which already exited is possible, the system will retain the necessary information until after the call to Tcl_JoinThread. This means that not calling Tcl_JoinThread for a joinable thread will cause a memory leak. The Tcl_GetThreadData call returns a pointer to a block of thread-pri‐ vate data. Its argument is a key that is shared by all threads and a size for the block of storage. The storage is automatically allocated and initialized to all zeros the first time each thread asks for it. The storage is automatically deallocated by Tcl_FinalizeThread. SYNCHRONIZATION AND COMMUNICATION Tcl provides Tcl_ThreadQueueEvent and Tcl_ThreadAlert for handling event queuing in multithreaded applications. See the Notifier manual page for more information on these procedures. A mutex is a lock that is used to serialize all threads through a piece of code by calling Tcl_MutexLock and Tcl_MutexUnlock. If one thread holds a mutex, any other thread calling Tcl_MutexLock will block until Tcl_MutexUnlock is called. A mutex can be destroyed after its use by calling Tcl_MutexFinalize. The result of locking a mutex twice from the same thread is undefined. On some platforms it will result in a deadlock. The Tcl_MutexLock, Tcl_MutexUnlock and Tcl_MutexFinalize procedures are defined as empty macros if not compiling with threads enabled. For declaration of mutexes the TCL_DECLARE_MUTEX macro should be used. This macro assures correct mutex handling even when the core is compiled without threads enabled. A condition variable is used as a signaling mechanism: a thread can lock a mutex and then wait on a condition variable with Tcl_Condition‐ Wait. This atomically releases the mutex lock and blocks the waiting thread until another thread calls Tcl_ConditionNotify. The caller of Tcl_ConditionNotify should have the associated mutex held by previously calling Tcl_MutexLock, but this is not enforced. Notifying the condi‐ tion variable unblocks all threads waiting on the condition variable, but they do not proceed until the mutex is released with Tcl_MutexUn‐ lock. The implementation of Tcl_ConditionWait automatically locks the mutex before returning. The caller of Tcl_ConditionWait should be prepared for spurious notifi‐ cations by calling Tcl_ConditionWait within a while loop that tests some invariant. A condition variable can be destroyed after its use by calling Tcl_Con‐ ditionFinalize. The Tcl_ConditionNotify, Tcl_ConditionWait and Tcl_ConditionFinalize procedures are defined as empty macros if not compiling with threads enabled. INITIALIZATION All of these synchronization objects are self-initializing. They are implemented as opaque pointers that should be NULL upon first use. The mutexes and condition variables are either cleaned up by process exit handlers (if living that long) or explicitly by calls to Tcl_MutexFi‐ nalize or Tcl_ConditionFinalize. Thread local storage is reclaimed during Tcl_FinalizeThread. SCRIPT-LEVEL ACCESS TO THREADS Tcl provides no built-in commands for scripts to use to create, manage, or join threads, nor any script-level access to mutex or condition variables. It provides such facilities only via C interfaces, and leaves it up to packages to expose these matters to the script level. One such package is the Thread package. EXAMPLE To create a thread with portable code, its implementation function should be declared as follows: static Tcl_ThreadCreateProc MyThreadImplFunc; It should then be defined like this example, which just counts up to a given value and then finishes. static Tcl_ThreadCreateType MyThreadImplFunc( ClientData clientData) { int i, limit = (int) clientData; for (i=0 ; i<limit ; i++) { /* doing nothing at all here */ } TCL_THREAD_CREATE_RETURN; } To create the above thread, make it execute, and wait for it to finish, we would do this: int limit = 1000000000; ClientData limitData = (void*)((intptr_t) limit); Tcl_ThreadId id; /* holds identity of thread created */ int result; if (Tcl_CreateThread(&id, MyThreadImplFunc, limitData, TCL_THREAD_STACK_DEFAULT, TCL_THREAD_JOINABLE) != TCL_OK) { /* Thread did not create correctly */ return; } /* Do something else for a while here */ if (Tcl_JoinThread(id, &result) != TCL_OK) { /* Thread did not finish properly */ return; } /* All cleaned up nicely */ SEE ALSO Tcl_GetCurrentThread(3), Tcl_ThreadQueueEvent(3), Tcl_ThreadAlert(3), Tcl_ExitThread(3), Tcl_FinalizeThread(3), Tcl_CreateThreadEx‐ itHandler(3), Tcl_DeleteThreadExitHandler(3), Thread KEYWORDS thread, mutex, condition variable, thread local storage Tcl 8.1 Threads(3)
Filesystem(3) Процедуры библиотеки Tcl Filesystem(3) ______________________________________________________________________________ NAME Tcl_FSRegister, Tcl_FSUnregister, Tcl_FSData, Tcl_FSMountsChanged, Tcl_FSGetFileSystemForPath, Tcl_FSGetPathType, Tcl_FSCopyFile, Tcl_FS‐ CopyDirectory, Tcl_FSCreateDirectory, Tcl_FSDeleteFile, Tcl_FSRemoveDi‐ rectory, Tcl_FSRenameFile, Tcl_FSListVolumes, Tcl_FSEvalFile, Tcl_FSE‐ valFileEx, Tcl_FSLoadFile, Tcl_FSUnloadFile, Tcl_FSMatchInDirectory, Tcl_FSLink, Tcl_FSLstat, Tcl_FSUtime, Tcl_FSFileAttrsGet, Tcl_FSFileAt‐ trsSet, Tcl_FSFileAttrStrings, Tcl_FSStat, Tcl_FSAccess, Tcl_FSOpen‐ FileChannel, Tcl_FSGetCwd, Tcl_FSChdir, Tcl_FSPathSeparator, Tcl_FSJoinPath, Tcl_FSSplitPath, Tcl_FSEqualPaths, Tcl_FSGetNormalized‐ Path, Tcl_FSJoinToPath, Tcl_FSConvertToPathType, Tcl_FSGetInternalRep, Tcl_FSGetTranslatedPath, Tcl_FSGetTranslatedStringPath, Tcl_FSNewNa‐ tivePath, Tcl_FSGetNativePath, Tcl_FSFileSystemInfo, Tcl_GetAccessTime‐ FromStat, Tcl_GetBlockSizeFromStat, Tcl_GetBlocksFromStat, Tcl_GetChangeTimeFromStat, Tcl_GetDeviceTypeFromStat, Tcl_GetFSDevice‐ FromStat, Tcl_GetFSInodeFromStat, Tcl_GetGroupIdFromStat, Tcl_GetLinkCountFromStat, Tcl_GetModeFromStat, Tcl_GetModificationTime‐ FromStat, Tcl_GetSizeFromStat, Tcl_GetUserIdFromStat, Tcl_AllocStatBuf - процедуры для взаимодействия с любой файловой системой SYNOPSIS #include <tcl.h> int Tcl_FSRegister(clientData, fsPtr) int Tcl_FSUnregister(fsPtr) void * Tcl_FSData(fsPtr) Tcl_FSMountsChanged(fsPtr) const Tcl_Filesystem * Tcl_FSGetFileSystemForPath(pathPtr) Tcl_PathType Tcl_FSGetPathType(pathPtr) int Tcl_FSCopyFile(srcPathPtr, destPathPtr) int Tcl_FSCopyDirectory(srcPathPtr, destPathPtr, errorPtr) int Tcl_FSCreateDirectory(pathPtr) int Tcl_FSDeleteFile(pathPtr) int Tcl_FSRemoveDirectory(pathPtr, recursive, errorPtr) int Tcl_FSRenameFile(srcPathPtr, destPathPtr) Tcl_Obj * Tcl_FSListVolumes(void) int Tcl_FSEvalFileEx(interp, pathPtr, encodingName) int Tcl_FSEvalFile(interp, pathPtr) int Tcl_FSLoadFile(interp, pathPtr, sym1, sym2, proc1Ptr, proc2Ptr, loadHandlePtr, unloadProcPtr) int │ Tcl_FSUnloadFile(interp, loadHandle) │ int Tcl_FSMatchInDirectory(interp, resultPtr, pathPtr, pattern, types) Tcl_Obj * Tcl_FSLink(linkNamePtr, toPtr, linkAction) int Tcl_FSLstat(pathPtr, statPtr) int Tcl_FSUtime(pathPtr, tval) int Tcl_FSFileAttrsGet(interp, index, pathPtr, objPtrRef) int Tcl_FSFileAttrsSet(interp, index, pathPtr, objPtr) const char *const * Tcl_FSFileAttrStrings(pathPtr, objPtrRef) int Tcl_FSStat(pathPtr, statPtr) int Tcl_FSAccess(pathPtr, mode) Tcl_Channel Tcl_FSOpenFileChannel(interp, pathPtr, modeString, permissions) Tcl_Obj * Tcl_FSGetCwd(interp) int Tcl_FSChdir(pathPtr) Tcl_Obj * Tcl_FSPathSeparator(pathPtr) Tcl_Obj * Tcl_FSJoinPath(listObj, elements) Tcl_Obj * Tcl_FSSplitPath(pathPtr, lenPtr) int Tcl_FSEqualPaths(firstPtr, secondPtr) Tcl_Obj * Tcl_FSGetNormalizedPath(interp, pathPtr) Tcl_Obj * Tcl_FSJoinToPath(basePtr, objc, objv) int Tcl_FSConvertToPathType(interp, pathPtr) void * Tcl_FSGetInternalRep(pathPtr, fsPtr) Tcl_Obj * Tcl_FSGetTranslatedPath(interp, pathPtr) const char * Tcl_FSGetTranslatedStringPath(interp, pathPtr) Tcl_Obj * Tcl_FSNewNativePath(fsPtr, clientData) const void * Tcl_FSGetNativePath(pathPtr) Tcl_Obj * Tcl_FSFileSystemInfo(pathPtr) Tcl_StatBuf * Tcl_AllocStatBuf() Tcl_WideInt │ Tcl_GetAccessTimeFromStat(statPtr) │ unsigned │ Tcl_GetBlockSizeFromStat(statPtr) │ Tcl_WideUInt │ Tcl_GetBlocksFromStat(statPtr) │ Tcl_WideInt │ Tcl_GetChangeTimeFromStat(statPtr) │ int │ Tcl_GetDeviceTypeFromStat(statPtr) │ unsigned │ Tcl_GetFSDeviceFromStat(statPtr) │ unsigned │ Tcl_GetFSInodeFromStat(statPtr) │ int │ Tcl_GetGroupIdFromStat(statPtr) │ int │ Tcl_GetLinkCountFromStat(statPtr) │ unsigned │ Tcl_GetModeFromStat(statPtr) │ Tcl_WideInt │ Tcl_GetModificationTimeFromStat(statPtr) │ Tcl_WideUInt │ Tcl_GetSizeFromStat(statPtr) │ int │ Tcl_GetUserIdFromStat(statPtr) │ ARGUMENTS const Tcl_Filesystem *fsPtr (in) Указатель на структуру, содержащую адреса процедур, которые могут быть вызваны для выполнения различных операций с файловой системой. Tcl_Obj *pathPtr (in) Путь, представленный этим значением, используется для операции. Если значение ещё не имеет внутреннего представления пути, оно будет преобразовано в такое. Tcl_Obj *srcPathPtr (in) Как и pathPtr, но используется для исходного файла для операции копирования или переименования. Tcl_Obj *destPathPtr (in) Как и pathPtr, но используется для имени файла назначения для операции копирования или переименования. int recursive (in) Флаг, указывающий, нужно ли удалять поддиректории и их содержимое тоже. const char *encodingName (in) Кодировка данных, хранящихся в файле, идентифицируемом pathPtr и подлежащих оценке. const char *pattern (in) Будут возвращены только файлы или директории, соответствующие этому шаблону. Tcl_GlobTypeData *types (in) Будут возвращены только файлы или директории, соответствующие описаниям типов, содержащимся в этой структуре. Этот параметр может быть NULL. Tcl_Interp *interp (in) Интерпретатор для использования либо для результатов, оценки или отчёта об ошибках. void *clientData (in) Внутреннее описание значения пути для создания. Tcl_Obj *firstPtr (in) Первый из двух путей для сравнения. Значение может быть преобразовано в тип пути. Tcl_Obj *secondPtr (in) Второй из двух путей для сравнения. Значение может быть преобразовано в тип пути. Tcl_Obj *listObj (in) Список элементов пути, на котором нужно выполнить операцию объединения. int elements (in) Количество элементов в listObj, которые нужно объединить. Если отрицательное, то объединяются все элементы. Tcl_Obj **errorPtr (out) В случае ошибки, заполняется значением, содержащим имя файла, который вызвал ошибку в различных операциях копирования/переименования. int index (in) Индекс атрибута, о котором идёт речь. Tcl_Obj *objPtr (in) Значение, которое нужно установить в операции. Tcl_Obj **objPtrRef (out) Заполняется значением, содержащим результат операции. Tcl_Obj *resultPtr (out) Предварительно выделенное значение, в которое нужно сохранить (используя Tcl_ListObjAppendElement) список файлов или директорий, которые успешно совпали. int mode (in) Маска, состоящая из одного или нескольких из R_OK, W_OK, X_OK и F_OK. R_OK, W_OK и X_OK запрашивают проверку, существует ли файл и у него есть права на чтение, запись и выполнение соответственно. F_OK запрашивает только проверку существования файла. Tcl_StatBuf *statPtr (out) Структура, которая содержит результат операции stat или lstat. const char *sym1 (in) Имя процедуры для поиска в таблице символов файла. const char *sym2 (in) Имя процедуры для поиска в таблице символов файла. Tcl_PackageInitProc **proc1Ptr (out) Заполняется функцией инициализации для этого кода. Tcl_PackageInitProc **proc2Ptr (out) Заполняется функцией безопасной инициализации для этого кода. void **clientDataPtr (out) Заполняется значением clientData, которое нужно передать функции выгрузки этого кода, когда она вызывается. Tcl_LoadHandle *loadHandlePtr (out) Заполняется абстрактным токеном, представляющим загруженный файл. Tcl_FSUnloadFileProc **unloadProcPtr (out) Заполняется функцией, которую нужно использовать для выгрузки этого кода. Tcl_LoadHandle loadHandle (in) Дескриптор загруженной библиотеки, которую нужно выгрузить. utimbuf *tval (in) В этой структуре читаются и используются времена доступа и изменения для установки этих значений для данного файла. const char *modeString (in) Указывает, как доступ к файлу. Может иметь любое из значений, разрешённых для аргумента mode команды Tcl open. int permissions (in) Флаги прав POSIX, такие как 0644. Если создаётся новый файл, эти права будут установлены на созданный файл. int *lenPtr (out) Если не NULL, заполняется количеством элементов в разделённом пути. Tcl_Obj *basePtr (in) Базовый путь, к которому нужно присоединить заданные элементы. Может быть NULL. int objc (in) Количество элементов в objv. Tcl_Obj *const objv[] (in) Элементы для присоединения к заданному базовому пути. Tcl_Obj *linkNamePtr (in) Имя ссылки, которую нужно создать или прочитать. Tcl_Obj *toPtr (in) На что должна ссылаться ссылка, называемая linkNamePtr, или NULL, если символическая ссылка, указанная linkNamePtr, должна быть прочитана. int linkAction (in) Сочетание флагов, объединённых OR, указывающее, какой тип ссылки нужно создать (будет игнорироваться, если toPtr равно NULL). Допустимые флаги: TCL_CREATE_SYMBOLIC_LINK и TCL_CREATE_HARD_LINK. Если оба флага установлены и базовая файловая система может сделать любой из них, предпочтение отдаётся символическим ссылкам. ______________________________________________________________________________ DESCRIPTION Существует несколько причин для вызова функций API Tcl_FS (например, Tcl_FSAccess и Tcl_FSStat) вместо прямого вызова системных функций, таких как access и stat. Во-первых, они работают кроссплатформенно, поэтому расширение, которое их использует, будет работать без изменений на Unix и Windows. Во-вторых, реализация Windows некоторых из этих функций исправляет ошибки в системных вызовах. В-третьих, эти вызовы функций обрабатывают любые необходимые преобразования "Utf в платформенно-родное" пути (и могут кэшировать результаты таких преобразований для большей эффективности при последующих вызовах). В-четвёртых, и, возможно, самое важное, все эти функции "осведомлены о виртуальной файловой системе". Любая виртуальная файловая система (VFS), зарегистрированная через Tcl_FSRegister, может перенаправлять доступ к файлам на альтернативные носители или методы доступа. Это означает, что все эти функции (а следовательно, и соответствующие команды Tcl, такие как file, glob, pwd, cd, open и т.д.) могут работать с "файлами", которые не являются родными файлами в родной файловой системе. Это также означает, что любое расширение Tcl, которое обращается к файловой системе (FS) через этот API, автоматически "осведомлено о виртуальной файловой системе". Конечно, если расширение обращается напрямую к родной файловой системе (через платформо-специфические API, например), Tcl не сможет перехватить такие вызовы. Если подходящие VFS зарегистрированы, "файлы" могут, например, быть удалёнными (например, расположенными на удалённом FTP-сервере) или заархивированными (например, лежать внутри архива .zip). Такие зарегистрированные файловые системы предоставляют таблицу поиска функций для реализации всех или некоторых из функциональности, перечисленной здесь. Наконец, вызовы Tcl_FSStat и Tcl_FSLstat абстрагируют структуру "struct stat", позволяя использовать один и тот же код как на системах с поддержкой, так и без поддержки файлов больше 2GB. API Tcl_FS основано на Tcl_Obj и может кэшировать внутренние представления и другие строки, связанные с путями (например, текущую рабочую директорию). Один из побочных эффектов этого заключается в том, что нельзя передавать значения с счётчиком ссылок, равным нулю, в любые из этих функций. Если такие вызовы обрабатывались, это могло бы привести к утечкам памяти (в некоторых обстоятельствах код файловой системы может захотеть сохранить ссылку на переданное значение, поэтому нельзя предполагать, что после любого из этих вызовов значение всё ещё имеет счётчик ссылок, равный нулю - он мог быть увеличен) или к прямому segmentation fault (или другой ошибке доступа к памяти) из-за освобождения значения на полпути через сложные манипуляции со значениями, необходимые для обеспечения того, чтобы путь был полностью нормализован и абсолютен для определения файловой системы. Практический урок из этого заключается в том, что Tcl_Obj *path = Tcl_NewStringObj(...); Tcl_FSWhatever(path); Tcl_DecrRefCount(path); неверно и может вызвать ошибки памяти. Путь должен иметь увеличенный счётчик ссылок перед передачей его или перед уменьшением. По этой причине значения с счётчиком ссылок, равным нулю, считаются недействительными путями файловой системы, и вызов любой функции API Tcl_FS с таким значением не произведёт никакого действия. ФУНКЦИИ API FS Tcl_FSCopyFile пытается скопировать файл, указанный srcPathPtr, в путь, указанный destPathPtr. Если два указанных пути лежат в одной файловой системе (согласно Tcl_FSGetFileSystemForPath), то вызывается функция "копирования файла" этой файловой системы (если она не равна NULL). В противном случае функция возвращает -1 и устанавливает глобальную переменную C errno на код POSIX-ошибки "EXDEV" (что означает "ссылка между доменами"). Tcl_FSCopyDirectory пытается скопировать директорию, указанную srcPathPtr, в путь, указанный destPathPtr. Если два указанных пути лежат в одной файловой системе (согласно Tcl_FSGetFileSystemForPath), то вызывается функция "копирования файла" этой файловой системы (если она не равна NULL). В противном случае функция возвращает -1 и устанавливает глобальную переменную C errno на код POSIX-ошибки "EXDEV" (что означает "ссылка между доменами"). Tcl_FSCreateDirectory пытается создать директорию, указанную pathPtr, вызывая функцию "создания директории" владельца. Tcl_FSDeleteFile пытается удалить файл, указанный pathPtr, вызывая функцию "удаления файла" владельца. Tcl_FSRemoveDirectory пытается удалить директорию, указанную pathPtr, вызывая функцию "удаления директории" владельца. Tcl_FSRenameFile пытается переименовать файл или директорию, указанную srcPathPtr, в путь, указанный destPathPtr. Если два указанных пути лежат в одной файловой системе (согласно Tcl_FSGetFileSystemForPath), то вызывается функция "переименования файла" этой файловой системы (если она не равна NULL). В противном случае функция возвращает -1 и устанавливает глобальную переменную C errno на код POSIX-ошибки "EXDEV" (что означает "ссылка между доменами"). Tcl_FSListVolumes вызывает функцию "списка томов" каждой файловой системы, у которой она не равна NULL, и запрашивает у них список корневых томов. Возвращаемые значения накапливаются в списке, который возвращается вызывающему (с счётчиком ссылок, равным 0). Tcl_FSEvalFileEx читает файл, указанный pathPtr, используя кодировку, идентифицируемую encodingName, и оценивает его содержимое как сценарий Tcl. Он возвращает ту же информацию, что и Tcl_EvalObjEx. Если encodingName равно NULL, используется системная кодировка для чтения содержимого файла. Если файл не может быть прочитан, возвращается ошибка Tcl, описывающая, почему файл не может быть прочитан. Символ конца файла для файлов - "\x1A" (^Z) для всех платформ. Если требуется "^Z" в коде для строкового сравнения, можно использовать "\x1A", который будет безопасно заменён интерпретатором Tcl на "^Z". Tcl_FSEvalFile - это упрощённая версия Tcl_FSEvalFileEx, которая всегда использует системную кодировку при чтении файла. Tcl_FSLoadFile динамически загружает двоичный файл кода в память и возвращает адреса двух процедур внутри этого файла, если они определены. Будет вызвана подходящая функция для файловой системы, к которой принадлежит pathPtr. Если эта файловая система не реализует эту функцию (большинство виртуальных файловых систем не будет, из-за ограничений ОС при динамической загрузке двоичного кода), Tcl попытается скопировать файл во временную директорию и загрузить этот временный файл. Tcl_FSUnloadFile │ отменяет операцию, запрашивая удаление библиотеки, указанной loadHandle, из процесса. Обратите внимание, что, в отличие от команды unload, это не даёт библиотеке возможности очистить. │ Оба вышеуказанных функции возвращают стандартный код завершения Tcl. Если возникает ошибка, сообщение об ошибке оставляется в результате интерпретатора. Токен, предоставленный через переменную, указанную loadHandlePtr, может │ использоваться с Tcl_FindSymbol. Tcl_FSMatchInDirectory используется кодом glob для поиска в директории всех файлов, которые соответствуют заданному шаблону. Будет вызвана подходящая функция для файловой системы, к которой принадлежит pathPtr. Возвращаемое значение - стандартный результат Tcl, указывающий, возникла ли ошибка в процессе glob. Сообщения об ошибках размещаются в interp (если interp не NULL, что разрешено), но хорошие результаты размещаются в указанном resultPtr. Обратите внимание, что код glob реализует рекурсивные шаблоны внутренне, поэтому эта функция будет получать только простые шаблоны. Для обработки рекурсии Tcl будет вызывать эту функцию часто, запрашивая только возвращение директорий. Специальный случай вызова с NULL-шаблоном указывает, что путь нужно проверить только на правильный тип. Tcl_FSLink заменяет библиотечную версию readlink и расширяет её для поддержки создания ссылок. Будет вызвана подходящая функция для файловой системы, к которой принадлежит linkNamePtr. Если toPtr равно NULL, выполняется действие "чтение ссылки". Результат - Tcl_Obj, указывающий содержимое символической ссылки, данной linkNamePtr, или NULL, если ссылку нельзя прочитать. Результат принадлежит вызывающему, который должен вызвать Tcl_DecrRefCount, когда результат больше не нужен. Если toPtr не NULL, Tcl должна создать ссылку одного из типов, переданных в флаге linkAction. Этот флаг - объединение по OR флагов TCL_CREATE_SYMBOLIC_LINK и TCL_CREATE_HARD_LINK. Где есть выбор (т.е. более одного флага передано), соглашение Tcl - отдавать предпочтение символическим ссылкам. При успешном создании ссылки возвращаемое значение должно быть toPtr (которое поэтому уже принадлежит вызывающему). Если неудачно, возвращается NULL. Tcl_FSLstat заполняет структуру Tcl_StatBuf statPtr информацией об указанном файле. Вам не нужны права доступа к файлу для получения этой информации, но нужны права поиска во всех директориях, названных в пути, ведущем к файлу. Структура Tcl_StatBuf включает информацию о устройстве, inode (всегда 0 в Windows), привилегированном режиме, nlink (всегда 1 в Windows), идентификаторе пользователя (всегда 0 в Windows), идентификаторе группы (всегда 0 в Windows), rdev (то же, что и устройство в Windows), размере, времени последнего доступа, времени последнего изменения и времени последнего изменения метаданных. См. PORTABLE STAT RESULT API для описания, как писать переносимый код для выделения и доступа к структуре Tcl_StatBuf. Если путь существует, Tcl_FSLstat возвращает 0, и структура stat заполняется данными. В противном случае возвращается -1, и информация stat не предоставляется. Tcl_FSUtime заменяет библиотечную версию utime. Это возвращает 0 при успехе и -1 при ошибке (как в документации utime). При успешном выполнении функция обновит значения "atime" и "mtime" для указанного файла. Tcl_FSFileAttrsGet реализует чтение для подкоманды хуков file attributes. Будет вызвана подходящая функция для файловой системы, к которой принадлежит pathPtr. Если результат равен TCL_OK, то значение размещается в objPtrRef, которое будет временно действительным (если не вызвать Tcl_IncrRefCount). Tcl_FSFileAttrsSet реализует запись для подкоманды хуков file attributes. Будет вызвана подходящая функция для файловой системы, к которой принадлежит pathPtr. Tcl_FSFileAttrStrings реализует часть подкоманды хуков file attributes. Будет вызвана подходящая функция для файловой системы, к которой принадлежит pathPtr. Вызванная процедура может либо вернуть массив строк, либо вместо этого вернуть NULL и поместить список Tcl в данный objPtrRef. Tcl возьмёт этот список и сначала увеличит его счётчик ссылок перед использованием. По завершении этого использования Tcl уменьшит его счётчик ссылок. Следовательно, если список должен быть удалён Tcl при завершении, у него должен быть счётчик ссылок, равный нулю, и если список не должен быть удалён, файловая система должна убедиться, что возвращается значение с счётчиком ссылок не менее одного. Tcl_FSAccess проверяет, будет ли процесс разрешён читать, писать или проверять существование файла (или другого объекта файловой системы), имя которого - pathname. Если pathname - символическая ссылка в Unix, то проверяются права файла, на который ссылается эта символическая ссылка. При успехе (все запрошенные права предоставлены) возвращается ноль. При ошибке (хотя бы один бит в mode запросил разрешение, которое запрещено, или произошла другая ошибка) возвращается -1. Tcl_FSStat заполняет структуру Tcl_StatBuf statPtr информацией об указанном файле. Вам не нужны права доступа к файлу для получения этой информации, но нужны права поиска во всех директориях, названных в пути, ведущем к файлу. Структура Tcl_StatBuf включает информацию о устройстве, inode (всегда 0 в Windows), привилегированном режиме, nlink (всегда 1 в Windows), идентификаторе пользователя (всегда 0 в Windows), идентификаторе группы (всегда 0 в Windows), rdev (то же, что и устройство в Windows), размере, времени последнего доступа, времени последнего изменения и времени последнего изменения метаданных. См. PORTABLE STAT RESULT API для описания, как писать переносимый код для выделения и доступа к структуре Tcl_StatBuf. Если путь существует, Tcl_FSStat возвращает 0, и структура stat заполняется данными. В противном случае возвращается -1, и информация stat не предоставляется. Tcl_FSOpenFileChannel открывает файл, указанный pathPtr, и возвращает дескриптор канала, который можно использовать для ввода и вывода в файл. Этот API моделирован по процедуре fopen стандартной библиотеки ввода/вывода Unix. Синтаксис и значение всех аргументов аналогичны тем, что даны в команде Tcl open при открытии файла. Если возникает ошибка при открытии канала, Tcl_FSOpenFileChannel возвращает NULL и записывает код POSIX-ошибки, который можно получить с помощью Tcl_GetErrno. Кроме того, если interp не NULL, Tcl_FSOpenFileChannel оставляет сообщение об ошибке в результате interp после любой ошибки. Новый созданный канал не регистрируется в предоставленном интерпретаторе; для регистрации используйте Tcl_RegisterChannel. Если один из стандартных каналов, stdin, stdout или stderr, был ранее закрыт, действие по созданию нового канала также назначает его как замену стандартного канала. Tcl_FSGetCwd заменяет библиотечную версию getcwd. Она возвращает текущую рабочую директорию библиотеки Tcl. Это может отличаться от рабочей директории родной платформы, что происходит, когда текущая рабочая директория не в родной файловой системе. Результат - указатель на Tcl_Obj, указывающий текущую директорию, или NULL, если текущую директорию нельзя определить. Если возвращается NULL, сообщение об ошибке оставляется в результате interp. Результат уже имеет увеличенный счётчик ссылок для вызывающего. Когда он больше не нужен, этот счётчик ссылок должен быть уменьшен. Это требуется для обеспечения безопасности потоков, чтобы позволить нескольким потокам получать доступ к этой и связанным функциям, при этом обеспечивая, что результаты всегда действительны. Tcl_FSChdir заменяет библиотечную версию chdir. Путь нормализуется, а затем передаётся файловой системе, которая заявляет на него права. Если эта файловая система не реализует эту функцию, Tcl вернётся к комбинации stat и access для проверки, существует ли директория и у неё есть подходящие права. Для результатов см. документацию chdir. При успешном выполнении мы сохраняем запись успешного пути в cwdPathPtr для последующих вызовов Tcl_FSGetCwd. Tcl_FSPathSeparator возвращает символ(ы) разделителя для самого конкретного элемента пути, указанного pathPtr (т.е. последней части пути). Разделитель возвращается как Tcl_Obj, содержащий строку длиной 1. Если путь недействителен, возвращается NULL. Tcl_FSJoinPath берёт данный Tcl_Obj, который должен быть допустимым списком (который может иметь счётчик ссылок, равный нулю), и возвращает значение пути, полученное путём рассмотрения первых elements элементов как допустимых сегментов пути (каждый сегмент пути может быть полным путём, частичным путём или просто одним возможным именем директории или файла). Если какой-либо сегмент пути является абсолютным путём, все предыдущие сегменты пути отбрасываются. Если elements меньше 0, используется весь список. Возможность того, что возвращаемое значение является элементом данного списка, так что вызывающий должен увеличить счётчик ссылок на результат перед освобождением списка. Возвращаемое значение, обычно с счётчиком ссылок, равным нулю (но оно может быть общим в некоторых условиях), содержит объединённый путь. Вызывающий должен добавить счётчик ссылок на значение перед его использованием. В частности, возвращаемое значение может быть элементом данного списка, так что освобождение списка может освободить значение преждевременно, если счётчик ссылок не был взят. Если количество элементов равно нулю, возвращаемое значение будет Tcl_Obj с пустой строкой. Tcl_FSSplitPath берёт данный Tcl_Obj, который должен быть допустимым путём, и возвращает значение списка Tcl, содержащее каждый сегмент этого пути как элемент. Возвращается значение списка с счётчиком ссылок, равным нулю. Если переданный lenPtr не NULL, переменная, на которую он указывает, будет обновлена для содержащего количество элементов в возвращённом списке. Tcl_FSEqualPaths проверяет, представляют ли два пути один и тот же объект файловой системы. Возвращает 1, если пути равны, и 0, если они разные. Если любой путь равен NULL, всегда возвращается 0. Tcl_FSGetNormalizedPath пытается извлечь из данного Tcl_Obj уникальное нормализованное представление пути, строковое значение которого может использоваться как уникальный идентификатор для файла. Он возвращает нормализованное значение пути, принадлежащее Tcl, или NULL, если путь недействителен или его нельзя успешно преобразовать. Извлечение абсолютных нормализованных путей очень эффективно (потому что файловая система работает с этими представлениями внутренне), хотя результат, когда файловая система содержит множество символических ссылок, может не быть самой удобной для пользователя версией пути. Возвращаемое значение принадлежит Tcl и имеет срок жизни, эквивалентный pathPtr, переданному (если это относительный путь, то нормализованное значение пути может быть освобождено в любой момент, когда cwd изменяется) - вызывающий, конечно, может увеличить счётчик ссылок, если хочет сохранить копию дольше. Tcl_FSJoinToPath берёт данное значение, которое обычно должно быть допустимым путём или NULL, и присоединяет к нему массив сегментов путей, данных. Возвращает значение, обычно с счётчиком ссылок, равным нулю (но оно может быть общим в некоторых условиях), содержащее объединённый путь. Вызывающий должен добавить счётчик ссылок на значение перед его использованием. Если какое-либо из значений, переданных в эту функцию (pathPtr или элементы пути), имеет счётчик ссылок, равный нулю, они будут освобождены, когда функция вернётся. Tcl_FSConvertToPathType пытается преобразовать данное Tcl_Obj в допустимый тип пути Tcl, учитывая, что cwd может измениться, даже если это значение уже якобы правильного типа. Имя файла может начинаться с "~" (для обозначения домашней директории текущего пользователя) или "~<user>" (для обозначения домашней директории любого пользователя). Если преобразование удаётся (т.е. значение является допустимым путём в одной из текущих файловых систем), то возвращается TCL_OK. В противном случае возвращается TCL_ERROR, и сообщение об ошибке может быть оставлено в интерпретаторе. Tcl_FSGetInternalRep извлекает внутреннее представление данного значения пути в данной файловой системе. Если значение пути принадлежит другой файловой системе, возвращается NULL. Если внутреннее представление в настоящее время равно NULL, мы пытаемся сгенерировать его, вызывая процедуру Tcl_FSCreateInternalRepProc файловой системы. Возвращает NULL или допустимое внутреннее представление пути. Это внутреннее представление кэшируется, так что повторные вызовы этой функции не потребуют дополнительных преобразований. Tcl_FSGetTranslatedPath пытается извлечь переведённый путь из данного Tcl_Obj. Если перевод успешен (т.е. значение является допустимым путём), то он возвращается. В противном случае возвращается NULL, и сообщение об ошибке может быть оставлено в интерпретаторе. "Переведённый" путь - это тот, который не содержит последовательностей "~" или "~user" (они были расширены до их текущего представления в файловой системе). Возвращаемое значение принадлежит вызывающему, который должен сохранить его или вызвать Tcl_DecrRefCount, чтобы обеспечить освобождение памяти. Эта функция имеет мало практического использования, и Tcl_FSGetNormalizedPath или Tcl_FSGetNativePath обычно являются лучшими функциями для использования в большинстве случаев. Tcl_FSGetTranslatedStringPath делает то же, что и Tcl_FSGetTranslatedPath, но возвращает строку символов или NULL. Возвращаемая строка динамически выделяется и принадлежит вызывающему, который должен сохранить её или вызвать ckfree, чтобы обеспечить её освобождение. Опять же, Tcl_FSGetNormalizedPath или Tcl_FSGetNativePath обычно являются лучшими функциями для использования в большинстве случаев. Tcl_FSNewNativePath выполняет что-то вроде обратного обычных преобразований obj->path->nativerep. Если какой-то код извлекает путь в родной форме (из, например, readlink или родного диалога) и этот путь должен использоваться на уровне Tcl, то вызов этой функции - эффективный способ создания подходящего значения типа пути. Результат - чистое значение "path", которое получит строковое представление UTF-8 только в том случае, если это требуется некоторым кодом Tcl. Tcl_FSGetNativePath предназначена для использования файловыми системами Win/Unix, чтобы они могли легко получить родное (char* или TCHAR*) представление пути. Эта функция - удобная обёртка вокруг Tcl_FSGetInternalRep. В будущем может быть желательно иметь родные представления, не основанные на строках (например, в macOS представление с использованием структуры fileSpec или FSRef было бы более эффективным). В Windows полное представление Unicode позволит для путей неограниченной длины. В настоящее время представление - просто строковый символ, который может содержать либо относительный путь, либо полный, абсолютный нормализованный путь в родной кодировке (сложные условия диктуют, какое из них будет предоставлено, так что ни одно из них нельзя полагаться, если путь известен как абсолютный). Если нужен родной путь, который должен быть абсолютным, то следует запросить родную версию нормализованного пути. Если по какой-то причине нужна неабсолютная, ненормализованная версия пути, её нужно построить отдельно (например, с помощью Tcl_FSGetTranslatedPath). Родное представление кэшируется, так что повторные вызовы этой функции не потребуют дополнительных преобразований. Возвращаемое значение принадлежит Tcl и имеет срок жизни, эквивалентный pathPtr, переданному (если это относительный путь, то родное представление может быть освобождено в любой момент, когда cwd изменяется). Tcl_FSFileSystemInfo возвращает список из двух элементов. Первый элемент - имя файловой системы (например, "native", "vfs", "zip" или "prowrap"), а второй - конкретный тип данного пути в этой файловой системе (что зависит от файловой системы). Второй элемент может быть пустым, если файловая система не предоставляет дальнейшую категоризацию файлов. Возвращается допустимое значение списка, если значение пути распознано, в противном случае возвращается NULL. Tcl_FSGetFileSystemForPath возвращает указатель на Tcl_Filesystem, которая принимает этот путь как допустимый. Если ни одна файловая система не примет путь, возвращается NULL. Tcl_FSGetPathType определяет, является ли данный путь относительным к текущей директории, относительным к текущему тому или абсолютным. Он возвращает один из TCL_PATH_ABSOLUTE, TCL_PATH_RELATIVE или TCL_PATH_VOLUME_RELATIVE. PORTABLE STAT RESULT API Tcl_AllocStatBuf выделяет Tcl_StatBuf на системной куче (которая может быть освобождена путём передачи в ckfree). Это позволяет расширениям вызывать Tcl_FSStat и Tcl_FSLstat без зависимости от размера буфера. Это, в свою очередь, зависит от флагов, использованных для сборки Tcl. Переносимые поля Tcl_StatBuf можно читать с помощью следующих │ функций, каждая из которых возвращает значение соответствующего поля, │ перечисленного в таблице ниже. Обратите внимание, что на некоторых платформах может быть │ другие поля в Tcl_StatBuf, так как это псевдоним подходящей системной │ структуры, но только переносимые доступны здесь. См. документацию вашей системы для полного описания этих полей. │ Access Function Field │ Tcl_GetFSDeviceFromStat st_dev │ Tcl_GetFSInodeFromStat st_ino │ Tcl_GetModeFromStat st_mode │ Tcl_GetLinkCountFromStat st_nlink │ Tcl_GetUserIdFromStat st_uid │ Tcl_GetGroupIdFromStat st_gid │ Tcl_GetDeviceTypeFromStat st_rdev │ Tcl_GetAccessTimeFromStat st_atime │ Tcl_GetModificationTimeFromStat st_mtime │ Tcl_GetChangeTimeFromStat st_ctime │ Tcl_GetSizeFromStat st_size │ Tcl_GetBlocksFromStat st_blocks │ Tcl_GetBlockSizeFromStat st_blksize │ THE VIRTUAL FILESYSTEM API Файловая система предоставляет структуру Tcl_Filesystem, содержащую указатели на функции, которые реализуют различные операции с файловой системой; эти операции вызываются по необходимости обобщённым слоем, что обычно происходит через функции, перечисленные выше. Структуры Tcl_Filesystem манипулируются с помощью следующих методов. Tcl_FSRegister принимает указатель на структуру файловой системы и необязательный фрагмент данных для ассоциации с этой файловой системой. При вызове этой функции Tcl присоединит файловую систему к списку известных файловых систем, и она станет полностью функциональной немедленно. Tcl не проверяет, регистрируется ли одна и та же файловая система несколько раз (и в общем это нехорошая вещь делать). Возвращается TCL_OK. Tcl_FSUnregister удаляет указанную структуру файловой системы из списка известных файловых систем, если она известна, и возвращает TCL_OK. Если файловая система в настоящее время не зарегистрирована, возвращается TCL_ERROR. Tcl_FSData вернёт clientData, ассоциированное с данной файловой системой, если эта файловая система зарегистрирована. В противном случае вернётся NULL. Tcl_FSMountsChanged используется для информирования ядра Tcl о том, что набор точек монтирования для данной (уже зарегистрированной) файловой системы изменился, и что кэшированные представления файлов, следовательно, больше не являются правильными. THE TCL_FILESYSTEM STRUCTURE Структура Tcl_Filesystem содержит следующие поля: typedef struct Tcl_Filesystem { const char *typeName; int structureLength; Tcl_FSVersion version; Tcl_FSPathInFilesystemProc *pathInFilesystemProc; Tcl_FSDupInternalRepProc *dupInternalRepProc; Tcl_FSFreeInternalRepProc *freeInternalRepProc; Tcl_FSInternalToNormalizedProc *internalToNormalizedProc; Tcl_FSCreateInternalRepProc *createInternalRepProc; Tcl_FSNormalizePathProc *normalizePathProc; Tcl_FSFilesystemPathTypeProc *filesystemPathTypeProc; Tcl_FSFilesystemSeparatorProc *filesystemSeparatorProc; Tcl_FSStatProc *statProc; Tcl_FSAccessProc *accessProc; Tcl_FSOpenFileChannelProc *openFileChannelProc; Tcl_FSMatchInDirectoryProc *matchInDirectoryProc; Tcl_FSUtimeProc *utimeProc; Tcl_FSLinkProc *linkProc; Tcl_FSListVolumesProc *listVolumesProc; Tcl_FSFileAttrStringsProc *fileAttrStringsProc; Tcl_FSFileAttrsGetProc *fileAttrsGetProc; Tcl_FSFileAttrsSetProc *fileAttrsSetProc; Tcl_FSCreateDirectoryProc *createDirectoryProc; Tcl_FSRemoveDirectoryProc *removeDirectoryProc; Tcl_FSDeleteFileProc *deleteFileProc; Tcl_FSCopyFileProc *copyFileProc; Tcl_FSRenameFileProc *renameFileProc; Tcl_FSCopyDirectoryProc *copyDirectoryProc; Tcl_FSLstatProc *lstatProc; Tcl_FSLoadFileProc *loadFileProc; Tcl_FSGetCwdProc *getCwdProc; Tcl_FSChdirProc *chdirProc; } Tcl_Filesystem; За исключением первых трёх полей в этой структуре, содержащих простые элементы данных, все записи содержат адреса функций, вызываемых обобщённым слоем файловой системы для выполнения полного диапазона действий, связанных с файловой системой. Многие функции в этой структуре разделены на три категории: инфраструктурные функции (почти все из которых должны быть реализованы), операционные функции (которые должны быть реализованы, если предоставляется полная файловая система) и функции эффективности (которые нужно реализовать только в том случае, если они могут быть сделаны эффективно или если у них есть побочные эффекты, требуемые файловой системой; у Tcl есть менее эффективные эмуляции, на которые можно опираться). Важно отметить, что в текущей версии Tcl большинство из этих резервных копий используются только для обработки команд, инициированных в Tcl, а не в C. Это значит, что если команда переименования файла вызвана в Tcl, и соответствующие файловая(ые) система(ы) не реализуют свою Tcl_FSRenameFileProc, ядро Tcl вместо этого вернётся к комбинации других функций файловой системы (оно использует Tcl_FSCopyFileProc, за которым следует Tcl_FSDeleteFileProc, и если Tcl_FSCopyFileProc не реализовано, есть дальнейший резерв). Однако, если Tcl_FSRenameFileProc вызвана на уровне C, такие резервные копии не происходят. Это верно, кроме последних четырёх записей в таблице файловой системы (lstat, load, getcwd и chdir), для которых резервные копии действительно происходят на уровне C. Любые функции, которые принимают имена путей в форме Tcl_Obj, принимают эти имена в форме UTF-8. API инфраструктуры файловой системы предназначено для поддержки эффективного, кэшированного преобразования этих путей UTF-8 в другие родные представления. EXAMPLE FILESYSTEM DEFINITION Вот таблица поиска файловой системы, используемая расширением "vfs", которое позволяет реализовывать действия файловой системы в Tcl. static Tcl_Filesystem vfsFilesystem = { "tclvfs", sizeof(Tcl_Filesystem), TCL_FILESYSTEM_VERSION_1, &VfsPathInFilesystem, &VfsDupInternalRep, &VfsFreeInternalRep, /* Нет internal to normalized, так как мы не создаём * чистых 'internal' представлений Tcl_Obj пути */ NULL, /* Нет функции создания родного представления, так как мы не используем * это и не выбираем поддержку использования Tcl_FSNewNativePath */ NULL, /* Нормализация пути не нужна - мы предполагаем, что пути имеют * только одно представление */ NULL, &VfsFilesystemPathType, &VfsFilesystemSeparator, &VfsStat, &VfsAccess, &VfsOpenFileChannel, &VfsMatchInDirectory, &VfsUtime, /* Мы выбираем не поддерживать символические ссылки внутри наших * VFS */ NULL, &VfsListVolumes, &VfsFileAttrStrings, &VfsFileAttrsGet, &VfsFileAttrsSet, &VfsCreateDirectory, &VfsRemoveDirectory, &VfsDeleteFile, /* Нет копирования файла; используем механизм резервного копирования ядра */ NULL, /* Нет переименования файла; используем механизм резервного копирования ядра */ NULL, /* Нет копирования директории; используем механизм резервного копирования ядра */ NULL, /* Ядро будет использовать stat для lstat */ NULL, /* Нет загрузки; используем механизм резервного копирования ядра */ NULL, /* Нам не нужна getcwd или chdir; внутреннее значение ядра подходит */ NULL, NULL }; ФАЙЛОВАЯ СИСТЕМА ИНФРАСТРУКТУРЫ Эти поля содержат базовую информацию о структуре файловой системы и адреса функций, которые используются для ассоциации конкретной файловой системы с путем файла и обработки внутренних представлений путей, например, копирования и освобождения таких представлений. TYPENAME Поле typeName содержит завершающую нулем строку, которая идентифицирует тип реализованной файловой системы, например, "native", "zip" или "vfs". STRUCTURE LENGTH Поле structureLength обычно реализуется как sizeof(Tcl_Filesystem) и предназначено для облегчения обратимой двоичной совместимости, если размер структуры изменится в будущей версии Tcl. VERSION Поле version должно быть установлено в TCL_FILESYSTEM_VERSION_1. PATHINFILESYSTEMPROC Поле pathInFilesystemProc содержит адрес функции, которая вызывается для определения, принадлежит ли данное значение пути этой файловой системе или нет. Tcl будет вызывать остальные функции файловой системы только с путём, для которого эта функция вернула TCL_OK. Если путь не принадлежит, должно быть возвращено -1 (поведение Tcl для любого другого возвращаемого значения не определено). Если возвращается TCL_OK, то необязательный выходной параметр clientDataPtr может использоваться для возврата внутреннего (специфичного для файловой системы) представления пути, которое будет кэшироваться внутри значения пути и может быть эффективно получено другими функциями файловой системы. Tcl одновременно закэширует тот факт, что этот путь принадлежит этой файловой системе. Такие кэши инвалидируются при добавлении или удалении структур файловых систем из внутреннего списка известных файловых систем Tcl. typedef int Tcl_FSPathInFilesystemProc( Tcl_Obj *pathPtr, ClientData *clientDataPtr); DUPINTERNALREPPROC Эта функция создаёт копию внутреннего представления пути и вызывается, когда Tcl нужно дублировать значение пути. Если NULL, Tcl просто не скопирует внутреннее представление, которое затем может потребовать повторной генерации позже. typedef ClientData Tcl_FSDupInternalRepProc( ClientData clientData); FREEINTERNALREPPROC Освободить внутреннее представление. Это должно быть реализовано, если внутренние представления нуждаются в освобождении (т.е. если выделяется некоторая память при генерации внутреннего представления), но в противном случае может быть NULL. typedef void Tcl_FSFreeInternalRepProc( ClientData clientData); INTERNALTONORMALIZEDPROC Функция для преобразования внутреннего представления в нормализованный путь. Требуется только в том случае, если файловая система создаёт чистые значения пути без строкового/путевого представления. Возвращаемое значение - значение Tcl, строковое представление которого является нормализованным путём. typedef Tcl_Obj *Tcl_FSInternalToNormalizedProc( ClientData clientData); CREATEINTERNALREPPROC Функция для взятия значения пути и расчёта внутреннего представления для него и хранения этого родного представления в значении. Может быть NULL, если пути не имеют внутреннего представления или если Tcl_FSPathInFilesystemProc для этой файловой системы всегда немедленно создаёт внутреннее представление для путей, которые она принимает. typedef ClientData Tcl_FSCreateInternalRepProc( Tcl_Obj *pathPtr); NORMALIZEPATHPROC Функция для нормализации пути. Должна быть реализована для всех файловых систем, которые могут иметь несколько строковых представлений для одного значения пути. В Tcl каждый "путь" должен иметь одно уникальное "нормализованное" строковое представление. В зависимости от файловой системы может быть более одного ненормализованного строкового представления, которое относится к этому пути (например, относительный путь, путь с разным регистром символов, если файловая система нечувствительна к регистру, путь, содержащий ссылку на домашнюю директорию, такую как "~", путь, содержащий символические ссылки и т.д.). Если самый последний компонент в пути является символической ссылкой, он не должен быть преобразован в значение, на которое он указывает (но его регистр или другие аспекты должны быть сделаны уникальными). Все остальные компоненты пути должны быть преобразованы из символических ссылок. Это одно исключение требуется для согласия с семантикой Tcl для file delete, file rename, file copy, действующих на символические ссылки. Эта функция может быть вызвана с nextCheckpoint либо в начале пути (т.е. ноль), в конце пути или в любой промежуточной разделительной точке пути. Она никогда не будет указывать на любую другую произвольную позицию в пути. В последнем из трёх допустимых случаев реализация может предположить, что путь до и включая разделитель файла известен и нормализован. typedef int Tcl_FSNormalizePathProc( Tcl_Interp *interp, Tcl_Obj *pathPtr, int nextCheckpoint); ФАЙЛОВАЯ СИСТЕМА ОПЕРАЦИЙ Поля в этом разделе структуры содержат адреса функций, которые вызываются для выполнения базовых операций файловой системы. Для файловой системы, которая ожидает использоваться с полным стандартным набором команд Tcl, все из них должны быть реализованы. Если некоторые из них не реализованы, то определённые команды Tcl могут завершиться неудачей при работе с путями в этой файловой системе. Однако в некоторых случаях это может быть желательно (например, файловая система только для чтения не должна реализовывать последние четыре функции, а файловая система, которая не поддерживает символические ссылки, не должна реализовывать функцию readlink и т.д. Ядро Tcl ожидает, что файловые системы будут вести себя так). FILESYSTEMPATHTYPEPROC Функция для определения типа пути в этой файловой системе. Может быть NULL, в этом случае информация о типе не будет доступна пользователям файловой системы. "Тип" используется только в информационных целях и должен быть возвращён как строковое представление Tcl_Obj, которое возвращается. Типичное возвращаемое значение может быть "networked", "zip" или "ftp". Результат Tcl_Obj принадлежит файловой системе, так что Tcl увеличит счётчик ссылок на это значение, если захочет сохранить ссылку на него. typedef Tcl_Obj *Tcl_FSFilesystemPathTypeProc( Tcl_Obj *pathPtr); FILESYSTEMSEPARATORPROC Функция для возврата символа(ов) разделителя для этой файловой системы. Это нужно реализовать только в том случае, если файловая система желает использовать другой разделитель, чем стандартную строку "/". Среди прочего, она возвращается командой file separator. Возвращаемое значение должно быть значением с счётчиком ссылок, равным нулю. typedef Tcl_Obj *Tcl_FSFilesystemSeparatorProc( Tcl_Obj *pathPtr); STATPROC Функция для обработки вызова Tcl_FSStat. Должна быть реализована для любой разумной файловой системы, поскольку многие команды уровня Tcl критически зависят от неё (например, file atime, file isdirectory, file size, glob). typedef int Tcl_FSStatProc( Tcl_Obj *pathPtr, Tcl_StatBuf *statPtr); Tcl_FSStatProc заполняет структуру stat информацией об указанном файле. Вам не нужны права доступа к файлу для получения этой информации, но нужны права поиска во всех директориях, названных в пути, ведущем к файлу. Структура stat включает информацию о устройстве, inode (всегда 0 в Windows), привилегированном режиме, nlink (всегда 1 в Windows), идентификаторе пользователя (всегда 0 в Windows), идентификаторе группы (всегда 0 в Windows), rdev (то же, что и устройство в Windows), размере, времени последнего доступа, времени последнего изменения и времени последнего изменения метаданных. Если файл, представленный pathPtr, существует, Tcl_FSStatProc возвращает 0, и структура stat заполняется данными. В противном случае возвращается -1, и информация stat не предоставляется. ACCESSPROC Функция для обработки вызова Tcl_FSAccess. Должна быть реализована для любой разумной файловой системы, поскольку многие команды уровня Tcl критически зависят от неё (например, file exists, file readable). typedef int Tcl_FSAccessProc( Tcl_Obj *pathPtr, int mode); Tcl_FSAccessProc проверяет, будет ли процесс разрешён читать, писать или проверять существование файла (или другого объекта файловой системы), имя которого находится в pathPtr. Если pathname относится к символической ссылке в Unix, то проверяются права файла, на который ссылается эта символическая ссылка. При успехе (все запрошенные права предоставлены) возвращается ноль. При ошибке (хотя бы один бит в mode запросил разрешение, которое запрещено, или произошла другая ошибка) возвращается -1. OPENFILECHANNELPROC Функция для обработки вызова Tcl_FSOpenFileChannel. Должна быть реализована для любой разумной файловой системы, поскольку любые операции, требующие открытия или доступа к содержимому файла, будут использовать её (например, open, encoding и многие команды Tk). typedef Tcl_Channel Tcl_FSOpenFileChannelProc( Tcl_Interp *interp, Tcl_Obj *pathPtr, int mode, int permissions); Tcl_FSOpenFileChannelProc открывает файл, указанный pathPtr, и возвращает дескриптор канала, который можно использовать для ввода и вывода в файл. Этот API моделирован по процедуре fopen стандартной библиотеки ввода/вывода Unix. Синтаксис и значение всех аргументов аналогичны тем, что даны в команде Tcl open при открытии файла, где аргумент mode - комбинация флагов POSIX O_RDONLY, O_WRONLY и т.д. Если возникает ошибка при открытии канала, Tcl_FSOpenFileChannelProc возвращает NULL и записывает код POSIX-ошибки, который можно получить с помощью Tcl_GetErrno. Кроме того, если interp не NULL, Tcl_FSOpenFileChannelProc оставляет сообщение об ошибке в результате interp после любой ошибки. Новый созданный канал не должен быть зарегистрирован в предоставленном интерпретаторе Tcl_FSOpenFileChannelProc; эта задача ложится на вызывающего Tcl_FSOpenFileChannel (если это необходимо). Если один из стандартных каналов, stdin, stdout или stderr, был ранее закрыт, действие по созданию нового канала также назначает его как замену стандартного канала. MATCHINDIRECTORYPROC Функция для обработки вызова Tcl_FSMatchInDirectory. Если не реализована, то функциональность glob и рекурсивного копирования будет отсутствовать в файловой системе (и это может повлиять на команды, такие как encoding names, которые используют функциональность glob внутренне). typedef int Tcl_FSMatchInDirectoryProc( Tcl_Interp *interp, Tcl_Obj *resultPtr, Tcl_Obj *pathPtr, const char *pattern, Tcl_GlobTypeData *types); Функция должна возвращать все файлы или директории (или другие объекты файловой системы), которые соответствуют данному шаблону и соответствуют указанной спецификации типов. Существует два способа вызова этой функции. Если pattern равно NULL, то pathPtr - полное спецификационное значение пути для одного файла или директории, которое нужно проверить на существование и правильный тип. В противном случае pathPtr - директория, содержимое которой функция должна искать файлы или директории, у которых правильный тип. В любом случае, pathPtr можно считать как не NULL, так и непустым. В настоящее время не задокументировано, будет ли у pathPtr разделитель файла в конце или нет, так что код должен быть гибким для обоих возможностей. Возвращаемое значение - стандартный результат Tcl, указывающий, возникла ли ошибка в процессе сопоставления. Сообщения об ошибках размещаются в interp, если interp не NULL (что разрешено), в противном случае сообщение об ошибке не нужно генерировать; при результате TCL_OK результаты должны быть добавлены к указанному значению resultPtr (которое можно считать допустимым неспециализированным списком Tcl). Совпадения, добавленные к resultPtr, должны включать любой префикс пути, данный в pathPtr (это обычно означает, что они будут абсолютными спецификациями пути). Обратите внимание, что если совпадения не найдены, это просто приводит к пустому результату; ошибки сигнализируются только для фактических проблем с файлом или файловой системой, которые могут возникнуть во время процесса сопоставления. Структура Tcl_GlobTypeData, передаваемая в параметре types, содержит следующие поля: typedef struct Tcl_GlobTypeData { /* Соответствует bcdpfls как в 'find -t' */ int type; /* Соответствует разрешениям файла */ int perm; /* Допустимый тип mac */ Tcl_Obj *macType; /* Допустимый создатель mac */ Tcl_Obj *macCreator; } Tcl_GlobTypeData; Существуют два конкретных случая, которые важно обработать правильно, оба, когда types не NULL. Два случая - когда types->types & TCL_GLOB_TYPE_DIR или types->types & TCL_GLOB_TYPE_MOUNT истинны (и в частности, когда другие флаги ложны). В первом из этих случаев функция должна перечислить содержащиеся директории. Tcl использует это для реализации рекурсивного globbing, так что критически важно, чтобы файловые системы правильно реализовывали сопоставление директорий. Во втором из этих случаев, с TCL_GLOB_TYPE_MOUNT, файловая система должна перечислить точки монтирования, которые лежат внутри данного pathPtr (и в этом случае pathPtr может не лежать в той же файловой системе - в отличие от всех других случаев, в которых вызывается эта функция). Поддержка этого критически важна, чтобы Tcl могла иметь бесшовные переходы между одной файловой системой и другой. UTIMEPROC Функция для обработки вызова Tcl_FSUtime. Требуется для разрешения установки (но не чтения) времён с помощью file mtime, file atime и реализации open-r/open-w/fcopy для копирования файла. typedef int Tcl_FSUtimeProc( Tcl_Obj *pathPtr, struct utimbuf *tval); Времена доступа и изменения файла, указанного pathPtr, должны быть изменены на значения, данные в структуре tval. Возвращаемое значение должно быть 0 при успехе и -1 при ошибке, как в системном utime. LINKPROC Функция для обработки вызова Tcl_FSLink. Должна быть реализована только в том случае, если файловая система поддерживает ссылки, и в противном случае может быть NULL. typedef Tcl_Obj *Tcl_FSLinkProc( Tcl_Obj *linkNamePtr, Tcl_Obj *toPtr, int linkAction); Если toPtr равно NULL, функция запрашивается для чтения содержимого ссылки. Результат - Tcl_Obj, указывающий содержимое символической ссылки, данной linkNamePtr, или NULL, если ссылку нельзя прочитать. Результат принадлежит вызывающему, который должен вызвать Tcl_DecrRefCount, когда результат больше не нужен. Если toPtr не NULL, функция должна попытаться создать ссылку. Результат в этом случае должен быть toPtr, если ссылка успешна, и NULL в противном случае. В этом случае результат не принадлежит вызывающему (т.е. манипуляции с счётчиком ссылок на обоих концах не нужны). См. документацию Tcl_FSLink для правильной интерпретации флагов linkAction. LISTVOLUMESPROC Функция для перечисления любых томов файловой системы, добавленных этой файловой системой. Должна быть реализована только в том случае, если файловая система добавляет тома в начале файловой системы, чтобы их можно было возвращать командой file volumes. typedef Tcl_Obj *Tcl_FSListVolumesProc(void); Результат должен быть списком томов, добавленных этой файловой системой, или NULL (или пустым списком), если томов не предоставляется. Значение результата считается принадлежащим файловой системе (не ядру Tcl), но должно быть дано счётчик ссылок для Tcl. Tcl использует содержимое списка, а затем уменьшает этот счётчик ссылок. Это позволяет файловым системам выбирать, хотят ли они фактически сохранить "глобальный список" томов или нет (если нет, они генерируют список на лету и передают его Tcl с счётчиком ссылок, равным 1, а затем забывают о списке; если да, то они просто увеличивают счётчик ссылок на свой глобальный список и передают его Tcl, который скопирует содержимое, а затем уменьшит счётчик обратно до того, чем он был). Следовательно, Tcl считает возвращаемые значения из этой процедуры только для чтения. FILEATTRSTRINGSPROC Функция для перечисления всех строк атрибутов, которые допустимы для этой файловой системы. Если не реализована, файловая система не будет поддерживать команду file attributes. Это позволяет прикреплять произвольную дополнительную информацию к файлам в файловой системе. Если это не реализовано, нет необходимости реализовывать методы получения и установки. typedef const char *const *Tcl_FSFileAttrStringsProc( Tcl_Obj *pathPtr, Tcl_Obj **objPtrRef); Вызванная функция может либо вернуть массив строк, либо вместо этого вернуть NULL и поместить список Tcl в данный objPtrRef. Tcl возьмёт этот список и сначала увеличит его счётчик ссылок перед использованием. По завершении этого использования Tcl уменьшит его счётчик ссылок. Следовательно, если список должен быть удалён Tcl при завершении, у него должен быть счётчик ссылок, равный нулю, и если список не должен быть удалён, файловая система должна убедиться, что возвращается значение с счётчиком ссылок не менее одного. FILEATTRSGETPROC Функция для обработки вызова Tcl_FSFileAttrsGet, используемая file attributes. typedef int Tcl_FSFileAttrsGetProc( Tcl_Interp *interp, int index, Tcl_Obj *pathPtr, Tcl_Obj **objPtrRef); Возвращает стандартный код возврата Tcl. Полученное значение атрибута, которое соответствует index'ному элементу в списке, возвращённом Tcl_FSFileAttrStringsProc, - Tcl_Obj, размещённое в objPtrRef (если возвращено TCL_OK) и, вероятно, имеющее счётчик ссылок, равный нулю. В любом случае мы должны либо сохранить его где-то (например, в результате Tcl), либо Incr/Decr его счётчик ссылок, чтобы обеспечить правильное освобождение. FILEATTRSSETPROC Функция для обработки вызова Tcl_FSFileAttrsSet, используемая file attributes. Если файловая система только для чтения, нет необходимости реализовывать это. typedef int Tcl_FSFileAttrsSetProc( Tcl_Interp *interp, int index, Tcl_Obj *pathPtr, Tcl_Obj *objPtr); Значение атрибута index'ного элемента в списке, возвращённом Tcl_FSFileAttrStringsProc, должно быть установлено в данное objPtr. CREATEDIRECTORYPROC Функция для обработки вызова Tcl_FSCreateDirectory. Должна быть реализована, если FS только для чтения. typedef int Tcl_FSCreateDirectoryProc( Tcl_Obj *pathPtr); Возвращаемое значение - стандартный результат Tcl, указывающий, возникла ли ошибка в процессе. При успешном выполнении в файловой системе должна быть добавлена новая директория в расположении, указанном pathPtr. REMOVEDIRECTORYPROC Функция для обработки вызова Tcl_FSRemoveDirectory. Должна быть реализована, если FS только для чтения. typedef int Tcl_FSRemoveDirectoryProc( Tcl_Obj *pathPtr, int recursive, Tcl_Obj **errorPtr); Возвращаемое значение - стандартный результат Tcl, указывающий, возникла ли ошибка в процессе. При успешном выполнении директория, указанная pathPtr, должна быть удалена из файловой системы. Если флаг recursive задан, то не пустая директория должна быть удалена без ошибки. Если этот флаг не задан, то и директория не пустая, должна быть сигналена ошибка POSIX "EEXIST". Если возникает ошибка, имя файла или директории, которая вызвала ошибку, должно быть размещено в errorPtr. DELETEFILEPROC Функция для обработки вызова Tcl_FSDeleteFile. Должна быть реализована, если FS только для чтения. typedef int Tcl_FSDeleteFileProc( Tcl_Obj *pathPtr); Возвращаемое значение - стандартный результат Tcl, указывающий, возникла ли ошибка в процессе. При успешном выполнении файл, указанный pathPtr, должен быть удалён из файловой системы. Обратите внимание, что, если файловая система поддерживает символические ссылки, Tcl всегда будет вызывать эту функцию, а не Tcl_FSRemoveDirectoryProc, когда нужно удалить их (даже если они являются символическими ссылками на директории). ФУНКЦИИ ЭФФЕКТИВНОСТИ ФАЙЛОВОЙ СИСТЕМЫ Эти функции необязательны для реализации в конкретной файловой системе, потому что ядро имеет резервную реализацию. См. описание каждой для последствий оставления поля NULL. LSTATPROC Функция для обработки вызова Tcl_FSLstat. Если не реализована, Tcl попытается использовать statProc, определённую выше. Следовательно, её нужно реализовать только в том случае, если файловая система может различать вызовы stat и lstat. typedef int Tcl_FSLstatProc( Tcl_Obj *pathPtr, Tcl_StatBuf *statPtr); Поведение этой функции очень похоже на то, что у Tcl_FSStatProc, определённой выше, за исключением того, что если она применяется к символической ссылке, она возвращает информацию о ссылке, а не о целевом файле. COPYFILEPROC Функция для обработки вызова Tcl_FSCopyFile. Если не реализована, Tcl вернётся к open-r, open-w и fcopy как механизму копирования. Следовательно, её нужно реализовать только в том случае, если файловая система может выполнить это действие более эффективно. typedef int Tcl_FSCopyFileProc( Tcl_Obj *srcPathPtr, Tcl_Obj *destPathPtr); Возвращаемое значение - стандартный результат Tcl, указывающий, возникла ли ошибка в процессе копирования. Обратите внимание, что destPathPtr - имя файла, который должен стать копией srcPathPtr. Это никогда не имя директории, в которую srcPathPtr мог бы быть скопирован (т.е. функция намного проще, чем подкоманда копирования файла на уровне Tcl). Обратите внимание, что, если файловая система поддерживает символические ссылки, Tcl всегда будет вызывать эту функцию, а не copyDirectoryProc, когда нужно скопировать их (даже если они являются символическими ссылками на директории). Наконец, если файловая система определяет, что не может поддерживать действие копирования файла, вызов Tcl_SetErrno(EXDEV) и возврат не TCL_OK результата скажет Tcl использовать свои стандартные механизмы резервного копирования. RENAMEFILEPROC Функция для обработки вызова Tcl_FSRenameFile. Если не реализована, Tcl вернётся к механизму копирования и удаления. Следовательно, её нужно реализовать только в том случае, если файловая система может выполнить это действие более эффективно. typedef int Tcl_FSRenameFileProc( Tcl_Obj *srcPathPtr, Tcl_Obj *destPathPtr); Возвращаемое значение - стандартный результат Tcl, указывающий, возникла ли ошибка в процессе переименования. Если файловая система определяет, что не может поддерживать действие переименования файла, вызов Tcl_SetErrno(EXDEV) и возврат не TCL_OK результата скажет Tcl использовать свои стандартные механизмы резервного копирования. COPYDIRECTORYPROC Функция для обработки вызова Tcl_FSCopyDirectory. Если не реализована, Tcl вернётся к рекурсивному механизму mkdir, file copy. Следовательно, её нужно реализовать только в том случае, если файловая система может выполнить это действие более эффективно. typedef int Tcl_FSCopyDirectoryProc( Tcl_Obj *srcPathPtr, Tcl_Obj *destPathPtr, Tcl_Obj **errorPtr); Возвращаемое значение - стандартный результат Tcl, указывающий, возникла ли ошибка в процессе копирования. Если возникает ошибка, имя файла или директории, которая вызвала ошибку, должно быть размещено в errorPtr. Обратите внимание, что destPathPtr - имя директории, которая должна стать зеркальным изображением srcPathPtr. Это не имя директории, в которую srcPathPtr должен быть скопирован (т.е. функция намного проще, чем подкоманда копирования файла на уровне Tcl). Наконец, если файловая система определяет, что не может поддерживать действие копирования директории, вызов Tcl_SetErrno(EXDEV) и возврат не TCL_OK результата скажет Tcl использовать свои стандартные механизмы резервного копирования. LOADFILEPROC Функция для обработки вызова Tcl_FSLoadFile. Если не реализована, Tcl вернётся к копированию в родную-temp, за которым следует Tcl_FSLoadFile на этой временной копии. Следовательно, её нужно реализовать только в том случае, если файловая система может загружать код напрямую или если она может быть реализована просто для возврата TCL_ERROR, чтобы отключить функциональность загрузки в этой файловой системе полностью. typedef int Tcl_FSLoadFileProc( Tcl_Interp *interp, Tcl_Obj *pathPtr, Tcl_LoadHandle *handlePtr, Tcl_FSUnloadFileProc *unloadProcPtr); Возвращает стандартный код завершения Tcl. Если возникает ошибка, сообщение об ошибке оставляется в результате interp. Функция динамически загружает двоичный файл кода в память. При успешной загрузке handlePtr должно быть заполнено токеном для динамически загруженного файла, а unloadProcPtr должно быть заполнено адресом процедуры. Процедура выгрузки будет вызвана с данным Tcl_LoadHandle в качестве своего единственного параметра, когда Tcl нужно выгрузить файл. Например, для родной файловой системы, Tcl_LoadHandle, возвращаемый в настоящее время, - токен, который может использоваться в частном TclpFindSymbol для доступа к функциям в новом коде. Каждая файловая система свободна определять Tcl_LoadHandle так, как ей требуется. Наконец, если файловая система определяет, что не может поддерживать действие загрузки файла, вызов Tcl_SetErrno(EXDEV) и возврат не TCL_OK результата скажет Tcl использовать свои стандартные механизмы резервного копирования. UNLOADFILEPROC Функция для выгрузки ранее успешно загруженного файла. Если load реализовано, то это тоже должно быть реализовано, если требуется какое-либо действие очистки. typedef void Tcl_FSUnloadFileProc( Tcl_LoadHandle loadHandle); GETCWDPROC Функция для обработки вызова Tcl_FSGetCwd. Большинству файловых систем не нужно реализовывать это. Она обычно будет вызываться только один раз, если getcwd вызывается перед chdir. Может быть NULL. typedef Tcl_Obj *Tcl_FSGetCwdProc( Tcl_Interp *interp); Если файловая система поддерживает родное понятие текущей рабочей директории (которая может изменяться независимо от Tcl), эта функция должна возвращать эту cwd как результат или NULL, если текущую директорию нельзя определить (например, у пользователя нет подходящих прав на директорию cwd). Если возвращается NULL, сообщение об ошибке оставляется в результате interp. CHDIRPROC Функция для обработки вызова Tcl_FSChdir. Если файловые системы не реализуют это, оно будет эмулировано серией проверок доступа к директории. В противном случае виртуальные файловые системы, которые реализуют это, должны только ответить положительным результатом возврата, если pathPtr - допустимая, доступная директория в их файловой системе. Им не нужно запоминать результат, так как он будет автоматически запомнен для использования Tcl_FSGetCwd. Реальные файловые системы должны выполнять правильное действие (т.е. вызывать правильный системный API chdir). typedef int Tcl_FSChdirProc( Tcl_Obj *pathPtr); Tcl_FSChdirProc изменяет текущую рабочую директорию приложения на значение, указанное в pathPtr. Функция возвращает -1 при ошибке или 0 при успехе. SEE ALSO cd(n), file(n), filename(n), load(n), open(n), pwd(n), source(n), unload(n) KEYWORDS stat, access, filesystem, vfs, virtual filesystem
Filesystem(3) Tcl Library Procedures Filesystem(3) ______________________________________________________________________________ NAME Tcl_FSRegister, Tcl_FSUnregister, Tcl_FSData, Tcl_FSMountsChanged, Tcl_FSGetFileSystemForPath, Tcl_FSGetPathType, Tcl_FSCopyFile, Tcl_FS‐ CopyDirectory, Tcl_FSCreateDirectory, Tcl_FSDeleteFile, Tcl_FSRemoveDi‐ rectory, Tcl_FSRenameFile, Tcl_FSListVolumes, Tcl_FSEvalFile, Tcl_FSE‐ valFileEx, Tcl_FSLoadFile, Tcl_FSUnloadFile, Tcl_FSMatchInDirectory, Tcl_FSLink, Tcl_FSLstat, Tcl_FSUtime, Tcl_FSFileAttrsGet, Tcl_FSFileAt‐ trsSet, Tcl_FSFileAttrStrings, Tcl_FSStat, Tcl_FSAccess, Tcl_FSOpen‐ FileChannel, Tcl_FSGetCwd, Tcl_FSChdir, Tcl_FSPathSeparator, Tcl_FSJoinPath, Tcl_FSSplitPath, Tcl_FSEqualPaths, Tcl_FSGetNormalized‐ Path, Tcl_FSJoinToPath, Tcl_FSConvertToPathType, Tcl_FSGetInternalRep, Tcl_FSGetTranslatedPath, Tcl_FSGetTranslatedStringPath, Tcl_FSNewNa‐ tivePath, Tcl_FSGetNativePath, Tcl_FSFileSystemInfo, Tcl_GetAccessTime‐ FromStat, Tcl_GetBlockSizeFromStat, Tcl_GetBlocksFromStat, Tcl_GetChangeTimeFromStat, Tcl_GetDeviceTypeFromStat, Tcl_GetFSDevice‐ FromStat, Tcl_GetFSInodeFromStat, Tcl_GetGroupIdFromStat, Tcl_GetLinkCountFromStat, Tcl_GetModeFromStat, Tcl_GetModificationTime‐ FromStat, Tcl_GetSizeFromStat, Tcl_GetUserIdFromStat, Tcl_AllocStatBuf - procedures to interact with any filesystem SYNOPSIS #include <tcl.h> int Tcl_FSRegister(clientData, fsPtr) int Tcl_FSUnregister(fsPtr) void * Tcl_FSData(fsPtr) Tcl_FSMountsChanged(fsPtr) const Tcl_Filesystem * Tcl_FSGetFileSystemForPath(pathPtr) Tcl_PathType Tcl_FSGetPathType(pathPtr) int Tcl_FSCopyFile(srcPathPtr, destPathPtr) int Tcl_FSCopyDirectory(srcPathPtr, destPathPtr, errorPtr) int Tcl_FSCreateDirectory(pathPtr) int Tcl_FSDeleteFile(pathPtr) int Tcl_FSRemoveDirectory(pathPtr, recursive, errorPtr) int Tcl_FSRenameFile(srcPathPtr, destPathPtr) Tcl_Obj * Tcl_FSListVolumes(void) int Tcl_FSEvalFileEx(interp, pathPtr, encodingName) int Tcl_FSEvalFile(interp, pathPtr) int Tcl_FSLoadFile(interp, pathPtr, sym1, sym2, proc1Ptr, proc2Ptr, loadHandlePtr, unloadProcPtr) int │ Tcl_FSUnloadFile(interp, loadHandle) │ int Tcl_FSMatchInDirectory(interp, resultPtr, pathPtr, pattern, types) Tcl_Obj * Tcl_FSLink(linkNamePtr, toPtr, linkAction) int Tcl_FSLstat(pathPtr, statPtr) int Tcl_FSUtime(pathPtr, tval) int Tcl_FSFileAttrsGet(interp, index, pathPtr, objPtrRef) int Tcl_FSFileAttrsSet(interp, index, pathPtr, objPtr) const char *const * Tcl_FSFileAttrStrings(pathPtr, objPtrRef) int Tcl_FSStat(pathPtr, statPtr) int Tcl_FSAccess(pathPtr, mode) Tcl_Channel Tcl_FSOpenFileChannel(interp, pathPtr, modeString, permissions) Tcl_Obj * Tcl_FSGetCwd(interp) int Tcl_FSChdir(pathPtr) Tcl_Obj * Tcl_FSPathSeparator(pathPtr) Tcl_Obj * Tcl_FSJoinPath(listObj, elements) Tcl_Obj * Tcl_FSSplitPath(pathPtr, lenPtr) int Tcl_FSEqualPaths(firstPtr, secondPtr) Tcl_Obj * Tcl_FSGetNormalizedPath(interp, pathPtr) Tcl_Obj * Tcl_FSJoinToPath(basePtr, objc, objv) int Tcl_FSConvertToPathType(interp, pathPtr) void * Tcl_FSGetInternalRep(pathPtr, fsPtr) Tcl_Obj * Tcl_FSGetTranslatedPath(interp, pathPtr) const char * Tcl_FSGetTranslatedStringPath(interp, pathPtr) Tcl_Obj * Tcl_FSNewNativePath(fsPtr, clientData) const void * Tcl_FSGetNativePath(pathPtr) Tcl_Obj * Tcl_FSFileSystemInfo(pathPtr) Tcl_StatBuf * Tcl_AllocStatBuf() Tcl_WideInt │ Tcl_GetAccessTimeFromStat(statPtr) │ unsigned │ Tcl_GetBlockSizeFromStat(statPtr) │ Tcl_WideUInt │ Tcl_GetBlocksFromStat(statPtr) │ Tcl_WideInt │ Tcl_GetChangeTimeFromStat(statPtr) │ int │ Tcl_GetDeviceTypeFromStat(statPtr) │ unsigned │ Tcl_GetFSDeviceFromStat(statPtr) │ unsigned │ Tcl_GetFSInodeFromStat(statPtr) │ int │ Tcl_GetGroupIdFromStat(statPtr) │ int │ Tcl_GetLinkCountFromStat(statPtr) │ unsigned │ Tcl_GetModeFromStat(statPtr) │ Tcl_WideInt │ Tcl_GetModificationTimeFromStat(statPtr) │ Tcl_WideUInt │ Tcl_GetSizeFromStat(statPtr) │ int │ Tcl_GetUserIdFromStat(statPtr) │ ARGUMENTS const Tcl_Filesystem *fsPtr (in) Points to a structure con‐ taining the addresses of procedures that can be called to perform the vari‐ ous filesystem operations. Tcl_Obj *pathPtr (in) The path represented by this value is used for the operation in question. If the value does not already have an internal path rep‐ resentation, it will be converted to have one. Tcl_Obj *srcPathPtr (in) As for pathPtr, but used for the source file for a copy or rename operation. Tcl_Obj *destPathPtr (in) As for pathPtr, but used for the destination file‐ name for a copy or rename operation. int recursive (in) Whether to remove subdirec‐ tories and their contents as well. const char *encodingName (in) The encoding of the data stored in the file identi‐ fied by pathPtr and to be evaluated. const char *pattern (in) Only files or directories matching this pattern will be returned. Tcl_GlobTypeData *types (in) Only files or directories matching the type descrip‐ tions contained in this structure will be returned. This parameter may be NULL. Tcl_Interp *interp (in) Interpreter to use either for results, evaluation, or reporting error messages. void *clientData (in) The native description of the path value to create. Tcl_Obj *firstPtr (in) The first of two path val‐ ues to compare. The value may be converted to path type. Tcl_Obj *secondPtr (in) The second of two path val‐ ues to compare. The value may be converted to path type. Tcl_Obj *listObj (in) The list of path elements to operate on with a join operation. int elements (in) The number of elements in the listObj which should be joined together. If nega‐ tive, then all elements are joined. Tcl_Obj **errorPtr (out) In the case of an error, filled with a value con‐ taining the name of the file which caused an error in the various copy/rename operations. int index (in) The index of the attribute in question. Tcl_Obj *objPtr (in) The value to set in the op‐ eration. Tcl_Obj **objPtrRef (out) Filled with a value con‐ taining the result of the operation. Tcl_Obj *resultPtr (out) Preallocated value in which to store (using Tcl_ListOb‐ jAppendElement) the list of files or directories which are successfully matched. int mode (in) Mask consisting of one or more of R_OK, W_OK, X_OK and F_OK. R_OK, W_OK and X_OK request checking whether the file exists and has read, write and exe‐ cute permissions, respec‐ tively. F_OK just requests checking for the existence of the file. Tcl_StatBuf *statPtr (out) The structure that contains the result of a stat or lstat operation. const char *sym1 (in) Name of a procedure to look up in the file's symbol ta‐ ble const char *sym2 (in) Name of a procedure to look up in the file's symbol ta‐ ble Tcl_PackageInitProc **proc1Ptr (out) Filled with the init func‐ tion for this code. Tcl_PackageInitProc **proc2Ptr (out) Filled with the safe-init function for this code. void **clientDataPtr (out) Filled with the clientData value to pass to this code's unload function when it is called. Tcl_LoadHandle *loadHandlePtr (out) Filled with an abstract to‐ ken representing the loaded file. Tcl_FSUnloadFileProc **unloadProcPtr (out) Filled with the function to use to unload this piece of code. Tcl_LoadHandle loadHandle (in) Handle to the loaded li‐ brary to be unloaded. utimbuf *tval (in) The access and modification times in this structure are read and used to set those values for a given file. const char *modeString (in) Specifies how the file is to be accessed. May have any of the values allowed for the mode argument to the Tcl open command. int permissions (in) POSIX-style permission flags such as 0644. If a new file is created, these permissions will be set on the created file. int *lenPtr (out) If non-NULL, filled with the number of elements in the split path. Tcl_Obj *basePtr (in) The base path on to which to join the given elements. May be NULL. int objc (in) The number of elements in objv. Tcl_Obj *const objv[] (in) The elements to join to the given base path. Tcl_Obj *linkNamePtr (in) The name of the link to be created or read. Tcl_Obj *toPtr (in) What the link called linkNamePtr should be linked to, or NULL if the symbolic link specified by linkNamePtr is to be read. int linkAction (in) OR-ed combination of flags indicating what kind of link should be created (will be ignored if toPtr is NULL). Valid bits to set are TCL_CREATE_SYM‐ BOLIC_LINK and TCL_CRE‐ ATE_HARD_LINK. When both flags are set and the un‐ derlying filesystem can do either, symbolic links are preferred. ______________________________________________________________________________ DESCRIPTION There are several reasons for calling the Tcl_FS API functions (e.g. Tcl_FSAccess and Tcl_FSStat) rather than calling system level functions like access and stat directly. First, they will work cross- platform, so an extension which calls them should work unmodified on Unix and Windows. Second, the Windows implementation of some of these functions fixes some bugs in the system level calls. Third, these func‐ tion calls deal with any “Utf to platform-native” path conversions which may be required (and may cache the results of such conversions for greater efficiency on subsequent calls). Fourth, and perhaps most importantly, all of these functions are “virtual filesystem aware”. Any virtual filesystem (VFS for short) which has been registered (through Tcl_FSRegister) may reroute file access to alternative media or access methods. This means that all of these functions (and there‐ fore the corresponding file, glob, pwd, cd, open, etc. Tcl commands) may be operate on “files” which are not native files in the native filesystem. This also means that any Tcl extension which accesses the filesystem (FS for short) through this API is automatically “virtual filesystem aware”. Of course, if an extension accesses the native filesystem directly (through platform-specific APIs, for example), then Tcl cannot intercept such calls. If appropriate VFSes have been registered, the “files” may, to give two examples, be remote (e.g. situated on a remote ftp server) or archived (e.g. lying inside a .zip archive). Such registered filesystems provide a lookup table of functions to implement all or some of the functional‐ ity listed here. Finally, the Tcl_FSStat and Tcl_FSLstat calls abstract away from what the “struct stat” buffer is actually declared to be, al‐ lowing the same code to be used both on systems with and systems with‐ out support for files larger than 2GB in size. The Tcl_FS API is Tcl_Obj-ified and may cache internal representations and other path-related strings (e.g. the current working directory). One side-effect of this is that one must not pass in values with a ref‐ erence count of zero to any of these functions. If such calls were han‐ dled, they might result in memory leaks (under some circumstances, the filesystem code may wish to retain a reference to the passed in value, and so one must not assume that after any of these calls return, the value still has a reference count of zero - it may have been incre‐ mented) or in a direct segmentation fault (or other memory access er‐ ror) due to the value being freed part way through the complex value manipulation required to ensure that the path is fully normalized and absolute for filesystem determination. The practical lesson to learn from this is that Tcl_Obj *path = Tcl_NewStringObj(...); Tcl_FSWhatever(path); Tcl_DecrRefCount(path); is wrong, and may cause memory errors. The path must have its reference count incremented before passing it in, or decrementing it. For this reason, values with a reference count of zero are considered not to be valid filesystem paths and calling any Tcl_FS API function with such a value will result in no action being taken. FS API FUNCTIONS Tcl_FSCopyFile attempts to copy the file given by srcPathPtr to the path name given by destPathPtr. If the two paths given lie in the same filesystem (according to Tcl_FSGetFileSystemForPath) then that filesys‐ tem's “copy file” function is called (if it is non-NULL). Otherwise the function returns -1 and sets the errno global C variable to the “EXDEV” POSIX error code (which signifies a “cross-domain link”). Tcl_FSCopyDirectory attempts to copy the directory given by srcPathPtr to the path name given by destPathPtr. If the two paths given lie in the same filesystem (according to Tcl_FSGetFileSystemForPath) then that filesystem's “copy file” function is called (if it is non-NULL). Oth‐ erwise the function returns -1 and sets the errno global C variable to the “EXDEV” POSIX error code (which signifies a “cross-domain link”). Tcl_FSCreateDirectory attempts to create the directory given by pathPtr by calling the owning filesystem's “create directory” function. Tcl_FSDeleteFile attempts to delete the file given by pathPtr by call‐ ing the owning filesystem's “delete file” function. Tcl_FSRemoveDirectory attempts to remove the directory given by pathPtr by calling the owning filesystem's “remove directory” function. Tcl_FSRenameFile attempts to rename the file or directory given by src‐ PathPtr to the path name given by destPathPtr. If the two paths given lie in the same filesystem (according to Tcl_FSGetFileSystemForPath) then that filesystem's “rename file” function is called (if it is non- NULL). Otherwise the function returns -1 and sets the errno global C variable to the “EXDEV” POSIX error code (which signifies a “cross-do‐ main link”). Tcl_FSListVolumes calls each filesystem which has a non-NULL “list vol‐ umes” function and asks them to return their list of root volumes. It accumulates the return values in a list which is returned to the caller (with a reference count of 0). Tcl_FSEvalFileEx reads the file given by pathPtr using the encoding identified by encodingName and evaluates its contents as a Tcl script. It returns the same information as Tcl_EvalObjEx. If encodingName is NULL, the system encoding is used for reading the file contents. If the file could not be read then a Tcl error is returned to describe why the file could not be read. The eofchar for files is “\x1A” (^Z) for all platforms. If you require a “^Z” in code for string comparison, you can use “\x1A”, which will be safely substituted by the Tcl inter‐ preter into “^Z”. Tcl_FSEvalFile is a simpler version of Tcl_FSEval‐ FileEx that always uses the system encoding when reading the file. Tcl_FSLoadFile dynamically loads a binary code file into memory and re‐ turns the addresses of two procedures within that file, if they are de‐ fined. The appropriate function for the filesystem to which pathPtr be‐ longs will be called. If that filesystem does not implement this func‐ tion (most virtual filesystems will not, because of OS limitations in dynamically loading binary code), Tcl will attempt to copy the file to a temporary directory and load that temporary file. Tcl_FSUnloadFile │ reverses the operation, asking for the library indicated by the load‐ │ Handle to be removed from the process. Note that, unlike with the un‐ │ load command, this does not give the library any opportunity to clean │ up. Both the above functions return a standard Tcl completion code. If an error occurs, an error message is left in the interp's result. The token provided via the variable indicated by loadHandlePtr may be │ used with Tcl_FindSymbol. Tcl_FSMatchInDirectory is used by the globbing code to search a direc‐ tory for all files which match a given pattern. The appropriate func‐ tion for the filesystem to which pathPtr belongs will be called. The return value is a standard Tcl result indicating whether an error occurred in globbing. Error messages are placed in interp (unless in‐ terp is NULL, which is allowed), but good results are placed in the re‐ sultPtr given. Note that the glob code implements recursive patterns internally, so this function will only ever be passed simple patterns, which can be matched using the logic of string match. To handle recursion, Tcl will call this function frequently asking only for directories to be re‐ turned. A special case of being called with a NULL pattern indicates that the path needs to be checked only for the correct type. Tcl_FSLink replaces the library version of readlink, and extends it to support the creation of links. The appropriate function for the filesystem to which linkNamePtr belongs will be called. If the toPtr is NULL, a “read link” action is performed. The result is a Tcl_Obj specifying the contents of the symbolic link given by linkNamePtr, or NULL if the link could not be read. The result is owned by the caller, which should call Tcl_DecrRefCount when the result is no longer needed. If the toPtr is not NULL, Tcl should create a link of one of the types passed in in the linkAction flag. This flag is an OR'ed combination of TCL_CREATE_SYMBOLIC_LINK and TCL_CREATE_HARD_LINK. Where a choice exists (i.e. more than one flag is passed in), the Tcl convention is to prefer symbolic links. When a link is successfully created, the return value should be toPtr (which is therefore already owned by the caller). If unsuccessful, NULL is returned. Tcl_FSLstat fills the Tcl_StatBuf structure statPtr with information about the specified file. You do not need any access rights to the file to get this information but you need search rights to all directories named in the path leading to the file. The Tcl_StatBuf structure in‐ cludes info regarding device, inode (always 0 on Windows), privilege mode, nlink (always 1 on Windows), user id (always 0 on Windows), group id (always 0 on Windows), rdev (same as device on Windows), size, last access time, last modification time, and last metadata change time. See PORTABLE STAT RESULT API for a description of how to write portable code to allocate and access the Tcl_StatBuf structure. If path exists, Tcl_FSLstat returns 0 and the stat structure is filled with data. Otherwise, -1 is returned, and no stat info is given. Tcl_FSUtime replaces the library version of utime. This returns 0 on success and -1 on error (as per the utime documenta‐ tion). If successful, the function will update the “atime” and “mtime” values of the file given. Tcl_FSFileAttrsGet implements read access for the hookable file at‐ tributes subcommand. The appropriate function for the filesystem to which pathPtr belongs will be called. If the result is TCL_OK, then a value was placed in objPtrRef, which will only be temporarily valid (unless Tcl_IncrRefCount is called). Tcl_FSFileAttrsSet implements write access for the hookable file at‐ tributes subcommand. The appropriate function for the filesystem to which pathPtr belongs will be called. Tcl_FSFileAttrStrings implements part of the hookable file attributes subcommand. The appropriate function for the filesystem to which path‐ Ptr belongs will be called. The called procedure may either return an array of strings, or may in‐ stead return NULL and place a Tcl list into the given objPtrRef. Tcl will take that list and first increment its reference count before us‐ ing it. On completion of that use, Tcl will decrement its reference count. Hence if the list should be disposed of by Tcl when done, it should have a reference count of zero, and if the list should not be disposed of, the filesystem should ensure it retains a reference count to the value. Tcl_FSAccess checks whether the process would be allowed to read, write or test for existence of the file (or other filesystem object) whose name is pathname. If pathname is a symbolic link on Unix, then permis‐ sions of the file referred by this symbolic link are tested. On success (all requested permissions granted), zero is returned. On error (at least one bit in mode asked for a permission that is denied, or some other error occurred), -1 is returned. Tcl_FSStat fills the Tcl_StatBuf structure statPtr with information about the specified file. You do not need any access rights to the file to get this information but you need search rights to all directories named in the path leading to the file. The Tcl_StatBuf structure in‐ cludes info regarding device, inode (always 0 on Windows), privilege mode, nlink (always 1 on Windows), user id (always 0 on Windows), group id (always 0 on Windows), rdev (same as device on Windows), size, last access time, last modification time, and last metadata change time. See PORTABLE STAT RESULT API for a description of how to write portable code to allocate and access the Tcl_StatBuf structure. If path exists, Tcl_FSStat returns 0 and the stat structure is filled with data. Otherwise, -1 is returned, and no stat info is given. Tcl_FSOpenFileChannel opens a file specified by pathPtr and returns a channel handle that can be used to perform input and output on the file. This API is modeled after the fopen procedure of the Unix stan‐ dard I/O library. The syntax and meaning of all arguments is similar to those given in the Tcl open command when opening a file. If an er‐ ror occurs while opening the channel, Tcl_FSOpenFileChannel returns NULL and records a POSIX error code that can be retrieved with Tcl_GetErrno. In addition, if interp is non-NULL, Tcl_FSOpenFileChan‐ nel leaves an error message in interp's result after any error. The newly created channel is not registered in the supplied inter‐ preter; to register it, use Tcl_RegisterChannel. If one of the stan‐ dard channels, stdin, stdout or stderr was previously closed, the act of creating the new channel also assigns it as a replacement for the standard channel. Tcl_FSGetCwd replaces the library version of getcwd. It returns the Tcl library's current working directory. This may be different to the native platform's working directory, which happens when the current working directory is not in the native filesystem. The result is a pointer to a Tcl_Obj specifying the current directory, or NULL if the current directory could not be determined. If NULL is returned, an error message is left in the interp's result. The result already has its reference count incremented for the caller. When it is no longer needed, that reference count should be decre‐ mented. This is needed for thread-safety purposes, to allow multiple threads to access this and related functions, while ensuring the re‐ sults are always valid. Tcl_FSChdir replaces the library version of chdir. The path is normal‐ ized and then passed to the filesystem which claims it. If that filesystem does not implement this function, Tcl will fallback to a combination of stat and access to check whether the directory exists and has appropriate permissions. For results, see chdir documentation. If successful, we keep a record of the successful path in cwdPathPtr for subsequent calls to Tcl_FS‐ GetCwd. Tcl_FSPathSeparator returns the separator character to be used for most specific element of the path specified by pathPtr (i.e. the last part of the path). The separator is returned as a Tcl_Obj containing a string of length 1. If the path is invalid, NULL is returned. Tcl_FSJoinPath takes the given Tcl_Obj, which must be a valid list (which is allowed to have a reference count of zero), and returns the path value given by considering the first elements elements as valid path segments (each path segment may be a complete path, a partial path or just a single possible directory or file name). If any path segment is actually an absolute path, then all prior path segments are dis‐ carded. If elements is less than 0, we use the entire list. It is possible that the returned value is actually an element of the given list, so the caller should be careful to increment the reference count of the result before freeing the list. The returned value, typically with a reference count of zero (but it could be shared under some conditions), contains the joined path. The caller must add a reference count to the value before using it. In par‐ ticular, the returned value could be an element of the given list, so freeing the list might free the value prematurely if no reference count has been taken. If the number of elements is zero, then the returned value will be an empty-string Tcl_Obj. Tcl_FSSplitPath takes the given Tcl_Obj, which should be a valid path, and returns a Tcl list value containing each segment of that path as an element. It returns a list value with a reference count of zero. If the passed in lenPtr is non-NULL, the variable it points to will be up‐ dated to contain the number of elements in the returned list. Tcl_FSEqualPaths tests whether the two paths given represent the same filesystem object. It returns 1 if the paths are equal, and 0 if they are different. If either path is NULL, 0 is always returned. Tcl_FSGetNormalizedPath attempts to extract from the given Tcl_Obj a unique normalized path representation, whose string value can be used as a unique identifier for the file. It returns the normalized path value, owned by Tcl, or NULL if the path was invalid or could otherwise not be successfully converted. Extrac‐ tion of absolute, normalized paths is very efficient (because the filesystem operates on these representations internally), although the result when the filesystem contains numerous symbolic links may not be the most user-friendly version of a path. The return value is owned by Tcl and has a lifetime equivalent to that of the pathPtr passed in (un‐ less that is a relative path, in which case the normalized path value may be freed any time the cwd changes) - the caller can of course in‐ crement the reference count if it wishes to maintain a copy for longer. Tcl_FSJoinToPath takes the given value, which should usually be a valid path or NULL, and joins onto it the array of paths segments given. Returns a value, typically with reference count of zero (but it could be shared under some conditions), containing the joined path. The caller must add a reference count to the value before using it. If any of the values passed into this function (pathPtr or path elements) have a reference count of zero, they will be freed when this function re‐ turns. Tcl_FSConvertToPathType tries to convert the given Tcl_Obj to a valid Tcl path type, taking account of the fact that the cwd may have changed even if this value is already supposedly of the correct type. The filename may begin with “~” (to indicate current user's home directory) or “~<user>” (to indicate any user's home directory). If the conversion succeeds (i.e. the value is a valid path in one of the current filesystems), then TCL_OK is returned. Otherwise TCL_ERROR is returned, and an error message may be left in the interpreter. Tcl_FSGetInternalRep extracts the internal representation of a given path value, in the given filesystem. If the path value belongs to a different filesystem, we return NULL. If the internal representation is currently NULL, we attempt to generate it, by calling the filesystem's Tcl_FSCreateInternalRepProc. Returns NULL or a valid internal path representation. This internal representation is cached, so that repeated calls to this function will not require additional conversions. Tcl_FSGetTranslatedPath attempts to extract the translated path from the given Tcl_Obj. If the translation succeeds (i.e. the value is a valid path), then it is returned. Otherwise NULL will be returned, and an error message may be left in the interpreter. A “translated” path is one which contains no “~” or “~user” sequences (these have been expanded to their current representation in the filesystem). The value returned is owned by the caller, which must store it or call Tcl_DecrRefCount to ensure memory is freed. This function is of little practical use, and Tcl_FSGetNor‐ malizedPath or Tcl_FSGetNativePath are usually better functions to use for most purposes. Tcl_FSGetTranslatedStringPath does the same as Tcl_FSGetTranslatedPath, but returns a character string or NULL. The string returned is dynami‐ cally allocated and owned by the caller, which must store it or call ckfree to ensure it is freed. Again, Tcl_FSGetNormalizedPath or Tcl_FS‐ GetNativePath are usually better functions to use for most purposes. Tcl_FSNewNativePath performs something like the reverse of the usual obj->path->nativerep conversions. If some code retrieves a path in na‐ tive form (from, e.g. readlink or a native dialog), and that path is to be used at the Tcl level, then calling this function is an efficient way of creating the appropriate path value type. The resulting value is a pure “path” value, which will only receive a UTF-8 string representation if that is required by some Tcl code. Tcl_FSGetNativePath is for use by the Win/Unix native filesystems, so that they can easily retrieve the native (char* or TCHAR*) representa‐ tion of a path. This function is a convenience wrapper around Tcl_FS‐ GetInternalRep. It may be desirable in the future to have non-string- based native representations (for example, on macOS, a representation using a fileSpec of FSRef structure would probably be more efficient). On Windows a full Unicode representation would allow for paths of un‐ limited length. Currently the representation is simply a character string which may contain either the relative path or a complete, abso‐ lute normalized path in the native encoding (complex conditions dictate which of these will be provided, so neither can be relied upon, unless the path is known to be absolute). If you need a native path which must be absolute, then you should ask for the native version of a normalized path. If for some reason a non-absolute, non-normalized version of the path is needed, that must be constructed separately (e.g. using Tcl_FS‐ GetTranslatedPath). The native representation is cached so that repeated calls to this function will not require additional conversions. The return value is owned by Tcl and has a lifetime equivalent to that of the pathPtr passed in (unless that is a relative path, in which case the native representation may be freed any time the cwd changes). Tcl_FSFileSystemInfo returns a list of two elements. The first element is the name of the filesystem (e.g. “native”, “vfs”, “zip”, or “prowrap”, perhaps), and the second is the particular type of the given path within that filesystem (which is filesystem dependent). The second element may be empty if the filesystem does not provide a further cate‐ gorization of files. A valid list value is returned, unless the path value is not recog‐ nized, when NULL will be returned. Tcl_FSGetFileSystemForPath returns a pointer to the Tcl_Filesystem which accepts this path as valid. If no filesystem will accept the path, NULL is returned. Tcl_FSGetPathType determines whether the given path is relative to the current directory, relative to the current volume, or absolute. It returns one of TCL_PATH_ABSOLUTE, TCL_PATH_RELATIVE, or TCL_PATH_VOLUME_RELATIVE PORTABLE STAT RESULT API Tcl_AllocStatBuf allocates a Tcl_StatBuf on the system heap (which may be deallocated by being passed to ckfree). This allows extensions to invoke Tcl_FSStat and Tcl_FSLstat without being dependent on the size of the buffer. That in turn depends on the flags used to build Tcl. The portable fields of a Tcl_StatBuf may be read using the following │ functions, each of which returns the value of the corresponding field │ listed in the table below. Note that on some platforms there may be │ other fields in the Tcl_StatBuf as it is an alias for a suitable system │ structure, but only the portable ones are made available here. See your │ system documentation for a full description of these fields. │ Access Function Field │ Tcl_GetFSDeviceFromStat st_dev │ Tcl_GetFSInodeFromStat st_ino │ Tcl_GetModeFromStat st_mode │ Tcl_GetLinkCountFromStat st_nlink │ Tcl_GetUserIdFromStat st_uid │ Tcl_GetGroupIdFromStat st_gid │ Tcl_GetDeviceTypeFromStat st_rdev │ Tcl_GetAccessTimeFromStat st_atime │ Tcl_GetModificationTimeFromStat st_mtime │ Tcl_GetChangeTimeFromStat st_ctime │ Tcl_GetSizeFromStat st_size │ Tcl_GetBlocksFromStat st_blocks │ Tcl_GetBlockSizeFromStat st_blksize │ THE VIRTUAL FILESYSTEM API A filesystem provides a Tcl_Filesystem structure that contains pointers to functions that implement the various operations on a filesystem; these operations are invoked as needed by the generic layer, which gen‐ erally occurs through the functions listed above. The Tcl_Filesystem structures are manipulated using the following meth‐ ods. Tcl_FSRegister takes a pointer to a filesystem structure and an op‐ tional piece of data to associated with that filesystem. On calling this function, Tcl will attach the filesystem to the list of known filesystems, and it will become fully functional immediately. Tcl does not check if the same filesystem is registered multiple times (and in general that is not a good thing to do). TCL_OK will be returned. Tcl_FSUnregister removes the given filesystem structure from the list of known filesystems, if it is known, and returns TCL_OK. If the filesystem is not currently registered, TCL_ERROR is returned. Tcl_FSData will return the clientData associated with the given filesystem, if that filesystem is registered. Otherwise it will return NULL. Tcl_FSMountsChanged is used to inform the Tcl's core that the set of mount points for the given (already registered) filesystem have changed, and that cached file representations may therefore no longer be correct. THE TCL_FILESYSTEM STRUCTURE The Tcl_Filesystem structure contains the following fields: typedef struct Tcl_Filesystem { const char *typeName; int structureLength; Tcl_FSVersion version; Tcl_FSPathInFilesystemProc *pathInFilesystemProc; Tcl_FSDupInternalRepProc *dupInternalRepProc; Tcl_FSFreeInternalRepProc *freeInternalRepProc; Tcl_FSInternalToNormalizedProc *internalToNormalizedProc; Tcl_FSCreateInternalRepProc *createInternalRepProc; Tcl_FSNormalizePathProc *normalizePathProc; Tcl_FSFilesystemPathTypeProc *filesystemPathTypeProc; Tcl_FSFilesystemSeparatorProc *filesystemSeparatorProc; Tcl_FSStatProc *statProc; Tcl_FSAccessProc *accessProc; Tcl_FSOpenFileChannelProc *openFileChannelProc; Tcl_FSMatchInDirectoryProc *matchInDirectoryProc; Tcl_FSUtimeProc *utimeProc; Tcl_FSLinkProc *linkProc; Tcl_FSListVolumesProc *listVolumesProc; Tcl_FSFileAttrStringsProc *fileAttrStringsProc; Tcl_FSFileAttrsGetProc *fileAttrsGetProc; Tcl_FSFileAttrsSetProc *fileAttrsSetProc; Tcl_FSCreateDirectoryProc *createDirectoryProc; Tcl_FSRemoveDirectoryProc *removeDirectoryProc; Tcl_FSDeleteFileProc *deleteFileProc; Tcl_FSCopyFileProc *copyFileProc; Tcl_FSRenameFileProc *renameFileProc; Tcl_FSCopyDirectoryProc *copyDirectoryProc; Tcl_FSLstatProc *lstatProc; Tcl_FSLoadFileProc *loadFileProc; Tcl_FSGetCwdProc *getCwdProc; Tcl_FSChdirProc *chdirProc; } Tcl_Filesystem; Except for the first three fields in this structure which contain sim‐ ple data elements, all entries contain addresses of functions called by the generic filesystem layer to perform the complete range of filesys‐ tem related actions. The many functions in this structure are broken down into three cate‐ gories: infrastructure functions (almost all of which must be imple‐ mented), operational functions (which must be implemented if a complete filesystem is provided), and efficiency functions (which need only be implemented if they can be done so efficiently, or if they have side- effects which are required by the filesystem; Tcl has less efficient emulations it can fall back on). It is important to note that, in the current version of Tcl, most of these fallbacks are only used to handle commands initiated in Tcl, not in C. What this means is, that if a file rename command is issued in Tcl, and the relevant filesystem(s) do not implement their Tcl_FSRenameFileProc, Tcl's core will instead fallback on a combination of other filesystem functions (it will use Tcl_FSCopy‐ FileProc followed by Tcl_FSDeleteFileProc, and if Tcl_FSCopyFileProc is not implemented there is a further fallback). However, if a Tcl_FSRe‐ nameFileProc command is issued at the C level, no such fallbacks occur. This is true except for the last four entries in the filesystem table (lstat, load, getcwd and chdir) for which fallbacks do in fact occur at the C level. Any functions which take path names in Tcl_Obj form take those names in UTF-8 form. The filesystem infrastructure API is designed to support efficient, cached conversion of these UTF-8 paths to other native rep‐ resentations. EXAMPLE FILESYSTEM DEFINITION Here is the filesystem lookup table used by the “vfs” extension which allows filesystem actions to be implemented in Tcl. static Tcl_Filesystem vfsFilesystem = { "tclvfs", sizeof(Tcl_Filesystem), TCL_FILESYSTEM_VERSION_1, &VfsPathInFilesystem, &VfsDupInternalRep, &VfsFreeInternalRep, /* No internal to normalized, since we don't create * any pure 'internal' Tcl_Obj path representations */ NULL, /* No create native rep function, since we don't use * it and don't choose to support uses of * Tcl_FSNewNativePath */ NULL, /* Normalize path isn't needed - we assume paths only * have one representation */ NULL, &VfsFilesystemPathType, &VfsFilesystemSeparator, &VfsStat, &VfsAccess, &VfsOpenFileChannel, &VfsMatchInDirectory, &VfsUtime, /* We choose not to support symbolic links inside our * VFS's */ NULL, &VfsListVolumes, &VfsFileAttrStrings, &VfsFileAttrsGet, &VfsFileAttrsSet, &VfsCreateDirectory, &VfsRemoveDirectory, &VfsDeleteFile, /* No copy file; use the core fallback mechanism */ NULL, /* No rename file; use the core fallback mechanism */ NULL, /* No copy directory; use the core fallback mechanism */ NULL, /* Core will use stat for lstat */ NULL, /* No load; use the core fallback mechanism */ NULL, /* We don't need a getcwd or chdir; the core's own * internal value is suitable */ NULL, NULL }; FILESYSTEM INFRASTRUCTURE These fields contain basic information about the filesystem structure and addresses of functions which are used to associate a particular filesystem with a file path, and deal with the internal handling of path representations, for example copying and freeing such representa‐ tions. TYPENAME The typeName field contains a null-terminated string that identifies the type of the filesystem implemented, e.g. “native”, “zip” or “vfs”. STRUCTURE LENGTH The structureLength field is generally implemented as sizeof(Tcl_Filesystem), and is there to allow easier binary backwards compatibility if the size of the structure changes in a future Tcl re‐ lease. VERSION The version field should be set to TCL_FILESYSTEM_VERSION_1. PATHINFILESYSTEMPROC The pathInFilesystemProc field contains the address of a function which is called to determine whether a given path value belongs to this filesystem or not. Tcl will only call the rest of the filesystem func‐ tions with a path for which this function has returned TCL_OK. If the path does not belong, -1 should be returned (the behavior of Tcl for any other return value is not defined). If TCL_OK is returned, then the optional clientDataPtr output parameter can be used to return an inter‐ nal (filesystem specific) representation of the path, which will be cached inside the path value, and may be retrieved efficiently by the other filesystem functions. Tcl will simultaneously cache the fact that this path belongs to this filesystem. Such caches are invalidated when filesystem structures are added or removed from Tcl's internal list of known filesystems. typedef int Tcl_FSPathInFilesystemProc( Tcl_Obj *pathPtr, ClientData *clientDataPtr); DUPINTERNALREPPROC This function makes a copy of a path's internal representation, and is called when Tcl needs to duplicate a path value. If NULL, Tcl will sim‐ ply not copy the internal representation, which may then need to be re‐ generated later. typedef ClientData Tcl_FSDupInternalRepProc( ClientData clientData); FREEINTERNALREPPROC Free the internal representation. This must be implemented if internal representations need freeing (i.e. if some memory is allocated when an internal representation is generated), but may otherwise be NULL. typedef void Tcl_FSFreeInternalRepProc( ClientData clientData); INTERNALTONORMALIZEDPROC Function to convert internal representation to a normalized path. Only required if the filesystem creates pure path values with no string/path representation. The return value is a Tcl value whose string represen‐ tation is the normalized path. typedef Tcl_Obj *Tcl_FSInternalToNormalizedProc( ClientData clientData); CREATEINTERNALREPPROC Function to take a path value, and calculate an internal representation for it, and store that native representation in the value. May be NULL if paths have no internal representation, or if the Tcl_FSPathIn‐ FilesystemProc for this filesystem always immediately creates an inter‐ nal representation for paths it accepts. typedef ClientData Tcl_FSCreateInternalRepProc( Tcl_Obj *pathPtr); NORMALIZEPATHPROC Function to normalize a path. Should be implemented for all filesystems which can have multiple string representations for the same path value. In Tcl, every “path” must have a single unique “normalized” string rep‐ resentation. Depending on the filesystem, there may be more than one unnormalized string representation which refers to that path (e.g. a relative path, a path with different character case if the filesystem is case insensitive, a path contain a reference to a home directory such as “~”, a path containing symbolic links, etc). If the very last component in the path is a symbolic link, it should not be converted into the value it points to (but its case or other aspects should be made unique). All other path components should be converted from sym‐ bolic links. This one exception is required to agree with Tcl's seman‐ tics with file delete, file rename, file copy operating on symbolic links. This function may be called with nextCheckpoint either at the beginning of the path (i.e. zero), at the end of the path, or at any intermediate file separator in the path. It will never point to any other arbitrary position in the path. In the last of the three valid cases, the implementation can assume that the path up to and including the file separator is known and normalized. typedef int Tcl_FSNormalizePathProc( Tcl_Interp *interp, Tcl_Obj *pathPtr, int nextCheckpoint); FILESYSTEM OPERATIONS The fields in this section of the structure contain addresses of func‐ tions which are called to carry out the basic filesystem operations. A filesystem which expects to be used with the complete standard Tcl com‐ mand set must implement all of these. If some of them are not imple‐ mented, then certain Tcl commands may fail when operating on paths within that filesystem. However, in some instances this may be desir‐ able (for example, a read-only filesystem should not implement the last four functions, and a filesystem which does not support symbolic links need not implement the readlink function, etc. The Tcl core expects filesystems to behave in this way). FILESYSTEMPATHTYPEPROC Function to determine the type of a path in this filesystem. May be NULL, in which case no type information will be available to users of the filesystem. The “type” is used only for informational purposes, and should be returned as the string representation of the Tcl_Obj which is returned. A typical return value might be “networked”, “zip” or “ftp”. The Tcl_Obj result is owned by the filesystem and so Tcl will increment the reference count of that value if it wishes to retain a reference to it. typedef Tcl_Obj *Tcl_FSFilesystemPathTypeProc( Tcl_Obj *pathPtr); FILESYSTEMSEPARATORPROC Function to return the separator character(s) for this filesystem. This need only be implemented if the filesystem wishes to use a differ‐ ent separator than the standard string “/”. Amongst other uses, it is returned by the file separator command. The return value should be a value with reference count of zero. typedef Tcl_Obj *Tcl_FSFilesystemSeparatorProc( Tcl_Obj *pathPtr); STATPROC Function to process a Tcl_FSStat call. Must be implemented for any rea‐ sonable filesystem, since many Tcl level commands depend crucially upon it (e.g. file atime, file isdirectory, file size, glob). typedef int Tcl_FSStatProc( Tcl_Obj *pathPtr, Tcl_StatBuf *statPtr); The Tcl_FSStatProc fills the stat structure statPtr with information about the specified file. You do not need any access rights to the file to get this information but you need search rights to all directories named in the path leading to the file. The stat structure includes info regarding device, inode (always 0 on Windows), privilege mode, nlink (always 1 on Windows), user id (always 0 on Windows), group id (always 0 on Windows), rdev (same as device on Windows), size, last access time, last modification time, and last metadata change time. If the file represented by pathPtr exists, the Tcl_FSStatProc returns 0 and the stat structure is filled with data. Otherwise, -1 is returned, and no stat info is given. ACCESSPROC Function to process a Tcl_FSAccess call. Must be implemented for any reasonable filesystem, since many Tcl level commands depend crucially upon it (e.g. file exists, file readable). typedef int Tcl_FSAccessProc( Tcl_Obj *pathPtr, int mode); The Tcl_FSAccessProc checks whether the process would be allowed to read, write or test for existence of the file (or other filesystem ob‐ ject) whose name is in pathPtr. If the pathname refers to a symbolic link, then the permissions of the file referred by this symbolic link should be tested. On success (all requested permissions granted), zero is returned. On error (at least one bit in mode asked for a permission that is denied, or some other error occurred), -1 is returned. OPENFILECHANNELPROC Function to process a Tcl_FSOpenFileChannel call. Must be implemented for any reasonable filesystem, since any operations which require open or accessing a file's contents will use it (e.g. open, encoding, and many Tk commands). typedef Tcl_Channel Tcl_FSOpenFileChannelProc( Tcl_Interp *interp, Tcl_Obj *pathPtr, int mode, int permissions); The Tcl_FSOpenFileChannelProc opens a file specified by pathPtr and re‐ turns a channel handle that can be used to perform input and output on the file. This API is modeled after the fopen procedure of the Unix standard I/O library. The syntax and meaning of all arguments is simi‐ lar to those given in the Tcl open command when opening a file, where the mode argument is a combination of the POSIX flags O_RDONLY, O_WRONLY, etc. If an error occurs while opening the channel, the Tcl_FSOpenFileChannelProc returns NULL and records a POSIX error code that can be retrieved with Tcl_GetErrno. In addition, if interp is non-NULL, the Tcl_FSOpenFileChannelProc leaves an error message in in‐ terp's result after any error. The newly created channel must not be registered in the supplied inter‐ preter by a Tcl_FSOpenFileChannelProc; that task is up to the caller of Tcl_FSOpenFileChannel (if necessary). If one of the standard channels, stdin, stdout or stderr was previously closed, the act of creating the new channel also assigns it as a replacement for the standard channel. MATCHINDIRECTORYPROC Function to process a Tcl_FSMatchInDirectory call. If not implemented, then glob and recursive copy functionality will be lacking in the filesystem (and this may impact commands like encoding names which use glob functionality internally). typedef int Tcl_FSMatchInDirectoryProc( Tcl_Interp *interp, Tcl_Obj *resultPtr, Tcl_Obj *pathPtr, const char *pattern, Tcl_GlobTypeData *types); The function should return all files or directories (or other filesys‐ tem objects) which match the given pattern and accord with the types specification given. There are two ways in which this function may be called. If pattern is NULL, then pathPtr is a full path specification of a single file or directory which should be checked for existence and correct type. Otherwise, pathPtr is a directory, the contents of which the function should search for files or directories which have the cor‐ rect type. In either case, pathPtr can be assumed to be both non-NULL and non-empty. It is not currently documented whether pathPtr will have a file separator at its end of not, so code should be flexible to both possibilities. The return value is a standard Tcl result indicating whether an error occurred in the matching process. Error messages are placed in interp, unless interp in NULL in which case no error message need be generated; on a TCL_OK result, results should be added to the resultPtr value given (which can be assumed to be a valid unshared Tcl list). The matches added to resultPtr should include any path prefix given in pathPtr (this usually means they will be absolute path specifications). Note that if no matches are found, that simply leads to an empty re‐ sult; errors are only signaled for actual file or filesystem problems which may occur during the matching process. The Tcl_GlobTypeData structure passed in the types parameter contains the following fields: typedef struct Tcl_GlobTypeData { /* Corresponds to bcdpfls as in 'find -t' */ int type; /* Corresponds to file permissions */ int perm; /* Acceptable mac type */ Tcl_Obj *macType; /* Acceptable mac creator */ Tcl_Obj *macCreator; } Tcl_GlobTypeData; There are two specific cases which it is important to handle correctly, both when types is non-NULL. The two cases are when types->types & TCL_GLOB_TYPE_DIR or types->types & TCL_GLOB_TYPE_MOUNT are true (and in particular when the other flags are false). In the first of these cases, the function must list the contained directories. Tcl uses this to implement recursive globbing, so it is critical that filesystems im‐ plement directory matching correctly. In the second of these cases, with TCL_GLOB_TYPE_MOUNT, the filesystem must list the mount points which lie within the given pathPtr (and in this case, pathPtr need not lie within the same filesystem - different to all other cases in which this function is called). Support for this is critical if Tcl is to have seamless transitions between from one filesystem to another. UTIMEPROC Function to process a Tcl_FSUtime call. Required to allow setting (not reading) of times with file mtime, file atime and the open-r/open- w/fcopy implementation of file copy. typedef int Tcl_FSUtimeProc( Tcl_Obj *pathPtr, struct utimbuf *tval); The access and modification times of the file specified by pathPtr should be changed to the values given in the tval structure. The return value should be 0 on success and -1 on an error, as with the system utime. LINKPROC Function to process a Tcl_FSLink call. Should be implemented only if the filesystem supports links, and may otherwise be NULL. typedef Tcl_Obj *Tcl_FSLinkProc( Tcl_Obj *linkNamePtr, Tcl_Obj *toPtr, int linkAction); If toPtr is NULL, the function is being asked to read the contents of a link. The result is a Tcl_Obj specifying the contents of the link given by linkNamePtr, or NULL if the link could not be read. The result is owned by the caller (and should therefore have its ref count incre‐ mented before being returned). Any callers should call Tcl_DecrRefCount on this result when it is no longer needed. If toPtr is not NULL, the function should attempt to create a link. The result in this case should be toPtr if the link was successful and NULL otherwise. In this case the result is not owned by the caller (i.e. no reference count ma‐ nipulations on either end are needed). See the documentation for Tcl_FSLink for the correct interpretation of the linkAction flags. LISTVOLUMESPROC Function to list any filesystem volumes added by this filesystem. Should be implemented only if the filesystem adds volumes at the head of the filesystem, so that they can be returned by file volumes. typedef Tcl_Obj *Tcl_FSListVolumesProc(void); The result should be a list of volumes added by this filesystem, or NULL (or an empty list) if no volumes are provided. The result value is considered to be owned by the filesystem (not by Tcl's core), but should be given a reference count for Tcl. Tcl will use the contents of the list and then decrement that reference count. This allows filesys‐ tems to choose whether they actually want to retain a “global list” of volumes or not (if not, they generate the list on the fly and pass it to Tcl with a reference count of 1 and then forget about the list, if yes, then they simply increment the reference count of their global list and pass it to Tcl which will copy the contents and then decrement the count back to where it was). Therefore, Tcl considers return values from this proc to be read-only. FILEATTRSTRINGSPROC Function to list all attribute strings which are valid for this filesystem. If not implemented the filesystem will not support the file attributes command. This allows arbitrary additional information to be attached to files in the filesystem. If it is not implemented, there is no need to implement the get and set methods. typedef const char *const *Tcl_FSFileAttrStringsProc( Tcl_Obj *pathPtr, Tcl_Obj **objPtrRef); The called function may either return an array of strings, or may in‐ stead return NULL and place a Tcl list into the given objPtrRef. Tcl will take that list and first increment its reference count before us‐ ing it. On completion of that use, Tcl will decrement its reference count. Hence if the list should be disposed of by Tcl when done, it should have a reference count of zero, and if the list should not be disposed of, the filesystem should ensure it returns a value with a reference count of at least one. FILEATTRSGETPROC Function to process a Tcl_FSFileAttrsGet call, used by file attributes. typedef int Tcl_FSFileAttrsGetProc( Tcl_Interp *interp, int index, Tcl_Obj *pathPtr, Tcl_Obj **objPtrRef); Returns a standard Tcl return code. The attribute value retrieved, which corresponds to the index'th element in the list returned by the Tcl_FSFileAttrStringsProc, is a Tcl_Obj placed in objPtrRef (if TCL_OK was returned) and is likely to have a reference count of zero. Either way we must either store it somewhere (e.g. the Tcl result), or Incr/Decr its reference count to ensure it is properly freed. FILEATTRSSETPROC Function to process a Tcl_FSFileAttrsSet call, used by file attributes. If the filesystem is read-only, there is no need to implement this. typedef int Tcl_FSFileAttrsSetProc( Tcl_Interp *interp, int index, Tcl_Obj *pathPtr, Tcl_Obj *objPtr); The attribute value of the index'th element in the list returned by the Tcl_FSFileAttrStringsProc should be set to the objPtr given. CREATEDIRECTORYPROC Function to process a Tcl_FSCreateDirectory call. Should be implemented unless the FS is read-only. typedef int Tcl_FSCreateDirectoryProc( Tcl_Obj *pathPtr); The return value is a standard Tcl result indicating whether an error occurred in the process. If successful, a new directory should have been added to the filesystem in the location specified by pathPtr. REMOVEDIRECTORYPROC Function to process a Tcl_FSRemoveDirectory call. Should be implemented unless the FS is read-only. typedef int Tcl_FSRemoveDirectoryProc( Tcl_Obj *pathPtr, int recursive, Tcl_Obj **errorPtr); The return value is a standard Tcl result indicating whether an error occurred in the process. If successful, the directory specified by pathPtr should have been removed from the filesystem. If the recursive flag is given, then a non-empty directory should be deleted without er‐ ror. If this flag is not given, then and the directory is non-empty a POSIX “EEXIST” error should be signaled. If an error does occur, the name of the file or directory which caused the error should be placed in errorPtr. DELETEFILEPROC Function to process a Tcl_FSDeleteFile call. Should be implemented un‐ less the FS is read-only. typedef int Tcl_FSDeleteFileProc( Tcl_Obj *pathPtr); The return value is a standard Tcl result indicating whether an error occurred in the process. If successful, the file specified by pathPtr should have been removed from the filesystem. Note that, if the filesystem supports symbolic links, Tcl will always call this function and not Tcl_FSRemoveDirectoryProc when needed to delete them (even if they are symbolic links to directories). FILESYSTEM EFFICIENCY These functions need not be implemented for a particular filesystem be‐ cause the core has a fallback implementation available. See each indi‐ vidual description for the consequences of leaving the field NULL. LSTATPROC Function to process a Tcl_FSLstat call. If not implemented, Tcl will attempt to use the statProc defined above instead. Therefore it need only be implemented if a filesystem can differentiate between stat and lstat calls. typedef int Tcl_FSLstatProc( Tcl_Obj *pathPtr, Tcl_StatBuf *statPtr); The behavior of this function is very similar to that of the Tcl_FSStatProc defined above, except that if it is applied to a sym‐ bolic link, it returns information about the link, not about the target file. COPYFILEPROC Function to process a Tcl_FSCopyFile call. If not implemented Tcl will fall back on open-r, open-w and fcopy as a copying mechanism. There‐ fore it need only be implemented if the filesystem can perform that ac‐ tion more efficiently. typedef int Tcl_FSCopyFileProc( Tcl_Obj *srcPathPtr, Tcl_Obj *destPathPtr); The return value is a standard Tcl result indicating whether an error occurred in the copying process. Note that, destPathPtr is the name of the file which should become the copy of srcPathPtr. It is never the name of a directory into which srcPathPtr could be copied (i.e. the function is much simpler than the Tcl level file copy subcommand). Note that, if the filesystem supports symbolic links, Tcl will always call this function and not copyDirectoryProc when needed to copy them (even if they are symbolic links to directories). Finally, if the filesystem determines it cannot support the file copy action, calling Tcl_SetEr‐ rno(EXDEV) and returning a non-TCL_OK result will tell Tcl to use its standard fallback mechanisms. RENAMEFILEPROC Function to process a Tcl_FSRenameFile call. If not implemented, Tcl will fall back on a copy and delete mechanism. Therefore it need only be implemented if the filesystem can perform that action more effi‐ ciently. typedef int Tcl_FSRenameFileProc( Tcl_Obj *srcPathPtr, Tcl_Obj *destPathPtr); The return value is a standard Tcl result indicating whether an error occurred in the renaming process. If the filesystem determines it can‐ not support the file rename action, calling Tcl_SetErrno(EXDEV) and re‐ turning a non-TCL_OK result will tell Tcl to use its standard fallback mechanisms. COPYDIRECTORYPROC Function to process a Tcl_FSCopyDirectory call. If not implemented, Tcl will fall back on a recursive file mkdir, file copy mechanism. There‐ fore it need only be implemented if the filesystem can perform that ac‐ tion more efficiently. typedef int Tcl_FSCopyDirectoryProc( Tcl_Obj *srcPathPtr, Tcl_Obj *destPathPtr, Tcl_Obj **errorPtr); The return value is a standard Tcl result indicating whether an error occurred in the copying process. If an error does occur, the name of the file or directory which caused the error should be placed in er‐ rorPtr. Note that, destPathPtr is the name of the directory-name which should become the mirror-image of srcPathPtr. It is not the name of a directory into which srcPathPtr should be copied (i.e. the function is much simpler than the Tcl level file copy subcommand). Finally, if the filesystem determines it cannot support the directory copy action, calling Tcl_SetErrno(EXDEV) and returning a non-TCL_OK result will tell Tcl to use its standard fallback mechanisms. LOADFILEPROC Function to process a Tcl_FSLoadFile call. If not implemented, Tcl will fall back on a copy to native-temp followed by a Tcl_FSLoadFile on that temporary copy. Therefore it need only be implemented if the filesystem can load code directly, or it can be implemented simply to return TCL_ERROR to disable load functionality in this filesystem entirely. typedef int Tcl_FSLoadFileProc( Tcl_Interp *interp, Tcl_Obj *pathPtr, Tcl_LoadHandle *handlePtr, Tcl_FSUnloadFileProc *unloadProcPtr); Returns a standard Tcl completion code. If an error occurs, an error message is left in the interp's result. The function dynamically loads a binary code file into memory. On a successful load, the handlePtr should be filled with a token for the dynamically loaded file, and the unloadProcPtr should be filled in with the address of a procedure. The unload procedure will be called with the given Tcl_LoadHandle as its only parameter when Tcl needs to unload the file. For example, for the native filesystem, the Tcl_LoadHandle returned is currently a token which can be used in the private TclpFindSymbol to access functions in the new code. Each filesystem is free to define the Tcl_LoadHandle as it requires. Finally, if the filesystem determines it cannot support the file load action, calling Tcl_SetErrno(EXDEV) and returning a non- TCL_OK result will tell Tcl to use its standard fallback mechanisms. UNLOADFILEPROC Function to unload a previously successfully loaded file. If load was implemented, then this should also be implemented, if there is any cleanup action required. typedef void Tcl_FSUnloadFileProc( Tcl_LoadHandle loadHandle); GETCWDPROC Function to process a Tcl_FSGetCwd call. Most filesystems need not im‐ plement this. It will usually only be called once, if getcwd is called before chdir. May be NULL. typedef Tcl_Obj *Tcl_FSGetCwdProc( Tcl_Interp *interp); If the filesystem supports a native notion of a current working direc‐ tory (which might perhaps change independent of Tcl), this function should return that cwd as the result, or NULL if the current directory could not be determined (e.g. the user does not have appropriate per‐ missions on the cwd directory). If NULL is returned, an error message is left in the interp's result. CHDIRPROC Function to process a Tcl_FSChdir call. If filesystems do not implement this, it will be emulated by a series of directory access checks. Oth‐ erwise, virtual filesystems which do implement it need only respond with a positive return result if the pathPtr is a valid, accessible di‐ rectory in their filesystem. They need not remember the result, since that will be automatically remembered for use by Tcl_FSGetCwd. Real filesystems should carry out the correct action (i.e. call the correct system chdir API). typedef int Tcl_FSChdirProc( Tcl_Obj *pathPtr); The Tcl_FSChdirProc changes the applications current working directory to the value specified in pathPtr. The function returns -1 on error or 0 on success. SEE ALSO cd(n), file(n), filename(n), load(n), open(n), pwd(n), source(n), un‐ load(n) KEYWORDS stat, access, filesystem, vfs, virtual filesystem Tcl 8.4 Filesystem(3)
Tcl_SplitList(3) Tcl Library Procedures Tcl_SplitList(3) ______________________________________________________________________________ NAME Tcl_SplitList, Tcl_Merge, Tcl_ScanElement, Tcl_ConvertElement, Tcl_ScanCountedElement, Tcl_ConvertCountedElement - манипулировать списками Tcl SYNOPSIS #include <tcl.h> int Tcl_SplitList(interp, list, argcPtr, argvPtr) char * Tcl_Merge(argc, argv) int Tcl_ScanElement(src, flagsPtr) int Tcl_ScanCountedElement(src, length, flagsPtr) int Tcl_ConvertElement(src, dst, flags) int Tcl_ConvertCountedElement(src, length, dst, flags) ARGUMENTS Tcl_Interp *interp (out) Интерпретатор для использования в отчёте об ошибках. Если NULL, то сообщение об ошибке не оставляется. const char *list (in) Указатель на строку с правильной структурой списка. int *argcPtr (out) Заполняется количеством элементов в списке. const char ***argvPtr (out) *argvPtr будет заполнено адресом массива указателей на строки, которые являются извлечёнными элементами списка. В массиве будет *argcPtr действительных записей, за которыми следует запись NULL. int argc (in) Количество элементов в argv. const char *const *argv (in) Массив строк для объединения в один список. Каждая строка станет отдельным элементом списка. const char *src (in) Строка, которая должна стать элементом списка. int *flagsPtr (in) Указатель на слово для заполнения информацией о src. Значение *flagsPtr должно быть передано в Tcl_ConvertElement. int length (in) Количество байтов в строке src. char *dst (in) Место для копирования преобразованного элемента списка. Должно содержать достаточно символов для хранения преобразованной строки. int flags (in) Информация о src. Должно быть значением, возвращенным предыдущим вызовом Tcl_ScanElement, возможно, объединённым с TCL_DONT_USE_BRACES с помощью операции OR. ______________________________________________________________________________ DESCRIPTION Эти процедуры могут использоваться для разбор и сборки списков Tcl. Tcl_SplitList разбивает список на его составные элементы, возвращая массив указателей на элементы с помощью argcPtr и argvPtr. При извлечении аргументов Tcl_SplitList соблюдает обычные правила для подстановок обратного слэша и фигурных скобок. Область памяти, на которую указывает *argvPtr, динамически выделяется; помимо массива указателей, она также содержит копии всех элементов списка. Ответственность за освобождение этой памяти лежит на вызывающей стороне. Например, предположим, что вы вызвали Tcl_SplitList с следующим кодом: int argc, code; char *string; char **argv; ... code = Tcl_SplitList(interp, string, &argc, &argv); Затем вы должны в конечном итоге освободить память с вызовом вроде следующего: Tcl_Free((char *) argv); Tcl_SplitList обычно возвращает TCL_OK, что означает, что список был успешно разобра. Если в списке была синтаксическая ошибка, то возвращается TCL_ERROR, и результат интерпретатора укажет на сообщение об ошибке, описывающее проблему (если interp не было NULL). Если возвращается TCL_ERROR, то память не выделяется и *argvPtr не изменяется. Tcl_Merge является обратной операцией Tcl_SplitList: она принимает коллекцию строк, заданных argc и argv, и генерирует результирующую строку с правильной структурой списка. Это означает, что команды вроде index могут использоваться для извлечения исходных элементов снова. Кроме того, если результат Tcl_Merge передать в Tcl_Eval, он будет разобра в argc слов, значения которых будут такими же, как строки argv, переданные в Tcl_Merge. Tcl_Merge модифицирует элементы списка с помощью фигурных скобок и/или обратных слэшей для получения правильной структуры списка Tcl. Результирующая строка динамически выделяется с помощью Tcl_Alloc; вызывающая сторона должна в конечном итоге освободить пространство с помощью Tcl_Free. Если результат Tcl_Merge передать в Tcl_SplitList, элементы, возвращенные Tcl_SplitList, будут идентичны тем, которые были переданы в Tcl_Merge. Однако обратное неверно: если Tcl_SplitList передать данную строку, а полученные argc и argv передать в Tcl_Merge, результирующая строка может отличаться от исходной строки, переданной в Tcl_SplitList. Это потому, что Tcl_Merge может использовать обратные слэши и фигурные скобки по-другому, чем исходная строка. Tcl_ScanElement и Tcl_ConvertElement являются процедурами, которые выполняют всю реальную работу Tcl_Merge. Tcl_ScanElement сканирует свой аргумент src и определяет, как использовать обратные слэши и фигурные скобки при преобразовании в элемент списка. Она возвращает завышенную оценку количества символов, необходимых для представления src в качестве элемента списка, и сохраняет информацию в *flagsPtr, которая нужна Tcl_ConvertElement. Tcl_ConvertElement является дополнительной процедурой к Tcl_ScanElement. Она выполняет фактическую работу по преобразованию строки в элемент списка. Её аргумент flags должен быть таким же, как значение, возвращенное Tcl_ScanElement. Tcl_ConvertElement записывает правильный элемент списка в память, начиная с *dst, и возвращает счётчик общего количества записанных символов, который не превысит результата, возвращенного Tcl_ScanElement. Tcl_ConvertElement записывает только сам элемент списка без каких-либо начальных или конечных пробелов: на вызывающей стороне лежит обязанность включить пробелы между соседними элементами списка. Tcl_ConvertElement использует один из двух разных подходов для обработки специальных символов в src. Везде, где возможно, она обрабатывает специальные символы, окружа строк с фигурными скобками. Это производит чистый вид вывода, но не может использоваться в некоторых ситуациях, таких как когда src содержит несовпадающие фигурные скобки. В этих ситуациях Tcl_ConvertElement обрабатывает специальные символы, генерируя последовательности обратного слэша для них. Вызывающая сторона может настаивать на втором подходе, объединяя значение флага, возвращенное Tcl_ScanElement, с TCL_DONT_USE_BRACES. Хотя это приведёт к менее красивому результату, это полезно в некоторых специальных ситуациях, таких как когда Tcl_ConvertElement используется для генерации части аргумента для команды Tcl. В этом случае, окружение src фигурными скобками вызовет неправильный разбор команды. По умолчанию, Tcl_ConvertElement будет использовать экранирование в своём выводе, чтобы убедиться, что первый символ элемента не является символом хэша (“#”). Это для того, чтобы убедиться, что первый элемент любого списка, переданного в eval, не будет неправильно разобран как начало комментария. Когда элемент списка не является первым элементом списка, такое экранирование не обязательно. Когда вызывающая сторона может быть уверена, что элемент не является первым элементом списка, она может отключить экранирование начального символа хэша, объединяя значение флага, возвращенное Tcl_ScanElement, с TCL_DONT_QUOTE_HASH. Tcl_ScanCountedElement и Tcl_ConvertCountedElement такие же, как Tcl_ScanElement и Tcl_ConvertElement, за исключением того, что длина строки src указывается аргументом length, и строка может содержать встроенные нулевые символы. SEE ALSO Tcl_ListObjGetElements(3) KEYWORDS backslash, convert, element, list, merge, split, strings Tcl 8.0 Tcl_SplitList(3)
Tcl_SplitList(3) Tcl Library Procedures Tcl_SplitList(3) ______________________________________________________________________________ NAME Tcl_SplitList, Tcl_Merge, Tcl_ScanElement, Tcl_ConvertElement, Tcl_ScanCountedElement, Tcl_ConvertCountedElement - manipulate Tcl lists SYNOPSIS #include <tcl.h> int Tcl_SplitList(interp, list, argcPtr, argvPtr) char * Tcl_Merge(argc, argv) int Tcl_ScanElement(src, flagsPtr) int Tcl_ScanCountedElement(src, length, flagsPtr) int Tcl_ConvertElement(src, dst, flags) int Tcl_ConvertCountedElement(src, length, dst, flags) ARGUMENTS Tcl_Interp *interp (out) Interpreter to use for error reporting. If NULL, then no error message is left. const char *list (in) Pointer to a string with proper list structure. int *argcPtr (out) Filled in with number of el‐ ements in list. const char ***argvPtr (out) *argvPtr will be filled in with the address of an array of pointers to the strings that are the extracted ele‐ ments of list. There will be *argcPtr valid entries in the array, followed by a NULL entry. int argc (in) Number of elements in argv. const char *const *argv (in) Array of strings to merge together into a single list. Each string will become a separate element of the list. const char *src (in) String that is to become an element of a list. int *flagsPtr (in) Pointer to word to fill in with information about src. The value of *flagsPtr must be passed to Tcl_ConvertEle‐ ment. int length (in) Number of bytes in string src. char *dst (in) Place to copy converted list element. Must contain enough characters to hold converted string. int flags (in) Information about src. Must be value returned by previ‐ ous call to Tcl_ScanElement, possibly OR-ed with TCL_DONT_USE_BRACES. ______________________________________________________________________________ DESCRIPTION These procedures may be used to disassemble and reassemble Tcl lists. Tcl_SplitList breaks a list up into its constituent elements, returning an array of pointers to the elements using argcPtr and argvPtr. While extracting the arguments, Tcl_SplitList obeys the usual rules for back‐ slash substitutions and braces. The area of memory pointed to by *argvPtr is dynamically allocated; in addition to the array of point‐ ers, it also holds copies of all the list elements. It is the caller's responsibility to free up all of this storage. For example, suppose that you have called Tcl_SplitList with the following code: int argc, code; char *string; char **argv; ... code = Tcl_SplitList(interp, string, &argc, &argv); Then you should eventually free the storage with a call like the fol‐ lowing: Tcl_Free((char *) argv); Tcl_SplitList normally returns TCL_OK, which means the list was suc‐ cessfully parsed. If there was a syntax error in list, then TCL_ERROR is returned and the interpreter's result will point to an error message describing the problem (if interp was not NULL). If TCL_ERROR is re‐ turned then no memory is allocated and *argvPtr is not modified. Tcl_Merge is the inverse of Tcl_SplitList: it takes a collection of strings given by argc and argv and generates a result string that has proper list structure. This means that commands like index may be used to extract the original elements again. In addition, if the result of Tcl_Merge is passed to Tcl_Eval, it will be parsed into argc words whose values will be the same as the argv strings passed to Tcl_Merge. Tcl_Merge will modify the list elements with braces and/or backslashes in order to produce proper Tcl list structure. The result string is dynamically allocated using Tcl_Alloc; the caller must eventually re‐ lease the space using Tcl_Free. If the result of Tcl_Merge is passed to Tcl_SplitList, the elements re‐ turned by Tcl_SplitList will be identical to those passed into Tcl_Merge. However, the converse is not true: if Tcl_SplitList is passed a given string, and the resulting argc and argv are passed to Tcl_Merge, the resulting string may not be the same as the original string passed to Tcl_SplitList. This is because Tcl_Merge may use backslashes and braces differently than the original string. Tcl_ScanElement and Tcl_ConvertElement are the procedures that do all of the real work of Tcl_Merge. Tcl_ScanElement scans its src argument and determines how to use backslashes and braces when converting it to a list element. It returns an overestimate of the number of characters required to represent src as a list element, and it stores information in *flagsPtr that is needed by Tcl_ConvertElement. Tcl_ConvertElement is a companion procedure to Tcl_ScanElement. It does the actual work of converting a string to a list element. Its flags argument must be the same as the value returned by Tcl_ScanEle‐ ment. Tcl_ConvertElement writes a proper list element to memory start‐ ing at *dst and returns a count of the total number of characters writ‐ ten, which will be no more than the result returned by Tcl_ScanElement. Tcl_ConvertElement writes out only the actual list element without any leading or trailing spaces: it is up to the caller to include spaces between adjacent list elements. Tcl_ConvertElement uses one of two different approaches to handle the special characters in src. Wherever possible, it handles special char‐ acters by surrounding the string with braces. This produces clean- looking output, but cannot be used in some situations, such as when src contains unmatched braces. In these situations, Tcl_ConvertElement handles special characters by generating backslash sequences for them. The caller may insist on the second approach by OR-ing the flag value returned by Tcl_ScanElement with TCL_DONT_USE_BRACES. Although this will produce an uglier result, it is useful in some special situations, such as when Tcl_ConvertElement is being used to generate a portion of an argument for a Tcl command. In this case, surrounding src with curly braces would cause the command not to be parsed correctly. By default, Tcl_ConvertElement will use quoting in its output to be sure the first character of an element is not the hash character (“#”.) This is to be sure the first element of any list passed to eval is not mis-parsed as the beginning of a comment. When a list element is not the first element of a list, this quoting is not necessary. When the caller can be sure that the element is not the first element of a list, it can disable quoting of the leading hash character by OR-ing the flag value returned by Tcl_ScanElement with TCL_DONT_QUOTE_HASH. Tcl_ScanCountedElement and Tcl_ConvertCountedElement are the same as Tcl_ScanElement and Tcl_ConvertElement, except the length of string src is specified by the length argument, and the string may contain embed‐ ded nulls. SEE ALSO Tcl_ListObjGetElements(3) KEYWORDS backslash, convert, element, list, merge, split, strings Tcl 8.0 Tcl_SplitList(3)
Tcl_SignalId(3) Tcl Library Procedures Tcl_SignalId(3) ______________________________________________________________________________ NAME Tcl_SignalId, Tcl_SignalMsg - Преобразование кодов сигналов SYNOPSIS #include <tcl.h> const char * Tcl_SignalId(sig) const char * Tcl_SignalMsg(sig) ARGUMENTS int sig (in) Число POSIX-сигнала, например SIGPIPE. ______________________________________________________________________________ DESCRIPTION Tcl_SignalId и Tcl_SignalMsg возвращают строковое представление предоставленного номера сигнала (sig). Tcl_SignalId возвращает машиночитаемый текстовый идентификатор, такой как “SIGPIPE”. Tcl_SignalMsg возвращает удобочитаемую строку, такую как “bus error”. Строки, возвращаемые этими функциями, статически выделены, и вызывающий код не должен освобождать или изменять их. KEYWORDS сигналы, номера сигналов Tcl 8.3 Tcl_SignalId(3)
Tcl_SignalId(3) Tcl Library Procedures Tcl_SignalId(3) ______________________________________________________________________________ NAME Tcl_SignalId, Tcl_SignalMsg - Convert signal codes SYNOPSIS #include <tcl.h> const char * Tcl_SignalId(sig) const char * Tcl_SignalMsg(sig) ARGUMENTS int sig (in) A POSIX signal number such as SIGPIPE. ______________________________________________________________________________ DESCRIPTION Tcl_SignalId and Tcl_SignalMsg return a string representation of the provided signal number (sig). Tcl_SignalId returns a machine-readable textual identifier such as “SIGPIPE”. Tcl_SignalMsg returns a human- readable string such as “bus error”. The strings returned by these functions are statically allocated and the caller must not free or mod‐ ify them. KEYWORDS signals, signal numbers Tcl 8.3 Tcl_SignalId(3)
Tcl_ListObj(3) Процедуры библиотеки Tcl Tcl_ListObj(3) ______________________________________________________________________________ NAME Tcl_ListObjAppendList, Tcl_ListObjAppendElement, Tcl_NewListObj, Tcl_SetListObj, Tcl_ListObjGetElements, Tcl_ListObjLength, Tcl_ListOb‐ jIndex, Tcl_ListObjReplace - манипулировать Tcl значениями как списками SYNOPSIS #include <tcl.h> int Tcl_ListObjAppendList(interp, listPtr, elemListPtr) int Tcl_ListObjAppendElement(interp, listPtr, objPtr) Tcl_Obj * Tcl_NewListObj(objc, objv) Tcl_SetListObj(objPtr, objc, objv) int Tcl_ListObjGetElements(interp, listPtr, objcPtr, objvPtr) int Tcl_ListObjLength(interp, listPtr, lengthPtr) int Tcl_ListObjIndex(interp, listPtr, index, objPtrPtr) int Tcl_ListObjReplace(interp, listPtr, first, count, objc, objv) ARGUMENTS Tcl_Interp *interp (in) Если возникает ошибка при пре‐ образовании значения в список значение, сообщение об ошибке оставляется в результате ин‐ терпретатора, если interp не равно NULL. Tcl_Obj *listPtr (in/out) Указывает на значение списка, которое нужно манипулировать. Если listPtr не указывает на значение списка, будет сдела‐ на попытка преобразовать его в такое. Tcl_Obj *elemListPtr (in/out) Для Tcl_ListObjAppendList, это указывает на значение списка, содержащее элементы, которые нужно добавить к listPtr. Ка‐ ждый элемент *elemListPtr ста‐ новится новым элементом list‐ Ptr. Если *elemListPtr не ра‐ вно NULL и не указывает на значение списка, будет сдела‐ на попытка преобразовать его в такое. Tcl_Obj *objPtr (in) Для Tcl_ListObjAppendElement, указывает на Tcl значение, которое будет добавлено к listPtr. Для Tcl_SetListObj, это указывает на Tcl значение, которое будет преобразовано в значение списка, содержащее objc элементов массива, на ко‐ торый ссылается objv. int *objcPtr (in) Указывает на место, где Tcl_ListObjGetElements сохра‐ няет количество элементных значений в listPtr. Tcl_Obj ***objvPtr (out) Место, где Tcl_ListObjGetEle‐ ments сохраняет указатель на массив указателей на элемент‐ ные значения listPtr. int objc (in) Количество Tcl значений, ко‐ торые Tcl_NewListObj вставит в новое значение списка, и Tcl_ListObjReplace вставит в listPtr. Для Tcl_SetListObj, количество Tcl значений для вставки в objPtr. Tcl_Obj *const objv[] (in) Массив указателей на значе‐ ния. Tcl_NewListObj вставит эти значения в новое значение списка, а Tcl_ListObjReplace вставит их в существующий listPtr. Каждое значение ста‐ новится отдельным элементом списка. int *lengthPtr (out) Указывает на место, где Tcl_ListObjLength сохраняет длину списка. int index (in) Индекс элемента списка, который Tcl_ListObjIndex дол‐ жен вернуть. Первый элемент имеет индекс 0. Tcl_Obj **objPtrPtr (out) Указывает на место, где Tcl_ListObjIndex должен сохра‐ нить указатель на результи‐ рующее значение элемента списка. int first (in) Индекс начального элемента списка, который Tcl_ListObjRe‐ place должен заменить. Первый элемент списка имеет индекс 0. int count (in) Количество элементов, которые Tcl_ListObjReplace должен за‐ менить. ______________________________________________________________________________ DESCRIPTION Значения Tcl списков имеют внутреннее представление, которое поддер‐ живает эффективный индексирование и добавление. Процедуры, описанные в этой man-странице, используются для создания, изменения, индексирования и добавления к значениям Tcl списков из кода C. Tcl_ListObjAppendList и Tcl_ListObjAppendElement оба добавляют одно или несколько значений в конец значения списка, на которое ссылается list‐ Ptr. Tcl_ListObjAppendList добавляет каждый элемент значения списка, на которое ссылается elemListPtr, в то время как Tcl_ListObjAppendElement добавляет одно значение, на которое ссылается objPtr. Обе процедуры преобразовывают значение, на которое ссылается listPtr, в значение списка, если это необходимо. Если возникает ошибка во время преобразу‐ вания, обе процедуры возвращают TCL_ERROR и оставляют сообщение об ошибке в результате интерпретатора, если interp не равно NULL. Анало‐ гично, если elemListPtr не ссылается на значение списка, Tcl_ListObjAp‐ pendList попытается преобразовать его в такое, и если возникает ошибка во время преобразования, вернет TCL_ERROR и оставит сообщение об ошибке в результате интерпретатора, если interp не равно NULL. Обе процедуры делают недействительной любую старую строковую репрезентацию listPtr и, если оно было преобразовано в значение списка, освобождают любое ста‐ рое внутреннее представление. Аналогично, Tcl_ListObjAppendList освобо‐ ждает любое старое внутреннее представление elemListPtr, если оно прео‐ бразуется в значение списка. После добавления каждого элемента в elem‐ ListPtr, Tcl_ListObjAppendList увеличивает счетчик ссылок элемента, поскольку listPtr теперь также ссылается на него. По той же причине Tcl_ListObjAppendElement увеличивает счетчик ссылок objPtr. Если ошибок не возникает, две процедуры возвращают TCL_OK после добавления значений. Tcl_NewListObj и Tcl_SetListObj создают новое значение или изменяют существующее значение для хранения objc элементов массива, на который ссылается objv, где каждый элемент является указателем на Tcl значение. Если objc меньше или равно нулю, они возвращают пустое значение. Если objv равно NULL, результирующий список содержит 0 элементов, с зарезер‐ вированным пространством во внутреннем представлении для objc дополни‐ тельных элементов (чтобы избежать его перераспределения позже). Строко‐ вая репрезентация нового значения оставляется недействительной. Две процедуры увеличивают счетчики ссылок элементов в objc, поскольку зна‐ чение списка теперь ссылается на них. Новое значение списка, возвращен‐ ное Tcl_NewListObj, имеет счетчик ссылок ноль. Tcl_ListObjGetElements возвращает количество и указатель на массив элементов в значении списка. Оно возвращает количество, сохраняя его в адресе objcPtr. Аналогично, оно возвращает указатель на массив, сохра‐ ня его в адресе objvPtr. Память, на которую указывается, управляется Tcl и не должна освобождаться или записываться вызывающим. Если список пуст, 0 сохраняется в objcPtr и NULL в objvPtr. Если listPtr не явля‐ ется уже значением списка, Tcl_ListObjGetElements попытается преобразо‐ вать его в такое; если преобразование не удается, оно возвращает TCL_ERROR и оставляет сообщение об ошибке в результате интерпретатора, если interp не равно NULL. В противном случае оно возвращает TCL_OK после сохранения количества и указателя на массив. Tcl_ListObjLength возвращает количество элементов в значении списка, на которое ссылается listPtr. Оно возвращает это количество, сохраняя целое число в адресе lengthPtr. Если значение не является уже значени‐ ем списка, Tcl_ListObjLength попытается преобразовать его в такое; если преобразование не удается, оно возвращает TCL_ERROR и оставляет сообще‐ ние об ошибке в результате интерпретатора, если interp не равно NULL. В противном случае оно возвращает TCL_OK после сохранения длины списка. Процедура Tcl_ListObjIndex возвращает указатель на значение по элемен‐ ту index в списке, на который ссылается listPtr. Оно возвращает это значение, сохраняя указатель на него в адресе objPtrPtr. Если listPtr не ссылается уже на значение списка, Tcl_ListObjIndex попытается прео‐ бросовать его в такое; если преобразование не удается, оно возвращает TCL_ERROR и оставляет сообщение об ошибке в результате интерпретатора, если interp не равно NULL. Если index выходит за пределы диапазона, то есть index отрицательный или больше или равен количеству элементов в списке, Tcl_ListObjIndex сохраняет NULL в objPtrPtr и возвращает TCL_OK. В противном случае оно возвращает TCL_OK после сохранения указателя на значение элемента. Счетчик ссылок для элемента списка не увеличивается; вызывающий должен сделать это, если ему нужно сохранить указатель на элемент. Tcl_ListObjReplace заменяет ноль или больше элементов списка, на кото‐ рый ссылается listPtr, на objc значений в массиве, на который ссылает‐ ся objv. Если listPtr не указывает на значение списка, Tcl_ListObjRe‐ place попытается преобразовать его в такое; если преобразование не удается, оно возвращает TCL_ERROR и оставляет сообщение об ошибке в ре‐ зультате интерпретатора, если interp не равно NULL. В противном случае оно возвращает TCL_OK после замены значений. Если objv равно NULL, новые элементы не добавляются. Если аргумент first равен нулю или отрицательный, он относится к первому элементу. Если first больше или равен количеству элементов в списке, то элементы не удаляются; новые элементы добавляются в конец списка. count дает количество элементов для замены. Если count равен нулю или отрицательный, то элементы не удаляются; новые элементы просто вставляются перед тем, который указа‐ н first. Tcl_ListObjReplace делает недействительной старую строковую репрезентацию listPtr. Счетчики ссылок любых вставленных элементов из objv увеличиваются, поскольку результирующий список теперь ссылается на них. Аналогично, счетчики ссылок для любых замененных значений уменьшаются. Поскольку Tcl_ListObjReplace объединяет как вставку элементов, так и их удаление, его можно использовать для реализации ряда операций со списками. Например, следующий код вставляет objc значений, на которые ссылается массив указателей на значения objv, прямо перед элементом index списка, на который ссылается listPtr: result = Tcl_ListObjReplace(interp, listPtr, index, 0, objc, objv); Аналогично, следующий код добавляет objc значений, на которые ссылает‐ ся массив objv, в конец списка listPtr: result = Tcl_ListObjLength(interp, listPtr, &length); if (result == TCL_OK) { result = Tcl_ListObjReplace(interp, listPtr, length, 0, objc, objv); } Элементы списка count, начиная с first, можно удалить, просто вызвав Tcl_ListObjReplace с NULL objvPtr: result = Tcl_ListObjReplace(interp, listPtr, first, count, 0, NULL); SEE ALSO Tcl_NewObj(3), Tcl_DecrRefCount(3), Tcl_IncrRefCount(3), Tcl_GetObjRe‐ sult(3) KEYWORDS append, index, insert, internal representation, length, list, list value, list type, value, value type, replace, string representation Tcl 8.0 Tcl_ListObj(3)
Tcl_ListObj(3) Tcl Library Procedures Tcl_ListObj(3) ______________________________________________________________________________ NAME Tcl_ListObjAppendList, Tcl_ListObjAppendElement, Tcl_NewListObj, Tcl_SetListObj, Tcl_ListObjGetElements, Tcl_ListObjLength, Tcl_ListOb‐ jIndex, Tcl_ListObjReplace - manipulate Tcl values as lists SYNOPSIS #include <tcl.h> int Tcl_ListObjAppendList(interp, listPtr, elemListPtr) int Tcl_ListObjAppendElement(interp, listPtr, objPtr) Tcl_Obj * Tcl_NewListObj(objc, objv) Tcl_SetListObj(objPtr, objc, objv) int Tcl_ListObjGetElements(interp, listPtr, objcPtr, objvPtr) int Tcl_ListObjLength(interp, listPtr, lengthPtr) int Tcl_ListObjIndex(interp, listPtr, index, objPtrPtr) int Tcl_ListObjReplace(interp, listPtr, first, count, objc, objv) ARGUMENTS Tcl_Interp *interp (in) If an error occurs while con‐ verting a value to be a list value, an error message is left in the interpreter's re‐ sult value unless interp is NULL. Tcl_Obj *listPtr (in/out) Points to the list value to be manipulated. If listPtr does not already point to a list value, an attempt will be made to convert it to one. Tcl_Obj *elemListPtr (in/out) For Tcl_ListObjAppendList, this points to a list value containing elements to be ap‐ pended onto listPtr. Each element of *elemListPtr will become a new element of listPtr. If *elemListPtr is not NULL and does not already point to a list value, an at‐ tempt will be made to convert it to one. Tcl_Obj *objPtr (in) For Tcl_ListObjAppendElement, points to the Tcl value that will be appended to listPtr. For Tcl_SetListObj, this points to the Tcl value that will be converted to a list value containing the objc el‐ ements of the array refer‐ enced by objv. int *objcPtr (in) Points to location where Tcl_ListObjGetElements stores the number of element values in listPtr. Tcl_Obj ***objvPtr (out) A location where Tcl_ListOb‐ jGetElements stores a pointer to an array of pointers to the element values of listPtr. int objc (in) The number of Tcl values that Tcl_NewListObj will insert into a new list value, and Tcl_ListObjReplace will in‐ sert into listPtr. For Tcl_SetListObj, the number of Tcl values to insert into ob‐ jPtr. Tcl_Obj *const objv[] (in) An array of pointers to val‐ ues. Tcl_NewListObj will in‐ sert these values into a new list value and Tcl_ListObjRe‐ place will insert them into an existing listPtr. Each value will become a separate list element. int *lengthPtr (out) Points to location where Tcl_ListObjLength stores the length of the list. int index (in) Index of the list element that Tcl_ListObjIndex is to return. The first element has index 0. Tcl_Obj **objPtrPtr (out) Points to place where Tcl_ListObjIndex is to store a pointer to the resulting list element value. int first (in) Index of the starting list element that Tcl_ListObjRe‐ place is to replace. The list's first element has in‐ dex 0. int count (in) The number of elements that Tcl_ListObjReplace is to re‐ place. ______________________________________________________________________________ DESCRIPTION Tcl list values have an internal representation that supports the effi‐ cient indexing and appending. The procedures described in this man page are used to create, modify, index, and append to Tcl list values from C code. Tcl_ListObjAppendList and Tcl_ListObjAppendElement both add one or more values to the end of the list value referenced by listPtr. Tcl_ListOb‐ jAppendList appends each element of the list value referenced by elem‐ ListPtr while Tcl_ListObjAppendElement appends the single value refer‐ enced by objPtr. Both procedures will convert the value referenced by listPtr to a list value if necessary. If an error occurs during con‐ version, both procedures return TCL_ERROR and leave an error message in the interpreter's result value if interp is not NULL. Similarly, if elemListPtr does not already refer to a list value, Tcl_ListObjAp‐ pendList will attempt to convert it to one and if an error occurs dur‐ ing conversion, will return TCL_ERROR and leave an error message in the interpreter's result value if interp is not NULL. Both procedures in‐ validate any old string representation of listPtr and, if it was con‐ verted to a list value, free any old internal representation. Simi‐ larly, Tcl_ListObjAppendList frees any old internal representation of elemListPtr if it converts it to a list value. After appending each element in elemListPtr, Tcl_ListObjAppendList increments the element's reference count since listPtr now also refers to it. For the same rea‐ son, Tcl_ListObjAppendElement increments objPtr's reference count. If no error occurs, the two procedures return TCL_OK after appending the values. Tcl_NewListObj and Tcl_SetListObj create a new value or modify an ex‐ isting value to hold the objc elements of the array referenced by objv where each element is a pointer to a Tcl value. If objc is less than or equal to zero, they return an empty value. If objv is NULL, the re‐ sulting list contains 0 elements, with reserved space in an internal representation for objc more elements (to avoid its reallocation later). The new value's string representation is left invalid. The two procedures increment the reference counts of the elements in objc since the list value now refers to them. The new list value returned by Tcl_NewListObj has reference count zero. Tcl_ListObjGetElements returns a count and a pointer to an array of the elements in a list value. It returns the count by storing it in the address objcPtr. Similarly, it returns the array pointer by storing it in the address objvPtr. The memory pointed to is managed by Tcl and should not be freed or written to by the caller. If the list is empty, 0 is stored at objcPtr and NULL at objvPtr. If listPtr is not already a list value, Tcl_ListObjGetElements will attempt to convert it to one; if the conversion fails, it returns TCL_ERROR and leaves an error mes‐ sage in the interpreter's result value if interp is not NULL. Other‐ wise it returns TCL_OK after storing the count and array pointer. Tcl_ListObjLength returns the number of elements in the list value ref‐ erenced by listPtr. It returns this count by storing an integer in the address lengthPtr. If the value is not already a list value, Tcl_Lis‐ tObjLength will attempt to convert it to one; if the conversion fails, it returns TCL_ERROR and leaves an error message in the interpreter's result value if interp is not NULL. Otherwise it returns TCL_OK after storing the list's length. The procedure Tcl_ListObjIndex returns a pointer to the value at ele‐ ment index in the list referenced by listPtr. It returns this value by storing a pointer to it in the address objPtrPtr. If listPtr does not already refer to a list value, Tcl_ListObjIndex will attempt to convert it to one; if the conversion fails, it returns TCL_ERROR and leaves an error message in the interpreter's result value if interp is not NULL. If the index is out of range, that is, index is negative or greater than or equal to the number of elements in the list, Tcl_ListObjIndex stores a NULL in objPtrPtr and returns TCL_OK. Otherwise it returns TCL_OK after storing the element's value pointer. The reference count for the list element is not incremented; the caller must do that if it needs to retain a pointer to the element. Tcl_ListObjReplace replaces zero or more elements of the list refer‐ enced by listPtr with the objc values in the array referenced by objv. If listPtr does not point to a list value, Tcl_ListObjReplace will at‐ tempt to convert it to one; if the conversion fails, it returns TCL_ER‐ ROR and leaves an error message in the interpreter's result value if interp is not NULL. Otherwise, it returns TCL_OK after replacing the values. If objv is NULL, no new elements are added. If the argument first is zero or negative, it refers to the first element. If first is greater than or equal to the number of elements in the list, then no elements are deleted; the new elements are appended to the list. count gives the number of elements to replace. If count is zero or negative then no elements are deleted; the new elements are simply inserted be‐ fore the one designated by first. Tcl_ListObjReplace invalidates listPtr's old string representation. The reference counts of any ele‐ ments inserted from objv are incremented since the resulting list now refers to them. Similarly, the reference counts for any replaced val‐ ues are decremented. Because Tcl_ListObjReplace combines both element insertion and dele‐ tion, it can be used to implement a number of list operations. For ex‐ ample, the following code inserts the objc values referenced by the ar‐ ray of value pointers objv just before the element index of the list referenced by listPtr: result = Tcl_ListObjReplace(interp, listPtr, index, 0, objc, objv); Similarly, the following code appends the objc values referenced by the array objv to the end of the list listPtr: result = Tcl_ListObjLength(interp, listPtr, &length); if (result == TCL_OK) { result = Tcl_ListObjReplace(interp, listPtr, length, 0, objc, objv); } The count list elements starting at first can be deleted by simply calling Tcl_ListObjReplace with a NULL objvPtr: result = Tcl_ListObjReplace(interp, listPtr, first, count, 0, NULL); SEE ALSO Tcl_NewObj(3), Tcl_DecrRefCount(3), Tcl_IncrRefCount(3), Tcl_GetObjRe‐ sult(3) KEYWORDS append, index, insert, internal representation, length, list, list value, list type, value, value type, replace, string representation Tcl 8.0 Tcl_ListObj(3)
Tcl_Exit(3) Процедуры Tcl Library Tcl_Exit(3) ______________________________________________________________________________ NAME Tcl_Exit, Tcl_Finalize, Tcl_CreateExitHandler, Tcl_DeleteExitHandler, Tcl_ExitThread, Tcl_FinalizeThread, Tcl_CreateThreadExitHandler, Tcl_DeleteThreadExitHandler, Tcl_SetExitProc - завершить приложение или поток (и вызвать обработчики выхода) SYNOPSIS #include <tcl.h> Tcl_Exit(status) Tcl_Finalize() Tcl_CreateExitHandler(proc, clientData) Tcl_DeleteExitHandler(proc, clientData) Tcl_ExitThread(status) Tcl_FinalizeThread() Tcl_CreateThreadExitHandler(proc, clientData) Tcl_DeleteThreadExitHandler(proc, clientData) Tcl_ExitProc * Tcl_SetExitProc(proc) ARGUMENTS int status (in) Предоставляет информацию о том, почему вышло приложение или поток. Точное значение может зависеть от платформы. 0 обычно означает нормальный выход, любое ненулевое значение обычно указывает на то, что произошла ошибка. Tcl_ExitProc *proc (in) Процедура для вызова перед завершением приложения, или (для Tcl_Se‐ tExitProc) NULL для удаления текущей процедуры выхода приложения. ClientData clientData (in) Произвольное значение одного слова для передачи в proc. ______________________________________________________________________________ DESCRIPTION Процедуры, описанные здесь, предоставляют грациозный механизм для завершения выполнения приложения Tcl. Обработчики выхода вызываются для очистки состояния приложения перед завершением выполнения кода Tcl. Вызовите Tcl_Exit для завершения приложения Tcl и выхода из процесса. Эта процедура вызывается командой exit и может быть вызвана в любом другом месте для завершения приложения. Никто не должен вызывать системную процедуру exit напрямую; всегда вызывайте Tcl_Exit, чтобы она могла вызвать обработчики выхода. Обратите внимание, что если другой код вызывает системную процедуру exit напрямую или иначе вызывает завершение приложения без вызова Tcl_Exit, обработчики выхода не будут выполнены. Tcl_Exit внутренне вызывает системный вызов exit, поэтому она никогда не возвращает управление вызывающему. Если установлен обработчик выхода приложения (см. Tcl_SetExitProc), этот обработчик вызывается с аргументом, состоящим из кода выхода (приведенного к ClientData); обработчик выхода приложения не должен возвращать управление Tcl. Tcl_Finalize похожа на Tcl_Exit, за исключением того, что она не выходит из текущего процесса. Она полезна для очистки, когда процесс закончил использование Tcl, но желает продолжить выполнение, и когда Tcl используется в динамически загружаемом расширении, которое собирается выгрузить. Ваш код должен всегда вызывать Tcl_Finalize при выгрузке Tcl, чтобы обеспечить правильную очистку. Tcl_Finalize можно безопасно вызывать более одного раза. Tcl_ExitThread используется для завершения текущего потока и вызова обработчиков выхода для потока. Эта финализация выполняется Tcl_FinalizeThread, которую вы можете вызвать, если хотите только очистить состояние для потока и вызвать обработчики выхода потока. Tcl_Finalize автоматически вызывает Tcl_FinalizeThread для текущего потока. Tcl_CreateExitHandler организует вызов proc Tcl_Finalize и Tcl_Exit. Tcl_CreateThreadExitHandler организует вызов proc Tcl_FinalizeThread и Tcl_ExitThread. Это предоставляет хук для операций очистки, таких как сброс буферов и освобождение глобальной памяти. Proc должна соответствовать типу Tcl_ExitProc: typedef void Tcl_ExitProc( ClientData clientData); Параметр clientData для proc является копией аргумента clientData, переданного Tcl_CreateExitHandler или Tcl_CreateThreadExitHandler при создании обратного вызова. Обычно clientData указывает на структуру данных, содержащую информацию, специфичную для приложения, о том, что делать в proc. Tcl_DeleteExitHandler и Tcl_DeleteThreadExitHandler могут быть вызваны для удаления ранее созданного обработчика выхода. Они удаляют обработчик, указанный proc и clientData, чтобы вызов proc не производился. Если такого обработчика не существует, Tcl_DeleteExitHandler или Tcl_DeleteThread‐ ExitHandler ничего не делают. Tcl_Finalize и Tcl_Exit выполняют все зарегистрированные обработчики выхода, в обратном порядке от порядка их регистрации. Это соответствует естественному порядку загрузки и выгрузки расширений; если расширение A загружает расширение B, оно обычно выгружает B перед тем, как само выгрузиться. Если расширение A регистрирует свои обработчики выхода перед загрузкой расширения B, это гарантирует, что любые обработчики выхода для B будут выполнены перед обработчиками выхода для A. Tcl_Finalize и Tcl_Exit вызывают Tcl_FinalizeThread и обработчики выхода потока после глобальных обработчиков выхода. Это потому, что финализация потока отключает систему ввода/выводa каналов, поэтому любые попытки ввода/выводa глобальными обработчиками выхода пропадут. Tcl_SetExitProc устанавливает обработчик выхода приложения, возвращая ранее установленный обработчик выхода приложения или NULL, если обработчик приложения не был установлен. Если установлен обработчик выхода приложения, этот обработчик берет на себя полную ответственность за финализацию подсистем Tcl через Tcl_Finalize в подходящее время. Аргумент, передаваемый proc при ее вызове, будет кодом выхода (как переданным Tcl_Exit), приведенным к значению ClientData. SEE ALSO exit(n) KEYWORDS abort, callback, cleanup, dynamic loading, end application, exit, un‐ loading, thread Tcl 8.5 Tcl_Exit(3)
Tcl_Exit(3) Tcl Library Procedures Tcl_Exit(3) ______________________________________________________________________________ NAME Tcl_Exit, Tcl_Finalize, Tcl_CreateExitHandler, Tcl_DeleteExitHandler, Tcl_ExitThread, Tcl_FinalizeThread, Tcl_CreateThreadExitHandler, Tcl_DeleteThreadExitHandler, Tcl_SetExitProc - end the application or thread (and invoke exit handlers) SYNOPSIS #include <tcl.h> Tcl_Exit(status) Tcl_Finalize() Tcl_CreateExitHandler(proc, clientData) Tcl_DeleteExitHandler(proc, clientData) Tcl_ExitThread(status) Tcl_FinalizeThread() Tcl_CreateThreadExitHandler(proc, clientData) Tcl_DeleteThreadExitHandler(proc, clientData) Tcl_ExitProc * Tcl_SetExitProc(proc) ARGUMENTS int status (in) Provides information about why the application or thread exited. Exact meaning may be platform- specific. 0 usually means a nor‐ mal exit, any nonzero value usu‐ ally means that an error oc‐ curred. Tcl_ExitProc *proc (in) Procedure to invoke before exit‐ ing application, or (for Tcl_Se‐ tExitProc) NULL to uninstall the current application exit proce‐ dure. ClientData clientData (in) Arbitrary one-word value to pass to proc. ______________________________________________________________________________ DESCRIPTION The procedures described here provide a graceful mechanism to end the execution of a Tcl application. Exit handlers are invoked to cleanup the application's state before ending the execution of Tcl code. Invoke Tcl_Exit to end a Tcl application and to exit from this process. This procedure is invoked by the exit command, and can be invoked any‐ place else to terminate the application. No-one should ever invoke the exit system procedure directly; always invoke Tcl_Exit instead, so that it can invoke exit handlers. Note that if other code invokes exit system procedure directly, or otherwise causes the application to ter‐ minate without calling Tcl_Exit, the exit handlers will not be run. Tcl_Exit internally invokes the exit system call, thus it never returns control to its caller. If an application exit handler has been in‐ stalled (see Tcl_SetExitProc), that handler is invoked with an argument consisting of the exit status (cast to ClientData); the application exit handler should not return control to Tcl. Tcl_Finalize is similar to Tcl_Exit except that it does not exit from the current process. It is useful for cleaning up when a process is finished using Tcl but wishes to continue executing, and when Tcl is used in a dynamically loaded extension that is about to be unloaded. Your code should always invoke Tcl_Finalize when Tcl is being unloaded, to ensure proper cleanup. Tcl_Finalize can be safely called more than once. Tcl_ExitThread is used to terminate the current thread and invoke per- thread exit handlers. This finalization is done by Tcl_FinalizeThread, which you can call if you just want to clean up per-thread state and invoke the thread exit handlers. Tcl_Finalize calls Tcl_FinalizeThread for the current thread automatically. Tcl_CreateExitHandler arranges for proc to be invoked by Tcl_Finalize and Tcl_Exit. Tcl_CreateThreadExitHandler arranges for proc to be in‐ voked by Tcl_FinalizeThread and Tcl_ExitThread. This provides a hook for cleanup operations such as flushing buffers and freeing global mem‐ ory. Proc should match the type Tcl_ExitProc: typedef void Tcl_ExitProc( ClientData clientData); The clientData parameter to proc is a copy of the clientData argument given to Tcl_CreateExitHandler or Tcl_CreateThreadExitHandler when the callback was created. Typically, clientData points to a data structure containing application-specific information about what to do in proc. Tcl_DeleteExitHandler and Tcl_DeleteThreadExitHandler may be called to delete a previously-created exit handler. It removes the handler indi‐ cated by proc and clientData so that no call to proc will be made. If no such handler exists then Tcl_DeleteExitHandler or Tcl_DeleteThread‐ ExitHandler does nothing. Tcl_Finalize and Tcl_Exit execute all registered exit handlers, in re‐ verse order from the order in which they were registered. This matches the natural order in which extensions are loaded and unloaded; if ex‐ tension A loads extension B, it usually unloads B before it itself is unloaded. If extension A registers its exit handlers before loading extension B, this ensures that any exit handlers for B will be executed before the exit handlers for A. Tcl_Finalize and Tcl_Exit call Tcl_FinalizeThread and the thread exit handlers after the process-wide exit handlers. This is because thread finalization shuts down the I/O channel system, so any attempt at I/O by the global exit handlers will vanish into the bitbucket. Tcl_SetExitProc installs an application exit handler, returning the previously-installed application exit handler or NULL if no application handler was installed. If an application exit handler is installed, that exit handler takes over complete responsibility for finalization of Tcl's subsystems via Tcl_Finalize at an appropriate time. The argu‐ ment passed to proc when it is invoked will be the exit status code (as passed to Tcl_Exit) cast to a ClientData value. SEE ALSO exit(n) KEYWORDS abort, callback, cleanup, dynamic loading, end application, exit, un‐ loading, thread Tcl 8.5 Tcl_Exit(3)