summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordkf <donal.k.fellows@manchester.ac.uk>2012-05-02 10:11:14 (GMT)
committerdkf <donal.k.fellows@manchester.ac.uk>2012-05-02 10:11:14 (GMT)
commit8cc3c8dbcc8bd130f161afaf0c4ccc36562ff705 (patch)
treedf76d75f4e58ef2352f36e8c9e65112b9be55e86
parentab87e428cb91100ed8882b1ab3188ace08a84dcd (diff)
downloadtcl-8cc3c8dbcc8bd130f161afaf0c4ccc36562ff705.zip
tcl-8cc3c8dbcc8bd130f161afaf0c4ccc36562ff705.tar.gz
tcl-8cc3c8dbcc8bd130f161afaf0c4ccc36562ff705.tar.bz2
Update of Patch 2445648 to trunk tip.
Implementation of TIP 106: Add Encoding Abilities to the [dde] Command
-rw-r--r--doc/dde.n22
-rw-r--r--win/tclWinDde.c100
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);