summaryrefslogtreecommitdiffstats
path: root/generic/tclExecute.c
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2018-03-07 21:45:12 (GMT)
committerdgp <dgp@users.sourceforge.net>2018-03-07 21:45:12 (GMT)
commit30e7e05895de1b9534837717365babc905955f7a (patch)
tree7c0c2e8af17312305f3c542b20a709032d35cc81 /generic/tclExecute.c
parentce6aa3ea082e901341852037de6a866850f28351 (diff)
downloadtcl-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.c45
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)));