]> git.saurik.com Git - apple/libc.git/blame - locale/collate.c
Libc-262.tar.gz
[apple/libc.git] / locale / collate.c
CommitLineData
5b2abdfb
A
1/*-
2 * Copyright (c) 1995 Alex Tatmanjants <alex@elvisti.kiev.ua>
3 * at Electronni Visti IA, Kiev, Ukraine.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 * $FreeBSD: src/lib/libc/locale/collate.c,v 1.21.2.1 2001/03/05 10:10:22 obrien Exp $
28 */
29
30#include <rune.h>
31#include <stdio.h>
32#include <stdlib.h>
33#include <string.h>
34#include <errno.h>
35#include <unistd.h>
36#include <sysexits.h>
37#include <crt_externs.h>
38#include "collate.h"
39#include "setlocale.h"
40
41int __collate_load_error = 1;
42int __collate_substitute_nontrivial;
43char __collate_version[STR_LEN];
44u_char __collate_substitute_table[UCHAR_MAX + 1][STR_LEN];
45struct __collate_st_char_pri __collate_char_pri_table[UCHAR_MAX + 1];
46struct __collate_st_chain_pri __collate_chain_pri_table[TABLE_SIZE];
47
48#define FREAD(a, b, c, d) \
49 do { \
50 if (fread(a, b, c, d) != c) { \
51 fclose(d); \
52 return -1; \
53 } \
54 } while(0)
55
56void __collate_err(int ex, const char *f) ;
57
58int
59__collate_load_tables(encoding)
60 char *encoding;
61{
62 char buf[PATH_MAX];
63 FILE *fp;
64 int i, save_load_error;
65
66 save_load_error = __collate_load_error;
67 __collate_load_error = 1;
68 if (!encoding) {
69 __collate_load_error = save_load_error;
70 return -1;
71 }
72 if (!strcmp(encoding, "C") || !strcmp(encoding, "POSIX"))
73 return 0;
74 if (!_PathLocale) {
75 __collate_load_error = save_load_error;
76 return -1;
77 }
78 /* Range checking not needed, encoding has fixed size */
79 (void) strcpy(buf, _PathLocale);
80 (void) strcat(buf, "/");
81 (void) strcat(buf, encoding);
82 (void) strcat(buf, "/LC_COLLATE");
83 if ((fp = fopen(buf, "r")) == NULL) {
84 __collate_load_error = save_load_error;
85 return -1;
86 }
87 FREAD(__collate_version, sizeof(__collate_version), 1, fp);
88 if (strcmp(__collate_version, COLLATE_VERSION) != 0) {
89 fclose(fp);
90 return -1;
91 }
92 FREAD(__collate_substitute_table, sizeof(__collate_substitute_table),
93 1, fp);
94 FREAD(__collate_char_pri_table, sizeof(__collate_char_pri_table), 1,
95 fp);
96 FREAD(__collate_chain_pri_table, sizeof(__collate_chain_pri_table), 1,
97 fp);
98 fclose(fp);
99 __collate_load_error = 0;
100
101 __collate_substitute_nontrivial = 0;
102 for (i = 0; i < UCHAR_MAX + 1; i++) {
103 if (__collate_substitute_table[i][0] != i ||
104 __collate_substitute_table[i][1] != 0) {
105 __collate_substitute_nontrivial = 1;
106 break;
107 }
108 }
109
110 return 0;
111}
112
113u_char *
114__collate_substitute(s)
115 const u_char *s;
116{
117 int dest_len, len, nlen;
118 int delta = strlen(s);
119 u_char *dest_str = NULL;
120
121 if(s == NULL || *s == '\0')
122 return __collate_strdup("");
123 delta += delta / 8;
124 dest_str = malloc(dest_len = delta);
125 if(dest_str == NULL)
126 __collate_err(EX_OSERR, __FUNCTION__);
127 len = 0;
128 while(*s) {
129 nlen = len + strlen(__collate_substitute_table[*s]);
130 if (dest_len <= nlen) {
131 dest_str = reallocf(dest_str, dest_len = nlen + delta);
132 if(dest_str == NULL)
133 __collate_err(EX_OSERR, __FUNCTION__);
134 }
135 strcpy(dest_str + len, __collate_substitute_table[*s++]);
136 len = nlen;
137 }
138 return dest_str;
139}
140
141void
142__collate_lookup(t, len, prim, sec)
143 const u_char *t;
144 int *len, *prim, *sec;
145{
146 struct __collate_st_chain_pri *p2;
147
148 *len = 1;
149 *prim = *sec = 0;
150 for(p2 = __collate_chain_pri_table; p2->str[0]; p2++) {
151 if(strncmp(t, p2->str, strlen(p2->str)) == 0) {
152 *len = strlen(p2->str);
153 *prim = p2->prim;
154 *sec = p2->sec;
155 return;
156 }
157 }
158 *prim = __collate_char_pri_table[*t].prim;
159 *sec = __collate_char_pri_table[*t].sec;
160}
161
162u_char *
163__collate_strdup(s)
164 u_char *s;
165{
166 u_char *t = strdup(s);
167
168 if (t == NULL)
169 __collate_err(EX_OSERR, __FUNCTION__);
170 return t;
171}
172
173void
174__collate_err(int ex, const char *f)
175{
176 char **__progname = _NSGetProgname();
177 const char *s;
178 int serrno = errno;
179
180 s = *__progname;
181 write(STDERR_FILENO, s, strlen(s));
182 write(STDERR_FILENO, ": ", 2);
183 s = f;
184 write(STDERR_FILENO, s, strlen(s));
185 write(STDERR_FILENO, ": ", 2);
186 s = strerror(serrno);
187 write(STDERR_FILENO, s, strlen(s));
188 write(STDERR_FILENO, "\n", 1);
189 exit(ex);
190}
191
192#ifdef COLLATE_DEBUG
193void
194__collate_print_tables()
195{
196 int i;
197 struct __collate_st_chain_pri *p2;
198
199 printf("Substitute table:\n");
200 for (i = 0; i < UCHAR_MAX + 1; i++)
201 if (i != *__collate_substitute_table[i])
202 printf("\t'%c' --> \"%s\"\n", i,
203 __collate_substitute_table[i]);
204 printf("Chain priority table:\n");
205 for (p2 = __collate_chain_pri_table; p2->str[0]; p2++)
206 printf("\t\"%s\" : %d %d\n\n", p2->str, p2->prim, p2->sec);
207 printf("Char priority table:\n");
208 for (i = 0; i < UCHAR_MAX + 1; i++)
209 printf("\t'%c' : %d %d\n", i, __collate_char_pri_table[i].prim,
210 __collate_char_pri_table[i].sec);
211}
212#endif