summaryrefslogtreecommitdiffstats
path: root/generic/tclTest.c
diff options
context:
space:
mode:
authorandreas_kupries <akupries@shaw.ca>2005-08-24 17:56:23 (GMT)
committerandreas_kupries <akupries@shaw.ca>2005-08-24 17:56:23 (GMT)
commitb32c5538015a9a182a54be4f711d0e01feb0a47c (patch)
tree20a737ae03097f905f0e9230c85c04123e5b5894 /generic/tclTest.c
parentd1b987be17d4f05e79530f9f0896284fbe354205 (diff)
downloadtcl-b32c5538015a9a182a54be4f711d0e01feb0a47c.zip
tcl-b32c5538015a9a182a54be4f711d0e01feb0a47c.tar.gz
tcl-b32c5538015a9a182a54be4f711d0e01feb0a47c.tar.bz2
TIP#219 IMPLEMENTATION
* doc/SetChanErr.3: ** New File **. Documentation of the new channel API functions. * generic/tcl.decls: Stub declarations of the new channel API. * generic/tclDecls.h: Regenerated * generic/tclStubInit.c: * tclIORChan.c: ** New File **. Implementation of the reflected channel. * generic/tclInt.h: Integration of reflected channel and new error * generic/tclIO.c: propagation into the generic I/O core. * generic/tclIOCmd.c: * generic/tclIO.h: * library/init.tcl: * tests/io.test: Extended testsuite. * tests/ioCmd.test: * tests/chan.test: * generic/tclTest.c: * generic/tclThreadTest.c: * unix/Makefile.in: Integration into the build machinery. * win/Makefile.in: * win/Makefile.vc:
Diffstat (limited to 'generic/tclTest.c')
-rw-r--r--generic/tclTest.c116
1 files changed, 111 insertions, 5 deletions
diff --git a/generic/tclTest.c b/generic/tclTest.c
index 974112c..d0f6406 100644
--- a/generic/tclTest.c
+++ b/generic/tclTest.c
@@ -14,7 +14,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclTest.c,v 1.91 2005/06/01 21:38:42 dgp Exp $
+ * RCS: @(#) $Id: tclTest.c,v 1.92 2005/08/24 17:56:23 andreas_kupries Exp $
*/
#define TCL_TEST
@@ -121,6 +121,20 @@ typedef struct TestEvent {
Tcl_Obj* tag; /* Tag for this event used to delete it */
} TestEvent;
+
+/*
+ * Simple detach/attach facility for testchannel cut|splice.
+ * Allow testing of channel transfer in core testsuite.
+ */
+
+typedef struct TestChannel {
+ Tcl_Channel chan; /* Detached channel */
+ struct TestChannel* nextPtr; /* Next in pool of detached channels */
+} TestChannel;
+
+static TestChannel* firstDetached;
+
+
/*
* Forward declarations for procedures defined later in this file:
*/
@@ -5352,10 +5366,33 @@ TestChannelCmd(clientData, interp, argc, argv)
chanPtr = (Channel *) NULL;
if (argc > 2) {
- chan = Tcl_GetChannel(interp, argv[2], &mode);
- if (chan == (Tcl_Channel) NULL) {
- return TCL_ERROR;
- }
+ if ((cmdName[0] == 's') && (strncmp(cmdName, "splice", len) == 0)) {
+ /* For splice access the pool of detached channels.
+ * Locate channel, remove from the list.
+ */
+
+ TestChannel** nextPtrPtr;
+ TestChannel* curPtr;
+
+ chan = (Tcl_Channel) NULL;
+ for (nextPtrPtr = &firstDetached, curPtr = firstDetached;
+ curPtr != NULL;
+ nextPtrPtr = &(curPtr->nextPtr), curPtr = curPtr->nextPtr) {
+
+ if (strcmp (argv[2], Tcl_GetChannelName (curPtr->chan)) == 0) {
+ *nextPtrPtr = curPtr->nextPtr;
+ curPtr->nextPtr = NULL;
+ chan = curPtr->chan;
+ ckfree ((char*) curPtr);
+ break;
+ }
+ }
+ } else {
+ chan = Tcl_GetChannel(interp, argv[2], &mode);
+ }
+ if (chan == (Tcl_Channel) NULL) {
+ return TCL_ERROR;
+ }
chanPtr = (Channel *) chan;
statePtr = chanPtr->state;
chanPtr = statePtr->topChanPtr;
@@ -5366,13 +5403,62 @@ TestChannelCmd(clientData, interp, argc, argv)
chan = NULL;
}
+ if ((cmdName[0] == 's') && (strncmp(cmdName, "setchannelerror", len) == 0)) {
+
+ Tcl_Obj* msg = Tcl_NewStringObj (argv [3],-1);
+
+ Tcl_IncrRefCount (msg);
+ Tcl_SetChannelError (chan, msg);
+ Tcl_DecrRefCount (msg);
+
+ Tcl_GetChannelError (chan, &msg);
+ Tcl_SetObjResult (interp, msg);
+ Tcl_DecrRefCount (msg);
+ return TCL_OK;
+ }
+ if ((cmdName[0] == 's') && (strncmp(cmdName, "setchannelerrorinterp", len) == 0)) {
+
+ Tcl_Obj* msg = Tcl_NewStringObj (argv [3],-1);
+
+ Tcl_IncrRefCount (msg);
+ Tcl_SetChannelErrorInterp (interp, msg);
+ Tcl_DecrRefCount (msg);
+
+ Tcl_GetChannelErrorInterp (interp, &msg);
+ Tcl_SetObjResult (interp, msg);
+ Tcl_DecrRefCount (msg);
+ return TCL_OK;
+ }
+
+ /*
+ * "cut" is actually more a simplified detach facility as provided
+ * by the Thread package. Without the safeguards of a regular
+ * command (no checking that the command is truly cut'able, no
+ * mutexes for thread-safety). Its complementary command is
+ * "splice", see below.
+ */
+
if ((cmdName[0] == 'c') && (strncmp(cmdName, "cut", len) == 0)) {
+ TestChannel* det;
+
if (argc != 3) {
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
" cut channelName\"", (char *) NULL);
return TCL_ERROR;
}
+
+ Tcl_RegisterChannel((Tcl_Interp *) NULL, chan); /* prevent closing */
+ Tcl_UnregisterChannel(interp, chan);
+
Tcl_CutChannel(chan);
+
+ /* Remember the channel in the pool of detached channels */
+
+ det = (TestChannel*) ckalloc (sizeof(TestChannel));
+ det->chan = chan;
+ det->nextPtr = firstDetached;
+ firstDetached = det;
+
return TCL_OK;
}
@@ -5626,6 +5712,14 @@ TestChannelCmd(clientData, interp, argc, argv)
return TCL_OK;
}
+ /*
+ * "splice" is actually more a simplified attach facility as
+ * provided by the Thread package. Without the safeguards of a
+ * regular command (no checking that the command is truly
+ * cut'able, no mutexes for thread-safety). Its complementary
+ * command is "cut", see above.
+ */
+
if ((cmdName[0] == 's') && (strncmp(cmdName, "splice", len) == 0)) {
if (argc != 3) {
Tcl_AppendResult(interp, "channel name required", (char *) NULL);
@@ -5633,6 +5727,10 @@ TestChannelCmd(clientData, interp, argc, argv)
}
Tcl_SpliceChannel(chan);
+
+ Tcl_RegisterChannel(interp, chan);
+ Tcl_UnregisterChannel((Tcl_Interp *)NULL, chan);
+
return TCL_OK;
}
@@ -6672,3 +6770,11 @@ TestgetintCmd(dummy, interp, argc, argv)
return TCL_OK;
}
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */