use crate::tcl::TclBuf;
use std::ffi::CString;
use std::ffi::c_double;
use std::ffi::c_int;
use std::ffi::c_longlong;
use std::ffi::c_uint;
use std::ffi::c_ulonglong;
use std::ffi::c_void;
use std::os::raw::c_char;
use crate::Object;
use crate::ObjectType;
use crate::RawObject;
use crate::TclObjectType;
use crate::tcl::*;
#[repr(C)]
#[derive(Debug)]
pub struct Interpreter {
_legacy_result: *const c_void,
_legacy_free_proc: *const c_void,
_error_line: isize,
stubs: *const Stubs,
}
type CmdProc = fn(interp: &Interpreter, args: Vec<&str>) -> Result<TclStatus, String>;
type ObjCmdProc = fn(interp: &Interpreter, args: Vec<Object>) -> Result<TclStatus, Object>;
const TCL_STUB_MAGIC: u32 = 0xFCA3BACB + size_of::<*const c_void>() as u32;
#[repr(C)]
#[derive(Debug, PartialEq)]
pub enum TclStatus {
Ok = 0,
Error = 1,
Return = 2,
Break = 3,
Continue = 4,
}
impl From<i32> for TclStatus {
fn from(val: i32) -> Self {
match val {
0 => TclStatus::Ok,
2 => TclStatus::Return,
3 => TclStatus::Break,
4 => TclStatus::Continue,
_ => TclStatus::Error,
}
}
}
#[repr(isize)]
pub enum TclUnloadFlag {
DetachFromInterpreter = 1 << 0,
DetachFromProcess = 1 << 1,
}
#[allow(clippy::zero_ptr)] const _TCL_STATIC: *const c_void = 0 as *const c_void;
#[allow(clippy::manual_dangling_ptr)] const _TCL_VOLATILE: *const c_void = 1 as *const c_void;
const _TCL_DYNAMIC: *const c_void = 3 as *const c_void;
#[repr(C)]
#[allow(non_snake_case)]
#[derive(Debug)]
struct Stubs {
magic: u32,
hooks: *const c_void,
Tcl_PkgProvideEx:
extern "C" fn(*const Interpreter, *const c_char, *const c_char, *const c_void) -> c_int, Tcl_PkgRequireEx: extern "C" fn(
*const Interpreter,
*const c_char,
*const c_char,
c_int,
*mut c_void,
) -> *const c_char, Tcl_Panic: extern "C" fn(*const c_char, *const c_char), Tcl_Alloc: extern "C" fn(usize) -> *mut c_void, Tcl_Free: extern "C" fn(*mut c_void), Tcl_Realloc: extern "C" fn(*mut c_void, usize) -> *mut c_void, Tcl_DbCkalloc: extern "C" fn(usize, *const c_char, c_int) -> *mut c_void, Tcl_DbCkfree: extern "C" fn(*mut c_void, *const c_char, c_int), Tcl_DbCkrealloc: extern "C" fn(*mut c_void, usize, *const c_char, c_int) -> *mut c_void, Tcl_CreateFileHandler: extern "C" fn(c_int, c_int, *mut c_void, *mut c_void), Tcl_DeleteFileHandler: extern "C" fn(c_int), Tcl_SetTimer: extern "C" fn(*const c_void), Tcl_Sleep: extern "C" fn(c_int), Tcl_WaitForEvent: extern "C" fn(*const c_void) -> c_int, Tcl_AppendAllObjTypes: extern "C" fn(*const Interpreter, *mut RawObject) -> c_int, Tcl_AppendStringsToObj: extern "C" fn(*mut RawObject, *mut RawObject), Tcl_AppendToObj: extern "C" fn(*mut RawObject, *const c_char, usize), Tcl_ConcatObj: extern "C" fn(usize, *mut c_void) -> *mut RawObject, Tcl_ConvertToType:
extern "C" fn(*const Interpreter, *mut RawObject, *const ObjectType) -> c_int, Tcl_DbDecrRefCount: extern "C" fn(*mut RawObject, *const c_char, c_int), Tcl_DbIncrRefCount: extern "C" fn(*mut RawObject, *const c_char, c_int), Tcl_DbIsShared: extern "C" fn(*mut RawObject, *const c_char, c_int) -> c_int, _deprecated_22: *const c_void, Tcl_DbNewByteArrayObj:
extern "C" fn(*const c_void, usize, *const c_char, c_int) -> *mut RawObject, Tcl_DbNewDoubleObj: extern "C" fn(c_double, *const c_char, c_int) -> *mut RawObject, Tcl_DbNewListObj: extern "C" fn(usize, *mut c_void, *const c_char, c_int) -> *mut RawObject, _deprecated_26: *const c_void, Tcl_DbNewObj: extern "C" fn(*const c_char, c_int) -> *mut RawObject, Tcl_DbNewStringObj: extern "C" fn(*const c_char, usize, *const c_char, c_int) -> *mut RawObject, Tcl_DuplicateObj: extern "C" fn(*mut RawObject) -> *mut RawObject, TclFreeObj: extern "C" fn(*mut RawObject), Tcl_GetBoolean: extern "C" fn(*const Interpreter, *const c_char, *mut c_void) -> c_int, Tcl_GetBooleanFromObj: extern "C" fn(*const Interpreter, *mut RawObject, *mut c_void) -> c_int, Tcl_GetByteArrayFromObj: extern "C" fn(*mut RawObject, *mut c_void) -> *mut c_void, Tcl_GetDouble: extern "C" fn(*const Interpreter, *const c_char, *mut c_void) -> c_int, Tcl_GetDoubleFromObj: extern "C" fn(*const Interpreter, *mut RawObject, *mut c_void) -> c_int, _deprecated_36: *const c_void, Tcl_GetInt: extern "C" fn(*const Interpreter, *const c_char, *mut c_void) -> c_int, Tcl_GetIntFromObj: extern "C" fn(*const Interpreter, *mut RawObject, *mut c_void) -> c_int, Tcl_GetLongFromObj: extern "C" fn(*const Interpreter, *mut RawObject, *mut c_void) -> c_int, Tcl_GetObjType: extern "C" fn(*const c_char) -> *const ObjectType, TclGetStringFromObj: extern "C" fn(*mut RawObject, *mut c_void) -> *mut c_char, Tcl_InvalidateStringRep: extern "C" fn(*mut RawObject), Tcl_ListObjAppendList:
extern "C" fn(*const Interpreter, *mut RawObject, *mut RawObject) -> c_int, Tcl_ListObjAppendElement:
extern "C" fn(*const Interpreter, *mut RawObject, *mut RawObject) -> c_int, TclListObjGetElements:
extern "C" fn(*const Interpreter, *mut RawObject, *mut c_void, *mut c_void) -> c_int, Tcl_ListObjIndex:
extern "C" fn(*const Interpreter, *mut RawObject, usize, *mut c_void) -> c_int, TclListObjLength: extern "C" fn(*const Interpreter, *mut RawObject, *mut c_void) -> c_int, Tcl_ListObjReplace: extern "C" fn(
*const Interpreter,
*mut RawObject,
usize,
usize,
usize,
*mut c_void,
) -> c_int, _deprecated_49: *const c_void, Tcl_NewByteArrayObj: extern "C" fn(*const c_void, usize) -> *mut RawObject, Tcl_NewDoubleObj: extern "C" fn(c_double) -> *mut RawObject, _deprecated_52: *const c_void, Tcl_NewListObj: extern "C" fn(usize, *mut c_void) -> *mut RawObject, _deprecated_54: *const c_void, Tcl_NewObj: extern "C" fn() -> *mut RawObject, Tcl_NewStringObj: extern "C" fn(*const c_char, usize) -> *mut RawObject, _deprecated_57: *const c_void, Tcl_SetByteArrayLength: extern "C" fn(*mut RawObject, usize) -> *mut c_void, Tcl_SetByteArrayObj: extern "C" fn(*mut RawObject, *const c_void, usize), Tcl_SetDoubleObj: extern "C" fn(*mut RawObject, c_double), _deprecated_61: *const c_void, Tcl_SetListObj: extern "C" fn(*mut RawObject, usize, *mut c_void), _deprecated_63: *const c_void, Tcl_SetObjLength: extern "C" fn(*mut RawObject, usize), Tcl_SetStringObj: extern "C" fn(*mut RawObject, *const c_char, usize), _deprecated_66: *const c_void, _deprecated_67: *const c_void, Tcl_AllowExceptions: extern "C" fn(*const Interpreter), Tcl_AppendElement: extern "C" fn(*const Interpreter, *const c_char), Tcl_AppendResult: extern "C" fn(*const Interpreter, *const Interpreter), Tcl_AsyncCreate: extern "C" fn(*mut c_void, *mut c_void) -> *mut c_void, Tcl_AsyncDelete: extern "C" fn(*mut c_void), Tcl_AsyncInvoke: extern "C" fn(*const Interpreter, c_int) -> c_int, Tcl_AsyncMark: extern "C" fn(*mut c_void), Tcl_AsyncReady: extern "C" fn() -> c_int, _deprecated_76: *const c_void, _deprecated_77: *const c_void, Tcl_BadChannelOption: extern "C" fn(*const Interpreter, *const c_char, *const c_char) -> c_int, Tcl_CallWhenDeleted: extern "C" fn(*const Interpreter, *mut c_void, *mut c_void), Tcl_CancelIdleCall: extern "C" fn(*mut c_void, *mut c_void), Tcl_Close: extern "C" fn(*const Interpreter, *mut c_void) -> c_int, Tcl_CommandComplete: extern "C" fn(*const c_char) -> c_int, Tcl_Concat: extern "C" fn(usize, *const c_void) -> *mut c_char, Tcl_ConvertElement: extern "C" fn(*const c_char, *mut c_char, c_int) -> usize, Tcl_ConvertCountedElement: extern "C" fn(*const c_char, usize, *mut c_char, c_int) -> usize, Tcl_CreateAlias: extern "C" fn(
*const Interpreter,
*const c_char,
*const Interpreter,
*const c_char,
usize,
*const c_void,
) -> c_int, Tcl_CreateAliasObj: extern "C" fn(
*const Interpreter,
*const c_char,
*const Interpreter,
*const c_char,
usize,
*mut c_void,
) -> c_int, Tcl_CreateChannel:
extern "C" fn(*const c_void, *const c_char, *mut c_void, c_int) -> *mut c_void, Tcl_CreateChannelHandler: extern "C" fn(*mut c_void, c_int, *mut c_void, *mut c_void), Tcl_CreateCloseHandler: extern "C" fn(*mut c_void, *mut c_void, *mut c_void), Tcl_CreateCommand: extern "C" fn(
*const Interpreter,
*const c_char,
*mut c_void,
*mut c_void,
*mut c_void,
) -> *mut c_void, Tcl_CreateEventSource: extern "C" fn(*mut c_void, *mut c_void, *mut c_void), Tcl_CreateExitHandler: extern "C" fn(*mut c_void, *mut c_void), Tcl_CreateInterp: extern "C" fn() -> *const Interpreter, _deprecated_95: *const c_void, Tcl_CreateObjCommand: extern "C" fn(
*const Interpreter,
*const c_char,
*mut c_void,
*mut c_void,
*mut c_void,
) -> *mut c_void, Tcl_CreateChild: extern "C" fn(*const Interpreter, *const c_char, c_int) -> *const Interpreter, Tcl_CreateTimerHandler: extern "C" fn(c_int, *mut c_void, *mut c_void) -> *mut c_void, Tcl_CreateTrace:
extern "C" fn(*const Interpreter, usize, *mut c_void, *mut c_void) -> *mut c_void, Tcl_DeleteAssocData: extern "C" fn(*const Interpreter, *const c_char), Tcl_DeleteChannelHandler: extern "C" fn(*mut c_void, *mut c_void, *mut c_void), Tcl_DeleteCloseHandler: extern "C" fn(*mut c_void, *mut c_void, *mut c_void), Tcl_DeleteCommand: extern "C" fn(*const Interpreter, *const c_char) -> c_int, Tcl_DeleteCommandFromToken: extern "C" fn(*const Interpreter, *mut c_void) -> c_int, Tcl_DeleteEvents: extern "C" fn(*mut c_void, *mut c_void), Tcl_DeleteEventSource: extern "C" fn(*mut c_void, *mut c_void, *mut c_void), Tcl_DeleteExitHandler: extern "C" fn(*mut c_void, *mut c_void), Tcl_DeleteHashEntry: extern "C" fn(*mut c_void), Tcl_DeleteHashTable: extern "C" fn(*mut c_void), Tcl_DeleteInterp: extern "C" fn(*const Interpreter), Tcl_DetachPids: extern "C" fn(usize, *mut c_void), Tcl_DeleteTimerHandler: extern "C" fn(*mut c_void), Tcl_DeleteTrace: extern "C" fn(*const Interpreter, *mut c_void), Tcl_DontCallWhenDeleted: extern "C" fn(*const Interpreter, *mut c_void, *mut c_void), Tcl_DoOneEvent: extern "C" fn(c_int) -> c_int, Tcl_DoWhenIdle: extern "C" fn(*mut c_void, *mut c_void), Tcl_DStringAppend: extern "C" fn(*mut c_void, *const c_char, usize) -> *mut c_char, Tcl_DStringAppendElement: extern "C" fn(*mut c_void, *const c_char) -> *mut c_char, Tcl_DStringEndSublist: extern "C" fn(*mut c_void), Tcl_DStringFree: extern "C" fn(*mut c_void), Tcl_DStringGetResult: extern "C" fn(*const Interpreter, *mut c_void), Tcl_DStringInit: extern "C" fn(*mut c_void), Tcl_DStringResult: extern "C" fn(*const Interpreter, *mut c_void), Tcl_DStringSetLength: extern "C" fn(*mut c_void, usize), Tcl_DStringStartSublist: extern "C" fn(*mut c_void), Tcl_Eof: extern "C" fn(*mut c_void) -> c_int, Tcl_ErrnoId: extern "C" fn() -> *const c_char, Tcl_ErrnoMsg: extern "C" fn(c_int) -> *const c_char, _deprecated_129: *const c_void, Tcl_EvalFile: extern "C" fn(*const Interpreter, *const c_char) -> c_int, _deprecated_131: *const c_void, Tcl_EventuallyFree: extern "C" fn(*mut c_void, *mut c_void), Tcl_Exit: extern "C" fn(c_int), Tcl_ExposeCommand: extern "C" fn(*const Interpreter, *const c_char, *const c_char) -> c_int, Tcl_ExprBoolean: extern "C" fn(*const Interpreter, *const c_char, *mut c_void) -> c_int, Tcl_ExprBooleanObj: extern "C" fn(*const Interpreter, *mut RawObject, *mut c_void) -> c_int, Tcl_ExprDouble: extern "C" fn(*const Interpreter, *const c_char, *mut c_void) -> c_int, Tcl_ExprDoubleObj: extern "C" fn(*const Interpreter, *mut RawObject, *mut c_void) -> c_int, Tcl_ExprLong: extern "C" fn(*const Interpreter, *const c_char, *mut c_void) -> c_int, Tcl_ExprLongObj: extern "C" fn(*const Interpreter, *mut RawObject, *mut c_void) -> c_int, Tcl_ExprObj: extern "C" fn(*const Interpreter, *mut RawObject, *mut c_void) -> c_int, Tcl_ExprString: extern "C" fn(*const Interpreter, *const c_char) -> c_int, Tcl_Finalize: extern "C" fn(), _deprecated_144: *const c_void, Tcl_FirstHashEntry: extern "C" fn(*mut c_void, *mut c_void) -> *mut c_void, Tcl_Flush: extern "C" fn(*mut c_void) -> c_int, _deprecated_147: *const c_void, _deprecated_148: *const c_void, TclGetAliasObj: extern "C" fn(
*const Interpreter,
*const c_char,
*mut c_void,
*const c_void,
*mut c_void,
*mut c_void,
) -> c_int, Tcl_GetAssocData: extern "C" fn(*const Interpreter, *const c_char, *mut c_void) -> *mut c_void, Tcl_GetChannel: extern "C" fn(*const Interpreter, *const c_char, *mut c_void) -> *mut c_void, Tcl_GetChannelBufferSize: extern "C" fn(*mut c_void) -> usize, Tcl_GetChannelHandle: extern "C" fn(*mut c_void, c_int, *mut c_void) -> c_int, Tcl_GetChannelInstanceData: extern "C" fn(*mut c_void) -> *mut c_void, Tcl_GetChannelMode: extern "C" fn(*mut c_void) -> c_int, Tcl_GetChannelName: extern "C" fn(*mut c_void) -> *const c_char, Tcl_GetChannelOption:
extern "C" fn(*const Interpreter, *mut c_void, *const c_char, *mut c_void) -> c_int, Tcl_GetChannelType: extern "C" fn(*mut c_void) -> *const c_void, Tcl_GetCommandInfo: extern "C" fn(*const Interpreter, *const c_char, *mut c_void) -> c_int, Tcl_GetCommandName: extern "C" fn(*const Interpreter, *mut c_void) -> *const c_char, Tcl_GetErrno: extern "C" fn() -> c_int, Tcl_GetHostName: extern "C" fn() -> *const c_char, Tcl_GetInterpPath: extern "C" fn(*const Interpreter, *const Interpreter) -> c_int, Tcl_GetParent: extern "C" fn(*const Interpreter) -> *const Interpreter, Tcl_GetNameOfExecutable: extern "C" fn() -> *const c_char, Tcl_GetObjResult: extern "C" fn(*const Interpreter) -> *mut RawObject, Tcl_GetOpenFile:
extern "C" fn(*const Interpreter, *const c_char, c_int, c_int, *mut c_void) -> c_int, Tcl_GetPathType: extern "C" fn(*const c_char) -> *mut c_void, Tcl_Gets: extern "C" fn(*mut c_void, *mut c_void) -> usize, Tcl_GetsObj: extern "C" fn(*mut c_void, *mut RawObject) -> usize, Tcl_GetServiceMode: extern "C" fn() -> c_int, Tcl_GetChild: extern "C" fn(*const Interpreter, *const c_char) -> *const Interpreter, Tcl_GetStdChannel: extern "C" fn(c_int) -> *mut c_void, _deprecated_174: *const c_void, _deprecated_175: *const c_void, Tcl_GetVar2:
extern "C" fn(*const Interpreter, *const c_char, *const c_char, c_int) -> *const c_char, _deprecated_177: *const c_void, _deprecated_178: *const c_void, Tcl_HideCommand: extern "C" fn(*const Interpreter, *const c_char, *const c_char) -> c_int, Tcl_Init: extern "C" fn(*const Interpreter) -> c_int, Tcl_InitHashTable: extern "C" fn(*mut c_void, c_int), Tcl_InputBlocked: extern "C" fn(*mut c_void) -> c_int, Tcl_InputBuffered: extern "C" fn(*mut c_void) -> c_int, Tcl_InterpDeleted: extern "C" fn(*const Interpreter) -> c_int, Tcl_IsSafe: extern "C" fn(*const Interpreter) -> c_int, Tcl_JoinPath: extern "C" fn(usize, *const c_void, *mut c_void) -> *mut c_char, Tcl_LinkVar: extern "C" fn(*const Interpreter, *const c_char, *mut c_void, c_int) -> c_int, _deprecated_188: *const c_void, Tcl_MakeFileChannel: extern "C" fn(*mut c_void, c_int) -> *mut c_void, _deprecated_190: *const c_void, Tcl_MakeTcpClientChannel: extern "C" fn(*mut c_void) -> *mut c_void, Tcl_Merge: extern "C" fn(usize, *const c_void) -> *mut c_char, Tcl_NextHashEntry: extern "C" fn(*mut c_void) -> *mut c_void, Tcl_NotifyChannel: extern "C" fn(*mut c_void, c_int), Tcl_ObjGetVar2:
extern "C" fn(*const Interpreter, *mut RawObject, *mut RawObject, c_int) -> *mut RawObject, Tcl_ObjSetVar2: extern "C" fn(
*const Interpreter,
*mut RawObject,
*mut RawObject,
*mut RawObject,
c_int,
) -> *mut RawObject, Tcl_OpenCommandChannel:
extern "C" fn(*const Interpreter, usize, *const c_void, c_int) -> *mut c_void, Tcl_OpenFileChannel:
extern "C" fn(*const Interpreter, *const c_char, *const c_char, c_int) -> *mut c_void, Tcl_OpenTcpClient: extern "C" fn(
*const Interpreter,
c_int,
*const c_char,
*const c_char,
c_int,
c_int,
) -> *mut c_void, Tcl_OpenTcpServer: extern "C" fn(
*const Interpreter,
c_int,
*const c_char,
*mut c_void,
*mut c_void,
) -> *mut c_void, Tcl_Preserve: extern "C" fn(*mut c_void), Tcl_PrintDouble: extern "C" fn(*const Interpreter, c_double, *mut c_char), Tcl_PutEnv: extern "C" fn(*const c_char) -> c_int, Tcl_PosixError: extern "C" fn(*const Interpreter) -> *const c_char, Tcl_QueueEvent: extern "C" fn(*mut c_void, c_int), Tcl_Read: extern "C" fn(*mut c_void, *mut c_char, usize) -> usize, Tcl_ReapDetachedProcs: extern "C" fn(), Tcl_RecordAndEval: extern "C" fn(*const Interpreter, *const c_char, c_int) -> c_int, Tcl_RecordAndEvalObj: extern "C" fn(*const Interpreter, *mut RawObject, c_int) -> c_int, Tcl_RegisterChannel: extern "C" fn(*const Interpreter, *mut c_void), Tcl_RegisterObjType: extern "C" fn(*const ObjectType), Tcl_RegExpCompile: extern "C" fn(*const Interpreter, *const c_char) -> *mut c_void, Tcl_RegExpExec:
extern "C" fn(*const Interpreter, *mut c_void, *const c_char, *const c_char) -> c_int, Tcl_RegExpMatch: extern "C" fn(*const Interpreter, *const c_char, *const c_char) -> c_int, Tcl_RegExpRange: extern "C" fn(*mut c_void, usize, *const c_void, *const c_void), Tcl_Release: extern "C" fn(*mut c_void), Tcl_ResetResult: extern "C" fn(*const Interpreter), Tcl_ScanElement: extern "C" fn(*const c_char, *mut c_void) -> usize, Tcl_ScanCountedElement: extern "C" fn(*const c_char, usize, *mut c_void) -> usize, _deprecated_220: *const c_void, Tcl_ServiceAll: extern "C" fn() -> c_int, Tcl_ServiceEvent: extern "C" fn(c_int) -> c_int, Tcl_SetAssocData: extern "C" fn(*const Interpreter, *const c_char, *mut c_void, *mut c_void), Tcl_SetChannelBufferSize: extern "C" fn(*mut c_void, usize), Tcl_SetChannelOption:
extern "C" fn(*const Interpreter, *mut c_void, *const c_char, *const c_char) -> c_int, Tcl_SetCommandInfo: extern "C" fn(*const Interpreter, *const c_char, *const c_void) -> c_int, Tcl_SetErrno: extern "C" fn(c_int), Tcl_SetErrorCode: extern "C" fn(*const Interpreter, *const Interpreter), Tcl_SetMaxBlockTime: extern "C" fn(*const c_void), _deprecated_230: *const c_void, Tcl_SetRecursionLimit: extern "C" fn(*const Interpreter, usize) -> usize, _deprecated_232: *const c_void, Tcl_SetServiceMode: extern "C" fn(c_int) -> c_int, Tcl_SetObjErrorCode: extern "C" fn(*const Interpreter, *mut RawObject), Tcl_SetObjResult: extern "C" fn(*const Interpreter, *mut RawObject), Tcl_SetStdChannel: extern "C" fn(*mut c_void, c_int), _deprecated_237: *const c_void, Tcl_SetVar2: extern "C" fn(
*const Interpreter,
*const c_char,
*const c_char,
*const c_char,
c_int,
) -> *const c_char, Tcl_SignalId: extern "C" fn(c_int) -> *const c_char, Tcl_SignalMsg: extern "C" fn(c_int) -> *const c_char, Tcl_SourceRCFile: extern "C" fn(*const Interpreter), TclSplitList:
extern "C" fn(*const Interpreter, *const c_char, *mut c_void, *const c_void) -> c_int, TclSplitPath: extern "C" fn(*const c_char, *mut c_void, *const c_void), _deprecated_244: *const c_void, _deprecated_245: *const c_void, _deprecated_246: *const c_void, _deprecated_247: *const c_void, Tcl_TraceVar2: extern "C" fn(
*const Interpreter,
*const c_char,
*const c_char,
c_int,
*mut c_void,
*mut c_void,
) -> c_int, Tcl_TranslateFileName:
extern "C" fn(*const Interpreter, *const c_char, *mut c_void) -> *mut c_char, Tcl_Ungets: extern "C" fn(*mut c_void, *const c_char, usize, c_int) -> usize, Tcl_UnlinkVar: extern "C" fn(*const Interpreter, *const c_char), Tcl_UnregisterChannel: extern "C" fn(*const Interpreter, *mut c_void) -> c_int, _deprecated_253: *const c_void, Tcl_UnsetVar2: extern "C" fn(*const Interpreter, *const c_char, *const c_char, c_int) -> c_int, _deprecated_255: *const c_void, Tcl_UntraceVar2: extern "C" fn(
*const Interpreter,
*const c_char,
*const c_char,
c_int,
*mut c_void,
*mut c_void,
), Tcl_UpdateLinkedVar: extern "C" fn(*const Interpreter, *const c_char), _deprecated_258: *const c_void, Tcl_UpVar2: extern "C" fn(
*const Interpreter,
*const c_char,
*const c_char,
*const c_char,
*const c_char,
c_int,
) -> c_int, Tcl_VarEval: extern "C" fn(*const Interpreter, *const Interpreter) -> c_int, _deprecated_261: *const c_void, Tcl_VarTraceInfo2: extern "C" fn(
*const Interpreter,
*const c_char,
*const c_char,
c_int,
*mut c_void,
*mut c_void,
) -> *mut c_void, Tcl_Write: extern "C" fn(*mut c_void, *const c_char, usize) -> usize, Tcl_WrongNumArgs: extern "C" fn(*const Interpreter, usize, *mut c_void, *const c_char), Tcl_DumpActiveMemory: extern "C" fn(*const c_char) -> c_int, Tcl_ValidateAllMemory: extern "C" fn(*const c_char, c_int), _deprecated_267: *const c_void, _deprecated_268: *const c_void, Tcl_HashStats: extern "C" fn(*mut c_void) -> *mut c_char, Tcl_ParseVar: extern "C" fn(*const Interpreter, *const c_char, *const c_void) -> *const c_char, _deprecated_271: *const c_void, Tcl_PkgPresentEx: extern "C" fn(
*const Interpreter,
*const c_char,
*const c_char,
c_int,
*mut c_void,
) -> *const c_char, _deprecated_273: *const c_void, _deprecated_274: *const c_void, _deprecated_275: *const c_void, _deprecated_276: *const c_void, Tcl_WaitPid: extern "C" fn(*mut c_void, *mut c_void, c_int) -> *mut c_void, _deprecated_278: *const c_void, Tcl_GetVersion: extern "C" fn(*mut c_void, *mut c_void, *mut c_void, *mut c_void), Tcl_InitMemory: extern "C" fn(*const Interpreter), Tcl_StackChannel: extern "C" fn(
*const Interpreter,
*const c_void,
*mut c_void,
c_int,
*mut c_void,
) -> *mut c_void, Tcl_UnstackChannel: extern "C" fn(*const Interpreter, *mut c_void) -> c_int, Tcl_GetStackedChannel: extern "C" fn(*mut c_void) -> *mut c_void, Tcl_SetMainLoop: extern "C" fn(*mut c_void), Tcl_GetAliasObj: extern "C" fn(
*const Interpreter,
*const c_char,
*mut c_void,
*const c_void,
*mut c_void,
*mut c_void,
) -> c_int, Tcl_AppendObjToObj: extern "C" fn(*mut RawObject, *mut RawObject), Tcl_CreateEncoding: extern "C" fn(*const c_void) -> *mut c_void, Tcl_CreateThreadExitHandler: extern "C" fn(*mut c_void, *mut c_void), Tcl_DeleteThreadExitHandler: extern "C" fn(*mut c_void, *mut c_void), _deprecated_290: *const c_void, Tcl_EvalEx: extern "C" fn(*const Interpreter, *const c_char, usize, c_int) -> c_int, Tcl_EvalObjv: extern "C" fn(*const Interpreter, usize, *mut c_void, c_int) -> c_int, Tcl_EvalObjEx: extern "C" fn(*const Interpreter, *mut RawObject, c_int) -> c_int, Tcl_ExitThread: extern "C" fn(c_int), Tcl_ExternalToUtf: extern "C" fn(
*const Interpreter,
*mut c_void,
*const c_char,
usize,
c_int,
*mut c_void,
*mut c_char,
usize,
*mut c_void,
*mut c_void,
*mut c_void,
) -> c_int, Tcl_ExternalToUtfDString:
extern "C" fn(*mut c_void, *const c_char, usize, *mut c_void) -> *mut c_char, Tcl_FinalizeThread: extern "C" fn(), Tcl_FinalizeNotifier: extern "C" fn(*mut c_void), Tcl_FreeEncoding: extern "C" fn(*mut c_void), Tcl_GetCurrentThread: extern "C" fn() -> *mut c_void, Tcl_GetEncoding: extern "C" fn(*const Interpreter, *const c_char) -> *mut c_void, Tcl_GetEncodingName: extern "C" fn(*mut c_void) -> *const c_char, Tcl_GetEncodingNames: extern "C" fn(*const Interpreter), Tcl_GetIndexFromObjStruct: extern "C" fn(
*const Interpreter,
*mut RawObject,
*const c_void,
usize,
*const c_char,
c_int,
*mut c_void,
) -> c_int, Tcl_GetThreadData: extern "C" fn(*mut c_void, usize) -> *mut c_void, Tcl_GetVar2Ex:
extern "C" fn(*const Interpreter, *const c_char, *const c_char, c_int) -> *mut RawObject, Tcl_InitNotifier: extern "C" fn() -> *mut c_void, Tcl_MutexLock: extern "C" fn(*mut c_void), Tcl_MutexUnlock: extern "C" fn(*mut c_void), Tcl_ConditionNotify: extern "C" fn(*mut c_void), Tcl_ConditionWait: extern "C" fn(*mut c_void, *mut c_void, *const c_void), TclNumUtfChars: extern "C" fn(*const c_char, usize) -> usize, Tcl_ReadChars: extern "C" fn(*mut c_void, *mut RawObject, usize, c_int) -> usize, _deprecated_314: *const c_void, _deprecated_315: *const c_void, Tcl_SetSystemEncoding: extern "C" fn(*const Interpreter, *const c_char) -> c_int, Tcl_SetVar2Ex: extern "C" fn(
*const Interpreter,
*const c_char,
*const c_char,
*mut RawObject,
c_int,
) -> *mut RawObject, Tcl_ThreadAlert: extern "C" fn(*mut c_void), Tcl_ThreadQueueEvent: extern "C" fn(*mut c_void, *mut c_void, c_int), Tcl_UniCharAtIndex: extern "C" fn(*const c_char, usize) -> c_int, Tcl_UniCharToLower: extern "C" fn(c_int) -> c_int, Tcl_UniCharToTitle: extern "C" fn(c_int) -> c_int, Tcl_UniCharToUpper: extern "C" fn(c_int) -> c_int, Tcl_UniCharToUtf: extern "C" fn(c_int, *mut c_char) -> usize, TclUtfAtIndex: extern "C" fn(*const c_char, usize) -> *const c_char, TclUtfCharComplete: extern "C" fn(*const c_char, usize) -> c_int, Tcl_UtfBackslash: extern "C" fn(*const c_char, *mut c_void, *mut c_char) -> usize, Tcl_UtfFindFirst: extern "C" fn(*const c_char, c_int) -> *const c_char, Tcl_UtfFindLast: extern "C" fn(*const c_char, c_int) -> *const c_char, TclUtfNext: extern "C" fn(*const c_char) -> *const c_char, TclUtfPrev: extern "C" fn(*const c_char, *const c_char) -> *const c_char, Tcl_UtfToExternal: extern "C" fn(
*const Interpreter,
*mut c_void,
*const c_char,
usize,
c_int,
*mut c_void,
*mut c_char,
usize,
*mut c_void,
*mut c_void,
*mut c_void,
) -> c_int, Tcl_UtfToExternalDString:
extern "C" fn(*mut c_void, *const c_char, usize, *mut c_void) -> *mut c_char, Tcl_UtfToLower: extern "C" fn(*mut c_char) -> usize, Tcl_UtfToTitle: extern "C" fn(*mut c_char) -> usize, Tcl_UtfToChar16: extern "C" fn(*const c_char, *mut c_void) -> usize, Tcl_UtfToUpper: extern "C" fn(*mut c_char) -> usize, Tcl_WriteChars: extern "C" fn(*mut c_void, *const c_char, usize) -> usize, Tcl_WriteObj: extern "C" fn(*mut c_void, *mut RawObject) -> usize, Tcl_GetString: extern "C" fn(*mut RawObject) -> *mut c_char, _deprecated_341: *const c_void, _deprecated_342: *const c_void, Tcl_AlertNotifier: extern "C" fn(*mut c_void), Tcl_ServiceModeHook: extern "C" fn(c_int), Tcl_UniCharIsAlnum: extern "C" fn(c_int) -> c_int, Tcl_UniCharIsAlpha: extern "C" fn(c_int) -> c_int, Tcl_UniCharIsDigit: extern "C" fn(c_int) -> c_int, Tcl_UniCharIsLower: extern "C" fn(c_int) -> c_int, Tcl_UniCharIsSpace: extern "C" fn(c_int) -> c_int, Tcl_UniCharIsUpper: extern "C" fn(c_int) -> c_int, Tcl_UniCharIsWordChar: extern "C" fn(c_int) -> c_int, Tcl_Char16Len: extern "C" fn(*const c_void) -> usize, _deprecated_353: *const c_void, Tcl_Char16ToUtfDString: extern "C" fn(*const c_void, usize, *mut c_void) -> *mut c_char, Tcl_UtfToChar16DString: extern "C" fn(*const c_char, usize, *mut c_void) -> *mut c_void, Tcl_GetRegExpFromObj: extern "C" fn(*const Interpreter, *mut RawObject, c_int) -> *mut c_void, _deprecated_357: *const c_void, Tcl_FreeParse: extern "C" fn(*mut c_void), Tcl_LogCommandInfo: extern "C" fn(*const Interpreter, *const c_char, *const c_char, usize), Tcl_ParseBraces: extern "C" fn(
*const Interpreter,
*const c_char,
usize,
*mut c_void,
c_int,
*const c_void,
) -> c_int, Tcl_ParseCommand:
extern "C" fn(*const Interpreter, *const c_char, usize, c_int, *mut c_void) -> c_int, Tcl_ParseExpr: extern "C" fn(*const Interpreter, *const c_char, usize, *mut c_void) -> c_int, Tcl_ParseQuotedString: extern "C" fn(
*const Interpreter,
*const c_char,
usize,
*mut c_void,
c_int,
*const c_void,
) -> c_int, Tcl_ParseVarName:
extern "C" fn(*const Interpreter, *const c_char, usize, *mut c_void, c_int) -> c_int, Tcl_GetCwd: extern "C" fn(*const Interpreter, *mut c_void) -> *mut c_char, Tcl_Chdir: extern "C" fn(*const c_char) -> c_int, Tcl_Access: extern "C" fn(*const c_char, c_int) -> c_int, Tcl_Stat: extern "C" fn(*const c_char, *mut c_void) -> c_int, TclUtfNcmp: extern "C" fn(*const c_char, *const c_char, *mut c_void) -> c_int, TclUtfNcasecmp: extern "C" fn(*const c_char, *const c_char, *mut c_void) -> c_int, Tcl_StringCaseMatch: extern "C" fn(*const c_char, *const c_char, c_int) -> c_int, Tcl_UniCharIsControl: extern "C" fn(c_int) -> c_int, Tcl_UniCharIsGraph: extern "C" fn(c_int) -> c_int, Tcl_UniCharIsPrint: extern "C" fn(c_int) -> c_int, Tcl_UniCharIsPunct: extern "C" fn(c_int) -> c_int, Tcl_RegExpExecObj: extern "C" fn(
*const Interpreter,
*mut c_void,
*mut RawObject,
usize,
usize,
c_int,
) -> c_int, Tcl_RegExpGetInfo: extern "C" fn(*mut c_void, *mut c_void), Tcl_NewUnicodeObj: extern "C" fn(*const c_void, usize) -> *mut RawObject, Tcl_SetUnicodeObj: extern "C" fn(*mut RawObject, *const c_void, usize), TclGetCharLength: extern "C" fn(*mut RawObject) -> usize, TclGetUniChar: extern "C" fn(*mut RawObject, usize) -> c_int, _deprecated_382: *const c_void, TclGetRange: extern "C" fn(*mut RawObject, usize, usize) -> *mut RawObject, Tcl_AppendUnicodeToObj: extern "C" fn(*mut RawObject, *const c_void, usize), Tcl_RegExpMatchObj: extern "C" fn(*const Interpreter, *mut RawObject, *mut RawObject) -> c_int, Tcl_SetNotifier: extern "C" fn(*const c_void), Tcl_GetAllocMutex: extern "C" fn() -> *mut c_void, Tcl_GetChannelNames: extern "C" fn(*const Interpreter) -> c_int, Tcl_GetChannelNamesEx: extern "C" fn(*const Interpreter, *const c_char) -> c_int, Tcl_ProcObjCmd: extern "C" fn(*mut c_void, *const Interpreter, usize, *mut c_void) -> c_int, Tcl_ConditionFinalize: extern "C" fn(*mut c_void), Tcl_MutexFinalize: extern "C" fn(*mut c_void), Tcl_CreateThread: extern "C" fn(*mut c_void, *mut c_void, *mut c_void, usize, c_int) -> c_int, Tcl_ReadRaw: extern "C" fn(*mut c_void, *mut c_char, usize) -> usize, Tcl_WriteRaw: extern "C" fn(*mut c_void, *const c_char, usize) -> usize, Tcl_GetTopChannel: extern "C" fn(*mut c_void) -> *mut c_void, Tcl_ChannelBuffered: extern "C" fn(*mut c_void) -> c_int, Tcl_ChannelName: extern "C" fn(*const c_void) -> *const c_char, Tcl_ChannelVersion: extern "C" fn(*const c_void) -> *mut c_void, Tcl_ChannelBlockModeProc: extern "C" fn(*const c_void) -> *mut c_void, _deprecated_401: *const c_void, Tcl_ChannelClose2Proc: extern "C" fn(*const c_void) -> *mut c_void, Tcl_ChannelInputProc: extern "C" fn(*const c_void) -> *mut c_void, Tcl_ChannelOutputProc: extern "C" fn(*const c_void) -> *mut c_void, _deprecated_405: *const c_void, Tcl_ChannelSetOptionProc: extern "C" fn(*const c_void) -> *mut c_void, Tcl_ChannelGetOptionProc: extern "C" fn(*const c_void) -> *mut c_void, Tcl_ChannelWatchProc: extern "C" fn(*const c_void) -> *mut c_void, Tcl_ChannelGetHandleProc: extern "C" fn(*const c_void) -> *mut c_void, Tcl_ChannelFlushProc: extern "C" fn(*const c_void) -> *mut c_void, Tcl_ChannelHandlerProc: extern "C" fn(*const c_void) -> *mut c_void, Tcl_JoinThread: extern "C" fn(*mut c_void, *mut c_void) -> c_int, Tcl_IsChannelShared: extern "C" fn(*mut c_void) -> c_int, Tcl_IsChannelRegistered: extern "C" fn(*const Interpreter, *mut c_void) -> c_int, Tcl_CutChannel: extern "C" fn(*mut c_void), Tcl_SpliceChannel: extern "C" fn(*mut c_void), Tcl_ClearChannelHandlers: extern "C" fn(*mut c_void), Tcl_IsChannelExisting: extern "C" fn(*const c_char) -> c_int, _deprecated_419: *const c_void, _deprecated_420: *const c_void, _deprecated_421: *const c_void, Tcl_CreateHashEntry: extern "C" fn(*mut c_void, *const c_void, *mut c_void) -> *mut c_void, Tcl_InitCustomHashTable: extern "C" fn(*mut c_void, c_int, *const c_void), Tcl_InitObjHashTable: extern "C" fn(*mut c_void), Tcl_CommandTraceInfo: extern "C" fn(
*const Interpreter,
*const c_char,
c_int,
*mut c_void,
*mut c_void,
) -> *mut c_void, Tcl_TraceCommand:
extern "C" fn(*const Interpreter, *const c_char, c_int, *mut c_void, *mut c_void) -> c_int, Tcl_UntraceCommand:
extern "C" fn(*const Interpreter, *const c_char, c_int, *mut c_void, *mut c_void), Tcl_AttemptAlloc: extern "C" fn(usize) -> *mut c_void, Tcl_AttemptDbCkalloc: extern "C" fn(usize, *const c_char, c_int) -> *mut c_void, Tcl_AttemptRealloc: extern "C" fn(*mut c_void, usize) -> *mut c_void, Tcl_AttemptDbCkrealloc: extern "C" fn(*mut c_void, usize, *const c_char, c_int) -> *mut c_void, Tcl_AttemptSetObjLength: extern "C" fn(*mut RawObject, usize) -> c_int, Tcl_GetChannelThread: extern "C" fn(*mut c_void) -> *mut c_void, TclGetUnicodeFromObj: extern "C" fn(*mut RawObject, *mut c_void) -> *mut c_void, _deprecated_435: *const c_void, _deprecated_436: *const c_void, Tcl_SubstObj: extern "C" fn(*const Interpreter, *mut RawObject, c_int) -> *mut RawObject, Tcl_DetachChannel: extern "C" fn(*const Interpreter, *mut c_void) -> c_int, Tcl_IsStandardChannel: extern "C" fn(*mut c_void) -> c_int, Tcl_FSCopyFile: extern "C" fn(*mut RawObject, *mut RawObject) -> c_int, Tcl_FSCopyDirectory: extern "C" fn(*mut RawObject, *mut RawObject, *mut c_void) -> c_int, Tcl_FSCreateDirectory: extern "C" fn(*mut RawObject) -> c_int, Tcl_FSDeleteFile: extern "C" fn(*mut RawObject) -> c_int, Tcl_FSLoadFile: extern "C" fn(
*const Interpreter,
*mut RawObject,
*const c_char,
*const c_char,
*mut c_void,
*mut c_void,
*mut c_void,
*mut c_void,
) -> c_int, Tcl_FSMatchInDirectory: extern "C" fn(
*const Interpreter,
*mut RawObject,
*mut RawObject,
*const c_char,
*mut c_void,
) -> c_int, Tcl_FSLink: extern "C" fn(*mut RawObject, *mut RawObject, c_int) -> *mut RawObject, Tcl_FSRemoveDirectory: extern "C" fn(*mut RawObject, c_int, *mut c_void) -> c_int, Tcl_FSRenameFile: extern "C" fn(*mut RawObject, *mut RawObject) -> c_int, Tcl_FSLstat: extern "C" fn(*mut RawObject, *mut c_void) -> c_int, Tcl_FSUtime: extern "C" fn(*mut RawObject, *mut c_void) -> c_int, Tcl_FSFileAttrsGet:
extern "C" fn(*const Interpreter, c_int, *mut RawObject, *mut c_void) -> c_int, Tcl_FSFileAttrsSet:
extern "C" fn(*const Interpreter, c_int, *mut RawObject, *mut RawObject) -> c_int, Tcl_FSFileAttrStrings: extern "C" fn(*mut RawObject, *mut c_void) -> *const c_void, Tcl_FSStat: extern "C" fn(*mut RawObject, *mut c_void) -> c_int, Tcl_FSAccess: extern "C" fn(*mut RawObject, c_int) -> c_int, Tcl_FSOpenFileChannel:
extern "C" fn(*const Interpreter, *mut RawObject, *const c_char, c_int) -> *mut c_void, Tcl_FSGetCwd: extern "C" fn(*const Interpreter) -> *mut RawObject, Tcl_FSChdir: extern "C" fn(*mut RawObject) -> c_int, Tcl_FSConvertToPathType: extern "C" fn(*const Interpreter, *mut RawObject) -> c_int, Tcl_FSJoinPath: extern "C" fn(*mut RawObject, usize) -> *mut RawObject, TclFSSplitPath: extern "C" fn(*mut RawObject, *mut c_void) -> *mut RawObject, Tcl_FSEqualPaths: extern "C" fn(*mut RawObject, *mut RawObject) -> c_int, Tcl_FSGetNormalizedPath: extern "C" fn(*const Interpreter, *mut RawObject) -> *mut RawObject, Tcl_FSJoinToPath: extern "C" fn(*mut RawObject, usize, *mut c_void) -> *mut RawObject, Tcl_FSGetInternalRep: extern "C" fn(*mut RawObject, *const c_void) -> *mut c_void, Tcl_FSGetTranslatedPath: extern "C" fn(*const Interpreter, *mut RawObject) -> *mut RawObject, Tcl_FSEvalFile: extern "C" fn(*const Interpreter, *mut RawObject) -> c_int, Tcl_FSNewNativePath: extern "C" fn(*const c_void, *mut c_void) -> *mut RawObject, Tcl_FSGetNativePath: extern "C" fn(*mut RawObject) -> *const c_void, Tcl_FSFileSystemInfo: extern "C" fn(*mut RawObject) -> *mut RawObject, Tcl_FSPathSeparator: extern "C" fn(*mut RawObject) -> *mut RawObject, Tcl_FSListVolumes: extern "C" fn() -> *mut RawObject, Tcl_FSRegister: extern "C" fn(*mut c_void, *const c_void) -> c_int, Tcl_FSUnregister: extern "C" fn(*const c_void) -> c_int, Tcl_FSData: extern "C" fn(*const c_void) -> *mut c_void, Tcl_FSGetTranslatedStringPath:
extern "C" fn(*const Interpreter, *mut RawObject) -> *const c_char, Tcl_FSGetFileSystemForPath: extern "C" fn(*mut RawObject) -> *const c_void, Tcl_FSGetPathType: extern "C" fn(*mut RawObject) -> *mut c_void, Tcl_OutputBuffered: extern "C" fn(*mut c_void) -> c_int, Tcl_FSMountsChanged: extern "C" fn(*const c_void), Tcl_EvalTokensStandard: extern "C" fn(*const Interpreter, *mut c_void, usize) -> c_int, Tcl_GetTime: extern "C" fn(*mut c_void), Tcl_CreateObjTrace: extern "C" fn(
*const Interpreter,
usize,
c_int,
*mut c_void,
*mut c_void,
*mut c_void,
) -> *mut c_void, Tcl_GetCommandInfoFromToken: extern "C" fn(*mut c_void, *mut c_void) -> c_int, Tcl_SetCommandInfoFromToken: extern "C" fn(*mut c_void, *const c_void) -> c_int, Tcl_DbNewWideIntObj: extern "C" fn(*mut c_void, *const c_char, c_int) -> *mut RawObject, Tcl_GetWideIntFromObj: extern "C" fn(*const Interpreter, *mut RawObject, *mut c_void) -> c_int, Tcl_NewWideIntObj: extern "C" fn(*mut c_void) -> *mut RawObject, Tcl_SetWideIntObj: extern "C" fn(*mut RawObject, *mut c_void), Tcl_AllocStatBuf: extern "C" fn() -> *mut c_void, Tcl_Seek: extern "C" fn(*mut c_void, c_longlong, c_int) -> c_longlong, Tcl_Tell: extern "C" fn(*mut c_void) -> c_longlong, Tcl_ChannelWideSeekProc: extern "C" fn(*const c_void) -> *mut c_void, Tcl_DictObjPut:
extern "C" fn(*const Interpreter, *mut RawObject, *mut RawObject, *mut RawObject) -> c_int, Tcl_DictObjGet:
extern "C" fn(*const Interpreter, *mut RawObject, *mut RawObject, *mut c_void) -> c_int, Tcl_DictObjRemove: extern "C" fn(*const Interpreter, *mut RawObject, *mut RawObject) -> c_int, TclDictObjSize: extern "C" fn(*const Interpreter, *mut RawObject, *mut c_void) -> c_int, Tcl_DictObjFirst: extern "C" fn(
*const Interpreter,
*mut RawObject,
*mut c_void,
*mut c_void,
*mut c_void,
*mut c_void,
) -> c_int, Tcl_DictObjNext: extern "C" fn(*mut c_void, *mut c_void, *mut c_void, *mut c_void), Tcl_DictObjDone: extern "C" fn(*mut c_void), Tcl_DictObjPutKeyList: extern "C" fn(
*const Interpreter,
*mut RawObject,
usize,
*mut c_void,
*mut RawObject,
) -> c_int, Tcl_DictObjRemoveKeyList:
extern "C" fn(*const Interpreter, *mut RawObject, usize, *mut c_void) -> c_int, Tcl_NewDictObj: extern "C" fn() -> *mut RawObject, Tcl_DbNewDictObj: extern "C" fn(*const c_char, c_int) -> *mut RawObject, Tcl_RegisterConfig:
extern "C" fn(*const Interpreter, *const c_char, *const c_void, *const c_char), Tcl_CreateNamespace:
extern "C" fn(*const Interpreter, *const c_char, *mut c_void, *mut c_void) -> *mut c_void, Tcl_DeleteNamespace: extern "C" fn(*mut c_void), Tcl_AppendExportList: extern "C" fn(*const Interpreter, *mut c_void, *mut RawObject) -> c_int, Tcl_Export: extern "C" fn(*const Interpreter, *mut c_void, *const c_char, c_int) -> c_int, Tcl_Import: extern "C" fn(*const Interpreter, *mut c_void, *const c_char, c_int) -> c_int, Tcl_ForgetImport: extern "C" fn(*const Interpreter, *mut c_void, *const c_char) -> c_int, Tcl_GetCurrentNamespace: extern "C" fn(*const Interpreter) -> *mut c_void, Tcl_GetGlobalNamespace: extern "C" fn(*const Interpreter) -> *mut c_void, Tcl_FindNamespace:
extern "C" fn(*const Interpreter, *const c_char, *mut c_void, c_int) -> *mut c_void, Tcl_FindCommand:
extern "C" fn(*const Interpreter, *const c_char, *mut c_void, c_int) -> *mut c_void, Tcl_GetCommandFromObj: extern "C" fn(*const Interpreter, *mut RawObject) -> *mut c_void, Tcl_GetCommandFullName: extern "C" fn(*const Interpreter, *mut c_void, *mut RawObject), Tcl_FSEvalFileEx: extern "C" fn(*const Interpreter, *mut RawObject, *const c_char) -> c_int, _deprecated_519: *const c_void, Tcl_LimitAddHandler:
extern "C" fn(*const Interpreter, c_int, *mut c_void, *mut c_void, *mut c_void), Tcl_LimitRemoveHandler: extern "C" fn(*const Interpreter, c_int, *mut c_void, *mut c_void), Tcl_LimitReady: extern "C" fn(*const Interpreter) -> c_int, Tcl_LimitCheck: extern "C" fn(*const Interpreter) -> c_int, Tcl_LimitExceeded: extern "C" fn(*const Interpreter) -> c_int, Tcl_LimitSetCommands: extern "C" fn(*const Interpreter, usize), Tcl_LimitSetTime: extern "C" fn(*const Interpreter, *mut c_void), Tcl_LimitSetGranularity: extern "C" fn(*const Interpreter, c_int, c_int), Tcl_LimitTypeEnabled: extern "C" fn(*const Interpreter, c_int) -> c_int, Tcl_LimitTypeExceeded: extern "C" fn(*const Interpreter, c_int) -> c_int, Tcl_LimitTypeSet: extern "C" fn(*const Interpreter, c_int), Tcl_LimitTypeReset: extern "C" fn(*const Interpreter, c_int), Tcl_LimitGetCommands: extern "C" fn(*const Interpreter) -> usize, Tcl_LimitGetTime: extern "C" fn(*const Interpreter, *mut c_void), Tcl_LimitGetGranularity: extern "C" fn(*const Interpreter, c_int) -> c_int, Tcl_SaveInterpState: extern "C" fn(*const Interpreter, c_int) -> *mut c_void, Tcl_RestoreInterpState: extern "C" fn(*const Interpreter, *mut c_void) -> c_int, Tcl_DiscardInterpState: extern "C" fn(*mut c_void), Tcl_SetReturnOptions: extern "C" fn(*const Interpreter, *mut RawObject) -> c_int, Tcl_GetReturnOptions: extern "C" fn(*const Interpreter, c_int) -> *mut RawObject, Tcl_IsEnsemble: extern "C" fn(*mut c_void) -> c_int, Tcl_CreateEnsemble:
extern "C" fn(*const Interpreter, *const c_char, *mut c_void, c_int) -> *mut c_void, Tcl_FindEnsemble: extern "C" fn(*const Interpreter, *mut RawObject, c_int) -> *mut c_void, Tcl_SetEnsembleSubcommandList:
extern "C" fn(*const Interpreter, *mut c_void, *mut RawObject) -> c_int, Tcl_SetEnsembleMappingDict:
extern "C" fn(*const Interpreter, *mut c_void, *mut RawObject) -> c_int, Tcl_SetEnsembleUnknownHandler:
extern "C" fn(*const Interpreter, *mut c_void, *mut RawObject) -> c_int, Tcl_SetEnsembleFlags: extern "C" fn(*const Interpreter, *mut c_void, c_int) -> c_int, Tcl_GetEnsembleSubcommandList:
extern "C" fn(*const Interpreter, *mut c_void, *mut c_void) -> c_int, Tcl_GetEnsembleMappingDict:
extern "C" fn(*const Interpreter, *mut c_void, *mut c_void) -> c_int, Tcl_GetEnsembleUnknownHandler:
extern "C" fn(*const Interpreter, *mut c_void, *mut c_void) -> c_int, Tcl_GetEnsembleFlags: extern "C" fn(*const Interpreter, *mut c_void, *mut c_void) -> c_int, Tcl_GetEnsembleNamespace: extern "C" fn(*const Interpreter, *mut c_void, *mut c_void) -> c_int, Tcl_SetTimeProc: extern "C" fn(*mut c_void, *mut c_void, *mut c_void), Tcl_QueryTimeProc: extern "C" fn(*mut c_void, *mut c_void, *mut c_void), Tcl_ChannelThreadActionProc: extern "C" fn(*const c_void) -> *mut c_void, Tcl_NewBignumObj: extern "C" fn(*mut c_void) -> *mut RawObject, Tcl_DbNewBignumObj: extern "C" fn(*mut c_void, *const c_char, c_int) -> *mut RawObject, Tcl_SetBignumObj: extern "C" fn(*mut RawObject, *mut c_void), Tcl_GetBignumFromObj: extern "C" fn(*const Interpreter, *mut RawObject, *mut c_void) -> c_int, Tcl_TakeBignumFromObj: extern "C" fn(*const Interpreter, *mut RawObject, *mut c_void) -> c_int, Tcl_TruncateChannel: extern "C" fn(*mut c_void, c_longlong) -> c_int, Tcl_ChannelTruncateProc: extern "C" fn(*const c_void) -> *mut c_void, Tcl_SetChannelErrorInterp: extern "C" fn(*const Interpreter, *mut RawObject), Tcl_GetChannelErrorInterp: extern "C" fn(*const Interpreter, *mut c_void), Tcl_SetChannelError: extern "C" fn(*mut c_void, *mut RawObject), Tcl_GetChannelError: extern "C" fn(*mut c_void, *mut c_void), Tcl_InitBignumFromDouble: extern "C" fn(*const Interpreter, c_double, *mut c_void) -> c_int, Tcl_GetNamespaceUnknownHandler:
extern "C" fn(*const Interpreter, *mut c_void) -> *mut RawObject, Tcl_SetNamespaceUnknownHandler:
extern "C" fn(*const Interpreter, *mut c_void, *mut RawObject) -> c_int, Tcl_GetEncodingFromObj: extern "C" fn(*const Interpreter, *mut RawObject, *mut c_void) -> c_int, Tcl_GetEncodingSearchPath: extern "C" fn() -> *mut RawObject, Tcl_SetEncodingSearchPath: extern "C" fn(*mut RawObject) -> c_int, Tcl_GetEncodingNameFromEnvironment: extern "C" fn(*mut c_void) -> *const c_char, Tcl_PkgRequireProc:
extern "C" fn(*const Interpreter, *const c_char, usize, *mut c_void, *mut c_void) -> c_int, Tcl_AppendObjToErrorInfo: extern "C" fn(*const Interpreter, *mut RawObject), Tcl_AppendLimitedToObj:
extern "C" fn(*mut RawObject, *const c_char, usize, usize, *const c_char), Tcl_Format:
extern "C" fn(*const Interpreter, *const c_char, usize, *mut c_void) -> *mut RawObject, Tcl_AppendFormatToObj: extern "C" fn(
*const Interpreter,
*mut RawObject,
*const c_char,
usize,
*mut c_void,
) -> c_int, Tcl_ObjPrintf: extern "C" fn(*const c_char, *const c_char) -> *mut RawObject, Tcl_AppendPrintfToObj: extern "C" fn(*mut RawObject, *const c_char, *const c_char), Tcl_CancelEval: extern "C" fn(*const Interpreter, *mut RawObject, *mut c_void, c_int) -> c_int, Tcl_Canceled: extern "C" fn(*const Interpreter, c_int) -> c_int, Tcl_CreatePipe: extern "C" fn(*mut c_void, *mut c_void, *mut c_void, c_int) -> c_int, Tcl_NRCreateCommand: extern "C" fn(
*const Interpreter,
*const c_char,
*mut c_void,
*mut c_void,
*mut c_void,
*mut c_void,
) -> *mut c_void, Tcl_NREvalObj: extern "C" fn(*const Interpreter, *mut RawObject, c_int) -> c_int, Tcl_NREvalObjv: extern "C" fn(*const Interpreter, usize, *mut c_void, c_int) -> c_int, Tcl_NRCmdSwap:
extern "C" fn(*const Interpreter, *mut c_void, usize, *mut c_void, c_int) -> c_int, Tcl_NRAddCallback: extern "C" fn(
*const Interpreter,
*mut c_void,
*mut c_void,
*mut c_void,
*mut c_void,
*mut c_void,
), Tcl_NRCallObjProc:
extern "C" fn(*const Interpreter, *mut c_void, *mut c_void, usize, *mut c_void) -> c_int, Tcl_GetFSDeviceFromStat: extern "C" fn(*const c_void) -> *mut c_void, Tcl_GetFSInodeFromStat: extern "C" fn(*const c_void) -> *mut c_void, Tcl_GetModeFromStat: extern "C" fn(*const c_void) -> *mut c_void, Tcl_GetLinkCountFromStat: extern "C" fn(*const c_void) -> c_int, Tcl_GetUserIdFromStat: extern "C" fn(*const c_void) -> c_int, Tcl_GetGroupIdFromStat: extern "C" fn(*const c_void) -> c_int, Tcl_GetDeviceTypeFromStat: extern "C" fn(*const c_void) -> c_int, Tcl_GetAccessTimeFromStat: extern "C" fn(*const c_void) -> c_longlong, Tcl_GetModificationTimeFromStat: extern "C" fn(*const c_void) -> c_longlong, Tcl_GetChangeTimeFromStat: extern "C" fn(*const c_void) -> c_longlong, Tcl_GetSizeFromStat: extern "C" fn(*const c_void) -> c_ulonglong, Tcl_GetBlocksFromStat: extern "C" fn(*const c_void) -> c_ulonglong, Tcl_GetBlockSizeFromStat: extern "C" fn(*const c_void) -> *mut c_void, Tcl_SetEnsembleParameterList:
extern "C" fn(*const Interpreter, *mut c_void, *mut RawObject) -> c_int, Tcl_GetEnsembleParameterList:
extern "C" fn(*const Interpreter, *mut c_void, *mut c_void) -> c_int, TclParseArgsObjv: extern "C" fn(
*const Interpreter,
*const c_void,
*mut c_void,
*mut c_void,
*mut c_void,
) -> c_int, Tcl_GetErrorLine: extern "C" fn(*const Interpreter) -> c_int, Tcl_SetErrorLine: extern "C" fn(*const Interpreter, c_int), Tcl_TransferResult: extern "C" fn(*const Interpreter, c_int, *const Interpreter), Tcl_InterpActive: extern "C" fn(*const Interpreter) -> c_int, Tcl_BackgroundException: extern "C" fn(*const Interpreter, c_int), Tcl_ZlibDeflate:
extern "C" fn(*const Interpreter, c_int, *mut RawObject, c_int, *mut RawObject) -> c_int, Tcl_ZlibInflate:
extern "C" fn(*const Interpreter, c_int, *mut RawObject, usize, *mut RawObject) -> c_int, Tcl_ZlibCRC32: extern "C" fn(c_uint, *const c_void, usize) -> c_uint, Tcl_ZlibAdler32: extern "C" fn(c_uint, *const c_void, usize) -> c_uint, Tcl_ZlibStreamInit: extern "C" fn(
*const Interpreter,
c_int,
c_int,
c_int,
*mut RawObject,
*mut c_void,
) -> c_int, Tcl_ZlibStreamGetCommandName: extern "C" fn(*mut c_void) -> *mut RawObject, Tcl_ZlibStreamEof: extern "C" fn(*mut c_void) -> c_int, Tcl_ZlibStreamChecksum: extern "C" fn(*mut c_void) -> c_int, Tcl_ZlibStreamPut: extern "C" fn(*mut c_void, *mut RawObject, c_int) -> c_int, Tcl_ZlibStreamGet: extern "C" fn(*mut c_void, *mut RawObject, usize) -> c_int, Tcl_ZlibStreamClose: extern "C" fn(*mut c_void) -> c_int, Tcl_ZlibStreamReset: extern "C" fn(*mut c_void) -> c_int, Tcl_SetStartupScript: extern "C" fn(*mut RawObject, *const c_char), Tcl_GetStartupScript: extern "C" fn(*const c_void) -> *mut RawObject, Tcl_CloseEx: extern "C" fn(*const Interpreter, *mut c_void, c_int) -> c_int, Tcl_NRExprObj: extern "C" fn(*const Interpreter, *mut RawObject, *mut RawObject) -> c_int, Tcl_NRSubstObj: extern "C" fn(*const Interpreter, *mut RawObject, c_int) -> c_int, Tcl_LoadFile: extern "C" fn(
*const Interpreter,
*mut RawObject,
*mut c_void,
c_int,
*mut c_void,
*mut c_void,
) -> c_int, Tcl_FindSymbol: extern "C" fn(*const Interpreter, *mut c_void, *const c_char) -> *mut c_void, Tcl_FSUnloadFile: extern "C" fn(*const Interpreter, *mut c_void) -> c_int, Tcl_ZlibStreamSetCompressionDictionary: extern "C" fn(*mut c_void, *mut RawObject), Tcl_OpenTcpServerEx: extern "C" fn(
*const Interpreter,
*const c_char,
*const c_char,
c_uint,
c_int,
*mut c_void,
*mut c_void,
) -> *mut c_void, TclZipfs_Mount:
extern "C" fn(*const Interpreter, *const c_char, *const c_char, *const c_char) -> c_int, TclZipfs_Unmount: extern "C" fn(*const Interpreter, *const c_char) -> c_int, TclZipfs_TclLibrary: extern "C" fn() -> *mut RawObject, TclZipfs_MountBuffer: extern "C" fn(
*const Interpreter,
*const c_void,
*mut c_void,
*const c_char,
c_int,
) -> c_int, Tcl_FreeInternalRep: extern "C" fn(*mut RawObject), Tcl_InitStringRep: extern "C" fn(*mut RawObject, *const c_char, usize) -> *mut c_char, Tcl_FetchInternalRep: extern "C" fn(*mut RawObject, *const ObjectType) -> *mut c_void, Tcl_StoreInternalRep: extern "C" fn(*mut RawObject, *const ObjectType, *const c_void), Tcl_HasStringRep: extern "C" fn(*mut RawObject) -> c_int, Tcl_IncrRefCount: extern "C" fn(*mut RawObject), Tcl_DecrRefCount: extern "C" fn(*mut RawObject), Tcl_IsShared: extern "C" fn(*mut RawObject) -> c_int, Tcl_LinkArray:
extern "C" fn(*const Interpreter, *const c_char, *mut c_void, c_int, usize) -> c_int, Tcl_GetIntForIndex:
extern "C" fn(*const Interpreter, *mut RawObject, usize, *mut c_void) -> c_int, Tcl_UtfToUniChar: extern "C" fn(*const c_char, *mut c_void) -> usize, Tcl_UniCharToUtfDString: extern "C" fn(*const c_void, usize, *mut c_void) -> *mut c_char, Tcl_UtfToUniCharDString: extern "C" fn(*const c_char, usize, *mut c_void) -> *mut c_void, TclGetBytesFromObj:
extern "C" fn(*const Interpreter, *mut RawObject, *mut c_void) -> *mut c_void, Tcl_GetBytesFromObj:
extern "C" fn(*const Interpreter, *mut RawObject, *mut c_void) -> *mut c_void, Tcl_GetStringFromObj: extern "C" fn(*mut RawObject, *mut c_void) -> *mut c_char, Tcl_GetUnicodeFromObj: extern "C" fn(*mut RawObject, *mut c_void) -> *mut c_void, Tcl_GetSizeIntFromObj: extern "C" fn(*const Interpreter, *mut RawObject, *mut c_void) -> c_int, Tcl_UtfCharComplete: extern "C" fn(*const c_char, usize) -> c_int, Tcl_UtfNext: extern "C" fn(*const c_char) -> *const c_char, Tcl_UtfPrev: extern "C" fn(*const c_char, *const c_char) -> *const c_char, Tcl_FSTildeExpand: extern "C" fn(*const Interpreter, *const c_char, *mut c_void) -> c_int, Tcl_ExternalToUtfDStringEx: extern "C" fn(
*const Interpreter,
*mut c_void,
*const c_char,
usize,
c_int,
*mut c_void,
*mut c_void,
) -> c_int, Tcl_UtfToExternalDStringEx: extern "C" fn(
*const Interpreter,
*mut c_void,
*const c_char,
usize,
c_int,
*mut c_void,
*mut c_void,
) -> c_int, Tcl_AsyncMarkFromSignal: extern "C" fn(*mut c_void, c_int) -> c_int, Tcl_ListObjGetElements:
extern "C" fn(*const Interpreter, *mut RawObject, *mut c_void, *mut c_void) -> c_int, Tcl_ListObjLength: extern "C" fn(*const Interpreter, *mut RawObject, *mut c_void) -> c_int, Tcl_DictObjSize: extern "C" fn(*const Interpreter, *mut RawObject, *mut c_void) -> c_int, Tcl_SplitList:
extern "C" fn(*const Interpreter, *const c_char, *mut c_void, *const c_void) -> c_int, Tcl_SplitPath: extern "C" fn(*const c_char, *mut c_void, *const c_void), Tcl_FSSplitPath: extern "C" fn(*mut RawObject, *mut c_void) -> *mut RawObject, Tcl_ParseArgsObjv: extern "C" fn(
*const Interpreter,
*const c_void,
*mut c_void,
*mut c_void,
*mut c_void,
) -> c_int, Tcl_UniCharLen: extern "C" fn(*const c_void) -> usize, Tcl_NumUtfChars: extern "C" fn(*const c_char, usize) -> usize, Tcl_GetCharLength: extern "C" fn(*mut RawObject) -> usize, Tcl_UtfAtIndex: extern "C" fn(*const c_char, usize) -> *const c_char, Tcl_GetRange: extern "C" fn(*mut RawObject, usize, usize) -> *mut RawObject, Tcl_GetUniChar: extern "C" fn(*mut RawObject, usize) -> c_int, Tcl_GetBool: extern "C" fn(*const Interpreter, *const c_char, c_int, *mut c_char) -> c_int, Tcl_GetBoolFromObj:
extern "C" fn(*const Interpreter, *mut RawObject, c_int, *mut c_char) -> c_int, Tcl_CreateObjCommand2: extern "C" fn(
*const Interpreter,
*const c_char,
*mut c_void,
*mut c_void,
*mut c_void,
) -> *mut c_void, Tcl_CreateObjTrace2: extern "C" fn(
*const Interpreter,
usize,
c_int,
*mut c_void,
*mut c_void,
*mut c_void,
) -> *mut c_void, Tcl_NRCreateCommand2: extern "C" fn(
*const Interpreter,
*const c_char,
*mut c_void,
*mut c_void,
*mut c_void,
*mut c_void,
) -> *mut c_void, Tcl_NRCallObjProc2:
extern "C" fn(*const Interpreter, *mut c_void, *mut c_void, usize, *mut c_void) -> c_int, Tcl_GetNumberFromObj:
extern "C" fn(*const Interpreter, *mut RawObject, *mut c_void, *mut c_void) -> c_int, Tcl_GetNumber:
extern "C" fn(*const Interpreter, *const c_char, usize, *mut c_void, *mut c_void) -> c_int, Tcl_RemoveChannelMode: extern "C" fn(*const Interpreter, *mut c_void, c_int) -> c_int, Tcl_GetEncodingNulLength: extern "C" fn(*mut c_void) -> usize, Tcl_GetWideUIntFromObj: extern "C" fn(*const Interpreter, *mut RawObject, *mut c_void) -> c_int, Tcl_DStringToObj: extern "C" fn(*mut c_void) -> *mut RawObject, Tcl_UtfNcmp: extern "C" fn(*const c_char, *const c_char, *mut c_void) -> c_int, Tcl_UtfNcasecmp: extern "C" fn(*const c_char, *const c_char, *mut c_void) -> c_int, Tcl_NewWideUIntObj: extern "C" fn(*mut c_void) -> *mut RawObject, Tcl_SetWideUIntObj: extern "C" fn(*mut RawObject, *mut c_void), }
#[derive(Debug)]
pub enum Error {
NullInterpreter,
NullStubs,
InvalidStubs,
TclError(String),
}
impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Error::NullInterpreter => write!(f, "interpreter pointer was null"),
Error::NullStubs => write!(f, "stubs pointer was null"),
Error::InvalidStubs => write!(f, "stubs magic number did not match expected value"),
Error::TclError(msg) => write!(f, "Tcl error: {msg}"),
}
}
}
impl std::error::Error for Error {}
impl<'a> Interpreter {
#[allow(clippy::not_unsafe_ptr_arg_deref)]
pub fn from_raw(interpreter: *const Interpreter) -> Result<&'a Interpreter, Error> {
let interpreter = unsafe { interpreter.as_ref() }.ok_or(Error::NullInterpreter)?;
let stubs = unsafe { interpreter.stubs.as_ref() }.ok_or(Error::NullStubs)?;
if stubs.magic != TCL_STUB_MAGIC {
return Err(Error::InvalidStubs);
}
Ok(interpreter)
}
pub fn init_global_functions(&self) {
unsafe {
let stubs = self
.stubs
.as_ref()
.expect("stubs missing after initial check");
ALLOC = Some(stubs.Tcl_AttemptAlloc);
REALLOC = Some(stubs.Tcl_AttemptRealloc);
FREE = Some(stubs.Tcl_Free);
NEW_OBJ = Some(stubs.Tcl_NewObj);
DUPLICATE_OBJ = Some(stubs.Tcl_DuplicateObj);
INCR_REF_COUNT = Some(stubs.Tcl_IncrRefCount);
DECR_REF_COUNT = Some(stubs.Tcl_DecrRefCount);
IS_SHARED = Some(stubs.Tcl_IsShared);
INVALIDATE_STRING_REP = Some(stubs.Tcl_InvalidateStringRep);
GET_STRING = Some(stubs.Tcl_GetString);
GET_OBJ_TYPE = Some(stubs.Tcl_GetObjType);
CONVERT_TO_TYPE = Some(stubs.Tcl_ConvertToType);
NEW_STRING_OBJ = Some(stubs.Tcl_NewStringObj);
SET_STRING_OBJ = Some(stubs.Tcl_SetStringObj);
}
}
pub fn provide_package(&self, name: &str, version: &str) -> Result<TclStatus, String> {
let name =
CString::new(name).map_err(|_| "unexpected Nul in package version".to_string())?;
let version =
CString::new(version).map_err(|_| "unexpected Nul in package version".to_string())?;
unsafe {
(self
.stubs
.as_ref()
.expect("stubs missing after initial check")
.Tcl_PkgProvideEx)(
self as *const Interpreter,
name.as_ptr(),
version.as_ptr(),
std::ptr::null(),
)
};
Ok(TclStatus::Ok)
}
pub fn create_command(&self, name: &str, proc: CmdProc) -> Result<TclStatus, String> {
let name = CString::new(name).map_err(|_| "unexpected Nul in command name".to_string())?;
extern "C" fn wrapper_proc(
f_ptr: *const c_void,
i: *const Interpreter,
argc: usize,
argv: *const *const i8,
) -> TclStatus {
let interp = Interpreter::from_raw(i).expect("Tcl passed bad interpreter");
let raw_args = unsafe { std::slice::from_raw_parts(argv, argc) };
let mut args = Vec::with_capacity(raw_args.len());
for arg in raw_args {
args.push(
unsafe { std::ffi::CStr::from_ptr(*arg) }
.to_str()
.expect("invalid args from Tcl"),
);
}
let f: CmdProc = unsafe { std::mem::transmute(f_ptr) };
f(interp, args).unwrap_or_else(|s| {
interp.set_result(&s);
TclStatus::Error
})
}
unsafe {
(self
.stubs
.as_ref()
.expect("stubs missing after initial check")
.Tcl_CreateCommand)(
self as *const Interpreter,
name.as_ptr(),
wrapper_proc as *mut c_void,
proc as *mut c_void,
std::ptr::null_mut::<c_void>(),
)
};
Ok(TclStatus::Ok)
}
pub fn create_obj_command(&self, name: &str, proc: ObjCmdProc) -> Result<TclStatus, String> {
let name = CString::new(name).map_err(|_| "unexpected Nul in command name".to_string())?;
extern "C" fn wrapper_proc(
f_ptr: *const c_void,
i: *const Interpreter,
argc: usize,
argv: *const *mut RawObject,
) -> TclStatus {
let interp = Interpreter::from_raw(i).expect("Tcl passed bad interpreter");
let raw_args = unsafe { std::slice::from_raw_parts(argv, argc) };
let mut args = Vec::with_capacity(raw_args.len());
for arg in raw_args {
args.push(RawObject::wrap(*arg));
}
let f: ObjCmdProc = unsafe { std::mem::transmute(f_ptr) };
f(interp, args).unwrap_or_else(|obj| {
interp.set_obj_result(&obj);
TclStatus::Error
})
}
unsafe {
(self
.stubs
.as_ref()
.expect("stubs missing after initial check")
.Tcl_CreateObjCommand)(
self as *const Interpreter,
name.as_ptr(),
wrapper_proc as *mut c_void,
proc as *mut c_void,
std::ptr::null_mut::<c_void>(),
)
};
Ok(TclStatus::Ok)
}
pub fn register_obj_type<T: TclObjectType>(&self) {
unsafe {
(self
.stubs
.as_ref()
.expect("stubs missing after initial check")
.Tcl_RegisterObjType)(T::tcl_type() as *const ObjectType)
}
}
pub fn delete_command(&self, name: &str) -> Result<bool, String> {
let name = CString::new(name).map_err(|_| "unexpected Nul in command name".to_string())?;
let ret = unsafe {
(self
.stubs
.as_ref()
.expect("stubs missing after initial check")
.Tcl_DeleteCommand)(self as *const Interpreter, name.as_ptr())
};
Ok(ret == 0)
}
pub fn get_obj_result(&self) -> Object {
unsafe {
RawObject::wrap((self
.stubs
.as_ref()
.expect("stubs missing after initial check")
.Tcl_GetObjResult)(
self as *const Interpreter
))
}
}
pub fn eval(&self, script: &str) -> Result<Object, Object> {
if script.len() > 1 << 31 {
return Err(
Object::new(), );
}
let status = unsafe {
(self
.stubs
.as_ref()
.expect("stubs missing after initial check")
.Tcl_EvalEx)(
self as *const Interpreter,
script.as_ptr() as *const c_char,
script.len(),
0,
)
};
let result = self.get_obj_result();
if TclStatus::Error == status.into() {
Err(result)
} else {
Ok(result)
}
}
pub fn set_result(&self, text: &str) {
let result = Object::new_string(text);
self.set_obj_result(&result);
}
pub fn set_obj_result(&self, result: &Object) {
unsafe {
(self
.stubs
.as_ref()
.expect("stubs missing after initial check")
.Tcl_SetObjResult)(self as *const Interpreter, result.obj)
}
}
pub fn alloc(&self, size: usize) -> Option<TclBuf> {
if size >= 1 << 32 {
return None;
}
let ptr = unsafe {
(self
.stubs
.as_ref()
.expect("stubs missing after initial check")
.Tcl_AttemptAlloc)(size)
};
if ptr.is_null() {
None
} else {
Some(unsafe { TclBuf::from_raw_parts(ptr as *mut u8, size) })
}
}
}
type CmdDataProc<T> =
fn(interp: &Interpreter, data: &T, args: Vec<&str>) -> Result<TclStatus, String>;
pub struct StatefulCommand<T> {
proc: CmdDataProc<T>,
data: T,
}
impl<T> StatefulCommand<T> {
pub fn new(proc: CmdDataProc<T>, data: T) -> StatefulCommand<T> {
StatefulCommand { proc, data }
}
pub fn attach_command(self, interp: &Interpreter, name: &str) -> Result<TclStatus, String> {
let state = Box::new(self);
let name = CString::new(name).map_err(|_| "unexpected Nul in command name".to_string())?;
extern "C" fn wrapper_proc<T>(
state: *const StatefulCommand<T>,
i: *const Interpreter,
argc: usize,
argv: *const *const i8,
) -> TclStatus {
let interp = Interpreter::from_raw(i).expect("Tcl passed bad interpreter");
let raw_args = unsafe { std::slice::from_raw_parts(argv, argc) };
let mut args = Vec::with_capacity(raw_args.len());
for arg in raw_args {
args.push(
unsafe { std::ffi::CStr::from_ptr(*arg) }
.to_str()
.expect("invalid args from Tcl"),
);
}
let state = unsafe { state.as_ref() }.expect("data command corrupted!");
(state.proc)(interp, &state.data, args).unwrap_or_else(|s| {
interp.set_result(&s);
TclStatus::Error
})
}
fn free_state<T>(state: *mut StatefulCommand<T>) {
unsafe {
let _ = Box::from_raw(state);
};
}
unsafe {
(interp
.stubs
.as_ref()
.expect("stubs missing after initial check")
.Tcl_CreateCommand)(
interp as *const Interpreter,
name.as_ptr(),
wrapper_proc::<T> as *mut c_void,
Box::<StatefulCommand<T>>::into_raw(state) as *mut c_void,
free_state::<T> as *mut c_void,
)
};
Ok(TclStatus::Ok)
}
}