summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2015-02-26 16:35:48 (GMT)
committerdgp <dgp@users.sourceforge.net>2015-02-26 16:35:48 (GMT)
commit90713744431fa23cc5fb5efe13db41c436d50a37 (patch)
tree3c1f9ff6cf6dad013b2e1d8d9248e31d7f3124b0
parent89a037dc4891736aa493a01e302352a9c3c857f0 (diff)
parent8104f5f53df16c73196450563e867f62798448e1 (diff)
downloadtcl-90713744431fa23cc5fb5efe13db41c436d50a37.zip
tcl-90713744431fa23cc5fb5efe13db41c436d50a37.tar.gz
tcl-90713744431fa23cc5fb5efe13db41c436d50a37.tar.bz2
merge trunk
-rw-r--r--doc/CrtChannel.32
-rw-r--r--generic/tclCompCmdsGR.c4
-rw-r--r--generic/tclIO.c16
-rw-r--r--tests/lreplace.test9
4 files changed, 30 insertions, 1 deletions
diff --git a/doc/CrtChannel.3 b/doc/CrtChannel.3
index 1c5c665..2335de1 100644
--- a/doc/CrtChannel.3
+++ b/doc/CrtChannel.3
@@ -336,7 +336,7 @@ typedef struct Tcl_ChannelType {
It is not necessary to provide implementations for all channel
operations. Those which are not necessary may be set to NULL in the
struct: \fIblockModeProc\fR, \fIseekProc\fR, \fIsetOptionProc\fR,
-\fIgetOptionProc\fR, and \fIclose2Proc\fR, in addition to
+\fIgetOptionProc\fR, \fIgetHandleProc\fR, and \fIclose2Proc\fR, in addition to
\fIflushProc\fR, \fIhandlerProc\fR, \fIthreadActionProc\fR, and
\fItruncateProc\fR. Other functions that cannot be implemented in a
meaningful way should return \fBEINVAL\fR when called, to indicate
diff --git a/generic/tclCompCmdsGR.c b/generic/tclCompCmdsGR.c
index e2fb43d..b77c43c 100644
--- a/generic/tclCompCmdsGR.c
+++ b/generic/tclCompCmdsGR.c
@@ -1501,6 +1501,10 @@ TclCompileLreplaceCmd(
return TCL_ERROR;
}
+ if(idx2 != INDEX_END && idx2 < idx1) {
+ idx2 = idx1-1;
+ }
+
/*
* Work out what this [lreplace] is actually doing.
*/
diff --git a/generic/tclIO.c b/generic/tclIO.c
index 409ff3e..14623a1 100644
--- a/generic/tclIO.c
+++ b/generic/tclIO.c
@@ -1548,6 +1548,22 @@ Tcl_CreateChannel(
*/
assert(sizeof(Tcl_ChannelTypeVersion) == sizeof(Tcl_DriverBlockModeProc *));
+ assert(typePtr->typeName != NULL);
+ if (NULL == typePtr->closeProc) {
+ Tcl_Panic("channel type %s must define closeProc", typePtr->typeName);
+ }
+ if ((TCL_READABLE & mask) && (NULL == typePtr->inputProc)) {
+ Tcl_Panic("channel type %s must define inputProc when used for reader channel", typePtr->typeName);
+ }
+ if ((TCL_WRITABLE & mask) && (NULL == typePtr->outputProc)) {
+ Tcl_Panic("channel type %s must define outputProc when used for writer channel", typePtr->typeName);
+ }
+ if (NULL == typePtr->watchProc) {
+ Tcl_Panic("channel type %s must define watchProc", typePtr->typeName);
+ }
+ if ((NULL!=typePtr->wideSeekProc) && (NULL == typePtr->seekProc)) {
+ Tcl_Panic("channel type %s must define seekProc if defining wideSeekProc", typePtr->typeName);
+ }
/*
* JH: We could subsequently memset these to 0 to avoid the numerous
diff --git a/tests/lreplace.test b/tests/lreplace.test
index b976788..d5c51ae 100644
--- a/tests/lreplace.test
+++ b/tests/lreplace.test
@@ -137,6 +137,15 @@ test lreplace-4.1 {Bug ccc2c2cc98: lreplace edge case} {
test lreplace-4.2 {Bug ccc2c2cc98: lreplace edge case} {
lreplace { } 1 1
} {}
+test lreplace-4.3 {lreplace edge case} {
+ lreplace {1 2 3} 2 0
+} {1 2 3}
+test lreplace-4.4 {lreplace edge case} {
+ lreplace {1 2 3 4 5} 3 1
+} {1 2 3 4 5}
+test lreplace-4.4 {lreplace edge case} {
+ lreplace {1 2 3 4 5} 3 0 _
+} {1 2 3 _ 4 5}
# cleanup
catch {unset foo}