diff options
author | ache <ache@FreeBSD.org> | 2003-08-03 03:51:27 +0000 |
---|---|---|
committer | ache <ache@FreeBSD.org> | 2003-08-03 03:51:27 +0000 |
commit | b97366a2365a23c5d581d22f32efd5dfbc55ec69 (patch) | |
tree | 06289a6ab3f1a04df95701445d8599de54954fba /usr.bin/tr/str.c | |
parent | 0113a19ead9ecc4c8d3e911e1dd52f2474e068b0 (diff) | |
download | FreeBSD-src-b97366a2365a23c5d581d22f32efd5dfbc55ec69.zip FreeBSD-src-b97366a2365a23c5d581d22f32efd5dfbc55ec69.tar.gz |
POSIX requires 'c-c' must conform collate and be in collation order
Diffstat (limited to 'usr.bin/tr/str.c')
-rw-r--r-- | usr.bin/tr/str.c | 29 |
1 files changed, 17 insertions, 12 deletions
diff --git a/usr.bin/tr/str.c b/usr.bin/tr/str.c index f8a7137..7d91e7b 100644 --- a/usr.bin/tr/str.c +++ b/usr.bin/tr/str.c @@ -92,13 +92,6 @@ next(s) if (s->str[0] == '-' && genrange(s)) return (next(s)); return (1); - case RANGE: - if (s->cnt-- == 0) { - s->state = NORMAL; - return (next(s)); - } - ++s->lastch; - return (1); case SEQUENCE: if (s->cnt-- == 0) { s->state = NORMAL; @@ -204,7 +197,7 @@ genclass(s) errx(1, "unknown class %s", s->str); if ((cp->set = p = malloc((NCHARS + 1) * sizeof(int))) == NULL) - err(1, "malloc"); + err(1, "genclass() malloc"); bzero(p, (NCHARS + 1) * sizeof(int)); for (cnt = 0, func = cp->func; cnt < NCHARS; ++cnt) if ((func)(cnt)) @@ -282,16 +275,28 @@ genrange(s) { int stopval; char *savestart; + int n, cnt, *p; savestart = s->str; stopval = *++s->str == '\\' ? backslash(s) : (u_char)*s->str++; - if (stopval < (u_char)s->lastch) { + if (charcoll((const void *)&stopval, (const void *)&(s->lastch)) < 0) { s->str = savestart; return (0); } - s->cnt = stopval - s->lastch + 1; - s->state = RANGE; - --s->lastch; + if ((s->set = p = malloc((NCHARS + 1) * sizeof(int))) == NULL) + err(1, "genrange() malloc"); + bzero(p, (NCHARS + 1) * sizeof(int)); + for (cnt = 0; cnt < NCHARS; ++cnt) + if (charcoll((const void *)&cnt, (const void *)&(s->lastch)) >= 0 && + charcoll((const void *)&cnt, (const void *)&stopval) <= 0) + *p++ = cnt; + *p = OOBCH; + n = p - s->set; + + s->cnt = 0; + s->state = SET; + if (n > 1) + mergesort(s->set, n, sizeof(*(s->set)), charcoll); return (1); } |