summaryrefslogtreecommitdiffstats
path: root/lib/libc/locale/toupper.c
diff options
context:
space:
mode:
authortjr <tjr@FreeBSD.org>2004-05-09 13:04:49 +0000
committertjr <tjr@FreeBSD.org>2004-05-09 13:04:49 +0000
commita8117b04ca4dd64fd8e14a2677860fbe87fce697 (patch)
treeafc406ac8f57049a431f52b1be0185f862495301 /lib/libc/locale/toupper.c
parent0b4230fd707323b4a6300fa70a4dbb2880a0125b (diff)
downloadFreeBSD-src-a8117b04ca4dd64fd8e14a2677860fbe87fce697.zip
FreeBSD-src-a8117b04ca4dd64fd8e14a2677860fbe87fce697.tar.gz
Use a binary search to find the range containing a character in
RuneRange arrays. This is much faster when there are hundreds of ranges (as is the case in UTF-8 locales) and was inspired by a similar change made by Apple in Darwin.
Diffstat (limited to 'lib/libc/locale/toupper.c')
-rw-r--r--lib/libc/locale/toupper.c19
1 files changed, 12 insertions, 7 deletions
diff --git a/lib/libc/locale/toupper.c b/lib/libc/locale/toupper.c
index 6ce6757..b83365d 100644
--- a/lib/libc/locale/toupper.c
+++ b/lib/libc/locale/toupper.c
@@ -44,18 +44,23 @@ __ct_rune_t
___toupper(c)
__ct_rune_t c;
{
- int x;
+ size_t lim;
_RuneRange *rr = &_CurrentRuneLocale->mapupper_ext;
- _RuneEntry *re = rr->ranges;
+ _RuneEntry *base, *re;
if (c < 0 || c == EOF)
return(c);
- for (x = 0; x < rr->nranges; ++x, ++re) {
- if (c < re->min)
- return(c);
- if (c <= re->max)
- return(re->map + c - re->min);
+ /* Binary search -- see bsearch.c for explanation. */
+ base = rr->ranges;
+ for (lim = rr->nranges; lim != 0; lim >>= 1) {
+ re = base + (lim >> 1);
+ if (re->min <= c && c <= re->max)
+ return (re->map + c - re->min);
+ else if (c > re->max) {
+ base = re + 1;
+ lim--;
+ }
}
return(c);
OpenPOWER on IntegriCloud