1c3d0cca4SAndrey A. Chernov /*- 2c3d0cca4SAndrey A. Chernov * Copyright (c) 1995 Alex Tatmanjants <alex@elvisti.kiev.ua> 3c3d0cca4SAndrey A. Chernov * at Electronni Visti IA, Kiev, Ukraine. 4c3d0cca4SAndrey A. Chernov * All rights reserved. 5c3d0cca4SAndrey A. Chernov * 6c3d0cca4SAndrey A. Chernov * Redistribution and use in source and binary forms, with or without 7c3d0cca4SAndrey A. Chernov * modification, are permitted provided that the following conditions 8c3d0cca4SAndrey A. Chernov * are met: 9c3d0cca4SAndrey A. Chernov * 1. Redistributions of source code must retain the above copyright 10c3d0cca4SAndrey A. Chernov * notice, this list of conditions and the following disclaimer. 11c3d0cca4SAndrey A. Chernov * 2. Redistributions in binary form must reproduce the above copyright 12c3d0cca4SAndrey A. Chernov * notice, this list of conditions and the following disclaimer in the 13c3d0cca4SAndrey A. Chernov * documentation and/or other materials provided with the distribution. 14c3d0cca4SAndrey A. Chernov * 15c3d0cca4SAndrey A. Chernov * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND 16c3d0cca4SAndrey A. Chernov * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17c3d0cca4SAndrey A. Chernov * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18c3d0cca4SAndrey A. Chernov * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE 19c3d0cca4SAndrey A. Chernov * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20c3d0cca4SAndrey A. Chernov * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21c3d0cca4SAndrey A. Chernov * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22c3d0cca4SAndrey A. Chernov * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23c3d0cca4SAndrey A. Chernov * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24c3d0cca4SAndrey A. Chernov * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25c3d0cca4SAndrey A. Chernov * SUCH DAMAGE. 26c3d0cca4SAndrey A. Chernov * 27c3d0cca4SAndrey A. Chernov * $Id: collate.c,v 1.8 1995/01/27 12:51:06 alex Exp alex $ 28c3d0cca4SAndrey A. Chernov */ 29c3d0cca4SAndrey A. Chernov 30c3d0cca4SAndrey A. Chernov #include <err.h> 31c3d0cca4SAndrey A. Chernov #include <rune.h> 32c3d0cca4SAndrey A. Chernov #include <stdio.h> 33c3d0cca4SAndrey A. Chernov #include <stdlib.h> 34c3d0cca4SAndrey A. Chernov #include <string.h> 35c3d0cca4SAndrey A. Chernov #include <sysexits.h> 36c3d0cca4SAndrey A. Chernov #include "collate.h" 37c3d0cca4SAndrey A. Chernov 38c3d0cca4SAndrey A. Chernov int __collate_load_error = 1; 39c3d0cca4SAndrey A. Chernov u_char __collate_charmap_table[UCHAR_MAX + 1][STR_LEN]; 40c3d0cca4SAndrey A. Chernov u_char __collate_substitute_table[UCHAR_MAX + 1][STR_LEN]; 41c3d0cca4SAndrey A. Chernov struct __collate_st_char_pri __collate_char_pri_table[UCHAR_MAX + 1]; 42c3d0cca4SAndrey A. Chernov struct __collate_st_name_pri __collate_name_pri_table[TABLE_SIZE]; 43c3d0cca4SAndrey A. Chernov struct __collate_st_chain_pri __collate_chain_pri_table[TABLE_SIZE]; 44c3d0cca4SAndrey A. Chernov 45c3d0cca4SAndrey A. Chernov #define FREAD(a, b, c, d) \ 46c3d0cca4SAndrey A. Chernov do { \ 47c3d0cca4SAndrey A. Chernov if(fread(a, b, c, d) != c) { \ 48c3d0cca4SAndrey A. Chernov fclose(d); \ 49c3d0cca4SAndrey A. Chernov return -1; \ 50c3d0cca4SAndrey A. Chernov } \ 51c3d0cca4SAndrey A. Chernov } while(0) 52c3d0cca4SAndrey A. Chernov 53c3d0cca4SAndrey A. Chernov int 54c3d0cca4SAndrey A. Chernov __collate_load_tables(encoding) 55c3d0cca4SAndrey A. Chernov char *encoding; 56c3d0cca4SAndrey A. Chernov { 57c3d0cca4SAndrey A. Chernov char buf[PATH_MAX]; 58c3d0cca4SAndrey A. Chernov static char *path_locale; 59c3d0cca4SAndrey A. Chernov FILE *fp; 60c3d0cca4SAndrey A. Chernov 61c3d0cca4SAndrey A. Chernov __collate_load_error = 1; 62c3d0cca4SAndrey A. Chernov if (!encoding) 63c3d0cca4SAndrey A. Chernov return -1; 64c3d0cca4SAndrey A. Chernov if (!path_locale && !(path_locale = getenv("PATH_LOCALE"))) 65c3d0cca4SAndrey A. Chernov path_locale = _PATH_LOCALE; 66c3d0cca4SAndrey A. Chernov strcpy(buf, path_locale); 67c3d0cca4SAndrey A. Chernov strcat(buf, "/"); 68c3d0cca4SAndrey A. Chernov strcat(buf, encoding); 69c3d0cca4SAndrey A. Chernov strcat(buf, "/LC_COLLATE"); 70c3d0cca4SAndrey A. Chernov if ((fp = fopen(buf, "r")) == NULL) 71c3d0cca4SAndrey A. Chernov return -1; 72c3d0cca4SAndrey A. Chernov FREAD(__collate_charmap_table, sizeof(__collate_charmap_table), 1, fp); 73c3d0cca4SAndrey A. Chernov FREAD(__collate_substitute_table, sizeof(__collate_substitute_table), 74c3d0cca4SAndrey A. Chernov 1, fp); 75c3d0cca4SAndrey A. Chernov FREAD(__collate_char_pri_table, sizeof(__collate_char_pri_table), 1, 76c3d0cca4SAndrey A. Chernov fp); 77c3d0cca4SAndrey A. Chernov FREAD(__collate_chain_pri_table, sizeof(__collate_chain_pri_table), 1, 78c3d0cca4SAndrey A. Chernov fp); 79c3d0cca4SAndrey A. Chernov FREAD(__collate_name_pri_table, sizeof(__collate_name_pri_table), 1, 80c3d0cca4SAndrey A. Chernov fp); 81c3d0cca4SAndrey A. Chernov fclose(fp); 82c3d0cca4SAndrey A. Chernov __collate_load_error = 0; 83c3d0cca4SAndrey A. Chernov return 0; 84c3d0cca4SAndrey A. Chernov } 85c3d0cca4SAndrey A. Chernov 86c3d0cca4SAndrey A. Chernov u_char * 87c3d0cca4SAndrey A. Chernov __collate_substitute(s) 88c3d0cca4SAndrey A. Chernov const u_char *s; 89c3d0cca4SAndrey A. Chernov { 90c3d0cca4SAndrey A. Chernov int dest_len = 0, len = 0; 91c3d0cca4SAndrey A. Chernov int delta = strlen(s); 92c3d0cca4SAndrey A. Chernov u_char *dest_str = 0; 93c3d0cca4SAndrey A. Chernov 94c3d0cca4SAndrey A. Chernov if(s == 0 || *s == '\0') 95c3d0cca4SAndrey A. Chernov return __collate_strdup(""); 96c3d0cca4SAndrey A. Chernov while(*s) { 97c3d0cca4SAndrey A. Chernov len += strlen(__collate_substitute_table[*s]); 98c3d0cca4SAndrey A. Chernov while(dest_len <= len) { 99c3d0cca4SAndrey A. Chernov if(!dest_str) 100c3d0cca4SAndrey A. Chernov dest_str = calloc(dest_len = delta, 1); 101c3d0cca4SAndrey A. Chernov else 102c3d0cca4SAndrey A. Chernov dest_str = realloc(dest_str, dest_len += delta); 103c3d0cca4SAndrey A. Chernov if(!dest_str) 104c3d0cca4SAndrey A. Chernov err(EX_OSERR, "%s(\"%s\")", __FUNCTION__, s); 105c3d0cca4SAndrey A. Chernov } 106c3d0cca4SAndrey A. Chernov strcat(dest_str, __collate_substitute_table[*s++]); 107c3d0cca4SAndrey A. Chernov } 108c3d0cca4SAndrey A. Chernov return dest_str; 109c3d0cca4SAndrey A. Chernov } 110c3d0cca4SAndrey A. Chernov 111c3d0cca4SAndrey A. Chernov void 112c3d0cca4SAndrey A. Chernov __collate_lookup(t, len, prim, sec) 113c3d0cca4SAndrey A. Chernov u_char *t; 114c3d0cca4SAndrey A. Chernov int *len, *prim, *sec; 115c3d0cca4SAndrey A. Chernov { 116c3d0cca4SAndrey A. Chernov struct __collate_st_name_pri *p; 117c3d0cca4SAndrey A. Chernov struct __collate_st_chain_pri *p2; 118c3d0cca4SAndrey A. Chernov 119c3d0cca4SAndrey A. Chernov *len = 1; 120c3d0cca4SAndrey A. Chernov *prim = *sec = 0; 121c3d0cca4SAndrey A. Chernov if(__collate_charmap_table[*t][0]) { 122c3d0cca4SAndrey A. Chernov for(p = __collate_name_pri_table; p->str[0]; p++) { 123c3d0cca4SAndrey A. Chernov if(strncmp(__collate_charmap_table[*t], p->str, strlen(p->str)) 124c3d0cca4SAndrey A. Chernov == 0) { 125c3d0cca4SAndrey A. Chernov *prim = p->prim; 126c3d0cca4SAndrey A. Chernov *sec = p->sec; 127c3d0cca4SAndrey A. Chernov return; 128c3d0cca4SAndrey A. Chernov } 129c3d0cca4SAndrey A. Chernov } 130c3d0cca4SAndrey A. Chernov return; 131c3d0cca4SAndrey A. Chernov } 132c3d0cca4SAndrey A. Chernov for(p2 = __collate_chain_pri_table; p2->str[0]; p2++) { 133c3d0cca4SAndrey A. Chernov if(strncmp(t, p2->str, strlen(p2->str)) == 0) { 134c3d0cca4SAndrey A. Chernov *len = strlen(p2->str); 135c3d0cca4SAndrey A. Chernov *prim = p2->prim; 136c3d0cca4SAndrey A. Chernov *sec = p2->sec; 137c3d0cca4SAndrey A. Chernov return; 138c3d0cca4SAndrey A. Chernov } 139c3d0cca4SAndrey A. Chernov } 140c3d0cca4SAndrey A. Chernov *prim = __collate_char_pri_table[*t].prim; 141c3d0cca4SAndrey A. Chernov *sec = __collate_char_pri_table[*t].sec; 142c3d0cca4SAndrey A. Chernov } 143c3d0cca4SAndrey A. Chernov 144c3d0cca4SAndrey A. Chernov u_char * 145c3d0cca4SAndrey A. Chernov __collate_strdup(s) 146c3d0cca4SAndrey A. Chernov u_char *s; 147c3d0cca4SAndrey A. Chernov { 148c3d0cca4SAndrey A. Chernov void *t = strdup(s); 149c3d0cca4SAndrey A. Chernov 150c3d0cca4SAndrey A. Chernov if (!t) 151c3d0cca4SAndrey A. Chernov err(EX_OSERR, "__collate_strdup(\"%s\")", s); 152c3d0cca4SAndrey A. Chernov return t; 153c3d0cca4SAndrey A. Chernov } 154c3d0cca4SAndrey A. Chernov 155c3d0cca4SAndrey A. Chernov #ifdef COLLATE_DEBUG 156c3d0cca4SAndrey A. Chernov void 157c3d0cca4SAndrey A. Chernov __collate_print_tables() 158c3d0cca4SAndrey A. Chernov { 159c3d0cca4SAndrey A. Chernov int i; 160c3d0cca4SAndrey A. Chernov struct __collate_st_name_pri *p; 161c3d0cca4SAndrey A. Chernov struct __collate_st_chain_pri *p2; 162c3d0cca4SAndrey A. Chernov 163c3d0cca4SAndrey A. Chernov printf("Substitute table:\n"); 164c3d0cca4SAndrey A. Chernov for (i = 0; i < UCHAR_MAX + 1; i++) 165c3d0cca4SAndrey A. Chernov printf("\t'%c' --> \"%s\"\n", i, 166c3d0cca4SAndrey A. Chernov __collate_substitute_table[i]); 167c3d0cca4SAndrey A. Chernov printf("Charmap table:\n"); 168c3d0cca4SAndrey A. Chernov for (i = 0; i < UCHAR_MAX + 1; i++) { 169c3d0cca4SAndrey A. Chernov if (__collate_charmap_table[i][0]) 170c3d0cca4SAndrey A. Chernov printf("\t\\x%02x --> \"%s\"\n", i, 171c3d0cca4SAndrey A. Chernov __collate_charmap_table[i]); 172c3d0cca4SAndrey A. Chernov } 173c3d0cca4SAndrey A. Chernov printf("Name priority table:\n"); 174c3d0cca4SAndrey A. Chernov for (p = __collate_name_pri_table; p->str[0]; p++) 175c3d0cca4SAndrey A. Chernov printf("\t\"%s\" : %d %d\n\n", p->str, p->prim, p->sec); 176c3d0cca4SAndrey A. Chernov printf("Chain priority table:\n"); 177c3d0cca4SAndrey A. Chernov for (p2 = __collate_chain_pri_table; p2->str[0]; p2++) 178c3d0cca4SAndrey A. Chernov printf("\t\"%s\" : %d %d\n\n", p2->str, p2->prim, p2->sec); 179c3d0cca4SAndrey A. Chernov printf("Char priority table:\n"); 180c3d0cca4SAndrey A. Chernov for (i = 0; i < UCHAR_MAX + 1; i++) 181c3d0cca4SAndrey A. Chernov printf("\t'%c' : %d %d\n", i, __collate_char_pri_table[i].prim, 182c3d0cca4SAndrey A. Chernov __collate_char_pri_table[i].sec); 183c3d0cca4SAndrey A. Chernov } 184c3d0cca4SAndrey A. Chernov #endif 185