diff options
author | dgp <dgp@users.sourceforge.net> | 2018-03-07 21:45:12 (GMT) |
---|---|---|
committer | dgp <dgp@users.sourceforge.net> | 2018-03-07 21:45:12 (GMT) |
commit | 30e7e05895de1b9534837717365babc905955f7a (patch) | |
tree | 7c0c2e8af17312305f3c542b20a709032d35cc81 /generic/tclExecute.c | |
parent | ce6aa3ea082e901341852037de6a866850f28351 (diff) | |
download | tcl-30e7e05895de1b9534837717365babc905955f7a.zip tcl-30e7e05895de1b9534837717365babc905955f7a.tar.gz tcl-30e7e05895de1b9534837717365babc905955f7a.tar.bz2 |
Streamline index decoding in INST_STR_RANGE_IMM execution.
Diffstat (limited to 'generic/tclExecute.c')
-rw-r--r-- | generic/tclExecute.c | 45 |
1 files changed, 28 insertions, 17 deletions
diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 6bc5485..2e3fcb9 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -5640,33 +5640,44 @@ TEBCresume( length = Tcl_GetCharLength(valuePtr); TRACE(("\"%.20s\" %d %d => ", O2S(valuePtr), fromIdx, toIdx)); - /* - * Adjust indices for end-based indexing. - */ + /* Every range of an empty value is an empty value */ + if (length == 0) { + TRACE_APPEND(("\n")); + NEXT_INST_F(9, 0, 0); + } - if (fromIdx == -1) { - fromIdx = 0; - } else if (fromIdx < -1) { - fromIdx += 1 + length; - if (fromIdx < 0) { - fromIdx = 0; + /* Decode index operands. */ + + assert ( toIdx != TCL_INDEX_BEFORE ); + assert ( toIdx != TCL_INDEX_AFTER); + + if (toIdx <= TCL_INDEX_END) { + toIdx += (length - 1 - TCL_INDEX_END); + if (toIdx < 0) { + goto emptyRange; } - } else if (fromIdx >= length) { - fromIdx = length; - } - if (toIdx < -1) { - toIdx += 1 + length; } else if (toIdx >= length) { toIdx = length - 1; } - /* - * Check if we can do a sane substring. - */ + assert ( toIdx >= 0 && toIdx < length ); + + assert ( fromIdx != TCL_INDEX_BEFORE ); + assert ( fromIdx != TCL_INDEX_AFTER); + + if (fromIdx <= TCL_INDEX_END) { + fromIdx += (length - 1 - TCL_INDEX_END); + if (fromIdx < 0) { + fromIdx = 0; + } + } + + assert ( fromIdx >= 0 ); if (fromIdx <= toIdx) { objResultPtr = Tcl_GetRange(valuePtr, fromIdx, toIdx); } else { + emptyRange: TclNewObj(objResultPtr); } TRACE_APPEND(("%.30s\n", O2S(objResultPtr))); |