source: trunk/libs/newlib/src/newlib/libc/posix/collate.c @ 444

Last change on this file since 444 was 444, checked in by satin@…, 6 years ago

add newlib,libalmos-mkh, restructure shared_syscalls.h and mini-libc

File size: 5.8 KB
Line 
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
28#include <sys/cdefs.h>
29
30#include "namespace.h"
31#include <rune.h>
32#include <stdio.h>
33#include <stdlib.h>
34#include <string.h>
35#include <errno.h>
36#include <unistd.h>
37#include <sysexits.h>
38#include "un-namespace.h"
39
40#include "collate.h"
41
42extern char *_PathLocale;
43int __collate_load_error = 1;
44int __collate_substitute_nontrivial;
45char __collate_version[STR_LEN];
46u_char __collate_substitute_table[UCHAR_MAX + 1][STR_LEN];
47struct __collate_st_char_pri __collate_char_pri_table[UCHAR_MAX + 1];
48struct __collate_st_chain_pri __collate_chain_pri_table[TABLE_SIZE];
49
50#define FREAD(a, b, c, d) \
51        do { \
52                if (fread(a, b, c, d) != c) { \
53                        fclose(d); \
54                        return -1; \
55                } \
56        } while(0)
57
58void __collate_err(int ex, const char *f);
59
60int
61__collate_load_tables(encoding)
62        char *encoding;
63{
64        char buf[PATH_MAX];
65        FILE *fp;
66        int i, save_load_error;
67
68        save_load_error = __collate_load_error;
69        __collate_load_error = 1;
70        if (!encoding) {
71                __collate_load_error = save_load_error;
72                return -1;
73        }
74        if (!strcmp(encoding, "C") || !strcmp(encoding, "POSIX"))
75                return 0;
76        if (!_PathLocale) {
77                __collate_load_error = save_load_error;
78                return -1;
79        }
80        /* Range checking not needed, encoding has fixed size */
81        (void) strcpy(buf, _PathLocale);
82        (void) strcat(buf, "/");
83        (void) strcat(buf, encoding);
84        (void) strcat(buf, "/LC_COLLATE");
85        if ((fp = fopen(buf, "r")) == NULL) {
86                __collate_load_error = save_load_error;
87                return -1;
88        }
89        FREAD(__collate_version, sizeof(__collate_version), 1, fp);
90        if (strcmp(__collate_version, COLLATE_VERSION) != 0) {
91                fclose(fp);
92                return -1;
93        }
94        FREAD(__collate_substitute_table, sizeof(__collate_substitute_table),
95              1, fp);
96        FREAD(__collate_char_pri_table, sizeof(__collate_char_pri_table), 1,
97              fp);
98        FREAD(__collate_chain_pri_table, sizeof(__collate_chain_pri_table), 1,
99              fp);
100        fclose(fp);
101        __collate_load_error = 0;
102       
103        __collate_substitute_nontrivial = 0;
104        for (i = 0; i < UCHAR_MAX + 1; i++) {
105                if (__collate_substitute_table[i][0] != i ||
106                    __collate_substitute_table[i][1] != 0) {
107                        __collate_substitute_nontrivial = 1;
108                        break;
109                }
110        }
111
112        return 0;
113}
114
115u_char *
116__collate_substitute(s)
117        const u_char *s;
118{
119        int dest_len, len, nlen;
120        int delta = strlen((const char *) s);
121        u_char *dest_str = NULL;
122
123        if(s == NULL || *s == '\0')
124                return __collate_strdup((u_char *) "");
125        delta += delta / 8;
126        dest_str = (u_char *) malloc(dest_len = delta);
127        if(dest_str == NULL)
128                __collate_err(EX_OSERR, __FUNCTION__);
129        len = 0;
130        while(*s) {
131                nlen = len + strlen((const char *)
132                                    __collate_substitute_table[*s]);
133                if (dest_len <= nlen) {
134                        dest_str = reallocf(dest_str, dest_len = nlen + delta);
135                        if(dest_str == NULL)
136                                __collate_err(EX_OSERR, __FUNCTION__);
137                }
138                strcpy((char *) dest_str + len,
139                       (const char *) __collate_substitute_table[*s++]);
140                len = nlen;
141        }
142        return dest_str;
143}
144
145void
146__collate_lookup(t, len, prim, sec)
147        const u_char *t;
148        int *len, *prim, *sec;
149{
150        struct __collate_st_chain_pri *p2;
151
152        *len = 1;
153        *prim = *sec = 0;
154        for(p2 = __collate_chain_pri_table; p2->str[0]; p2++) {
155                if(strncmp((const char *) t, (const char *) p2->str,
156                           strlen((const char *) p2->str)) == 0) {
157                        *len = strlen((const char *) p2->str);
158                        *prim = p2->prim;
159                        *sec = p2->sec;
160                        return;
161                }
162        }
163        *prim = __collate_char_pri_table[*t].prim;
164        *sec = __collate_char_pri_table[*t].sec;
165}
166
167u_char *
168__collate_strdup(s)
169        u_char *s;
170{
171        u_char *t = (u_char *) strdup((const char *) s);
172
173        if (t == NULL)
174                __collate_err(EX_OSERR, __FUNCTION__);
175        return t;
176}
177
178void
179__collate_err(int ex, const char *f)
180{
181        const char *s;
182        int serrno = errno;
183        int dummy;
184
185        /* Be careful to change write counts if you change the strings */
186        write(STDERR_FILENO, "collate_error: ", 15);
187        write(STDERR_FILENO, f, strlen(f));
188        write(STDERR_FILENO, ": ", 2);
189        s = _strerror_r(_REENT, serrno, 1, &dummy);
190        write(STDERR_FILENO, s, strlen(s));
191        write(STDERR_FILENO, "\n", 1);
192        exit(ex);
193}
194
195#ifdef COLLATE_DEBUG
196void
197__collate_print_tables()
198{
199        int i;
200        struct __collate_st_chain_pri *p2;
201
202        printf("Substitute table:\n");
203        for (i = 0; i < UCHAR_MAX + 1; i++)
204            if (i != *__collate_substitute_table[i])
205                printf("\t'%c' --> \"%s\"\n", i,
206                       __collate_substitute_table[i]);
207        printf("Chain priority table:\n");
208        for (p2 = __collate_chain_pri_table; p2->str[0]; p2++)
209                printf("\t\"%s\" : %d %d\n\n", p2->str, p2->prim, p2->sec);
210        printf("Char priority table:\n");
211        for (i = 0; i < UCHAR_MAX + 1; i++)
212                printf("\t'%c' : %d %d\n", i, __collate_char_pri_table[i].prim,
213                       __collate_char_pri_table[i].sec);
214}
215#endif
Note: See TracBrowser for help on using the repository browser.