summaryrefslogtreecommitdiffstats
path: root/generic/tclStringObj.c
diff options
context:
space:
mode:
authorjan.nijtmans <nijtmans@users.sourceforge.net>2020-03-30 11:37:54 (GMT)
committerjan.nijtmans <nijtmans@users.sourceforge.net>2020-03-30 11:37:54 (GMT)
commitaa371355b1d31208dd1e1c3b5cae011d33a62290 (patch)
tree07701075dc01630cf4902d3d3ae324f4f6531f6d /generic/tclStringObj.c
parent4cbd0649efa1b88510c6873aa3f348b58d51b982 (diff)
downloadtcl-aa371355b1d31208dd1e1c3b5cae011d33a62290.zip
tcl-aa371355b1d31208dd1e1c3b5cae011d33a62290.tar.gz
tcl-aa371355b1d31208dd1e1c3b5cae011d33a62290.tar.bz2
Optimize TclStringFirst/TclStringLast: Let it return a Tcl_Obj * in stead of an int, so its callers don't need to do the conversion any more.
Diffstat (limited to 'generic/tclStringObj.c')
-rw-r--r--generic/tclStringObj.c98
1 files changed, 53 insertions, 45 deletions
diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c
index cb2a773..c6d5323 100644
--- a/generic/tclStringObj.c
+++ b/generic/tclStringObj.c
@@ -3544,13 +3544,16 @@ TclStringCmp(
*---------------------------------------------------------------------------
*/
-int
+Tcl_Obj *
TclStringFirst(
Tcl_Obj *needle,
Tcl_Obj *haystack,
int start)
{
int lh, ln = Tcl_GetCharLength(needle);
+ Tcl_Obj *result;
+ int value = -1;
+ Tcl_UniChar *check, *end, *uh, *un;
if (start < 0) {
start = 0;
@@ -3559,7 +3562,7 @@ TclStringFirst(
/* We don't find empty substrings. Bizarre!
* Whenever this routine is turned into a proper substring
* finder, change to `return start` after limits imposed. */
- return -1;
+ goto firstEnd;
}
if (TclIsPureByteArray(needle) && TclIsPureByteArray(haystack)) {
@@ -3570,7 +3573,7 @@ TclStringFirst(
bh = Tcl_GetByteArrayFromObj(haystack, &lh);
if ((lh < ln) || (start > lh - ln)) {
/* Don't start the loop if there cannot be a valid answer */
- return -1;
+ goto firstEnd;
}
end = bh + lh;
@@ -3584,17 +3587,18 @@ TclStringFirst(
check = (unsigned char *)memchr(check, bn[0], (end + 1 - ln) - check);
if (check == NULL) {
/* Leading byte not found -> needle cannot be found. */
- return -1;
+ goto firstEnd;
}
/* Leading byte found, check rest of needle. */
if (0 == memcmp(check+1, bn+1, ln-1)) {
/* Checks! Return the successful index. */
- return (check - bh);
+ value = (check - bh);
+ goto firstEnd;
}
/* Rest of needle match failed; Iterate to continue search. */
check++;
}
- return -1;
+ goto firstEnd;
}
/*
@@ -3609,25 +3613,24 @@ TclStringFirst(
* do only the well-defined Tcl_UniChar array search.
*/
- {
- Tcl_UniChar *check, *end, *uh;
- Tcl_UniChar *un = Tcl_GetUnicodeFromObj(needle, &ln);
-
- uh = Tcl_GetUnicodeFromObj(haystack, &lh);
- if ((lh < ln) || (start > lh - ln)) {
- /* Don't start the loop if there cannot be a valid answer */
- return -1;
- }
- end = uh + lh;
+ un = Tcl_GetUnicodeFromObj(needle, &ln);
+ uh = Tcl_GetUnicodeFromObj(haystack, &lh);
+ if ((lh < ln) || (start > lh - ln)) {
+ /* Don't start the loop if there cannot be a valid answer */
+ goto firstEnd;
+ }
+ end = uh + lh;
- for (check = uh + start; check + ln <= end; check++) {
- if ((*check == *un) && (0 ==
- memcmp(check + 1, un + 1, (ln-1) * sizeof(Tcl_UniChar)))) {
- return (check - uh);
- }
+ for (check = uh + start; check + ln <= end; check++) {
+ if ((*check == *un) && (0 ==
+ memcmp(check + 1, un + 1, (ln-1) * sizeof(Tcl_UniChar)))) {
+ value = (check - uh);
+ goto firstEnd;
}
- return -1;
}
+ firstEnd:
+ TclNewIntObj(result, value);
+ return result;
}
/*
@@ -3648,13 +3651,16 @@ TclStringFirst(
*---------------------------------------------------------------------------
*/
-int
+Tcl_Obj *
TclStringLast(
Tcl_Obj *needle,
Tcl_Obj *haystack,
int last)
{
int lh, ln = Tcl_GetCharLength(needle);
+ Tcl_Obj *result;
+ int value = -1;
+ Tcl_UniChar *check, *uh, *un;
if (ln == 0) {
/*
@@ -3663,7 +3669,7 @@ TclStringLast(
* TODO: When we one day make this a true substring
* finder, change this to "return last", after limitation.
*/
- return -1;
+ goto lastEnd;
}
if (TclIsPureByteArray(needle) && TclIsPureByteArray(haystack)) {
@@ -3675,41 +3681,43 @@ TclStringLast(
}
if (last + 1 < ln) {
/* Don't start the loop if there cannot be a valid answer */
- return -1;
+ goto lastEnd;
}
check = bh + last + 1 - ln;
while (check >= bh) {
if ((*check == bn[0])
&& (0 == memcmp(check+1, bn+1, ln-1))) {
- return (check - bh);
+ value = (check - bh);
+ goto lastEnd;
}
check--;
}
- return -1;
+ goto lastEnd;
}
- {
- Tcl_UniChar *check, *uh = Tcl_GetUnicodeFromObj(haystack, &lh);
- Tcl_UniChar *un = Tcl_GetUnicodeFromObj(needle, &ln);
+ uh = Tcl_GetUnicodeFromObj(haystack, &lh);
+ un = Tcl_GetUnicodeFromObj(needle, &ln);
- if (last >= lh) {
- last = lh - 1;
- }
- if (last + 1 < ln) {
- /* Don't start the loop if there cannot be a valid answer */
- return -1;
- }
- check = uh + last + 1 - ln;
- while (check >= uh) {
- if ((*check == un[0])
- && (0 == memcmp(check+1, un+1, (ln-1)*sizeof(Tcl_UniChar)))) {
- return (check - uh);
- }
- check--;
+ if (last >= lh) {
+ last = lh - 1;
+ }
+ if (last + 1 < ln) {
+ /* Don't start the loop if there cannot be a valid answer */
+ goto lastEnd;
+ }
+ check = uh + last + 1 - ln;
+ while (check >= uh) {
+ if ((*check == un[0])
+ && (0 == memcmp(check+1, un+1, (ln-1)*sizeof(Tcl_UniChar)))) {
+ value = (check - uh);
+ goto lastEnd;
}
- return -1;
+ check--;
}
+ lastEnd:
+ TclNewIntObj(result, value);
+ return result;
}
/*