diff options
author | tjr <tjr@FreeBSD.org> | 2002-06-14 07:37:08 +0000 |
---|---|---|
committer | tjr <tjr@FreeBSD.org> | 2002-06-14 07:37:08 +0000 |
commit | 0c8a9db6f99a60d7dd69784a1c0e0f6d254fdcc3 (patch) | |
tree | d2045ef36addf678037810b6a9dfe3d0c268d899 /usr.bin/tr/str.c | |
parent | 6231c89ca356ca59780afac8c23b8b9333851cfc (diff) | |
download | FreeBSD-src-0c8a9db6f99a60d7dd69784a1c0e0f6d254fdcc3.zip FreeBSD-src-0c8a9db6f99a60d7dd69784a1c0e0f6d254fdcc3.tar.gz |
Implement support for equivalence classes ([=e=]) when the mapping is
one-to-one (SUSv3)
Diffstat (limited to 'usr.bin/tr/str.c')
-rw-r--r-- | usr.bin/tr/str.c | 29 |
1 files changed, 25 insertions, 4 deletions
diff --git a/usr.bin/tr/str.c b/usr.bin/tr/str.c index 46bf340..90f7335 100644 --- a/usr.bin/tr/str.c +++ b/usr.bin/tr/str.c @@ -216,14 +216,13 @@ c_class(a, b) return (strcmp(((const CLASS *)a)->name, ((const CLASS *)b)->name)); } -/* - * English doesn't have any equivalence classes, so for now - * we just syntax check and grab the character. - */ static void genequiv(s) STR *s; { + int i, p, pri; + char src[2], dst[3]; + if (*s->str == '\\') { s->equiv[0] = backslash(s); if (*s->str != '=') @@ -233,6 +232,28 @@ genequiv(s) if (s->str[1] != '=') errx(1, "misplaced equivalence equals sign"); } + + /* + * Calculate the set of all characters in the same equivalence class + * as the specified character (they will have the same primary + * collation weights). + * XXX Knows too much about how strxfrm() is implemented. Assumes + * it fills the string with primary collation weight bytes. Only one- + * to-one mappings are supported. + */ + src[0] = s->equiv[0]; + src[1] = '\0'; + if (strxfrm(dst, src, sizeof(dst)) == 1) { + pri = (unsigned char)*dst; + for (p = 1, i = 1; i < NCHARS; i++) { + *src = i; + if (strxfrm(dst, src, sizeof(dst)) == 1 && pri && + pri == (unsigned char)*dst) + s->equiv[p++] = i; + } + s->equiv[p] = OOBCH; + } + s->str += 2; s->cnt = 0; s->state = SET; |