diff options
author | dgp <dgp@users.sourceforge.net> | 2016-11-08 02:56:11 (GMT) |
---|---|---|
committer | dgp <dgp@users.sourceforge.net> | 2016-11-08 02:56:11 (GMT) |
commit | cad330bea5eb1c5fa6958b11506b10529846eb00 (patch) | |
tree | e1ef2f40fc3b0408147198398113220f4f9d7eb4 /generic/tclCmdMZ.c | |
parent | b1c86e9055e5384cf165f8e509583067d4b32796 (diff) | |
download | tcl-cad330bea5eb1c5fa6958b11506b10529846eb00.zip tcl-cad330bea5eb1c5fa6958b11506b10529846eb00.tar.gz tcl-cad330bea5eb1c5fa6958b11506b10529846eb00.tar.bz2 |
Route all [string last] operations through a common implementation.
Diffstat (limited to 'generic/tclCmdMZ.c')
-rw-r--r-- | generic/tclCmdMZ.c | 67 |
1 files changed, 11 insertions, 56 deletions
diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c index be77b1f..e9a6933 100644 --- a/generic/tclCmdMZ.c +++ b/generic/tclCmdMZ.c @@ -1229,76 +1229,31 @@ StringLastCmd( int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { - Tcl_UniChar *needleStr, *haystackStr, *p; - int match, start, needleLen, haystackLen; + int last = INT_MAX - 1; if (objc < 3 || objc > 4) { Tcl_WrongNumArgs(interp, 1, objv, - "needleString haystackString ?startIndex?"); + "needleString haystackString ?lastIndex?"); return TCL_ERROR; } - /* - * We are searching haystackString for the sequence needleString. - */ - - match = -1; - start = 0; - haystackLen = -1; - - needleStr = Tcl_GetUnicodeFromObj(objv[1], &needleLen); - haystackStr = Tcl_GetUnicodeFromObj(objv[2], &haystackLen); - if (objc == 4) { - /* - * If a startIndex is specified, we will need to restrict the string - * range to that char index in the string - */ + int size = Tcl_GetCharLength(objv[2]); - if (TclGetIntForIndexM(interp, objv[3], haystackLen-1, - &start) != TCL_OK){ + if (TCL_OK != TclGetIntForIndexM(interp, objv[3], size - 1, &last)) { return TCL_ERROR; } - /* - * Reread to prevent shimmering problems. - */ - - needleStr = Tcl_GetUnicodeFromObj(objv[1], &needleLen); - haystackStr = Tcl_GetUnicodeFromObj(objv[2], &haystackLen); - - if (start < 0) { - goto str_last_done; - } else if (start < haystackLen) { - p = haystackStr + start + 1 - needleLen; - } else { - p = haystackStr + haystackLen - needleLen; + if (last < 0) { + Tcl_SetObjResult(interp, Tcl_NewIntObj(-1)); + return TCL_OK; } - } else { - p = haystackStr + haystackLen - needleLen; - } - - /* - * If the length of the needle is more than the length of the haystack, it - * cannot be contained in there so we can avoid searching. [Bug 2960021] - */ - - if (needleLen > 0 && needleLen <= haystackLen) { - for (; p >= haystackStr; p--) { - /* - * Scan backwards to find the first character. - */ - - if ((*p == *needleStr) && !memcmp(needleStr, p, - sizeof(Tcl_UniChar) * (size_t)needleLen)) { - match = p - haystackStr; - break; - } + if (last >= size) { + last = size - 1; } } - - str_last_done: - Tcl_SetObjResult(interp, Tcl_NewIntObj(match)); + Tcl_SetObjResult(interp, Tcl_NewIntObj(TclStringLast(objv[1], + objv[2], last))); return TCL_OK; } |