Пакет: 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)