From 0113a19ead9ecc4c8d3e911e1dd52f2474e068b0 Mon Sep 17 00:00:00 2001 From: ache Date: Sun, 3 Aug 2003 02:23:39 +0000 Subject: This patch address two problems. 1st one is relatively minor: according our own manpage, upper and lower classes must be sorted, but currently not. 2nd one is serious: tr '[:lower:]' '[:upper:]' (and vice versa) currently works only if upper and lower classes have exact the same number of elements. When it is not true, like for many ISO8859-x locales which have bigger amount of lowercase letters, tr may do nasty things. See this page http://www.opengroup.org/onlinepubs/007908799/xcu/tr.html for detailed description of desired tr behaviour in such cases. --- usr.bin/tr/str.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'usr.bin/tr/str.c') diff --git a/usr.bin/tr/str.c b/usr.bin/tr/str.c index fee1824..f8a7137 100644 --- a/usr.bin/tr/str.c +++ b/usr.bin/tr/str.c @@ -106,6 +106,8 @@ next(s) } return (1); case SET: + case SET_UPPER: + case SET_LOWER: if ((s->lastch = s->set[s->cnt++]) == OOBCH) { s->state = NORMAL; return (next(s)); @@ -194,7 +196,7 @@ genclass(s) { int cnt, (*func)(int); CLASS *cp, tmp; - int *p; + int *p, n; tmp.name = s->str; if ((cp = (CLASS *)bsearch(&tmp, classes, sizeof(classes) / @@ -208,10 +210,18 @@ genclass(s) if ((func)(cnt)) *p++ = cnt; *p = OOBCH; + n = p - cp->set; s->cnt = 0; - s->state = SET; s->set = cp->set; + if (strcmp(s->str, "upper") == 0) + s->state = SET_UPPER; + else if (strcmp(s->str, "lower") == 0) { + s->state = SET_LOWER; + } else + s->state = SET; + if ((s->state == SET_LOWER || s->state == SET_UPPER) && n > 1) + mergesort(s->set, n, sizeof(*(s->set)), charcoll); } static int -- cgit v1.1