int NS(GetClientData) ( Tcl_Interp * interp, Tcl_Obj * obj, MQ_PTR *out ) { Tcl_CmdInfo infoPtr; Tcl_Command command; *out = NULL; command = Tcl_GetCommandFromObj (interp, obj); if (command == NULL) return TCL_ERROR; Tcl_GetCommandInfoFromToken (command, &infoPtr); *out = infoPtr.objClientData; return TCL_OK; }
int NS(GetClientData) ( Tcl_Interp * interp, Tcl_Obj * obj, MQ_INT signature, MQ_PTR *out ) { MQ_INT *ret; Tcl_CmdInfo infoPtr; Tcl_Command command; *out = NULL; command = Tcl_GetCommandFromObj (interp, obj); if (command == NULL) return TCL_ERROR; Tcl_GetCommandInfoFromToken (command, &infoPtr); ret = infoPtr.objClientData; if (ret == NULL || *ret != signature) return TCL_ERROR; *out = (MQ_PTR) ret; return TCL_OK; }
/*++ Alcoext_Init Initialises the extension for a regular interpreter. Arguments: interp - Current interpreter. Return Value: A standard Tcl result. --*/ int Alcoext_Init( Tcl_Interp *interp ) { int i; ExtState *state; Tcl_CmdInfo cmdInfo; DebugPrint("Init: interp=%p\n", interp); // Wide integer support was added in Tcl 8.4. if (Tcl_InitStubs(interp, "8.4", 0) == NULL) { return TCL_ERROR; } if (Tcl_PkgProvide(interp, PACKAGE_NAME, PACKAGE_VERSION) != TCL_OK) { return TCL_ERROR; } Initialise(); // Allocate state structure. state = (ExtState *)ckalloc(sizeof(ExtState)); memset(state, 0, sizeof(ExtState)); state->interp = interp; state->cryptTable = (Tcl_HashTable *)ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(state->cryptTable, TCL_STRING_KEYS); #ifndef _WINDOWS state->glftpdTable = (Tcl_HashTable *)ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(state->glftpdTable, TCL_STRING_KEYS); #endif Tcl_MutexLock(&stateListMutex); // Insert at the list head. if (stateHead == NULL) { stateHead = state; } else { state->next = stateHead; stateHead->prev = state; stateHead = state; } Tcl_MutexUnlock(&stateListMutex); // Clean up state on interpreter deletion. Tcl_CallWhenDeleted(interp, InterpDeleted, (ClientData)state); // Create Tcl commands. state->cmds[0] = Tcl_CreateObjCommand(interp, "compress", CompressObjCmd, NULL, CmdDeleted); state->cmds[1] = Tcl_CreateObjCommand(interp, "crypt", CryptObjCmd, (ClientData)state, CmdDeleted); state->cmds[2] = Tcl_CreateObjCommand(interp, "decode", EncodingObjCmd, (ClientData)decodeFuncts, CmdDeleted); state->cmds[3] = Tcl_CreateObjCommand(interp, "encode", EncodingObjCmd, (ClientData)encodeFuncts, CmdDeleted); // // These commands are not created for safe interpreters because // they interact with the file system and/or other processes. // if (!Tcl_IsSafe(interp)) { state->cmds[4] = Tcl_CreateObjCommand(interp, "volume", VolumeObjCmd, NULL, CmdDeleted); #ifdef _WINDOWS state->cmds[5] = Tcl_CreateObjCommand(interp, "ioftpd", IoFtpdObjCmd, NULL, CmdDeleted); #else state->cmds[5] = Tcl_CreateObjCommand(interp, "glftpd", GlFtpdObjCmd, (ClientData)state, CmdDeleted); #endif } // Pass the address of the command token to the deletion handler. for (i = 0; i < ARRAYSIZE(state->cmds); i++) { if (Tcl_GetCommandInfoFromToken(state->cmds[i], &cmdInfo)) { cmdInfo.deleteData = (ClientData)&state->cmds[i]; Tcl_SetCommandInfoFromToken(state->cmds[i], &cmdInfo); } } return TCL_OK; }