From c3d0cca4e90381dd0ec3c78b0720dfcca6682dbe Mon Sep 17 00:00:00 2001 From: "Andrey A. Chernov" Date: Thu, 16 Feb 1995 04:24:39 +0000 Subject: [PATCH] Add 8-bit collate stuff Submitted by: alex@elvisti.kiev.ua --- lib/libc/locale/Makefile.inc | 2 +- lib/libc/locale/collate.c | 184 ++++++++++++++++++++++++++++ lib/libc/locale/collate.h | 69 +++++++++++ lib/libc/locale/setlocale.c | 9 +- lib/libc/locale/startup_setlocale.c | 8 ++ 5 files changed, 270 insertions(+), 2 deletions(-) create mode 100644 lib/libc/locale/collate.c create mode 100644 lib/libc/locale/collate.h diff --git a/lib/libc/locale/Makefile.inc b/lib/libc/locale/Makefile.inc index 57a82cfc317a..795d1f81bf89 100644 --- a/lib/libc/locale/Makefile.inc +++ b/lib/libc/locale/Makefile.inc @@ -6,7 +6,7 @@ SRCS+= ansi.c ctype.c euc.c frune.c isctype.c lconv.c localeconv.c \ mbrune.c none.c rune.c common_setlocale.c \ startup_setlocale.c read_runemagi.c setlocale.c table.c utf2.c \ - runetype.c tolower.c toupper.c nomacros.c + runetype.c tolower.c toupper.c nomacros.c collate.c MAN3+= locale/ctype.3 locale/isalnum.3 locale/isalpha.3 locale/isascii.3 \ locale/isblank.3 locale/iscntrl.3 locale/isdigit.3 locale/isgraph.3 \ diff --git a/lib/libc/locale/collate.c b/lib/libc/locale/collate.c new file mode 100644 index 000000000000..e597f0403069 --- /dev/null +++ b/lib/libc/locale/collate.c @@ -0,0 +1,184 @@ +/*- + * Copyright (c) 1995 Alex Tatmanjants + * 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 +#include +#include +#include +#include +#include +#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 diff --git a/lib/libc/locale/collate.h b/lib/libc/locale/collate.h new file mode 100644 index 000000000000..c7c0b6d668b6 --- /dev/null +++ b/lib/libc/locale/collate.h @@ -0,0 +1,69 @@ +/*- + * Copyright (c) 1995 Alex Tatmanjants + * 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.h,v 1.4 1995/01/27 12:51:06 alex Exp alex $ + */ + +#ifndef COLLATE_H_INCLUDED +#define COLLATE_H_INCLUDED + +#include +#include +#include + +#define STR_LEN 10 +#define TABLE_SIZE 100 + +struct __collate_st_char_pri { + int prim, sec; +}; +struct __collate_st_name_pri { + u_char str[STR_LEN]; + int prim, sec; +}; +struct __collate_st_chain_pri { + u_char str[STR_LEN]; + int prim, sec; +}; + +extern int __collate_load_error; +extern u_char __collate_charmap_table[UCHAR_MAX + 1][STR_LEN]; +extern u_char __collate_substitute_table[UCHAR_MAX + 1][STR_LEN]; +extern struct __collate_st_char_pri __collate_char_pri_table[UCHAR_MAX + 1]; +extern struct __collate_st_name_pri __collate_name_pri_table[TABLE_SIZE]; +extern struct __collate_st_chain_pri __collate_chain_pri_table[TABLE_SIZE]; + +__BEGIN_DECLS +u_char *__collate_strdup __P((u_char *)); +u_char *__collate_substitute __P((const u_char *)); +int __collate_load_tables __P((char *)); +void __collate_lookup __P((u_char *, int *, int *, int *)); +#ifdef COLLATE_DEBUG +void __collate_print_tables __P((void)); +#endif +__END_DECLS + +#endif /* not COLLATE_H_INCLUDED */ diff --git a/lib/libc/locale/setlocale.c b/lib/libc/locale/setlocale.c index 0f4a77b63a62..20bcb6a77aee 100644 --- a/lib/libc/locale/setlocale.c +++ b/lib/libc/locale/setlocale.c @@ -158,6 +158,14 @@ loadlocale(category) return (current_categories[LC_CTYPE]); } + if (category == LC_COLLATE) { + if (__collate_load_tables(new_categories[LC_COLLATE]) < 0) + return (NULL); + (void)strcpy(current_categories[LC_COLLATE], + new_categories[LC_COLLATE]); + return (current_categories[LC_COLLATE]); + } + if (!strcmp(new_categories[category], "C") || !strcmp(new_categories[category], "POSIX")) { @@ -178,7 +186,6 @@ loadlocale(category) PathLocale, new_categories[category], categories[category]); #endif switch (category) { - case LC_COLLATE: case LC_MONETARY: case LC_NUMERIC: case LC_TIME: diff --git a/lib/libc/locale/startup_setlocale.c b/lib/libc/locale/startup_setlocale.c index ac93c4048c92..cfacf8bdc9c5 100644 --- a/lib/libc/locale/startup_setlocale.c +++ b/lib/libc/locale/startup_setlocale.c @@ -123,6 +123,14 @@ loadlocale(category) return (current_categories[LC_CTYPE]); } + if (category == LC_COLLATE) { + if (__collate_load_tables(new_categories[LC_COLLATE]) < 0) + return (NULL); + (void)strcpy(current_categories[LC_COLLATE], + new_categories[LC_COLLATE]); + return (current_categories[LC_COLLATE]); + } + if (!strcmp(new_categories[category], "C") || !strcmp(new_categories[category], "POSIX")) {