summaryrefslogtreecommitdiffstats
path: root/usr.bin/tr/str.c
diff options
context:
space:
mode:
authortjr <tjr@FreeBSD.org>2002-06-14 07:37:08 +0000
committertjr <tjr@FreeBSD.org>2002-06-14 07:37:08 +0000
commit0c8a9db6f99a60d7dd69784a1c0e0f6d254fdcc3 (patch)
treed2045ef36addf678037810b6a9dfe3d0c268d899 /usr.bin/tr/str.c
parent6231c89ca356ca59780afac8c23b8b9333851cfc (diff)
downloadFreeBSD-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.c29
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;
OpenPOWER on IntegriCloud