summaryrefslogtreecommitdiffstats
path: root/lib/libc/locale/collate.c
diff options
context:
space:
mode:
authorache <ache@FreeBSD.org>1995-02-16 04:24:39 +0000
committerache <ache@FreeBSD.org>1995-02-16 04:24:39 +0000
commit472ef98cfb41668dee3c9f21484591b5eae44679 (patch)
treee465d799627f4d138821a4405f3d5255f0a64df0 /lib/libc/locale/collate.c
parenta29b82d0e3e1b9a6ff39663d3c59a6673b39a1ba (diff)
downloadFreeBSD-src-472ef98cfb41668dee3c9f21484591b5eae44679.zip
FreeBSD-src-472ef98cfb41668dee3c9f21484591b5eae44679.tar.gz
Add 8-bit collate stuff
Submitted by: alex@elvisti.kiev.ua
Diffstat (limited to 'lib/libc/locale/collate.c')
-rw-r--r--lib/libc/locale/collate.c184
1 files changed, 184 insertions, 0 deletions
diff --git a/lib/libc/locale/collate.c b/lib/libc/locale/collate.c
new file mode 100644
index 0000000..e597f04
--- /dev/null
+++ b/lib/libc/locale/collate.c
@@ -0,0 +1,184 @@
+/*-
+ * Copyright (c) 1995 Alex Tatmanjants <alex@elvisti.kiev.ua>
+ * at Electronni Visti IA, Kiev, Ukraine.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: collate.c,v 1.8 1995/01/27 12:51:06 alex Exp alex $
+ */
+
+#include <err.h>
+#include <rune.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sysexits.h>
+#include "collate.h"
+
+int __collate_load_error = 1;
+u_char __collate_charmap_table[UCHAR_MAX + 1][STR_LEN];
+u_char __collate_substitute_table[UCHAR_MAX + 1][STR_LEN];
+struct __collate_st_char_pri __collate_char_pri_table[UCHAR_MAX + 1];
+struct __collate_st_name_pri __collate_name_pri_table[TABLE_SIZE];
+struct __collate_st_chain_pri __collate_chain_pri_table[TABLE_SIZE];
+
+#define FREAD(a, b, c, d) \
+ do { \
+ if(fread(a, b, c, d) != c) { \
+ fclose(d); \
+ return -1; \
+ } \
+ } while(0)
+
+ int
+__collate_load_tables(encoding)
+ char *encoding;
+{
+ char buf[PATH_MAX];
+ static char *path_locale;
+ FILE *fp;
+
+ __collate_load_error = 1;
+ if (!encoding)
+ return -1;
+ if (!path_locale && !(path_locale = getenv("PATH_LOCALE")))
+ path_locale = _PATH_LOCALE;
+ strcpy(buf, path_locale);
+ strcat(buf, "/");
+ strcat(buf, encoding);
+ strcat(buf, "/LC_COLLATE");
+ if ((fp = fopen(buf, "r")) == NULL)
+ return -1;
+ FREAD(__collate_charmap_table, sizeof(__collate_charmap_table), 1, fp);
+ FREAD(__collate_substitute_table, sizeof(__collate_substitute_table),
+ 1, fp);
+ FREAD(__collate_char_pri_table, sizeof(__collate_char_pri_table), 1,
+ fp);
+ FREAD(__collate_chain_pri_table, sizeof(__collate_chain_pri_table), 1,
+ fp);
+ FREAD(__collate_name_pri_table, sizeof(__collate_name_pri_table), 1,
+ fp);
+ fclose(fp);
+ __collate_load_error = 0;
+ return 0;
+}
+
+u_char *
+__collate_substitute(s)
+ const u_char *s;
+{
+ int dest_len = 0, len = 0;
+ int delta = strlen(s);
+ u_char *dest_str = 0;
+
+ if(s == 0 || *s == '\0')
+ return __collate_strdup("");
+ while(*s) {
+ len += strlen(__collate_substitute_table[*s]);
+ while(dest_len <= len) {
+ if(!dest_str)
+ dest_str = calloc(dest_len = delta, 1);
+ else
+ dest_str = realloc(dest_str, dest_len += delta);
+ if(!dest_str)
+ err(EX_OSERR, "%s(\"%s\")", __FUNCTION__, s);
+ }
+ strcat(dest_str, __collate_substitute_table[*s++]);
+ }
+ return dest_str;
+}
+
+void
+__collate_lookup(t, len, prim, sec)
+ u_char *t;
+ int *len, *prim, *sec;
+{
+ struct __collate_st_name_pri *p;
+ struct __collate_st_chain_pri *p2;
+
+ *len = 1;
+ *prim = *sec = 0;
+ if(__collate_charmap_table[*t][0]) {
+ for(p = __collate_name_pri_table; p->str[0]; p++) {
+ if(strncmp(__collate_charmap_table[*t], p->str, strlen(p->str))
+ == 0) {
+ *prim = p->prim;
+ *sec = p->sec;
+ return;
+ }
+ }
+ return;
+ }
+ for(p2 = __collate_chain_pri_table; p2->str[0]; p2++) {
+ if(strncmp(t, p2->str, strlen(p2->str)) == 0) {
+ *len = strlen(p2->str);
+ *prim = p2->prim;
+ *sec = p2->sec;
+ return;
+ }
+ }
+ *prim = __collate_char_pri_table[*t].prim;
+ *sec = __collate_char_pri_table[*t].sec;
+}
+
+u_char *
+__collate_strdup(s)
+ u_char *s;
+{
+ void *t = strdup(s);
+
+ if (!t)
+ err(EX_OSERR, "__collate_strdup(\"%s\")", s);
+ return t;
+}
+
+#ifdef COLLATE_DEBUG
+void
+__collate_print_tables()
+{
+ int i;
+ struct __collate_st_name_pri *p;
+ struct __collate_st_chain_pri *p2;
+
+ printf("Substitute table:\n");
+ for (i = 0; i < UCHAR_MAX + 1; i++)
+ printf("\t'%c' --> \"%s\"\n", i,
+ __collate_substitute_table[i]);
+ printf("Charmap table:\n");
+ for (i = 0; i < UCHAR_MAX + 1; i++) {
+ if (__collate_charmap_table[i][0])
+ printf("\t\\x%02x --> \"%s\"\n", i,
+ __collate_charmap_table[i]);
+ }
+ printf("Name priority table:\n");
+ for (p = __collate_name_pri_table; p->str[0]; p++)
+ printf("\t\"%s\" : %d %d\n\n", p->str, p->prim, p->sec);
+ printf("Chain priority table:\n");
+ for (p2 = __collate_chain_pri_table; p2->str[0]; p2++)
+ printf("\t\"%s\" : %d %d\n\n", p2->str, p2->prim, p2->sec);
+ printf("Char priority table:\n");
+ for (i = 0; i < UCHAR_MAX + 1; i++)
+ printf("\t'%c' : %d %d\n", i, __collate_char_pri_table[i].prim,
+ __collate_char_pri_table[i].sec);
+}
+#endif
OpenPOWER on IntegriCloud