diff options
author | tjr <tjr@FreeBSD.org> | 2004-05-09 13:04:49 +0000 |
---|---|---|
committer | tjr <tjr@FreeBSD.org> | 2004-05-09 13:04:49 +0000 |
commit | a8117b04ca4dd64fd8e14a2677860fbe87fce697 (patch) | |
tree | afc406ac8f57049a431f52b1be0185f862495301 /lib/libc/locale/toupper.c | |
parent | 0b4230fd707323b4a6300fa70a4dbb2880a0125b (diff) | |
download | FreeBSD-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.c | 19 |
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); |