Index: ChangeLog ================================================================== --- ChangeLog +++ ChangeLog @@ -1,5 +1,10 @@ +2012-05-?? Jan Nijtmans + + * win/tclWinDde.c: [Bug 473946]: special characters not correctly sent + * library/dde/pkgIndex.tcl Increase version to 1.2.5 + 2012-05-02 Jan Nijtmans * generic/configure.in: Better detection and implementation for cpuid * generic/configure: instruction on Intel-derived processors, both * generic/tclUnixCompat.c: 32-bit and 64-bit. Index: library/dde/pkgIndex.tcl ================================================================== --- library/dde/pkgIndex.tcl +++ library/dde/pkgIndex.tcl @@ -1,7 +1,7 @@ if {![package vsatisfies [package provide Tcl] 8]} return if {[string compare [info sharedlibextension] .dll]} return if {[info exists ::tcl_platform(debug)]} { - package ifneeded dde 1.2.4 [list load [file join $dir tcldde12g.dll] dde] + package ifneeded dde 1.2.5 [list load [file join $dir tcldde12g.dll] dde] } else { - package ifneeded dde 1.2.4 [list load [file join $dir tcldde12.dll] dde] + package ifneeded dde 1.2.5 [list load [file join $dir tcldde12.dll] dde] } Index: win/tclWinDde.c ================================================================== --- win/tclWinDde.c +++ win/tclWinDde.c @@ -1,6 +1,6 @@ -/* +/* * tclWinDde.c -- * * This file provides procedures that implement the "send" * command, allowing commands to be passed from interpreter * to interpreter. @@ -22,11 +22,11 @@ */ #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLEXPORT -/* +/* * The following structure is used to keep track of the interpreters * registered by this process. */ typedef struct RegisteredInterp { @@ -66,42 +66,42 @@ static HSZ ddeServiceGlobal = 0; static DWORD ddeInstance; /* The application instance handle given * to us by DdeInitialize. */ static int ddeIsServer = 0; -#define TCL_DDE_VERSION "1.2.4" -#define TCL_DDE_PACKAGE_NAME "dde" -#define TCL_DDE_SERVICE_NAME "TclEval" +#define TCL_DDE_VERSION "1.2.5" +#define TCL_DDE_PACKAGE_NAME "dde" +#define TCL_DDE_SERVICE_NAME "TclEval" +#define TCL_DDE_EXECUTE_RESULT "$TCLEVAL$EXECUTE$RESULT" TCL_DECLARE_MUTEX(ddeMutex) /* * Forward declarations for procedures defined later in this file. */ -static void DdeExitProc _ANSI_ARGS_((ClientData clientData)); -static void DeleteProc _ANSI_ARGS_((ClientData clientData)); -static Tcl_Obj * ExecuteRemoteObject _ANSI_ARGS_(( - RegisteredInterp *riPtr, - Tcl_Obj *ddeObjectPtr)); -static int MakeDdeConnection _ANSI_ARGS_((Tcl_Interp *interp, - char *name, HCONV *ddeConvPtr)); -static HDDEDATA CALLBACK DdeServerProc _ANSI_ARGS_((UINT uType, +static void DdeExitProc(ClientData clientData); +static void DeleteProc(ClientData clientData); +static Tcl_Obj * ExecuteRemoteObject( + RegisteredInterp *riPtr, + Tcl_Obj *ddeObjectPtr); +static int MakeDdeConnection(Tcl_Interp *interp, + const char *name, HCONV *ddeConvPtr); +static HDDEDATA CALLBACK DdeServerProc(UINT uType, UINT uFmt, HCONV hConv, HSZ ddeTopic, - HSZ ddeItem, HDDEDATA hData, DWORD dwData1, - DWORD dwData2)); -static void SetDdeError _ANSI_ARGS_((Tcl_Interp *interp)); -static int DdeGetServicesList _ANSI_ARGS_(( + HSZ ddeItem, HDDEDATA hData, DWORD dwData1, + DWORD dwData2); +static void SetDdeError(Tcl_Interp *interp); +static int DdeGetServicesList( Tcl_Interp *interp, - char *serviceName, - char *topicName)); -int Tcl_DdeObjCmd(ClientData clientData, /* Used only for deletion */ - Tcl_Interp *interp, /* The interp we are sending from */ - int objc, /* Number of arguments */ - Tcl_Obj *CONST objv[]); /* The arguments */ - -EXTERN int Dde_Init(Tcl_Interp *interp); + const char *serviceName, + const char *topicName); +static int DdeObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); + +EXTERN int Dde_Init(Tcl_Interp *interp); /* *---------------------------------------------------------------------- * * Dde_Init -- @@ -119,18 +119,16 @@ int Dde_Init( Tcl_Interp *interp) { - if (!Tcl_InitStubs(interp, "8.0", 0)) { + if (!Tcl_InitStubs(interp, "8.1", 0)) { return TCL_ERROR; } - Tcl_CreateObjCommand(interp, "dde", Tcl_DdeObjCmd, NULL, NULL); - + Tcl_CreateObjCommand(interp, "dde", DdeObjCmd, NULL, NULL); Tcl_CreateExitHandler(DdeExitProc, NULL); - return Tcl_PkgProvide(interp, TCL_DDE_PACKAGE_NAME, TCL_DDE_VERSION); } /* *---------------------------------------------------------------------- @@ -151,11 +149,11 @@ static void Initialize(void) { int nameFound = 0; ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); - + /* * See if the application is already registered; if so, remove its * current name from the registry. The deletion of the command * will take care of disposing of this entry. */ @@ -173,11 +171,11 @@ Tcl_MutexLock(&ddeMutex); if (ddeInstance == 0) { if (DdeInitialize(&ddeInstance, (PFNCALLBACK) DdeServerProc, CBF_SKIP_REGISTRATIONS | CBF_SKIP_UNREGISTRATIONS - | CBF_FAIL_POKES, 0) + | CBF_FAIL_POKES, 0) != DMLERR_NO_ERROR) { ddeInstance = 0; } } Tcl_MutexUnlock(&ddeMutex); @@ -193,11 +191,11 @@ } else { ddeIsServer = 0; } Tcl_MutexUnlock(&ddeMutex); } -} +} /* *-------------------------------------------------------------- * * DdeSetServerName -- @@ -223,11 +221,11 @@ */ static char * DdeSetServerName( Tcl_Interp *interp, - char *name /* The name that will be used to + const char *name /* The name that will be used to * refer to the interpreter in later * "send" commands. Must be globally * unique. */ ) { @@ -239,11 +237,11 @@ * See if the application is already registered; if so, remove its * current name from the registry. The deletion of the command * will take care of disposing of this entry. */ - for (riPtr = tsdPtr->interpListPtr, prevPtr = NULL; riPtr != NULL; + for (riPtr = tsdPtr->interpListPtr, prevPtr = NULL; riPtr != NULL; prevPtr = riPtr, riPtr = riPtr->nextPtr) { if (riPtr->interp == interp) { if (name != NULL) { if (prevPtr == NULL) { tsdPtr->interpListPtr = tsdPtr->interpListPtr->nextPtr; @@ -269,11 +267,11 @@ * have a name. */ return ""; } - + /* * Pick a name to use for the application. Use "name" if it's not * already in use. Otherwise add a suffix such as " #2", trying * larger and larger numbers until we eventually find one that is * unique. @@ -290,11 +288,11 @@ riPtr->name = ckalloc((unsigned int) strlen(name) + 1); riPtr->nextPtr = tsdPtr->interpListPtr; tsdPtr->interpListPtr = riPtr; strcpy(riPtr->name, name); - Tcl_CreateObjCommand(interp, "dde", Tcl_DdeObjCmd, + Tcl_CreateObjCommand(interp, "dde", DdeObjCmd, (ClientData) riPtr, DeleteProc); if (Tcl_IsSafe(interp)) { Tcl_HideCommand(interp, "dde", "dde"); } Tcl_DStringFree(&dString); @@ -301,11 +299,11 @@ /* * re-initialize with the new name */ Initialize(); - + return riPtr->name; } /* *-------------------------------------------------------------- @@ -426,15 +424,15 @@ DdeServerProc ( UINT uType, /* The type of DDE transaction we * are performing. */ UINT uFmt, /* The format that data is sent or * received. */ - HCONV hConv, /* The conversation associated with the + HCONV hConv, /* The conversation associated with the * current transaction. */ - HSZ ddeTopic, /* A string handle. Transaction-type + HSZ ddeTopic, /* A string handle. Transaction-type * dependent. */ - HSZ ddeItem, /* A string handle. Transaction-type + HSZ ddeItem, /* A string handle. Transaction-type * dependent. */ HDDEDATA hData, /* DDE data. Transaction-type dependent. */ DWORD dwData1, /* Transaction-dependent data. */ DWORD dwData2) /* Transaction-dependent data. */ { @@ -475,23 +473,23 @@ return (HDDEDATA) FALSE; case XTYP_CONNECT_CONFIRM: /* - * Dde has decided that we can connect, so it gives us a + * Dde has decided that we can connect, so it gives us a * conversation handle. We need to keep track of it * so we know which execution result to return in an * XTYP_REQUEST. */ len = DdeQueryString(ddeInstance, ddeTopic, NULL, 0, 0); Tcl_DStringInit(&dString); Tcl_DStringSetLength(&dString, len); utilString = Tcl_DStringValue(&dString); - DdeQueryString(ddeInstance, ddeTopic, utilString, (DWORD) len + 1, + DdeQueryString(ddeInstance, ddeTopic, utilString, (DWORD) len + 1, CP_WINANSI); - for (riPtr = tsdPtr->interpListPtr; riPtr != NULL; + for (riPtr = tsdPtr->interpListPtr; riPtr != NULL; riPtr = riPtr->nextPtr) { if (stricmp(riPtr->name, utilString) == 0) { convPtr = (Conversation *) ckalloc(sizeof(Conversation)); convPtr->nextPtr = tsdPtr->currentConversations; convPtr->returnPackagePtr = NULL; @@ -510,11 +508,11 @@ * The client has disconnected from our server. Forget this * conversation. */ for (convPtr = tsdPtr->currentConversations, prevConvPtr = NULL; - convPtr != NULL; + convPtr != NULL; prevConvPtr = convPtr, convPtr = convPtr->nextPtr) { if (hConv == convPtr->hConv) { if (prevConvPtr == NULL) { tsdPtr->currentConversations = convPtr->nextPtr; } else { @@ -535,11 +533,11 @@ * This could be either a request for a value of a Tcl variable, * or it could be the send command requesting the results of the * last execute. */ - if (uFmt != CF_TEXT) { + if ((uFmt != CF_TEXT) && (uFmt != CF_UNICODETEXT)) { return (HDDEDATA) FALSE; } ddeReturn = (HDDEDATA) FALSE; for (convPtr = tsdPtr->currentConversations; (convPtr != NULL) @@ -548,35 +546,45 @@ * Empty loop body. */ } if (convPtr != NULL) { - BYTE *returnString; + char *returnString; len = DdeQueryString(ddeInstance, ddeItem, NULL, 0, CP_WINANSI); Tcl_DStringInit(&dString); Tcl_DStringSetLength(&dString, len); utilString = Tcl_DStringValue(&dString); - DdeQueryString(ddeInstance, ddeItem, utilString, + DdeQueryString(ddeInstance, ddeItem, utilString, (DWORD) len + 1, CP_WINANSI); - if (stricmp(utilString, "$TCLEVAL$EXECUTE$RESULT") == 0) { - returnString = - (BYTE *)Tcl_GetStringFromObj(convPtr->returnPackagePtr, &len); + if (stricmp(utilString, TCL_DDE_EXECUTE_RESULT) == 0) { + if (uFmt == CF_TEXT) { + returnString = + Tcl_GetStringFromObj(convPtr->returnPackagePtr, &len); + } else { + returnString = (char *) + Tcl_GetUnicodeFromObj(convPtr->returnPackagePtr, &len); + len = 2 * len + 1; + } ddeReturn = DdeCreateDataHandle(ddeInstance, - returnString, (DWORD) len+1, 0, ddeItem, CF_TEXT, - 0); + (BYTE *)returnString, (DWORD) len+1, 0, ddeItem, uFmt, 0); } else { Tcl_Obj *variableObjPtr = Tcl_GetVar2Ex( - convPtr->riPtr->interp, utilString, NULL, + convPtr->riPtr->interp, utilString, NULL, TCL_GLOBAL_ONLY); if (variableObjPtr != NULL) { - returnString = (BYTE *)Tcl_GetStringFromObj(variableObjPtr, - &len); + if (uFmt == CF_TEXT) { + returnString = + Tcl_GetStringFromObj(variableObjPtr, &len); + } else { + returnString = (char *) + Tcl_GetUnicodeFromObj(variableObjPtr, &len); + len = 2 * len + 1; + } ddeReturn = DdeCreateDataHandle(ddeInstance, - returnString, (DWORD) len+1, 0, ddeItem, - CF_TEXT, 0); + (BYTE *)returnString, (DWORD) len+1, 0, ddeItem, uFmt, 0); } else { ddeReturn = NULL; } } Tcl_DStringFree(&dString); @@ -612,11 +620,11 @@ DdeUnaccessData(hData); if (convPtr->returnPackagePtr != NULL) { Tcl_DecrRefCount(convPtr->returnPackagePtr); } convPtr->returnPackagePtr = NULL; - returnPackagePtr = + returnPackagePtr = ExecuteRemoteObject(convPtr->riPtr, ddeObjectPtr); Tcl_IncrRefCount(returnPackagePtr); for (convPtr = tsdPtr->currentConversations; (convPtr != NULL) && (convPtr->hConv != hConv); convPtr = convPtr->nextPtr) { /* @@ -634,11 +642,11 @@ return (HDDEDATA) DDE_FNOTPROCESSED; } else { return (HDDEDATA) DDE_FACK; } } - + case XTYP_WILDCONNECT: { /* * Dde wants a list of services and topics that we support. */ @@ -658,14 +666,14 @@ numItems = i; ddeReturn = DdeCreateDataHandle(ddeInstance, NULL, (numItems + 1) * sizeof(HSZPAIR), 0, 0, 0, 0); returnPtr = (HSZPAIR *) DdeAccessData(ddeReturn, &dlen); len = dlen; - for (i = 0, riPtr = tsdPtr->interpListPtr; i < numItems; + for (i = 0, riPtr = tsdPtr->interpListPtr; i < numItems; i++, riPtr = riPtr->nextPtr) { returnPtr[i].hszSvc = DdeCreateStringHandle( - ddeInstance, "TclEval", CP_WINANSI); + ddeInstance, TCL_DDE_SERVICE_NAME, CP_WINANSI); returnPtr[i].hszTopic = DdeCreateStringHandle( ddeInstance, riPtr->name, CP_WINANSI); } returnPtr[i].hszSvc = NULL; returnPtr[i].hszTopic = NULL; @@ -710,11 +718,11 @@ * This procedure is a utility used to connect to a DDE * server when given a server name and a topic name. * * Results: * A standard Tcl result. - * + * * * Side effects: * Passes back a conversation through ddeConvPtr * *-------------------------------------------------------------- @@ -721,17 +729,17 @@ */ static int MakeDdeConnection( Tcl_Interp *interp, /* Used to report errors. */ - char *name, /* The connection to use. */ + const char *name, /* The connection to use. */ HCONV *ddeConvPtr) { HSZ ddeTopic, ddeService; HCONV ddeConv; - - ddeService = DdeCreateStringHandle(ddeInstance, "TclEval", 0); + + ddeService = DdeCreateStringHandle(ddeInstance, TCL_DDE_SERVICE_NAME, 0); ddeTopic = DdeCreateStringHandle(ddeInstance, name, 0); ddeConv = DdeConnect(ddeInstance, ddeService, ddeTopic, NULL); DdeFreeStringHandle(ddeInstance, ddeService); DdeFreeStringHandle(ddeInstance, ddeTopic); @@ -773,11 +781,11 @@ ATOM service; ATOM topic; HWND hwnd; } ddeEnumServices; -LRESULT CALLBACK +static LRESULT CALLBACK DdeClientWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); static LRESULT DdeServicesOnAck(HWND hwnd, WPARAM wParam, LPARAM lParam); static int @@ -800,11 +808,11 @@ WS_POPUP, 0, 0, 0, 0, NULL, NULL, NULL, (LPVOID)es); return TCL_OK; } -LRESULT CALLBACK +static LRESULT CALLBACK DdeClientWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { LRESULT lr = 0L; switch (uMsg) { @@ -881,24 +889,24 @@ SMTO_ABORTIFHUNG, 1000, &dwResult); return TRUE; } static int -DdeGetServicesList(Tcl_Interp *interp, char *serviceName, char *topicName) +DdeGetServicesList(Tcl_Interp *interp, const char *serviceName, const char *topicName) { ddeEnumServices es; es.interp = interp; es.result = TCL_OK; es.service = (serviceName == NULL) ? (ATOM)0 : GlobalAddAtom(serviceName); es.topic = (topicName == NULL) ? (ATOM)0 : GlobalAddAtom(topicName); - + Tcl_ResetResult(interp); /* our list is to be appended to result. */ DdeCreateClient(&es); EnumWindows(DdeEnumWindowsCallback, (LPARAM)&es); - + if (IsWindow(es.hwnd)) DestroyWindow(es.hwnd); if (es.service != (ATOM)0) GlobalDeleteAtom(es.service); if (es.topic != (ATOM)0) @@ -914,11 +922,11 @@ * Sets the interp result to a cogent error message * describing the last DDE error. * * Results: * None. - * + * * * Side effects: * The interp's result object is changed. * *-------------------------------------------------------------- @@ -943,11 +951,11 @@ case DMLERR_BUSY: Tcl_SetStringObj(resultPtr, "remote server is busy", -1); break; case DMLERR_NOTPROCESSED: - Tcl_SetStringObj(resultPtr, + Tcl_SetStringObj(resultPtr, "remote server cannot handle this command", -1); break; default: Tcl_SetStringObj(resultPtr, "dde command failed", -1); @@ -955,11 +963,11 @@ } /* *-------------------------------------------------------------- * - * Tcl_DdeObjCmd -- + * DdeObjCmd -- * * This procedure is invoked to process the "dde" Tcl command. * See the user documentation for details on what it does. * * Results: @@ -969,16 +977,16 @@ * See the user documentation. * *-------------------------------------------------------------- */ -int -Tcl_DdeObjCmd( +static int +DdeObjCmd( ClientData clientData, /* Used only for deletion */ Tcl_Interp *interp, /* The interp we are sending from */ int objc, /* Number of arguments */ - Tcl_Obj *CONST *objv) /* The arguments */ + Tcl_Obj *const *objv) /* The arguments */ { enum { DDE_SERVERNAME, DDE_EXECUTE, DDE_POKE, @@ -985,15 +993,15 @@ DDE_REQUEST, DDE_SERVICES, DDE_EVAL }; - static CONST char *ddeCommands[] = {"servername", "execute", "poke", - "request", "services", "eval", + static const char *ddeCommands[] = {"servername", "execute", "poke", + "request", "services", "eval", (char *) NULL}; - static CONST char *ddeOptions[] = {"-async", (char *) NULL}; - static CONST char *ddeReqOptions[] = {"-binary", (char *) NULL}; + static const char *ddeOptions[] = {"-async", (char *) NULL}; + static const char *ddeReqOptions[] = {"-binary", (char *) NULL}; int index, argIndex; int async = 0, binary = 0; int result = TCL_OK; HSZ ddeService = NULL; HSZ ddeTopic = NULL; @@ -1000,11 +1008,11 @@ HSZ ddeItem = NULL; HDDEDATA ddeData = NULL; HDDEDATA ddeItemData = NULL; HCONV hConv = NULL; HSZ ddeCookie = 0; - char *serviceName, *topicName = NULL, *itemString; + const char *serviceName, *topicName = NULL, *itemString; char *string; int firstArg = 0, length, dataLength; DWORD ddeResult; HDDEDATA ddeReturn; RegisteredInterp *riPtr; @@ -1013,13 +1021,13 @@ ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); /* * Initialize DDE server/client */ - + if (objc < 2) { - Tcl_WrongNumArgs(interp, 1, objv, + Tcl_WrongNumArgs(interp, 1, objv, "?-async? serviceName topicName value"); return TCL_ERROR; } if (Tcl_GetIndexFromObj(interp, objv[1], ddeCommands, "command", 0, @@ -1035,11 +1043,11 @@ } firstArg = (objc - 1); break; case DDE_EXECUTE: if ((objc < 5) || (objc > 6)) { - Tcl_WrongNumArgs(interp, 1, objv, + Tcl_WrongNumArgs(interp, 1, objv, "execute ?-async? serviceName topicName value"); return TCL_ERROR; } if (Tcl_GetIndexFromObj(NULL, objv[2], ddeOptions, "option", 0, &argIndex) != TCL_OK) { @@ -1068,11 +1076,11 @@ } firstArg = 2; break; case DDE_REQUEST: if ((objc < 5) || (objc > 6)) { - Tcl_WrongNumArgs(interp, 1, objv, + Tcl_WrongNumArgs(interp, 1, objv, "request ?-binary? serviceName topicName value"); return TCL_ERROR; } if (Tcl_GetIndexFromObj(NULL, objv[2], ddeReqOptions, "option", 0, &argIndex) != TCL_OK) { @@ -1101,11 +1109,11 @@ } firstArg = 2; break; case DDE_EVAL: if (objc < 4) { - Tcl_WrongNumArgs(interp, 1, objv, + Tcl_WrongNumArgs(interp, 1, objv, "eval ?-async? serviceName args"); return TCL_ERROR; } if (Tcl_GetIndexFromObj(NULL, objv[2], ddeOptions, "option", 0, &argIndex) != TCL_OK) { @@ -1146,11 +1154,11 @@ if ((index != DDE_SERVERNAME) &&(index != DDE_EVAL)) { topicName = Tcl_GetStringFromObj(objv[firstArg + 1], &length); if (length == 0) { topicName = NULL; } else { - ddeTopic = DdeCreateStringHandle(ddeInstance, + ddeTopic = DdeCreateStringHandle(ddeInstance, topicName, CP_WINANSI); } } switch (index) { @@ -1185,13 +1193,13 @@ ddeData = DdeCreateDataHandle(ddeInstance, dataString, (DWORD) dataLength+1, 0, 0, CF_TEXT, 0); if (ddeData != NULL) { if (async) { - DdeClientTransaction((LPBYTE) ddeData, 0xFFFFFFFF, hConv, 0, + DdeClientTransaction((LPBYTE) ddeData, 0xFFFFFFFF, hConv, 0, CF_TEXT, XTYP_EXECUTE, TIMEOUT_ASYNC, &ddeResult); - DdeAbandonTransaction(ddeInstance, hConv, + DdeAbandonTransaction(ddeInstance, hConv, ddeResult); } else { ddeReturn = DdeClientTransaction((LPBYTE) ddeData, 0xFFFFFFFF, hConv, 0, CF_TEXT, XTYP_EXECUTE, 30000, NULL); if (ddeReturn == 0) { @@ -1214,17 +1222,17 @@ goto errorNoResult; } hConv = DdeConnect(ddeInstance, ddeService, ddeTopic, NULL); DdeFreeStringHandle(ddeInstance, ddeService); DdeFreeStringHandle(ddeInstance, ddeTopic); - + if (hConv == NULL) { SetDdeError(interp); result = TCL_ERROR; } else { Tcl_Obj *returnObjPtr; - ddeItem = DdeCreateStringHandle(ddeInstance, + ddeItem = DdeCreateStringHandle(ddeInstance, itemString, CP_WINANSI); if (ddeItem != NULL) { ddeData = DdeClientTransaction(NULL, 0, hConv, ddeItem, CF_TEXT, XTYP_REQUEST, 5000, NULL); if (ddeData == NULL) { @@ -1259,11 +1267,11 @@ Tcl_SetStringObj(Tcl_GetObjResult(interp), "cannot have a null item", -1); goto errorNoResult; } dataString = (BYTE *) Tcl_GetStringFromObj(objv[firstArg + 3], &length); - + hConv = DdeConnect(ddeInstance, ddeService, ddeTopic, NULL); DdeFreeStringHandle(ddeInstance, ddeService); DdeFreeStringHandle(ddeInstance, ddeTopic); if (hConv == NULL) { @@ -1303,16 +1311,16 @@ /* * See if the target interpreter is local. If so, execute * the command directly without going through the DDE server. * Don't exchange objects between interps. The target interp could - * compile an object, producing a bytecode structure that refers to - * other objects owned by the target interp. If the target interp - * is then deleted, the bytecode structure would be referring to + * compile an object, producing a bytecode structure that refers to + * other objects owned by the target interp. If the target interp + * is then deleted, the bytecode structure would be referring to * deallocated objects. */ - + for (riPtr = tsdPtr->interpListPtr; riPtr != NULL; riPtr = riPtr->nextPtr) { if (stricmp(serviceName, riPtr->name) == 0) { break; } @@ -1321,15 +1329,15 @@ if (riPtr != NULL) { /* * This command is to a local interp. No need to go through * the server. */ - + Tcl_Preserve((ClientData) riPtr); sendInterp = riPtr->interp; Tcl_Preserve((ClientData) sendInterp); - + /* * Don't exchange objects between interps. The target interp * would compile an object, producing a bytecode structure that * refers to other objects owned by the target interp. If the * target interp is then deleted, the bytecode structure would @@ -1351,17 +1359,17 @@ /* * An error occurred, so transfer error information * from the destination interpreter back to our * interpreter. */ - + Tcl_ResetResult(interp); - objPtr = Tcl_GetVar2Ex(sendInterp, "errorInfo", NULL, + objPtr = Tcl_GetVar2Ex(sendInterp, "errorInfo", NULL, TCL_GLOBAL_ONLY); string = Tcl_GetStringFromObj(objPtr, &length); Tcl_AddObjErrorInfo(interp, string, length); - + objPtr = Tcl_GetVar2Ex(sendInterp, "errorCode", NULL, TCL_GLOBAL_ONLY); Tcl_SetObjErrorCode(interp, objPtr); } Tcl_SetObjResult(interp, Tcl_GetObjResult(sendInterp)); @@ -1371,20 +1379,20 @@ } else { /* * This is a non-local request. Send the script to the server * and poll it for a result. */ - + if (MakeDdeConnection(interp, serviceName, &hConv) != TCL_OK) { goto error; } - + objPtr = Tcl_ConcatObj(objc, objv); string = Tcl_GetStringFromObj(objPtr, &length); ddeItemData = DdeCreateDataHandle(ddeInstance, (BYTE *) string, (DWORD) length+1, 0, 0, CF_TEXT, 0); - + if (async) { ddeData = DdeClientTransaction((LPBYTE) ddeItemData, 0xFFFFFFFF, hConv, 0, CF_TEXT, XTYP_EXECUTE, TIMEOUT_ASYNC, &ddeResult); DdeAbandonTransaction(ddeInstance, hConv, ddeResult); @@ -1391,44 +1399,44 @@ } else { ddeData = DdeClientTransaction((LPBYTE) ddeItemData, 0xFFFFFFFF, hConv, 0, CF_TEXT, XTYP_EXECUTE, 30000, NULL); if (ddeData != 0) { - - ddeCookie = DdeCreateStringHandle(ddeInstance, - "$TCLEVAL$EXECUTE$RESULT", CP_WINANSI); + + ddeCookie = DdeCreateStringHandle(ddeInstance, + TCL_DDE_EXECUTE_RESULT, CP_WINANSI); ddeData = DdeClientTransaction(NULL, 0, hConv, ddeCookie, CF_TEXT, XTYP_REQUEST, 30000, NULL); } } Tcl_DecrRefCount(objPtr); - + if (ddeData == 0) { SetDdeError(interp); goto errorNoResult; } - + if (async == 0) { Tcl_Obj *resultPtr; - + /* * The return handle has a two or four element list in * it. The first element is the return code (TCL_OK, * TCL_ERROR, etc.). The second is the result of the * script. If the return code is TCL_ERROR, then the third * element is the value of the variable "errorCode", and * the fourth is the value of the variable "errorInfo". */ - + resultPtr = Tcl_NewObj(); length = DdeGetData(ddeData, NULL, 0, 0); Tcl_SetObjLength(resultPtr, length); string = Tcl_GetString(resultPtr); DdeGetData(ddeData, (BYTE *) string, (DWORD) length, 0); Tcl_SetObjLength(resultPtr, (int) strlen(string)); - + if (Tcl_ListObjIndex(NULL, resultPtr, 0, &objPtr) != TCL_OK) { Tcl_DecrRefCount(resultPtr); goto error; } @@ -1445,11 +1453,11 @@ goto error; } length = -1; string = Tcl_GetStringFromObj(objPtr, &length); Tcl_AddObjErrorInfo(interp, string, length); - + Tcl_ListObjIndex(NULL, resultPtr, 2, &objPtr); Tcl_SetObjErrorCode(interp, objPtr); } if (Tcl_ListObjIndex(NULL, resultPtr, 1, &objPtr) != TCL_OK) {