diff options
| -rw-r--r-- | generic/tclCompCmdsGR.c | 25 | ||||
| -rw-r--r-- | generic/tclCompCmdsSZ.c | 19 | ||||
| -rw-r--r-- | generic/tclListObj.c | 14 |
3 files changed, 45 insertions, 13 deletions
diff --git a/generic/tclCompCmdsGR.c b/generic/tclCompCmdsGR.c index 0720a6b..8779a78 100644 --- a/generic/tclCompCmdsGR.c +++ b/generic/tclCompCmdsGR.c @@ -1505,7 +1505,6 @@ TclCompileLreplaceCmd( * - integer: [0,len+1] * - end index: TCL_INDEX_END * - -ive offset: TCL_INDEX_END-[len-1,0] - * - +ive offset: TCL_INDEX_END+1 */ /* @@ -1515,6 +1514,11 @@ TclCompileLreplaceCmd( */ if ((idx1 <= TCL_INDEX_END) != (idx2 <= TCL_INDEX_END)) { + + /* + * NOTE: when idx1 == 0 and idx2 == TCL_INDEX_END, + * we bail out here! Yet, down below + */ return TCL_ERROR; } @@ -1531,9 +1535,11 @@ TclCompileLreplaceCmd( if (parsePtr->numWords == 4) { if (idx1 == 0) { if (idx2 == TCL_INDEX_END) { + + /* Here we are down below! Now look somewhere else! */ goto dropAll; } - idx1 = idx2 + 1; + idx1 = idx2 + 1; /* TODO: Overflow? */ idx2 = TCL_INDEX_END; goto dropEnd; } else if (idx2 == TCL_INDEX_END) { @@ -1561,9 +1567,10 @@ TclCompileLreplaceCmd( TclEmitInstInt4( INST_REVERSE, 2, envPtr); if (idx1 == 0) { if (idx2 == TCL_INDEX_END) { + /* Another Can't Happen. */ goto replaceAll; } - idx1 = idx2 + 1; + idx1 = idx2 + 1; /* TODO: Overflow? */ idx2 = TCL_INDEX_END; goto replaceHead; } else if (idx2 == TCL_INDEX_END) { @@ -1588,6 +1595,11 @@ TclCompileLreplaceCmd( */ dropAll: /* This just ensures the arg is a list. */ + /* + * And now we're here down below the down below where flow can never go. + * CONCLUSION: This code has no purpose. + */ +Tcl_Panic("Can not get here."); TclEmitOpcode( INST_LIST_LENGTH, envPtr); TclEmitOpcode( INST_POP, envPtr); PushStringLiteral(envPtr, ""); @@ -1615,6 +1627,9 @@ TclCompileLreplaceCmd( * Emit an error if we've been given an empty list. */ +/* If we're generating bytecode to report an error, we've gone wrong. + * Just fallback to direct invocation. + */ TclEmitOpcode( INST_DUP, envPtr); TclEmitOpcode( INST_LIST_LENGTH, envPtr); offset2 = CurrentOffset(envPtr); @@ -1646,6 +1661,7 @@ TclCompileLreplaceCmd( */ replaceAll: +Tcl_Panic("Can not get here."); TclEmitOpcode( INST_LIST_LENGTH, envPtr); TclEmitOpcode( INST_POP, envPtr); goto done; @@ -1685,6 +1701,9 @@ TclCompileLreplaceCmd( * Emit an error if we've been given an empty list. */ +/* If we're generating bytecode to report an error, we've gone wrong. + * Just fallback to direct invocation. + */ TclEmitOpcode( INST_DUP, envPtr); TclEmitOpcode( INST_LIST_LENGTH, envPtr); offset2 = CurrentOffset(envPtr); diff --git a/generic/tclCompCmdsSZ.c b/generic/tclCompCmdsSZ.c index 294ee25..05ef8e0 100644 --- a/generic/tclCompCmdsSZ.c +++ b/generic/tclCompCmdsSZ.c @@ -1005,6 +1005,14 @@ TclCompileStringReplaceCmd( * We handle these replacements specially: first character (where * idx1=idx2=0) and last character (where idx1=idx2=TCL_INDEX_END). Anything * else and the semantics get rather screwy. + * + * TODO: These seem to be very narrow cases. They are not even + * covered by the test suite, and any programming that ends up + * here could have been coded by the programmer using [string range] + * and [string cat]. [*] Not clear at all to me that the bytecode + * generated here is worthwhile. + * + * [*] Except for the empty string exceptions. UGGGGHHHH. */ if (idx1 == 0 && idx2 == 0) { @@ -1022,6 +1030,14 @@ TclCompileStringReplaceCmd( } /* Replace first */ CompileWord(envPtr, replacementTokenPtr, interp, 4); + + /* + * NOTE: The following tower of bullshit is present because + * [string replace] was boneheadedly defined not to replace + * empty strings, so we actually have to detect the empty + * string case and treat it differently. + */ + OP4( OVER, 1); PUSH( ""); OP( STR_EQ); @@ -1051,6 +1067,9 @@ TclCompileStringReplaceCmd( } /* Replace last */ CompileWord(envPtr, replacementTokenPtr, interp, 4); + + /* More bullshit; see NOTE above. */ + OP4( OVER, 1); PUSH( ""); OP( STR_EQ); diff --git a/generic/tclListObj.c b/generic/tclListObj.c index 43d90ab..7b91d63 100644 --- a/generic/tclListObj.c +++ b/generic/tclListObj.c @@ -1165,17 +1165,11 @@ TclLindexList( return TclLindexFlat(interp, listPtr, 1, &argPtr); } - if (indexListCopy->typePtr == &tclListType) { - List *listRepPtr = ListRepPtr(indexListCopy); + { + int indexCount = -1; /* Size of the array of list indices. */ + Tcl_Obj **indices = NULL; /* Array of list indices. */ - listPtr = TclLindexFlat(interp, listPtr, listRepPtr->elemCount, - &listRepPtr->elements); - } else { - int indexCount = -1; /* Size of the array of list indices. */ - Tcl_Obj **indices = NULL; - /* Array of list indices. */ - - Tcl_ListObjGetElements(NULL, indexListCopy, &indexCount, &indices); + TclListObjGetElements(NULL, indexListCopy, &indexCount, &indices); listPtr = TclLindexFlat(interp, listPtr, indexCount, indices); } Tcl_DecrRefCount(indexListCopy); |
