2 * Copyright (c) 1995 Alex Tatmanjants <alex@elvisti.kiev.ua>
3 * at Electronni Visti IA, Kiev, Ukraine.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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.
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
27 * $FreeBSD: src/lib/libc/locale/collate.c,v 1.21.2.1 2001/03/05 10:10:22 obrien Exp $
37 #include <crt_externs.h>
39 #include "setlocale.h"
41 int __collate_load_error
= 1;
42 int __collate_substitute_nontrivial
;
43 char __collate_version
[STR_LEN
];
44 u_char __collate_substitute_table
[UCHAR_MAX
+ 1][STR_LEN
];
45 struct __collate_st_char_pri __collate_char_pri_table
[UCHAR_MAX
+ 1];
46 struct __collate_st_chain_pri __collate_chain_pri_table
[TABLE_SIZE
];
48 #define FREAD(a, b, c, d) \
50 if (fread(a, b, c, d) != c) { \
56 void __collate_err(int ex
, const char *f
) ;
59 __collate_load_tables(encoding
)
64 int i
, save_load_error
;
66 save_load_error
= __collate_load_error
;
67 __collate_load_error
= 1;
69 __collate_load_error
= save_load_error
;
72 if (!strcmp(encoding
, "C") || !strcmp(encoding
, "POSIX"))
75 __collate_load_error
= save_load_error
;
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
;
87 FREAD(__collate_version
, sizeof(__collate_version
), 1, fp
);
88 if (strcmp(__collate_version
, COLLATE_VERSION
) != 0) {
92 FREAD(__collate_substitute_table
, sizeof(__collate_substitute_table
),
94 FREAD(__collate_char_pri_table
, sizeof(__collate_char_pri_table
), 1,
96 FREAD(__collate_chain_pri_table
, sizeof(__collate_chain_pri_table
), 1,
99 __collate_load_error
= 0;
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;
114 __collate_substitute(s
)
117 int dest_len
, len
, nlen
;
118 int delta
= strlen(s
);
119 u_char
*dest_str
= NULL
;
121 if(s
== NULL
|| *s
== '\0')
122 return __collate_strdup("");
124 dest_str
= malloc(dest_len
= delta
);
126 __collate_err(EX_OSERR
, __FUNCTION__
);
129 nlen
= len
+ strlen(__collate_substitute_table
[*s
]);
130 if (dest_len
<= nlen
) {
131 dest_str
= reallocf(dest_str
, dest_len
= nlen
+ delta
);
133 __collate_err(EX_OSERR
, __FUNCTION__
);
135 strcpy(dest_str
+ len
, __collate_substitute_table
[*s
++]);
142 __collate_lookup(t
, len
, prim
, sec
)
144 int *len
, *prim
, *sec
;
146 struct __collate_st_chain_pri
*p2
;
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
);
158 *prim
= __collate_char_pri_table
[*t
].prim
;
159 *sec
= __collate_char_pri_table
[*t
].sec
;
166 u_char
*t
= strdup(s
);
169 __collate_err(EX_OSERR
, __FUNCTION__
);
174 __collate_err(int ex
, const char *f
)
176 char **__progname
= _NSGetProgname();
181 write(STDERR_FILENO
, s
, strlen(s
));
182 write(STDERR_FILENO
, ": ", 2);
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);
194 __collate_print_tables()
197 struct __collate_st_chain_pri
*p2
;
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
);