From 8cc3c8dbcc8bd130f161afaf0c4ccc36562ff705 Mon Sep 17 00:00:00 2001 From: dkf Date: Wed, 2 May 2012 10:11:14 +0000 Subject: Update of Patch 2445648 to trunk tip. Implementation of TIP 106: Add Encoding Abilities to the [dde] Command --- doc/dde.n | 22 ++++++++++--- win/tclWinDde.c | 100 ++++++++++++++++++++++++++++++++++++-------------------- 2 files changed, 83 insertions(+), 39 deletions(-) diff --git a/doc/dde.n b/doc/dde.n index a02c582..60dd058 100644 --- a/doc/dde.n +++ b/doc/dde.n @@ -17,9 +17,11 @@ dde \- Execute a Dynamic Data Exchange command .sp \fBdde servername\fR ?\fB\-force\fR? ?\fB\-handler \fIproc\fR? ?\fB\-\|\-\fR? ?\fItopic\fR? .sp -\fBdde execute\fR ?\fB\-async\fR? \fIservice topic data\fR +.VS 8.6 +\fBdde execute\fR ?\fB\-async\fR? ?\fB\-binary\fR? \fIservice topic data\fR .sp -\fBdde poke\fR \fIservice topic item data\fR +\fBdde poke\fR ?\fB\-binary\fR? \fIservice topic item data\fR +.VE 8.6 .sp \fBdde request\fR ?\fB\-binary\fR? \fIservice topic item\fR .sp @@ -69,7 +71,7 @@ procedure is called with all the arguments provided by the remote call. .RE .TP -\fBdde execute\fR ?\fB\-async\fR? \fIservice topic data\fR +\fBdde execute\fR ?\fB\-async\fR? ?\fB\-binary\fR? \fIservice topic data\fR . \fBdde execute\fR takes the \fIdata\fR and sends it to the server indicated by \fIservice\fR with the topic indicated by \fItopic\fR. Typically, @@ -80,8 +82,13 @@ script is run in the application. The \fB\-async\fR option requests asynchronous invocation. The command returns an error message if the script did not run, unless the \fB\-async\fR flag was used, in which case the command returns immediately with no error. +.VS 8.6 +The \fB\-binary\fR option treats \fIdata\fR as binary data, otherwise an utf-8 +string is sent. Combining \fB-binary\fR with the result of +\fBencoding convertto\fR may be used to send data in arbitrary encodings. +.VE 8.6 .TP -\fBdde poke \fIservice topic item data\fR +\fBdde poke ?\fB\-binary\fR? \fIservice topic item data\fR . \fBdde poke\fR passes the \fIdata\fR to the server indicated by \fIservice\fR using the \fItopic\fR and \fIitem\fR specified. Typically, @@ -90,6 +97,10 @@ specific but can be a command to the server or the name of a file to work on. The \fIitem\fR is also application specific and is often not used, but it must always be non-null. The \fIdata\fR field is given to the remote application. +.VS 8.6 +The \fB\-binary\fR option treats \fIdata\fR as binary data, otherwise an utf-8 +string is sent. +.VE 8.6 .TP \fBdde request\fR ?\fB\-binary\fR? \fIservice topic item\fR . @@ -168,3 +179,6 @@ package require dde tk(n), winfo(n), send(n) .SH KEYWORDS application, dde, name, remote execution +'\"Local Variables: +'\"mode: nroff +'\"End: diff --git a/win/tclWinDde.c b/win/tclWinDde.c index 71b03a9..e917570 100644 --- a/win/tclWinDde.c +++ b/win/tclWinDde.c @@ -1164,13 +1164,19 @@ DdeObjCmd( DDE_SERVERNAME_EXACT, DDE_SERVERNAME_HANDLER, DDE_SERVERNAME_LAST, }; static const char *const ddeExecOptions[] = { - "-async", NULL + "-async", "-binary", NULL + }; + enum DdeExecOptions { + DDE_EXEC_ASYNC, DDE_EXEC_BINARY + }; + static const char *const ddePokeOptions[] = { + "-binary", NULL }; static const char *const ddeReqOptions[] = { "-binary", NULL }; - int index, i, length; + int index, i, length, argIndex; int async = 0, binary = 0, exact = 0; int result = TCL_OK, firstArg = 0; HSZ ddeService = NULL, ddeTopic = NULL, ddeItem = NULL, ddeCookie = NULL; @@ -1198,7 +1204,6 @@ DdeObjCmd( switch ((enum DdeSubcommands) index) { case DDE_SERVERNAME: for (i = 2; i < objc; i++) { - int argIndex; if (Tcl_GetIndexFromObj(interp, objv[i], ddeSrvOptions, "option", 0, &argIndex) != TCL_OK) { /* @@ -1245,39 +1250,52 @@ DdeObjCmd( if (objc == 5) { firstArg = 2; break; - } else if (objc == 6) { - int dummy; - if (Tcl_GetIndexFromObj(NULL, objv[2], ddeExecOptions, "option", 0, - &dummy) == TCL_OK) { - async = 1; - firstArg = 3; - break; + } else if (objc >= 6 && objc <= 7) { + firstArg = objc - 3; + for (i = 2; i < firstArg; i++) { + if (Tcl_GetIndexFromObj(NULL, objv[2], ddeExecOptions, + "option", 0, &argIndex) != TCL_OK) { + return TCL_ERROR; + } + if (argIndex == DDE_EXEC_ASYNC) { + async = 1; + } else { + binary = 1; + } } + break; } /* otherwise... */ Tcl_WrongNumArgs(interp, 2, objv, - "?-async? serviceName topicName value"); + "?-async? ?-binary? serviceName topicName value"); return TCL_ERROR; case DDE_POKE: - if (objc != 6) { - Tcl_WrongNumArgs(interp, 2, objv, - "serviceName topicName item value"); - return TCL_ERROR; + if (objc == 6) { + firstArg = 2; + break; + } else if ((objc == 7) && (Tcl_GetIndexFromObj(NULL, objv[2], + ddePokeOptions, "option", 0, &argIndex) == TCL_OK)) { + binary = 1; + firstArg = 3; + break; } - firstArg = 2; - break; + + /* + * Otherwise... + */ + + Tcl_WrongNumArgs(interp, 2, objv, + "serviceName ?-binary? topicName item value"); + return TCL_ERROR; case DDE_REQUEST: if (objc == 5) { firstArg = 2; break; - } else if (objc == 6) { - int dummy; - if (Tcl_GetIndexFromObj(NULL, objv[2], ddeReqOptions, "option", 0, - &dummy) == TCL_OK) { - binary = 1; - firstArg = 3; - break; - } + } else if ((objc == 6) && (Tcl_GetIndexFromObj(NULL, objv[2], + ddeReqOptions, "option", 0, &argIndex) == TCL_OK)) { + binary = 1; + firstArg = 3; + break; } /* @@ -1300,11 +1318,9 @@ DdeObjCmd( Tcl_WrongNumArgs(interp, 2, objv, "?-async? serviceName args"); return TCL_ERROR; } else { - int dummy; - firstArg = 2; if (Tcl_GetIndexFromObj(NULL, objv[2], ddeExecOptions, "option", - 0, &dummy) == TCL_OK) { + 0, &argIndex) == TCL_OK) { if (objc < 5) { goto wrongDdeEvalArgs; } @@ -1353,8 +1369,15 @@ DdeObjCmd( case DDE_EXECUTE: { int dataLength; - BYTE *dataString = (BYTE *) Tcl_GetStringFromObj( - objv[firstArg + 2], &dataLength); + BYTE *dataString; + + if (binary) { + dataString = (BYTE *) + Tcl_GetByteArrayFromObj(objv[firstArg + 2], &dataLength); + } else { + dataString = (BYTE *) + Tcl_GetStringFromObj(objv[firstArg + 2], &dataLength); + } if (dataLength == 0) { Tcl_SetObjResult(interp, @@ -1415,6 +1438,7 @@ DdeObjCmd( result = TCL_ERROR; } else { Tcl_Obj *returnObjPtr; + ddeItem = DdeCreateStringHandleA(ddeInstance, (void *) itemString, CP_WINANSI); if (ddeItem != NULL) { @@ -1428,10 +1452,11 @@ DdeObjCmd( const BYTE *dataString = DdeAccessData(ddeData, &tmp); if (binary) { - returnObjPtr = Tcl_NewByteArrayObj(dataString, - (int) tmp); + returnObjPtr = + Tcl_NewByteArrayObj(dataString, (int) tmp); } else { - returnObjPtr = Tcl_NewStringObj((char*)dataString,-1); + returnObjPtr = + Tcl_NewStringObj((char *) dataString, -1); } DdeUnaccessData(ddeData); DdeFreeDataHandle(ddeData); @@ -1457,8 +1482,13 @@ DdeObjCmd( result = TCL_ERROR; goto cleanup; } - dataString = (BYTE *) Tcl_GetStringFromObj(objv[firstArg + 3], - &length); + if (binary) { + dataString = (BYTE *) + Tcl_GetByteArrayFromObj(objv[firstArg + 3], &length); + } else { + dataString = (BYTE *) + Tcl_GetStringFromObj(objv[firstArg + 3], &length); + } hConv = DdeConnect(ddeInstance, ddeService, ddeTopic, NULL); DdeFreeStringHandle(ddeInstance, ddeService); -- cgit v0.12