diff options
author | jan.nijtmans <nijtmans@users.sourceforge.net> | 2020-03-30 11:37:54 (GMT) |
---|---|---|
committer | jan.nijtmans <nijtmans@users.sourceforge.net> | 2020-03-30 11:37:54 (GMT) |
commit | aa371355b1d31208dd1e1c3b5cae011d33a62290 (patch) | |
tree | 07701075dc01630cf4902d3d3ae324f4f6531f6d /generic/tclStringObj.c | |
parent | 4cbd0649efa1b88510c6873aa3f348b58d51b982 (diff) | |
download | tcl-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.c | 98 |
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; } /* |